Skip to content

Commit

Permalink
[readobj] Handle ELF files with no section table or with no program h…
Browse files Browse the repository at this point in the history
…eaders.

This adds support for finding the dynamic table and dynamic symbol table via
the section table or the program header table. If there's no section table an
attempt is made to figure out the length of the dynamic symbol table.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260488 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Bigcheese committed Feb 11, 2016
1 parent c2545ee commit f8cdb80
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 110 deletions.
17 changes: 15 additions & 2 deletions include/llvm/Object/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class ELFFile {
return reinterpret_cast<const uint8_t *>(Buf.data());
}

size_t getBufSize() const { return Buf.size(); }

private:

StringRef Buf;
Expand Down Expand Up @@ -200,6 +202,9 @@ class ELFFile {
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,
Expand All @@ -225,8 +230,15 @@ 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 - symbol_begin(SymTab);
unsigned Index = Sym - FirstSym;

// The size of the table was checked in getSHNDXTable.
return ShndxTable[Index];
Expand All @@ -238,7 +250,8 @@ 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, SymTab, ShndxTable));
return getSection(
getExtendedSymbolTableIndex(Sym, symbol_begin(SymTab), ShndxTable));

if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
return nullptr;
Expand Down
Binary file not shown.
11 changes: 2 additions & 9 deletions test/Object/corrupt.test
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,17 @@ 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 relocation entry size
RELOC: Invalid entity 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 dynamic table size
DYN-TABLE-SIZE: Invalid entity size


RUN: not llvm-readobj -dyn-relocations \
Expand Down
4 changes: 3 additions & 1 deletion test/Object/invalid.test
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ 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
Expand Down
Binary file not shown.
Binary file not shown.
198 changes: 198 additions & 0 deletions test/tools/llvm-readobj/dynamic-symbols.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
RUN: llvm-readobj -dyn-symbols -dynamic-table \
RUN: %S/Inputs/dynamic-table-exe-no-shdrs.x86 | FileCheck %s
RUN: llvm-readobj -dyn-symbols -dynamic-table \
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-NEXT: 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: ]
Loading

0 comments on commit f8cdb80

Please sign in to comment.