forked from OSchip/llvm-project
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:
parent
0050b48f6c
commit
073624bb56
|
@ -349,18 +349,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Iterate over program header table.
|
/// \brief Iterate over program header table.
|
||||||
typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter;
|
const Elf_Phdr *program_header_begin() const {
|
||||||
|
if (Header->e_phnum && Header->e_phentsize != sizeof(Elf_Phdr))
|
||||||
Elf_Phdr_Iter program_header_begin() const {
|
report_fatal_error("Invalid program header size");
|
||||||
return Elf_Phdr_Iter(Header->e_phentsize,
|
return reinterpret_cast<const Elf_Phdr *>(base() + Header->e_phoff);
|
||||||
(const char*)base() + Header->e_phoff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf_Phdr_Iter program_header_end() const {
|
const Elf_Phdr *program_header_end() const {
|
||||||
return Elf_Phdr_Iter(Header->e_phentsize,
|
return program_header_begin() + Header->e_phnum;
|
||||||
(const char*)base() +
|
}
|
||||||
Header->e_phoff +
|
|
||||||
(Header->e_phnum * Header->e_phentsize));
|
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;
|
uint64_t getNumSections() const;
|
||||||
|
@ -735,21 +737,16 @@ void ELFFile<ELFT>::scanDynamicTable() {
|
||||||
// stack doesn't get realigned despite LoadMap having alignment 8 (PR24113).
|
// stack doesn't get realigned despite LoadMap having alignment 8 (PR24113).
|
||||||
std::unique_ptr<LoadMapT> LoadMap(new LoadMapT(Alloc));
|
std::unique_ptr<LoadMapT> LoadMap(new LoadMapT(Alloc));
|
||||||
|
|
||||||
for (Elf_Phdr_Iter PhdrI = program_header_begin(),
|
for (const Elf_Phdr &Phdr : program_headers()) {
|
||||||
PhdrE = program_header_end();
|
if (Phdr.p_type == ELF::PT_DYNAMIC) {
|
||||||
PhdrI != PhdrE; ++PhdrI) {
|
DynamicRegion.Addr = base() + Phdr.p_offset;
|
||||||
if (PhdrI->p_type == ELF::PT_DYNAMIC) {
|
DynamicRegion.Size = Phdr.p_filesz;
|
||||||
DynamicRegion.Addr = base() + PhdrI->p_offset;
|
|
||||||
DynamicRegion.Size = PhdrI->p_filesz;
|
|
||||||
DynamicRegion.EntSize = sizeof(Elf_Dyn);
|
DynamicRegion.EntSize = sizeof(Elf_Dyn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (PhdrI->p_type != ELF::PT_LOAD)
|
if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
|
||||||
continue;
|
continue;
|
||||||
if (PhdrI->p_filesz == 0)
|
LoadMap->insert(Phdr.p_vaddr, Phdr.p_vaddr + Phdr.p_filesz, Phdr.p_offset);
|
||||||
continue;
|
|
||||||
LoadMap->insert(PhdrI->p_vaddr, PhdrI->p_vaddr + PhdrI->p_filesz,
|
|
||||||
PhdrI->p_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
|
auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
|
||||||
|
|
Binary file not shown.
|
@ -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
|
RUN: 2>&1 | FileCheck --check-prefix=STRTAB %s
|
||||||
|
|
||||||
STRTAB: Invalid dynamic string table reference
|
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
|
||||||
|
|
|
@ -24,10 +24,8 @@ using namespace llvm::object;
|
||||||
template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
|
template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
|
||||||
typedef ELFFile<ELFT> ELFO;
|
typedef ELFFile<ELFT> ELFO;
|
||||||
outs() << "Program Header:\n";
|
outs() << "Program Header:\n";
|
||||||
for (typename ELFO::Elf_Phdr_Iter pi = o->program_header_begin(),
|
for (const typename ELFO::Elf_Phdr &Phdr : o->program_headers()) {
|
||||||
pe = o->program_header_end();
|
switch (Phdr.p_type) {
|
||||||
pi != pe; ++pi) {
|
|
||||||
switch (pi->p_type) {
|
|
||||||
case ELF::PT_LOAD:
|
case ELF::PT_LOAD:
|
||||||
outs() << " LOAD ";
|
outs() << " LOAD ";
|
||||||
break;
|
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 " ";
|
const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";
|
||||||
|
|
||||||
outs() << "off "
|
outs() << "off " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr "
|
||||||
<< format(Fmt, (uint64_t)pi->p_offset)
|
<< format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr "
|
||||||
<< "vaddr "
|
<< format(Fmt, (uint64_t)Phdr.p_paddr)
|
||||||
<< format(Fmt, (uint64_t)pi->p_vaddr)
|
<< format("align 2**%u\n",
|
||||||
<< "paddr "
|
countTrailingZeros<uint64_t>(Phdr.p_align))
|
||||||
<< format(Fmt, (uint64_t)pi->p_paddr)
|
<< " filesz " << format(Fmt, (uint64_t)Phdr.p_filesz)
|
||||||
<< format("align 2**%u\n", countTrailingZeros<uint64_t>(pi->p_align))
|
<< "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags "
|
||||||
<< " filesz "
|
<< ((Phdr.p_flags & ELF::PF_R) ? "r" : "-")
|
||||||
<< format(Fmt, (uint64_t)pi->p_filesz)
|
<< ((Phdr.p_flags & ELF::PF_W) ? "w" : "-")
|
||||||
<< "memsz "
|
<< ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n";
|
||||||
<< 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() << "\n";
|
outs() << "\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1109,20 +1109,18 @@ template<class ELFT>
|
||||||
void ELFDumper<ELFT>::printProgramHeaders() {
|
void ELFDumper<ELFT>::printProgramHeaders() {
|
||||||
ListScope L(W, "ProgramHeaders");
|
ListScope L(W, "ProgramHeaders");
|
||||||
|
|
||||||
for (typename ELFO::Elf_Phdr_Iter PI = Obj->program_header_begin(),
|
for (const typename ELFO::Elf_Phdr &Phdr : Obj->program_headers()) {
|
||||||
PE = Obj->program_header_end();
|
|
||||||
PI != PE; ++PI) {
|
|
||||||
DictScope P(W, "ProgramHeader");
|
DictScope P(W, "ProgramHeader");
|
||||||
W.printHex ("Type",
|
W.printHex("Type",
|
||||||
getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type),
|
getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type),
|
||||||
PI->p_type);
|
Phdr.p_type);
|
||||||
W.printHex ("Offset", PI->p_offset);
|
W.printHex("Offset", Phdr.p_offset);
|
||||||
W.printHex ("VirtualAddress", PI->p_vaddr);
|
W.printHex("VirtualAddress", Phdr.p_vaddr);
|
||||||
W.printHex ("PhysicalAddress", PI->p_paddr);
|
W.printHex("PhysicalAddress", Phdr.p_paddr);
|
||||||
W.printNumber("FileSize", PI->p_filesz);
|
W.printNumber("FileSize", Phdr.p_filesz);
|
||||||
W.printNumber("MemSize", PI->p_memsz);
|
W.printNumber("MemSize", Phdr.p_memsz);
|
||||||
W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags));
|
W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags));
|
||||||
W.printNumber("Alignment", PI->p_align);
|
W.printNumber("Alignment", Phdr.p_align);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue