#include "exe.h" #include "elf.h" static enum ec3_status get_elf_executable_info( FILE *fp, struct ec3_tag_executable_info *out) { elf_ehdr_t hdr; fseek(fp, 0, SEEK_SET); size_t r = fread(&hdr, sizeof hdr, 1, fp); if (r != 1) { return EC3_ERR_IO_FAILURE; } out->exe_elf.elf_entry = hdr.e_entry; bool text_found = false, data_found = false; for (size_t i = 0; i < hdr.e_phnum; i++) { elf_phdr_t phdr; size_t offset = hdr.e_phoff + (i * hdr.e_phentsize); fseek(fp, offset, SEEK_SET); r = fread(&phdr, sizeof phdr, 1, fp); if (r != 1) { return EC3_ERR_IO_FAILURE; } if (phdr.p_type != PT_LOAD) { continue; } if ((phdr.p_flags & (PF_R | PF_X)) == (PF_R | PF_X)) { if (text_found) { out->exe_format = EC3_EXEC_OTHER; return EC3_SUCCESS; } out->exe_elf.elf_text_offset = phdr.p_offset; out->exe_elf.elf_text_filesz = phdr.p_filesz; out->exe_elf.elf_text_vaddr = phdr.p_vaddr; out->exe_elf.elf_text_memsz = phdr.p_memsz; out->exe_elf.elf_text_align = phdr.p_align; text_found = true; } if ((phdr.p_flags & (PF_R | PF_W)) == (PF_R | PF_W)) { if (data_found) { out->exe_format = EC3_EXEC_OTHER; return EC3_SUCCESS; } out->exe_elf.elf_data_offset = phdr.p_offset; out->exe_elf.elf_data_filesz = phdr.p_filesz; out->exe_elf.elf_data_vaddr = phdr.p_vaddr; out->exe_elf.elf_data_memsz = phdr.p_memsz; out->exe_elf.elf_data_align = phdr.p_align; data_found = true; } } return EC3_SUCCESS; } enum ec3_status get_executable_info_from_file( FILE *fp, enum ec3_executable_format format, struct ec3_tag_executable_info *out) { out->exe_format = format; switch (format) { case EC3_EXEC_ELF: return get_elf_executable_info(fp, out); default: return EC3_SUCCESS; } }