diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-20 13:40:59 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-20 13:48:06 -0800 |
commit | 5c866a8b9be0bd8dff97dd8143e55dd228617c23 (patch) | |
tree | 4ff0d2cb41595f5252997879c04baaaef02a4953 | |
parent | 1d204bf2945617be272f88ee233adbceeffd5315 (diff) | |
download | glibc-5c866a8b9be0bd8dff97dd8143e55dd228617c23.tar.gz glibc-5c866a8b9be0bd8dff97dd8143e55dd228617c23.tar.xz glibc-5c866a8b9be0bd8dff97dd8143e55dd228617c23.zip |
Fix PLT rewrite when prelinking fails on 32-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.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/dl-machine.h | 16 |
2 files changed, 15 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog index 85327329ff..cd1be57595 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-02-20 David S. Miller <davem@davemloft.net> + + * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_runtime_setup): + Adjust rela->r_offset by l->l_addr when rewriting PLT. + 2009-02-20 Joseph Myers <joseph@codesourcery.com> * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_runtime_setup): diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index e1385f7aca..53257104a6 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -166,15 +166,19 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) in .rela.plt. */ while (rela < relaend) { - *(unsigned int *) rela->r_offset - = OPCODE_SETHI_G1 | (rela->r_offset - (Elf32_Addr) plt); - *(unsigned int *) (rela->r_offset + 4) + *(unsigned int *) (rela->r_offset + l->l_addr) + = OPCODE_SETHI_G1 | (rela->r_offset + l->l_addr + - (Elf32_Addr) plt); + *(unsigned int *) (rela->r_offset + l->l_addr + 4) = OPCODE_BA | ((((Elf32_Addr) plt - - rela->r_offset - 4) >> 2) & 0x3fffff); + - rela->r_offset - l->l_addr - 4) >> 2) + & 0x3fffff); if (do_flush) { - __asm __volatile ("flush %0" : : "r"(rela->r_offset)); - __asm __volatile ("flush %0+4" : : "r"(rela->r_offset)); + __asm __volatile ("flush %0" : : "r" (rela->r_offset + + l->l_addr)); + __asm __volatile ("flush %0+4" : : "r" (rela->r_offset + + l->l_addr)); } ++rela; } |