From 1d204bf2945617be272f88ee233adbceeffd5315 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Sat, 20 Feb 2010 13:39:58 -0800 Subject: 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. --- ChangeLog | 5 +++++ sysdeps/sparc/sparc64/dl-machine.h | 25 ++++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1044b4de65..85327329ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-02-20 Joseph Myers + + * 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 * hurd/hurdioctl.c (tiocsctty): Call `do_tiocsctty' instead of 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; } } -- cgit 1.4.1