void X86ContextDump(Object *self, FILE *f) { X86Context *context = asX86Context(self); char state_str[MAX_STRING_SIZE]; /* Title */ fprintf(f, "------------\n"); fprintf(f, "Context %d\n", context->pid); fprintf(f, "------------\n\n"); str_map_flags(&x86_context_state_map, context->state, state_str, sizeof state_str); fprintf(f, "State = %s\n", state_str); if (!context->parent) fprintf(f, "Parent = None\n"); else fprintf(f, "Parent = %d\n", context->parent->pid); fprintf(f, "Heap break: 0x%x\n", context->mem->heap_break); /* Bit masks */ fprintf(f, "BlockedSignalMask = 0x%llx ", context->signal_mask_table->blocked); x86_sigset_dump(context->signal_mask_table->blocked, f); fprintf(f, "\nPendingSignalMask = 0x%llx ", context->signal_mask_table->pending); x86_sigset_dump(context->signal_mask_table->pending, f); fprintf(f, "\nAffinity = "); bit_map_dump(context->affinity, 0, x86_cpu_num_cores * x86_cpu_num_threads, f); fprintf(f, "\n"); /* End */ fprintf(f, "\n\n"); }
/* Load sections from an ELF file */ void X86ContextLoadELFSections(X86Context *self, struct elf_file_t *elf_file) { struct mem_t *mem = self->mem; struct x86_loader_t *loader = self->loader; struct elf_section_t *section; int i; enum mem_access_t perm; char flags_str[200]; x86_loader_debug("\nLoading ELF sections\n"); loader->bottom = 0xffffffff; for (i = 0; i < list_count(elf_file->section_list); i++) { section = list_get(elf_file->section_list, i); perm = mem_access_init | mem_access_read; str_map_flags(&elf_section_flags_map, section->header->sh_flags, flags_str, sizeof(flags_str)); x86_loader_debug(" section %d: name='%s', offset=0x%x, " "addr=0x%x, size=%u, flags=%s\n", i, section->name, section->header->sh_offset, section->header->sh_addr, section->header->sh_size, flags_str); /* Process section */ if (section->header->sh_flags & SHF_ALLOC) { /* Permissions */ if (section->header->sh_flags & SHF_WRITE) perm |= mem_access_write; if (section->header->sh_flags & SHF_EXECINSTR) perm |= mem_access_exec; /* Load section */ mem_map(mem, section->header->sh_addr, section->header->sh_size, perm); mem->heap_break = MAX(mem->heap_break, section->header->sh_addr + section->header->sh_size); loader->bottom = MIN(loader->bottom, section->header->sh_addr); /* If section type is SHT_NOBITS (sh_type=8), initialize to 0. * Otherwise, copy section contents from ELF file. */ if (section->header->sh_type == 8) { void *ptr; ptr = xcalloc(1, section->header->sh_size); mem_access(mem, section->header->sh_addr, section->header->sh_size, ptr, mem_access_init); free(ptr); } else { mem_access(mem, section->header->sh_addr, section->header->sh_size, section->buffer.ptr, mem_access_init); } } } }
static int mips_sys_mmap_impl(struct mips_ctx_t *ctx) { struct mips_regs_t *regs = ctx->regs; struct mem_t *mem = ctx->mem; // unsigned int args_ptr; unsigned int addr; unsigned int len; int prot; int flags; int offset; int guest_fd; char prot_str[MAX_STRING_SIZE]; char flags_str[MAX_STRING_SIZE]; /* This system call takes the arguments from memory, at the address * pointed by 'ebx'. */ addr = regs->regs_R[4]; len = regs->regs_R[5]; prot = regs->regs_R[6]; flags = regs->regs_R[7]; // mem_read(mem, args_ptr, 4, &addr); // mem_read(mem, args_ptr + 4, 4, &len); // mem_read(mem, args_ptr + 8, 4, &prot); // mem_read(mem, args_ptr + 12, 4, &flags); mem_read(mem, regs->regs_R[29] + 16, 4, &guest_fd); mem_read(mem, regs->regs_R[29] + 20, 4, &offset); // mips_sys_debug(" args_ptr=0x%x\n", args_ptr); mips_sys_debug(" addr=0x%x, len=%u, prot=0x%x, flags=0x%x, " "guest_fd=%d, offset=0x%x\n", addr, len, prot, flags, guest_fd, offset); str_map_flags(&sys_mmap_prot_map, prot, prot_str, sizeof prot_str); str_map_flags(&sys_mmap_flags_map, flags, flags_str, sizeof flags_str); mips_sys_debug(" prot=%s, flags=%s\n", prot_str, flags_str); /* Call */ return mips_sys_mmap(ctx, addr, len, prot, flags, guest_fd, offset); }
static void X86ContextUpdateState(X86Context *self, X86ContextState state) { X86Emu *emu = self->emu; X86ContextState status_diff; char state_str[MAX_STRING_SIZE]; /* Remove contexts from the following lists: * running, suspended, zombie */ if (DOUBLE_LINKED_LIST_MEMBER(emu, running, self)) DOUBLE_LINKED_LIST_REMOVE(emu, running, self); if (DOUBLE_LINKED_LIST_MEMBER(emu, suspended, self)) DOUBLE_LINKED_LIST_REMOVE(emu, suspended, self); if (DOUBLE_LINKED_LIST_MEMBER(emu, zombie, self)) DOUBLE_LINKED_LIST_REMOVE(emu, zombie, self); if (DOUBLE_LINKED_LIST_MEMBER(emu, finished, self)) DOUBLE_LINKED_LIST_REMOVE(emu, finished, self); /* If the difference between the old and new state lies in other * states other than 'x86_ctx_specmode', a reschedule is marked. */ status_diff = self->state ^ state; if (status_diff & ~X86ContextSpecMode) emu->schedule_signal = 1; /* Update state */ self->state = state; if (self->state & X86ContextFinished) self->state = X86ContextFinished | (state & X86ContextAlloc) | (state & X86ContextMapped); if (self->state & X86ContextZombie) self->state = X86ContextZombie | (state & X86ContextAlloc) | (state & X86ContextMapped); if (!(self->state & X86ContextSuspended) && !(self->state & X86ContextFinished) && !(self->state & X86ContextZombie) && !(self->state & X86ContextLocked)) self->state |= X86ContextRunning; else self->state &= ~X86ContextRunning; /* Insert context into the corresponding lists. */ if (self->state & X86ContextRunning) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, running, self); if (self->state & X86ContextZombie) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, zombie, self); if (self->state & X86ContextFinished) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, finished, self); if (self->state & X86ContextSuspended) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, suspended, self); /* Dump new state (ignore 'x86_ctx_specmode' state, it's too frequent) */ if (debug_status(x86_context_debug_category) && (status_diff & ~X86ContextSpecMode)) { str_map_flags(&x86_context_state_map, self->state, state_str, sizeof state_str); X86ContextDebug("inst %lld: ctx %d changed state to %s\n", asEmu(emu)->instructions, self->pid, state_str); } /* Start/stop x86 timer depending on whether there are any contexts * currently running. */ if (emu->running_list_count) m2s_timer_start(asEmu(emu)->timer); else m2s_timer_stop(asEmu(emu)->timer); }
static int mips_sys_open_impl(struct mips_ctx_t *ctx) { struct mips_regs_t *regs = ctx->regs; struct mem_t *mem = ctx->mem; struct mips_file_desc_t *desc; unsigned int file_name_ptr; int flags; int mode; int length; char file_name[MAX_PATH_SIZE]; char full_path[MAX_PATH_SIZE]; char temp_path[MAX_PATH_SIZE]; char flags_str[MAX_STRING_SIZE]; int host_fd; /* Arguments */ file_name_ptr = regs->regs_R[4]; flags = regs->regs_R[5]; mode = regs->regs_R[6]; length = mem_read_string(mem, file_name_ptr, sizeof file_name, file_name); if (length >= MAX_PATH_SIZE) fatal("syscall open: maximum path length exceeded"); mips_ctx_loader_get_full_path(ctx, file_name, full_path, sizeof full_path); mips_sys_debug(" filename='%s' flags=0x%x, mode=0x%x\n", file_name, flags, mode); mips_sys_debug(" fullpath='%s'\n", full_path); str_map_flags(&mips_sys_open_flags_map, flags, flags_str, sizeof flags_str); mips_sys_debug(" flags=%s\n", flags_str); /* Virtual files */ if (!strncmp(full_path, "/proc/", 6)) { /* File /proc/self/maps */ if (!strcmp(full_path, "/proc/self/maps")) { /* Create temporary file and open it. */ mips_ctx_gen_proc_self_maps(ctx, temp_path); host_fd = open(temp_path, flags, mode); assert(host_fd > 0); /* Add file descriptor table entry. */ desc = mips_file_desc_table_entry_new(ctx->file_desc_table, mips_file_desc_virtual, host_fd, temp_path, flags); mips_sys_debug(" host file '%s' opened: guest_fd=%d, host_fd=%d\n", temp_path, desc->guest_fd, desc->host_fd); return desc->guest_fd; } /* Unhandled virtual file. Let the application read the contents of the host * version of the file as if it was a regular file. */ mips_sys_debug(" warning: unhandled virtual file\n"); } /* Regular file. */ host_fd = open(full_path, flags, mode); if (host_fd == -1) return -errno; /* File opened, create a new file descriptor. */ desc = mips_file_desc_table_entry_new(ctx->file_desc_table, mips_file_desc_regular, host_fd, full_path, flags); mips_sys_debug(" file descriptor opened: guest_fd=%d, host_fd=%d\n", desc->guest_fd, desc->host_fd); /* Return guest descriptor index */ return desc->guest_fd; }