void arch_handle_single_step_trap(os_context_t *context, int trap) { unsigned char register_offset = *((unsigned char *)(*os_context_pc_addr(context))+5); handle_single_step_trap(context, trap, register_offset); /* KLUDGE: arch_skip_instruction() only skips one instruction, and * there is a following word to deal with as well, so skip * twice. */ arch_skip_instruction(context); arch_skip_instruction(context); }
int handle_smc(struct trap_context *ctx) { unsigned long *regs = ctx->regs; switch (SMCCC_GET_OWNER(regs[0])) { case ARM_SMCCC_OWNER_ARCH: regs[0] = handle_arch(ctx); break; case ARM_SMCCC_OWNER_SIP: regs[0] = ARM_SMCCC_NOT_SUPPORTED; break; case ARM_SMCCC_OWNER_STANDARD: regs[0] = psci_dispatch(ctx); break; default: return TRAP_UNHANDLED; } arch_skip_instruction(ctx); return TRAP_HANDLED; }
static void sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context) { unsigned int code = *((unsigned char *)(4+*os_context_pc_addr(context))); u32 trap_instruction = *((u32 *)*os_context_pc_addr(context)); int condition_bits = (trap_instruction >> 28) & 0x0f; /* Make sure that we're looking at an SWI instruction or that one * undefined instruction that the kernel recognizes as an explicit * trap. */ if ((condition_bits == 15) || (((trap_instruction & 0x0f000000) != 0x0f000000) && (trap_instruction != 0xe7f001f0))) { lose("Unrecognized trap instruction %08lx in sigtrap_handler()", trap_instruction); } if (trap_instruction == 0xe7f001f0) { handle_trap(context, code); } else { arch_clear_pseudo_atomic_interrupted(context); arch_skip_instruction(context); interrupt_handle_pending(context); } }
void arch_handle_single_step_trap(os_context_t *context, int trap) { arch_skip_instruction(context); /* On x86-64 the fdefn / function is always in RAX, so we pass * 0 as the register_offset. */ handle_single_step_trap(context, trap, 0); }
static void sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context) { unsigned int code = *((unsigned char *)(4+*os_context_pc_addr(context))); u32 trap_instruction = *((u32 *)*os_context_pc_addr(context)); if (trap_instruction != 0xe7f001f0) { lose("Unrecognized trap instruction %08lx in sigtrap_handler()", trap_instruction); } if (code == trap_PendingInterrupt) { arch_skip_instruction(context); } handle_trap(context, code); }
void sigtrap_handler(HANDLER_ARGS) { unsigned int trap; os_context_t* os_context = (os_context_t *) context; #if 0 fprintf(stderr, "x86sigtrap: %8x %x\n", SC_PC(os_os_context), *(unsigned char *) (SC_PC(os_context) - 1)); fprintf(stderr, "sigtrap(%d %d %x)\n", signal, CODE(code), os_context); #endif if (single_stepping && (signal == SIGTRAP)) { #if 0 fprintf(stderr, "* Single step trap %p\n", single_stepping); #endif #ifdef SC_EFLAGS /* Disable single-stepping */ SC_EFLAGS(os_context) ^= 0x100; #else /* Un-install single step helper instructions. */ *(single_stepping - 3) = single_step_save1; *(single_stepping - 2) = single_step_save2; *(single_stepping - 1) = single_step_save3; DPRINTF(0, (stderr, "Uninstalling helper instructions\n")); #endif /* * Re-install the breakpoint if possible. */ if ((int) SC_PC(os_context) == (int) single_stepping + 1) fprintf(stderr, "* Breakpoint not re-install\n"); else { char *ptr = (char *) single_stepping; ptr[0] = BREAKPOINT_INST; /* x86 INT3 */ ptr[1] = trap_Breakpoint; } single_stepping = NULL; return; } /* This is just for info in case monitor wants to print an approx */ current_control_stack_pointer = (unsigned long *) SC_SP(os_context); RESTORE_FPU(os_context); /* * On entry %eip points just after the INT3 byte and aims at the * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *) SC_PC(os_context); switch (trap) { case trap_PendingInterrupt: DPRINTF(0, (stderr, "<trap Pending Interrupt.>\n")); arch_skip_instruction(os_context); interrupt_handle_pending(os_context); break; case trap_Halt: { FPU_STATE(fpu_state); save_fpu_state(fpu_state); fake_foreign_function_call(os_context); lose("%%primitive halt called; the party is over.\n"); undo_fake_foreign_function_call(os_context); restore_fpu_state(fpu_state); arch_skip_instruction(os_context); break; } case trap_Error: case trap_Cerror: DPRINTF(0, (stderr, "<trap Error %x>\n", CODE(code))); interrupt_internal_error(signal, code, os_context, CODE(code) == trap_Cerror); break; case trap_Breakpoint: #if 0 fprintf(stderr, "*C break\n"); #endif SC_PC(os_context) -= 1; handle_breakpoint(signal, CODE(code), os_context); #if 0 fprintf(stderr, "*C break return\n"); #endif break; case trap_FunctionEndBreakpoint: SC_PC(os_context) -= 1; SC_PC(os_context) = (int) handle_function_end_breakpoint(signal, CODE(code), os_context); break; #ifdef trap_DynamicSpaceOverflowWarning case trap_DynamicSpaceOverflowWarning: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_WARNING_HIT), os_context); break; #endif #ifdef trap_DynamicSpaceOverflowError case trap_DynamicSpaceOverflowError: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_ERROR_HIT), os_context); break; #endif default: DPRINTF(0, (stderr, "[C--trap default %d %d %p]\n", signal, CODE(code), os_context)); interrupt_handle_now(signal, code, os_context); break; } }
void sigtrap_handler(HANDLER_ARGS) { unsigned int trap; #ifdef __linux__ GET_CONTEXT #endif #if 0 fprintf(stderr, "x86sigtrap: %8x %x\n", context->sc_pc, *(unsigned char *) (context->sc_pc - 1)); fprintf(stderr, "sigtrap(%d %d %x)\n", signal, code, context); #endif if (single_stepping && (signal == SIGTRAP)) { #if 0 fprintf(stderr, "* Single step trap %x\n", single_stepping); #endif #ifndef __linux__ /* Un-install single step helper instructions. */ *(single_stepping - 3) = single_step_save1; *(single_stepping - 2) = single_step_save2; *(single_stepping - 1) = single_step_save3; #else context->eflags ^= 0x100; #endif /* * Re-install the breakpoint if possible. */ if ((int) context->sc_pc == (int) single_stepping + 1) fprintf(stderr, "* Breakpoint not re-install\n"); else { char *ptr = (char *) single_stepping; ptr[0] = BREAKPOINT_INST; /* x86 INT3 */ ptr[1] = trap_Breakpoint; } single_stepping = NULL; return; } /* This is just for info in case monitor wants to print an approx */ current_control_stack_pointer = (unsigned long *) context->sc_sp; #if defined(__linux__) && (defined(i386) || defined(__x86_64)) /* * Restore the FPU control word, setting the rounding mode to nearest. */ if (contextstruct.fpstate) #if defined(__x86_64) setfpucw(contextstruct.fpstate->cwd & ~0xc00); #else setfpucw(contextstruct.fpstate->cw & ~0xc00); #endif #endif /* * On entry %eip points just after the INT3 byte and aims at the * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *) (context->sc_pc); switch (trap) { case trap_PendingInterrupt: DPRINTF(0, (stderr, "<trap Pending Interrupt.>\n")); arch_skip_instruction(context); interrupt_handle_pending(context); break; case trap_Halt: { #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) int fpu_state[27]; fpu_save(fpu_state); #endif fake_foreign_function_call(context); lose("%%primitive halt called; the party is over.\n"); undo_fake_foreign_function_call(context); #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) fpu_restore(fpu_state); #endif arch_skip_instruction(context); break; } case trap_Error: case trap_Cerror: DPRINTF(0, (stderr, "<trap Error %d>\n", code)); #ifdef __linux__ interrupt_internal_error(signal, contextstruct, code == trap_Cerror); #else interrupt_internal_error(signal, code, context, code == trap_Cerror); #endif break; case trap_Breakpoint: #if 0 fprintf(stderr, "*C break\n"); #endif (char *) context->sc_pc -= 1; handle_breakpoint(signal, code, context); #if 0 fprintf(stderr, "*C break return\n"); #endif break; case trap_FunctionEndBreakpoint: (char *) context->sc_pc -= 1; context->sc_pc = (int) handle_function_end_breakpoint(signal, code, context); break; #ifdef DYNAMIC_SPACE_OVERFLOW_WARNING_HIT case trap_DynamicSpaceOverflowWarning: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_WARNING_HIT), context); break; #endif #ifdef DYNAMIC_SPACE_OVERFLOW_ERROR_HIT case trap_DynamicSpaceOverflowError: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_ERROR_HIT), context); break; #endif default: DPRINTF(0, (stderr, "[C--trap default %d %d %x]\n", signal, code, context)); #ifdef __linux__ interrupt_handle_now(signal, contextstruct); #else interrupt_handle_now(signal, code, context); #endif break; } }