static bool isObject(ELFObjectFile<ELFT> &Obj, symbol_iterator I) { typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; DataRefImpl Symb = I->getRawDataRefImpl(); const Elf_Sym *ESym = Obj.getSymbol(Symb); return ESym->getType() == ELF::STT_OBJECT; }
error_or<int64_t> symbol_address(const ELFObjectFile<T> &obj, const SymbolRef &sym) { auto sym_elf = obj.getSymbol(sym.getRawDataRefImpl()); if (is_rel(obj) && !is_abs_symbol(*sym_elf)) { // abs symbols does not affected by relocations return success(int64_t(0)); } else { auto addr = prim::symbol_address(sym); if (!addr) return addr; auto base = base_address(obj); return success(prim::relative_address(base, *addr)); } }
void symbol_entry(const ELFObjectFile<T> &obj, const SymbolRef &sym, ogre_doc &s) { auto sym_elf = obj.getSymbol(sym.getRawDataRefImpl()); if (is_abs_symbol(*sym_elf)) { return; } auto name = prim::symbol_name(sym); auto addr = symbol_address(obj, sym); auto off = symbol_file_offset(obj, sym); if (name && addr && off) { s.entry("symbol-entry") << *name << *addr << sym_elf->st_size << *off; if (sym_elf->getType() == ELF::STT_FUNC) s.entry("code-entry") << *name << *off << sym_elf->st_size ; } }
void symbol_reference(const ELFObjectFile<T> &obj, const RelocationRef &rel, section_iterator sec, ogre_doc &s) { auto it = rel.getSymbol(); if (it == prim::end_symbols(obj)) return; auto sym_elf = obj.getSymbol(it->getRawDataRefImpl()); auto sec_offset = section_offset(obj, sec); auto off = prim::relocation_offset(rel) + sec_offset; // relocation file offset if (is_external_symbol(*sym_elf)) { if (auto name = prim::symbol_name(*it)) s.entry("ref-external") << off << *name; } else { if (auto file_offset = symbol_file_offset(obj, *it)) s.entry("ref-internal") << *file_offset << off; } }
static char getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, basic_symbol_iterator I) { typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; // OK, this is ELF symbol_iterator SymI(I); DataRefImpl Symb = I->getRawDataRefImpl(); const Elf_Sym *ESym = Obj.getSymbol(Symb); const ELFFile<ELFT> &EF = *Obj.getELFFile(); const Elf_Shdr *ESec = EF.getSection(ESym); if (ESec) { switch (ESec->sh_type) { case ELF::SHT_PROGBITS: case ELF::SHT_DYNAMIC: switch (ESec->sh_flags) { case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): return 't'; case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): case (ELF::SHF_ALLOC | ELF::SHF_WRITE): return 'd'; case ELF::SHF_ALLOC: case (ELF::SHF_ALLOC | ELF::SHF_MERGE): case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): return 'r'; } break; case ELF::SHT_NOBITS: return 'b'; } } if (ESym->getType() == ELF::STT_SECTION) { StringRef Name; if (error(SymI->getName(Name))) return '?'; return StringSwitch<char>(Name) .StartsWith(".debug", 'N') .StartsWith(".note", 'n') .Default('?'); } return '?'; }
error_code getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, symbol_iterator I, char &Result) { typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; DataRefImpl Symb = I->getRawDataRefImpl(); const Elf_Sym *ESym = Obj.getSymbol(Symb); const ELFFile<ELFT> &EF = *Obj.getELFFile(); const Elf_Shdr *ESec = EF.getSection(ESym); char ret = '?'; if (ESec) { switch (ESec->sh_type) { case ELF::SHT_PROGBITS: case ELF::SHT_DYNAMIC: switch (ESec->sh_flags) { case(ELF::SHF_ALLOC | ELF::SHF_EXECINSTR) : ret = 't'; break; case(ELF::SHF_ALLOC | ELF::SHF_WRITE) : ret = 'd'; break; case ELF::SHF_ALLOC: case(ELF::SHF_ALLOC | ELF::SHF_MERGE) : case(ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS) : ret = 'r'; break; } break; case ELF::SHT_NOBITS: ret = 'b'; } } switch (EF.getSymbolTableIndex(ESym)) { case ELF::SHN_UNDEF: if (ret == '?') ret = 'U'; break; case ELF::SHN_ABS: ret = 'a'; break; case ELF::SHN_COMMON: ret = 'c'; break; } switch (ESym->getBinding()) { case ELF::STB_GLOBAL: ret = ::toupper(ret); break; case ELF::STB_WEAK: if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) ret = 'w'; else if (ESym->getType() == ELF::STT_OBJECT) ret = 'V'; else ret = 'W'; } if (ret == '?' && ESym->getType() == ELF::STT_SECTION) { StringRef Name; error_code EC = I->getName(Name); if (EC) return EC; Result = StringSwitch<char>(Name) .StartsWith(".debug", 'N') .StartsWith(".note", 'n') .Default('?'); return object_error::success; } Result = ret; return object_error::success; }