]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Factor out some common code in m_syswrap.
authorNicholas Nethercote <njn@valgrind.org>
Thu, 10 Nov 2005 02:48:04 +0000 (02:48 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Thu, 10 Nov 2005 02:48:04 +0000 (02:48 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5062

coregrind/m_syswrap/priv_syswrap-linux.h
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c

index 5229d149d9956eb85c12eaf54e3b2ae390451776..6c871be817148c91828029d18e06ae2ffbab702c 100644 (file)
 
 /* requires #include "priv_types_n_macros.h" */
 
-// Run a thread from beginning to end. 
-extern VgSchedReturnCode ML_(thread_wrapper)(Word /*ThreadId*/ tid);
-
+// Clone-related functions
 extern Int  ML_(start_thread_NORETURN) ( void* arg );
-extern void ML_(run_a_thread_NORETURN) ( Word tidW );
 extern Addr ML_(allocstack)            ( ThreadId tid );
 extern void ML_(call_on_new_stack_0_1) ( Addr stack, Addr retaddr,
                                         void (*f)(Word), Word arg1 );
+extern SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
+                                   Int* parent_tidptr, Int* child_tidptr );
+
+
+// Linux-specific (but non-arch-specific) syscalls
 
 DECL_TEMPLATE(linux, sys_mount);
 DECL_TEMPLATE(linux, sys_oldumount);
index 67595b1a24c5e58ff6b4ccf7e457c7e53751862d..257820d39feea52c02b54ed2a246b207af72614d 100644 (file)
@@ -54,8 +54,7 @@
 
 
 /* ---------------------------------------------------------------------
-   Stacks, thread wrappers
-   Note.  Why is this stuff here?
+   clone() handling
    ------------------------------------------------------------------ */
 
 /* Call f(arg1), but first switch stacks, using 'stack' as the new
@@ -97,10 +96,6 @@ asm(
 "   ud2\n"                 // should never get here
 );
 
-/* ---------------------------------------------------------------------
-   clone() handling
-   ------------------------------------------------------------------ */
-
 /*
         Perform a clone system call.  clone is strange because it has
         fork()-like return-twice semantics, so it needs special
@@ -299,54 +294,6 @@ static SysRes do_clone ( ThreadId ptid,
 }
 
 
-/* Do a clone which is really a fork() */
-static SysRes do_fork_clone ( ThreadId tid, 
-                              ULong flags, Addr rsp, 
-                              Long* parent_tidptr, 
-                              Long* child_tidptr )
-{
-   vki_sigset_t fork_saved_mask;
-   vki_sigset_t mask;
-   SysRes       res;
-
-   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM 
-                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
-      return VG_(mk_SysRes_Error)( VKI_EINVAL );
-
-   /* Block all signals during fork, so that we can fix things up in
-      the child without being interrupted. */
-   VG_(sigfillset)(&mask);
-   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
-
-   /* Since this is the fork() form of clone, we don't need all that
-      VG_(clone) stuff - note that the last two arguments are the
-      opposite way round to x86 and ppc32 as the amd64 kernel expects
-      the arguments in a different order */
-   res = VG_(do_syscall5)( __NR_clone, flags, 
-                           (UWord)NULL, (UWord)parent_tidptr, 
-                           (UWord)child_tidptr, (UWord)NULL );
-
-   if (!res.isError && res.val == 0) {
-      /* child */
-      VG_(do_atfork_child)(tid);
-
-      /* restore signal mask */
-      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   } 
-   else 
-   if (!res.isError && res.val > 0) {
-      /* parent */
-      if (VG_(clo_trace_syscalls))
-         VG_(printf)("   clone(fork): process %d created child %d\n", 
-                      VG_(getpid)(), res.val);
-
-      /* restore signal mask */
-      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   }
-
-   return res;
-}
-
 /* ---------------------------------------------------------------------
    More thread stuff
    ------------------------------------------------------------------ */
@@ -468,9 +415,8 @@ PRE(sys_clone)
 
    case 0: /* plain fork */
       SET_STATUS_from_SysRes(
-         do_fork_clone(tid,
+         ML_(do_fork_clone)(tid,
                        cloneflags,      /* flags */
-                       (Addr)ARG2,      /* child ESP */
                        (Long *)ARG3,    /* parent_tidptr */
                        (Long *)ARG4));  /* child_tidptr */
       break;
index 0d203fcb0231b605f6dbc2f8204de7dd35aa8783..e1615c53311434d4545ff54e647941571f8028ee 100644 (file)
@@ -39,6 +39,7 @@
 #include "pub_core_libcfile.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
+#include "pub_core_libcsignal.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_tooliface.h"
 #include "pub_core_options.h"
 
 // Run a thread from beginning to end and return the thread's
 // scheduler-return-code.
-VgSchedReturnCode ML_(thread_wrapper)(Word /*ThreadId*/ tidW)
+static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
 {
    VgSchedReturnCode ret;
    ThreadId     tid = (ThreadId)tidW;
    ThreadState* tst = VG_(get_ThreadState)(tid);
 
    VG_(debugLog)(1, "syswrap-linux", 
-                    "ML_(thread_wrapper)(tid=%lld): entry\n", 
+                    "thread_wrapper(tid=%lld): entry\n", 
                     (ULong)tidW);
 
    vg_assert(tst->status == VgTs_Init);
@@ -90,7 +91,7 @@ VgSchedReturnCode ML_(thread_wrapper)(Word /*ThreadId*/ tidW)
    vg_assert(VG_(is_running_thread)(tid));
 
    VG_(debugLog)(1, "syswrap-linux", 
-                    "ML_(thread_wrapper)(tid=%lld): done\n", 
+                    "thread_wrapper(tid=%lld): exit\n", 
                     (ULong)tidW);
 
    /* Return to caller, still holding the lock. */
@@ -104,24 +105,22 @@ VgSchedReturnCode ML_(thread_wrapper)(Word /*ThreadId*/ tidW)
 
 /* Run a thread all the way to the end, then do appropriate exit actions
    (this is the last-one-out-turn-off-the-lights bit).  */
-void ML_(run_a_thread_NORETURN) ( Word tidW )
+static void run_a_thread_NORETURN ( Word tidW )
 {
    ThreadId          tid = (ThreadId)tidW;
    VgSchedReturnCode src;
    Int               c;
 
    VG_(debugLog)(1, "syswrap-linux", 
-                    "run_a_thread_NORETURN(tid=%lld): "
-                       "ML_(thread_wrapper) called\n",
-                       (ULong)tidW);
+                    "run_a_thread_NORETURN(tid=%lld): pre-thread_wrapper\n",
+                    (ULong)tidW);
 
    /* Run the thread all the way through. */
-   src = ML_(thread_wrapper)(tid);  
+   src = thread_wrapper(tid);  
 
    VG_(debugLog)(1, "syswrap-linux", 
-                    "run_a_thread_NORETURN(tid=%lld): "
-                       "ML_(thread_wrapper) done\n",
-                       (ULong)tidW);
+                    "run_a_thread_NORETURN(tid=%lld): post-thread_wrapper\n",
+                    (ULong)tidW);
 
    c = VG_(count_living_threads)();
    vg_assert(c >= 1); /* stay sane */
@@ -204,7 +203,7 @@ Int ML_(start_thread_NORETURN) ( void* arg )
    ThreadState* tst = (ThreadState*)arg;
    ThreadId     tid = tst->tid;
 
-   ML_(run_a_thread_NORETURN) ( (Word)tid );
+   run_a_thread_NORETURN ( (Word)tid );
    /*NOTREACHED*/
    vg_assert(0);
 }
@@ -275,10 +274,10 @@ void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
    vg_assert( VG_(count_living_threads)() == 1 );
 
    ML_(call_on_new_stack_0_1)( 
-      (Addr)sp,                    /* stack */
-      0,                           /* bogus return address */
-      ML_(run_a_thread_NORETURN),  /* fn to call */
-      (Word)tid                    /* arg to give it */
+      (Addr)sp,               /* stack */
+      0,                      /* bogus return address */
+      run_a_thread_NORETURN,  /* fn to call */
+      (Word)tid               /* arg to give it */
    );
 
    /*NOTREACHED*/
@@ -286,6 +285,62 @@ void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
 }
 
 
+/* Do a clone which is really a fork() */
+SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
+                            Int* parent_tidptr, Int* child_tidptr )
+{
+   vki_sigset_t fork_saved_mask;
+   vki_sigset_t mask;
+   SysRes       res;
+
+   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM 
+                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
+
+   /* Block all signals during fork, so that we can fix things up in
+      the child without being interrupted. */
+   VG_(sigfillset)(&mask);
+   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
+
+   /* Since this is the fork() form of clone, we don't need all that
+      VG_(clone) stuff */
+#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+   res = VG_(do_syscall5)( __NR_clone, flags, 
+                           (UWord)NULL, (UWord)parent_tidptr, 
+                           (UWord)NULL, (UWord)child_tidptr );
+#elif defined(VGP_amd64_linux)
+   /* note that the last two arguments are the opposite way round to x86 and
+      ppc32 as the amd64 kernel expects the arguments in a different order */
+   res = VG_(do_syscall5)( __NR_clone, flags, 
+                           (UWord)NULL, (UWord)parent_tidptr, 
+                           (UWord)child_tidptr, (UWord)NULL );
+#elif defined(VGP_ppc32_linux)
+#else
+# error Unknown platform
+#endif
+
+   if (!res.isError && res.val == 0) {
+      /* child */
+      VG_(do_atfork_child)(tid);
+
+      /* restore signal mask */
+      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
+   } 
+   else 
+   if (!res.isError && res.val > 0) {
+      /* parent */
+      if (VG_(clo_trace_syscalls))
+         VG_(printf)("   clone(fork): process %d created child %d\n", 
+                      VG_(getpid)(), res.val);
+
+      /* restore signal mask */
+      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
+   }
+
+   return res;
+}
+
+
 /* ---------------------------------------------------------------------
    PRE/POST wrappers for arch-generic, Linux-specific syscalls
    ------------------------------------------------------------------ */
index dc3ff04e756188447df48f78c5213def42192b02..e171a59080ea06fa1188d06d5b5dded7baaf46fe 100644 (file)
@@ -36,7 +36,7 @@
 #include "pub_core_libcassert.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
-#include "pub_core_libcsignal.h"
+//#include "pub_core_libcsignal.h"
 #include "pub_core_options.h"
 #include "pub_core_scheduler.h"
 #include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
@@ -54,8 +54,7 @@
 
 
 /* ---------------------------------------------------------------------
-   Stacks, thread wrappers, clone
-   Note.  Why is this stuff here?
+   clone() handling
    ------------------------------------------------------------------ */
 
 /* Call f(arg1), but first switch stacks, using 'stack' as the new
@@ -113,10 +112,6 @@ asm(
 );
 
 
-/* ---------------------------------------------------------------------
-   clone() handling
-   ------------------------------------------------------------------ */
-
 /*
         Perform a clone system call.  clone is strange because it has
         fork()-like return-twice semantics, so it needs special
@@ -352,51 +347,6 @@ static SysRes do_clone ( ThreadId ptid,
 }
 
 
-/* Do a clone which is really a fork() */
-static SysRes do_fork_clone( ThreadId tid,
-                             UInt flags, Addr sp,
-                             Int* parent_tidptr,
-                             Int* child_tidptr )
-{
-   vki_sigset_t fork_saved_mask;
-   vki_sigset_t mask;
-   SysRes       res;
-
-   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM 
-                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
-      return VG_(mk_SysRes_Error)( VKI_EINVAL );
-
-   /* Block all signals during fork, so that we can fix things up in
-      the child without being interrupted. */
-   VG_(sigfillset)(&mask);
-   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
-
-   /* Since this is the fork() form of clone, we don't need all that
-      VG_(clone) stuff */
-   res = VG_(do_syscall5)( __NR_clone, flags, 
-                           (UWord)NULL, (UWord)parent_tidptr, 
-                           (UWord)NULL, (UWord)child_tidptr );
-
-   if (!res.isError && res.val == 0) {
-      /* child */
-      VG_(do_atfork_child)(tid);
-
-      /* restore signal mask */
-      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   } else 
-   if (!res.isError && res.val > 0) {
-      /* parent */
-      if (VG_(clo_trace_syscalls))
-         VG_(printf)("   clone(fork): process %d created child %d\n", 
-                      VG_(getpid)(), res.val);
-
-      /* restore signal mask */
-      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   }
-
-   return res;
-}
-
 
 /* ---------------------------------------------------------------------
    More thread stuff
@@ -1023,9 +973,8 @@ PRE(sys_clone)
 
    case 0: /* plain fork */
       SET_STATUS_from_SysRes(
-         do_fork_clone(tid,
+         ML_(do_fork_clone)(tid,
                        cloneflags,      /* flags */
-                       (Addr)ARG2,      /* child SP */
                        (Int *)ARG3,     /* parent_tidptr */
                        (Int *)ARG5));   /* child_tidptr */
       break;
index 6ea89dafda41d71e33c35cc5922b56bdcd50010f..f5c00ac591a332ed7b5f038a1445cccdfbff9188 100644 (file)
@@ -62,8 +62,7 @@
 
 
 /* ---------------------------------------------------------------------
-   Stacks, thread wrappers
-   Note.  Why is this stuff here?
+   clone() handling
    ------------------------------------------------------------------ */
 
 /* Call f(arg1), but first switch stacks, using 'stack' as the new
@@ -98,10 +97,6 @@ asm(
 );
 
 
-/* ---------------------------------------------------------------------
-   clone() handling
-   ------------------------------------------------------------------ */
-
 /*
         Perform a clone system call.  clone is strange because it has
         fork()-like return-twice semantics, so it needs special
@@ -319,52 +314,6 @@ static SysRes do_clone ( ThreadId ptid,
 }
 
 
-/* Do a clone which is really a fork() */
-static SysRes do_fork_clone ( ThreadId tid, 
-                              UInt flags, Addr esp, 
-                              Int* parent_tidptr, 
-                              Int* child_tidptr )
-{
-   vki_sigset_t fork_saved_mask;
-   vki_sigset_t mask;
-   SysRes       res;
-
-   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM 
-                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
-      return VG_(mk_SysRes_Error)( VKI_EINVAL );
-
-   /* Block all signals during fork, so that we can fix things up in
-      the child without being interrupted. */
-   VG_(sigfillset)(&mask);
-   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
-
-   /* Since this is the fork() form of clone, we don't need all that
-      VG_(clone) stuff */
-   res = VG_(do_syscall5)( __NR_clone, flags, 
-                           (UWord)NULL, (UWord)parent_tidptr, 
-                           (UWord)NULL, (UWord)child_tidptr );
-
-   if (!res.isError && res.val == 0) {
-      /* child */
-      VG_(do_atfork_child)(tid);
-
-      /* restore signal mask */
-      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   } 
-   else 
-   if (!res.isError && res.val > 0) {
-      /* parent */
-      if (VG_(clo_trace_syscalls))
-         VG_(printf)("   clone(fork): process %d created child %d\n", 
-                      VG_(getpid)(), res.val);
-
-      /* restore signal mask */
-      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   }
-
-   return res;
-}
-
 /* ---------------------------------------------------------------------
    LDT/GDT simulation
    ------------------------------------------------------------------ */
@@ -945,9 +894,8 @@ PRE(sys_clone)
 
    case 0: /* plain fork */
       SET_STATUS_from_SysRes(
-         do_fork_clone(tid,
+         ML_(do_fork_clone)(tid,
                        cloneflags,      /* flags */
-                       (Addr)ARG2,      /* child ESP */
                        (Int *)ARG3,     /* parent_tidptr */
                        (Int *)ARG5));   /* child_tidptr */
       break;