2000-04-17 Andreas Jaeger <aj@suse.de>

* sysdeps/mips/dl-machine.h (elf_machine_got_rel): Optimize a bit
	as suggested by Ulrich Drepper.
	(__dl_runtime_resolve): Remove unused variable, initialize sym
	directly.
	(RTLD_START): Document OFFSET_GP_GOT.
	(OFFSET_GP_GOT): New magic value.
	(elf_mips_got_from_gpreg): Use OFFSET_GP_GOT.
	(elf_machine_got_rel): Only declare strtab if needed.
This commit is contained in:
Andreas Jaeger 2000-04-17 21:22:59 +00:00
parent f80ea15d3b
commit 36af960c23
1 changed files with 21 additions and 18 deletions

View File

@ -18,6 +18,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
/* FIXME: Profiling of shared libraries is not implemented yet. */
#ifndef dl_machine_h #ifndef dl_machine_h
#define dl_machine_h #define dl_machine_h
@ -31,6 +32,10 @@
#error ENTRY_POINT needs to be defined for MIPS. #error ENTRY_POINT needs to be defined for MIPS.
#endif #endif
/* The offset of gp from GOT might be system-dependent. It's set by
ld. The same value is also */
#define OFFSET_GP_GOT 0x7ff0
#ifndef _RTLD_PROLOGUE #ifndef _RTLD_PROLOGUE
# define _RTLD_PROLOGUE(entry) "\n\t.globl " #entry \ # define _RTLD_PROLOGUE(entry) "\n\t.globl " #entry \
"\n\t.ent " #entry \ "\n\t.ent " #entry \
@ -95,7 +100,7 @@ static inline ElfW(Addr) *
elf_mips_got_from_gpreg (ElfW(Addr) gpreg) elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
{ {
/* FIXME: the offset of gp from GOT may be system-dependent. */ /* FIXME: the offset of gp from GOT may be system-dependent. */
return (ElfW(Addr) *) (gpreg - 0x7ff0); return (ElfW(Addr) *) (gpreg - OFFSET_GP_GOT);
} }
/* Return the link-time address of _DYNAMIC. Conveniently, this is the /* Return the link-time address of _DYNAMIC. Conveniently, this is the
@ -207,7 +212,7 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
_dl_runtime_resolve. MIPS instead calls __dl_runtime_resolve. We _dl_runtime_resolve. MIPS instead calls __dl_runtime_resolve. We
have to use our own version because of the way the got section is have to use our own version because of the way the got section is
treaded on MIPS (we've also got ELF_MACHINE_PLT defined). */ treaded on MIPS (we've also got ELF_MACHINE_PLT defined). */
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ #define ELF_MACHINE_RUNTIME_TRAMPOLINE \
/* The flag _dl_mips_gnu_objects is set if all dynamic objects are \ /* The flag _dl_mips_gnu_objects is set if all dynamic objects are \
generated by the gnu linker. */ \ generated by the gnu linker. */ \
@ -235,12 +240,9 @@ __dl_runtime_resolve (ElfW(Word) sym_index, \
= (const ElfW(Word)) l->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; \ = (const ElfW(Word)) l->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; \
const ElfW(Word) gotsym \ const ElfW(Word) gotsym \
= (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; \ = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; \
const ElfW(Sym) *sym; \ const ElfW(Sym) *sym = &symtab[sym_index]; \
ElfW(Addr) funcaddr; \
ElfW(Addr) value; \ ElfW(Addr) value; \
\ \
/* Look up the symbol's run-time value. */ \
sym = &symtab[sym_index]; \
/* FIXME: The symbol versioning stuff is not tested yet. */ \ /* FIXME: The symbol versioning stuff is not tested yet. */ \
if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) \ if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) \
{ \ { \
@ -279,7 +281,7 @@ __dl_runtime_resolve (ElfW(Word) sym_index, \
/* Apply the relocation with that value. */ \ /* Apply the relocation with that value. */ \
*(got + local_gotno + sym_index - gotsym) = value; \ *(got + local_gotno + sym_index - gotsym) = value; \
\ \
return value; \ return value; \
} \ } \
\ \
asm ("\n \ asm ("\n \
@ -291,6 +293,7 @@ asm ("\n \
_dl_runtime_resolve:\n \ _dl_runtime_resolve:\n \
.set noreorder\n \ .set noreorder\n \
# Save slot call pc.\n \ # Save slot call pc.\n \
# XXX: Is this ok? \
move $3, $31\n \ move $3, $31\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 \
@ -362,6 +365,7 @@ _RTLD_PROLOGUE(ENTRY_POINT)\
# the address of the dynamic structure. Though MIPS ABI\n\ # the address of the dynamic structure. Though MIPS ABI\n\
# doesn't say nothing about this, I emulate this here.\n\ # doesn't say nothing about this, I emulate this here.\n\
la $4, _DYNAMIC\n\ la $4, _DYNAMIC\n\
# Subtract OFFSET_GP_GOT\n\
sw $4, -0x7ff0($28)\n\ sw $4, -0x7ff0($28)\n\
move $4, $29\n\ move $4, $29\n\
subu $29, 16\n\ subu $29, 16\n\
@ -485,7 +489,9 @@ elf_machine_got_rel (struct link_map *map, int lazy)
ElfW(Addr) *got; ElfW(Addr) *got;
ElfW(Sym) *sym; ElfW(Sym) *sym;
int i, n, symidx; int i, n, symidx;
#ifndef RTLD_BOOTSTRAP
const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
#endif
/* This function is loaded in dl-reloc as a nested function and can /* This function is loaded in dl-reloc as a nested function and can
therefore access the variable scope from _dl_relocate_object. */ therefore access the variable scope from _dl_relocate_object. */
#ifdef RTLD_BOOTSTRAP #ifdef RTLD_BOOTSTRAP
@ -531,12 +537,12 @@ elf_machine_got_rel (struct link_map *map, int lazy)
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; 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 (map->l_addr != 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;
/* Keep track of the symbol index. */ /* Keep track of the symbol index. */
@ -544,19 +550,16 @@ elf_machine_got_rel (struct link_map *map, int lazy)
sym = (ElfW(Sym) *) D_PTR (map, l_info[DT_SYMTAB]) + symidx; sym = (ElfW(Sym) *) D_PTR (map, l_info[DT_SYMTAB]) + symidx;
i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val
- map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val); - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val);
/* This loop doesn't handle Quickstart. */
while (i--) while (i--)
{ {
if (sym->st_shndx == SHN_UNDEF) if (sym->st_shndx == SHN_UNDEF)
{ {
if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC) if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
{ && sym->st_value && lazy)
if (sym->st_value && lazy) *got = sym->st_value + map->l_addr;
*got = sym->st_value + map->l_addr; else
else
*got = RESOLVE_GOTSYM (sym, symidx);
}
else /* if (*got == 0 || *got == QS) */
*got = RESOLVE_GOTSYM (sym, symidx); *got = RESOLVE_GOTSYM (sym, symidx);
} }
else if (sym->st_shndx == SHN_COMMON) else if (sym->st_shndx == SHN_COMMON)