diff options
author | Joseph Myers <joseph@codesourcery.com> | 2010-02-20 13:39:58 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-20 13:48:05 -0800 |
commit | 1d204bf2945617be272f88ee233adbceeffd5315 (patch) | |
tree | 53434b857b2568fe20a535a8d8abd854ea379b55 /sysdeps/sparc | |
parent | 199428c19774c12b3c4b6e6486ea9d4a021288af (diff) | |
download | glibc-1d204bf2945617be272f88ee233adbceeffd5315.tar.gz |
Fix PLT rewrite when prelinking fails on 64-bit sparc.
When prelinking fails we have to rewrite the PLT, but the code
doing so forgets to adjust all rela->r_offset addresses by the
location of where the object was actually mapped.
Diffstat (limited to 'sysdeps/sparc')
-rw-r--r-- | sysdeps/sparc/sparc64/dl-machine.h | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index b4f43e9cf5..4c915eb586 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. Sparc64 version. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2010 Free Software Foundation, Inc. + 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -227,7 +227,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { if (__builtin_expect (rela->r_addend, 0) != 0) { - Elf64_Addr slot = ((rela->r_offset + 0x400 + Elf64_Addr slot = ((rela->r_offset + l->l_addr + 0x400 - (Elf64_Addr) plt) / 0x1400) * 0x1400 + (Elf64_Addr) plt - 0x400; @@ -235,20 +235,23 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) unsigned int first_ldx = *(unsigned int *)(slot + 12); Elf64_Addr ptr = slot + (first_ldx & 0xfff) + 4; - *(Elf64_Addr *) rela->r_offset + *(Elf64_Addr *) (rela->r_offset + l->l_addr) = (Elf64_Addr) plt - - (slot + ((rela->r_offset - ptr) / 8) * 24 + 4); + - (slot + ((rela->r_offset + l->l_addr - ptr) / 8) * 24 + + 4); ++rela; continue; } - *(unsigned int *) rela->r_offset - = 0x03000000 | (rela->r_offset - (Elf64_Addr) plt); - *(unsigned int *) (rela->r_offset + 4) - = 0x30680000 | ((((Elf64_Addr) plt + 32 - - rela->r_offset - 4) >> 2) & 0x7ffff); - __asm __volatile ("flush %0" : : "r" (rela->r_offset)); - __asm __volatile ("flush %0+4" : : "r" (rela->r_offset)); + *(unsigned int *) (rela->r_offset + l->l_addr) + = 0x03000000 | (rela->r_offset + l->l_addr - (Elf64_Addr) plt); + *(unsigned int *) (rela->r_offset + l->l_addr + 4) + = 0x30680000 | ((((Elf64_Addr) plt + 32 - rela->r_offset + - l->l_addr - 4) >> 2) & 0x7ffff); + __asm __volatile ("flush %0" : : "r" (rela->r_offset + + l->l_addr)); + __asm __volatile ("flush %0+4" : : "r" (rela->r_offset + + l->l_addr)); ++rela; } } |