diff options
author | Roland Reichwein <mail@reichwein.it> | 2020-03-28 22:27:01 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2020-03-28 22:27:01 +0100 |
commit | ee18ec019ef6f0ef9d7cd3b4cf0314291814cab0 (patch) | |
tree | 5f23e0bce52e24c3c04825ad008ec74a5e722a1c /elf.cpp | |
parent | 7fdcbd50a35c17e8ea7d88fbcaa3080ee44351b3 (diff) |
Add ELF handling (WIP)
Diffstat (limited to 'elf.cpp')
-rw-r--r-- | elf.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
@@ -1 +1,90 @@ #include "elf.h" + +#include "file.h" + +//#include <boost/endian/conversion.hpp> + +#include <cstring> + +// Helper Functions +namespace { + void AddFileHeader(std::vector<uint8_t>& data, const std::vector<uint8_t>& code) + { + Elf::FileHeader fh; + + fh.e_shoff = sizeof(fh) + sizeof(Elf::ProgramHeader) + code.size() + 16; + + size_t old_size {data.size()}; + data.resize(old_size + sizeof(fh)); + std::memcpy(data.data() + old_size, reinterpret_cast<void*>(&fh), sizeof(fh)); + } + + void AddProgramHeader(std::vector<uint8_t>& data, const std::vector<uint8_t>& code) + { + Elf::ProgramHeader ph; + + ph.p_offset = sizeof(Elf::FileHeader) + sizeof(Elf::ProgramHeader); + ph.p_filesz = code.size(); + ph.p_memsz = code.size(); + + size_t old_size {data.size()}; + data.resize(old_size + sizeof(ph)); + std::memcpy(data.data() + old_size, reinterpret_cast<void*>(&ph), sizeof(ph)); + } + + void AddSectionHeaderText(std::vector<uint8_t>& data, const std::vector<uint8_t>& code) + { + Elf::SectionHeader sh; + + sh.sh_name = 0; // offset in section + sh.sh_size = code.size(); + sh.sh_type = 1; // program + + size_t old_size {data.size()}; + data.resize(old_size + sizeof(sh)); + std::memcpy(data.data() + old_size, reinterpret_cast<void*>(&sh), sizeof(sh)); + } + + void AddSectionHeaderSectionNames(std::vector<uint8_t>& data, const std::vector<uint8_t>& code) + { + Elf::SectionHeader sh; + + sh.sh_name = 0; // offset in section + sh.sh_size = 16; + sh.sh_type = 3; // section names + sh.sh_flags = 0; + + size_t old_size {data.size()}; + data.resize(old_size + sizeof(sh)); + std::memcpy(data.data() + old_size, reinterpret_cast<void*>(&sh), sizeof(sh)); + } +} + +void Elf::Write(const std::filesystem::path& path, const std::vector<uint8_t>& code) +{ + std::vector<uint8_t> data; + + AddFileHeader(data, code); + AddProgramHeader(data, code); + + data.insert(data.end(), code.begin(), code.end()); + + std::string section_names(".text\0.shstrtab\0", 16); + size_t old_size {data.size()}; + data.resize(old_size + section_names.size()); + std::memcpy(data.data() + old_size, section_names.data(), section_names.size()); + + AddSectionHeaderText(data, code); + AddSectionHeaderSectionNames(data, code); + + File::setFile(path, data); +} + +std::vector<uint8_t> Elf::Read(const std::filesystem::path& path) +{ + std::vector<uint8_t> result; + + // TODO + + return result; +} |