mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-07 06:43:00 +03:00
Update.
2001-09-29 Jes Sorensen <jes@trained-monkey.org> * sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h (struct sigcontext): Add sc_loadrs and sc_rbs_bas to match current kernel. 2001-09-27 Jakub Jelinek <jakub@redhat.com> * sysdeps/sparc/sparc64/fpu/libm-test-ulps: Update. * sysdeps/ieee754/ldbl-128/s_erfl.c (__erfcl): Fix erfc(-inf). 2001-09-27 Jakub Jelinek <jakub@redhat.com> * elf/dl-open.c (dl_open_worker): If l_opencount of freshly loaded object has been bumped because of relocation dependency, avoid duplicates in l_scope. (show_scope): Fix typos. * elf/Makefile: Add rules to build and run reldep6. * elf/reldep6.c: New file. * elf/reldep6mod0.c: New file. * elf/reldep6mod1.c: New file. * elf/reldep6mod2.c: New file. * elf/reldep6mod3.c: New file. * elf/reldep6mod4.c: New file. 2001-09-26 Jakub Jelinek <jakub@redhat.com> * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_fixup_plt): Call sparc64_fixup_plt. (sparc64_fixup_plt): Moved from elf_machine_fixup_plt. Optimize near jumps and 0xfffff800XXXXXXXX target addresses, no thread safety for non-lazy binding. Fix .plt[32768+] handling. (elf_machine_plt_value): Don't add addend. (elf_machine_rela): Call sparc64_fixup_plt instead of elf_machine_fixup_plt. (elf_machine_runtime_setup, TRAMPOLINE_TEMPLATE): Optimize for dynamic linker at 0xfffff800XXXXXXXX. * sysdeps/sparc/sparc32/fpu/libm-test-ulps: Update.
This commit is contained in:
@@ -84,41 +84,51 @@ elf_machine_load_address (void)
|
||||
|
||||
/* We have 4 cases to handle. And we code different code sequences
|
||||
for each one. I love V9 code models... */
|
||||
static inline Elf64_Addr
|
||||
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
const Elf64_Rela *reloc,
|
||||
Elf64_Addr *reloc_addr, Elf64_Addr value)
|
||||
static inline void
|
||||
sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc,
|
||||
Elf64_Addr *reloc_addr, Elf64_Addr value,
|
||||
Elf64_Addr high, int t)
|
||||
{
|
||||
unsigned int *insns = (unsigned int *) reloc_addr;
|
||||
Elf64_Addr plt_vaddr = (Elf64_Addr) reloc_addr;
|
||||
Elf64_Sxword disp = value - plt_vaddr;
|
||||
|
||||
/* Now move plt_vaddr up to the call instruction. */
|
||||
plt_vaddr += (2 * 4);
|
||||
plt_vaddr += ((t + 1) * 4);
|
||||
|
||||
/* PLT entries .PLT32768 and above look always the same. */
|
||||
if (__builtin_expect (reloc->r_addend, 0) != 0)
|
||||
if (__builtin_expect (high, 0) != 0)
|
||||
{
|
||||
*reloc_addr = value - map->l_addr;
|
||||
}
|
||||
/* Near destination. */
|
||||
else if (disp >= -0x800000 && disp < 0x800000)
|
||||
{
|
||||
/* As this is just one instruction, it is thread safe and so
|
||||
we can avoid the unnecessary sethi FOO, %g1.
|
||||
b,a target */
|
||||
insns[0] = 0x30800000 | ((disp >> 2) & 0x3fffff);
|
||||
__asm __volatile ("flush %0" : : "r" (insns));
|
||||
}
|
||||
/* 32-bit Sparc style, the target is in the lower 32-bits of
|
||||
address space. */
|
||||
else if ((value >> 32) == 0)
|
||||
else if (insns += t, (value >> 32) == 0)
|
||||
{
|
||||
/* sethi %hi(target), %g1
|
||||
jmpl %g1 + %lo(target), %g0 */
|
||||
|
||||
insns[2] = 0x81c06000 | (value & 0x3ff);
|
||||
__asm __volatile ("flush %0 + 8" : : "r" (insns));
|
||||
|
||||
insns[1] = 0x03000000 | ((unsigned int)(value >> 10));
|
||||
insns[1] = 0x81c06000 | (value & 0x3ff);
|
||||
__asm __volatile ("flush %0 + 4" : : "r" (insns));
|
||||
|
||||
insns[0] = 0x03000000 | ((unsigned int)(value >> 10));
|
||||
__asm __volatile ("flush %0" : : "r" (insns));
|
||||
}
|
||||
/* We can also get somewhat simple sequences if the distance between
|
||||
the target and the PLT entry is within +/- 2GB. */
|
||||
else if ((plt_vaddr > value
|
||||
&& ((plt_vaddr - value) >> 32) == 0)
|
||||
&& ((plt_vaddr - value) >> 31) == 0)
|
||||
|| (value > plt_vaddr
|
||||
&& ((value - plt_vaddr) >> 32) == 0))
|
||||
&& ((value - plt_vaddr) >> 31) == 0))
|
||||
{
|
||||
unsigned int displacement;
|
||||
|
||||
@@ -131,14 +141,14 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
call displacement
|
||||
mov %g1, %o7 */
|
||||
|
||||
insns[3] = 0x9e100001;
|
||||
__asm __volatile ("flush %0 + 12" : : "r" (insns));
|
||||
|
||||
insns[2] = 0x40000000 | (displacement >> 2);
|
||||
insns[2] = 0x9e100001;
|
||||
__asm __volatile ("flush %0 + 8" : : "r" (insns));
|
||||
|
||||
insns[1] = 0x8210000f;
|
||||
insns[1] = 0x40000000 | (displacement >> 2);
|
||||
__asm __volatile ("flush %0 + 4" : : "r" (insns));
|
||||
|
||||
insns[t] = 0x8210000f;
|
||||
__asm __volatile ("flush %0" : : "r" (insns));
|
||||
}
|
||||
/* Worst case, ho hum... */
|
||||
else
|
||||
@@ -149,33 +159,62 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
/* ??? Some tricks can be stolen from the sparc64 egcs backend
|
||||
constant formation code I wrote. -DaveM */
|
||||
|
||||
/* sethi %hh(value), %g1
|
||||
sethi %lm(value), %g5
|
||||
or %g1, %hm(value), %g1
|
||||
or %g5, %lo(value), %g5
|
||||
sllx %g1, 32, %g1
|
||||
jmpl %g1 + %g5, %g0
|
||||
nop */
|
||||
if (__builtin_expect (high32 & 0x3ff, 0))
|
||||
{
|
||||
/* sethi %hh(value), %g1
|
||||
sethi %lm(value), %g5
|
||||
or %g1, %hm(value), %g1
|
||||
or %g5, %lo(value), %g5
|
||||
sllx %g1, 32, %g1
|
||||
jmpl %g1 + %g5, %g0
|
||||
nop */
|
||||
|
||||
insns[6] = 0x81c04005;
|
||||
__asm __volatile ("flush %0 + 24" : : "r" (insns));
|
||||
insns[5] = 0x81c04005;
|
||||
__asm __volatile ("flush %0 + 20" : : "r" (insns));
|
||||
|
||||
insns[5] = 0x83287020;
|
||||
__asm __volatile ("flush %0 + 20" : : "r" (insns));
|
||||
insns[4] = 0x83287020;
|
||||
__asm __volatile ("flush %0 + 16" : : "r" (insns));
|
||||
|
||||
insns[4] = 0x8a116000 | (low32 & 0x3ff);
|
||||
__asm __volatile ("flush %0 + 16" : : "r" (insns));
|
||||
insns[3] = 0x8a116000 | (low32 & 0x3ff);
|
||||
__asm __volatile ("flush %0 + 12" : : "r" (insns));
|
||||
|
||||
insns[3] = 0x82106000 | (high32 & 0x3ff);
|
||||
__asm __volatile ("flush %0 + 12" : : "r" (insns));
|
||||
insns[2] = 0x82106000 | (high32 & 0x3ff);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* sethi %hh(value), %g1
|
||||
sethi %lm(value), %g5
|
||||
sllx %g1, 32, %g1
|
||||
or %g5, %lo(value), %g5
|
||||
jmpl %g1 + %g5, %g0
|
||||
nop */
|
||||
|
||||
insns[4] = 0x81c04005;
|
||||
__asm __volatile ("flush %0 + 16" : : "r" (insns));
|
||||
|
||||
insns[3] = 0x8a116000 | (low32 & 0x3ff);
|
||||
__asm __volatile ("flush %0 + 12" : : "r" (insns));
|
||||
|
||||
insns[2] = 0x83287020;
|
||||
}
|
||||
|
||||
insns[2] = 0x0b000000 | (low32 >> 10);
|
||||
__asm __volatile ("flush %0 + 8" : : "r" (insns));
|
||||
|
||||
insns[1] = 0x03000000 | (high32 >> 10);
|
||||
insns[1] = 0x0b000000 | (low32 >> 10);
|
||||
__asm __volatile ("flush %0 + 4" : : "r" (insns));
|
||||
}
|
||||
|
||||
insns[0] = 0x03000000 | (high32 >> 10);
|
||||
__asm __volatile ("flush %0" : : "r" (insns));
|
||||
}
|
||||
}
|
||||
|
||||
static inline Elf64_Addr
|
||||
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
const Elf64_Rela *reloc,
|
||||
Elf64_Addr *reloc_addr, Elf64_Addr value)
|
||||
{
|
||||
sparc64_fixup_plt (map, reloc, reloc_addr, value + reloc->r_addend,
|
||||
reloc->r_addend, 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -184,7 +223,10 @@ static inline Elf64_Addr
|
||||
elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
|
||||
Elf64_Addr value)
|
||||
{
|
||||
return value + reloc->r_addend;
|
||||
/* Don't add addend here, but in elf_machine_fixup_plt instead.
|
||||
value + reloc->r_addend is the value which should actually be
|
||||
stored into .plt data slot. */
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifdef RESOLVE
|
||||
@@ -329,7 +371,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
|
||||
break;
|
||||
#endif
|
||||
case R_SPARC_JMP_SLOT:
|
||||
elf_machine_fixup_plt(map, 0, reloc, reloc_addr, value);
|
||||
sparc64_fixup_plt (map, reloc, reloc_addr, value,
|
||||
reloc->r_addend, 0);
|
||||
break;
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
case R_SPARC_UA16:
|
||||
@@ -425,6 +468,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
extern void _dl_runtime_profile_1 (void);
|
||||
Elf64_Addr res0_addr, res1_addr;
|
||||
unsigned int *plt = (void *) D_PTR (l, l_info[DT_PLTGOT]);
|
||||
int i = 0;
|
||||
|
||||
if (! profile)
|
||||
{
|
||||
@@ -473,13 +517,21 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
*/
|
||||
|
||||
plt[8 + 0] = 0x9de3bf40;
|
||||
if (__builtin_expect (((res1_addr + 4) >> 32) & 0x3ff, 0))
|
||||
i = 1;
|
||||
else
|
||||
res1_addr += 4;
|
||||
plt[8 + 1] = 0x21000000 | (res1_addr >> (64 - 22));
|
||||
plt[8 + 2] = 0x23000000 | ((res1_addr >> 10) & 0x003fffff);
|
||||
plt[8 + 3] = 0xa0142000 | ((res1_addr >> 32) & 0x3ff);
|
||||
if (__builtin_expect (i, 0))
|
||||
plt[8 + 3] = 0xa0142000 | ((res1_addr >> 32) & 0x3ff);
|
||||
else
|
||||
plt[8 + 3] = 0xa12c3020;
|
||||
plt[8 + 4] = 0xa2146000 | (res1_addr & 0x3ff);
|
||||
plt[8 + 5] = 0xa12c3020;
|
||||
plt[8 + 6] = 0xadc40011;
|
||||
plt[8 + 7] = 0x9330700c;
|
||||
if (__builtin_expect (i, 0))
|
||||
plt[8 + 5] = 0xa12c3020;
|
||||
plt[8 + 5 + i] = 0xadc40011;
|
||||
plt[8 + 6 + i] = 0x9330700c;
|
||||
|
||||
/* Now put the magic cookie at the beginning of .PLT2
|
||||
Entry .PLT3 is unused by this implementation. */
|
||||
@@ -526,10 +578,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
"\n" \
|
||||
" .globl " #tramp_name "_1\n" \
|
||||
" .type " #tramp_name "_1, @function\n" \
|
||||
" .align 32\n" \
|
||||
" ! tramp_name_1 + 4 needs to be .align 32\n" \
|
||||
"\t" #tramp_name "_1:\n" \
|
||||
" sub %l6, 4, %l6\n" \
|
||||
" ! srlx %g1, 12, %o1 - Done in .PLT1\n" \
|
||||
" ldx [%l6 + 8], %o0\n" \
|
||||
" ldx [%l6 + 12], %o0\n" \
|
||||
" add %o1, %o1, %o3\n" \
|
||||
" sub %o1, 96, %o1 ! No thanks to Sun for not obeying their own ABI\n" \
|
||||
" mov %i7, %o2\n" \
|
||||
|
Reference in New Issue
Block a user