void arch_skip_instruction(os_context_t * context) { int vlen, code; DPRINTF(0, (stderr, "[arch_skip_inst at %lx>]\n", SC_PC(context))); /* Get and skip the lisp error code. */ code = *(char *) SC_PC(context)++; switch (code) { case trap_Error: case trap_Cerror: /* Lisp error arg vector length */ vlen = *(char *) SC_PC(context)++; /* Skip lisp error arg data bytes */ while (vlen-- > 0) SC_PC(context)++; break; case trap_Breakpoint: case trap_FunctionEndBreakpoint: break; case trap_PendingInterrupt: case trap_Halt: /* Only needed to skip the Code. */ break; default: fprintf(stderr, "[arch_skip_inst invalid code %d\n]\n", code); break; } DPRINTF(0, (stderr, "[arch_skip_inst resuming at %lx>]\n", SC_PC(context))); }
void arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst) { unsigned int *pc = (unsigned int *) SC_PC(context); /* * Put the original instruction back. */ *((char *) pc) = orig_inst & 0xff; *((char *) pc + 1) = (orig_inst & 0xff00) >> 8; #ifdef SC_EFLAGS /* Enable single-stepping */ SC_EFLAGS(context) |= 0x100; #else /* * Install helper instructions for the single step: * nop; nop; nop; pushf; or [esp],0x100; popf. * * The or instruction enables the trap flag which enables * single-stepping. So when the popf instruction is run, we start * single-stepping and stop on the next instruction. */ DPRINTF(0, (stderr, "Installing helper instructions\n")); single_step_save1 = *(pc - 3); single_step_save2 = *(pc - 2); single_step_save3 = *(pc - 1); *(pc - 3) = 0x9c909090; *(pc - 2) = 0x00240c81; *(pc - 1) = 0x9d000001; #endif single_stepping = (unsigned int *) pc; #ifndef SC_EFLAGS /* * pc - 9 points to the pushf instruction that we installed for * the helper. */ DPRINTF(0, (stderr, " Setting pc to pushf instruction at %p\n", (void*) ((char*) pc - 9))); SC_PC(context) = (int)((char *) pc - 9); #endif }
static void info_from_sigcontext(struct call_info *info, os_context_t * csp) { unsigned long pc; info->interrupted = 1; if (LowtagOf(SC_REG(csp, reg_CODE)) == type_FunctionPointer) { /* We tried to call a function, but crapped out before $CODE could be fixed up. Probably an undefined function. */ info->frame = (struct call_frame *) SC_REG(csp, reg_OCFP); info->lra = (lispobj) SC_REG(csp, reg_LRA); info->code = code_pointer(info->lra); pc = (unsigned long) PTR(info->lra); } else { info->frame = (struct call_frame *) SC_REG(csp, reg_CFP); info->code = code_pointer(SC_REG(csp, reg_CODE)); info->lra = NIL; pc = SC_PC(csp); } if (info->code != NULL) info->pc = pc - (unsigned long) info->code - #ifndef alpha (HEADER_LENGTH(info->code->header) * sizeof(lispobj)); #else (HEADER_LENGTH(((struct code *) info->code)->header) * sizeof(lispobj)); #endif else
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; } }
unsigned char * arch_internal_error_arguments(os_context_t * context) { return (unsigned char *) (SC_PC(context) + 1); }