Simplify iterating over program headers and detect corrupt ones.

We now use a simple pointer and have range loops.

llvm-svn: 242669
This commit is contained in:
Rafael Espindola 2015-07-20 13:35:33 +00:00
parent 0050b48f6c
commit 073624bb56
5 changed files with 47 additions and 54 deletions

View File

@ -349,18 +349,20 @@ public:
}
/// \brief Iterate over program header table.
typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter;
Elf_Phdr_Iter program_header_begin() const {
return Elf_Phdr_Iter(Header->e_phentsize,
(const char*)base() + Header->e_phoff);
const Elf_Phdr *program_header_begin() const {
if (Header->e_phnum && Header->e_phentsize != sizeof(Elf_Phdr))
report_fatal_error("Invalid program header size");
return reinterpret_cast<const Elf_Phdr *>(base() + Header->e_phoff);
}
Elf_Phdr_Iter program_header_end() const {
return Elf_Phdr_Iter(Header->e_phentsize,
(const char*)base() +
Header->e_phoff +
(Header->e_phnum * Header->e_phentsize));
const Elf_Phdr *program_header_end() const {
return program_header_begin() + Header->e_phnum;
}
typedef iterator_range<const Elf_Phdr *> Elf_Phdr_Range;
const Elf_Phdr_Range program_headers() const {
return make_range(program_header_begin(), program_header_end());
}
uint64_t getNumSections() const;
@ -735,21 +737,16 @@ void ELFFile<ELFT>::scanDynamicTable() {
// stack doesn't get realigned despite LoadMap having alignment 8 (PR24113).
std::unique_ptr<LoadMapT> LoadMap(new LoadMapT(Alloc));
for (Elf_Phdr_Iter PhdrI = program_header_begin(),
PhdrE = program_header_end();
PhdrI != PhdrE; ++PhdrI) {
if (PhdrI->p_type == ELF::PT_DYNAMIC) {
DynamicRegion.Addr = base() + PhdrI->p_offset;
DynamicRegion.Size = PhdrI->p_filesz;
for (const Elf_Phdr &Phdr : program_headers()) {
if (Phdr.p_type == ELF::PT_DYNAMIC) {
DynamicRegion.Addr = base() + Phdr.p_offset;
DynamicRegion.Size = Phdr.p_filesz;
DynamicRegion.EntSize = sizeof(Elf_Dyn);
continue;
}
if (PhdrI->p_type != ELF::PT_LOAD)
if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
continue;
if (PhdrI->p_filesz == 0)
continue;
LoadMap->insert(PhdrI->p_vaddr, PhdrI->p_vaddr + PhdrI->p_filesz,
PhdrI->p_offset);
LoadMap->insert(Phdr.p_vaddr, Phdr.p_vaddr + Phdr.p_filesz, Phdr.p_offset);
}
auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {

Binary file not shown.

View File

@ -31,3 +31,9 @@ RUN: not llvm-readobj -dynamic-table %p/Inputs/corrupt-invalid-strtab.elf.x86-64
RUN: 2>&1 | FileCheck --check-prefix=STRTAB %s
STRTAB: Invalid dynamic string table reference
RUN: not llvm-readobj -program-headers \
RUN: %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \
RUN: FileCheck --check-prefix=PHENTSIZE %s
PHENTSIZE: Invalid program header size

View File

@ -24,10 +24,8 @@ using namespace llvm::object;
template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
typedef ELFFile<ELFT> ELFO;
outs() << "Program Header:\n";
for (typename ELFO::Elf_Phdr_Iter pi = o->program_header_begin(),
pe = o->program_header_end();
pi != pe; ++pi) {
switch (pi->p_type) {
for (const typename ELFO::Elf_Phdr &Phdr : o->program_headers()) {
switch (Phdr.p_type) {
case ELF::PT_LOAD:
outs() << " LOAD ";
break;
@ -55,22 +53,16 @@ template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";
outs() << "off "
<< format(Fmt, (uint64_t)pi->p_offset)
<< "vaddr "
<< format(Fmt, (uint64_t)pi->p_vaddr)
<< "paddr "
<< format(Fmt, (uint64_t)pi->p_paddr)
<< format("align 2**%u\n", countTrailingZeros<uint64_t>(pi->p_align))
<< " filesz "
<< format(Fmt, (uint64_t)pi->p_filesz)
<< "memsz "
<< format(Fmt, (uint64_t)pi->p_memsz)
<< "flags "
<< ((pi->p_flags & ELF::PF_R) ? "r" : "-")
<< ((pi->p_flags & ELF::PF_W) ? "w" : "-")
<< ((pi->p_flags & ELF::PF_X) ? "x" : "-")
<< "\n";
outs() << "off " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr "
<< format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr "
<< format(Fmt, (uint64_t)Phdr.p_paddr)
<< format("align 2**%u\n",
countTrailingZeros<uint64_t>(Phdr.p_align))
<< " filesz " << format(Fmt, (uint64_t)Phdr.p_filesz)
<< "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags "
<< ((Phdr.p_flags & ELF::PF_R) ? "r" : "-")
<< ((Phdr.p_flags & ELF::PF_W) ? "w" : "-")
<< ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n";
}
outs() << "\n";
}

View File

@ -1109,20 +1109,18 @@ template<class ELFT>
void ELFDumper<ELFT>::printProgramHeaders() {
ListScope L(W, "ProgramHeaders");
for (typename ELFO::Elf_Phdr_Iter PI = Obj->program_header_begin(),
PE = Obj->program_header_end();
PI != PE; ++PI) {
for (const typename ELFO::Elf_Phdr &Phdr : Obj->program_headers()) {
DictScope P(W, "ProgramHeader");
W.printHex ("Type",
getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type),
PI->p_type);
W.printHex ("Offset", PI->p_offset);
W.printHex ("VirtualAddress", PI->p_vaddr);
W.printHex ("PhysicalAddress", PI->p_paddr);
W.printNumber("FileSize", PI->p_filesz);
W.printNumber("MemSize", PI->p_memsz);
W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags));
W.printNumber("Alignment", PI->p_align);
W.printHex("Type",
getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type),
Phdr.p_type);
W.printHex("Offset", Phdr.p_offset);
W.printHex("VirtualAddress", Phdr.p_vaddr);
W.printHex("PhysicalAddress", Phdr.p_paddr);
W.printNumber("FileSize", Phdr.p_filesz);
W.printNumber("MemSize", Phdr.p_memsz);
W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags));
W.printNumber("Alignment", Phdr.p_align);
}
}