Skip to content

Commit

Permalink
ELFLoader: Add program header support.
Browse files Browse the repository at this point in the history
We don't do anything useful with the data yet, but I'm gonna rewrite
the layout code to run off of the program header table instead.
This will allow us to map .text and .rodata sections in read-only memory.
  • Loading branch information
awesomekling committed Nov 3, 2018
1 parent 20fb1fc commit 8f51f0e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
17 changes: 17 additions & 0 deletions ELFLoader/ELFImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -148,6 +153,12 @@ const Elf32_Ehdr& ELFImage::header() const
return *reinterpret_cast<const Elf32_Ehdr*>(rawData(0));
}

const Elf32_Phdr& ELFImage::program_header_internal(unsigned index) const
{
ASSERT(index < header().e_phnum);
return *reinterpret_cast<const Elf32_Phdr*>(rawData(header().e_phoff + (index * sizeof(Elf32_Phdr))));
}

const Elf32_Shdr& ELFImage::sectionHeader(unsigned index) const
{
ASSERT(index < header().e_shnum);
Expand All @@ -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());
Expand Down
37 changes: 37 additions & 0 deletions ELFLoader/ELFImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <AK/HashMap.h>
#include <AK/String.h>
#include "elf.h"
#include "types.h"

class ELFImage {
public:
Expand Down Expand Up @@ -51,6 +52,31 @@ class ELFImage {
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)
Expand Down Expand Up @@ -112,13 +138,16 @@ class ELFImage {

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<typename F> void forEachSection(F) const;
template<typename F> void forEachSectionOfType(unsigned, F) const;
template<typename F> void forEachSymbol(F) const;
template<typename F> 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.
Expand All @@ -132,6 +161,7 @@ class ELFImage {
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);
Expand Down Expand Up @@ -184,3 +214,10 @@ inline void ELFImage::forEachSymbol(F func) const
}
}

template<typename F>
inline void ELFImage::for_each_program_header(F func) const
{
for (unsigned i = 0; i < program_header_count(); ++i) {
func(program_header(i));
}
}
9 changes: 9 additions & 0 deletions ELFLoader/ELFLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 8f51f0e

Please sign in to comment.