Organized and documented the code more.
This commit is contained in:
61
src/ELF.cpp
Normal file
61
src/ELF.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#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);
|
||||
}
|
114
src/main.cpp
Normal file
114
src/main.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "ELF.h"
|
||||
|
||||
#include <ehs/EHS.h>
|
||||
#include <ehs/io/Console.h>
|
||||
#include <ehs/io/File.h>
|
||||
|
||||
ehs::SInt_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVer)
|
||||
{
|
||||
*appName = "Compiler";
|
||||
*appVerId = "Alpha";
|
||||
*appVer = {1, 0, 0};
|
||||
|
||||
ehs::Vector<ehs::Str_8> args = ehs::Console::GetArgs_8();
|
||||
if (args.Size() <= 1)
|
||||
{
|
||||
ehs::Console::Write_8(*appName + " " + *appVerId + " v" + ehs::Str_8::FromNum(appVer->major) + "." +
|
||||
ehs::Str_8::FromNum(appVer->minor) + "." + ehs::Str_8::FromNum(appVer->patch));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ehs::File codeFile(args[1].RemoveAll("\""), ehs::Mode::READ, ehs::Disposition::OPEN);
|
||||
ehs::Serializer<ehs::UInt_64> code = codeFile.ReadSerializer_64(ehs::Endianness::LE, codeFile.Size());
|
||||
codeFile.Release();
|
||||
|
||||
char sections[] = "\0.text\0.shstrtab\0";
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
ehs::File file(args[2].RemoveAll("\""), ehs::Mode::WRITE, ehs::Disposition::CREATE_PERSISTENT);
|
||||
file.WriteSerializer_64(data);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user