diff options
-rw-r--r-- | ldso/ldso/sh/elfinterp.c | 81 |
1 files changed, 45 insertions, 36 deletions
diff --git a/ldso/ldso/sh/elfinterp.c b/ldso/ldso/sh/elfinterp.c index e094cc79b..10973c517 100644 --- a/ldso/ldso/sh/elfinterp.c +++ b/ldso/ldso/sh/elfinterp.c @@ -81,17 +81,20 @@ static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt) symtab_index = ELF32_R_SYM(rpnt->r_info); sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0"; + if(_dl_debug_symbols) + _dl_dprintf(_dl_debug_file, "\n\t"); + else + _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym); + #ifdef ELF_USES_RELOCA - _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x\taddend=%x %s", + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x", _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), rpnt->r_offset, - rpnt->r_addend, - sym); + rpnt->r_addend); #else - _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x %s", + _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n", _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), - rpnt->r_offset, - sym); + rpnt->r_offset); #endif } } @@ -121,6 +124,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) char *new_addr; char **got_addr; unsigned long instr_addr; + char *symname; rel_addr = (char *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr); @@ -130,6 +134,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); + symname = strtab + symtab[symtab_index].st_name; if (reloc_type != R_SH_JMP_SLOT) { _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", @@ -144,11 +149,14 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) /* Get the address of the GOT entry */ - new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, - tpnt->symbol_scope, tpnt, resolver); + new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, resolver); if (!new_addr) { - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", - _dl_progname, strtab + symtab[symtab_index].st_name); + new_addr = _dl_find_hash(symname, NULL, NULL, resolver); + if (new_addr) { + return (unsigned long) new_addr; + } + + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); } @@ -157,10 +165,9 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) { if (_dl_debug_bindings) { - _dl_dprintf(_dl_debug_file, "\nresolve function: %s", - strtab + symtab[symtab_index].st_name); + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname); if(_dl_debug_detail) _dl_dprintf(_dl_debug_file, - "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr); + "\n\tpatched %x ==> %x @ %x\n", *got_addr, new_addr, got_addr); } } if (!_dl_debug_nofixups) { @@ -182,7 +189,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, { unsigned int i; char *strtab; - int goof = 0; Elf32_Sym *symtab; ELF_RELOC *rpnt; int symtab_index; @@ -234,10 +240,10 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, else if (res >0) { _dl_dprintf(2, "can't resolve symbol\n"); - goof += res; + return res; } } - return goof; + return 0; } @@ -247,20 +253,23 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, { int reloc_type; int symtab_index; + char *symname; unsigned long *reloc_addr; unsigned long symbol_addr; - int goof = 0; +#if defined (__SUPPORT_LD_DEBUG__) + unsigned long old_val; +#endif reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; + symname = strtab + symtab[symtab_index].st_name; if (symtab_index) { - symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, - scope, + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, (reloc_type == R_SH_JMP_SLOT ? tpnt : NULL), symbolrel); /* @@ -269,14 +278,17 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, * here, so all bases should be covered. */ if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) { - goof++; +#if defined (__SUPPORT_LD_DEBUG__) + _dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s'\n", + symname, tpnt->libname); +#endif + return 0; } } #if defined (__SUPPORT_LD_DEBUG__) - { - unsigned long old_val = *reloc_addr; + old_val = *reloc_addr; #endif switch (reloc_type) { case R_SH_NONE: @@ -301,12 +313,10 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, } #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug_reloc && _dl_debug_detail) - _dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr); - } - + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr); #endif - return goof; + return 0; } @@ -316,6 +326,9 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, { int reloc_type; unsigned long *reloc_addr; +#if defined (__SUPPORT_LD_DEBUG__) + unsigned long old_val; +#endif (void)scope; (void)symtab; (void)strtab; @@ -324,8 +337,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, reloc_type = ELF32_R_TYPE(rpnt->r_info); #if defined (__SUPPORT_LD_DEBUG__) - { - unsigned long old_val = *reloc_addr; + old_val = *reloc_addr; #endif switch (reloc_type) { case R_SH_NONE: @@ -338,9 +350,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, } #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug_reloc && _dl_debug_detail) - _dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr); - } - + _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr); #endif return 0; @@ -363,6 +373,7 @@ _dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long *reloc_addr; unsigned long symbol_addr; int goof = 0; + char*symname; reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); @@ -370,20 +381,18 @@ _dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope, return 0; symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; + symname = strtab + symtab[symtab_index].st_name; if (symtab_index) { - symbol_addr = (unsigned long) _dl_find_hash(strtab + - symtab[symtab_index].st_name, scope, - NULL, copyrel); + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel); if (!symbol_addr) goof++; } if (!goof) { #if defined (__SUPPORT_LD_DEBUG__) if(_dl_debug_move) _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x", - strtab + symtab[symtab_index].st_name, - symtab[symtab_index].st_size, + symname, symtab[symtab_index].st_size, symbol_addr, symtab[symtab_index].st_value); #endif _dl_memcpy((char *) symtab[symtab_index].st_value, |