mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:47:35 +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;
|
return header().e_shnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned ELFImage::program_header_count() const
|
||||||
|
{
|
||||||
|
return header().e_phnum;
|
||||||
|
}
|
||||||
|
|
||||||
bool ELFImage::parse()
|
bool ELFImage::parse()
|
||||||
{
|
{
|
||||||
// We only support i386.
|
// We only support i386.
|
||||||
|
@ -148,6 +153,12 @@ const Elf32_Ehdr& ELFImage::header() const
|
||||||
return *reinterpret_cast<const Elf32_Ehdr*>(rawData(0));
|
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
|
const Elf32_Shdr& ELFImage::sectionHeader(unsigned index) const
|
||||||
{
|
{
|
||||||
ASSERT(index < header().e_shnum);
|
ASSERT(index < header().e_shnum);
|
||||||
|
@ -167,6 +178,12 @@ const ELFImage::Section ELFImage::section(unsigned index) const
|
||||||
return Section(*this, index);
|
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
|
const ELFImage::Relocation ELFImage::RelocationSection::relocation(unsigned index) const
|
||||||
{
|
{
|
||||||
ASSERT(index < relocationCount());
|
ASSERT(index < relocationCount());
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
class ELFImage {
|
class ELFImage {
|
||||||
public:
|
public:
|
||||||
|
@ -51,6 +52,31 @@ public:
|
||||||
const unsigned m_index;
|
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 {
|
class Section {
|
||||||
public:
|
public:
|
||||||
Section(const ELFImage& image, unsigned sectionIndex)
|
Section(const ELFImage& image, unsigned sectionIndex)
|
||||||
|
@ -112,13 +138,16 @@ public:
|
||||||
|
|
||||||
unsigned symbolCount() const;
|
unsigned symbolCount() const;
|
||||||
unsigned sectionCount() const;
|
unsigned sectionCount() const;
|
||||||
|
unsigned program_header_count() const;
|
||||||
|
|
||||||
const Symbol symbol(unsigned) const;
|
const Symbol symbol(unsigned) const;
|
||||||
const Section section(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 forEachSection(F) const;
|
||||||
template<typename F> void forEachSectionOfType(unsigned, F) const;
|
template<typename F> void forEachSectionOfType(unsigned, F) const;
|
||||||
template<typename F> void forEachSymbol(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.
|
// NOTE: Returns section(0) if section with name is not found.
|
||||||
// FIXME: I don't love this API.
|
// FIXME: I don't love this API.
|
||||||
|
@ -132,6 +161,7 @@ private:
|
||||||
const char* rawData(unsigned offset) const;
|
const char* rawData(unsigned offset) const;
|
||||||
const Elf32_Ehdr& header() const;
|
const Elf32_Ehdr& header() const;
|
||||||
const Elf32_Shdr& sectionHeader(unsigned) const;
|
const Elf32_Shdr& sectionHeader(unsigned) const;
|
||||||
|
const Elf32_Phdr& program_header_internal(unsigned) const;
|
||||||
const char* tableString(unsigned offset) const;
|
const char* tableString(unsigned offset) const;
|
||||||
const char* sectionHeaderTableString(unsigned offset) const;
|
const char* sectionHeaderTableString(unsigned offset) const;
|
||||||
const char* sectionIndexToString(unsigned index);
|
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
|
#ifdef ELFLOADER_DEBUG
|
||||||
kprintf("ELFLoader: Layout\n");
|
kprintf("ELFLoader: Layout\n");
|
||||||
#endif
|
#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;
|
bool failed = false;
|
||||||
dword highestOffset = 0;
|
dword highestOffset = 0;
|
||||||
dword sizeNeeded = 0;
|
dword sizeNeeded = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue