about summary refs log tree commit diff
path: root/sysdeps/x86_64/dl-machine.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-05-10 17:05:06 -0700
committerH.J. Lu <hjl.tools@gmail.com>2012-05-10 17:05:06 -0700
commitdf8a552f6f93f62c494177a49ee49d3bf40949b8 (patch)
tree8aee7d998d4e25fe5563f87295f317d5800e4f0e /sysdeps/x86_64/dl-machine.h
parentf42d41d10769f9bf465348e6cf6960364d47e10b (diff)
downloadglibc-df8a552f6f93f62c494177a49ee49d3bf40949b8.tar.gz
glibc-df8a552f6f93f62c494177a49ee49d3bf40949b8.tar.xz
glibc-df8a552f6f93f62c494177a49ee49d3bf40949b8.zip
Handle R_X86_64_RELATIVE64 and R_X86_64_64 for x32
Diffstat (limited to 'sysdeps/x86_64/dl-machine.h')
-rw-r--r--sysdeps/x86_64/dl-machine.h22
1 files changed, 19 insertions, 3 deletions
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 934e0b0d6f..e3bab5f22d 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -283,6 +283,13 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
     }
   else
 # endif
+# if !defined RTLD_BOOTSTRAP
+  /* l_addr + r_addend may be > 0xffffffff and R_X86_64_RELATIVE64
+     relocation updates the whole 64-bit entry.  */
+  if (__builtin_expect (r_type == R_X86_64_RELATIVE64, 0))
+    *(Elf64_Addr *) reloc_addr = (Elf64_Addr) map->l_addr + reloc->r_addend;
+  else
+# endif
   if (__builtin_expect (r_type == R_X86_64_NONE, 0))
     return;
   else
@@ -407,7 +414,9 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 
 # ifndef RTLD_BOOTSTRAP
 	case R_X86_64_64:
-	  *reloc_addr = value + reloc->r_addend;
+	  /* value + r_addend may be > 0xffffffff and R_X86_64_64
+	     relocation updates the whole 64-bit entry.  */
+	  *(Elf64_Addr *) reloc_addr = (Elf64_Addr) value + reloc->r_addend;
 	  break;
 	case R_X86_64_32:
 	  value += reloc->r_addend;
@@ -478,8 +487,15 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 			   void *const reloc_addr_arg)
 {
   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
-  assert (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE);
-  *reloc_addr = l_addr + reloc->r_addend;
+  /* l_addr + r_addend may be > 0xffffffff and R_X86_64_RELATIVE64
+     relocation updates the whole 64-bit entry.  */
+  if (__builtin_expect (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE64, 0))
+    *(Elf64_Addr *) reloc_addr = (Elf64_Addr) l_addr + reloc->r_addend;
+  else
+    {
+      assert (ELFW(R_TYPE) (reloc->r_info) == R_X86_64_RELATIVE);
+      *reloc_addr = l_addr + reloc->r_addend;
+    }
 }
 
 auto inline void