X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fx86-arch.c;h=96d3bcd72e6f4ebefd46510977e15763ee37b16d;hb=0bca0cb1bf5ce5572ab5cd7ba59f87fed1f2edb0;hp=3c556c4fc64e888b6f7e6414d41b0effd044dbff;hpb=6d9ecc45cb21a1208deb8c4d128adc04aa289c9d;p=sbcl.git diff --git a/src/runtime/x86-arch.c b/src/runtime/x86-arch.c index 3c556c4..96d3bcd 100644 --- a/src/runtime/x86-arch.c +++ b/src/runtime/x86-arch.c @@ -9,10 +9,6 @@ * files for more information. */ -/* - * $Header$ - */ - #include #include "runtime.h" @@ -27,6 +23,7 @@ #include "interrupt.h" #include "interr.h" #include "breakpoint.h" +#include "monitor.h" #define BREAKPOINT_INST 0xcc /* INT3 */ @@ -71,7 +68,7 @@ void arch_skip_instruction(os_context_t *context) int vlen; int code; - FSHOW((stderr, "[arch_skip_inst at %x]\n", *os_context_pc_addr(context))); + FSHOW((stderr, "/[arch_skip_inst at %x]\n", *os_context_pc_addr(context))); /* Get and skip the Lisp interrupt code. */ code = *(char*)(*os_context_pc_addr(context))++; @@ -83,12 +80,12 @@ void arch_skip_instruction(os_context_t *context) vlen = *(char*)(*os_context_pc_addr(context))++; /* Skip Lisp error arg data bytes. */ while (vlen-- > 0) { - (char*)(*os_context_pc_addr(context))++; + ( (char*)(*os_context_pc_addr(context)) )++; } break; case trap_Breakpoint: /* not tested */ - case trap_FunctionEndBreakpoint: /* not tested */ + case trap_FunEndBreakpoint: /* not tested */ break; case trap_PendingInterrupt: @@ -102,7 +99,7 @@ void arch_skip_instruction(os_context_t *context) } FSHOW((stderr, - "[arch_skip_inst resuming at %x]\n", + "/[arch_skip_inst resuming at %x]\n", *os_context_pc_addr(context))); } @@ -148,15 +145,15 @@ arch_remove_breakpoint(void *pc, unsigned long orig_inst) /* When single stepping, single_stepping holds the original instruction * PC location. */ -unsigned int *single_stepping=NULL; -#ifndef __linux__ +unsigned int *single_stepping = NULL; +#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG unsigned int single_step_save1; unsigned int single_step_save2; unsigned int single_step_save3; #endif void -arch_do_displaced_inst(os_context_t *context, unsigned long orig_inst) +arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst) { unsigned int *pc = (unsigned int*)(*os_context_pc_addr(context)); @@ -164,9 +161,7 @@ arch_do_displaced_inst(os_context_t *context, unsigned long orig_inst) *((char *)pc) = orig_inst & 0xff; *((char *)pc + 1) = (orig_inst & 0xff00) >> 8; -#ifdef __linux__ - *context_eflags_addr(context) |= 0x100; -#else +#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG /* Install helper instructions for the single step: * pushf; or [esp],0x100; popf. */ single_step_save1 = *(pc-3); @@ -175,11 +170,13 @@ arch_do_displaced_inst(os_context_t *context, unsigned long orig_inst) *(pc-3) = 0x9c909090; *(pc-2) = 0x00240c81; *(pc-1) = 0x9d000001; +#else + *context_eflags_addr(context) |= 0x100; #endif single_stepping = (unsigned int*)pc; -#ifndef __linux__ +#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG *os_context_pc_addr(context) = (char *)pc - 9; #endif } @@ -195,7 +192,7 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) { /* fprintf(stderr,"* single step trap %x\n", single_stepping); */ -#ifndef __linux__ +#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; @@ -207,7 +204,6 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) if (*os_context_pc_addr(context) == (int)single_stepping + 1) { fprintf(stderr, "warning: couldn't reinstall breakpoint\n"); } else { - char *ptr = (char*)single_stepping; *((char *)single_stepping) = BREAKPOINT_INST; /* x86 INT3 */ *((char *)single_stepping+1) = trap_Breakpoint; } @@ -219,7 +215,7 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) /* This is just for info in case the monitor wants to print an * approximation. */ current_control_stack_pointer = - (lispobj*)*os_context_sp_addr(context); + (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 @@ -229,7 +225,7 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) switch (trap) { case trap_PendingInterrupt: - FSHOW((stderr, "\n")); + FSHOW((stderr, "/\n")); arch_skip_instruction(context); interrupt_handle_pending(context); break; @@ -240,7 +236,7 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) * seems to be no point in doing that, since we're just * going to lose(..) anyway. */ fake_foreign_function_call(context); - lose("%%primitive halt called; the party is over."); + lose("%%PRIMITIVE HALT called; the party is over."); case trap_Error: case trap_Cerror: @@ -253,25 +249,46 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) handle_breakpoint(signal, info, context); break; - case trap_FunctionEndBreakpoint: + case trap_FunEndBreakpoint: (char*)(*os_context_pc_addr(context)) -= 1; *os_context_pc_addr(context) = - (int)handle_function_end_breakpoint(signal, info, context); + (int)handle_fun_end_breakpoint(signal, info, context); break; default: - FSHOW((stderr,"[C--trap default %d %d %x]\n", + FSHOW((stderr,"/[C--trap default %d %d %x]\n", signal, code, context)); interrupt_handle_now(signal, info, context); break; } } +static void +sigill_handler(int signal, siginfo_t *siginfo, void *void_context) { + os_context_t *context = (os_context_t*)void_context; + fake_foreign_function_call(context); + monitor_or_something(); +} + void arch_install_interrupt_handlers() { - interrupt_install_low_level_handler(SIGILL , sigtrap_handler); - interrupt_install_low_level_handler(SIGTRAP, sigtrap_handler); + SHOW("entering arch_install_interrupt_handlers()"); + + /* Note: The old CMU CL code here used sigtrap_handler() to handle + * SIGILL as well as SIGTRAP. I couldn't see any reason to do + * things that way. So, I changed to separate handlers when + * debugging a problem on OpenBSD, where SBCL wasn't catching + * SIGILL properly, but was instead letting the process be + * terminated with an "Illegal instruction" output. If this change + * turns out to break something (maybe breakpoint handling on some + * OS I haven't tested on?) and we have to go back to the old CMU + * CL way, I hope there will at least be a comment to explain + * why.. -- WHN 2001-06-07 */ + undoably_install_low_level_interrupt_handler(SIGILL , sigill_handler); + undoably_install_low_level_interrupt_handler(SIGTRAP, sigtrap_handler); + + SHOW("returning from arch_install_interrupt_handlers()"); } /* This is implemented in assembly language and called from C: */ @@ -291,6 +308,7 @@ funcall0(lispobj function) { lispobj *args = NULL; + FSHOW((stderr, "/entering funcall0(0x%lx)\n", (long)function)); return call_into_lisp(function, args, 0); } lispobj