/** * @file elf_load.cpp * @brief Loads ELF binary data into memory for execution. * * Copyright (C) 2020 Clyne Sullivan * * Distributed under the GNU GPL v3 or later. You should have received a copy of * the GNU General Public License along with this program. * If not, see . */ #include "elf_load.hpp" #include "elf_format.hpp" #include #include static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' }; template constexpr static auto ptr_from_offset(void *base, uint32_t offset) { return reinterpret_cast(reinterpret_cast(base) + offset); } namespace ELF { Entry load(void *elf_data) { // Check the ELF's header signature auto ehdr = reinterpret_cast(elf_data); if (!std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header)) return nullptr; // Iterate through program header LOAD sections bool loaded = false; auto phdr = ptr_from_offset(elf_data, ehdr->e_phoff); for (Elf32_Half i = 0; i < ehdr->e_phnum; i++) { if (phdr->p_type == PT_LOAD) { if (phdr->p_filesz == 0) { std::memset(reinterpret_cast(phdr->p_vaddr), 0, phdr->p_memsz); } else { std::memcpy(reinterpret_cast(phdr->p_vaddr), ptr_from_offset(elf_data, phdr->p_offset), phdr->p_filesz); if (!loaded) loaded = true; } } phdr = ptr_from_offset(phdr, ehdr->e_phentsize); } return loaded ? reinterpret_cast(ehdr->e_entry) : nullptr; } } // namespace ELF