//------------------------------------------------------------------------------ bool get_entry( Elf_Xword index, Elf64_Addr& offset, Elf_Word& symbol, Elf_Word& type, Elf_Sxword& addend ) const { if ( index >= get_entries_num() ) { // Is index valid return false; } if ( elf_file.get_class() == ELFCLASS32 ) { if ( SHT_REL == relocation_section->get_type() ) { generic_get_entry_rel< Elf32_Rel >( index, offset, symbol, type, addend ); } else if ( SHT_RELA == relocation_section->get_type() ) { generic_get_entry_rela< Elf32_Rela >( index, offset, symbol, type, addend ); } } else { if ( SHT_REL == relocation_section->get_type() ) { generic_get_entry_rel< Elf64_Rel >( index, offset, symbol, type, addend ); } else if ( SHT_RELA == relocation_section->get_type() ) { generic_get_entry_rela< Elf64_Rela >( index, offset, symbol, type, addend ); } } return true; }
//------------------------------------------------------------------------------ bool get_entry( Elf_Xword index, Elf_Xword& tag, Elf_Xword& value, std::string& str ) const { if ( index >= get_entries_num() ) { // Is index valid return false; } if ( elf_file.get_class() == ELFCLASS32 ) { generic_get_entry_dyn< Elf32_Dyn >( index, tag, value ); } else { generic_get_entry_dyn< Elf64_Dyn >( index, tag, value ); } // If the tag may have a string table reference, prepare the string if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH || tag == DT_RUNPATH ) { string_section_accessor strsec = elf_file.sections[ get_string_table_index() ]; const char* result = strsec.get_string( value ); if ( 0 == result ) { str.clear(); return false; } str = result; } else { str.clear(); } return true; }
void DotOFileParser::load_relocations() { // Relocations for (auto &psec : reader->sections) { if ((reader->get_class() == ELFCLASS32 && psec->get_type() == SHT_REL) || (reader->get_class() == ELFCLASS64 && psec->get_type() == SHT_RELA)) { try { Section &targetSection = _sections.at((Elf_Half) psec->get_info()); // We need to ignore relocations on !allocated sections, // since they don't have memory addresses if (!targetSection.allocated) continue; vector<Relocation> &relo_vec = targetSection.relo_vec; const auto relocations = relocation_section_accessor(*reader, psec); auto relo_num = relocations.get_entries_num(); for (unsigned int i = 0; i < relo_num; ++i) { Elf64_Addr offset; Elf_Word symbol; Elf64_Addr symbolValue; std::string symbolName; Elf_Word type; Elf_Sxword addend; Elf_Sxword calcValue; relocations.get_entry(i, offset, symbolValue, symbolName, type, addend, calcValue); if (strncmp(symbolName.c_str(), "_TRaP_Linux", sizeof("_TRaP_Linux")-1) == 0) continue; bool elf32 = reader->get_class() == ELFCLASS32; bool elf64 = reader->get_class() == ELFCLASS64; if (std::find(std::begin(RelocWhitelist), std::end(RelocWhitelist), type) != std::end(RelocWhitelist)) { relo_vec.push_back(Relocation(offset, type, addend)); #if OFPreadprint >= 2 printf("%4d: 0x%08llx 0x%08x %+lld %i\n", i, offset, symbol, addend, type); #endif } else { cerr << "Unknown type " << type << " (file '" << filename << "', " << "section: " << psec->get_name() << ", " << "offset: " << hex << offset << dec << ", " << "relo index: " << i << "/" << relo_num << ")" << endl; exit(13); } } } catch (std::out_of_range e) {} // for .sr.text } } #ifdef OFPprintres for (auto &it : _sections) { if (!it.second.executable) continue; printf("sec %d: %s\n", it.first, it.second.name.c_str()); auto &sym_vec = it.second.sym_vec; printf(" symbols:\n"); sort(sym_vec.begin(), sym_vec.end()); for (auto &jt : sym_vec) { printf(" %08lx %08ld\n", jt.start, jt.size); } auto &relo_vec = it.second.relo_vec; printf(" relocations:\n"); sort(relo_vec.begin(), relo_vec.end()); for (auto &jt : relo_vec) { printf(" %08lx %d\n", jt.offset, jt.type); } } #endif }