From: Nicholas Nethercote Date: Thu, 10 Nov 2005 02:48:04 +0000 (+0000) Subject: Factor out some common code in m_syswrap. X-Git-Tag: svn/VALGRIND_3_1_0~170 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a58b97fbbb209e33f64dbbc7aeb76f135a51eee;p=thirdparty%2Fvalgrind.git Factor out some common code in m_syswrap. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5062 --- diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index 5229d149d9..6c871be817 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -33,14 +33,16 @@ /* 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); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 67595b1a24..257820d39f 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -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; diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 0d203fcb02..e1615c5331 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -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" @@ -55,14 +56,14 @@ // 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 ------------------------------------------------------------------ */ diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index dc3ff04e75..e171a59080 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -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; diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 6ea89dafda..f5c00ac591 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -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;