Finished OOP conversion.

This commit is contained in:
2024-02-14 23:39:35 -08:00
parent c3eb95e8f3
commit 669b6d66a3
20 changed files with 769 additions and 820 deletions

View File

@@ -1,61 +0,0 @@
#include "ELF.h"
constexpr ehs::Char_8 Elf_Magic[] = "\x7F" "ELF";
constexpr ehs::UInt_8 Elf_Magic_Size = sizeof(Elf_Magic) - 1;
void WriteHeader(const ElfHeader& header, ehs::Serializer<ehs::UInt_64>& data)
{
data.Resize(Elf_Magic_Size);
ehs::Util::Copy(&data[0], Elf_Magic, Elf_Magic_Size);
data.SetOffset(Elf_Magic_Size);
data.Write(header.architecture);
data.Write(header.endianness);
data.Write(header.elfV1);
data.Write(header.targetABI);
data.Write(header.abiV);
data.Resize(data.Size() + 7);
ehs::Util::Zero(&data[data.GetOffset()], 7);
data.SetOffset(data.GetOffset() + 7);
data.Write(header.elfType);
data.Write(header.machineArch);
data.Write(header.elfV2);
data.Write(header.entryAddress);
data.Write(header.programsOffset);
data.Write(header.sectionsOffset);
data.Write(header.flags);
data.Write(header.headerSize);
data.Write(header.pHeaderSize);
data.Write(header.pEntries);
data.Write(header.sSize);
data.Write(header.sEntries);
data.Write(header.strTabIndex);
}
void WriteHeader(const ElfPrgHeader& header, ehs::Serializer<ehs::UInt_64>& data)
{
data.Write(header.type);
data.Write(header.flags);
data.Write(header.offset);
data.Write(header.vAddr);
data.Write(header.pAddr);
data.Write(header.fileSize);
data.Write(header.memSize);
data.Write(header.align);
}
void WriteHeader(const ElfSecHeader& header, ehs::Serializer<ehs::UInt_64>& data)
{
data.Write(header.index);
data.Write(header.type);
data.Write(header.flags);
data.Write(header.vAddr);
data.Write(header.offset);
data.Write(header.size);
data.Write(header.associatedIndex);
data.Write(header.info);
data.Write(header.align);
data.Write(header.entrySize);
}

View File

@@ -1,3 +1,317 @@
//
// Created by karutoh on 2/14/24.
//
#include "ELF64.h"
constexpr ehs::Char_8 Elf_Magic[] = "\x7F" "ELF";
constexpr ehs::UInt_8 Elf_Magic_Size = sizeof(Elf_Magic) - 1;
ELF64::ELF64()
: subArch(ELFH_ARCH_64), endianness(ELFH_END_LE), abi(ELFH_ABI_SYSTEMV), type(ELFH_TYPE_EXEC),
arch(ELFH_MARCH_AMD_X86_64), entryPoint(0)
{
InitializeSections();
}
ELF64::ELF64(ehs::UInt_8 subArch, ehs::UInt_8 end, ehs::UInt_8 abi, ehs::UInt_16 type, ehs::UInt_16 arch)
: subArch(subArch), endianness(end), abi(abi), type(type), arch(arch), entryPoint(0)
{
InitializeSections();
}
ELF64::ELF64(ehs::Serializer<ehs::UInt_64>& data)
{
}
ELF64::ELF64(ELF64&& header) noexcept
: subArch(header.subArch), endianness(header.endianness), abi(header.abi), type(header.type), arch(header.arch),
entryPoint(header.entryPoint), programs((ehs::Vector<ELF64_Program, ehs::UInt_16>&&)header.programs),
sections((ehs::Vector<ELF64_Section, ehs::UInt_16>&&)header.sections)
{
header.subArch = ELFH_ARCH_64;
header.endianness = ELFH_END_LE;
header.abi = ELFH_ABI_SYSTEMV;
header.type = ELFH_TYPE_EXEC;
header.arch = ELFH_MARCH_AMD_X86_64;
header.entryPoint = 0;
header.InitializeSections();
}
ELF64::ELF64(const ELF64& header)
: subArch(header.subArch), endianness(header.endianness), abi(header.abi), type(header.type), arch(header.arch),
entryPoint(header.entryPoint), programs(header.programs), sections(header.sections)
{
}
ELF64& ELF64::operator=(ELF64&& header) noexcept
{
if (this == &header)
return *this;
subArch = header.subArch;
endianness = header.endianness;
abi = header.abi;
type = header.type;
arch = header.arch;
entryPoint = header.entryPoint;
programs = (ehs::Vector<ELF64_Program, ehs::UInt_16>&&)header.programs;
sections = (ehs::Vector<ELF64_Section, ehs::UInt_16>&&)header.sections;
header.subArch = ELFH_ARCH_64;
header.endianness = ELFH_END_LE;
header.abi = ELFH_ABI_SYSTEMV;
header.type = ELFH_TYPE_EXEC;
header.arch = ELFH_MARCH_AMD_X86_64;
header.entryPoint = 0;
header.InitializeSections();
return *this;
}
ELF64& ELF64::operator=(const ELF64& header)
{
if (this == &header)
return *this;
subArch = header.subArch;
endianness = header.endianness;
abi = header.abi;
type = header.type;
arch = header.arch;
entryPoint = header.entryPoint;
programs = header.programs;
sections = header.sections;
return *this;
}
ehs::UInt_8 ELF64::GetSubArchitecture() const
{
return subArch;
}
ehs::UInt_8 ELF64::GetEndianness() const
{
return endianness;
}
ehs::UInt_8 ELF64::GetABI() const
{
return abi;
}
ehs::UInt_16 ELF64::GetType() const
{
return type;
}
ehs::UInt_16 ELF64::GetArchitecture() const
{
return arch;
}
void ELF64::SetEntryPoint(ehs::UInt_16 programIndex)
{
if (programIndex > programs.End())
{
EHS_LOG("Warning", 0, "The given index, \"" + ehs::Str_8::FromNum(programIndex) +
"\", is outside the bounds of, \"" + ehs::Str_8::FromNum(programs.End()) + "\".");
return;
}
entryPoint = programIndex;
}
ELF64_Program* ELF64::GetEntryPoint() const
{
return &programs[entryPoint];
}
void ELF64::AddProgram(ELF64_Program newProgram)
{
/*
for (ehs::UInt_16 i = 0; i < programs.Size(); i++)
{
if (programs[i].fileSize < newProgram.fileSize)
continue;
EHS_LOG("Warning", 0, "The new program file size, \"" + ehs::Str_8::FromNum(newProgram.fileSize) +
"\" must be greater than, \"" + ehs::Str_8::FromNum(programs[i].fileSize) + "\".");
return;
}
*/
newProgram.owner = this;
if (programs.Size())
sections[newProgram.sectionIndex].programIndex = programs.End() + 1;
else
sections[newProgram.sectionIndex].programIndex = programs.End();
programs.Push((ELF64_Program&&)newProgram);
}
bool ELF64::HasSection(ehs::UInt_64 hashId)
{
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
if (sections[i].GetHashId() == hashId)
return true;
return false;
}
bool ELF64::HasSection(ehs::Str_8& id)
{
return HasSection(id.Hash_64());
}
void ELF64::AddSection(ELF64_Section newSection)
{
if (HasSection(newSection.GetHashId()))
{
EHS_LOG("Warning", 0, "The section, \"" + newSection.GetId() + "\", already exists.");
return;
}
ehs::Str_8 newId = newSection.GetId();
ELF64_Section* shStrTab = FindShStrTab();
ehs::Serializer<ehs::UInt_64>& data = shStrTab->GetData();
newSection.nameOffset = data.GetOffset();
data.Resize(data.Size() + newId.Size() + 1);
ehs::Util::Copy(&data[data.GetOffset()], &newId[0], newId.Size());
data.SetOffset(data.GetOffset() + newId.Size());
data.Write('\0');
sections.Push((ELF64_Section&&)newSection);
}
ehs::Serializer<ehs::UInt_64> ELF64::Serialize() const
{
ehs::Serializer<ehs::UInt_64> result(ehs::Endianness::LE);
result.Resize(Elf_Magic_Size);
ehs::Util::Copy(&result[0], Elf_Magic, Elf_Magic_Size);
result.SetOffset(Elf_Magic_Size);
result.Write(subArch);
result.Write(endianness);
result.Write<ehs::UInt_8>(1);
result.Write(abi);
result.Write<ehs::UInt_8>(0);
result.Resize(result.Size() + 7);
ehs::Util::Zero(&result[result.GetOffset()], 7);
result.SetOffset(result.GetOffset() + 7);
result.Write(type);
result.Write(arch);
result.Write<ehs::UInt_32>(1);
ehs::UInt_64 entryAddress = result.GetOffset();
result.Write<ehs::UInt_64>(0);
result.Write<ehs::UInt_64>(ELFH_SIZE);
result.Write(RetrieveSectionsOffset());
result.Write<ehs::UInt_32>(0);
result.Write<ehs::UInt_16>(ELFH_SIZE);
result.Write<ehs::UInt_16>(PRGH_SIZE);
result.Write(programs.Size());
result.Write<ehs::UInt_16>(SECH_SIZE);
result.Write(sections.Size());
result.Write(FindShStrTabIndex());
ehs::Array<ehs::Serializer<ehs::UInt_64>, ehs::UInt_16> segmentData(sections.Size());
ehs::UInt_64 segmentOffset = 0;
const ehs::UInt_64 programsSize = PRGH_SIZE * programs.Size();
for (ehs::UInt_16 i = 1; i < sections.Size(); i++)
{
sections[i].segmentOffset = result.GetOffset() + programsSize + segmentOffset;
segmentData[i] = sections[i].GetData();
if (sections[i].programIndex < EHS_UINT_16_MAX + 1)
{
sections[i].vAddr = programs[entryPoint].pAddr + result.GetOffset() + programsSize + segmentOffset;
programs[sections[i].programIndex].fileSize =
result.GetOffset() + programsSize + segmentOffset + segmentData[i].Size();
}
segmentOffset += segmentData[i].Size();
}
for (ehs::UInt_16 i = 0; i < programs.Size(); i++)
programs[i].Serialize(result);
for (ehs::UInt_16 i = 0; i < segmentData.Size(); i++)
result.WriteSer(segmentData[i]);
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
sections[i].Serialize(result);
*(ehs::UInt_64*)(&result[entryAddress]) = programs[entryPoint].pAddr + sections[programs[entryPoint].sectionIndex].segmentOffset;
return result;
}
void ELF64::InitializeSections()
{
ehs::Str_8 nullName = ".NULL";
ELF64_Section null(nullName, SECH_TYPE_NULL, 0, 0);
ehs::Str_8 shStrTabName = ".shstrtab";
ELF64_Section shStrTab(shStrTabName, SECH_TYPE_STRTAB, SECH_FLAG_STRINGS, 1);
ehs::Serializer<ehs::UInt_64>& data = shStrTab.GetData();
data.Resize(nullName.Size() + shStrTabName.Size() + 2);
null.nameOffset = data.GetOffset();
ehs::Util::Copy(&data[data.GetOffset()], &nullName[0], nullName.Size());
data.SetOffset(data.GetOffset() + nullName.Size());
data.Write('\0');
shStrTab.nameOffset = data.GetOffset();
ehs::Util::Copy(&data[data.GetOffset()], &shStrTabName[0], shStrTabName.Size());
data.SetOffset(data.GetOffset() + shStrTabName.Size());
data.Write('\0');
sections.Push((ELF64_Section&&)null);
sections.Push((ELF64_Section&&)shStrTab);
}
ehs::UInt_64 ELF64::RetrieveSectionsOffset() const
{
ehs::UInt_64 result = ELFH_SIZE + PRGH_SIZE * programs.Size();
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
result += sections[i].GetData().Size();
return result;
}
ehs::UInt_16 ELF64::FindShStrTabIndex() const
{
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
if (sections[i].GetHashId() == 7974729948679187860ull)
return i;
EHS_LOG("Error", 0, "Could not find the \".shstrtab\" index.");
return 0;
}
ELF64_Section* ELF64::FindShStrTab() const
{
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
if (sections[i].GetHashId() == 7974729948679187860ull)
return &sections[i];
EHS_LOG("Error", 0, "Could not find the \".shstrtab\".");
return nullptr;
}

View File

@@ -1,3 +1,119 @@
//
// Created by karutoh on 2/14/24.
//
#include "ELF64_Program.h"
ELF64_Program::ELF64_Program()
: owner(nullptr), sectionIndex(0), type(PRGH_TYPE_LOAD), flags(PRGH_FLAG_EXEC | PRGH_FLAG_READ), offset(0), vAddr(0),
pAddr(0), fileSize(0), adjustedMemSize(0), align(0x200000)
{
}
ELF64_Program::ELF64_Program(ehs::UInt_16 sectionIndex, ehs::UInt_32 type, ehs::UInt_32 flags, ehs::UInt_64 address, ehs::UInt_64 align)
: owner(nullptr), sectionIndex(sectionIndex), type(type), flags(flags), offset(0), vAddr(address), pAddr(address),
fileSize(0), adjustedMemSize(0), align(align)
{
}
ELF64_Program::ELF64_Program(ehs::Serializer<ehs::UInt_64>& data)
: owner(nullptr), sectionIndex(0), type(PRGH_TYPE_LOAD), flags(PRGH_FLAG_EXEC | PRGH_FLAG_READ), offset(0), vAddr(0),
pAddr(0), fileSize(0), adjustedMemSize(0), align(0x200000)
{
}
ELF64_Program::ELF64_Program(ELF64_Program&& program) noexcept
: owner(program.owner), sectionIndex(program.sectionIndex), type(program.type), flags(program.flags),
offset(program.offset), vAddr(program.vAddr), pAddr(program.pAddr), fileSize(program.fileSize),
adjustedMemSize(program.adjustedMemSize), align(program.align)
{
program.owner = nullptr;
program.sectionIndex = 0;
program.type = PRGH_TYPE_LOAD;
program.flags = PRGH_FLAG_EXEC | PRGH_FLAG_READ;
program.offset = 0;
program.vAddr = 0;
program.pAddr = 0;
program.fileSize = 0;
program.adjustedMemSize = 0;
program.align = 0x200000;
}
ELF64_Program::ELF64_Program(const ELF64_Program& program)
: owner(nullptr), sectionIndex(0), type(program.type), flags(program.flags),
offset(program.offset), vAddr(program.vAddr), pAddr(program.pAddr), fileSize(program.fileSize),
adjustedMemSize(program.adjustedMemSize), align(program.align)
{
}
ELF64_Program& ELF64_Program::operator=(ELF64_Program&& program) noexcept
{
if (this == &program)
return *this;
owner = program.owner;
sectionIndex = program.sectionIndex;
type = program.type;
flags = program.flags;
offset = program.offset;
vAddr = program.vAddr;
pAddr = program.pAddr;
fileSize = program.fileSize;
adjustedMemSize = program.adjustedMemSize;
align = program.align;
program.owner = nullptr;
program.sectionIndex = 0;
program.type = PRGH_TYPE_LOAD;
program.flags = PRGH_FLAG_EXEC | PRGH_FLAG_READ;
program.offset = 0;
program.vAddr = 0;
program.pAddr = 0;
program.fileSize = 0;
program.adjustedMemSize = 0;
program.align = 0x200000;
return *this;
}
ELF64_Program& ELF64_Program::operator=(const ELF64_Program& program)
{
if (this == &program)
return *this;
owner = nullptr;
sectionIndex = program.sectionIndex;
type = program.type;
flags = program.flags;
offset = program.offset;
vAddr = program.vAddr;
pAddr = program.pAddr;
fileSize = program.fileSize;
adjustedMemSize = program.adjustedMemSize;
align = program.align;
return *this;
}
ehs::UInt_32 ELF64_Program::GetType() const
{
return type;
}
ehs::UInt_32 ELF64_Program::GetFlags() const
{
return flags;
}
ehs::UInt_64 ELF64_Program::GetAlign() const
{
return align;
}
void ELF64_Program::Serialize(ehs::Serializer<ehs::UInt_64>& inData) const
{
inData.Write(type);
inData.Write(flags);
inData.Write(offset);
inData.Write(vAddr);
inData.Write(pAddr);
inData.Write(fileSize);
inData.Write(fileSize + adjustedMemSize);
inData.Write(align);
}

View File

@@ -1,3 +1,151 @@
//
// Created by karutoh on 2/14/24.
//
#include "ELF64_Section.h"
ELF64_Section::ELF64_Section()
: hashId(0), programIndex(EHS_UINT_16_MAX + 1), nameOffset(0), type(0), flags(0), vAddr(0), segmentOffset(0), associatedIndex(0),
info(0), align(0), entrySize(0), data(ehs::Endianness::LE)
{
}
ELF64_Section::ELF64_Section(ehs::Str_8 id, ehs::UInt_32 type, ehs::UInt_64 flags, ehs::UInt_64 align)
: hashId(id.Hash_64()), id((ehs::Str_8&&)id), programIndex(EHS_UINT_16_MAX + 1), nameOffset(0), type(type), flags(flags), vAddr(0),
segmentOffset(0), associatedIndex(0), info(0), align(align), entrySize(0), data(ehs::Endianness::LE)
{
}
ELF64_Section::ELF64_Section(ELF64_Section&& sect) noexcept
: hashId(sect.hashId), id((ehs::Str_8&&)sect.id), programIndex(sect.programIndex), nameOffset(sect.nameOffset),
type(sect.type), flags(sect.flags), vAddr(sect.vAddr), segmentOffset(sect.segmentOffset),
associatedIndex(sect.associatedIndex), info(sect.info), align(sect.align), entrySize(sect.entrySize),
data((ehs::Serializer<ehs::UInt_64>&&)sect.data)
{
sect.hashId = 0;
sect.programIndex = EHS_UINT_16_MAX + 1;
sect.nameOffset = 0;
sect.type = 0;
sect.flags = 0;
sect.vAddr = 0;
sect.segmentOffset = 0;
sect.associatedIndex = 0;
sect.info = 0;
sect.align = 0;
sect.entrySize = 0;
}
ELF64_Section::ELF64_Section(const ELF64_Section& sect)
: hashId(sect.hashId), id(sect.id), programIndex(EHS_UINT_16_MAX + 1), nameOffset(0), type(sect.type),
flags(sect.flags), vAddr(sect.vAddr), segmentOffset(sect.segmentOffset), associatedIndex(sect.associatedIndex),
info(sect.info), align(sect.align), entrySize(sect.entrySize), data(sect.data)
{
}
ELF64_Section& ELF64_Section::operator=(ELF64_Section&& sect) noexcept
{
if (this == &sect)
return *this;
hashId = sect.hashId;
id = (ehs::Str_8&&)sect.id;
programIndex = sect.programIndex;
nameOffset = sect.nameOffset;
type = sect.type;
flags = sect.flags;
vAddr = sect.vAddr;
segmentOffset = sect.segmentOffset;
associatedIndex = sect.associatedIndex;
info = sect.info;
align = sect.align;
entrySize = sect.entrySize;
data = (ehs::Serializer<ehs::UInt_64>&&)sect.data;
sect.hashId = 0;
sect.programIndex = EHS_UINT_16_MAX + 1;
sect.nameOffset = 0;
sect.type = 0;
sect.flags = 0;
sect.vAddr = 0;
sect.segmentOffset = 0;
sect.associatedIndex = 0;
sect.info = 0;
sect.align = 0;
sect.entrySize = 0;
sect.data = {ehs::Endianness::LE};
return *this;
}
ELF64_Section& ELF64_Section::operator=(const ELF64_Section& sect)
{
if (this == &sect)
return *this;
hashId = sect.hashId;
id = sect.id;
programIndex = EHS_UINT_16_MAX + 1;
nameOffset = 0;
type = sect.type;
flags = sect.flags;
vAddr = sect.vAddr;
segmentOffset = sect.segmentOffset;
associatedIndex = sect.associatedIndex;
info = sect.info;
align = sect.align;
entrySize = sect.entrySize;
data = sect.data;
return *this;
}
ehs::UInt_64 ELF64_Section::GetHashId() const
{
return hashId;
}
ehs::Str_8 ELF64_Section::GetId() const
{
return id;
}
ehs::UInt_32 ELF64_Section::GetType() const
{
return type;
}
ehs::UInt_64 ELF64_Section::GetFlags() const
{
return flags;
}
ehs::UInt_64 ELF64_Section::GetVirtualAddress() const
{
return vAddr;
}
ehs::UInt_64 ELF64_Section::GetAlignment() const
{
return align;
}
void ELF64_Section::SetData(ehs::Serializer<ehs::UInt_64> newData)
{
data = (ehs::Serializer<ehs::UInt_64>&&)newData;
}
ehs::Serializer<ehs::UInt_64>& ELF64_Section::GetData()
{
return data;
}
void ELF64_Section::Serialize(ehs::Serializer<ehs::UInt_64>& inData) const
{
inData.Write(nameOffset);
inData.Write(type);
inData.Write(flags);
inData.Write(vAddr);
inData.Write(segmentOffset);
inData.Write(data.Size());
inData.Write(associatedIndex);
inData.Write(info);
inData.Write(align);
inData.Write(entrySize);
}

View File

@@ -1,4 +1,4 @@
#include "ELF.h"
#include "ELF64.h"
#include <ehs/EHS.h>
#include <ehs/io/Console.h>
@@ -23,92 +23,16 @@ ehs::SInt_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVe
ehs::Serializer<ehs::UInt_64> code = codeFile.ReadSerializer_64(ehs::Endianness::LE, codeFile.Size());
codeFile.Release();
char sections[] = "\0.text\0.shstrtab\0";
ELF64 executable(ELFH_ARCH_64, ELFH_END_LE, ELFH_ABI_SYSTEMV, ELFH_TYPE_EXEC, ELFH_MARCH_AMD_X86_64);
ElfHeader elfHeader = {};
elfHeader.architecture = ELFH_ARCH_64;
elfHeader.endianness = ELFH_END_LE;
elfHeader.elfV1 = 1;
elfHeader.targetABI = ELFH_ABI_SYSTEMV;
elfHeader.abiV = 0;
elfHeader.elfType = ELFH_TYPE_EXEC;
elfHeader.machineArch = ELFH_MARCH_AMD_X86_64;
elfHeader.elfV2 = 1;
elfHeader.entryAddress = 0x400000 + ELFH_SIZE + PRGH_SIZE;
elfHeader.programsOffset = ELFH_SIZE;
elfHeader.sectionsOffset = ELFH_SIZE + PRGH_SIZE + code.Size() + sizeof(sections);
elfHeader.flags = 0;
elfHeader.headerSize = ELFH_SIZE;
elfHeader.pHeaderSize = PRGH_SIZE;
elfHeader.pEntries = 1;
elfHeader.sSize = SECH_SIZE;
elfHeader.sEntries = 3;
elfHeader.strTabIndex = 2;
ELF64_Section text(".text", SECH_TYPE_PROGBITS, SECH_FLAG_ALLOC | SECH_FLAG_EXEC, 16);
text.SetData(code);
executable.AddSection(text);
ElfPrgHeader programHeader = {};
programHeader.type = PRGH_TYPE_LOAD;
programHeader.flags = PRGH_FLAG_EXEC | PRGH_FLAG_READ;
programHeader.offset = 0;
programHeader.vAddr = 0x400000;
programHeader.pAddr = 0x400000;
programHeader.fileSize = ELFH_SIZE + PRGH_SIZE + code.Size();
programHeader.memSize = ELFH_SIZE + PRGH_SIZE + code.Size();
programHeader.align = 0x200000;
ElfSecHeader null = {};
null.index = 0;
null.type = SECH_TYPE_NULL;
null.flags = 0;
null.vAddr = 0;
null.offset = 0;
null.size = 0;
null.associatedIndex = 0;
null.info = 0;
null.align = 0;
null.entrySize = 0;
ElfSecHeader text = {};
text.index = 1;
text.type = SECH_TYPE_PROGBITS;
text.flags = SECH_FLAG_ALLOC | SECH_FLAG_EXEC;
text.vAddr = 0x400000 + ELFH_SIZE + PRGH_SIZE;
text.offset = ELFH_SIZE + PRGH_SIZE;
text.size = sizeof(code.Size());
text.associatedIndex = 0;
text.info = 0;
text.align = 16;
text.entrySize = 0;
ElfSecHeader strTbl = {};
strTbl.index = 7;
strTbl.type = SECH_TYPE_STRTAB;
strTbl.flags = SECH_FLAG_STRINGS;
strTbl.vAddr = 0;
strTbl.offset = ELFH_SIZE + PRGH_SIZE + code.Size();
strTbl.size = sizeof(sections);
strTbl.associatedIndex = 0;
strTbl.info = 0;
strTbl.align = 0;
strTbl.entrySize = 0;
ehs::Serializer<ehs::UInt_64> data(ehs::Endianness::LE);
WriteHeader(elfHeader, data);
WriteHeader(programHeader, data);
data.Resize(data.Size() + code.Size());
ehs::Util::Copy(&data[data.GetOffset()], code, code.Size());
data.SetOffset(data.GetOffset() + code.Size());
data.Resize(data.Size() + sizeof(sections));
ehs::Util::Copy(&data[data.GetOffset()], sections, sizeof(sections));
data.SetOffset(data.GetOffset() + sizeof(sections));
WriteHeader(null, data);
WriteHeader(text, data);
WriteHeader(strTbl, data);
executable.AddProgram({2, PRGH_TYPE_LOAD, PRGH_FLAG_EXEC | PRGH_FLAG_READ, 0x400000, 0x200000});
ehs::File file(args[2].RemoveAll("\""), ehs::Mode::WRITE, ehs::Disposition::CREATE_PERSISTENT);
file.WriteSerializer_64(data);
file.WriteSerializer_64(executable.Serialize());
return 0;
}