about summary refs log tree commit diff stats
Commit message (Expand)AuthorAgeFilesLines
...
* 3497Kartik K. Agaram2016-10-132-46/+48
* 3496Kartik K. Agaram2016-10-111-2/+2
* 3495Kartik K. Agaram2016-10-111-1/+1
* 3494Kartik K. Agaram2016-10-111-3/+1
* 3493Kartik K. Agaram2016-10-101-1/+1
* 3492Kartik K. Agaram2016-10-101-2/+2
* 3491Kartik K. Agaram2016-10-0915-175/+347
* 3490Kartik K. Agaram2016-10-0917-303/+310
* 3489Kartik K. Agaram2016-10-0822-1015/+1015
* 3488 -Kartik K. Agaram2016-10-082-2/+2
* 3487Kartik K. Agaram2016-10-081-1/+1
* 3486Kartik K. Agaram2016-10-081-3/+3
* 3485Kartik K. Agaram2016-10-081-2/+2
* 3484Kartik K. Agaram2016-10-081-5/+5
* 3483Kartik K. Agaram2016-10-089-111/+111
* 3482Kartik K. Agaram2016-10-081-1/+1
* 3481Kartik K. Agaram2016-10-081-2/+2
* 3480Kartik K. Agaram2016-10-081-2/+2
* 3479Kartik K. Agaram2016-10-081-0/+0
* 3478Kartik K. Agaram2016-10-081-5/+8
* 3477Kartik K. Agaram2016-10-081-0/+5
* 3476Kartik K. Agaram2016-10-073-10/+10
* 3475Kartik K. Agaram2016-10-071-22/+20
* 3474Kartik K. Agaram2016-10-071-20/+27
* 3473Kartik K. Agaram2016-10-071-2/+2
* 3472Kartik K. Agaram2016-10-071-2/+2
* 3471Kartik K. Agaram2016-10-071-10/+17
* 3470Kartik K. Agaram2016-10-071-3/+4
* 3469Kartik K. Agaram2016-10-071-5/+5
* 3468Kartik K. Agaram2016-10-071-1/+1
* 3467Kartik K. Agaram2016-10-071-19/+18
* 3466Kartik K. Agaram2016-10-071-13/+14
* 3465Kartik K. Agaram2016-10-071-5/+8
* 3464Kartik K. Agaram2016-10-071-2/+1
* 3463Kartik K. Agaram2016-10-071-5/+4
* 3462Kartik K. Agaram2016-10-074-5/+11
* 3461Kartik K. Agaram2016-10-071-8/+9
* 3460Kartik K. Agaram2016-10-071-0/+1
* 3459Kartik K. Agaram2016-10-071-2/+2
* 3458Stephen Malina2016-10-072-2/+118
* 3457Kartik K. Agaram2016-10-0633-1766/+1766
* 3456Kartik K. Agaram2016-10-0619-568/+601
* 3455Kartik K. Agaram2016-10-063-3/+3
* 3454Kartik K. Agaram2016-10-061-1/+1
* 3453Kartik K. Agaram2016-10-061-0/+4
* 3452Kartik K. Agaram2016-10-061-21/+23
* 3451Kartik K. Agaram2016-10-061-1/+1
* 3450Kartik K. Agaram2016-10-067-75/+9
* 3449Kartik K. Agaram2016-10-061-1/+2
* 3448Kartik K. Agaram2016-10-063-8/+8
span>= read(fd, elf_contents, size); if (size != read_size) raise << "read → " << size << " (!= " << read_size << ')' << perr() << '\n' << die(); load_elf_contents(elf_contents, size); free(elf_contents); } void load_elf_contents(uint8_t* elf_contents, size_t size) { uint8_t magic[5] = {0}; memcpy(magic, elf_contents, 4); if (memcmp(magic, "\177ELF", 4) != 0) raise << "Invalid ELF file; starts with \"" << magic << '"' << die(); if (elf_contents[4] != 1) raise << "Only 32-bit ELF files (4-byte words; virtual addresses up to 4GB) supported.\n" << die(); if (elf_contents[5] != 1) raise << "Only little-endian ELF files supported.\n" << die(); // unused: remaining 10 bytes of e_ident uint32_t e_machine_type = u32_in(&elf_contents[16]); if (e_machine_type != 0x00030002) raise << "ELF type/machine 0x" << HEXWORD << e_machine_type << " isn't i386 executable\n" << die(); // unused: e_version. We only support version 1, and later versions will be backwards compatible. uint32_t e_entry = u32_in(&elf_contents[24]); uint32_t e_phoff = u32_in(&elf_contents[28]); // unused: e_shoff // unused: e_flags uint32_t e_ehsize = u16_in(&elf_contents[40]); if (e_ehsize < 52) raise << "Invalid binary; ELF header too small\n" << die(); uint32_t e_phentsize = u16_in(&elf_contents[42]); uint32_t e_phnum = u16_in(&elf_contents[44]); info << e_phnum << " entries in the program header, each " << e_phentsize << " bytes long\n"; // unused: e_shentsize // unused: e_shnum // unused: e_shstrndx for (size_t i = 0; i < e_phnum; ++i) load_program_header(elf_contents, size, e_phoff + i*e_phentsize, e_ehsize); // TODO: need to set up real stack somewhere Reg[ESP].u = Reg[EBP].u = End_of_program; EIP = e_entry; } void load_program_header(uint8_t* elf_contents, size_t size, uint32_t offset, uint32_t e_ehsize) { uint32_t p_type = u32_in(&elf_contents[offset]); info << "program header at offset " << offset << ": type " << p_type << '\n'; if (p_type != 1) { info << "ignoring segment at offset " << offset << " of non PT_LOAD type " << p_type << " (see http://refspecs.linuxbase.org/elf/elf.pdf)\n"; return; } uint32_t p_offset = u32_in(&elf_contents[offset + 4]); uint32_t p_vaddr = u32_in(&elf_contents[offset + 8]); if (e_ehsize > p_vaddr) raise << "Invalid binary; program header overlaps ELF header\n" << die(); // unused: p_paddr uint32_t p_filesz = u32_in(&elf_contents[offset + 16]); uint32_t p_memsz = u32_in(&elf_contents[offset + 20]); if (p_filesz != p_memsz) raise << "Can't handle segments where p_filesz != p_memsz (see http://refspecs.linuxbase.org/elf/elf.pdf)\n" << die(); if (p_offset + p_filesz > size) raise << "Invalid binary; segment at offset " << offset << " is too large: wants to end at " << p_offset+p_filesz << " but the file ends at " << size << '\n' << die(); Mem.resize(p_vaddr + p_memsz); if (size > p_memsz) size = p_memsz; info << "blitting file offsets (" << p_offset << ", " << (p_offset+p_filesz) << ") to addresses (" << p_vaddr << ", " << (p_vaddr+p_memsz) << ")\n"; for (size_t i = 0; i < p_filesz; ++i) Mem.at(p_vaddr + i) = elf_contents[p_offset + i]; if (End_of_program < p_vaddr+p_memsz) End_of_program = p_vaddr+p_memsz; } inline uint32_t u32_in(uint8_t* p) { return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; } inline uint16_t u16_in(uint8_t* p) { return p[0] | p[1] << 8; } :(before "End Types") struct perr {}; :(code) ostream& operator<<(ostream& os, unused perr) { if (errno) os << ": " << strerror(errno); return os; } :(before "End Types") struct die {}; :(code) ostream& operator<<(unused ostream& os, unused die) { if (Trace_stream) Trace_stream->newline(); exit(1); } :(before "End Includes") #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdarg.h> #include <errno.h> #define info cerr // #define info dbg