void SymElf::init() { if (elf->e_machine() == EM_PPC64) { unsigned short stridx = elf->e_shstrndx(); Elf_X_Shdr strshdr = elf->get_shdr(stridx); Elf_X_Data strdata = strshdr.get_data(); const char *names = (const char *) strdata.d_buf(); for (unsigned i=0; i < elf->e_shnum(); i++) { Elf_X_Shdr &shdr = elf->get_shdr(i); if (strcmp(names + shdr.sh_name(), ".opd") != 0) continue; odp_section = & shdr; need_odp = true; break; } } }
Symbol_t SymElf::getSymbolByName(std::string symname) { Symbol_t ret; for (unsigned i=0; i < elf->e_shnum(); i++) { Elf_X_Shdr shdr = elf->get_shdr(i); if (shdr.sh_type() != SHT_SYMTAB && shdr.sh_type() != SHT_DYNSYM) { continue; } FOR_EACH_SYMBOL(shdr, symbol, str_buffer, idx) { unsigned str_loc = symbol.st_name(idx); if (strcmp(str_buffer+str_loc, symname.c_str()) != 0) continue; if (symbol.st_shndx(idx) == 0) { continue; } MAKE_SYMBOL(str_buffer+str_loc, idx, shdr, ret); return ret; } }
// findFunctionIn_ld_so_1: this routine finds the symbol table for ld.so.1 and // parses it to find the address of symbol r_debug // it returns false on error bool dynamic_linking::findFunctionIn_ld_so_1(pdstring f_name, int ld_fd, Address ld_base_addr, Address *f_addr, int st_type) { bool result = false; Elf_X elf; Elf_X_Shdr shstrscn; Elf_X_Data shstrdata; Elf_X_Shdr symscn; Elf_X_Shdr strscn; Elf_X_Data symdata; Elf_X_Data strdata; const char *shnames = NULL; lseek(ld_fd, 0, SEEK_SET); elf = Elf_X(ld_fd, ELF_C_READ); if (elf.isValid()) shstrscn = elf.get_shdr( elf.e_shstrndx() ); if (shstrscn.isValid()) shstrdata = shstrscn.get_data(); if (shstrdata.isValid()) shnames = shstrdata.get_string(); if (elf.isValid() && shstrscn.isValid() && shstrdata.isValid()) { for (int i = 0; i < elf.e_shnum(); ++i) { Elf_X_Shdr shdr = elf.get_shdr(i); if (!shdr.isValid()) return false; const char* name = (const char *) &shnames[shdr.sh_name()]; if (P_strcmp(name, ".symtab") == 0) { symscn = shdr; } else if (P_strcmp(name, ".strtab") == 0) { strscn = shdr; } } if (strscn.isValid()) symdata = symscn.get_data(); if (symscn.isValid()) strdata = strscn.get_data(); if (symdata.isValid() && strdata.isValid()) { Elf_X_Sym syms = symdata.get_sym(); const char* strs = strdata.get_string(); if (f_addr != NULL) *f_addr = 0; for (u_int i = 0; i < syms.count(); ++i) { if (syms.st_shndx(i) != SHN_UNDEF) { if (syms.ST_TYPE(i) == st_type) { pdstring name = pdstring(&strs[ syms.st_name(i) ]); if (name == f_name) { if (f_addr != NULL) { *f_addr = syms.st_value(i) + ld_base_addr; } result = true; break; } } } } } } elf.end(); return result; }