1
2
3 :(before "End Main")
4 assert(argc > 1);
5 reset();
6 load_elf(argv[1]);
7 while (EIP < End_of_program)
8 run_one_instruction();
9
10 :(code)
11 void load_elf(const string& filename) {
12 int fd = open(filename.c_str(), O_RDONLY);
13 if (fd < 0) die("%s: open", filename.c_str());
14 off_t size = lseek(fd, 0, SEEK_END);
15 lseek(fd, 0, SEEK_SET);
16 uint8_t* elf_contents = static_cast<uint8_t*>(malloc(size));
17 if (elf_contents == NULL) die("malloc(%d)", size);
18 ssize_t read_size = read(fd, elf_contents, size);
19 if (size != read_size) die("read → %d (!= %d)", size, read_size);
20 load_elf_contents(elf_contents, size);
21 free(elf_contents);
22 }
23
24 void load_elf_contents(uint8_t* elf_contents, size_t length) {
25 uint8_t magic[5] = {0};
26 memcpy(magic, elf_contents, 4);
27 if (0 != memcmp(magic, "\177ELF", 4))
28 die("Invalid ELF file starting with \"%s\"", magic);
29
30 uint32_t e_type = u32_in(&elf_contents[16]);
31 if (0x00030002 != e_type)
32 die("ELF type/machine 0x%x isn't i386 executable", e_type);
33
34 uint32_t e_entry = u32_in(&elf_contents[24]);
35 uint32_t e_phoff = u32_in(&elf_contents[28]);
36 uint32_t p_vaddr = u32_in(&elf_contents[e_phoff + 8]);
37 uint32_t p_memsz = u32_in(&elf_contents[e_phoff + 20]);
38
39 Mem.resize(p_memsz); TODO
40 if (length > p_memsz - p_vaddr) length = p_memsz - p_vaddr;
41 for (size_t i = 0; i < length; ++i)
42 Mem.at(p_vaddr + i) = elf_contents[i];
43 End_of_program = p_memsz;
44
45 TODO
46
47 Reg[ESP].u = Reg[EBP].u = End_of_program;
48 EIP = e_entry;
49 }
50
51 inline uint32_t u32_in(uint8_t* p) {
52 return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
53 }
54
55 void die(const char* format, ...) {
56 va_list args;
57 va_start(args, format);
58 vfprintf(stderr, format, args);
59 if (errno)
60 perror("<200c>");
61 else
62 fprintf(stderr, "\n");
63 va_end(args);
64 abort();
65 }
66
67 :(before "End Types")
68 #include <sys/types.h>
69 #include <sys/stat.h>
70 #include <fcntl.h>
71 #include <unistd.h>
72 #include <stdarg.h>
73 #include <errno.h>