# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R0])
+#if 0
# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
/* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
VG_(mk_SysRes_ppc64_linux)( \
(uc)->uc_mcontext.gp_regs[VKI_PT_R3], \
(((uc)->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1) \
)
+#else
+ /* Dubious hack: if there is an error, only consider the lowest 8
+ bits of r3. memcheck/tests/post-syscall shows a case where an
+ interrupted syscall should have produced a ucontext with 0x4
+ (VKI_EINTR) in r3 but is in fact producing 0x204. */
+ /* Awaiting clarification from PaulM. Evidently 0x204 is
+ ERESTART_RESTARTBLOCK, which shouldn't have made it into user
+ space. */
+ static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( struct vki_ucontext* uc )
+ {
+ ULong err = (uc->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1;
+ ULong r3 = uc->uc_mcontext.gp_regs[VKI_PT_R3];
+ if (err) r3 &= 0xFF;
+ return VG_(mk_SysRes_ppc64_linux)( r3, err );
+ }
+#endif
# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_LNK])
#else