diff -ur 2.5.old/arch/ppc/kernel/misc.S 2.5/arch/ppc/kernel/misc.S --- 2.5.old/arch/ppc/kernel/misc.S 2003-12-15 11:20:44.000000000 -0600 +++ 2.5/arch/ppc/kernel/misc.S 2003-12-14 21:31:49.000000000 -0600 @@ -1385,3 +1385,5 @@ .long sys_statfs64 .long sys_fstatfs64 .long ppc_fadvise64_64 + .long sys_ni_syscall /* 255 */ + .long sys_debug_setcontext diff -ur 2.5.old/arch/ppc/kernel/signal.c 2.5/arch/ppc/kernel/signal.c --- 2.5.old/arch/ppc/kernel/signal.c 2003-12-15 11:21:16.000000000 -0600 +++ 2.5/arch/ppc/kernel/signal.c 2003-12-17 07:50:15.000000000 -0600 @@ -445,6 +445,88 @@ return 0; } +int sys_debug_setcontext(struct ucontext __user *ctx, + int ndbg, struct sig_dbg_op *dbg, + int r6, int r7, int r8, + struct pt_regs *regs) +{ + unsigned char tmp; + struct sig_dbg_op op; + int i; + unsigned long new_msr = regs->msr; +#if defined(CONFIG_4xx) + unsigned long new_dbcr0 = current->thread.dbcr0; +#endif + + for (i=0; imsr = new_msr; +#if defined(CONFIG_4xx) + current->thread.dbcr0 = new_dbcr0; +#endif + + /* + * If we get a fault copying the context into the kernel's + * image of the user's registers, we can't just return -EFAULT + * because the user's registers will be corrupted. For instance + * the NIP value may have been updated but not some of the + * other registers. Given that we have done the verify_area + * and successfully read the first and last bytes of the region + * above, this should only happen in an out-of-memory situation + * or if another thread unmaps the region containing the context. + * We kill the task with a SIGSEGV in this situation. + */ + if (do_setcontext(ctx, regs)) + do_exit(SIGSEGV); + sigreturn_exit(regs); + /* doesn't actually return back to here */ + return 0; +} + /* * OK, we're invoking a handler */ diff -ur 2.5.old/arch/ppc/kernel/traps.c 2.5/arch/ppc/kernel/traps.c --- 2.5.old/arch/ppc/kernel/traps.c 2003-12-15 11:18:41.000000000 -0600 +++ 2.5/arch/ppc/kernel/traps.c 2003-12-14 21:27:33.000000000 -0600 @@ -462,7 +462,7 @@ void SingleStepException(struct pt_regs *regs) { - regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ + regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ if (debugger_sstep(regs)) return; _exception(SIGTRAP, regs, TRAP_TRACE, 0); diff -ur 2.5.old/include/asm-ppc/signal.h 2.5/include/asm-ppc/signal.h --- 2.5.old/include/asm-ppc/signal.h 2003-12-15 11:18:33.000000000 -0600 +++ 2.5/include/asm-ppc/signal.h 2003-12-14 21:27:40.000000000 -0600 @@ -153,4 +153,23 @@ #define ptrace_signal_deliver(regs, cookie) do { } while (0) #endif /* __KERNEL__ */ +/* + * These are parameters to dbg_sigreturn syscall. They enable or + * disable certain debugging things that can be done from signal + * handlers. The dbg_sigreturn syscall *must* be called from a + * SA_SIGINFO signal so the ucontext can be passed to it. It takes an + * array of struct sig_dbg_op, which has the debug operations to + * perform before returning from the signal. + */ +struct sig_dbg_op { + int dbg_type; + unsigned long dbg_value; +}; + +/* Enable or disable single-stepping. The value sets the state. */ +#define SIG_DBG_SINGLE_STEPPING 1 + +/* Enable or disable branch tracing. The value sets the state. */ +#define SIG_DBG_BRANCH_TRACING 2 + #endif diff -ur 2.5.old/include/asm-ppc/unistd.h 2.5/include/asm-ppc/unistd.h --- 2.5.old/include/asm-ppc/unistd.h 2003-12-15 11:18:41.000000000 -0600 +++ 2.5/include/asm-ppc/unistd.h 2003-12-14 21:29:24.000000000 -0600 @@ -259,8 +259,9 @@ #define __NR_statfs64 252 #define __NR_fstatfs64 253 #define __NR_fadvise64_64 254 +#define __NR_debug_setcontext 256 -#define __NR_syscalls 255 +#define __NR_syscalls 257 #define __NR(n) #n