From 8243d6f1b70a506419329c81d862b80e9104ca9b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 27 Sep 2002 03:23:45 +0000 Subject: [PATCH] 2002-09-24 Jakub Jelinek * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_load_address): Don't rely on *r_offset of R_SPARC_RELATIVE reloc in .got to contain the addend. * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_load_address): Use the same l_addr computation. * sysdeps/sparc/sparc64/configure.in: Removed. * sysdeps/sparc/sparc64/configure: Removed. * config.h.in (SPARC64_DYNAMIC_BEFORE_GOT): Remove. --- config.h.in | 4 --- sysdeps/sparc/sparc32/dl-machine.h | 29 ++++++++++----------- sysdeps/sparc/sparc64/configure | 33 ------------------------ sysdeps/sparc/sparc64/configure.in | 26 ------------------- sysdeps/sparc/sparc64/dl-machine.h | 53 +++++++++++--------------------------- 5 files changed, 29 insertions(+), 116 deletions(-) rewrite sysdeps/sparc/sparc64/configure (100%) rewrite sysdeps/sparc/sparc64/configure.in (100%) diff --git a/config.h.in b/config.h.in index 84e1e04a73..581de35208 100644 --- a/config.h.in +++ b/config.h.in @@ -175,10 +175,6 @@ /* Mach/i386 specific: define if the `i386_io_perm_*' RPCs are available. */ #undef HAVE_I386_IO_PERM_MODIFY -/* Sparc64 specific: define if .dynamic section comes before .got for - shared libs. */ -#undef SPARC64_DYNAMIC_BEFORE_GOT - /* */ diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index 72258bbf16..51060b652a 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -101,21 +101,20 @@ elf_machine_dynamic (void) static inline Elf32_Addr elf_machine_load_address (void) { - register Elf32_Addr pc __asm("%o7"), pic __asm("%l7"), got; - - LOAD_PIC_REG (pic); - - /* Utilize the fact that a local .got entry will be partially - initialized at startup awaiting its RELATIVE fixup. */ - - __asm("sethi %%hi(.Load_address),%1\n" - ".Load_address:\n\t" - "call 1f\n\t" - "or %1,%%lo(.Load_address),%1\n" - "1:\tld [%2+%1],%1" - : "=r"(pc), "=r"(got) : "r"(pic)); - - return pc - got; + register Elf32_Addr *pc __asm ("%o7"), *got __asm ("%l7"); + + __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" + "call 1f\n\t" + " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" + "call _DYNAMIC\n\t" + "call _GLOBAL_OFFSET_TABLE_\n" + "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got)); + + /* got is now l_addr + _GLOBAL_OFFSET_TABLE_ + *got is _DYNAMIC + pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8 + pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12 */ + return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4; } /* Set up the loaded object described by L so its unrelocated PLT diff --git a/sysdeps/sparc/sparc64/configure b/sysdeps/sparc/sparc64/configure dissimilarity index 100% index 954ff7a03d..e69de29bb2 100644 --- a/sysdeps/sparc/sparc64/configure +++ b/sysdeps/sparc/sparc64/configure @@ -1,33 +0,0 @@ - # Local configure fragment for sysdeps/sparc/sparc64. - -# Check whether .got section comes before or after .dynamic -echo $ac_n "checking where sparc64 .dynamic section comes before .got""... $ac_c" 1>&6 -echo "configure:6: checking where sparc64 .dynamic section comes before .got" >&5 -if eval "test \"`echo '$''{'libc_cv_sparc64_dynamic_before_got'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - -${CC-cc} $CFLAGS -shared -Wl,--verbose 2>&1 \ - | grep '^[ ]*\.\(got\|dynamic\)[^A-Za-z0-9_]' > conftest.order - -if test `cat conftest.order | wc -l` != 2; then - { echo "configure: error: Couldn't figure .got/.dynamic relative placement" 1>&2; exit 1; } -else - - if head -n 1 conftest.order | grep '^[ ]*\.got'; then - libc_cv_sparc64_dynamic_before_got=no - else - libc_cv_sparc64_dynamic_before_got=yes - fi - -fi -rm -f conftest* -fi - -echo "$ac_t""$libc_cv_sparc64_dynamic_before_got" 1>&6 -if test $libc_cv_sparc64_dynamic_before_got = yes; then - cat >> confdefs.h <<\EOF -#define SPARC64_DYNAMIC_BEFORE_GOT 1 -EOF - -fi diff --git a/sysdeps/sparc/sparc64/configure.in b/sysdeps/sparc/sparc64/configure.in dissimilarity index 100% index 30b012205b..e69de29bb2 100644 --- a/sysdeps/sparc/sparc64/configure.in +++ b/sysdeps/sparc/sparc64/configure.in @@ -1,26 +0,0 @@ -sinclude(./aclocal.m4)dnl Autoconf lossage -GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. -# Local configure fragment for sysdeps/sparc/sparc64. - -# Check whether .got section comes before or after .dynamic -AC_CACHE_CHECK(where sparc64 .dynamic section comes before .got, - libc_cv_sparc64_dynamic_before_got, [dnl -changequote(,) -${CC-cc} $CFLAGS -shared -Wl,--verbose 2>&1 \ - | grep '^[ ]*\.\(got\|dynamic\)[^A-Za-z0-9_]' > conftest.order -changequote([,]) -if test `cat conftest.order | wc -l` != 2; then - AC_ERROR(Couldn't figure .got/.dynamic relative placement) -else - changequote(,) - if head -n 1 conftest.order | grep '^[ ]*\.got'; then - libc_cv_sparc64_dynamic_before_got=no - else - libc_cv_sparc64_dynamic_before_got=yes - fi - changequote([,]) -fi -rm -f conftest*]) -if test $libc_cv_sparc64_dynamic_before_got = yes; then - AC_DEFINE(SPARC64_DYNAMIC_BEFORE_GOT) -fi diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index fba323dece..802364b662 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -68,44 +68,21 @@ elf_machine_dynamic (void) static inline Elf64_Addr elf_machine_load_address (void) { - register Elf64_Addr *elf_pic_register __asm__("%l7"); - - LOAD_PIC_REG (elf_pic_register); - - /* We used to utilize the fact that a local .got entry will - be partially initialized at startup awaiting its RELATIVE - fixup: - - Elf64_Addr pc, la; - - __asm("sethi %%hi(.Load_address), %1\n" - ".Load_address:\n\t" - "rd %%pc, %0\n\t" - "or %1, %%lo(.Load_address), %1\n\t" - : "=r"(pc), "=r"(la)); - - return pc - *(Elf64_Addr *)(elf_pic_register + la); - - Unfortunately as binutils tries to work around Solaris - dynamic linker bug which resolves R_SPARC_RELATIVE as X += B + A - instead of X = B + A this does not work any longer, since ld - clears it. - - The following method relies on the fact that sparcv9 ABI maximal - page length is 1MB and all ELF segments on sparc64 are aligned - to 1MB. Also assumes that they both fit into the first 1MB of - the RW segment. This should be true for some time unless ld.so - grows too much, at the moment the whole stripped ld.so is 128KB - and only smaller part of that is in the RW segment. */ - -#ifdef SPARC64_DYNAMIC_BEFORE_GOT - /* If _DYNAMIC comes before _GLOBAL_OFFSET_TABLE_... */ - return ((Elf64_Addr)elf_pic_register - *elf_pic_register) & ~0xfffffUL; -#else - /* ... and if _DYNAMIC comes after _GLOBAL_OFFSET_TABLE_. */ - return ((Elf64_Addr)elf_pic_register - *elf_pic_register + 0xfffff) - & ~0xfffffUL; -#endif + register Elf32_Addr *pc __asm ("%o7"); + register Elf64_Addr *got __asm ("%l7"); + + __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" + "call 1f\n\t" + " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" + "call _DYNAMIC\n\t" + "call _GLOBAL_OFFSET_TABLE_\n" + "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got)); + + /* got is now l_addr + _GLOBAL_OFFSET_TABLE_ + *got is _DYNAMIC + pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8 + pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12 */ + return (Elf64_Addr) got - *got + (Elf32_Sword) ((pc[2] - pc[3]) * 4) - 4; } /* We have 4 cases to handle. And we code different code sequences -- 2.11.4.GIT