/* elf.c - ELF64 loader for Pactor64 */ #include "elf.h" int elf64_validate(const void *file_data, uint32_t file_size) { if (file_size < sizeof(elf64_ehdr_t)) { kprintf("[elf] File too small for ELF header\n"); return -1; } const elf64_ehdr_t *ehdr = (const elf64_ehdr_t *)file_data; if (ehdr->e_ident[0] != ELFMAG0 || ehdr->e_ident[1] != ELFMAG1 || ehdr->e_ident[2] != ELFMAG2 || ehdr->e_ident[3] != ELFMAG3) { kprintf("[elf] Bad ELF magic\n"); return -1; } if (ehdr->e_ident[4] != ELFCLASS64) { kprintf("[elf] Not a 64-bit ELF (class=%d)\n", ehdr->e_ident[4]); return -1; } if (ehdr->e_ident[5] != ELFDATA2LSB) { kprintf("[elf] Not little-endian\n"); return -1; } if (ehdr->e_type != ET_EXEC) { kprintf("[elf] Not an executable (type=%d)\n", ehdr->e_type); return -1; } if (ehdr->e_machine != EM_X86_64) { kprintf("[elf] Not x86-64 (machine=%d)\n", ehdr->e_machine); return -1; } if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > file_size) { kprintf("[elf] Program header table extends beyond file\n"); return -1; } return 0; } elf64_load_result_t elf64_load(const void *file_data, uint32_t file_size) { elf64_load_result_t result; result.valid = 0; result.entry = 0; result.load_base = 0xFFFFFFFFFFFFFFFFULL; result.load_end = 0; if (elf64_validate(file_data, file_size) != 0) return result; const elf64_ehdr_t *ehdr = (const elf64_ehdr_t *)file_data; result.entry = ehdr->e_entry; kprintf("[elf] Entry point: 0x%x\n", result.entry); kprintf("[elf] Program headers: %d\n", ehdr->e_phnum); const uint8_t *base = (const uint8_t *)file_data; for (uint16_t i = 0; i < ehdr->e_phnum; i++) { const elf64_phdr_t *phdr = (const elf64_phdr_t *) (base + ehdr->e_phoff + i * ehdr->e_phentsize); if (phdr->p_type != PT_LOAD) continue; kprintf("[elf] PT_LOAD[%d]: vaddr=0x%x filesz=0x%x memsz=0x%x flags=%c%c%c\n", i, phdr->p_vaddr, phdr->p_filesz, phdr->p_memsz, (phdr->p_flags & PF_R) ? 'R' : '-', (phdr->p_flags & PF_W) ? 'W' : '-', (phdr->p_flags & PF_X) ? 'E' : '-'); if (phdr->p_offset + phdr->p_filesz > file_size) { kprintf("[elf] Segment extends beyond file\n"); return result; } void *dest = (void *)(uintptr_t)phdr->p_vaddr; kmemset(dest, 0, phdr->p_memsz); if (phdr->p_filesz > 0) { kmemcpy(dest, base + phdr->p_offset, phdr->p_filesz); } if (phdr->p_vaddr < result.load_base) result.load_base = phdr->p_vaddr; if (phdr->p_vaddr + phdr->p_memsz > result.load_end) result.load_end = phdr->p_vaddr + phdr->p_memsz; } result.valid = 1; kprintf("[elf] Loaded at 0x%x - 0x%x, entry at 0x%x\n", result.load_base, result.load_end, result.entry); return result; } uint64_t elf64_get_entry(const void *file_data) { const elf64_ehdr_t *ehdr = (const elf64_ehdr_t *)file_data; return ehdr->e_entry; }