exe: implement querying of executable metadata from simple elf executables
This commit is contained in:
79
src/exe.c
Normal file
79
src/exe.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user