Handle sys_sigaction on ppc32-linux.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5028 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c
index c78825f..6e5b49b 100644
--- a/coregrind/m_syswrap/syswrap-ppc32-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c
@@ -604,6 +604,7 @@
 DECL_TEMPLATE(ppc32_linux, sys_ipc);
 DECL_TEMPLATE(ppc32_linux, sys_clone);
 DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
+DECL_TEMPLATE(ppc32_linux, sys_sigaction);
 
 PRE(sys_socketcall)
 {
@@ -1564,83 +1565,77 @@
 //.. }
 
 
-//.. // jrs 20050207: this is from the svn branch
-//.. //PRE(sys_sigaction, Special)
-//.. //{
-//.. //   PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
-//.. //   PRE_REG_READ3(int, "sigaction",
-//.. //                 int, signum, const struct old_sigaction *, act,
-//.. //                 struct old_sigaction *, oldact)
-//.. //   if (ARG2 != 0)
-//.. //      PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
-//.. //   if (ARG3 != 0)
-//.. //      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
-//.. //
-//.. //   VG_(do_sys_sigaction)(tid);
-//.. //}
+/* Convert from non-RT to RT sigset_t's */
+static 
+void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
+{
+   VG_(sigemptyset)(set);
+   set->sig[0] = *oldset;
+}
+PRE(sys_sigaction)
+{
+   struct vki_sigaction new, old;
+   struct vki_sigaction *newp, *oldp;
 
-//.. /* Convert from non-RT to RT sigset_t's */
-//.. static void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
-//.. {
-//..    VG_(sigemptyset)(set);
-//..    set->sig[0] = *oldset;
-//.. }
-//.. PRE(sys_sigaction, Special)
-//.. {
-//..    struct vki_sigaction new, old;
-//..    struct vki_sigaction *newp, *oldp;
-//.. 
-//..    PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
-//..    PRE_REG_READ3(int, "sigaction",
-//..                  int, signum, const struct old_sigaction *, act,
-//..                  struct old_sigaction *, oldact);
-//.. 
-//..    newp = oldp = NULL;
-//.. 
-//..    if (ARG2 != 0)
-//..       PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
-//.. 
-//..    if (ARG3 != 0) {
-//..       PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
-//..       oldp = &old;
-//..    }
-//.. 
-//..    //jrs 20050207: what?!  how can this make any sense?
-//..    //if (VG_(is_kerror)(SYSRES))
-//..    //   return;
-//.. 
-//..    if (ARG2 != 0) {
-//..       struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
-//.. 
-//..       new.ksa_handler = oldnew->ksa_handler;
-//..       new.sa_flags = oldnew->sa_flags;
-//..       new.sa_restorer = oldnew->sa_restorer;
-//..       convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
-//..       newp = &new;
-//..    }
-//.. 
-//..    SET_RESULT( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
-//.. 
-//..    if (ARG3 != 0 && RES == 0) {
-//..       struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
-//.. 
-//..       oldold->ksa_handler = oldp->ksa_handler;
-//..       oldold->sa_flags = oldp->sa_flags;
-//..       oldold->sa_restorer = oldp->sa_restorer;
-//..       oldold->sa_mask = oldp->sa_mask.sig[0];
-//..    }
-//.. }
+   PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
+   PRE_REG_READ3(int, "sigaction",
+                 int, signum, const struct old_sigaction *, act,
+                 struct old_sigaction *, oldact);
 
-//.. POST(sys_sigaction)
-//.. {
-//..    if (RES == 0 && ARG3 != 0)
-//..       POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
-//.. }
+   newp = oldp = NULL;
+
+   if (ARG2 != 0) {
+      struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
+      PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
+      PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
+      PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
+      if (ML_(safe_to_deref)(sa,sizeof(sa)) 
+          && (sa->sa_flags & VKI_SA_RESTORER))
+         PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
+   }
+
+   if (ARG3 != 0) {
+      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
+      oldp = &old;
+   }
+
+   //jrs 20050207: what?!  how can this make any sense?
+   //if (VG_(is_kerror)(SYSRES))
+   //   return;
+
+   if (ARG2 != 0) {
+      struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
+
+      new.ksa_handler = oldnew->ksa_handler;
+      new.sa_flags = oldnew->sa_flags;
+      new.sa_restorer = oldnew->sa_restorer;
+      convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
+      newp = &new;
+   }
+
+   SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
+
+   if (ARG3 != 0 && SUCCESS && RES == 0) {
+      struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
+
+      oldold->ksa_handler = oldp->ksa_handler;
+      oldold->sa_flags = oldp->sa_flags;
+      oldold->sa_restorer = oldp->sa_restorer;
+      oldold->sa_mask = oldp->sa_mask.sig[0];
+   }
+}
+
+POST(sys_sigaction)
+{
+   vg_assert(SUCCESS);
+   if (RES == 0 && ARG3 != 0)
+      POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
+}
+
 
 #undef PRE
 #undef POST
 
-
 /* ---------------------------------------------------------------------
    The ppc32/Linux syscall table
    ------------------------------------------------------------------ */
@@ -1738,7 +1733,7 @@
 
    GENX_(__NR_getpgrp,           sys_getpgrp),           // 65
    GENX_(__NR_setsid,            sys_setsid),            // 66
-//..    PLAXY(__NR_sigaction,         sys_sigaction),         // 67
+   PLAXY(__NR_sigaction,         sys_sigaction),         // 67
 //..    //   (__NR_sgetmask,          sys_sgetmask),          // 68 */* (ANSI C)
 //..    //   (__NR_ssetmask,          sys_ssetmask),          // 69 */* (ANSI C)
 //.. 
diff --git a/coregrind/vki_unistd-ppc32-linux.h b/coregrind/vki_unistd-ppc32-linux.h
index d43f69c..190591e 100644
--- a/coregrind/vki_unistd-ppc32-linux.h
+++ b/coregrind/vki_unistd-ppc32-linux.h
@@ -96,7 +96,7 @@
 #define __NR_getppid			 64
 #define __NR_getpgrp			 65
 #define __NR_setsid			 66
-//#define __NR_sigaction		 67
+#define __NR_sigaction			 67
 //#define __NR_sgetmask			 68
 //#define __NR_ssetmask			 69
 //#define __NR_setreuid			 70
diff --git a/include/vki-ppc32-linux.h b/include/vki-ppc32-linux.h
index cc3d071..7f8b752 100644
--- a/include/vki-ppc32-linux.h
+++ b/include/vki-ppc32-linux.h
@@ -152,16 +152,16 @@
 #define VKI_SS_ONSTACK		1
 #define VKI_SS_DISABLE		2
 
-//.. struct vki_old_sigaction {
-//..         // [[Nb: a 'k' prefix is added to "sa_handler" because
-//..         // bits/sigaction.h (which gets dragged in somehow via signal.h)
-//..         // #defines it as something else.  Since that is done for glibc's
-//..         // purposes, which we don't care about here, we use our own name.]]
-//..         __vki_sighandler_t ksa_handler;
-//..         vki_old_sigset_t sa_mask;
-//..         unsigned long sa_flags;
-//..         __vki_sigrestore_t sa_restorer;
-//.. };
+struct vki_old_sigaction {
+        // [[Nb: a 'k' prefix is added to "sa_handler" because
+        // bits/sigaction.h (which gets dragged in somehow via signal.h)
+        // #defines it as something else.  Since that is done for glibc's
+        // purposes, which we don't care about here, we use our own name.]]
+        __vki_sighandler_t ksa_handler;
+        vki_old_sigset_t sa_mask;
+        unsigned long sa_flags;
+        __vki_sigrestore_t sa_restorer;
+};
 
 struct vki_sigaction {
         // [[See comment about extra 'k' above]]