void img_load (IMG img, void *v) { struct event_imload *imevent; char buffer[512]; size_t length; /* fprintf(logfp, "load %s off=%08x low=%08x high=%08x start=%08x size=%08x\n", IMG_Name(img).c_str(), IMG_LoadOffset(img), IMG_LowAddress(img), IMG_HighAddress(img), IMG_StartAddress(img), IMG_SizeMapped(img));*/ imevent = (struct event_imload *)buffer; length = IMG_Name(img).length(); if (length > sizeof(buffer) - sizeof(struct event_imload)) length = sizeof(buffer) - sizeof(struct event_imload); imevent->comm.type = ET_IMLOAD; imevent->comm.tid = PIN_ThreadId(); imevent->struct_size = (int)((char *)imevent->name - (char *)imevent) + length + 1; imevent->addr = IMG_LowAddress(img); imevent->size = IMG_HighAddress(img) - IMG_LowAddress(img); imevent->entry = IMG_Entry(img); imevent->ismain = IMG_IsMainExecutable(img); memcpy(imevent->name, IMG_Name(img).c_str(), length); imevent->name[length] = '\0'; tb_write((event_common *)imevent, (size_t)imevent->struct_size); osdep_iterate_symbols(img, process_symbol, (void *)&img); tb_flush(PIN_ThreadId()); fprintf(logfp, "img+ %08x+%08x %s\n", IMG_StartAddress(img), IMG_SizeMapped(img), IMG_Name(img).c_str()); }
/** Records given fragment. */ void record_frag(void* ctx, instrlist_t* frag, frag_id_t id) { bool flushed; struct trace_buffer_t* tb; tb = dr_get_tls_field(ctx); tb_tlv_complete(tb); for(flushed = false; ; tb_flush(tb), flushed = true) { struct frag_t* frag_data; void* current; tb_tlv(tb, TYPE_FRAG); frag_data = tb->current; current = record_frag_instrs(ctx, frag, &frag_data->chunks, tb_end(tb)); if(current) { frag_data->id = id; tb->current = current; tb_tlv_complete(tb); tb_tlv(tb, TYPE_TRACE); break; } else { if(flushed) { dr_fprintf(STDERR, "fatal: not enough buffer space after flush\n"); dr_exit_process(1); } tb_tlv_cancel(tb); } } }
void finish_qemu_rr (void) { printf("Record/Replay finished Entering live mode\n"); tb_flush(first_cpu); first_cpu->n_branches = 0; }
void helper_fence_i(CPURISCVState *env) { RISCVCPU *cpu = riscv_env_get_cpu(env); CPUState *cs = CPU(cpu); // Flush QEMU's TLB tlb_flush(cs, 1); // ARM port seems to not know if this is okay inside a TB... // But we need to do it tb_flush(cs); }
void ski_exec_trace_stop(CPUState* env){ if(ski_exec_trace_execution_fd){ ski_loop_finish(); fclose(ski_exec_trace_execution_fd); ski_exec_trace_execution_fd = 0; tb_flush(env); //FIXME: Should flush for all CPUs } }
void do_flush_all (void) { first_cpu->halted = 0; first_cpu->interrupt_request = 0; first_cpu->exit_request = 0; tb_flush(first_cpu); tb_invalidated_flag = 1; tlb_flush (first_cpu, 1); }
static int qemu_cpu_exec(CPUState *env) { int ret; #ifdef CONFIG_PROFILER int64_t ti; #endif #ifdef CONFIG_PROFILER ti = profile_getclock(); #endif if (use_icount) { int64_t count; int decr; qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); env->icount_decr.u16.low = 0; env->icount_extra = 0; count = qemu_next_icount_deadline(); count = (count + (1 << icount_time_shift) - 1) >> icount_time_shift; qemu_icount += count; decr = (count > 0xffff) ? 0xffff : count; count -= decr; env->icount_decr.u16.low = decr; env->icount_extra = count; } #ifdef CONFIG_TRACE if (tbflush_requested) { tbflush_requested = 0; tb_flush(env); return EXCP_INTERRUPT; } #endif ret = cpu_exec(env); #ifdef CONFIG_PROFILER qemu_time += profile_getclock() - ti; #endif if (use_icount) { /* Fold pending instructions back into the instruction counter, and clear the interrupt flag. */ qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); env->icount_decr.u32 = 0; env->icount_extra = 0; } return ret; }
static int qemu_cpu_exec(CPUState *env) { int ret; #ifdef CONFIG_PROFILER int64_t ti; #endif #if 1 /* yclin */ if (tracer_toggle_request) { tb_flush(env); } #endif #ifdef CONFIG_PROFILER ti = profile_getclock(); #endif if (use_icount) { int64_t count; int decr; qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); env->icount_decr.u16.low = 0; env->icount_extra = 0; count = qemu_icount_round (qemu_next_deadline()); qemu_icount += count; decr = (count > 0xffff) ? 0xffff : count; count -= decr; env->icount_decr.u16.low = decr; env->icount_extra = count; } ret = cpu_exec(env); #ifdef CONFIG_PROFILER qemu_time += profile_getclock() - ti; #endif if (use_icount) { /* Fold pending instructions back into the instruction counter, and clear the interrupt flag. */ qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); env->icount_decr.u32 = 0; env->icount_extra = 0; } return ret; }
// XXX: use exceptions on Windows dr_signal_action_t handle_signal(void* ctx, dr_siginfo_t* siginfo) { dr_fprintf(STDERR, "info: caught signal %u\n", (unsigned int)siginfo->sig); if(siginfo->sig == SIGSEGV) { struct trace_buffer_t* tb; struct tag_info_t* tag_info; #ifdef TRACE_DEBUG dr_fprintf(STDERR, "debug: this is SIGSEGV and faulting address is " PFX "\n", siginfo->access_address); #endif if(siginfo->raw_mcontext == NULL) { dr_fprintf(STDERR, "fatal: raw_mcontext missing\n"); dr_exit_process(1); } #ifdef TRACE_DEBUG dr_fprintf(STDERR, "debug: offending instruction is\n"); disassemble(ctx, siginfo->raw_mcontext->xip, STDERR); #endif tag_info = find_tag_or_die(siginfo->fault_fragment_info.tag); if(is_guard_page_access(siginfo->raw_mcontext, tag_info, siginfo->fault_fragment_info.cache_start_pc)) { #ifdef TRACE_DEBUG dr_fprintf(STDERR, "debug: this is guard page access\n"); #endif // Flush. tb = dr_get_tls_field(siginfo->drcontext); tb_flush(tb); tb_tlv(tb, TYPE_TRACE); // Restart instrumentation. siginfo->raw_mcontext->xip = siginfo->fault_fragment_info.cache_start_pc + tag_info->instr_info.first_offset; restore_state(ctx, siginfo->raw_mcontext, tag_info); return DR_SIGNAL_SUPPRESS; } } return DR_SIGNAL_DELIVER; }
void ski_exec_trace_start(CPUState* env){ char trace_filename[256]; char trace_filename_full[512]; time_t t; struct tm *tmp; // Initialize the execution trace file for this test (different tests have different execution trace files) t = time(NULL); tmp = localtime(&t); assert(tmp); if(ski_forkall_enabled){ assert(snprintf(trace_filename, sizeof(trace_filename), "trace_%s_%d_%d_%d.txt", ski_init_execution_ts, ski_init_options_input_number[0] , ski_init_options_input_number[1], ski_init_options_seed)); }else{ assert(strftime(trace_filename, sizeof(trace_filename), "trace_%Y%m%d_%H%M%S.txt", tmp)); } SKI_TRACE("Execution trace filename: \"%s\"\n", trace_filename); trace_filename_full[0] = 0; assert(strlen(ski_init_options_destination_dir)>0); sprintf(trace_filename_full, "%s/%s", ski_init_options_destination_dir, trace_filename); ski_exec_redirect_to_null(trace_filename_full); ski_exec_trace_execution_fd = fopen(trace_filename_full,"w"); assert(ski_exec_trace_execution_fd); SKI_TRACE("Opened the trace file\n"); if(ski_forkall_enabled){ ski_stats_add_trace(trace_filename, trace_filename_full); } ski_exec_trace_nr_entries = 0; ski_loop_init(); tb_flush(env); #define SKI_EXIT_OTHER -1 }
void tb_tlv(struct trace_buffer_t* tb, uint32_t type) { void* original_current; // Align current position. original_current = tb->current; tb->current = aligned_tlv(tb->current); // Check if there is space for a new TLV. if(tb_available(tb) < sizeof(struct tlv_t)) { // Flush; assume resulting position is properly aligned. tb_flush(tb); } else { // Fill padding. memset(original_current, 'X', tb->current - original_current); } // Set up a new TLV. tb->current_tlv = tb->current; tb->current_tlv->type = type; tb->current = tb->current_tlv + 1; }
/** Records fragment deletion event into trace buffer. */ void record_deletion(struct trace_buffer_t* tb, frag_id_t id) { struct frag_del_t* frag_del; bool flushed; tb_tlv_complete(tb); for(flushed = false; ; tb_flush(tb), flushed = true) { tb_tlv(tb, TYPE_FRAG_DEL); if(tb_available(tb) < sizeof(struct frag_del_t)) { if(flushed) { dr_fprintf(STDERR, "fatal: not enough buffer space after flush\n"); dr_exit_process(1); } tb_tlv_cancel(tb); continue; } else { frag_del = tb->current; frag_del->frag_id = id; tb->current = frag_del + 1; tb_tlv_complete(tb); tb_tlv(tb, TYPE_TRACE); break; } } }
static void gdb_vm_state_change(void *opaque, int running, RunState state) { GDBState *s = gdbserver_state; CPUState *cpu = s->c_cpu; char buf[256]; const char *type; int ret; if (running || s->state == RS_INACTIVE) { return; } /* Is there a GDB syscall waiting to be sent? */ if (s->current_syscall_cb) { put_packet(s, s->syscall_buf); return; } switch (state) { case RUN_STATE_DEBUG: if (cpu->watchpoint_hit) { switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) { case BP_MEM_READ: type = "r"; break; case BP_MEM_ACCESS: type = "a"; break; default: type = ""; break; } snprintf(buf, sizeof(buf), "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";", GDB_SIGNAL_TRAP, cpu_index(cpu), type, (target_ulong)cpu->watchpoint_hit->vaddr); cpu->watchpoint_hit = NULL; goto send_packet; } tb_flush(cpu); ret = GDB_SIGNAL_TRAP; break; case RUN_STATE_PAUSED: ret = GDB_SIGNAL_INT; break; case RUN_STATE_SHUTDOWN: ret = GDB_SIGNAL_QUIT; break; case RUN_STATE_IO_ERROR: ret = GDB_SIGNAL_IO; break; case RUN_STATE_WATCHDOG: ret = GDB_SIGNAL_ALRM; break; case RUN_STATE_INTERNAL_ERROR: ret = GDB_SIGNAL_ABRT; break; case RUN_STATE_SAVE_VM: case RUN_STATE_RESTORE_VM: return; case RUN_STATE_FINISH_MIGRATE: ret = GDB_SIGNAL_XCPU; break; default: ret = GDB_SIGNAL_UNKNOWN; break; } gdb_set_stop_cpu(cpu); snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu)); send_packet: put_packet(s, buf); /* disable single step if it was enabled */ cpu_single_step(cpu, 0); }
/* CPUClass::reset() */ static void arm_cpu_reset(CPUState *s) { ARMCPU *cpu = ARM_CPU(s); ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); CPUARMState *env = &cpu->env; acc->parent_reset(s); memset(env, 0, offsetof(CPUARMState, features)); g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; } if (arm_feature(env, ARM_FEATURE_AARCH64)) { /* 64 bit CPUs always start in 64 bit mode */ env->aarch64 = 1; #if defined(CONFIG_USER_ONLY) env->pstate = PSTATE_MODE_EL0t; /* Userspace expects access to CTL_EL0 and the cache ops */ env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI; /* and to the FP/Neon instructions */ env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3); #else env->pstate = PSTATE_MODE_EL1h; env->pc = cpu->rvbar; #endif } else { #if defined(CONFIG_USER_ONLY) /* Userspace expects access to cp10 and cp11 for FP/Neon */ env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 4, 0xf); #endif } #if defined(CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; /* For user mode we must enable access to coprocessors */ env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->cp15.c15_cpar = 3; } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { env->cp15.c15_cpar = 1; } #else /* SVC mode with interrupts disabled. */ env->uncached_cpsr = ARM_CPU_MODE_SVC; env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F; /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is clear at reset. Initial SP and PC are loaded from ROM. */ if (IS_M(env)) { uint32_t pc; uint8_t *rom; env->daif &= ~PSTATE_I; rom = rom_ptr(0); if (rom) { /* We should really use ldl_phys here, in case the guest modified flash and reset itself. However images loaded via -kernel have not been copied yet, so load the values directly from there. */ env->regs[13] = ldl_p(rom) & 0xFFFFFFFC; pc = ldl_p(rom + 4); env->thumb = pc & 1; env->regs[15] = pc & ~1; } } if (env->cp15.c1_sys & SCTLR_V) { env->regs[15] = 0xFFFF0000; } env->vfp.xregs[ARM_VFP_FPEXC] = 0; #endif set_flush_to_zero(1, &env->vfp.standard_fp_status); set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->vfp.fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->vfp.standard_fp_status); tlb_flush(s, 1); /* Reset is a state change for some CPUARMState fields which we * bake assumptions about into translated code, so we need to * tb_flush(). */ tb_flush(env); #ifndef CONFIG_USER_ONLY if (kvm_enabled()) { kvm_arm_reset_vcpu(cpu); } #endif }
/* CPUClass::reset() */ static void arm_cpu_reset(CPUState *s) { ARMCPU *cpu = ARM_CPU(s); ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); CPUARMState *env = &cpu->env; acc->parent_reset(s); memset(env, 0, offsetof(CPUARMState, breakpoints)); g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; } #if defined(CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; /* For user mode we must enable access to coprocessors */ env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->cp15.c15_cpar = 3; } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { env->cp15.c15_cpar = 1; } #else /* SVC mode with interrupts disabled. */ env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is clear at reset. Initial SP and PC are loaded from ROM. */ if (IS_M(env)) { uint32_t pc; uint8_t *rom; env->uncached_cpsr &= ~CPSR_I; rom = rom_ptr(0); if (rom) { /* We should really use ldl_phys here, in case the guest modified flash and reset itself. However images loaded via -kernel have not been copied yet, so load the values directly from there. */ env->regs[13] = ldl_p(rom); pc = ldl_p(rom + 4); env->thumb = pc & 1; env->regs[15] = pc & ~1; } } env->vfp.xregs[ARM_VFP_FPEXC] = 0; #endif set_flush_to_zero(1, &env->vfp.standard_fp_status); set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->vfp.fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->vfp.standard_fp_status); tlb_flush(env, 1); /* Reset is a state change for some CPUARMState fields which we * bake assumptions about into translated code, so we need to * tb_flush(). */ tb_flush(env); }
int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap) { tb_flush(env); return 0; }
/* CPUClass::reset() */ static void arm_cpu_reset(CPUState *s) { ARMCPU *cpu = ARM_CPU(s); ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); CPUARMState *env = &cpu->env; acc->parent_reset(s); memset(env, 0, offsetof(CPUARMState, features)); g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; } if (arm_feature(env, ARM_FEATURE_AARCH64)) { /* 64 bit CPUs always start in 64 bit mode */ env->aarch64 = 1; #if defined(CONFIG_USER_ONLY) env->pstate = PSTATE_MODE_EL0t; /* Userspace expects access to CTL_EL0 and the cache ops */ env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI; /* and to the FP/Neon instructions */ env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3); #else env->pstate = PSTATE_MODE_EL1h; env->pc = cpu->rvbar; #endif } else { #if defined(CONFIG_USER_ONLY) /* Userspace expects access to cp10 and cp11 for FP/Neon */ env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 4, 0xf); #endif } #if defined(CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; /* For user mode we must enable access to coprocessors */ env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; if (arm_feature(env, ARM_FEATURE_IWMMXT)) { env->cp15.c15_cpar = 3; } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { env->cp15.c15_cpar = 1; } #else /* SVC mode with interrupts disabled. */ env->uncached_cpsr = ARM_CPU_MODE_SVC; env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F; /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is * clear at reset. Initial SP and PC are loaded from ROM. */ if (IS_M(env)) { uint32_t initial_msp; /* Loaded from 0x0 */ uint32_t initial_pc; /* Loaded from 0x4 */ uint8_t *rom; env->daif &= ~PSTATE_I; rom = rom_ptr(0); if (rom) { /* Address zero is covered by ROM which hasn't yet been * copied into physical memory. */ initial_msp = ldl_p(rom); initial_pc = ldl_p(rom + 4); } else { /* Address zero not covered by a ROM blob, or the ROM blob * is in non-modifiable memory and this is a second reset after * it got copied into memory. In the latter case, rom_ptr * will return a NULL pointer and we should use ldl_phys instead. */ initial_msp = ldl_phys(s->as, 0); initial_pc = ldl_phys(s->as, 4); } env->regs[13] = initial_msp & 0xFFFFFFFC; env->regs[15] = initial_pc & ~1; env->thumb = initial_pc & 1; } if (env->cp15.c1_sys & SCTLR_V) { env->regs[15] = 0xFFFF0000; } env->vfp.xregs[ARM_VFP_FPEXC] = 0; #endif set_flush_to_zero(1, &env->vfp.standard_fp_status); set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->vfp.fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->vfp.standard_fp_status); tlb_flush(s, 1); /* Reset is a state change for some CPUARMState fields which we * bake assumptions about into translated code, so we need to * tb_flush(). */ tb_flush(env); #ifndef CONFIG_USER_ONLY if (kvm_enabled()) { kvm_arm_reset_vcpu(cpu); } #endif hw_watchpoint_update_all(cpu); }
void tb_delete(struct trace_buffer_t* tb) { tb_flush(tb); if(!dr_unmap_file(tb, TRACE_BUFFER_SIZE)) { dr_fprintf(STDERR, "warning: dr_unmap_file() failed\n"); } }
void helper_tb_flush (void) { tb_flush(env); }
void SkyriseAnalyst::slot_onEntryExecution(S2EExecutionState *state, uint64_t pc) { assert(m_module.EntryPoint == pc); assert(!(b_targetModule_exec)); // Disconnect entry point signals regEntryHook.disconnect(); sig_EntryExec.disconnect(); // Set running flag b_targetModule_exec = true; // Parse PE import table of target module if (!(m_monitor->getImports(state, m_module, imports))) { std::cout << "[State " << std::dec << state->getID() << "] Error: Could not retrieve " << "imports from " << m_module.Name << '\n'; exit(1); } // Print APIs in import table print_imports(); // Register imported API hooks regImportHooks = s2e()->getCorePlugin()->onTranslateInstructionEnd.connect( sigc::mem_fun(*this, &SkyriseAnalyst::slot_registerImportHooks) ); std::cout << "[+] Starting program execution at address 0x" << std::hex << pc << std::endl << std::endl; /* State forking/switching * */ s2e()->getCorePlugin()->onStateFork.connect( sigc::mem_fun(*this, &SkyriseAnalyst::slot_onStateFork) ); s2e()->getCorePlugin()->onStateSwitch.connect( sigc::mem_fun(*this, &SkyriseAnalyst::slot_onStateSwitch) ); /* Attempt to force re-translation so we can hook * import functions. Surely adds less overhead than * instrumenting *every* instruction. */ tb_flush(env); throw CpuExitException(); }