mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:38:11 +00:00
ELFLoader: Add program header support.
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.
This commit is contained in:
parent
20fb1fc377
commit
8f51f0e6b2
3 changed files with 63 additions and 0 deletions
|
@ -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<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);
|
||||
|
@ -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());
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <AK/HashMap.h>
|
||||
#include <AK/String.h>
|
||||
#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<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.
|
||||
|
@ -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<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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue