2002-09-24 Jakub Jelinek <jakub@redhat.com>

* 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.
This commit is contained in:
Roland McGrath 2002-09-27 03:23:45 +00:00
parent 9a88a2d7b3
commit 8243d6f1b7
5 changed files with 25 additions and 112 deletions

View file

@ -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
/*
*/

View 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;
register Elf32_Addr *pc __asm ("%o7"), *got __asm ("%l7");
LOAD_PIC_REG (pic);
__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));
/* 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;
/* 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

View 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

View 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

View 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");
register Elf32_Addr *pc __asm ("%o7");
register Elf64_Addr *got __asm ("%l7");
LOAD_PIC_REG (elf_pic_register);
__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));
/* 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
/* 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