LibELF: Add 32 bit support
This commit is contained in:
parent
4f8f3ddc29
commit
163d2e4ba8
|
@ -40,12 +40,106 @@ namespace LibELF
|
||||||
return elf;
|
return elf;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ELF::lookup_section_name(uint32_t offset) const
|
BAN::ErrorOr<void> ELF::load()
|
||||||
{
|
{
|
||||||
return lookup_string(file_header64().e_shstrndx, offset);
|
if (m_data.size() < EI_NIDENT)
|
||||||
|
{
|
||||||
|
dprintln("Too small ELF file");
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_data[EI_MAG0] != ELFMAG0 ||
|
||||||
|
m_data[EI_MAG1] != ELFMAG1 ||
|
||||||
|
m_data[EI_MAG2] != ELFMAG2 ||
|
||||||
|
m_data[EI_MAG3] != ELFMAG3)
|
||||||
|
{
|
||||||
|
dprintln("Invalid ELF header");
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_data[EI_DATA] != ELFDATA2LSB)
|
||||||
|
{
|
||||||
|
dprintln("Only little-endian is supported");
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_data[EI_VERSION] != EV_CURRENT)
|
||||||
|
{
|
||||||
|
dprintln("Invalid ELF version");
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_data[EI_CLASS] == ELFCLASS64)
|
||||||
|
{
|
||||||
|
if (m_data.size() <= sizeof(Elf64FileHeader))
|
||||||
|
{
|
||||||
|
dprintln("Too small ELF file");
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& header = file_header64();
|
||||||
|
if (!parse_elf64_file_header(header))
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < header.e_phnum; i++)
|
||||||
|
{
|
||||||
|
auto& program_header = program_header64(i);
|
||||||
|
if (!parse_elf64_program_header(program_header))
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < header.e_shnum; i++)
|
||||||
|
{
|
||||||
|
auto& section_header = section_header64(i);
|
||||||
|
if (!parse_elf64_section_header(section_header))
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_data[EI_CLASS] == ELFCLASS32)
|
||||||
|
{
|
||||||
|
if (m_data.size() <= sizeof(Elf32FileHeader))
|
||||||
|
{
|
||||||
|
dprintln("Too small ELF file");
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& header = file_header32();
|
||||||
|
if (!parse_elf32_file_header(header))
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < header.e_phnum; i++)
|
||||||
|
{
|
||||||
|
auto& program_header = program_header32(i);
|
||||||
|
if (!parse_elf32_program_header(program_header))
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < header.e_shnum; i++)
|
||||||
|
{
|
||||||
|
auto& section_header = section_header32(i);
|
||||||
|
if (!parse_elf32_section_header(section_header))
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ELF::lookup_string(size_t table_index, uint32_t offset) const
|
bool ELF::is_x86_32() const { return m_data[EI_CLASS] == ELFCLASS32; }
|
||||||
|
bool ELF::is_x86_64() const { return m_data[EI_CLASS] == ELFCLASS64; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
64 bit ELF
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char* ELF::lookup_section_name64(uint32_t offset) const
|
||||||
|
{
|
||||||
|
return lookup_string64(file_header64().e_shstrndx, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ELF::lookup_string64(size_t table_index, uint32_t offset) const
|
||||||
{
|
{
|
||||||
if (table_index == SHN_UNDEF)
|
if (table_index == SHN_UNDEF)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -90,7 +184,7 @@ namespace LibELF
|
||||||
bool ELF::parse_elf64_section_header(const Elf64SectionHeader& header)
|
bool ELF::parse_elf64_section_header(const Elf64SectionHeader& header)
|
||||||
{
|
{
|
||||||
#if ELF_PRINT_HEADERS
|
#if ELF_PRINT_HEADERS
|
||||||
if (auto* name = lookup_section_name(header.sh_name))
|
if (auto* name = lookup_section_name64(header.sh_name))
|
||||||
dprintln("{}", name);
|
dprintln("{}", name);
|
||||||
|
|
||||||
switch (header.sh_type)
|
switch (header.sh_type)
|
||||||
|
@ -105,7 +199,7 @@ namespace LibELF
|
||||||
for (size_t i = 1; i < header.sh_size / header.sh_entsize; i++)
|
for (size_t i = 1; i < header.sh_size / header.sh_entsize; i++)
|
||||||
{
|
{
|
||||||
auto& symbol = ((const Elf64Symbol*)(m_data.data() + header.sh_offset))[i];
|
auto& symbol = ((const Elf64Symbol*)(m_data.data() + header.sh_offset))[i];
|
||||||
if (auto* name = lookup_string(header.sh_link, symbol.st_name))
|
if (auto* name = lookup_string64(header.sh_link, symbol.st_name))
|
||||||
dprintln(" {}", name);
|
dprintln(" {}", name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -135,76 +229,15 @@ namespace LibELF
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> ELF::load()
|
|
||||||
{
|
|
||||||
if (m_data.size() < EI_NIDENT)
|
|
||||||
{
|
|
||||||
dprintln("Too small ELF file");
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_data[EI_MAG0] != ELFMAG0 ||
|
|
||||||
m_data[EI_MAG1] != ELFMAG1 ||
|
|
||||||
m_data[EI_MAG2] != ELFMAG2 ||
|
|
||||||
m_data[EI_MAG3] != ELFMAG3)
|
|
||||||
{
|
|
||||||
dprintln("Invalid ELF header");
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_data[EI_DATA] != ELFDATA2LSB)
|
|
||||||
{
|
|
||||||
dprintln("Only little-endian is supported");
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_data[EI_VERSION] != EV_CURRENT)
|
|
||||||
{
|
|
||||||
dprintln("Invalid ELF version");
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_data[EI_CLASS] != ELFCLASS64)
|
|
||||||
{
|
|
||||||
dprintln("Only 64 bit is supported");
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_data.size() <= sizeof(Elf64FileHeader))
|
|
||||||
{
|
|
||||||
dprintln("Too small ELF file");
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& header = file_header64();
|
|
||||||
if (!parse_elf64_file_header(header))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < header.e_phnum; i++)
|
|
||||||
{
|
|
||||||
auto& program_header = program_header64(i);
|
|
||||||
if (!parse_elf64_program_header(program_header))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 1; i < header.e_shnum; i++)
|
|
||||||
{
|
|
||||||
auto& section_header = section_header64(i);
|
|
||||||
if (!parse_elf64_section_header(section_header))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Elf64FileHeader& ELF::file_header64() const
|
const Elf64FileHeader& ELF::file_header64() const
|
||||||
{
|
{
|
||||||
|
ASSERT(is_x86_64());
|
||||||
return *(const Elf64FileHeader*)m_data.data();
|
return *(const Elf64FileHeader*)m_data.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Elf64ProgramHeader& ELF::program_header64(size_t index) const
|
const Elf64ProgramHeader& ELF::program_header64(size_t index) const
|
||||||
{
|
{
|
||||||
|
ASSERT(is_x86_64());
|
||||||
const auto& file_header = file_header64();
|
const auto& file_header = file_header64();
|
||||||
ASSERT(index < file_header.e_phnum);
|
ASSERT(index < file_header.e_phnum);
|
||||||
return *(const Elf64ProgramHeader*)(m_data.data() + file_header.e_phoff + file_header.e_phentsize * index);
|
return *(const Elf64ProgramHeader*)(m_data.data() + file_header.e_phoff + file_header.e_phentsize * index);
|
||||||
|
@ -212,10 +245,135 @@ namespace LibELF
|
||||||
|
|
||||||
const Elf64SectionHeader& ELF::section_header64(size_t index) const
|
const Elf64SectionHeader& ELF::section_header64(size_t index) const
|
||||||
{
|
{
|
||||||
|
ASSERT(is_x86_64());
|
||||||
const auto& file_header = file_header64();
|
const auto& file_header = file_header64();
|
||||||
ASSERT(index < file_header.e_shnum);
|
ASSERT(index < file_header.e_shnum);
|
||||||
return *(const Elf64SectionHeader*)(m_data.data() + file_header.e_shoff + file_header.e_shentsize * index);
|
return *(const Elf64SectionHeader*)(m_data.data() + file_header.e_shoff + file_header.e_shentsize * index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
32 bit ELF
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char* ELF::lookup_section_name32(uint32_t offset) const
|
||||||
|
{
|
||||||
|
return lookup_string32(file_header32().e_shstrndx, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ELF::lookup_string32(size_t table_index, uint32_t offset) const
|
||||||
|
{
|
||||||
|
if (table_index == SHN_UNDEF)
|
||||||
|
return nullptr;
|
||||||
|
auto& section_header = section_header32(table_index);
|
||||||
|
return (const char*)m_data.data() + section_header.sh_offset + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ELF::parse_elf32_file_header(const Elf32FileHeader& header)
|
||||||
|
{
|
||||||
|
if (header.e_type != ET_EXEC)
|
||||||
|
{
|
||||||
|
dprintln("Only executable files are supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.e_version != EV_CURRENT)
|
||||||
|
{
|
||||||
|
dprintln("Invalid ELF version");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ELF::parse_elf32_program_header(const Elf32ProgramHeader& header)
|
||||||
|
{
|
||||||
|
#if ELF_PRINT_HEADERS
|
||||||
|
dprintln("program header");
|
||||||
|
dprintln(" type {H}", header.p_type);
|
||||||
|
dprintln(" flags {H}", header.p_flags);
|
||||||
|
dprintln(" offset {H}", header.p_offset);
|
||||||
|
dprintln(" vaddr {H}", header.p_vaddr);
|
||||||
|
dprintln(" paddr {H}", header.p_paddr);
|
||||||
|
dprintln(" filesz {}", header.p_filesz);
|
||||||
|
dprintln(" memsz {}", header.p_memsz);
|
||||||
|
dprintln(" align {}", header.p_align);
|
||||||
|
#endif
|
||||||
|
(void)header;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ELF::parse_elf32_section_header(const Elf32SectionHeader& header)
|
||||||
|
{
|
||||||
|
#if ELF_PRINT_HEADERS
|
||||||
|
if (auto* name = lookup_section_name32(header.sh_name))
|
||||||
|
dprintln("{}", name);
|
||||||
|
|
||||||
|
switch (header.sh_type)
|
||||||
|
{
|
||||||
|
case SHT_NULL:
|
||||||
|
dprintln(" SHT_NULL");
|
||||||
|
break;
|
||||||
|
case SHT_PROGBITS:
|
||||||
|
dprintln(" SHT_PROGBITS");
|
||||||
|
break;
|
||||||
|
case SHT_SYMTAB:
|
||||||
|
for (size_t i = 1; i < header.sh_size / header.sh_entsize; i++)
|
||||||
|
{
|
||||||
|
auto& symbol = ((const Elf32Symbol*)(m_data.data() + header.sh_offset))[i];
|
||||||
|
if (auto* name = lookup_string32(header.sh_link, symbol.st_name))
|
||||||
|
dprintln(" {}", name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHT_STRTAB:
|
||||||
|
dprintln(" SHT_STRTAB");
|
||||||
|
break;
|
||||||
|
case SHT_RELA:
|
||||||
|
dprintln(" SHT_RELA");
|
||||||
|
break;
|
||||||
|
case SHT_NOBITS:
|
||||||
|
dprintln(" SHT_NOBITS");
|
||||||
|
break;
|
||||||
|
case SHT_REL:
|
||||||
|
dprintln(" SHT_REL");
|
||||||
|
break;
|
||||||
|
case SHT_SHLIB:
|
||||||
|
dprintln(" SHT_SHLIB");
|
||||||
|
break;
|
||||||
|
case SHT_DYNSYM:
|
||||||
|
dprintln(" SHT_DYNSYM");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
(void)header;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Elf32FileHeader& ELF::file_header32() const
|
||||||
|
{
|
||||||
|
ASSERT(is_x86_32());
|
||||||
|
return *(const Elf32FileHeader*)m_data.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Elf32ProgramHeader& ELF::program_header32(size_t index) const
|
||||||
|
{
|
||||||
|
ASSERT(is_x86_32());
|
||||||
|
const auto& file_header = file_header32();
|
||||||
|
ASSERT(index < file_header.e_phnum);
|
||||||
|
return *(const Elf32ProgramHeader*)(m_data.data() + file_header.e_phoff + file_header.e_phentsize * index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Elf32SectionHeader& ELF::section_header32(size_t index) const
|
||||||
|
{
|
||||||
|
ASSERT(is_x86_32());
|
||||||
|
const auto& file_header = file_header32();
|
||||||
|
ASSERT(index < file_header.e_shnum);
|
||||||
|
return *(const Elf32SectionHeader*)(m_data.data() + file_header.e_shoff + file_header.e_shentsize * index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/StringView.h>
|
||||||
#include <BAN/Vector.h>
|
#include <BAN/Vector.h>
|
||||||
|
#include <kernel/Arch.h>
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
namespace LibELF
|
namespace LibELF
|
||||||
|
@ -15,12 +16,36 @@ namespace LibELF
|
||||||
const Elf64FileHeader& file_header64() const;
|
const Elf64FileHeader& file_header64() const;
|
||||||
const Elf64ProgramHeader& program_header64(size_t) const;
|
const Elf64ProgramHeader& program_header64(size_t) const;
|
||||||
const Elf64SectionHeader& section_header64(size_t) const;
|
const Elf64SectionHeader& section_header64(size_t) const;
|
||||||
|
const char* lookup_section_name64(uint32_t) const;
|
||||||
|
const char* lookup_string64(size_t, uint32_t) const;
|
||||||
|
#if ARCH(x86_64)
|
||||||
|
const Elf64FileHeader& file_header_native() const { return file_header64(); }
|
||||||
|
const Elf64ProgramHeader& program_header_native(size_t index) const { return program_header64(index); }
|
||||||
|
const Elf64SectionHeader& section_header_native(size_t index) const { return section_header64(index); }
|
||||||
|
const char* lookup_section_name_native(uint32_t offset) const { return lookup_section_name64(offset); }
|
||||||
|
const char* lookup_string_native(size_t table_index, uint32_t offset) const { return lookup_string64(table_index, offset); }
|
||||||
|
bool is_native() const { return is_x86_64(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
const char* lookup_section_name(uint32_t) const;
|
const Elf32FileHeader& file_header32() const;
|
||||||
const char* lookup_string(size_t, uint32_t) const;
|
const Elf32ProgramHeader& program_header32(size_t) const;
|
||||||
|
const Elf32SectionHeader& section_header32(size_t) const;
|
||||||
|
const char* lookup_section_name32(uint32_t) const;
|
||||||
|
const char* lookup_string32(size_t, uint32_t) const;
|
||||||
|
#if ARCH(i386)
|
||||||
|
const Elf32FileHeader& file_header_native() const { return file_header32(); }
|
||||||
|
const Elf32ProgramHeader& program_header_native(size_t index) const { return program_header32(index); }
|
||||||
|
const Elf32SectionHeader& section_header_native(size_t index) const { return section_header32(index); }
|
||||||
|
const char* lookup_section_name_native(uint32_t offset) const { return lookup_section_name32(offset); }
|
||||||
|
const char* lookup_string_native(size_t table_index, uint32_t offset) const { return lookup_string32(table_index, offset); }
|
||||||
|
bool is_native() const { return is_x86_32(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
const uint8_t* data() const { return m_data.data(); }
|
const uint8_t* data() const { return m_data.data(); }
|
||||||
|
|
||||||
|
bool is_x86_32() const;
|
||||||
|
bool is_x86_64() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ELF(BAN::Vector<uint8_t>&& data)
|
ELF(BAN::Vector<uint8_t>&& data)
|
||||||
: m_data(BAN::move(data))
|
: m_data(BAN::move(data))
|
||||||
|
@ -31,6 +56,10 @@ namespace LibELF
|
||||||
bool parse_elf64_program_header(const Elf64ProgramHeader&);
|
bool parse_elf64_program_header(const Elf64ProgramHeader&);
|
||||||
bool parse_elf64_section_header(const Elf64SectionHeader&);
|
bool parse_elf64_section_header(const Elf64SectionHeader&);
|
||||||
|
|
||||||
|
bool parse_elf32_file_header(const Elf32FileHeader&);
|
||||||
|
bool parse_elf32_program_header(const Elf32ProgramHeader&);
|
||||||
|
bool parse_elf32_section_header(const Elf32SectionHeader&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const BAN::Vector<uint8_t> m_data;
|
const BAN::Vector<uint8_t> m_data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,80 @@
|
||||||
namespace LibELF
|
namespace LibELF
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using Elf32Addr = uint32_t;
|
||||||
|
using Elf32Off = uint32_t;
|
||||||
|
using Elf32Half = uint16_t;
|
||||||
|
using Elf32Word = uint32_t;
|
||||||
|
using Elf32Sword = int32_t;
|
||||||
|
|
||||||
|
struct Elf32FileHeader
|
||||||
|
{
|
||||||
|
unsigned char e_ident[16];
|
||||||
|
Elf32Half e_type;
|
||||||
|
Elf32Half e_machine;
|
||||||
|
Elf32Word e_version;
|
||||||
|
Elf32Addr e_entry;
|
||||||
|
Elf32Off e_phoff;
|
||||||
|
Elf32Off e_shoff;
|
||||||
|
Elf32Word e_flags;
|
||||||
|
Elf32Half e_ehsize;
|
||||||
|
Elf32Half e_phentsize;
|
||||||
|
Elf32Half e_phnum;
|
||||||
|
Elf32Half e_shentsize;
|
||||||
|
Elf32Half e_shnum;
|
||||||
|
Elf32Half e_shstrndx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Elf32SectionHeader
|
||||||
|
{
|
||||||
|
Elf32Word sh_name;
|
||||||
|
Elf32Word sh_type;
|
||||||
|
Elf32Word sh_flags;
|
||||||
|
Elf32Addr sh_addr;
|
||||||
|
Elf32Off sh_offset;
|
||||||
|
Elf32Word sh_size;
|
||||||
|
Elf32Word sh_link;
|
||||||
|
Elf32Word sh_info;
|
||||||
|
Elf32Word sh_addralign;
|
||||||
|
Elf32Word sh_entsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Elf32Symbol
|
||||||
|
{
|
||||||
|
Elf32Word st_name;
|
||||||
|
Elf32Addr st_value;
|
||||||
|
Elf32Word st_size;
|
||||||
|
unsigned char st_info;
|
||||||
|
unsigned char st_other;
|
||||||
|
Elf32Half st_shndx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Elf32Relocation
|
||||||
|
{
|
||||||
|
Elf32Addr r_offset;
|
||||||
|
Elf32Word r_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Elf32RelocationA
|
||||||
|
{
|
||||||
|
Elf32Addr r_offset;
|
||||||
|
Elf32Word r_info;
|
||||||
|
Elf32Sword r_addend;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Elf32ProgramHeader
|
||||||
|
{
|
||||||
|
Elf32Word p_type;
|
||||||
|
Elf32Off p_offset;
|
||||||
|
Elf32Addr p_vaddr;
|
||||||
|
Elf32Addr p_paddr;
|
||||||
|
Elf32Word p_filesz;
|
||||||
|
Elf32Word p_memsz;
|
||||||
|
Elf32Word p_flags;
|
||||||
|
Elf32Word p_align;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
using Elf64Addr = uint64_t;
|
using Elf64Addr = uint64_t;
|
||||||
using Elf64Off = uint64_t;
|
using Elf64Off = uint64_t;
|
||||||
using Elf64Half = uint16_t;
|
using Elf64Half = uint16_t;
|
||||||
|
|
Loading…
Reference in New Issue