void init_address_space(void) {
void *ret = mmap((void *)AS_START, AS_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
assert(ret != MAP_FAILED);
uint32_t *p = ret;
int i;
for (i = 0; i < AS_SIZE / sizeof(uint32_t); i ++) {
p = rand();
}
}
void segv_handler(int signum, siginfo_t *siginfo, void *ucontext) {
printf("catch SIGSEGV\n");
// get ebp and eip from the context
int *regs = ((ucontext_t *)ucontext)->uc_mcontext.gregs;
uint32_t ebp = regs[REG_EBP];
uint32_t eip = regs[REG_EIP];
printf("ebp = %x, eip = %x\n", ebp, eip);
bt(ebp, eip);
exit(0);
}
void load_elf_tables(char *filename) {
int ret;
FILE *fp = fopen(filename, "rb");
assert(fp != NULL);
uint8_t buf[sizeof(Elf32_Ehdr)];
ret = fread(buf, sizeof(Elf32_Ehdr), 1, fp);
assert(ret == 1);
// the first several bytes contain the ELF header
Elf32_Ehdr *elf = (void *)buf;
char magic[] = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
// check ELF header
assert(memcmp(elf->e_ident, magic, 4) == 0); // magic number
assert(elf->e_ident[EI_CLASS] == ELFCLASS32); // 32-bit architecture
assert(elf->e_ident[EI_DATA] == ELFDATA2LSB); // littel-endian
assert(elf->e_ident[EI_VERSION] == EV_CURRENT); // current version
assert(elf->e_ident[EI_OSABI] == ELFOSABI_SYSV || // UNIX System V ABI
elf->e_ident[EI_OSABI] == ELFOSABI_LINUX); // UNIX - GNU
assert(elf->e_ident[EI_ABIVERSION] == 0); // should be 0
assert(elf->e_type == ET_EXEC); // executable file
assert(elf->e_machine == EM_386); // Intel 80386 architecture
assert(elf->e_version == EV_CURRENT); // current version
// load section header table
uint32_t sh_size = elf->e_shentsize * elf->e_shnum;
Elf32_Shdr *sh = malloc(sh_size);
fseek(fp, elf->e_shoff, SEEK_SET);
ret = fread(sh, sh_size, 1, fp);
assert(ret == 1);
// load section header string table
char *shstrtab = malloc(sh[elf->e_shstrndx].sh_size);
fseek(fp, sh[elf->e_shstrndx].sh_offset, SEEK_SET);
ret = fread(shstrtab, sh[elf->e_shstrndx].sh_size, 1, fp);
assert(ret == 1);
int i;
for(i = 0; i < elf->e_shnum; i ++) {
if(sh.sh_type == SHT_SYMTAB &&
strcmp(shstrtab + sh.sh_name, ".symtab") == 0) {
// load symbol table
symtab = malloc(sh.sh_size);
fseek(fp, sh.sh_offset, SEEK_SET);
ret = fread(symtab, sh.sh_size, 1, fp);
assert(ret == 1);
nr_symtab_entry = sh.sh_size / sizeof(symtab[0]);
}
else if(sh.sh_type == SHT_STRTAB &&
strcmp(shstrtab + sh.sh_name, ".strtab") == 0) {
// load string table
strtab = malloc(sh.sh_size);
fseek(fp, sh.sh_offset, SEEK_SET);
ret = fread(strtab, sh.sh_size, 1, fp);
assert(ret == 1);
}
}
free(sh);
free(shstrtab);
assert(strtab != NULL && symtab != NULL);
fclose(fp);
}