Files
ec3/src/exe.c

80 lines
1.7 KiB
C
Raw Normal View History

#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;
}
}