about summary refs log tree commit diff
path: root/sysdeps/powerpc/powerpc32
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2013-10-03 13:51:52 +0930
committerAlan Modra <amodra@gmail.com>2013-10-04 11:33:12 +0930
commitf8e3e9f31bfd71641418897228fa1732170b69cc (patch)
treee3989beb32870a742129b014e2486edc342fe221 /sysdeps/powerpc/powerpc32
parentf5a0a42a03cb56ef89aeebf94214752a98d074cb (diff)
downloadglibc-f8e3e9f31bfd71641418897228fa1732170b69cc.tar.gz
glibc-f8e3e9f31bfd71641418897228fa1732170b69cc.tar.xz
glibc-f8e3e9f31bfd71641418897228fa1732170b69cc.zip
Correct little-endian relocation of UADDR64,32,16.
	* sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela):
	Correct handling of unaligned relocs for little-endian.
	* sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela): Likewise.
Diffstat (limited to 'sysdeps/powerpc/powerpc32')
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 3e7202d869..f81899a0ac 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -416,6 +416,12 @@ __process_machine_rela (struct link_map *map,
 			Elf32_Addr const finaladdr,
 			int rinfo)
 {
+  union unaligned
+    {
+      unsigned u2 __attribute__ ((mode (HI)));
+      unsigned u4 __attribute__ ((mode (SI)));
+    } __attribute__((__packed__));
+
   switch (rinfo)
     {
     case R_PPC_NONE:
@@ -432,10 +438,7 @@ __process_machine_rela (struct link_map *map,
       return;
 
     case R_PPC_UADDR32:
-      ((char *) reloc_addr)[0] = finaladdr >> 24;
-      ((char *) reloc_addr)[1] = finaladdr >> 16;
-      ((char *) reloc_addr)[2] = finaladdr >> 8;
-      ((char *) reloc_addr)[3] = finaladdr;
+      ((union unaligned *) reloc_addr)->u4 = finaladdr;
       break;
 
     case R_PPC_ADDR24:
@@ -453,8 +456,7 @@ __process_machine_rela (struct link_map *map,
     case R_PPC_UADDR16:
       if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0))
 	_dl_reloc_overflow (map,  "R_PPC_UADDR16", reloc_addr, refsym);
-      ((char *) reloc_addr)[0] = finaladdr >> 8;
-      ((char *) reloc_addr)[1] = finaladdr;
+      ((union unaligned *) reloc_addr)->u2 = finaladdr;
       break;
 
     case R_PPC_ADDR16_LO: