After reading eglibc code, I find it's much similar to uclibc ldso/ldso/mips/elfinterp.c:_dl_perform_mips_global_got_relocations. See " http://www.eglibc.org/svn/branches/eglibc-2_18/libc/ports/sysdeps/mips/dl-machine.h" elf_machine_got_rel function for more inspect. I slightly modify my last patch to speed the fixup function. Last patch: Go through the whole symtab. This patch: Go through symtab[tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX], the last item of symtab]. Actually this is the .got section. And .got section is subset of symtab.
[PATCH] MIPS: Scan the symtab for the dependency of the library to avoid runtime empty function pointer. The dependency = SHN_UNDEF && STB_GLOBAL && (STT_FUNC || STT_OBJECT) Signed-off-by: Jean Lee <[email protected]> --- ldso/ldso/mips/elfinterp.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c index dfe37c5..a83da8d 100644 --- a/ldso/ldso/mips/elfinterp.c +++ b/ldso/ldso/mips/elfinterp.c @@ -162,6 +162,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, #endif struct symbol_ref sym_ref; + ElfW(Sym) *psym = NULL; /* Now parse the relocation information */ rel_size = rel_size / sizeof(ElfW(Rel)); rpnt = (ELF_RELOC *) rel_addr; @@ -170,6 +171,33 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; got = (unsigned long *) tpnt->dynamic_info[DT_PLTGOT]; + i = tpnt->dynamic_info[DT_MIPS_SYMTABNO_IDX] - + tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; + psym = symtab + tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; + for (; i != 0; --i, ++psym) { + if (psym->st_name == 0) { + continue; + } + + if (psym->st_shndx != SHN_UNDEF + || ELF_ST_BIND(psym->st_info) != STB_GLOBAL + || (ELF_ST_TYPE(psym->st_info) != STT_FUNC + && ELF_ST_TYPE(psym->st_info) != STT_OBJECT)) { + continue; + } + symname = strtab + psym->st_name; + + sym_ref.tpnt = NULL; + sym_ref.sym = psym; + symbol_addr = (unsigned long)_dl_find_hash(symname, + scope, + tpnt, + ELF_RTYPE_CLASS_PLT, &sym_ref); + if (symbol_addr == 0) { + _dl_dprintf (2, "%s: undefined symbol: %s\n",tpnt->libname, symname); + return 1; + } + } for (i = 0; i < rel_size; i++, rpnt++) { reloc_addr = (unsigned long *) (tpnt->loadaddr + _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
