mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 16:21:06 +00:00
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:
parent
9a88a2d7b3
commit
8243d6f1b7
@ -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
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/* 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"
|
||||
__asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t"
|
||||
"call 1f\n\t"
|
||||
"or %1,%%lo(.Load_address),%1\n"
|
||||
"1:\tld [%2+%1],%1"
|
||||
: "=r"(pc), "=r"(got) : "r"(pic));
|
||||
" 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));
|
||||
|
||||
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
|
||||
|
33
sysdeps/sparc/sparc64/configure
vendored
33
sysdeps/sparc/sparc64/configure
vendored
@ -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
|
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user