static int _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long rel_addr, unsigned long rel_size, int (*reloc_fnc)(struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { int symtab_index; unsigned int i; char *strtab; Elf32_Sym *symtab; ELF_RELOC *rpnt; /* Parse the relocation information. */ rpnt = (ELF_RELOC *)(intptr_t)rel_addr; rel_size /= sizeof(ELF_RELOC); symtab = (Elf32_Sym *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB]; strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; for (i = 0; i < rel_size; i++, rpnt++) { int res; symtab_index = ELF32_R_SYM(rpnt->r_info); debug_sym(symtab, strtab, symtab_index); debug_reloc(symtab, strtab, rpnt); /* Pass over to actual relocation function. */ res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab); if (res == 0) continue; _dl_dprintf(2, "\n%s: ", _dl_progname); if (symtab_index) _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name); if (unlikely(res < 0)) { int reloc_type = ELF32_R_TYPE(rpnt->r_info); #if defined (__SUPPORT_LD_DEBUG__) _dl_dprintf(2, "can't handle reloc type %s\n", _dl_reltypes(reloc_type)); #else _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type); #endif _dl_exit(-res); } else if (unlikely(res > 0)) { _dl_dprintf(2, "can't resolve symbol\n"); return res; } } return 0; }
static int _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long rel_addr, unsigned long rel_size, int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { unsigned int i; char *strtab; int goof = 0; Elf32_Sym *symtab; ELF_RELOC *rpnt; int symtab_index; /* Now parse the relocation information */ rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr); rel_size = rel_size / sizeof(ELF_RELOC); symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); for (i = 0; i < rel_size; i++, rpnt++) { int res; symtab_index = ELF32_R_SYM(rpnt->r_info); /* When the dynamic linker bootstrapped itself, it resolved some symbols. Make sure we do not do them again */ if (!symtab_index && tpnt->libtype == program_interpreter) continue; if (symtab_index && tpnt->libtype == program_interpreter && _dl_symbol(strtab + symtab[symtab_index].st_name)) continue; #if defined (__SUPPORT_LD_DEBUG__) debug_sym(symtab,strtab,symtab_index); debug_reloc(symtab,strtab,rpnt); #endif res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab); if (res==0) continue; _dl_dprintf(2, "\n%s: ",_dl_progname); if (symtab_index) _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name); if (res <0) { int reloc_type = ELF32_R_TYPE(rpnt->r_info); #if defined (__SUPPORT_LD_DEBUG__) _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type)); #else _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type); #endif _dl_exit(-res); } else if (res >0) { _dl_dprintf(2, "can't resolve symbol\n"); goof += res; } } return goof; }