diff --git a/ELFLoader/ELFImage.cpp b/ELFLoader/ELFImage.cpp index f42f1be771..33d4de35c7 100644 --- a/ELFLoader/ELFImage.cpp +++ b/ELFLoader/ELFImage.cpp @@ -91,6 +91,11 @@ unsigned ELFImage::sectionCount() const return header().e_shnum; } +unsigned ELFImage::program_header_count() const +{ + return header().e_phnum; +} + bool ELFImage::parse() { // We only support i386. @@ -148,6 +153,12 @@ const Elf32_Ehdr& ELFImage::header() const return *reinterpret_cast(rawData(0)); } +const Elf32_Phdr& ELFImage::program_header_internal(unsigned index) const +{ + ASSERT(index < header().e_phnum); + return *reinterpret_cast(rawData(header().e_phoff + (index * sizeof(Elf32_Phdr)))); +} + const Elf32_Shdr& ELFImage::sectionHeader(unsigned index) const { ASSERT(index < header().e_shnum); @@ -167,6 +178,12 @@ const ELFImage::Section ELFImage::section(unsigned index) const return Section(*this, index); } +const ELFImage::ProgramHeader ELFImage::program_header(unsigned index) const +{ + ASSERT(index < program_header_count()); + return ProgramHeader(*this, index); +} + const ELFImage::Relocation ELFImage::RelocationSection::relocation(unsigned index) const { ASSERT(index < relocationCount()); diff --git a/ELFLoader/ELFImage.h b/ELFLoader/ELFImage.h index 5181b637e2..287bdd0abf 100644 --- a/ELFLoader/ELFImage.h +++ b/ELFLoader/ELFImage.h @@ -8,6 +8,7 @@ #include #include #include "elf.h" +#include "types.h" class ELFImage { public: @@ -51,6 +52,31 @@ public: const unsigned m_index; }; + class ProgramHeader { + public: + ProgramHeader(const ELFImage& image, unsigned program_header_index) + : m_program_header(image.program_header_internal(program_header_index)) + , m_program_header_index(program_header_index) + { + } + ~ProgramHeader() { } + + unsigned index() const { return m_program_header_index; } + dword type() const { return m_program_header.p_type; } + dword flags() const { return m_program_header.p_flags; } + dword offset() const { return m_program_header.p_offset; } + LinearAddress laddr() const { return LinearAddress(m_program_header.p_vaddr); } + dword size_in_memory() const { return m_program_header.p_memsz; } + dword size_in_image() const { return m_program_header.p_filesz; } + dword alignment() const { return m_program_header.p_align; } + bool is_readable() const { return flags() & PF_R; } + bool is_writable() const { return flags() & PF_W; } + bool is_executable() const { return flags() & PF_X; } + private: + const Elf32_Phdr& m_program_header; + unsigned m_program_header_index { 0 }; + }; + class Section { public: Section(const ELFImage& image, unsigned sectionIndex) @@ -112,13 +138,16 @@ public: unsigned symbolCount() const; unsigned sectionCount() const; + unsigned program_header_count() const; const Symbol symbol(unsigned) const; const Section section(unsigned) const; + const ProgramHeader program_header(unsigned const) const; template void forEachSection(F) const; template void forEachSectionOfType(unsigned, F) const; template void forEachSymbol(F) const; + template void for_each_program_header(F) const; // NOTE: Returns section(0) if section with name is not found. // FIXME: I don't love this API. @@ -132,6 +161,7 @@ private: const char* rawData(unsigned offset) const; const Elf32_Ehdr& header() const; const Elf32_Shdr& sectionHeader(unsigned) const; + const Elf32_Phdr& program_header_internal(unsigned) const; const char* tableString(unsigned offset) const; const char* sectionHeaderTableString(unsigned offset) const; const char* sectionIndexToString(unsigned index); @@ -184,3 +214,10 @@ inline void ELFImage::forEachSymbol(F func) const } } +template +inline void ELFImage::for_each_program_header(F func) const +{ + for (unsigned i = 0; i < program_header_count(); ++i) { + func(program_header(i)); + } +} diff --git a/ELFLoader/ELFLoader.cpp b/ELFLoader/ELFLoader.cpp index 5bac37265e..5c3918b7fc 100644 --- a/ELFLoader/ELFLoader.cpp +++ b/ELFLoader/ELFLoader.cpp @@ -39,6 +39,15 @@ bool ELFLoader::layout() #ifdef ELFLOADER_DEBUG kprintf("ELFLoader: Layout\n"); #endif + + m_image->for_each_program_header([&] (const ELFImage::ProgramHeader& program_header) { + if (program_header.type() != PT_LOAD) + return; +#ifdef ELFLOADER_DEBUG + kprintf("PH: L%x %u r:%u w:%u\n", program_header.laddr().get(), program_header.size_in_memory(), program_header.is_readable(), program_header.is_writable()); +#endif + }); + bool failed = false; dword highestOffset = 0; dword sizeNeeded = 0;