diff --git a/lisp/breakpoint.c b/lisp/breakpoint.c index e3468d36bf27079a51515d2cb0a59dbb4594f42a..db68b4f9e6a144f9ee5cf9fb39a3ca2d00b6ab2c 100644 --- a/lisp/breakpoint.c +++ b/lisp/breakpoint.c @@ -1,6 +1,6 @@ /* - $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/breakpoint.c,v 1.15 2005/03/17 23:13:55 rtoy Exp $ + $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/breakpoint.c,v 1.16 2005/03/18 05:30:50 rtoy Exp $ This code was written as part of the CMU Common Lisp project at Carnegie Mellon University, and has been placed in the public domain. @@ -119,7 +119,7 @@ static int compute_offset(os_context_t *scp, lispobj code, boolean function_end) int offset = pc - code_start; if (offset >= codeptr->code_size) { if (function_end) { -#ifdef sparc +#if defined(sparc) || defined(DARWIN) /* * We're in a function end breakpoint. Compute the * offset from the (known) breakpoint location and the @@ -203,6 +203,13 @@ void *handle_function_end_breakpoint(int signal, int subcode, code = find_code(scp); codeptr = (struct code *)PTR(code); offset = compute_offset(scp, code, 1); +#if 0 + printf("handle_function_end:\n"); + printf(" code = 0x%08x\n", code); + printf(" codeptr = %p\n", codeptr); + printf(" offset = %d\n", fixnum_value(offset)); + fflush(stdout); +#endif if (offset < 0) { @@ -213,7 +220,7 @@ void *handle_function_end_breakpoint(int signal, int subcode, * appropriately so the breakpoint handler can do the right * thing. */ - unsigned long pc; + unsigned int pc; pc = SC_PC(scp); @@ -228,6 +235,12 @@ void *handle_function_end_breakpoint(int signal, int subcode, code -= sizeof(struct code) + BOGUS_LRA_CONSTANTS*sizeof(lispobj); code += type_OtherPointer; codeptr = (struct code *) PTR(code); +#if 0 + printf(" pc = 0x%08x\n", pc); + printf(" code = 0x%08x\n", code); + printf(" codeptr = %p\n", codeptr); + fflush(stdout); +#endif } funcall3(SymbolFunction(HANDLE_BREAKPOINT), diff --git a/lisp/ppc-arch.c b/lisp/ppc-arch.c index 5d6774f617caf2ce22a85c5df7669d28619e56af..17dda5a2da8851f7ecf90ecfddef6444920b4cf8 100644 --- a/lisp/ppc-arch.c +++ b/lisp/ppc-arch.c @@ -1,6 +1,6 @@ /* - $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/ppc-arch.c,v 1.2 2005/02/06 19:43:15 rtoy Exp $ + $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/ppc-arch.c,v 1.3 2005/03/18 05:30:50 rtoy Exp $ This code was written as part of the CMU Common Lisp project at Carnegie Mellon University, and has been placed in the public domain. @@ -41,6 +41,16 @@ #define PT_DSISR 42 #endif +/* + * A macro to generate the instruction + * + * twllei r0, code + * + * This is what the ppc port uses to signal various traps like + * breakpoints and stuff. + */ +#define TWLLEI_R0(code) ((3<<26) | (6 << 21) | code) + char * arch_init(void) { return "lisp.core"; @@ -101,7 +111,10 @@ arch_install_breakpoint(void *pc) { unsigned long *ptr = (unsigned long *)pc; unsigned long result = *ptr; - *ptr = (3<<26) | (5 << 21) | trap_Breakpoint; + /* + * Insert a twllei r0, trap_Breakpoint instruction. + */ + *ptr = TWLLEI_R0(trap_Breakpoint); os_flush_icache((os_vm_address_t) pc, sizeof(unsigned long)); return result; } @@ -119,15 +132,25 @@ static sigset_t orig_sigmask; void arch_do_displaced_inst(os_context_t *scp, unsigned long orig_inst) { - unsigned long *pc = (unsigned long *)SC_PC(scp); + unsigned int *pc = (unsigned long *)SC_PC(scp); orig_sigmask = scp->uc_sigmask; sigemptyset(&scp->uc_sigmask); FILLBLOCKSET(&scp->uc_sigmask); + /* Put the original instruction back */ *pc = orig_inst; - os_flush_icache((os_vm_address_t) pc, sizeof(unsigned long)); + os_flush_icache((os_vm_address_t) pc, sizeof(unsigned int)); skipped_break_addr = pc; + + /* + * Replace the next instruction with a + * twllei r0, trap_AfterBreakpoint + */ + displaced_after_inst = *++pc; + *pc = TWLLEI_R0(trap_AfterBreakpoint); + os_flush_icache((os_vm_address_t) pc, sizeof(unsigned int)); + sigreturn(scp); } static void @@ -142,6 +165,11 @@ sigill_handler(HANDLER_ARGS) sigprocmask(SIG_SETMASK, &context->uc_sigmask, 0); opcode = *((int *) SC_PC(context)); +#if 0 + printf("SIGILL entry: opcode = 0x%08x\n", opcode); + fflush(stdout); +#endif + if (opcode == ((3 << 26) | (16 << 21) | (reg_ALLOC << 16))) { /* twlti reg_ALLOC,0 - check for deferred interrupt */ (SC_REG(context, reg_ALLOC) -= PSEUDO_ATOMIC_INTERRUPTED_BIAS); @@ -158,6 +186,11 @@ sigill_handler(HANDLER_ARGS) /* twllei reg_ZERO,N will always trap if reg_ZERO = 0 */ int trap = opcode & 0x1f, extra = (opcode >> 5) & 0x1f; +#if 0 + printf("SIGILL: TWLLEI, code = %d\n", trap); + fflush(stdout); +#endif + switch (trap) { case trap_Halt: fake_foreign_function_call(context); @@ -174,15 +207,24 @@ sigill_handler(HANDLER_ARGS) break; case trap_Breakpoint: +#if 0 + printf("trap_Breakpoint\n"); + fflush(stdout); +#endif handle_breakpoint(signal, code, context); break; case trap_FunctionEndBreakpoint: +#if 0 + printf("trap_FunctionEndBreakpoint\n"); + fflush(stdout); +#endif SC_PC(context)=(int)handle_function_end_breakpoint(signal, code, context); break; case trap_AfterBreakpoint: - *skipped_break_addr = trap_Breakpoint; + /* Put our breakpoint instruction back in */ + *skipped_break_addr = TWLLEI_R0(trap_Breakpoint); skipped_break_addr = NULL; *(unsigned long *)SC_PC(context) = displaced_after_inst; context->uc_sigmask = orig_sigmask; diff --git a/lisp/ppc-assem.S b/lisp/ppc-assem.S index bfb5207510ac4ff554066daa1d8ad639fefc9306..dac3fed0a2494d2d94ace0e0c288d528f326dfc5 100644 --- a/lisp/ppc-assem.S +++ b/lisp/ppc-assem.S @@ -470,21 +470,32 @@ _closure_tramp: SET_SIZE(xclosure_tramp) - GFUNCDEF(function_end_breakpoint_trap) - .long 0 - SET_SIZE(function_end_breakpoint_trap) - - GFUNCDEF(function_end_breakpoint) - .long 0 - SET_SIZE(function_end_breakpoint) - - GFUNCDEF(function_end_breakpoint_guts) - .long 0 - SET_SIZE(function_end_breakpoint_guts) - - GFUNCDEF(function_end_breakpoint_end) - .long 0 - SET_SIZE(function_end_breakpoint_end) +/* + * Function-end breakpoint magic. See MAKE-BOGUS-LRA in + * code/debug-int.lisp. + */ + .text + .align 3 + .globl _function_end_breakpoint_guts +_function_end_breakpoint_guts: + .long type_ReturnPcHeader + b 1f + /* + * Are these really necessary? I'm cargo-culting from the sparc port + */ + mr reg_OCFP, reg_CSP + addi reg_CSP, reg_CSP, 4 + li reg_NARGS, 4 + mr reg_A1, reg_NULL + mr reg_A2, reg_NULL + mr reg_A3, reg_NULL +1: + .globl _function_end_breakpoint_trap +_function_end_breakpoint_trap: + twllei reg_ZERO, trap_FunctionEndBreakpoint + b 1b + .globl _function_end_breakpoint_end +_function_end_breakpoint_end: GFUNCDEF(ppc_flush_cache_line)