summaryrefslogtreecommitdiffhomepage
path: root/elf.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-03-28 22:27:01 +0100
committerRoland Reichwein <mail@reichwein.it>2020-03-28 22:27:01 +0100
commitee18ec019ef6f0ef9d7cd3b4cf0314291814cab0 (patch)
tree5f23e0bce52e24c3c04825ad008ec74a5e722a1c /elf.cpp
parent7fdcbd50a35c17e8ea7d88fbcaa3080ee44351b3 (diff)
Add ELF handling (WIP)
Diffstat (limited to 'elf.cpp')
-rw-r--r--elf.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/elf.cpp b/elf.cpp
index c94f2f5..9a835ff 100644
--- a/elf.cpp
+++ b/elf.cpp
@@ -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;
+}