Index: valgrind-quilt/coregrind/vg_syscalls.c =================================================================== --- valgrind-quilt.orig/coregrind/vg_syscalls.c 2005-06-10 13:06:50.439909152 -0400 +++ valgrind-quilt/coregrind/vg_syscalls.c 2005-06-10 13:59:37.742966632 -0400 @@ -5770,6 +5770,14 @@ { if (SYSRES == 0 && arg3 != 0) POST_MEM_WRITE( arg3, sizeof(vki_old_sigset_t)); +#ifdef __powerpc__ + /* The signal delivery mechanism expects the signal number to be in gpr3. + However, at this point, the sigprocmask return value has overwritten + that value. So here we put the signal number into gpr3. The syscall + return value will later be restored from tst->arch.saved_rc. */ + if (tst->arch.saved_signal) + tst->arch.m_gpr[3] = tst->arch.saved_signal; +#endif } PRE(sys_rt_sigprocmask, Special) @@ -5797,6 +5805,14 @@ { if (SYSRES == 0 && arg3 != 0) POST_MEM_WRITE( arg3, sizeof(vki_sigset_t)); +#ifdef __powerpc__ + /* The signal delivery mechanism expects the signal number to be in gpr3. + However, at this point, the sigprocmask return value has overwritten + that value. So here we put the signal number into gpr3. The syscall + return value will later be restored from tst->arch.saved_rc. */ + if (tst->arch.saved_signal) + tst->arch.m_gpr[3] = tst->arch.saved_signal; +#endif } PRE(sys_sigpending, 0) Index: valgrind-quilt/coregrind/ppc/signal.c =================================================================== --- valgrind-quilt.orig/coregrind/ppc/signal.c 2005-06-10 13:06:50.437909456 -0400 +++ valgrind-quilt/coregrind/ppc/signal.c 2005-06-10 13:59:49.746006000 -0400 @@ -252,6 +252,10 @@ SET_SIGNAL_GPR(tid, 3, sigNo); tst->arch.m_eip = (Addr) handler; + /* If this is happening in a system call, the system call return value will + overwrite sigNo in gpr3. We need to preserve the signal number + elsewhere. */ + tst->arch.saved_signal = sigNo; } void VGA_(signal_return)(ThreadId tid, Bool has_siginfo) @@ -265,6 +269,11 @@ vg_assert(VG_(is_valid_tid)(tid)); tst = VG_(get_ThreadState)(tid); + + /* Restore syscall return val to gpr3 */ + SET_SYSCALL_RETVAL(tid, tst->arch.saved_rc); + tst->arch.saved_signal = 0; + tst->arch.saved_rc = 0; /* Check that the stack frame looks valid */ sp = tst->arch.m_gpr[1]; Index: valgrind-quilt/coregrind/ppc/core_arch.h =================================================================== --- valgrind-quilt.orig/coregrind/ppc/core_arch.h 2005-06-10 13:06:50.437909456 -0400 +++ valgrind-quilt/coregrind/ppc/core_arch.h 2005-06-10 13:09:15.648935144 -0400 @@ -113,6 +113,8 @@ Bool vr_live; /* vector state is in machine regs */ Addr dispatch_sp; + UInt saved_signal; /* needed to preserve sigNo during syscall */ + UInt saved_rc; /* needed to preserve syscall rc during signal handler */ } arch_thread_t; Index: valgrind-quilt/coregrind/ppc-linux/core_platform.h =================================================================== --- valgrind-quilt.orig/coregrind/ppc-linux/core_platform.h 2005-06-10 13:06:50.438909304 -0400 +++ valgrind-quilt/coregrind/ppc-linux/core_platform.h 2005-06-10 13:55:31.980916080 -0400 @@ -70,6 +70,7 @@ } \ (regs).m_result = __val; \ (regs).m_gpr[0] = 0; \ + (regs).saved_rc = __val; \ } while (0) #define PLATFORM_SYSCALL_GPR3(regs) ((regs).m_gpr[3]) @@ -89,6 +90,7 @@ /* XXX this isn't right because it makes the whole CR valid. */ \ SET_THREAD_REG(zztid, __cr, PLATFORM_SYSCALL_CR, R_CR, \ post_reg_write_syscall_return); \ + VG_(threads)[zztid].arch.saved_rc = __val; \ } while (0) /* --------------------------------------------------------------------- Index: valgrind-quilt/coregrind/ppc-linux/syscalls.c =================================================================== --- valgrind-quilt.orig/coregrind/ppc-linux/syscalls.c 2005-06-10 13:06:50.438909304 -0400 +++ valgrind-quilt/coregrind/ppc-linux/syscalls.c 2005-06-10 13:58:31.470923008 -0400 @@ -685,6 +685,12 @@ VGA_(signal_return)(tid, False); } +POST(sys_sigreturn) +{ + /* restore gpr3, the return code from sys_sigreturn is unimportant */ + tst->arch.m_gpr[3] = tst->arch.m_orig_gpr3; +} + PRE(sys_rt_sigreturn, Special) { /* no arguments, expects an RT signal frame on the stack */ @@ -861,7 +867,7 @@ LINXY(__NR_sysinfo, sys_sysinfo), // 116 GENXY(__NR_ipc, sys_ipc), // 117 GENX_(__NR_fsync, sys_fsync), // 118 - PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ppc/Linux + PLAXY(__NR_sigreturn, sys_sigreturn), // 119 ppc/Linux PLAX_(__NR_clone, sys_clone), // 120 // (__NR_setdomainname, sys_setdomainname),// 121