This reverts commit r260488 and r260489.

Original messages:
    Revert "[readobj] Handle ELF files with no section table or with no program headers."
    Revert "[readobj] Dump DT_JMPREL relocations when outputting dynamic relocations."

r260489 depends on r260488 and among other issues r260488 deleted error
handling code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260962 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2016-02-16 14:17:48 +00:00
parent e13835e919
commit ed783357b0
10 changed files with 108 additions and 440 deletions

View File

@ -62,8 +62,6 @@ public:
return reinterpret_cast<const uint8_t *>(Buf.data());
}
size_t getBufSize() const { return Buf.size(); }
private:
StringRef Buf;
@ -202,9 +200,6 @@ public:
uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
const Elf_Shdr *SymTab,
ArrayRef<Elf_Word> ShndxTable) const;
uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
const Elf_Sym *FirstSym,
ArrayRef<Elf_Word> ShndxTable) const;
const Elf_Ehdr *getHeader() const { return Header; }
ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
const Elf_Shdr *SymTab,
@ -230,15 +225,8 @@ template <class ELFT>
uint32_t ELFFile<ELFT>::getExtendedSymbolTableIndex(
const Elf_Sym *Sym, const Elf_Shdr *SymTab,
ArrayRef<Elf_Word> ShndxTable) const {
return getExtendedSymbolTableIndex(Sym, symbol_begin(SymTab), ShndxTable);
}
template <class ELFT>
uint32_t ELFFile<ELFT>::getExtendedSymbolTableIndex(
const Elf_Sym *Sym, const Elf_Sym *FirstSym,
ArrayRef<Elf_Word> ShndxTable) const {
assert(Sym->st_shndx == ELF::SHN_XINDEX);
unsigned Index = Sym - FirstSym;
unsigned Index = Sym - symbol_begin(SymTab);
// The size of the table was checked in getSHNDXTable.
return ShndxTable[Index];
@ -250,8 +238,7 @@ 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(Sym, symbol_begin(SymTab), ShndxTable));
return getSection(getExtendedSymbolTableIndex(Sym, SymTab, ShndxTable));
if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
return nullptr;

Binary file not shown.

View File

@ -38,17 +38,24 @@ RUN: FileCheck --check-prefix=PHENTSIZE %s
PHENTSIZE: Invalid program header size
RUN: not llvm-readobj -dynamic-table \
RUN: %p/Inputs/corrupt-invalid-virtual-addr.elf.x86-64 2>&1 | \
RUN: FileCheck --check-prefix=VIRTADDR %s
VIRTADDR: Virtual address is not in any segment
RUN: not llvm-readobj -dyn-relocations \
RUN: %p/Inputs/corrupt-invalid-relocation-size.elf.x86-64 2>&1 | \
RUN: FileCheck --check-prefix=RELOC %s
RELOC: Invalid entity size
RELOC: Invalid relocation entry size
RUN: not llvm-readobj -dyn-relocations \
RUN: %p/Inputs/corrupt-invalid-dynamic-table-size.elf.x86-64 2>&1 | \
RUN: FileCheck --check-prefix=DYN-TABLE-SIZE %s
DYN-TABLE-SIZE: Invalid entity size
DYN-TABLE-SIZE: Invalid dynamic table size
RUN: not llvm-readobj -dyn-relocations \

View File

@ -35,11 +35,9 @@ SECTION-NEXT: AddressAlignment:
SECTION-NEXT: EntrySize: 32
RUN: not llvm-readobj -t %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-SYM-SIZE %s
RUN: not llvm-readobj --dyn-symbols %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-SYM-SIZE %s
INVALID-SYM-SIZE: Invalid symbol size
RUN: not llvm-readobj --dyn-symbols %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-DYNSYM-SIZE %s
INVALID-DYNSYM-SIZE: Invalid entity size
RUN: not llvm-readobj -t %p/Inputs/invalid-section-index.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-INDEX %s
INVALID-SECTION-INDEX: Invalid section index

View File

@ -34,18 +34,6 @@ RUN: %p/Inputs/hello-world.elf-x86-64 | FileCheck %s --check-prefix=DYN
// DYN-NEXT: Symbol: __gmon_start__
// DYN-NEXT: Addend: 0x0
// DYN-NEXT: }
// DYN-NEXT: Relocation {
// DYN-NEXT: Offset: 0x4018F8
// DYN-NEXT: Type: R_X86_64_JUMP_SLOT (7)
// DYN-NEXT: Symbol: __libc_start_main
// DYN-NEXT: Addend: 0x0
// DYN-NEXT: }
// DYN-NEXT: Relocation {
// DYN-NEXT: Offset: 0x401900
// DYN-NEXT: Type: R_X86_64_JUMP_SLOT (7)
// DYN-NEXT: Symbol: puts
// DYN-NEXT: Addend: 0x0
// DYN-NEXT: }
// DYN-NEXT: }
RUN: llvm-readobj -dyn-relocations -expand-relocs \

View File

@ -1,223 +0,0 @@
RUN: llvm-readobj -dyn-symbols -dynamic-table -dyn-relocations \
RUN: %S/Inputs/dynamic-table-exe-no-shdrs.x86 | FileCheck %s
RUN: llvm-readobj -dyn-symbols -dynamic-table -relocations \
RUN: %S/Inputs/dynamic-table-exe-no-phdrs.x86 | FileCheck %s
CHECK: File:
CHECK-NEXT: Format: ELF32-i386
CHECK-NEXT: Arch: i386
CHECK-NEXT: AddressSize: 32bit
CHECK-NEXT: LoadName:
CHECK: 0x85F R_386_RELATIVE - 0x0
CHECK-NEXT: 0x874 R_386_RELATIVE - 0x0
CHECK-NEXT: 0x19FC R_386_RELATIVE - 0x0
CHECK-NEXT: 0x1A00 R_386_RELATIVE - 0x0
CHECK-NEXT: 0x1B2C R_386_RELATIVE - 0x0
CHECK-NEXT: 0x1B60 R_386_RELATIVE - 0x0
CHECK-NEXT: 0x0 R_386_NONE - 0x0
CHECK-NEXT: 0x864 R_386_PC32 puts 0x0
CHECK-NEXT: 0x880 R_386_PC32 _ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode 0x0
CHECK-NEXT: 0x88C R_386_PC32 _ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev 0x0
CHECK-NEXT: 0x89B R_386_PC32 _Unwind_Resume 0x0
CHECK-NEXT: 0x9BB R_386_32 __gxx_personality_v0 0x0
CHECK-NEXT: 0x1B18 R_386_GLOB_DAT __gmon_start__ 0x0
CHECK-NEXT: 0x1B1C R_386_GLOB_DAT _Jv_RegisterClasses 0x0
CHECK-NEXT: 0x1B20 R_386_GLOB_DAT _ITM_deregisterTMCloneTable 0x0
CHECK-NEXT: 0x1B24 R_386_GLOB_DAT _ITM_registerTMCloneTable 0x0
CHECK-NEXT: 0x1B28 R_386_GLOB_DAT __cxa_finalize 0x0
CHECK: 0x1B3C R_386_JUMP_SLOT __gmon_start__ 0x0
CHECK-NEXT: 0x1B40 R_386_JUMP_SLOT __libc_start_main 0x0
CHECK-NEXT: 0x1B44 R_386_JUMP_SLOT _ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev 0x0
CHECK-NEXT: 0x1B48 R_386_JUMP_SLOT _ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode 0x0
CHECK-NEXT: 0x1B4C R_386_JUMP_SLOT puts 0x0
CHECK-NEXT: 0x1B50 R_386_JUMP_SLOT __gxx_personality_v0 0x0
CHECK-NEXT: 0x1B54 R_386_JUMP_SLOT _Unwind_Resume 0x0
CHECK-NEXT: 0x1B58 R_386_JUMP_SLOT __cxa_finalize 0x0
CHECK: DynamicSymbols [
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: @
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Local
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: __gmon_start__@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Weak
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _Jv_RegisterClasses@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Weak
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: __libc_start_main@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _ITM_deregisterTMCloneTable@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Weak
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _ITM_registerTMCloneTable@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Weak
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: puts@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: __gxx_personality_v0@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _Unwind_Resume@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: __cxa_finalize@
CHECK-NEXT: Value: 0x0
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Weak
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Undefined
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _end@
CHECK-NEXT: Value: 0x1B68
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Absolute
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _edata@
CHECK-NEXT: Value: 0x1B64
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Absolute
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: _IO_stdin_used@
CHECK-NEXT: Value: 0x93C
CHECK-NEXT: Size: 4
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Object
CHECK-NEXT: Other: 0
CHECK-NEXT: Section:
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: __bss_start@
CHECK-NEXT: Value: 0x1B64
CHECK-NEXT: Size: 0
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: None
CHECK-NEXT: Other: 0
CHECK-NEXT: Section: Absolute
CHECK-NEXT: }
CHECK-NEXT: Symbol {
CHECK-NEXT: Name: main@
CHECK-NEXT: Value: 0x850
CHECK-NEXT: Size: 81
CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK-NEXT: Other: 0
CHECK-NEXT: Section:
CHECK-NEXT: }
CHECK-NEXT: ]
CHECK-NEXT: DynamicSection [
CHECK-NEXT: Tag Type Name/Value
CHECK-NEXT: 0x00000001 NEEDED SharedLibrary (libstdc++.so.6)
CHECK-NEXT: 0x00000001 NEEDED SharedLibrary (libgcc_s.so.1)
CHECK-NEXT: 0x00000001 NEEDED SharedLibrary (libc.so.6)
CHECK-NEXT: 0x0000000C INIT 0x62C
CHECK-NEXT: 0x0000000D FINI 0x920
CHECK-NEXT: 0x00000019 INIT_ARRAY 0x19FC
CHECK-NEXT: 0x0000001B INIT_ARRAYSZ 4
CHECK-NEXT: 0x0000001A FINI_ARRAY 0x1A00
CHECK-NEXT: 0x0000001C FINI_ARRAYSZ 4
CHECK-NEXT: 0x00000004 HASH 0x18C
CHECK-NEXT: 0x6FFFFEF5 GNU_HASH 0x1E4
CHECK-NEXT: 0x00000005 STRTAB 0x328
CHECK-NEXT: 0x00000006 SYMTAB 0x218
CHECK-NEXT: 0x0000000A STRSZ 408
CHECK-NEXT: 0x0000000B SYMENT 16
CHECK-NEXT: 0x00000015 DEBUG 0x0
CHECK-NEXT: 0x00000003 PLTGOT 0x1B30
CHECK-NEXT: 0x00000002 PLTRELSZ 64
CHECK-NEXT: 0x00000014 PLTREL REL
CHECK-NEXT: 0x00000017 JMPREL 0x5EC
CHECK-NEXT: 0x00000011 REL 0x564
CHECK-NEXT: 0x00000012 RELSZ 136
CHECK-NEXT: 0x00000013 RELENT 8
CHECK-NEXT: 0x00000016 TEXTREL 0x0
CHECK-NEXT: 0x0000001E FLAGS TEXTREL
CHECK-NEXT: 0x6FFFFFFE VERNEED 0x4E4
CHECK-NEXT: 0x6FFFFFFF VERNEEDNUM 3
CHECK-NEXT: 0x6FFFFFF0 VERSYM 0x4C0
CHECK-NEXT: 0x6FFFFFFA RELCOUNT 6
CHECK-NEXT: 0x00000000 NULL 0x0
CHECK-NEXT: ]

View File

@ -48,28 +48,6 @@ namespace {
template <class ELFT> class DumpStyle;
/// \brief Represents a region described by entries in the .dynamic table.
struct DynRegionInfo {
DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
DynRegionInfo(const void *A, uint64_t S, uint64_t ES)
: Addr(A), Size(S), EntSize(ES) {}
/// \brief Address in current address space.
const void *Addr;
/// \brief Size in bytes of the region.
uint64_t Size;
/// \brief Size of each entity in the region.
uint64_t EntSize;
template <typename Type> iterator_range<const Type *> getAsRange() const {
const Type *Start = reinterpret_cast<const Type *>(Addr);
if (Size == 0)
return {Start, Start};
if (EntSize != sizeof(Type) || Size % EntSize)
reportError("Invalid entity size");
return {Start, Start + (Size / EntSize)};
}
};
template<typename ELFT>
class ELFDumper : public ObjDumper {
public:
@ -104,7 +82,6 @@ private:
typedef ELFFile<ELFT> ELFO;
typedef typename ELFO::Elf_Shdr Elf_Shdr;
typedef typename ELFO::Elf_Sym Elf_Sym;
typedef typename ELFO::Elf_Sym_Range Elf_Sym_Range;
typedef typename ELFO::Elf_Dyn Elf_Dyn;
typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range;
typedef typename ELFO::Elf_Rel Elf_Rel;
@ -124,25 +101,21 @@ private:
typedef typename ELFO::Elf_Verdef Elf_Verdef;
typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
DynRegionInfo checkDRI(DynRegionInfo DRI) {
if (DRI.Addr < Obj->base() ||
(const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
error(llvm::object::object_error::parse_failed);
return DRI;
}
DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize});
}
DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize});
}
/// \brief Represents a region described by entries in the .dynamic table.
struct DynRegionInfo {
DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
/// \brief Address in current address space.
const void *Addr;
/// \brief Size in bytes of the region.
uintX_t Size;
/// \brief Size of each entity in the region.
uintX_t EntSize;
};
void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
void printSymbolsHelper(bool IsDynamic);
void printSymbol(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
StringRef StrTable, bool IsDynamic);
void printDynamicRelocation(Elf_Rela Rel);
@ -150,9 +123,23 @@ private:
void printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab);
void printValue(uint64_t Type, uint64_t Value);
template <typename REL>
static const REL *dyn_rel_begin(const DynRegionInfo &region);
template <typename REL>
static const REL *dyn_rel_end(const DynRegionInfo &region);
Elf_Rel_Range dyn_rels() const;
Elf_Rela_Range dyn_relas() const;
StringRef getDynamicString(uint64_t Offset) const;
const Elf_Dyn *dynamic_table_begin() const {
ErrorOr<const Elf_Dyn *> Ret = Obj->dynamic_table_begin(DynamicProgHeader);
error(Ret.getError());
return *Ret;
}
const Elf_Dyn *dynamic_table_end() const {
ErrorOr<const Elf_Dyn *> Ret = Obj->dynamic_table_end(DynamicProgHeader);
error(Ret.getError());
return *Ret;
}
StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
bool &IsDefault);
void LoadVersionMap();
@ -160,18 +147,15 @@ private:
void LoadVersionDefs(const Elf_Shdr *sec) const;
const ELFO *Obj;
DynRegionInfo DynamicTable;
// Dynamic relocation info.
DynRegionInfo DynRelRegion;
DynRegionInfo DynRelaRegion;
DynRegionInfo DynPLTRelRegion;
DynRegionInfo DynSymRegion;
const Elf_Phdr *DynamicProgHeader = nullptr;
StringRef DynamicStringTable;
const Elf_Sym *DynSymStart = nullptr;
StringRef SOName;
const Elf_Hash *HashTable = nullptr;
const Elf_GnuHash *GnuHashTable = nullptr;
const Elf_Shdr *DotDynSymSec = nullptr;
const Elf_Shdr *DotSymtabSec = nullptr;
ArrayRef<Elf_Word> ShndxTable;
@ -204,18 +188,16 @@ private:
public:
Elf_Dyn_Range dynamic_table() const {
return DynamicTable.getAsRange<Elf_Dyn>();
}
Elf_Sym_Range dynamic_symbols() const {
return DynSymRegion.getAsRange<Elf_Sym>();
ErrorOr<Elf_Dyn_Range> Ret = Obj->dynamic_table(DynamicProgHeader);
error(Ret.getError());
return *Ret;
}
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; }
StringRef getDynamicStringTable() const { return DynamicStringTable; }
};
template <typename ELFT> class DumpStyle {
@ -358,7 +340,7 @@ void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() {
// If there is no dynamic symtab or version table, there is nothing to do.
if (!DynSymRegion.Addr || !dot_gnu_version_sec)
if (!DynSymStart || !dot_gnu_version_sec)
return;
// Has the VersionMap already been loaded?
@ -392,15 +374,18 @@ static void printVersionSymbolSection(ELFDumper<ELFT> *Dumper,
W.printHex("Offset", Sec->sh_offset);
W.printNumber("Link", Sec->sh_link);
const typename ELFO::Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
const uint8_t *P = (const uint8_t *)Obj->base() + Sec->sh_offset;
StringRef StrTable = Dumper->getDynamicStringTable();
ErrorOr<StringRef> StrTableOrErr =
Obj->getStringTableForSymtab(*DynSymSec);
error(StrTableOrErr.getError());
// Same number of entries in the dynamic symbol table (DT_SYMTAB).
ListScope Syms(W, "Symbols");
for (const typename ELFO::Elf_Sym &Sym : Dumper->dynamic_symbols()) {
for (const typename ELFO::Elf_Sym &Sym : Obj->symbols(DynSymSec)) {
DictScope S(W, "Symbol");
std::string FullSymbolName =
Dumper->getFullSymbolName(&Sym, StrTable, true /* IsDynamic */);
Dumper->getFullSymbolName(&Sym, *StrTableOrErr, true /* IsDynamic */);
W.printNumber("Version", *P);
W.printString("Name", FullSymbolName);
P += sizeof(typename ELFO::Elf_Half);
@ -476,7 +461,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
// Determine the position in the symbol table of this entry.
size_t entry_index = (reinterpret_cast<uintptr_t>(symb) -
reinterpret_cast<uintptr_t>(DynSymRegion.Addr)) /
reinterpret_cast<uintptr_t>(DynSymStart)) /
sizeof(Elf_Sym);
// Get the corresponding version index entry
@ -532,7 +517,7 @@ std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
template <typename ELFO>
static void
getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
const typename ELFO::Elf_Sym *FirstSym,
const typename ELFO::Elf_Shdr *SymTab,
ArrayRef<typename ELFO::Elf_Word> ShndxTable,
StringRef &SectionName, unsigned &SectionIndex) {
SectionIndex = Symbol->st_shndx;
@ -551,7 +536,7 @@ getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol,
else {
if (SectionIndex == SHN_XINDEX)
SectionIndex =
Obj.getExtendedSymbolTableIndex(Symbol, FirstSym, ShndxTable);
Obj.getExtendedSymbolTableIndex(Symbol, SymTab, ShndxTable);
ErrorOr<const typename ELFO::Elf_Shdr *> Sec = Obj.getSection(SectionIndex);
error(Sec.getError());
SectionName = errorOrDefault(Obj.getSectionName(*Sec));
@ -1005,7 +990,7 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
SmallVector<const Elf_Phdr *, 4> LoadSegments;
for (const Elf_Phdr &Phdr : Obj->program_headers()) {
if (Phdr.p_type == ELF::PT_DYNAMIC) {
DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
DynamicProgHeader = &Phdr;
continue;
}
if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
@ -1020,17 +1005,10 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
reportError("Multilpe SHT_SYMTAB");
DotSymtabSec = &Sec;
break;
case ELF::SHT_DYNAMIC: {
if (DynamicTable.Addr == nullptr)
DynamicTable = createDRIFrom(&Sec);
const Elf_Shdr *DynStrSec = unwrapOrError(Obj->getSection(Sec.sh_link));
DynamicStringTable = unwrapOrError(Obj->getStringTable(DynStrSec));
break;
}
case ELF::SHT_DYNSYM:
// The dynamic table does not contain the size of the dynamic symbol
// table, so get that from the section table if present.
DynSymRegion = createDRIFrom(&Sec);
if (DotDynSymSec != nullptr)
reportError("Multilpe SHT_DYNSYM");
DotDynSymSec = &Sec;
break;
case ELF::SHT_SYMTAB_SHNDX: {
ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj->getSHNDXTable(Sec);
@ -1071,12 +1049,12 @@ void ELFDumper<ELFT>::parseDynamicTable(
const Elf_Phdr *const *I = std::upper_bound(
LoadSegments.begin(), LoadSegments.end(), VAddr, compareAddr<ELFT>);
if (I == LoadSegments.begin())
return nullptr;
report_fatal_error("Virtual address is not in any segment");
--I;
const Elf_Phdr &Phdr = **I;
uint64_t Delta = VAddr - Phdr.p_vaddr;
if (Delta >= Phdr.p_filesz)
return nullptr;
report_fatal_error("Virtual address is not in any segment");
return Obj->base() + Phdr.p_offset + Delta;
};
@ -1100,11 +1078,8 @@ void ELFDumper<ELFT>::parseDynamicTable(
StringTableSize = Dyn.getVal();
break;
case ELF::DT_SYMTAB:
if (DynSymRegion.Addr)
break;
DynSymRegion.Addr = toMappedAddr(Dyn.getPtr());
DynSymRegion.EntSize = sizeof(Elf_Sym);
// Figure out the size once we have scanned the entire dynamic table.
DynSymStart =
reinterpret_cast<const Elf_Sym *>(toMappedAddr(Dyn.getPtr()));
break;
case ELF::DT_RELA:
DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr());
@ -1127,81 +1102,41 @@ void ELFDumper<ELFT>::parseDynamicTable(
case ELF::DT_RELENT:
DynRelRegion.EntSize = Dyn.getVal();
break;
case ELF::DT_PLTREL:
if (Dyn.getVal() == DT_REL)
DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
else if (Dyn.getVal() == DT_RELA)
DynPLTRelRegion.EntSize = sizeof(Elf_Rela);
else
reportError(Twine("unknown DT_PLTREL value of ") +
Twine((uint64_t)Dyn.getVal()));
break;
case ELF::DT_JMPREL:
DynPLTRelRegion.Addr = toMappedAddr(Dyn.getPtr());
break;
case ELF::DT_PLTRELSZ:
DynPLTRelRegion.Size = Dyn.getVal();
break;
}
}
if (StringTableBegin)
DynamicStringTable = StringRef(StringTableBegin, StringTableSize);
if (SONameOffset)
SOName = getDynamicString(SONameOffset);
if (DynSymRegion.Addr && !DynSymRegion.Size) {
// There was no section table entry for the dynamic section, and there is
// no DT entry describing its size, so attempt to guess at its size.
// Initally guess that it ends at the end of the file.
const void *Start = DynSymRegion.Addr;
const void *End = Obj->base() + Obj->getBufSize();
}
// Check all the sections we know about.
for (const Elf_Shdr &Sec : Obj->sections()) {
const void *Addr = Obj->base() + Sec.sh_offset;
if (Addr >= Start && Addr < End)
End = Addr;
}
template <typename ELFT>
template <typename REL>
const REL *ELFDumper<ELFT>::dyn_rel_begin(const DynRegionInfo &Region) {
if (Region.Size && Region.EntSize != sizeof(REL))
report_fatal_error("Invalid relocation entry size");
return reinterpret_cast<const REL *>(Region.Addr);
}
// Check all the dynamic regions we know about.
auto CheckDRI = [&](DynRegionInfo DRI) {
if (DRI.Addr >= Start && DRI.Addr < End)
End = DRI.Addr;
};
CheckDRI(DynamicTable);
CheckDRI(DynRelRegion);
CheckDRI(DynRelaRegion);
CheckDRI(DynPLTRelRegion);
if (DynamicStringTable.data() >= Start && DynamicStringTable.data() < End)
End = DynamicStringTable.data();
// Scan to the first invalid symbol.
auto SymI = reinterpret_cast<const Elf_Sym *>(Start);
for (; ((const char *)SymI + sizeof(Elf_Sym)) <= End; ++SymI) {
uint32_t NameOffset = SymI->st_name;
if (SymI > Start && !NameOffset)
break;
if (NameOffset >= DynamicStringTable.size())
break;
uint16_t SectionIndex = SymI->st_shndx;
if ((Obj->getNumSections() && SectionIndex >= Obj->getNumSections()) &&
SectionIndex < SHN_LORESERVE)
break;
}
End = SymI;
DynSymRegion.Size = (const char *)End - (const char *)Start;
}
template <typename ELFT>
template <typename REL>
const REL *ELFDumper<ELFT>::dyn_rel_end(const DynRegionInfo &Region) {
uint64_t Size = Region.Size;
if (Size % sizeof(REL))
report_fatal_error("Invalid relocation table size");
return dyn_rel_begin<REL>(Region) + Size / sizeof(REL);
}
template <typename ELFT>
typename ELFDumper<ELFT>::Elf_Rel_Range ELFDumper<ELFT>::dyn_rels() const {
return DynRelRegion.getAsRange<Elf_Rel>();
return make_range(dyn_rel_begin<Elf_Rel>(DynRelRegion),
dyn_rel_end<Elf_Rel>(DynRelRegion));
}
template <typename ELFT>
typename ELFDumper<ELFT>::Elf_Rela_Range ELFDumper<ELFT>::dyn_relas() const {
return DynRelaRegion.getAsRange<Elf_Rela>();
return make_range(dyn_rel_begin<Elf_Rela>(DynRelaRegion),
dyn_rel_end<Elf_Rela>(DynRelaRegion));
}
template<class ELFT>
@ -1276,7 +1211,7 @@ void ELFDumper<ELFT>::printSections() {
if (!SymSec)
continue;
if (*SymSec == &Sec)
printSymbol(&Sym, Obj->symbol_begin(Symtab), StrTable, false);
printSymbol(&Sym, Symtab, StrTable, false);
}
}
@ -1327,17 +1262,6 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
Rela.r_addend = 0;
printDynamicRelocation(Rela);
}
if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange<Elf_Rela>())
printDynamicRelocation(Rela);
else
for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange<Elf_Rel>()) {
Elf_Rela Rela;
Rela.r_offset = Rel.r_offset;
Rela.r_info = Rel.r_info;
Rela.r_addend = 0;
printDynamicRelocation(Rela);
}
W.unindent();
W.startLine() << "}\n";
}
@ -1404,8 +1328,7 @@ void ELFDumper<ELFT>::printDynamicRelocation(Elf_Rela Rel) {
Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
StringRef SymbolName;
uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
const Elf_Sym *Sym =
DynSymRegion.getAsRange<Elf_Sym>().begin() + SymIndex;
const Elf_Sym *Sym = DynSymStart + SymIndex;
SymbolName = errorOrDefault(Sym->getName(DynamicStringTable));
if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation");
@ -1423,21 +1346,14 @@ void ELFDumper<ELFT>::printDynamicRelocation(Elf_Rela Rel) {
template<class ELFT>
void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) {
StringRef StrTable = DynamicStringTable;
Elf_Sym_Range Syms(nullptr, nullptr);
if (IsDynamic)
Syms = DynSymRegion.getAsRange<Elf_Sym>();
else {
if (!DotSymtabSec)
const Elf_Shdr *Symtab = (IsDynamic) ? DotDynSymSec : DotSymtabSec;
if (!Symtab)
return;
ErrorOr<StringRef> StrTableOrErr =
Obj->getStringTableForSymtab(*DotSymtabSec);
ErrorOr<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(*Symtab);
error(StrTableOrErr.getError());
StrTable = *StrTableOrErr;
Syms = Obj->symbols(DotSymtabSec);
}
for (const Elf_Sym &Sym : Syms)
printSymbol(&Sym, Syms.begin(), StrTable, IsDynamic);
StringRef StrTable = *StrTableOrErr;
for (const Elf_Sym &Sym : Obj->symbols(Symtab))
printSymbol(&Sym, Symtab, StrTable, IsDynamic);
}
template<class ELFT>
@ -1453,12 +1369,11 @@ void ELFDumper<ELFT>::printDynamicSymbols() {
}
template <class ELFT>
void ELFDumper<ELFT>::printSymbol(const Elf_Sym *Symbol,
const Elf_Sym *FirstSym, 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, FirstSym, ShndxTable, SectionName,
getSectionNameIndex(*Obj, Symbol, SymTab, ShndxTable, SectionName,
SectionIndex);
std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic);
unsigned char SymbolType = Symbol->getType();
@ -1735,8 +1650,8 @@ template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() {
template<class ELFT>
void ELFDumper<ELFT>::printDynamicTable() {
auto I = dynamic_table().begin();
auto E = dynamic_table().end();
auto I = dynamic_table_begin();
auto E = dynamic_table_end();
if (I == E)
return;
@ -1832,10 +1747,10 @@ void ELFDumper<ELFT>::printGnuHashTable() {
W.printNumber("Shift Count", GnuHashTable->shift2);
W.printHexList("Bloom Filter", GnuHashTable->filter());
W.printList("Buckets", GnuHashTable->buckets());
if (!DynSymRegion.Size || !DynSymRegion.EntSize)
if (!DotDynSymSec)
reportError("No dynamic symbol section");
W.printHexList(
"Values", GnuHashTable->values(DynSymRegion.Size / DynSymRegion.EntSize));
W.printHexList("Values",
GnuHashTable->values(DotDynSymSec->getEntityCount()));
}
template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {
@ -1963,9 +1878,11 @@ template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() {
return;
}
StringRef StrTable = Dumper->getDynamicStringTable();
const Elf_Sym *DynSymBegin = Dumper->dynamic_symbols().begin();
const Elf_Sym *DynSymEnd = Dumper->dynamic_symbols().end();
const Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
ErrorOr<StringRef> StrTable = Obj->getStringTableForSymtab(*DynSymSec);
error(StrTable.getError());
const Elf_Sym *DynSymBegin = Obj->symbol_begin(DynSymSec);
const Elf_Sym *DynSymEnd = Obj->symbol_end(DynSymSec);
std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
if (*DtGotSym > DynSymTotal)
@ -2025,8 +1942,8 @@ template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() {
const Elf_Sym *GotDynSym = DynSymBegin + *DtGotSym;
for (; It != GotGlobalEnd; ++It) {
DictScope D(W, "Entry");
printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++, StrTable,
true);
printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++,
*StrTable, true);
}
}
@ -2129,7 +2046,7 @@ void MipsGOTParser<ELFT>::printGlobalGotEntry(
unsigned SectionIndex = 0;
StringRef SectionName;
getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(),
getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
Dumper->getShndxTable(), SectionName, SectionIndex);
W.printHex("Section", SectionName, SectionIndex);
@ -2163,7 +2080,7 @@ void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr,
unsigned SectionIndex = 0;
StringRef SectionName;
getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(),
getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(),
Dumper->getShndxTable(), SectionName, SectionIndex);
W.printHex("Section", SectionName, SectionIndex);

View File

@ -12,7 +12,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorOr.h"
#include <string>
namespace llvm {
@ -23,11 +22,6 @@ namespace llvm {
// Various helper functions.
LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg);
void error(std::error_code ec);
template <class T> T unwrapOrError(ErrorOr<T> EO) {
if (EO)
return *EO;
reportError(EO.getError().message());
}
bool relocAddressLess(object::RelocationRef A,
object::RelocationRef B);
} // namespace llvm