1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00

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.
This commit is contained in:
Joseph Myers
2010-02-20 13:39:58 -08:00
committed by David S. Miller
parent 199428c197
commit 1d204bf294
2 changed files with 19 additions and 11 deletions

View File

@ -1,3 +1,8 @@
2009-02-20 Joseph Myers <joseph@codesourcery.com>
* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_runtime_setup):
Adjust rela->r_offset by l->l_addr when rewriting PLT.
2010-02-19 Carl Fredrik Hammar <hammy.lite@gmail.com> 2010-02-19 Carl Fredrik Hammar <hammy.lite@gmail.com>
* hurd/hurdioctl.c (tiocsctty): Call `do_tiocsctty' instead of * hurd/hurdioctl.c (tiocsctty): Call `do_tiocsctty' instead of

View File

@ -1,6 +1,6 @@
/* Machine-dependent ELF dynamic relocation inline functions. Sparc64 version. /* Machine-dependent ELF dynamic relocation inline functions. Sparc64 version.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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) 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) - (Elf64_Addr) plt)
/ 0x1400) * 0x1400 / 0x1400) * 0x1400
+ (Elf64_Addr) plt - 0x400; + (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); unsigned int first_ldx = *(unsigned int *)(slot + 12);
Elf64_Addr ptr = slot + (first_ldx & 0xfff) + 4; Elf64_Addr ptr = slot + (first_ldx & 0xfff) + 4;
*(Elf64_Addr *) rela->r_offset *(Elf64_Addr *) (rela->r_offset + l->l_addr)
= (Elf64_Addr) plt = (Elf64_Addr) plt
- (slot + ((rela->r_offset - ptr) / 8) * 24 + 4); - (slot + ((rela->r_offset + l->l_addr - ptr) / 8) * 24
+ 4);
++rela; ++rela;
continue; continue;
} }
*(unsigned int *) rela->r_offset *(unsigned int *) (rela->r_offset + l->l_addr)
= 0x03000000 | (rela->r_offset - (Elf64_Addr) plt); = 0x03000000 | (rela->r_offset + l->l_addr - (Elf64_Addr) plt);
*(unsigned int *) (rela->r_offset + 4) *(unsigned int *) (rela->r_offset + l->l_addr + 4)
= 0x30680000 | ((((Elf64_Addr) plt + 32 = 0x30680000 | ((((Elf64_Addr) plt + 32 - rela->r_offset
- rela->r_offset - 4) >> 2) & 0x7ffff); - l->l_addr - 4) >> 2) & 0x7ffff);
__asm __volatile ("flush %0" : : "r" (rela->r_offset)); __asm __volatile ("flush %0" : : "r" (rela->r_offset
__asm __volatile ("flush %0+4" : : "r" (rela->r_offset)); + l->l_addr));
__asm __volatile ("flush %0+4" : : "r" (rela->r_offset
+ l->l_addr));
++rela; ++rela;
} }
} }