void arch_handle_fun_end_breakpoint(os_context_t *context) { *os_context_pc_addr(context) -= BREAKPOINT_WIDTH; *os_context_pc_addr(context) = (uword_t)handle_fun_end_breakpoint(context); }
void restore_breakpoint_from_single_step(os_context_t * context) { /* fprintf(stderr,"* single step trap %x\n", single_stepping); */ #ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG /* 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_addr(context) &= ~0x100; #endif /* Re-install the breakpoint if possible. */ if (((char *)*os_context_pc_addr(context) > (char *)single_stepping) && ((char *)*os_context_pc_addr(context) <= (char *)single_stepping + BREAKPOINT_WIDTH)) { fprintf(stderr, "warning: couldn't reinstall breakpoint\n"); } else { arch_install_breakpoint(single_stepping); } single_stepping = NULL; return; }
static long compute_offset(os_context_t *context, lispobj code) { if (code == NIL) return 0; else { uword_t code_start; struct code *codeptr = (struct code *)native_pointer(code); #ifdef LISP_FEATURE_HPPA uword_t pc = *os_context_pc_addr(context) & ~3; #else uword_t pc = *os_context_pc_addr(context); #endif code_start = (uword_t)codeptr + HeaderValue(codeptr->header)*sizeof(lispobj); if (pc < code_start) return 0; else { uword_t offset = pc - code_start; if (offset >= (uword_t)fixnum_value(codeptr->code_size)) return 0; else return make_fixnum(offset); } } }
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_do_displaced_inst(os_context_t *context, unsigned int orig_inst) { unsigned int *pc = (unsigned int*)(*os_context_pc_addr(context)); /* Put the original instruction back. */ arch_remove_breakpoint(pc, orig_inst); #ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG /* Install helper instructions for the single step: * pushf; or [esp],0x100; popf. */ single_step_save1 = *(pc-3); single_step_save2 = *(pc-2); single_step_save3 = *(pc-1); *(pc-3) = 0x9c909090; *(pc-2) = 0x00240c81; *(pc-1) = 0x9d000001; #else *context_eflags_addr(context) |= 0x100; #endif single_stepping = pc; #ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG *os_context_pc_addr(context) = (os_context_register_t)((char *)pc - 9); #endif }
void arch_skip_instruction(os_context_t *context) { /* Assuming we get here via an INT3 xxx instruction, the PC now * points to the interrupt code (a Lisp value) so we just move * past it. Skip the code; after that, if the code is an * error-trap or cerror-trap then skip the data bytes that follow. */ int vlen; long code; /* Get and skip the Lisp interrupt code. */ code = *(char*)(*os_context_pc_addr(context))++; switch (code) { case trap_Error: case trap_Cerror: /* Lisp error arg vector length */ vlen = *(char*)(*os_context_pc_addr(context))++; /* Skip Lisp error arg data bytes. */ while (vlen-- > 0) { ++*os_context_pc_addr(context); } break; case trap_Breakpoint: /* not tested */ case trap_FunEndBreakpoint: /* not tested */ break; #ifdef LISP_FEATURE_SB_SAFEPOINT case trap_GlobalSafepoint: case trap_CspSafepoint: #endif case trap_PendingInterrupt: case trap_Halt: case trap_SingleStepAround: case trap_SingleStepBefore: case trap_InvalidArgCount: /* only needed to skip the Code */ break; default: fprintf(stderr,"[arch_skip_inst invalid code %ld\n]\n",code); break; } FSHOW((stderr, "/[arch_skip_inst resuming at %x]\n", *os_context_pc_addr(context))); }
void sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context) { /* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so * we need to use illegal instructions for traps. */ #if defined(LISP_FEATURE_UD2_BREAKPOINTS) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER) if (*((unsigned short *)*os_context_pc_addr(context)) == UD2_INST) { *os_context_pc_addr(context) += 2; return sigtrap_handler(signal, siginfo, context); } #endif fake_foreign_function_call(context); lose("Unhandled SIGILL"); }
void sigtrap_handler(int signal, siginfo_t *info, os_context_t *context) { unsigned int trap; if (single_stepping) { restore_breakpoint_from_single_step(context); return; } /* This is just for info in case the monitor wants to print an * approximation. */ current_control_stack_pointer = (lispobj *)*os_context_sp_addr(context); #ifdef LISP_FEATURE_SUNOS /* For some reason the breakpoints that :ENCAPSULATE NIL tracing sets up * cause a trace trap (i.e. processor single-stepping trap) on the following * instruction on Solaris 10/x86. -- JES, 2006-04-07 */ if (info->si_code == TRAP_TRACE) { lose("foo"); return; } #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 *)(*os_context_pc_addr(context)); handle_trap(context, trap); }
static void call_info_from_context(struct call_info *info, os_context_t *context) { unsigned long pc; info->interrupted = 1; if (lowtag_of(*os_context_register_addr(context, reg_CODE)) == FUN_POINTER_LOWTAG) { /* We tried to call a function, but crapped out before $CODE could * be fixed up. Probably an undefined function. */ info->frame = (struct call_frame *)(unsigned long) (*os_context_register_addr(context, reg_OCFP)); info->lra = (lispobj)(*os_context_register_addr(context, reg_LRA)); info->code = code_pointer(info->lra); pc = (unsigned long)native_pointer(info->lra); } else { info->frame = (struct call_frame *)(unsigned long) (*os_context_register_addr(context, reg_CFP)); info->code = code_pointer(*os_context_register_addr(context, reg_CODE)); info->lra = NIL; pc = *os_context_pc_addr(context); } if (info->code != NULL) info->pc = pc - (unsigned long) info->code - #ifndef LISP_FEATURE_ALPHA (HEADER_LENGTH(info->code->header) * sizeof(lispobj)); #else (HEADER_LENGTH(((struct code *)info->code)->header) * sizeof(lispobj)); #endif else
static lispobj find_code(os_context_t *context) { #ifdef reg_CODE lispobj code = *os_context_register_addr(context, reg_CODE); lispobj header; if (lowtag_of(code) != OTHER_POINTER_LOWTAG) return NIL; header = *(lispobj *)(code-OTHER_POINTER_LOWTAG); if (widetag_of(header) == CODE_HEADER_WIDETAG) return code; else return code - HeaderValue(header)*sizeof(lispobj); #else lispobj codeptr = (lispobj)component_ptr_from_pc((lispobj *)(*os_context_pc_addr(context))); if (codeptr == 0) return NIL; else return codeptr + OTHER_POINTER_LOWTAG; #endif }
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 arch_skip_instruction(os_context_t *context) { /* KLUDGE: Other platforms check for trap codes and skip inlined * trap/error parameters. We should too. */ /* Note that we're doing integer arithmetic here, not pointer. So * the value that the return value of os_context_pc_addr() points * to will be incremented by 4, not 16. */ *os_context_pc_addr(context) += 4; }
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); }
static void print_context(os_context_t *context) { int i; for (i = 0; i < NREGS; i++) { printf("%s:\t", lisp_register_names[i]); #ifdef LISP_FEATURE_X86 brief_print((lispobj)(*os_context_register_addr(context, i*2))); #else brief_print((lispobj)(*os_context_register_addr(context,i))); #endif } #ifdef LISP_FEATURE_DARWIN printf("DAR:\t\t 0x%08lx\n", (unsigned long)(*os_context_register_addr(context, 41))); printf("DSISR:\t\t 0x%08lx\n", (unsigned long)(*os_context_register_addr(context, 42))); #endif printf("PC:\t\t 0x%08lx\n", (unsigned long)(*os_context_pc_addr(context))); }
void sigtrap_handler(int signal, siginfo_t *info, os_context_t *context) { unsigned int trap; if (single_stepping) { restore_breakpoint_from_single_step(context); return; } /* This is just for info in case the monitor wants to print an * approximation. */ access_control_stack_pointer(arch_os_get_current_thread()) = (lispobj *)*os_context_sp_addr(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 *)(*os_context_pc_addr(context)); handle_trap(context, trap); }
void arch_handle_fun_end_breakpoint(os_context_t *context) { *os_context_pc_addr(context) = (int) handle_fun_end_breakpoint(context); }
/* SIGINT handler that invokes the monitor (for when Lisp isn't up to it) */ static void sigint_handler(int signal, siginfo_t *info, os_context_t *context) { lose("\nSIGINT hit at 0x%08lX\n", (unsigned long) *os_context_pc_addr(context)); }
void arch_handle_breakpoint(os_context_t *context) { *os_context_pc_addr(context) -= BREAKPOINT_WIDTH; handle_breakpoint(context); }
unsigned char * arch_internal_error_arguments(os_context_t *context) { return 1 + (unsigned char *)(*os_context_pc_addr(context)); }