diff options
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/ld/sparc/md.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/gnu/usr.bin/ld/sparc/md.c b/gnu/usr.bin/ld/sparc/md.c index c5b200ded67..824feecf436 100644 --- a/gnu/usr.bin/ld/sparc/md.c +++ b/gnu/usr.bin/ld/sparc/md.c @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: md.c,v 1.4 1996/08/22 01:24:21 deraadt Exp $ + * $Id: md.c,v 1.5 1997/11/05 10:32:52 deraadt Exp $ */ #include <sys/param.h> @@ -138,26 +138,28 @@ md_relocate(r, relocation, addr, relocatable_output) relocation <<= RELOC_TARGET_BITPOS(r); mask <<= RELOC_TARGET_BITPOS(r); +#define RELOCATE(type) \ + { \ + type ad; \ + (void)memcpy(&ad, addr, sizeof(ad)); \ + if (RELOC_MEMORY_ADD_P(r)) \ + relocation += (mask & ad); \ + ad &= ~mask; \ + ad |= relocation; \ + (void)memcpy(addr, &ad, sizeof(ad)); \ + } + switch (RELOC_TARGET_SIZE(r)) { case 0: - if (RELOC_MEMORY_ADD_P(r)) - relocation += (mask & *(u_char *) (addr)); - *(u_char *) (addr) &= ~mask; - *(u_char *) (addr) |= relocation; + RELOCATE(u_char) break; case 1: - if (RELOC_MEMORY_ADD_P(r)) - relocation += (mask & *(u_short *) (addr)); - *(u_short *) (addr) &= ~mask; - *(u_short *) (addr) |= relocation; + RELOCATE(u_short) break; case 2: - if (RELOC_MEMORY_ADD_P(r)) - relocation += (mask & *(u_long *) (addr)); - *(u_long *) (addr) &= ~mask; - *(u_long *) (addr) |= relocation; + RELOCATE(u_long) break; default: errx(1, "Unimplemented relocation field length: %d", |