From 6c605fa4b46d3fee9304c4e40e0e605aa5a24f28 Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Sun, 1 Apr 2007 19:36:16 +0000 Subject: [PATCH] 1.0.4.13: refactor trap handling * All architectures had an essentially identical switch(trap){...} for different trap codes. Pull this into a single shared handle_trap function, which dispatches to architecture specific functions where necessary. * Remove unnecessary signal and siginfo arguments from breakpoint handling functions and interrupt_internal_error as a tentative step towards admitting that POSIX is not the only world out there. * Clean up some compiler warnings from the runtime, and a missing anti-copyright header. * Fix the PPC build... at least on G4 Darwin 10.3: no suseconds_t here. Tested on x86, x86-64, and PPC. Sparc, MIPS (and Alpha) testing needed. --- contrib/sb-posix/constants.lisp | 4 +- src/runtime/alpha-arch.c | 47 ++++++----------- src/runtime/arch.h | 9 ++++ src/runtime/breakpoint.c | 5 +- src/runtime/breakpoint.h | 6 +-- src/runtime/hppa-arch.c | 66 ++++++++--------------- src/runtime/interrupt.c | 52 ++++++++++++++++-- src/runtime/interrupt.h | 9 +++- src/runtime/mips-arch.c | 68 ++++++++++-------------- src/runtime/ppc-arch.c | 108 ++++++++++++++++++-------------------- src/runtime/print.c | 7 ++- src/runtime/sparc-arch.c | 68 ++++++++++-------------- src/runtime/x86-64-arch.c | 72 +++++++++---------------- src/runtime/x86-arch.c | 74 +++++++++----------------- src/runtime/x86-bsd-os.c | 20 +++---- tools-for-build/grovel-headers.c | 7 +++ version.lisp-expr | 2 +- 17 files changed, 293 insertions(+), 331 deletions(-) diff --git a/contrib/sb-posix/constants.lisp b/contrib/sb-posix/constants.lisp index f1d25ba..efecc18 100644 --- a/contrib/sb-posix/constants.lisp +++ b/contrib/sb-posix/constants.lisp @@ -383,7 +383,9 @@ ;; utime(), utimes() #-win32 - (:type suseconds-t "suseconds_t") + (:type suseconds-t ; OAOOM warning: similar kludge in tools-for-build + #-(and darwin ppc) "suseconds_t" + #+(and darwin ppc) "int") #-win32 (:structure alien-utimbuf diff --git a/src/runtime/alpha-arch.c b/src/runtime/alpha-arch.c index 96f7f2c..827080f 100644 --- a/src/runtime/alpha-arch.c +++ b/src/runtime/alpha-arch.c @@ -277,6 +277,21 @@ void arch_do_displaced_inst(os_context_t *context,unsigned int orig_inst) os_flush_icache((os_vm_address_t)next_pc, sizeof(unsigned int)); } +void +arch_handle_breakpoint(os_context_t *context) +{ + *os_context_pc_addr(context) -=4; + handle_breakpoint(context); +} + +void +arch_handle_fun_end_breakpoint(os_context_t *context) +{ + *os_context_pc_addr(context) -=4; + *os_context_pc_addr(context) = + (int)handle_fun_end_breakpoint(context); +} + static void sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context) { @@ -313,38 +328,8 @@ sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context) } else /* a "system service" */ code=*((u32 *)(*os_context_pc_addr(context))); - - switch (code) { - case trap_PendingInterrupt: - arch_skip_instruction(context); - interrupt_handle_pending(context); - break; - - case trap_Halt: - fake_foreign_function_call(context); - lose("%%primitive halt called; the party is over.\n"); - - case trap_Error: - case trap_Cerror: - interrupt_internal_error(signal, siginfo, context, code==trap_Cerror); - break; - - case trap_Breakpoint: /* call lisp-level handler */ - *os_context_pc_addr(context) -=4; - handle_breakpoint(signal, siginfo, context); - break; - - case trap_FunEndBreakpoint: - *os_context_pc_addr(context) -=4; - *os_context_pc_addr(context) = - (int)handle_fun_end_breakpoint(signal, siginfo, context); - break; - - default: - fprintf(stderr, "unidentified breakpoint/trap %d\n",code); + if (!maybe_handle_trap(context, code)) interrupt_handle_now(signal, siginfo, context); - break; - } } unsigned long diff --git a/src/runtime/arch.h b/src/runtime/arch.h index 4a7bc1b..f50e0d4 100644 --- a/src/runtime/arch.h +++ b/src/runtime/arch.h @@ -51,4 +51,13 @@ extern unsigned int * single_stepping; extern void restore_breakpoint_from_single_step(os_context_t * context); #endif +extern void arch_handle_breakpoint(os_context_t* context); +extern void arch_handle_fun_end_breakpoint(os_context_t *context); +#ifdef trap_AfterBreakpoint +extern void arch_handle_after_breakpoint(os_context_t *context); +#endif +#ifdef trap_SingleStepAround +extern void arch_handle_single_step_trap(os_context_t *context, int trap); +#endif + #endif /* __ARCH_H__ */ diff --git a/src/runtime/breakpoint.c b/src/runtime/breakpoint.c index 5bbc108..7892dc1 100644 --- a/src/runtime/breakpoint.c +++ b/src/runtime/breakpoint.c @@ -124,7 +124,7 @@ static long compute_offset(os_context_t *context, lispobj code) } } -void handle_breakpoint(int signal, siginfo_t* info, os_context_t *context) +void handle_breakpoint(os_context_t *context) { lispobj code, context_sap; @@ -147,8 +147,7 @@ void handle_breakpoint(int signal, siginfo_t* info, os_context_t *context) undo_fake_foreign_function_call(context); } -void *handle_fun_end_breakpoint(int signal, siginfo_t *info, - os_context_t *context) +void *handle_fun_end_breakpoint(os_context_t *context) { lispobj code, context_sap, lra; struct code *codeptr; diff --git a/src/runtime/breakpoint.h b/src/runtime/breakpoint.h index 8647aef..76317a5 100644 --- a/src/runtime/breakpoint.h +++ b/src/runtime/breakpoint.h @@ -18,10 +18,8 @@ extern void breakpoint_remove(lispobj code_obj, unsigned int orig_inst); extern void breakpoint_do_displaced_inst(os_context_t *context, unsigned int orig_inst); -extern void handle_breakpoint(int signal, siginfo_t *info, - os_context_t *context); -extern void *handle_fun_end_breakpoint(int signal, siginfo_t *info, - os_context_t *context); +extern void handle_breakpoint(os_context_t *context); +extern void *handle_fun_end_breakpoint(os_context_t *context); extern void handle_single_step_trap (os_context_t *context, int kind, int register_offset); diff --git a/src/runtime/hppa-arch.c b/src/runtime/hppa-arch.c index 8fba416..0624da6 100644 --- a/src/runtime/hppa-arch.c +++ b/src/runtime/hppa-arch.c @@ -181,7 +181,26 @@ static void restore_breakpoint(struct sigcontext *scp) } #endif -static void sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context) +void +arch_handle_breakpoint(os_context_t *context) +{ + /*sigsetmask(scp->sc_mask); */ + handle_breakpoint(context); +} + +void +arch_handle_fun_end_breakpoint(os_context_t *context) +{ + /*sigsetmask(scp->sc_mask); */ + unsigned long pc; + pc = (unsigned long) + handle_fun_end_breakpoint(context); + *os_context_pc_addr(context) = pc; + *os_context_npc_addr(context) = pc + 4; +} + +static void +sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context) { os_context_t *context = arch_os_get_context(&void_context); unsigned int bad_inst; @@ -196,49 +215,8 @@ static void sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context) interrupt_handle_now(signal, siginfo, context); else { int im5 = bad_inst & 0x1f; - - switch (im5) { - case trap_Halt: - fake_foreign_function_call(context); - lose("%%primitive halt called; the party is over.\n"); - - case trap_PendingInterrupt: - arch_skip_instruction(context); - interrupt_handle_pending(context); - break; - - case trap_Error: - case trap_Cerror: - interrupt_internal_error(signal, siginfo, context, im5==trap_Cerror); - break; - - case trap_Breakpoint: - /*sigsetmask(scp->sc_mask); */ - handle_breakpoint(signal, siginfo, context); - break; - - case trap_FunEndBreakpoint: - /*sigsetmask(scp->sc_mask); */ - { - unsigned long pc; - pc = (unsigned long) - handle_fun_end_breakpoint(signal, siginfo, context); - *os_context_pc_addr(context) = pc; - *os_context_npc_addr(context) = pc + 4; - } - break; - - case trap_SingleStepBreakpoint: - /* Uh, FIXME */ -#ifdef hpux - restore_breakpoint(context); -#endif - break; - - default: - interrupt_handle_now(signal, siginfo, context); - break; - } + if (!maybe_handle_trap(context, trap)) + interrupt_handle_now(signal, sigingo, context); } } diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index eb1e834..69e890d 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -67,8 +67,6 @@ #include "genesis/simple-fun.h" #include "genesis/cons.h" - - static void run_deferred_handler(struct interrupt_data *data, void *v_context); #ifndef LISP_FEATURE_WIN32 static void store_signal_data_for_later (struct interrupt_data *data, @@ -368,8 +366,7 @@ undo_fake_foreign_function_call(os_context_t *context) /* a handler for the signal caused by execution of a trap opcode * signalling an internal error */ void -interrupt_internal_error(int signal, siginfo_t *info, os_context_t *context, - boolean continuable) +interrupt_internal_error(os_context_t *context, boolean continuable) { lispobj context_sap; @@ -1432,3 +1429,50 @@ lisp_memory_fault_error(os_context_t *context, os_vm_address_t addr) arrange_return_to_lisp_function(context, SymbolFunction(MEMORY_FAULT_ERROR)); } #endif + +/* Common logic far trapping instructions. How we actually handle each + * case is highly architecture dependant, but the overall shape is + * this. */ +boolean +maybe_handle_trap(os_context_t *context, int trap) +{ + switch(trap) { + case trap_PendingInterrupt: + FSHOW((stderr, "/\n")); + arch_skip_instruction(context); + interrupt_handle_pending(context); + break; + case trap_Error: + case trap_Cerror: + FSHOW((stderr, "/\n", trap)); + interrupt_internal_error(context, trap==trap_Cerror); + break; + case trap_Breakpoint: + arch_handle_breakpoint(context); + break; + case trap_FunEndBreakpoint: + arch_handle_fun_end_breakpoint(context); + break; +#ifdef trap_AfterBreakpoint + case trap_AfterBreakpoint: + arch_handle_after_breakpoint(context); + break; +#endif +#ifdef trap_SingleStepAround + case trap_SingleStepAround: + case trap_SingleStepBefore: + arch_handle_single_step_trap(context, trap); + break; +#endif + case trap_Halt: + fake_foreign_function_call(context); + lose("%%PRIMITIVE HALT called; the party is over.\n"); + default: + FSHOW((stderr,"/[C--trap default %d %d %x]\n", + signal, trap, context)); + /* Not our trap! */ + return 0; + } + return 1; +} + diff --git a/src/runtime/interrupt.h b/src/runtime/interrupt.h index 7213c0c..ee13671 100644 --- a/src/runtime/interrupt.h +++ b/src/runtime/interrupt.h @@ -66,8 +66,7 @@ extern void undo_fake_foreign_function_call(os_context_t* context); extern void arrange_return_to_lisp_function(os_context_t *, lispobj); extern void interrupt_handle_now(int, siginfo_t*, void*); extern void interrupt_handle_pending(os_context_t*); -extern void interrupt_internal_error(int, siginfo_t*, os_context_t*, - boolean continuable); +extern void interrupt_internal_error(os_context_t*, boolean continuable); extern boolean handle_guard_page_triggered(os_context_t *,os_vm_address_t); extern boolean interrupt_maybe_gc(int, siginfo_t*, void*); extern boolean interrupt_maybe_gc_int(int, siginfo_t *, void *); @@ -107,4 +106,10 @@ extern void block_blockable_signals(); * "cleanly" with union types is in fact a mess. */ #define ARE_SAME_HANDLER(x, y) ((void*)(x) == (void*)(y)) +extern boolean maybe_handle_trap(os_context_t *context, int trap); + +#ifndef LISP_FEATURE_WIN32 +extern void lisp_memory_fault_error(os_context_t *context, os_vm_address_t addr); +#endif + #endif diff --git a/src/runtime/mips-arch.c b/src/runtime/mips-arch.c index d63a380..0ecc8fa 100644 --- a/src/runtime/mips-arch.c +++ b/src/runtime/mips-arch.c @@ -363,54 +363,42 @@ arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst) displaced_after_inst = arch_install_after_breakpoint(next_pc); } +void +arch_handle_breakpoint(os_context_t *context) +{ + handle_breakpoint(context); +} + +void +arch_handle_fun_end_breakpoint(os_context_t *context) +{ + *os_context_pc_addr(context) + = (os_context_register_t)(unsigned int) + handle_fun_end_breakpoint(context); +} + +void +arch_handle_after_breakpoint(os_context_t *context) +{ + arch_install_breakpoint(skipped_break_addr); + arch_remove_breakpoint((unsigned int *)os_context_pc(context), + displaced_after_inst); + *os_context_sigmask_addr(context) = orig_sigmask; +} + static void sigtrap_handler(int signal, siginfo_t *info, void *void_context) { os_context_t *context = arch_os_get_context(&void_context); unsigned int code = (os_context_insn(context) >> 6) & 0xfffff; - - switch (code) { - case trap_Halt: - fake_foreign_function_call(context); - lose("%%primitive halt called; the party is over.\n"); - - case trap_PendingInterrupt: - arch_skip_instruction(context); - interrupt_handle_pending(context); - break; - - case trap_Error: - case trap_Cerror: - interrupt_internal_error(signal, info, context, code == trap_Cerror); - break; - - case trap_Breakpoint: - handle_breakpoint(signal, info, context); - break; - - case trap_FunEndBreakpoint: - *os_context_pc_addr(context) - = (os_context_register_t)(unsigned int) - handle_fun_end_breakpoint(signal, info, context); - break; - - case trap_AfterBreakpoint: - arch_install_breakpoint(skipped_break_addr); - arch_remove_breakpoint((unsigned int *)os_context_pc(context), - displaced_after_inst); - *os_context_sigmask_addr(context) = orig_sigmask; - break; - - case 0x10: + /* FIXME: WTF is this magic number? Needs to become a #define + * and go into maybe_handle_trap. */ + if (code==0x10) { arch_clear_pseudo_atomic_interrupted(context); arch_skip_instruction(context); interrupt_handle_pending(context); - return; - - default: - interrupt_handle_now(signal, info, context); - break; - } + } else if (!maybe_handle_trap(context,code)) + interrupt_handle_now(signal, info, void_context); } #define FIXNUM_VALUE(lispobj) (((int)lispobj) >> N_FIXNUM_TAG_BITS) diff --git a/src/runtime/ppc-arch.c b/src/runtime/ppc-arch.c index ac6b3d9..35dc843 100644 --- a/src/runtime/ppc-arch.c +++ b/src/runtime/ppc-arch.c @@ -1,3 +1,14 @@ +/* + * This software is part of the SBCL system. See the README file for + * more information. + * + * This software is derived from the CMU CL system, which was + * written at Carnegie Mellon University and released into the + * public domain. The software is in the public domain and is + * provided with absolutely no warranty. See the COPYING and CREDITS + * files for more information. + */ + #include #include "sbcl.h" @@ -9,6 +20,7 @@ #include "signal.h" #include "interrupt.h" #include "interr.h" +#include "breakpoint.h" #if defined(LISP_FEATURE_GENCGC) #include "gencgc-alloc-region.h" @@ -43,7 +55,6 @@ void arch_init() { os_vm_address_t arch_get_bad_addr(int sig, siginfo_t *code, os_context_t *context) { - unsigned long pc = (unsigned long)(*os_context_pc_addr(context)); os_vm_address_t addr; #if defined(LISP_FEATURE_NETBSD) @@ -207,14 +218,11 @@ handle_allocation_trap(os_context_t * context) { unsigned int *pc; unsigned int inst; - unsigned int or_inst; unsigned int target, target_ptr, end_addr; unsigned int opcode; int size; - int immed; boolean were_in_lisp; char *memory; - sigset_t block; target = 0; size = 0; @@ -366,6 +374,42 @@ handle_allocation_trap(os_context_t * context) } #endif +void +arch_handle_breakpoint(os_context_t *context) +{ + handle_breakpoint(context); +} + +void +arch_handle_fun_end_breakpoint(os_context_t *context) +{ + *os_context_pc_addr(context) + =(int)handle_fun_end_breakpoint(context); +} + +/* FIXME: AFTER-BREAKPOINT-TRAP is defined for PPC, but never + * emitted as far as I can see. Should it be emitted, do removed + * entirely? */ +void +arch_handle_after_breakpoint(os_context_t *context) +{ + *skipped_break_addr = trap_Breakpoint; + skipped_break_addr = NULL; + *(unsigned int *)*os_context_pc_addr(context) + = displaced_after_inst; + *os_context_sigmask_addr(context)= orig_sigmask; + os_flush_icache((os_vm_address_t) *os_context_pc_addr(context), + sizeof(unsigned int)); +} + +void +arch_handle_single_step_trap(os_context_t *context, int trap) +{ + unsigned int code = *((u32 *)(*os_context_pc_addr(context))); + int register_offset = code >> 5 & 0x1f; + handle_single_step_trap(context, trap, register_offset); + arch_skip_instruction(context); +} static void sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context) @@ -401,64 +445,16 @@ sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context) /* twllei reg_ZERO,N will always trap if reg_ZERO = 0 */ int trap = code & 0x1f; - switch (trap) { - case trap_Halt: - fake_foreign_function_call(context); - lose("%%primitive halt called; the party is over.\n"); - - case trap_Error: - case trap_Cerror: - interrupt_internal_error(signal, code, context, trap == trap_Cerror); - break; - - case trap_PendingInterrupt: - /* This is supposed run after WITHOUT-INTERRUPTS if there - * were pending signals. */ - arch_skip_instruction(context); - interrupt_handle_pending(context); - break; - - case trap_Breakpoint: - handle_breakpoint(signal, code, context); - break; - - case trap_FunEndBreakpoint: - *os_context_pc_addr(context) - =(int)handle_fun_end_breakpoint(signal, code, context); - break; - - case trap_AfterBreakpoint: - *skipped_break_addr = trap_Breakpoint; - skipped_break_addr = NULL; - *(unsigned int *)*os_context_pc_addr(context) - = displaced_after_inst; - *os_context_sigmask_addr(context)= orig_sigmask; - - os_flush_icache((os_vm_address_t) *os_context_pc_addr(context), - sizeof(unsigned int)); - break; - - case trap_SingleStepAround: - case trap_SingleStepBefore: - { - int register_offset = code >> 5 & 0x1f; - - handle_single_step_trap(context, trap, register_offset); - - arch_skip_instruction(context); - break; - } - default: - interrupt_handle_now(signal, code, context); - break; - } + if (!maybe_handle_trap(context,trap)) + interrupt_handle_now(signal, siginfo, context); + #ifdef LISP_FEATURE_DARWIN DARWIN_FIX_CONTEXT(context); #endif return; } if (((code >> 26) == 3) && (((code >> 21) & 31) == 24)) { - interrupt_internal_error(signal, code, context, 0); + interrupt_internal_error(context, 0); #ifdef LISP_FEATURE_DARWIN DARWIN_FIX_CONTEXT(context); #endif diff --git a/src/runtime/print.c b/src/runtime/print.c index 8e3ba51..ea57ae0 100644 --- a/src/runtime/print.c +++ b/src/runtime/print.c @@ -351,7 +351,12 @@ static void brief_list(lispobj obj) static void print_unknown(lispobj obj) { - printf("unknown object: %p", obj); + printf("unknown object: %p", (void *)obj); +} + +static void print_unknown(lispobj obj) +{ + printf("unknown object: %p", (void *)obj); } static void print_list(lispobj obj) diff --git a/src/runtime/sparc-arch.c b/src/runtime/sparc-arch.c index 6151619..d258e7d 100644 --- a/src/runtime/sparc-arch.c +++ b/src/runtime/sparc-arch.c @@ -207,6 +207,30 @@ static int pseudo_atomic_trap_p(os_context_t *context) return result; } +void +arch_handle_breakpoint(os_context_t *context) +{ + handle_breakpoint(context); +} + +void +arch_handle_fun_end_breakpoint(os_context_t *context) +{ + *os_context_pc_addr(context) = (int) handle_fun_end_breakpoint(context); + *os_context_npc_addr(context) = *os_context_pc_addr(context) + 4; +} + +void +arch_handle_after_breakpoint(os_context_t *context) +{ + *skipped_break_addr = trap_Breakpoint; + os_flush_icache(skipped_break_addr, sizeof(unsigned int)); + skipped_break_addr = NULL; + *(unsigned long *) os_context_pc_addr(context) = displaced_after_inst; + /* context->sigmask = orig_sigmask; */ + os_flush_icache((os_vm_address_t) os_context_pc_addr(context), sizeof(unsigned int)); +} + static void sigill_handler(int signal, siginfo_t *siginfo, void *void_context) { os_context_t *context = arch_os_get_context(&void_context); @@ -226,44 +250,8 @@ static void sigill_handler(int signal, siginfo_t *siginfo, void *void_context) inst = *pc; trap = inst & 0x3fffff; - - switch (trap) { - case trap_PendingInterrupt: - arch_skip_instruction(context); - interrupt_handle_pending(context); - break; - - case trap_Halt: - fake_foreign_function_call(context); - lose("%%primitive halt called; the party is over.\n"); - - case trap_Error: - case trap_Cerror: - interrupt_internal_error(signal, siginfo, context, trap == trap_Cerror); - break; - - case trap_Breakpoint: - handle_breakpoint(signal, siginfo, context); - break; - - case trap_FunEndBreakpoint: - *os_context_pc_addr(context) = (int) handle_fun_end_breakpoint(signal, siginfo, context); - *os_context_npc_addr(context) = *os_context_pc_addr(context) + 4; - break; - - case trap_AfterBreakpoint: - *skipped_break_addr = trap_Breakpoint; - os_flush_icache(skipped_break_addr, sizeof(unsigned int)); - skipped_break_addr = NULL; - *(unsigned long *) os_context_pc_addr(context) = displaced_after_inst; - /* context->sigmask = orig_sigmask; */ - os_flush_icache((os_vm_address_t) os_context_pc_addr(context), sizeof(unsigned int)); - break; - - default: + if (!maybe_handle_trap(context,trap)) interrupt_handle_now(signal, siginfo, context); - break; - } } else if ((siginfo->si_code) == ILL_ILLTRP #ifdef LISP_FEATURE_LINUX @@ -280,7 +268,7 @@ static void sigill_handler(int signal, siginfo_t *siginfo, void *void_context) interrupt_handle_pending(context); } else { - interrupt_internal_error(signal, siginfo, context, 0); + interrupt_internal_error(context, 0); } } else { @@ -333,7 +321,7 @@ static void sigemt_handler(int signal, siginfo_t *siginfo, void *void_context) if ((op1 & 3) != 0) { /* The first arg wan't a fixnum. */ - interrupt_internal_error(signal, siginfo, context, 0); + interrupt_internal_error(context, 0); return; } @@ -349,7 +337,7 @@ static void sigemt_handler(int signal, siginfo_t *siginfo, void *void_context) if ((op2 & 3) != 0) { /* The second arg wan't a fixnum. */ - interrupt_internal_error(signal, siginfo, context, 0); + interrupt_internal_error(context, 0); return; } diff --git a/src/runtime/x86-64-arch.c b/src/runtime/x86-64-arch.c index 0401c48..657381f 100644 --- a/src/runtime/x86-64-arch.c +++ b/src/runtime/x86-64-arch.c @@ -203,6 +203,30 @@ arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst) #endif } +void +arch_handle_breakpoint(os_context_t *context) +{ + --*os_context_pc_addr(context); + handle_breakpoint(context); +} + +void +arch_handle_fun_end_breakpoint(os_context_t *context) +{ + --*os_context_pc_addr(context); + *os_context_pc_addr(context) = + (unsigned long)handle_fun_end_breakpoint(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); +} + void sigtrap_handler(int signal, siginfo_t *info, void *void_context) @@ -254,53 +278,9 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *)(*os_context_pc_addr(context)); - switch (trap) { - - case trap_PendingInterrupt: - FSHOW((stderr, "/\n")); - arch_skip_instruction(context); - interrupt_handle_pending(context); - break; - - case trap_Halt: - /* Note: the old CMU CL code tried to save FPU state - * here, and restore it after we do our thing, but there - * 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.\n"); - - case trap_Error: - case trap_Cerror: - FSHOW((stderr, "\n", trap)); - interrupt_internal_error(signal, info, context, trap==trap_Cerror); - break; - - case trap_Breakpoint: - --*os_context_pc_addr(context); - handle_breakpoint(signal, info, context); - break; - - case trap_FunEndBreakpoint: - --*os_context_pc_addr(context); - *os_context_pc_addr(context) = - (unsigned long)handle_fun_end_breakpoint(signal, info, context); - break; - - case trap_SingleStepAround: - case trap_SingleStepBefore: - 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); - break; - - default: - FSHOW((stderr,"/[C--trap default %d %d %x]\n", - signal, code, context)); + + if (!maybe_handle_trap(context, trap)) interrupt_handle_now(signal, info, context); - break; - } } void diff --git a/src/runtime/x86-arch.c b/src/runtime/x86-arch.c index c32aed7..3ef7fc8 100644 --- a/src/runtime/x86-arch.c +++ b/src/runtime/x86-arch.c @@ -66,7 +66,7 @@ context_eflags_addr(os_context_t *context) #elif defined __OpenBSD__ return &context->sc_eflags; #elif defined LISP_FEATURE_DARWIN - return &context->uc_mcontext->ss.eflags; + return (int *)(&context->uc_mcontext->ss.eflags); #elif defined __NetBSD__ return &(context->uc_mcontext.__gregs[_REG_EFL]); #elif defined LISP_FEATURE_WIN32 @@ -233,6 +233,30 @@ restore_breakpoint_from_single_step(os_context_t * context) } void +arch_handle_breakpoint(os_context_t *context) +{ + --*os_context_pc_addr(context); + handle_breakpoint(context); +} + +void +arch_handle_fun_end_breakpoint(os_context_t *context) +{ + --*os_context_pc_addr(context); + *os_context_pc_addr(context) = + (int)handle_fun_end_breakpoint(context); +} + +void +arch_handle_single_step_trap(os_context_t *context, int trap) +{ + arch_skip_instruction(context); + /* On x86 the fdefn / function is always in EAX, so we pass 0 + * as the register_offset. */ + handle_single_step_trap(context, trap, 0); +} + +void sigtrap_handler(int signal, siginfo_t *info, void *void_context) { os_context_t *context = (os_context_t*)void_context; @@ -278,54 +302,8 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context) * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *)(*os_context_pc_addr(context)); - /* FSHOW((stderr, "/\n", trap, *os_context_pc_addr(context))); */ - switch (trap) { - - case trap_PendingInterrupt: - FSHOW((stderr, "/\n")); - arch_skip_instruction(context); - interrupt_handle_pending(context); - break; - - case trap_Halt: - /* Note: the old CMU CL code tried to save FPU state - * here, and restore it after we do our thing, but there - * 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.\n"); - - case trap_Error: - case trap_Cerror: - FSHOW((stderr, "\n", trap)); - interrupt_internal_error(signal, info, context, trap==trap_Cerror); - break; - - case trap_Breakpoint: - --*os_context_pc_addr(context); - handle_breakpoint(signal, info, context); - break; - - case trap_FunEndBreakpoint: - --*os_context_pc_addr(context); - *os_context_pc_addr(context) = - (int)handle_fun_end_breakpoint(signal, info, context); - break; - - case trap_SingleStepAround: - case trap_SingleStepBefore: - arch_skip_instruction(context); - /* On x86 the fdefn / function is always in EAX, so we pass 0 - * as the register_offset. */ - handle_single_step_trap(context, trap, 0); - break; - - default: - FSHOW((stderr,"/[C--trap default %d %d %x]\n", - signal, trap, context)); + if (!maybe_handle_trap(context, trap)) interrupt_handle_now(signal, info, context); - break; - } } void diff --git a/src/runtime/x86-bsd-os.c b/src/runtime/x86-bsd-os.c index f1b66c7..bde0ac0 100644 --- a/src/runtime/x86-bsd-os.c +++ b/src/runtime/x86-bsd-os.c @@ -36,21 +36,21 @@ os_context_register_addr(os_context_t *context, int offset) { switch(offset) { case 0: - return CONTEXT_ADDR_FROM_STEM(eax); + return (int *)CONTEXT_ADDR_FROM_STEM(eax); case 2: - return CONTEXT_ADDR_FROM_STEM(ecx); + return (int *)CONTEXT_ADDR_FROM_STEM(ecx); case 4: - return CONTEXT_ADDR_FROM_STEM(edx); + return (int *)CONTEXT_ADDR_FROM_STEM(edx); case 6: - return CONTEXT_ADDR_FROM_STEM(ebx); + return (int *)CONTEXT_ADDR_FROM_STEM(ebx); case 8: - return CONTEXT_ADDR_FROM_STEM(esp); + return (int *)CONTEXT_ADDR_FROM_STEM(esp); case 10: - return CONTEXT_ADDR_FROM_STEM(ebp); + return (int *)CONTEXT_ADDR_FROM_STEM(ebp); case 12: - return CONTEXT_ADDR_FROM_STEM(esi); + return (int *)CONTEXT_ADDR_FROM_STEM(esi); case 14: - return CONTEXT_ADDR_FROM_STEM(edi); + return (int *)CONTEXT_ADDR_FROM_STEM(edi); default: return 0; } @@ -59,7 +59,7 @@ os_context_register_addr(os_context_t *context, int offset) int * os_context_sp_addr(os_context_t *context) { - return CONTEXT_ADDR_FROM_STEM(esp); + return (int *)CONTEXT_ADDR_FROM_STEM(esp); } #endif /* __FreeBSD__ || __OpenBSD__ */ @@ -109,7 +109,7 @@ int *os_context_pc_addr(os_context_t *context) #elif defined __NetBSD__ return CONTEXT_ADDR_FROM_STEM(EIP); #elif defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_X86) - return CONTEXT_ADDR_FROM_STEM(eip); + return (int *)CONTEXT_ADDR_FROM_STEM(eip); #elif defined LISP_FEATURE_DARWIN return &context->uc_mcontext->ss.srr0; #else diff --git a/tools-for-build/grovel-headers.c b/tools-for-build/grovel-headers.c index 40f4320..9b16e06 100644 --- a/tools-for-build/grovel-headers.c +++ b/tools-for-build/grovel-headers.c @@ -241,7 +241,14 @@ main(int argc, char *argv[]) DEFTYPE("off-t", off_t); DEFTYPE("size-t", size_t); DEFTYPE("time-t", time_t); +#if defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_PPC) + /* No idea if this is an issue with PPC versions of OS X, or just + * 10.3, but at any rate on some Darwin versions suseconds_t seems + * to be missing... Similar kludge in sb-posix. */ + DEFTYPE("suseconds-t", int); +#else DEFTYPE("suseconds-t", suseconds_t); +#endif DEFTYPE("uid-t", uid_t); printf("\n"); diff --git a/version.lisp-expr b/version.lisp-expr index 7f518a6..1657ab2 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.4.12" +"1.0.4.13" -- 1.7.10.4