2002-09-24 Jakub Jelinek <jakub@redhat.com>
authorroland <roland>
Fri, 27 Sep 2002 03:23:44 +0000 (03:23 +0000)
committerroland <roland>
Fri, 27 Sep 2002 03:23:44 +0000 (03:23 +0000)
* 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
sysdeps/sparc/sparc32/dl-machine.h
sysdeps/sparc/sparc64/configure
sysdeps/sparc/sparc64/configure.in
sysdeps/sparc/sparc64/dl-machine.h

index 84e1e04..581de35 100644 (file)
 /* 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
-
 /*
 \f */
 
index 72258bb..51060b6 100644 (file)
@@ -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
index 954ff7a..e69de29 100644 (file)
@@ -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
index 30b0122..e69de29 100644 (file)
@@ -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
index fba323d..802364b 100644 (file)
@@ -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