Fix up ppc32-linux handlers for sys_sigreturn and sys_rt_sigreturn. I really
have no idea how these work (what's there is a conceptual transcription of
what we have for x86-linux) and so if those of you more Skilled In The Art
Of Signals than myself would care to peer at it, that would be appreciated.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5153 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c
index 5aa1bfe..c68b2df 100644
--- a/coregrind/m_syswrap/syswrap-ppc32-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c
@@ -387,6 +387,7 @@
DECL_TEMPLATE(ppc32_linux, sys_ipc);
DECL_TEMPLATE(ppc32_linux, sys_clone);
DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
+DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn);
DECL_TEMPLATE(ppc32_linux, sys_sigaction);
PRE(sys_socketcall)
@@ -1015,20 +1016,32 @@
// sigreturn sequence's "popl %eax" and handler ret addr */
tst = VG_(get_ThreadState)(tid);
//tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
+ // Should we do something equivalent on ppc32? Who knows.
///* This is only so that the EIP is (might be) useful to report if
// something goes wrong in the sigreturn */
//ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
+ // Should we do something equivalent on ppc32? Who knows.
VG_(sigframe_destroy)(tid, False);
/* For unclear reasons, it appears we need the syscall to return
- without changing %EAX. Since %EAX is the return value, and can
+ without changing R3. Since R3 is the return value, and can
denote either success or failure, we must set up so that the
- driver logic copies it back unchanged. Also, note %EAX is of
+ driver logic copies it back unchanged. Also, note R3 is of
the guest registers written by VG_(sigframe_destroy). */
- //SET_STATUS_from_SysRes( VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX ) );
- SET_STATUS_from_SysRes(
+ /* jrs 16 Nov 05: for some reason this occasionally causes the
+ is-this-a-sane-error-value sanity check to fail:
+ m_syswrap/syswrap-ppc32-linux.c:1037
+ (vgSysWrap_ppc32_linux_sys_sigreturn_before):
+ Assertion 'wzz >= 0 && wzz < 10000' failed.
+ Hence use a sanity-check-free version.
+ Perhaps we should ignore CR0.S0 here?
+ In general I have no idea what this is for or if it is necessary.
+ It's a conceptual copy-n-paste from the x86 equivalent, but I'm
+ equally unclear as to whether it is needed there either.
+ */
+ SET_STATUS_from_SysRes_NO_SANITY_CHECK(
VG_(mk_SysRes_ppc32_linux)(
tst->arch.vex.guest_GPR3,
/* get CR0.SO */
@@ -1040,47 +1053,41 @@
*flags |= SfPollAfter;
}
-//.. PRE(sys_sigreturn, Special)
-//.. {
-//.. PRINT("sigreturn ( )");
-//..
-//.. /* Adjust esp to point to start of frame; skip back up over
-//.. sigreturn sequence's "popl %eax" and handler ret addr */
-//.. tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
-//..
-//.. /* This is only so that the EIP is (might be) useful to report if
-//.. something goes wrong in the sigreturn */
-//.. VG_(restart_syscall)(&tst->arch);
-//..
-//.. VG_(sigframe_destroy)(tid, False);
-//..
-//.. /* Keep looking for signals until there are none */
-//.. VG_(poll_signals)(tid);
-//..
-//.. /* placate return-must-be-set assertion */
-//.. SET_RESULT(RES);
-//.. }
+PRE(sys_rt_sigreturn)
+{
+ ThreadState* tst;
+ PRINT("rt_sigreturn ( )");
-//.. PRE(sys_rt_sigreturn, Special)
-//.. {
-//.. PRINT("rt_sigreturn ( )");
-//..
-//.. /* Adjust esp to point to start of frame; skip back up over handler
-//.. ret addr */
-//.. tst->arch.vex.guest_ESP -= sizeof(Addr);
-//..
-//.. /* This is only so that the EIP is (might be) useful to report if
-//.. something goes wrong in the sigreturn */
-//.. VG_(restart_syscall)(&tst->arch);
-//..
-//.. VG_(sigframe_destroy)(tid, False);
-//..
-//.. /* Keep looking for signals until there are none */
-//.. VG_(poll_signals)(tid);
-//..
-//.. /* placate return-must-be-set assertion */
-//.. SET_RESULT(RES);
-//.. }
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
+ ///* Adjust esp to point to start of frame; skip back up over handler
+ // ret addr */
+ tst = VG_(get_ThreadState)(tid);
+ //tst->arch.vex.guest_ESP -= sizeof(Addr);
+ // Should we do something equivalent on ppc32? Who knows.
+
+ ///* This is only so that the EIP is (might be) useful to report if
+ // something goes wrong in the sigreturn */
+ //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
+ // Should we do something equivalent on ppc32? Who knows.
+
+ VG_(sigframe_destroy)(tid, True);
+
+ /* See comments above in PRE(sys_sigreturn) about this. */
+ SET_STATUS_from_SysRes_NO_SANITY_CHECK(
+ VG_(mk_SysRes_ppc32_linux)(
+ tst->arch.vex.guest_GPR3,
+ /* get CR0.SO */
+ (LibVEX_GuestPPC32_get_CR( &tst->arch.vex ) >> 28) & 1
+ )
+ );
+
+ /* Check to see if some any signals arose as a result of this. */
+ *flags |= SfPollAfter;
+}
+
//.. PRE(sys_modify_ldt, Special)
//.. {
@@ -1644,7 +1651,7 @@
//.. LINX_(__NR_setresgid, sys_setresgid16), // 169
LINXY(__NR_getresgid, sys_getresgid16), // 170
LINX_(__NR_prctl, sys_prctl), // 171
-//.. PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 172
+ PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 172
LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 173
LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 174