const Elf_Ehdr *Header;
const Elf_Shdr *SectionHeaderTable = nullptr;
StringRef DotShstrtab; // Section header string table.
- const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section.
-
- const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr;
public:
template<typename T>
ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const;
ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
+ ErrorOr<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
+
void VerifyStrTab(const Elf_Shdr *sh) const;
StringRef getRelocationTypeName(uint32_t Type) const;
uint64_t getNumSections() const;
uintX_t getStringTableIndex() const;
- ELF::Elf64_Word getExtendedSymbolTableIndex(const Elf_Sym *symb) const;
+ ELF::Elf64_Word
+ getExtendedSymbolTableIndex(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
+ ArrayRef<Elf_Word> ShndxTable) const;
const Elf_Ehdr *getHeader() const { return Header; }
- ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *symb) const;
+ ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
+ const Elf_Shdr *SymTab,
+ ArrayRef<Elf_Word> ShndxTable) const;
ErrorOr<const Elf_Shdr *> getSection(uint32_t Index) const;
const Elf_Sym *getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
typedef ELFFile<ELFType<support::big, true>> ELF64BEFile;
template <class ELFT>
-ELF::Elf64_Word
-ELFFile<ELFT>::getExtendedSymbolTableIndex(const Elf_Sym *Sym) const {
+ELF::Elf64_Word ELFFile<ELFT>::getExtendedSymbolTableIndex(
+ const Elf_Sym *Sym, const Elf_Shdr *SymTab,
+ ArrayRef<Elf_Word> ShndxTable) const {
assert(Sym->st_shndx == ELF::SHN_XINDEX);
- unsigned Index = Sym - symbol_begin(dot_symtab_sec);
+ unsigned Index = Sym - symbol_begin(SymTab);
// FIXME: error checking
- const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word *>(
- base() + SymbolTableSectionHeaderIndex->sh_offset);
return ShndxTable[Index];
}
template <class ELFT>
ErrorOr<const typename ELFFile<ELFT>::Elf_Shdr *>
-ELFFile<ELFT>::getSection(const Elf_Sym *symb) const {
- uint32_t Index = symb->st_shndx;
+ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
+ ArrayRef<Elf_Word> ShndxTable) const {
+ uint32_t Index = Sym->st_shndx;
if (Index == ELF::SHN_XINDEX)
- return getSection(getExtendedSymbolTableIndex(symb));
+ return getSection(getExtendedSymbolTableIndex(Sym, SymTab, ShndxTable));
+
if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
return nullptr;
- return getSection(symb->st_shndx);
+ return getSection(Sym->st_shndx);
}
template <class ELFT>
return;
}
- // Scan sections for special sections.
-
- for (const Elf_Shdr &Sec : sections()) {
- switch (Sec.sh_type) {
- case ELF::SHT_SYMTAB_SHNDX:
- if (SymbolTableSectionHeaderIndex) {
- // More than one .symtab_shndx!
- EC = object_error::parse_failed;
- return;
- }
- SymbolTableSectionHeaderIndex = &Sec;
- break;
- case ELF::SHT_SYMTAB: {
- if (dot_symtab_sec) {
- // More than one .symtab!
- EC = object_error::parse_failed;
- return;
- }
- dot_symtab_sec = &Sec;
- } break;
- }
- }
-
// Get string table sections.
uintX_t StringTableIndex = getStringTableIndex();
if (StringTableIndex) {
return Data;
}
+template <class ELFT>
+ErrorOr<ArrayRef<typename ELFFile<ELFT>::Elf_Word>>
+ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
+ assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
+ const Elf_Word *ShndxTableBegin =
+ reinterpret_cast<const Elf_Word *>(base() + Section.sh_offset);
+ uintX_t Size = Section.sh_offset;
+ if (Size % sizeof(uintX_t))
+ return object_error::parse_failed;
+ const Elf_Word *ShndxTableEnd = ShndxTableBegin + Size / sizeof(uintX_t);
+ if (reinterpret_cast<const char *>(ShndxTableEnd) > Buf.end())
+ return object_error::parse_failed;
+ return ArrayRef<Elf_Word>(ShndxTableBegin, ShndxTableEnd);
+}
+
template <class ELFT>
ErrorOr<StringRef>
ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
+ ArrayRef<Elf_Word> ShndxTable;
void moveSymbolNext(DataRefImpl &Symb) const override;
ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
uint8_t getSymbolOther(DataRefImpl Symb) const override;
uint8_t getSymbolELFType(DataRefImpl Symb) const override;
SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
- ErrorOr<section_iterator> getSymbolSection(const Elf_Sym *Symb) const;
+ ErrorOr<section_iterator> getSymbolSection(const Elf_Sym *Symb,
+ const Elf_Shdr *SymTab) const;
ErrorOr<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
}
const Elf_Ehdr *Header = EF.getHeader();
+ const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
if (Header->e_type == ELF::ET_REL) {
- ErrorOr<const Elf_Shdr *> SectionOrErr = EF.getSection(ESym);
+ ErrorOr<const Elf_Shdr *> SectionOrErr =
+ EF.getSection(ESym, SymTab, ShndxTable);
if (std::error_code EC = SectionOrErr.getError())
return EC;
const Elf_Shdr *Section = *SectionOrErr;
template <class ELFT>
ErrorOr<section_iterator>
-ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym) const {
- ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym);
+ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
+ const Elf_Shdr *SymTab) const {
+ ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
if (std::error_code EC = ESecOrErr.getError())
return EC;
template <class ELFT>
ErrorOr<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
- return getSymbolSection(getSymbol(Symb));
+ const Elf_Sym *Sym = getSymbol(Symb);
+ const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
+ return getSymbolSection(Sym, SymTab);
}
template <class ELFT>
DotSymtabSec = &Sec;
break;
}
+ case ELF::SHT_SYMTAB_SHNDX: {
+ ErrorOr<ArrayRef<Elf_Word>> TableOrErr = EF.getSHNDXTable(Sec);
+ if ((EC = TableOrErr.getError()))
+ return;
+ ShndxTable = *TableOrErr;
+ break;
+ }
}
}
}
typedef typename object::ELFFile<ET>::Elf_Sym Elf_Sym;
typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr;
typedef typename object::ELFFile<ET>::Elf_Rel Elf_Rel;
+ typedef typename object::ELFFile<ET>::Elf_Word Elf_Word;
StreamWriter &SW;
const object::ELFFile<ET> *ELF;
const Elf_Shdr *Symtab;
+ ArrayRef<Elf_Word> ShndxTable;
static const size_t IndexTableEntrySize;
std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol =
ELF->getRelocationSymbol(&Sec, &RelA);
- ErrorOr<const Elf_Shdr *> Ret = ELF->getSection(Symbol.second);
+ ErrorOr<const Elf_Shdr *> Ret =
+ ELF->getSection(Symbol.second, Symbol.first, ShndxTable);
if (std::error_code EC = Ret.getError())
report_fatal_error(EC.message());
return *Ret;
typedef typename ELFO::Elf_Phdr Elf_Phdr;
typedef typename ELFO::Elf_Hash Elf_Hash;
typedef typename ELFO::Elf_Ehdr Elf_Ehdr;
+ typedef typename ELFO::Elf_Word Elf_Word;
typedef typename ELFO::uintX_t uintX_t;
typedef typename ELFO::Elf_Versym Elf_Versym;
typedef typename ELFO::Elf_Verneed Elf_Verneed;
uintX_t EntSize;
};
- void printSymbol(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic);
+ void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
+ StringRef StrTable, bool IsDynamic);
void printRelocations(const Elf_Shdr *Sec);
void printRelocation(const Elf_Shdr *Sec, Elf_Rela Rel);
const Elf_Hash *HashTable = nullptr;
const Elf_Shdr *DotDynSymSec = nullptr;
const Elf_Shdr *DotSymtabSec = nullptr;
+ ArrayRef<Elf_Word> ShndxTable;
const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version
const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r
std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
bool IsDynamic);
const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; }
+ const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
+ ArrayRef<Elf_Word> getShndxTable() { return ShndxTable; }
};
template <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) {
template <typename ELFO>
static void
getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
+ const typename ELFO::Elf_Shdr *SymTab,
+ ArrayRef<typename ELFO::Elf_Word> ShndxTable,
StringRef &SectionName, unsigned &SectionIndex) {
SectionIndex = Symbol->st_shndx;
if (Symbol->isUndefined())
SectionName = "Reserved";
else {
if (SectionIndex == SHN_XINDEX)
- SectionIndex = Obj.getExtendedSymbolTableIndex(Symbol);
+ SectionIndex =
+ Obj.getExtendedSymbolTableIndex(Symbol, SymTab, ShndxTable);
ErrorOr<const typename ELFO::Elf_Shdr *> Sec = Obj.getSection(SectionIndex);
error(Sec.getError());
SectionName = errorOrDefault(Obj.getSectionName(*Sec));
reportError("Multilpe SHT_SYMTAB");
DotSymtabSec = &Sec;
break;
+ case ELF::SHT_SYMTAB_SHNDX: {
+ ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj->getSHNDXTable(Sec);
+ error(TableOrErr.getError());
+ ShndxTable = *TableOrErr;
+ break;
+ }
}
}
}
StringRef StrTable = *StrTableOrErr;
for (const Elf_Sym &Sym : Obj->symbols(Symtab)) {
- ErrorOr<const Elf_Shdr *> SymSec = Obj->getSection(&Sym);
+ ErrorOr<const Elf_Shdr *> SymSec =
+ Obj->getSection(&Sym, Symtab, ShndxTable);
if (!SymSec)
continue;
if (*SymSec == &Sec)
- printSymbol(&Sym, StrTable, false);
+ printSymbol(&Sym, Symtab, StrTable, false);
}
}
std::pair<const Elf_Shdr *, const Elf_Sym *> Sym =
Obj->getRelocationSymbol(Sec, &Rel);
if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) {
- ErrorOr<const Elf_Shdr *> Sec = Obj->getSection(Sym.second);
+ ErrorOr<const Elf_Shdr *> Sec =
+ Obj->getSection(Sym.second, Sym.first, ShndxTable);
error(Sec.getError());
ErrorOr<StringRef> SecName = Obj->getSectionName(*Sec);
if (SecName)
error(StrTableOrErr.getError());
StringRef StrTable = *StrTableOrErr;
for (const Elf_Sym &Sym : Obj->symbols(Symtab))
- printSymbol(&Sym, StrTable, false);
+ printSymbol(&Sym, Symtab, StrTable, false);
}
template<class ELFT>
error(StrTableOrErr.getError());
StringRef StrTable = *StrTableOrErr;
for (const Elf_Sym &Sym : Obj->symbols(Symtab))
- printSymbol(&Sym, StrTable, true);
+ printSymbol(&Sym, Symtab, StrTable, true);
}
template <class ELFT>
-void ELFDumper<ELFT>::printSymbol(const Elf_Sym *Symbol, StringRef StrTable,
- bool IsDynamic) {
+void ELFDumper<ELFT>::printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
+ StringRef StrTable, bool IsDynamic) {
unsigned SectionIndex = 0;
StringRef SectionName;
- getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex);
+ getSectionNameIndex(*Obj, Symbol, SymTab, ShndxTable, SectionName,
+ SectionIndex);
std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
unsigned char SymbolType = Symbol->getType();
unsigned SectionIndex = 0;
StringRef SectionName;
- getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
+ getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
+ Dumper->getShndxTable(), SectionName, SectionIndex);
W.printHex("Section", SectionName, SectionIndex);
std::string FullSymbolName =
unsigned SectionIndex = 0;
StringRef SectionName;
- getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
+ getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
+ Dumper->getShndxTable(), SectionName, SectionIndex);
W.printHex("Section", SectionName, SectionIndex);
std::string FullSymbolName = Dumper->getFullSymbolName(Sym, StrTable, true);
typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word;
const object::ELFFile<ELFT> &Obj;
+ ArrayRef<Elf_Word> ShndxTable;
- std::error_code dumpSymbol(const Elf_Sym *Sym, StringRef StrTable,
- ELFYAML::Symbol &S);
+ std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
+ StringRef StrTable, ELFYAML::Symbol &S);
std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr,
ELFYAML::RelocationSection &S);
case ELF::SHT_SYMTAB:
Symtab = &Sec;
break;
+ case ELF::SHT_SYMTAB_SHNDX: {
+ ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj.getSHNDXTable(Sec);
+ if (std::error_code EC = TableOrErr.getError())
+ return EC;
+ ShndxTable = *TableOrErr;
+ break;
+ }
case ELF::SHT_RELA: {
ErrorOr<ELFYAML::RelocationSection *> S = dumpRelaSection(&Sec);
if (std::error_code EC = S.getError())
}
ELFYAML::Symbol S;
- if (std::error_code EC = ELFDumper<ELFT>::dumpSymbol(&Sym, StrTable, S))
+ if (std::error_code EC =
+ ELFDumper<ELFT>::dumpSymbol(&Sym, Symtab, StrTable, S))
return EC;
switch (Sym.getBinding())
}
template <class ELFT>
-std::error_code ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym,
- StringRef StrTable,
- ELFYAML::Symbol &S) {
+std::error_code
+ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
+ StringRef StrTable, ELFYAML::Symbol &S) {
S.Type = Sym->getType();
S.Value = Sym->st_value;
S.Size = Sym->st_size;
return EC;
S.Name = NameOrErr.get();
- ErrorOr<const Elf_Shdr *> ShdrOrErr = Obj.getSection(Sym);
+ ErrorOr<const Elf_Shdr *> ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
if (std::error_code EC = ShdrOrErr.getError())
return EC;
const Elf_Shdr *Shdr = *ShdrOrErr;