From 9d3f2b289563cb7c845c8a35cb0e7553b21f85e2 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sun, 29 Mar 2020 15:01:38 +0200 Subject: Fix ELF --- elf.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 5 deletions(-) (limited to 'elf.cpp') diff --git a/elf.cpp b/elf.cpp index 9a835ff..2923392 100644 --- a/elf.cpp +++ b/elf.cpp @@ -2,17 +2,25 @@ #include "file.h" +// TODO //#include #include +// We need at least 4096 bytes aligment. Otherwise we get segfaults at startup +#define PAD 0x1000 + // Helper Functions namespace { void AddFileHeader(std::vector& data, const std::vector& code) { Elf::FileHeader fh; - fh.e_shoff = sizeof(fh) + sizeof(Elf::ProgramHeader) + code.size() + 16; +#ifdef PAD + fh.e_shoff = PAD + code.size() + 17; +#else + fh.e_shoff = sizeof(fh) + sizeof(Elf::ProgramHeader) + code.size() + 17; +#endif size_t old_size {data.size()}; data.resize(old_size + sizeof(fh)); @@ -23,7 +31,12 @@ namespace { { Elf::ProgramHeader ph; +#ifdef PAD + ph.p_offset = PAD; + ph.p_align = PAD; +#else ph.p_offset = sizeof(Elf::FileHeader) + sizeof(Elf::ProgramHeader); +#endif ph.p_filesz = code.size(); ph.p_memsz = code.size(); @@ -32,13 +45,35 @@ namespace { std::memcpy(data.data() + old_size, reinterpret_cast(&ph), sizeof(ph)); } - void AddSectionHeaderText(std::vector& data, const std::vector& code) + void AddSectionHeaderNull(std::vector& data, const std::vector& code) { Elf::SectionHeader sh; sh.sh_name = 0; // offset in section + sh.sh_size = 0; + sh.sh_type = 0; // + sh.sh_flags = 0; + sh.sh_addr = 0; + sh.sh_offset = 0; + + size_t old_size {data.size()}; + data.resize(old_size + sizeof(sh)); + std::memcpy(data.data() + old_size, reinterpret_cast(&sh), sizeof(sh)); + } + + void AddSectionHeaderText(std::vector& data, const std::vector& code) + { + Elf::SectionHeader sh; + + sh.sh_name = 1; // offset in section sh.sh_size = code.size(); sh.sh_type = 1; // program +#ifdef PAD + sh.sh_offset = PAD; +#else + sh.sh_offset = sizeof(Elf::FileHeader) + sizeof(Elf::ProgramHeader); +#endif + sh.sh_addralign = 1; size_t old_size {data.size()}; data.resize(old_size + sizeof(sh)); @@ -49,15 +84,30 @@ namespace { { Elf::SectionHeader sh; - sh.sh_name = 0; // offset in section - sh.sh_size = 16; + sh.sh_name = 7; // offset in section + sh.sh_size = 17; sh.sh_type = 3; // section names sh.sh_flags = 0; + sh.sh_addr = 0; +#ifdef PAD + sh.sh_offset = PAD + code.size(); +#else + sh.sh_offset = sizeof(Elf::FileHeader) + sizeof(Elf::ProgramHeader) + code.size(); +#endif + sh.sh_addralign = 1; size_t old_size {data.size()}; data.resize(old_size + sizeof(sh)); std::memcpy(data.data() + old_size, reinterpret_cast(&sh), sizeof(sh)); } + + void PadUpTo(std::vector& data, size_t size) + { + if (data.size() < size) { + data.resize(size); + } else + throw std::runtime_error("Padding not possible. Too many bytes already."); + } } void Elf::Write(const std::filesystem::path& path, const std::vector& code) @@ -67,13 +117,21 @@ void Elf::Write(const std::filesystem::path& path, const std::vector& c AddFileHeader(data, code); AddProgramHeader(data, code); +#ifdef PAD + PadUpTo(data, PAD); +#endif + data.insert(data.end(), code.begin(), code.end()); - std::string section_names(".text\0.shstrtab\0", 16); + std::string section_names("\0.text\0.shstrtab\0", 17); + if (section_names.size() != 17) + throw std::runtime_error("Bad size"); + 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()); + AddSectionHeaderNull(data, code); AddSectionHeaderText(data, code); AddSectionHeaderSectionNames(data, code); @@ -88,3 +146,4 @@ std::vector Elf::Read(const std::filesystem::path& path) return result; } + -- cgit v1.2.3