void str_map_flags(struct str_map_t *map, int flags, char *out, int size) { int i; char *comma = ""; char temp[MAX_STRING_SIZE]; str_printf(&out, &size, "{"); for (i = 0; i < 32; i++) { if (flags & (1 << i)) { str_printf(&out, &size, "%s", comma); str_map_value_buf(map, 1 << i, temp, sizeof temp); str_printf(&out, &size, "%s", temp); comma = "|"; } } str_printf(&out, &size, "}"); }
/* Load program headers table */ void X86ContextLoadProgramHeaders(X86Context *self) { struct x86_loader_t *loader = self->loader; struct mem_t *mem = self->mem; struct elf_file_t *elf_file = loader->elf_file; struct elf_program_header_t *program_header; uint32_t phdt_base; uint32_t phdt_size; uint32_t phdr_count; uint32_t phdr_size; char str[MAX_STRING_SIZE]; int i; /* Load program header table from ELF */ x86_loader_debug("\nLoading program headers\n"); phdr_count = elf_file->header->e_phnum; phdr_size = elf_file->header->e_phentsize; phdt_size = phdr_count * phdr_size; assert(phdr_count == list_count(elf_file->program_header_list)); /* Program header PT_PHDR, specifying location and size of the program header table itself. */ /* Search for program header PT_PHDR, specifying location and size of the program header table. * If none found, choose loader->bottom - phdt_size. */ phdt_base = loader->bottom - phdt_size; for (i = 0; i < list_count(elf_file->program_header_list); i++) { program_header = list_get(elf_file->program_header_list, i); if (program_header->header->p_type == PT_PHDR) phdt_base = program_header->header->p_vaddr; } x86_loader_debug(" virtual address for program header table: 0x%x\n", phdt_base); /* Load program headers */ mem_map(mem, phdt_base, phdt_size, mem_access_init | mem_access_read); for (i = 0; i < list_count(elf_file->program_header_list); i++) { /* Load program header */ program_header = list_get(elf_file->program_header_list, i); mem_access(mem, phdt_base + i * phdr_size, phdr_size, program_header->header, mem_access_init); /* Debug */ str_map_value_buf(&elf_program_header_type_map, program_header->header->p_type, str, sizeof(str)); x86_loader_debug(" header loaded at 0x%x\n", phdt_base + i * phdr_size); x86_loader_debug(" type=%s, offset=0x%x, vaddr=0x%x, paddr=0x%x\n", str, program_header->header->p_offset, program_header->header->p_vaddr, program_header->header->p_paddr); x86_loader_debug(" filesz=%d, memsz=%d, flags=%d, align=%d\n", program_header->header->p_filesz, program_header->header->p_memsz, program_header->header->p_flags, program_header->header->p_align); /* Program interpreter */ if (program_header->header->p_type == 3) { mem_read_string(mem, program_header->header->p_vaddr, sizeof(str), str); loader->interp = str_set(NULL, str); } } /* Free buffer and save pointers */ loader->phdt_base = phdt_base; loader->phdr_count = phdr_count; }