Remove Elf_Sym_Iter.

It was a fairly broken concept for an ELF only class.

An ELF file can have two symbol tables, but they have exactly the same
format. There is no concept of a dynamic or a static symbol. Storing this
on the iterator also makes us do more work per symbol than necessary. To fetch
a name we would:

* Find if we had a static or a dynamic symbol.
* Look at the corresponding symbol table and find the string table section.
* Look at the string table section to fetch its contents.
* Compute the name as a substring of the string table.

All but the last step can be done per symbol table instead of per symbol. This
is a step in that direction.

llvm-svn: 240939
This commit is contained in:
Rafael Espindola 2015-06-29 12:38:31 +00:00
parent 4a38b0b493
commit 719dc7c436
6 changed files with 124 additions and 189 deletions

View File

@ -158,76 +158,7 @@ public:
enum { NumLowBitsAvailable = 1 }; enum { NumLowBitsAvailable = 1 };
}; };
class Elf_Sym_Iter { typedef iterator_range<const Elf_Sym *> Elf_Sym_Range;
public:
typedef ptrdiff_t difference_type;
typedef const Elf_Sym value_type;
typedef std::random_access_iterator_tag iterator_category;
typedef value_type &reference;
typedef value_type *pointer;
/// \brief Default construct iterator.
Elf_Sym_Iter() : EntitySize(0), Current(0, false) {}
Elf_Sym_Iter(uintX_t EntSize, const char *Start, bool IsDynamic)
: EntitySize(EntSize), Current(Start, IsDynamic) {}
reference operator*() {
assert(Current.getPointer() &&
"Attempted to dereference an invalid iterator!");
return *reinterpret_cast<pointer>(Current.getPointer());
}
pointer operator->() {
assert(Current.getPointer() &&
"Attempted to dereference an invalid iterator!");
return reinterpret_cast<pointer>(Current.getPointer());
}
bool operator==(const Elf_Sym_Iter &Other) {
return Current == Other.Current;
}
bool operator!=(const Elf_Sym_Iter &Other) { return !(*this == Other); }
Elf_Sym_Iter &operator++() {
assert(Current.getPointer() &&
"Attempted to increment an invalid iterator!");
Current.setPointer(Current.getPointer() + EntitySize);
return *this;
}
Elf_Sym_Iter operator++(int) {
Elf_Sym_Iter Tmp = *this;
++*this;
return Tmp;
}
Elf_Sym_Iter operator+(difference_type Dist) {
assert(Current.getPointer() &&
"Attempted to increment an invalid iterator!");
Current.setPointer(Current.getPointer() + EntitySize * Dist);
return *this;
}
difference_type operator-(const Elf_Sym_Iter &Other) const {
assert(EntitySize == Other.EntitySize &&
"Subtracting iterators of different EntitySize!");
return (Current.getPointer() - Other.Current.getPointer()) / EntitySize;
}
const char *get() const { return Current.getPointer(); }
bool isDynamic() const { return Current.getInt(); }
uintX_t getEntSize() const { return EntitySize; }
private:
uintX_t EntitySize;
PointerIntPair<const char *, 1, bool,
ArchivePointerTypeTraits<const char> > Current;
};
typedef iterator_range<Elf_Sym_Iter> Elf_Sym_Range;
private: private:
typedef SmallVector<const Elf_Shdr *, 2> Sections_t; typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
@ -339,8 +270,8 @@ public:
return make_range(begin_sections(), end_sections()); return make_range(begin_sections(), end_sections());
} }
Elf_Sym_Iter begin_symbols() const; const Elf_Sym *begin_symbols() const;
Elf_Sym_Iter end_symbols() const; const Elf_Sym *end_symbols() const;
Elf_Sym_Range symbols() const { Elf_Sym_Range symbols() const {
return make_range(begin_symbols(), end_symbols()); return make_range(begin_symbols(), end_symbols());
} }
@ -353,19 +284,22 @@ public:
return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd)); return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd));
} }
Elf_Sym_Iter begin_dynamic_symbols() const { const Elf_Sym *begin_dynamic_symbols() const {
if (DynSymRegion.Addr) if (DynSymRegion.Addr)
return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr, return reinterpret_cast<const Elf_Sym *>(DynSymRegion.Addr);
true); return nullptr;
return Elf_Sym_Iter(0, nullptr, true);
} }
Elf_Sym_Iter end_dynamic_symbols() const { const Elf_Sym *end_dynamic_symbols() const {
if (DynSymRegion.Addr) if (DynSymRegion.Addr)
return Elf_Sym_Iter(DynSymRegion.EntSize, return reinterpret_cast<const Elf_Sym *>(
(const char *)DynSymRegion.Addr + DynSymRegion.Size, ((const char *)DynSymRegion.Addr + DynSymRegion.Size));
true);
return Elf_Sym_Iter(0, nullptr, true); return nullptr;
}
Elf_Sym_Range dynamic_symbols() const {
return make_range(begin_dynamic_symbols(), end_dynamic_symbols());
} }
Elf_Rela_Iter begin_dyn_rela() const { Elf_Rela_Iter begin_dyn_rela() const {
@ -427,8 +361,9 @@ public:
const Elf_Shdr *getSection(uint32_t Index) const; const Elf_Shdr *getSection(uint32_t Index) const;
const Elf_Sym *getSymbol(uint32_t index) const; const Elf_Sym *getSymbol(uint32_t index) const;
ErrorOr<StringRef> getSymbolName(Elf_Sym_Iter Sym) const;
ErrorOr<StringRef> getStaticSymbolName(const Elf_Sym *Symb) const; ErrorOr<StringRef> getStaticSymbolName(const Elf_Sym *Symb) const;
ErrorOr<StringRef> getDynamicSymbolName(const Elf_Sym *Symb) const;
ErrorOr<StringRef> getSymbolName(const Elf_Sym *Symb, bool IsDynamic) const;
/// \brief Get the name of \p Symb. /// \brief Get the name of \p Symb.
/// \param SymTab The symbol table section \p Symb is contained in. /// \param SymTab The symbol table section \p Symb is contained in.
@ -436,7 +371,7 @@ public:
/// ///
/// \p SymTab is used to lookup the string table to use to get the symbol's /// \p SymTab is used to lookup the string table to use to get the symbol's
/// name. /// name.
ErrorOr<StringRef> getSymbolName(const Elf_Shdr *SymTab, ErrorOr<StringRef> getSymbolName(const Elf_Shdr *StrTab,
const Elf_Sym *Symb) const; const Elf_Sym *Symb) const;
ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const; ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const;
uint64_t getSymbolIndex(const Elf_Sym *sym) const; uint64_t getSymbolIndex(const Elf_Sym *sym) const;
@ -763,10 +698,9 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
if (SymbolTableSectionHeaderIndex) { if (SymbolTableSectionHeaderIndex) {
const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() + const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
SymbolTableSectionHeaderIndex->sh_offset); SymbolTableSectionHeaderIndex->sh_offset);
for (Elf_Sym_Iter SI = begin_symbols(), SE = end_symbols(); SI != SE; for (const Elf_Sym &S : symbols()) {
++SI) {
if (*ShndxTable != ELF::SHN_UNDEF) if (*ShndxTable != ELF::SHN_UNDEF)
ExtendedSymbolTable[&*SI] = *ShndxTable; ExtendedSymbolTable[&S] = *ShndxTable;
++ShndxTable; ++ShndxTable;
} }
} }
@ -844,21 +778,18 @@ typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::end_sections() const {
} }
template <class ELFT> template <class ELFT>
typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const { const typename ELFFile<ELFT>::Elf_Sym *ELFFile<ELFT>::begin_symbols() const {
if (!dot_symtab_sec) if (!dot_symtab_sec)
return Elf_Sym_Iter(0, nullptr, false); return nullptr;
return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, return reinterpret_cast<const Elf_Sym *>(base() + dot_symtab_sec->sh_offset);
(const char *)base() + dot_symtab_sec->sh_offset, false);
} }
template <class ELFT> template <class ELFT>
typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::end_symbols() const { const typename ELFFile<ELFT>::Elf_Sym *ELFFile<ELFT>::end_symbols() const {
if (!dot_symtab_sec) if (!dot_symtab_sec)
return Elf_Sym_Iter(0, nullptr, false); return nullptr;
return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, return reinterpret_cast<const Elf_Sym *>(base() + dot_symtab_sec->sh_offset +
(const char *)base() + dot_symtab_sec->sh_offset + dot_symtab_sec->sh_size);
dot_symtab_sec->sh_size,
false);
} }
template <class ELFT> template <class ELFT>
@ -950,26 +881,29 @@ const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const {
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const { ErrorOr<StringRef>
if (!Sym.isDynamic()) ELFFile<ELFT>::getStaticSymbolName(const Elf_Sym *Symb) const {
return getSymbolName(dot_symtab_sec, &*Sym); return getSymbolName(dot_strtab_sec, Symb);
if (!DynStrRegion.Addr || Sym->st_name >= DynStrRegion.Size)
return object_error::parse_failed;
return StringRef(getDynamicString(Sym->st_name));
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> ErrorOr<StringRef>
ELFFile<ELFT>::getStaticSymbolName(const Elf_Sym *Symb) const { ELFFile<ELFT>::getDynamicSymbolName(const Elf_Sym *Symb) const {
return getSymbolName(dot_symtab_sec, Symb); return StringRef(getDynamicString(Symb->st_name));
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section, ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Sym *Symb,
const Elf_Sym *Symb) const { bool IsDynamic) const {
const Elf_Shdr *StrTab = getSection(Section->sh_link); if (IsDynamic)
return getString(StrTab, Symb->st_name); return getDynamicSymbolName(Symb);
return getStaticSymbolName(Symb);
}
template <class ELFT>
ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *StrTab,
const Elf_Sym *Sym) const {
return getString(StrTab, Sym->st_name);
} }
template <class ELFT> template <class ELFT>

View File

@ -159,7 +159,6 @@ public:
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter; typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter;
typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter; typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter;
@ -224,20 +223,14 @@ protected:
const Elf_Rel *getRel(DataRefImpl Rel) const; const Elf_Rel *getRel(DataRefImpl Rel) const;
const Elf_Rela *getRela(DataRefImpl Rela) const; const Elf_Rela *getRela(DataRefImpl Rela) const;
Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const { const Elf_Sym *toELFSymIter(DataRefImpl Sym) const {
bool IsDynamic = Symb.p & 1; return reinterpret_cast<const Elf_Sym *>(Sym.p & ~uintptr_t(1));
if (IsDynamic)
return Elf_Sym_Iter(
EF.begin_dynamic_symbols().getEntSize(),
reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic);
return Elf_Sym_Iter(EF.begin_symbols().getEntSize(),
reinterpret_cast<const char *>(Symb.p), IsDynamic);
} }
DataRefImpl toDRI(Elf_Sym_Iter Symb) const { DataRefImpl toDRI(const Elf_Sym *Sym, bool IsDynamic) const {
DataRefImpl DRI; DataRefImpl DRI;
DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) | DRI.p =
static_cast<uintptr_t>(Symb.isDynamic()); reinterpret_cast<uintptr_t>(Sym) | static_cast<uintptr_t>(IsDynamic);
return DRI; return DRI;
} }
@ -334,14 +327,16 @@ typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile;
typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile; typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile;
template <class ELFT> template <class ELFT>
void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const { void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
Symb = toDRI(++toELFSymIter(Symb)); const Elf_Sym *S = toELFSymIter(Sym);
Sym = toDRI(++S, Sym.p & 1);
} }
template <class ELFT> template <class ELFT>
std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym,
StringRef &Result) const { StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb)); const Elf_Sym *ESym = toELFSymIter(Sym);
ErrorOr<StringRef> Name = EF.getSymbolName(ESym, Sym.p & 1);
if (!Name) if (!Name)
return Name.getError(); return Name.getError();
Result = *Name; Result = *Name;
@ -405,7 +400,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
template <class ELFT> template <class ELFT>
uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const { uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
Elf_Sym_Iter Sym = toELFSymIter(Symb); const Elf_Sym *Sym = toELFSymIter(Symb);
if (Sym->st_shndx == ELF::SHN_COMMON) if (Sym->st_shndx == ELF::SHN_COMMON)
return Sym->st_value; return Sym->st_value;
return 0; return 0;
@ -454,9 +449,8 @@ SymbolRef::Type ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
} }
template <class ELFT> template <class ELFT>
uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const { uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
Elf_Sym_Iter EIter = toELFSymIter(Symb); const Elf_Sym *ESym = toELFSymIter(Sym);
const Elf_Sym *ESym = &*EIter;
uint32_t Result = SymbolRef::SF_None; uint32_t Result = SymbolRef::SF_None;
@ -470,11 +464,12 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const {
Result |= SymbolRef::SF_Absolute; Result |= SymbolRef::SF_Absolute;
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols()) ESym == EF.begin_symbols() || ESym == EF.begin_dynamic_symbols())
Result |= SymbolRef::SF_FormatSpecific; Result |= SymbolRef::SF_FormatSpecific;
if (EF.getHeader()->e_machine == ELF::EM_ARM) { if (EF.getHeader()->e_machine == ELF::EM_ARM) {
if (ErrorOr<StringRef> NameOrErr = EF.getSymbolName(EIter)) { ErrorOr<StringRef> NameOrErr = EF.getSymbolName(ESym, Sym.p & 1);
if (NameOrErr) {
StringRef Name = *NameOrErr; StringRef Name = *NameOrErr;
if (Name.startswith("$d") || Name.startswith("$t") || if (Name.startswith("$d") || Name.startswith("$t") ||
Name.startswith("$a")) Name.startswith("$a"))
@ -584,7 +579,7 @@ bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
template <class ELFT> template <class ELFT>
bool ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, bool ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
DataRefImpl Symb) const { DataRefImpl Symb) const {
Elf_Sym_Iter ESym = toELFSymIter(Symb); const Elf_Sym *ESym = toELFSymIter(Symb);
uintX_t Index = ESym->st_shndx; uintX_t Index = ESym->st_shndx;
bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE; bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE;
@ -665,10 +660,10 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
default: default:
report_fatal_error("Invalid symbol table section type!"); report_fatal_error("Invalid symbol table section type!");
case ELF::SHT_SYMTAB: case ELF::SHT_SYMTAB:
SymbolData = toDRI(EF.begin_symbols() + symbolIdx); SymbolData = toDRI(EF.begin_symbols() + symbolIdx, false);
break; break;
case ELF::SHT_DYNSYM: case ELF::SHT_DYNSYM:
SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx); SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx, true);
break; break;
} }
@ -804,22 +799,26 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
template <class ELFT> template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const { basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); DataRefImpl Sym = toDRI(EF.begin_symbols(), false);
return basic_symbol_iterator(SymbolRef(Sym, this));
} }
template <class ELFT> template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const { basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); DataRefImpl Sym = toDRI(EF.end_symbols(), false);
return basic_symbol_iterator(SymbolRef(Sym, this));
} }
template <class ELFT> template <class ELFT>
elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); DataRefImpl Sym = toDRI(EF.begin_dynamic_symbols(), true);
return symbol_iterator(SymbolRef(Sym, this));
} }
template <class ELFT> template <class ELFT>
elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); DataRefImpl Sym = toDRI(EF.end_dynamic_symbols(), true);
return symbol_iterator(SymbolRef(Sym, this));
} }
template <class ELFT> template <class ELFT>

View File

@ -321,6 +321,10 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
const ELFFile<ELFT> &EF = *Obj->getELFFile(); const ELFFile<ELFT> &EF = *Obj->getELFFile();
const Elf_Shdr *sec = EF.getSection(Rel.d.a); const Elf_Shdr *sec = EF.getSection(Rel.d.a);
const Elf_Shdr *SymTab = EF.getSection(sec->sh_link);
assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
SymTab->sh_type == ELF::SHT_DYNSYM);
const Elf_Shdr *StrTab = EF.getSection(SymTab->sh_link);
uint8_t type; uint8_t type;
StringRef res; StringRef res;
int64_t addend = 0; int64_t addend = 0;
@ -351,8 +355,7 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
return EC; return EC;
Target = *SecName; Target = *SecName;
} else { } else {
ErrorOr<StringRef> SymName = ErrorOr<StringRef> SymName = EF.getSymbolName(StrTab, symb);
EF.getSymbolName(EF.getSection(sec->sh_link), symb);
if (!SymName) if (!SymName)
return SymName.getError(); return SymName.getError();
Target = *SymName; Target = *SymName;

View File

@ -312,7 +312,6 @@ class PrinterContext {
typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr; typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr;
typedef typename object::ELFFile<ET>::Elf_Rel_Iter Elf_Rel_iterator; typedef typename object::ELFFile<ET>::Elf_Rel_Iter Elf_Rel_iterator;
typedef typename object::ELFFile<ET>::Elf_Sym_Iter Elf_Sym_iterator;
typedef typename object::ELFFile<ET>::Elf_Shdr_Iter Elf_Shdr_iterator; typedef typename object::ELFFile<ET>::Elf_Shdr_Iter Elf_Shdr_iterator;
static const size_t IndexTableEntrySize; static const size_t IndexTableEntrySize;
@ -344,13 +343,13 @@ template <typename ET>
const size_t PrinterContext<ET>::IndexTableEntrySize = 8; const size_t PrinterContext<ET>::IndexTableEntrySize = 8;
template <typename ET> template <typename ET>
ErrorOr<StringRef> PrinterContext<ET>::FunctionAtAddress(unsigned Section, ErrorOr<StringRef>
uint64_t Address) const { PrinterContext<ET>::FunctionAtAddress(unsigned Section,
for (Elf_Sym_iterator SI = ELF->begin_symbols(), SE = ELF->end_symbols(); uint64_t Address) const {
SI != SE; ++SI) for (const Elf_Sym &Sym : ELF->symbols())
if (SI->st_shndx == Section && SI->st_value == Address && if (Sym.st_shndx == Section && Sym.st_value == Address &&
SI->getType() == ELF::STT_FUNC) Sym.getType() == ELF::STT_FUNC)
return ELF->getSymbolName(SI); return ELF->getSymbolName(&Sym, false);
return readobj_error::unknown_symbol; return readobj_error::unknown_symbol;
} }

View File

@ -69,7 +69,7 @@ private:
typedef typename ELFO::Elf_Shdr Elf_Shdr; typedef typename ELFO::Elf_Shdr Elf_Shdr;
typedef typename ELFO::Elf_Sym Elf_Sym; typedef typename ELFO::Elf_Sym Elf_Sym;
void printSymbol(typename ELFO::Elf_Sym_Iter Symbol); void printSymbol(const Elf_Sym *Symbol, bool IsDynamic);
void printRelocations(const Elf_Shdr *Sec); void printRelocations(const Elf_Shdr *Sec);
void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel); void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel);
@ -123,9 +123,10 @@ std::error_code createELFDumper(const object::ObjectFile *Obj,
template <typename ELFO> template <typename ELFO>
static std::string getFullSymbolName(const ELFO &Obj, static std::string getFullSymbolName(const ELFO &Obj,
typename ELFO::Elf_Sym_Iter Symbol) { const typename ELFO::Elf_Sym *Symbol,
StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol)); bool IsDynamic) {
if (!Symbol.isDynamic()) StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol, IsDynamic));
if (!IsDynamic)
return SymbolName; return SymbolName;
std::string FullSymbolName(SymbolName); std::string FullSymbolName(SymbolName);
@ -143,7 +144,7 @@ static std::string getFullSymbolName(const ELFO &Obj,
template <typename ELFO> template <typename ELFO>
static void static void
getSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol, getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
StringRef &SectionName, unsigned &SectionIndex) { StringRef &SectionName, unsigned &SectionIndex) {
SectionIndex = Symbol->st_shndx; SectionIndex = Symbol->st_shndx;
if (Symbol->isUndefined()) if (Symbol->isUndefined())
@ -645,11 +646,9 @@ void ELFDumper<ELFT>::printSections() {
if (opts::SectionSymbols) { if (opts::SectionSymbols) {
ListScope D(W, "Symbols"); ListScope D(W, "Symbols");
for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), for (const typename ELFO::Elf_Sym &Sym : Obj->symbols()) {
SymE = Obj->end_symbols(); if (Obj->getSection(&Sym) == Section)
SymI != SymE; ++SymI) { printSymbol(&Sym, false);
if (Obj->getSection(&*SymI) == Section)
printSymbol(SymI);
} }
} }
@ -697,8 +696,8 @@ void ELFDumper<ELFT>::printDynamicRelocations() {
Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName); Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName);
StringRef SymbolName; StringRef SymbolName;
uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL()); uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL());
typename ELFO::Elf_Sym_Iter Sym = Obj->begin_dynamic_symbols() + SymIndex; const typename ELFO::Elf_Sym *Sym = Obj->begin_dynamic_symbols() + SymIndex;
SymbolName = errorOrDefault(Obj->getSymbolName(Sym)); SymbolName = errorOrDefault(Obj->getSymbolName(Sym, true));
if (opts::ExpandRelocs) { if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation"); DictScope Group(W, "Relocation");
W.printHex("Offset", RelI->r_offset); W.printHex("Offset", RelI->r_offset);
@ -757,7 +756,9 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
if (SecName) if (SecName)
TargetName = SecName.get(); TargetName = SecName.get();
} else if (Sym.first) { } else if (Sym.first) {
TargetName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second)); const Elf_Shdr *SymTable = Sym.first;
const Elf_Shdr *StrTable = Obj->getSection(SymTable->sh_link);
TargetName = errorOrDefault(Obj->getSymbolName(StrTable, Sym.second));
} }
if (opts::ExpandRelocs) { if (opts::ExpandRelocs) {
@ -778,30 +779,25 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec,
template<class ELFT> template<class ELFT>
void ELFDumper<ELFT>::printSymbols() { void ELFDumper<ELFT>::printSymbols() {
ListScope Group(W, "Symbols"); ListScope Group(W, "Symbols");
for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), for (const typename ELFO::Elf_Sym &Sym : Obj->symbols())
SymE = Obj->end_symbols(); printSymbol(&Sym, false);
SymI != SymE; ++SymI) {
printSymbol(SymI);
}
} }
template<class ELFT> template<class ELFT>
void ELFDumper<ELFT>::printDynamicSymbols() { void ELFDumper<ELFT>::printDynamicSymbols() {
ListScope Group(W, "DynamicSymbols"); ListScope Group(W, "DynamicSymbols");
for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(), for (const typename ELFO::Elf_Sym &Sym : Obj->dynamic_symbols())
SymE = Obj->end_dynamic_symbols(); printSymbol(&Sym, true);
SymI != SymE; ++SymI) {
printSymbol(SymI);
}
} }
template <class ELFT> template <class ELFT>
void ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) { void ELFDumper<ELFT>::printSymbol(const typename ELFO::Elf_Sym *Symbol,
bool IsDynamic) {
unsigned SectionIndex = 0; unsigned SectionIndex = 0;
StringRef SectionName; StringRef SectionName;
getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex); getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex);
std::string FullSymbolName = getFullSymbolName(*Obj, Symbol); std::string FullSymbolName = getFullSymbolName(*Obj, Symbol, IsDynamic);
DictScope D(W, "Symbol"); DictScope D(W, "Symbol");
W.printNumber("Name", FullSymbolName, Symbol->st_name); W.printNumber("Name", FullSymbolName, Symbol->st_name);
@ -1160,13 +1156,13 @@ template <class ELFT> class MipsGOTParser {
public: public:
typedef object::ELFFile<ELFT> ObjectFile; typedef object::ELFFile<ELFT> ObjectFile;
typedef typename ObjectFile::Elf_Shdr Elf_Shdr; typedef typename ObjectFile::Elf_Shdr Elf_Shdr;
typedef typename ObjectFile::Elf_Sym Elf_Sym;
MipsGOTParser(const ObjectFile *Obj, StreamWriter &W) : Obj(Obj), W(W) {} MipsGOTParser(const ObjectFile *Obj, StreamWriter &W) : Obj(Obj), W(W) {}
void parseGOT(const Elf_Shdr &GOTShdr); void parseGOT(const Elf_Shdr &GOTShdr);
private: private:
typedef typename ObjectFile::Elf_Sym_Iter Elf_Sym_Iter;
typedef typename ObjectFile::Elf_Addr GOTEntry; typedef typename ObjectFile::Elf_Addr GOTEntry;
typedef typename ObjectFile::template ELFEntityIterator<const GOTEntry> typedef typename ObjectFile::template ELFEntityIterator<const GOTEntry>
GOTIter; GOTIter;
@ -1180,7 +1176,7 @@ private:
bool getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym); bool getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym);
void printGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It); void printGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It);
void printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It, void printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It,
Elf_Sym_Iter Sym); const Elf_Sym *Sym, bool IsDynamic);
}; };
} }
@ -1206,8 +1202,8 @@ void MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) {
return; return;
} }
Elf_Sym_Iter DynSymBegin = Obj->begin_dynamic_symbols(); const Elf_Sym *DynSymBegin = Obj->begin_dynamic_symbols();
Elf_Sym_Iter DynSymEnd = Obj->end_dynamic_symbols(); const Elf_Sym *DynSymEnd = Obj->end_dynamic_symbols();
std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd)); std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
if (DtGotSym > DynSymTotal) { if (DtGotSym > DynSymTotal) {
@ -1255,10 +1251,10 @@ void MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) {
ListScope GS(W, "Global entries"); ListScope GS(W, "Global entries");
GOTIter GotGlobalEnd = makeGOTIter(*GOT, DtLocalGotNum + GlobalGotNum); GOTIter GotGlobalEnd = makeGOTIter(*GOT, DtLocalGotNum + GlobalGotNum);
Elf_Sym_Iter GotDynSym = DynSymBegin + DtGotSym; const Elf_Sym *GotDynSym = DynSymBegin + DtGotSym;
for (; It != GotGlobalEnd; ++It) { for (; It != GotGlobalEnd; ++It) {
DictScope D(W, "Entry"); DictScope D(W, "Entry");
printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++); printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++, true);
} }
} }
@ -1319,7 +1315,8 @@ void MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr, GOTIter BeginIt,
template <class ELFT> template <class ELFT>
void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt,
GOTIter It, Elf_Sym_Iter Sym) { GOTIter It, const Elf_Sym *Sym,
bool IsDynamic) {
printGotEntry(GotAddr, BeginIt, It); printGotEntry(GotAddr, BeginIt, It);
W.printHex("Value", Sym->st_value); W.printHex("Value", Sym->st_value);
@ -1330,7 +1327,7 @@ void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt,
getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex); getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex);
W.printHex("Section", SectionName, SectionIndex); W.printHex("Section", SectionName, SectionIndex);
std::string FullSymbolName = getFullSymbolName(*Obj, Sym); std::string FullSymbolName = getFullSymbolName(*Obj, Sym, IsDynamic);
W.printNumber("Name", FullSymbolName, Sym->st_name); W.printNumber("Name", FullSymbolName, Sym->st_name);
} }

View File

@ -23,12 +23,12 @@ template <class ELFT>
class ELFDumper { class ELFDumper {
typedef object::Elf_Sym_Impl<ELFT> Elf_Sym; typedef object::Elf_Sym_Impl<ELFT> Elf_Sym;
typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
typedef typename object::ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word; typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word;
const object::ELFFile<ELFT> &Obj; const object::ELFFile<ELFT> &Obj;
std::error_code dumpSymbol(Elf_Sym_Iter Sym, ELFYAML::Symbol &S); std::error_code dumpSymbol(const Elf_Sym *Sym, bool IsDynamic,
ELFYAML::Symbol &S);
std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S); std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr, std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr,
ELFYAML::RelocationSection &S); ELFYAML::RelocationSection &S);
@ -122,7 +122,7 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
} }
ELFYAML::Symbol S; ELFYAML::Symbol S;
if (std::error_code EC = ELFDumper<ELFT>::dumpSymbol(SI, S)) if (std::error_code EC = ELFDumper<ELFT>::dumpSymbol(SI, false, S))
return EC; return EC;
switch (SI->getBinding()) switch (SI->getBinding())
@ -145,14 +145,14 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
} }
template <class ELFT> template <class ELFT>
std::error_code ELFDumper<ELFT>::dumpSymbol(Elf_Sym_Iter Sym, std::error_code ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, bool IsDynamic,
ELFYAML::Symbol &S) { ELFYAML::Symbol &S) {
S.Type = Sym->getType(); S.Type = Sym->getType();
S.Value = Sym->st_value; S.Value = Sym->st_value;
S.Size = Sym->st_size; S.Size = Sym->st_size;
S.Other = Sym->st_other; S.Other = Sym->st_other;
ErrorOr<StringRef> NameOrErr = Obj.getSymbolName(Sym); ErrorOr<StringRef> NameOrErr = Obj.getSymbolName(Sym, IsDynamic);
if (std::error_code EC = NameOrErr.getError()) if (std::error_code EC = NameOrErr.getError())
return EC; return EC;
S.Name = NameOrErr.get(); S.Name = NameOrErr.get();
@ -182,8 +182,10 @@ std::error_code ELFDumper<ELFT>::dumpRelocation(const Elf_Shdr *Shdr,
if (!NamePair.first) if (!NamePair.first)
return obj2yaml_error::success; return obj2yaml_error::success;
ErrorOr<StringRef> NameOrErr = const Elf_Shdr *SymTab = NamePair.first;
Obj.getSymbolName(NamePair.first, NamePair.second); const Elf_Shdr *StrTab = Obj.getSection(SymTab->sh_link);
ErrorOr<StringRef> NameOrErr = Obj.getSymbolName(StrTab, NamePair.second);
if (std::error_code EC = NameOrErr.getError()) if (std::error_code EC = NameOrErr.getError())
return EC; return EC;
R.Symbol = NameOrErr.get(); R.Symbol = NameOrErr.get();
@ -300,10 +302,11 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
// Get sh_info which is the signature. // Get sh_info which is the signature.
const Elf_Sym *symbol = Obj.getSymbol(Shdr->sh_info); const Elf_Sym *symbol = Obj.getSymbol(Shdr->sh_info);
const Elf_Shdr *symtab = Obj.getSection(Shdr->sh_link); const Elf_Shdr *symtab = Obj.getSection(Shdr->sh_link);
const Elf_Shdr *StrTab = Obj.getSection(symtab->sh_link);
auto sectionContents = Obj.getSectionContents(Shdr); auto sectionContents = Obj.getSectionContents(Shdr);
if (std::error_code ec = sectionContents.getError()) if (std::error_code ec = sectionContents.getError())
return ec; return ec;
ErrorOr<StringRef> symbolName = Obj.getSymbolName(symtab, symbol); ErrorOr<StringRef> symbolName = Obj.getSymbolName(StrTab, symbol);
if (std::error_code EC = symbolName.getError()) if (std::error_code EC = symbolName.getError())
return EC; return EC;
S->Info = *symbolName; S->Info = *symbolName;