2000-10-18 Andreas Jaeger <aj@suse.de>
* sysdeps/mips/dl-machine.h (ELF_MIPS_GNU_GOT1_OK): New. (ELF_MACHINE_BEFORE_RTLD_RELOC): Handle newer linkers. (elf_machine_runtime_link_map): Likewise. (elf_machine_runtime_setup): Likewise. Handle dynamic linker's local got entries. Patches by Ralf Baechle <ralf@gnu.org>. 2000-10-09 Maciej W. Rozycki <macro@ds2.pg.gda.pl> * sysdeps/mips/dl-machine.h (_dl_runtime_resolve): Define $sp as the frame pointer. Allocate stack space for $a0 for __dl_runtime_resolve(). Do not save $sp in $s0 as it's callee-saved anyway.
This commit is contained in:
parent
deda4d1a4e
commit
c9f4ffcf5a
@ -138,6 +138,10 @@ elf_machine_load_address (void)
|
|||||||
/* The MSB of got[1] of a gnu object is set to identify gnu objects. */
|
/* The MSB of got[1] of a gnu object is set to identify gnu objects. */
|
||||||
#define ELF_MIPS_GNU_GOT1_MASK 0x80000000
|
#define ELF_MIPS_GNU_GOT1_MASK 0x80000000
|
||||||
|
|
||||||
|
/* GNU Binutils upto 2.10 produce a wrong relocations. Bit 30 of
|
||||||
|
got[1] marks good objects. */
|
||||||
|
#define ELF_MIPS_GNU_GOT1_OK 0x00000001
|
||||||
|
|
||||||
/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
|
/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
|
||||||
fiddles with global data. */
|
fiddles with global data. */
|
||||||
#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
|
#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
|
||||||
@ -149,6 +153,9 @@ do { \
|
|||||||
\
|
\
|
||||||
got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); \
|
got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); \
|
||||||
\
|
\
|
||||||
|
if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0) \
|
||||||
|
got[1] = (ElfW(Addr)) ELF_MIPS_GNU_GOT1_MASK \
|
||||||
|
| (got[1] & ELF_MIPS_GNU_GOT1_OK); \
|
||||||
\
|
\
|
||||||
if (__builtin_expect (map->l_addr == 0, 1)) \
|
if (__builtin_expect (map->l_addr == 0, 1)) \
|
||||||
goto done; \
|
goto done; \
|
||||||
@ -212,8 +219,8 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
|
|||||||
|
|
||||||
if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
|
if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
|
||||||
{
|
{
|
||||||
struct link_map *l =
|
struct link_map *l = (struct link_map *)
|
||||||
(struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
|
(g1 & ~(ELF_MIPS_GNU_GOT1_MASK|ELF_MIPS_GNU_GOT1_OK));
|
||||||
ElfW(Addr) base, limit;
|
ElfW(Addr) base, limit;
|
||||||
const ElfW(Phdr) *p = l->l_phdr;
|
const ElfW(Phdr) *p = l->l_phdr;
|
||||||
ElfW(Half) this, nent = l->l_phnum;
|
ElfW(Half) this, nent = l->l_phnum;
|
||||||
@ -352,11 +359,12 @@ asm ("\n \
|
|||||||
.type _dl_runtime_resolve,@function\n \
|
.type _dl_runtime_resolve,@function\n \
|
||||||
.ent _dl_runtime_resolve\n \
|
.ent _dl_runtime_resolve\n \
|
||||||
_dl_runtime_resolve:\n \
|
_dl_runtime_resolve:\n \
|
||||||
|
.frame $29, 40, $31\n \
|
||||||
.set noreorder\n \
|
.set noreorder\n \
|
||||||
# Save GP.\n \
|
# Save GP.\n \
|
||||||
move $3, $28\n \
|
move $3, $28\n \
|
||||||
# Modify t9 ($25) so as to point .cpload instruction.\n \
|
# Modify t9 ($25) so as to point .cpload instruction.\n \
|
||||||
addu $25,8\n \
|
addu $25, 8\n \
|
||||||
# Compute GP.\n \
|
# Compute GP.\n \
|
||||||
.cpload $25\n \
|
.cpload $25\n \
|
||||||
.set reorder\n \
|
.set reorder\n \
|
||||||
@ -366,24 +374,20 @@ _dl_runtime_resolve:\n \
|
|||||||
subu $29, 40\n \
|
subu $29, 40\n \
|
||||||
.cprestore 32\n \
|
.cprestore 32\n \
|
||||||
sw $15, 36($29)\n \
|
sw $15, 36($29)\n \
|
||||||
sw $4, 12($29)\n \
|
sw $4, 16($29)\n \
|
||||||
sw $5, 16($29)\n \
|
sw $5, 20($29)\n \
|
||||||
sw $6, 20($29)\n \
|
sw $6, 24($29)\n \
|
||||||
sw $7, 24($29)\n \
|
sw $7, 28($29)\n \
|
||||||
sw $16, 28($29)\n \
|
|
||||||
move $16, $29\n \
|
|
||||||
move $4, $24\n \
|
move $4, $24\n \
|
||||||
move $5, $15\n \
|
move $5, $15\n \
|
||||||
move $6, $3\n \
|
move $6, $3\n \
|
||||||
move $7, $2\n \
|
move $7, $2\n \
|
||||||
jal __dl_runtime_resolve\n \
|
jal __dl_runtime_resolve\n \
|
||||||
move $29, $16\n \
|
|
||||||
lw $31, 36($29)\n \
|
lw $31, 36($29)\n \
|
||||||
lw $4, 12($29)\n \
|
lw $4, 16($29)\n \
|
||||||
lw $5, 16($29)\n \
|
lw $5, 20($29)\n \
|
||||||
lw $6, 20($29)\n \
|
lw $6, 24($29)\n \
|
||||||
lw $7, 24($29)\n \
|
lw $7, 28($29)\n \
|
||||||
lw $16, 28($29)\n \
|
|
||||||
addu $29, 40\n \
|
addu $29, 40\n \
|
||||||
move $25, $2\n \
|
move $25, $2\n \
|
||||||
jr $25\n \
|
jr $25\n \
|
||||||
@ -580,16 +584,21 @@ elf_machine_got_rel (struct link_map *map, int lazy)
|
|||||||
|
|
||||||
got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
|
got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
|
||||||
|
|
||||||
|
n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
|
||||||
|
/* The dynamic linker's local got entries have already been relocated. */
|
||||||
|
if (map != &_dl_rtld_map)
|
||||||
|
{
|
||||||
/* got[0] is reserved. got[1] is also reserved for the dynamic object
|
/* got[0] is reserved. got[1] is also reserved for the dynamic object
|
||||||
generated by gnu ld. Skip these reserved entries from relocation. */
|
generated by gnu ld. Skip these reserved entries from relocation. */
|
||||||
i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
|
i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
|
||||||
n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
|
|
||||||
/* Add the run-time display to all local got entries if needed. */
|
/* Add the run-time display to all local got entries if needed. */
|
||||||
if (__builtin_expect (map->l_addr != 0, 0))
|
if (__builtin_expect (map->l_addr != 0, 0))
|
||||||
{
|
{
|
||||||
while (i < n)
|
while (i < n)
|
||||||
got[i++] += map->l_addr;
|
got[i++] += map->l_addr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle global got entries. */
|
/* Handle global got entries. */
|
||||||
got += n;
|
got += n;
|
||||||
@ -661,7 +670,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
|||||||
of got[1] of a gnu object is set to identify gnu objects.
|
of got[1] of a gnu object is set to identify gnu objects.
|
||||||
Where we can store l for non gnu objects? XXX */
|
Where we can store l for non gnu objects? XXX */
|
||||||
if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0)
|
if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0)
|
||||||
got[1] = (ElfW(Addr)) ((unsigned) l | ELF_MIPS_GNU_GOT1_MASK);
|
got[1] = (ElfW(Addr)) ((unsigned) l | ELF_MIPS_GNU_GOT1_MASK
|
||||||
|
| (got[1] & ELF_MIPS_GNU_GOT1_OK));
|
||||||
else
|
else
|
||||||
_dl_mips_gnu_objects = 0;
|
_dl_mips_gnu_objects = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user