]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Write return address for threads in assembly so we can reliably
authorJulian Seward <jseward@acm.org>
Sat, 13 Apr 2002 00:08:51 +0000 (00:08 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 13 Apr 2002 00:08:51 +0000 (00:08 +0000)
grab their return values.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@58

coregrind/vg_constants.h
coregrind/vg_helpers.S
coregrind/vg_include.h
coregrind/vg_scheduler.c
vg_constants.h
vg_helpers.S
vg_include.h
vg_scheduler.c

index 9fb6a237814cf33946176f4bfe673eef891cef20..b4e359b3834036a924cf6474f16af90080f28644 100644 (file)
 
 /* Assembly code stubs make these requests ... */
 #define VG_USERREQ__SIGNAL_RETURNS          0x4001
-#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4002 
+#define VG_USERREQ__PTHREAD_RETURNS         0x4002
+#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4003
 
 #endif /* ndef __VG_INCLUDE_H */
 
index 4d1f8c26297052f2a1d7359895570073fa8bd4ad..e0afa6c0818bcf7c63ea15ab8726f3b0d8da9080 100644 (file)
@@ -68,6 +68,37 @@ signalreturn_bogusRA_panic_msg:
 .text  
        
 
+
+.global VG_(pthreadreturn_bogusRA)
+VG_(pthreadreturn_bogusRA):
+       subl    $20, %esp       # allocate arg block
+       movl    %esp, %edx      # %edx == &_zzq_args[0]
+       movl    $VG_USERREQ__PTHREAD_RETURNS, 0(%edx)   # request
+       movl    %eax, 4(%edx)   # arg1 == thread return value
+       movl    $0, 8(%edx)     # arg2
+       movl    $0, 12(%edx)    # arg3
+       movl    $0, 16(%edx)    # arg4
+       movl    %edx, %eax
+       # and now the magic sequence itself:
+       roll $29, %eax
+       roll $3, %eax
+       rorl $27, %eax
+       rorl $5, %eax
+       roll $13, %eax
+       roll $19, %eax
+       # should never get here
+       pushl   $pthreadreturn_bogusRA_panic_msg
+       call    VG_(panic)
+       
+.data
+pthreadreturn_bogusRA_panic_msg:
+.ascii "vg_pthreadreturn_bogusRA: VG_USERREQ__PTHREAD_RETURNS was missed"
+.byte  0
+.text  
+       
+
+
+
        
 /* ------------------ REAL CPU HELPERS ------------------ */
 /* The rest of this lot run on the real CPU. */
index 0833cae833a0f3a079a4539dd7dc832823129c8f..52706e0395546363d6d14e3a417d792db02d1ca3 100644 (file)
@@ -400,19 +400,19 @@ extern Bool  VG_(is_empty_arena) ( ArenaId aid );
 
 
 #define VG_USERREQ__PTHREAD_CREATE          0x3001
-#define VG_USERREQ__PTHREAD_CREATE_BOGUSRA  0x3002
-#define VG_USERREQ__PTHREAD_JOIN            0x3003
-#define VG_USERREQ__PTHREAD_GET_THREADID    0x3004
-#define VG_USERREQ__PTHREAD_MUTEX_INIT      0x3005
-#define VG_USERREQ__PTHREAD_MUTEX_LOCK      0x3006
-#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK    0x3007
-#define VG_USERREQ__PTHREAD_MUTEX_DESTROY   0x3008
-#define VG_USERREQ__PTHREAD_CANCEL          0x3009
+#define VG_USERREQ__PTHREAD_JOIN            0x3002
+#define VG_USERREQ__PTHREAD_GET_THREADID    0x3003
+#define VG_USERREQ__PTHREAD_MUTEX_INIT      0x3004
+#define VG_USERREQ__PTHREAD_MUTEX_LOCK      0x3005
+#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK    0x3006
+#define VG_USERREQ__PTHREAD_MUTEX_DESTROY   0x3007
+#define VG_USERREQ__PTHREAD_CANCEL          0x3008
 
 /* 
 In vg_constants.h:
 #define VG_USERREQ__SIGNAL_RETURNS          0x4001
-#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4002 
+#define VG_USERREQ__PTHREAD_RETURNS         0x4002
+#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4003
 */
 
 
@@ -1520,8 +1520,9 @@ extern void VG_(helper_value_check2_fail);
 extern void VG_(helper_value_check1_fail);
 extern void VG_(helper_value_check0_fail);
 
-/* NOT A FUNCTION; a bogus RETURN ADDRESS. */
+/* NOT FUNCTIONS; these are bogus RETURN ADDRESS. */
 extern void VG_(signalreturn_bogusRA)( void );
+extern void VG_(pthreadreturn_bogusRA)( void );
 
 
 /* ---------------------------------------------------------------------
index e748db1709aef5928a3e120b86dcc82afd78aab4..ff1697c4d2af135751067e6f5acb2c6b92daefdd 100644 (file)
@@ -47,9 +47,6 @@ anyone at all!
 - signals interrupting read/write and nanosleep, and take notice
   of SA_RESTART or not
 
-- return bogus RA: %EAX trashed, so pthread_joiner gets nonsense
-  exit codes
-
 - when a thread is done mark its stack as noaccess 
 
 - make signal return and .fini call be detected via request mechanism
@@ -1182,20 +1179,6 @@ VgSchedReturnCode VG_(scheduler) ( void )
     typedef unsigned long int pthread_t;
 */
 
-/* RUNS ON SIMD CPU!
-   This is the return address that pthread_create uses.
-*/
-static
-void do_pthread_create_bogusRA ( void )
-{
-   /* Tell the scheduler that this thread has returned. */
-   Int res;
-   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
-                           VG_USERREQ__PTHREAD_CREATE_BOGUSRA,
-                           0, 0, 0, 0);
-   VG_(panic)("do_pthread_create_bogusRA: shouldn't be still alive!");
-}
-
 
 static
 void do_pthread_cancel ( ThreadId  tid_canceller,
@@ -1211,17 +1194,18 @@ void do_pthread_cancel ( ThreadId  tid_canceller,
       print_sched_event(tid_cancellee, msg_buf);
    }
    vg_threads[tid_cancellee].m_eax  = (UInt)PTHREAD_CANCELED;
-   vg_threads[tid_cancellee].m_eip  = (UInt)&do_pthread_create_bogusRA;
+   vg_threads[tid_cancellee].m_eip  = (UInt)&VG_(pthreadreturn_bogusRA);
    vg_threads[tid_cancellee].status = VgTs_Runnable;
 }
 
 
 
 /* Thread tid is exiting, by returning from the function it was
-   created with.  The main complication here is to resume any thread
-   waiting to join with this one. */
+   created with.  Or possibly due to pthread_exit or cancellation.
+   The main complication here is to resume any thread waiting to join
+   with this one. */
 static 
-void do_pthread_create_exit_by_returning ( ThreadId tid )
+void handle_pthread_return ( ThreadId tid, void* retval )
 {
    ThreadId jnr; /* joiner, the thread calling pthread_join. */
    UInt*    jnr_args;
@@ -1233,7 +1217,7 @@ void do_pthread_create_exit_by_returning ( ThreadId tid )
    vg_assert(tid >= 0 && tid < VG_N_THREADS);
    vg_assert(vg_threads[tid].status != VgTs_Empty);
 
-   vg_threads[tid].retval = (void*)vg_threads[tid].m_eax;
+   vg_threads[tid].retval = retval;
 
    if (vg_threads[tid].joiner == VG_INVALID_THREADID) {
       /* No one has yet done a join on me */
@@ -1401,7 +1385,7 @@ void do_pthread_create ( ThreadId parent_tid,
 
    /* push (magical) return address */
    vg_threads[tid].m_esp -= 4;
-   * (UInt*)(vg_threads[tid].m_esp) = (UInt)do_pthread_create_bogusRA;
+   * (UInt*)(vg_threads[tid].m_esp) = (UInt)VG_(pthreadreturn_bogusRA);
 
    if (VG_(clo_instrument))
       VGM_(make_readable)( vg_threads[tid].m_esp, 2 * 4 );
@@ -1687,8 +1671,8 @@ void do_nontrivial_clientreq ( ThreadId tid )
                             (void*)arg[4] );
          break;
 
-      case VG_USERREQ__PTHREAD_CREATE_BOGUSRA:
-         do_pthread_create_exit_by_returning( tid );
+      case VG_USERREQ__PTHREAD_RETURNS:
+         handle_pthread_return( tid, (void*)arg[1] );
          break;
 
       case VG_USERREQ__PTHREAD_JOIN:
index 9fb6a237814cf33946176f4bfe673eef891cef20..b4e359b3834036a924cf6474f16af90080f28644 100644 (file)
 
 /* Assembly code stubs make these requests ... */
 #define VG_USERREQ__SIGNAL_RETURNS          0x4001
-#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4002 
+#define VG_USERREQ__PTHREAD_RETURNS         0x4002
+#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4003
 
 #endif /* ndef __VG_INCLUDE_H */
 
index 4d1f8c26297052f2a1d7359895570073fa8bd4ad..e0afa6c0818bcf7c63ea15ab8726f3b0d8da9080 100644 (file)
@@ -68,6 +68,37 @@ signalreturn_bogusRA_panic_msg:
 .text  
        
 
+
+.global VG_(pthreadreturn_bogusRA)
+VG_(pthreadreturn_bogusRA):
+       subl    $20, %esp       # allocate arg block
+       movl    %esp, %edx      # %edx == &_zzq_args[0]
+       movl    $VG_USERREQ__PTHREAD_RETURNS, 0(%edx)   # request
+       movl    %eax, 4(%edx)   # arg1 == thread return value
+       movl    $0, 8(%edx)     # arg2
+       movl    $0, 12(%edx)    # arg3
+       movl    $0, 16(%edx)    # arg4
+       movl    %edx, %eax
+       # and now the magic sequence itself:
+       roll $29, %eax
+       roll $3, %eax
+       rorl $27, %eax
+       rorl $5, %eax
+       roll $13, %eax
+       roll $19, %eax
+       # should never get here
+       pushl   $pthreadreturn_bogusRA_panic_msg
+       call    VG_(panic)
+       
+.data
+pthreadreturn_bogusRA_panic_msg:
+.ascii "vg_pthreadreturn_bogusRA: VG_USERREQ__PTHREAD_RETURNS was missed"
+.byte  0
+.text  
+       
+
+
+
        
 /* ------------------ REAL CPU HELPERS ------------------ */
 /* The rest of this lot run on the real CPU. */
index 0833cae833a0f3a079a4539dd7dc832823129c8f..52706e0395546363d6d14e3a417d792db02d1ca3 100644 (file)
@@ -400,19 +400,19 @@ extern Bool  VG_(is_empty_arena) ( ArenaId aid );
 
 
 #define VG_USERREQ__PTHREAD_CREATE          0x3001
-#define VG_USERREQ__PTHREAD_CREATE_BOGUSRA  0x3002
-#define VG_USERREQ__PTHREAD_JOIN            0x3003
-#define VG_USERREQ__PTHREAD_GET_THREADID    0x3004
-#define VG_USERREQ__PTHREAD_MUTEX_INIT      0x3005
-#define VG_USERREQ__PTHREAD_MUTEX_LOCK      0x3006
-#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK    0x3007
-#define VG_USERREQ__PTHREAD_MUTEX_DESTROY   0x3008
-#define VG_USERREQ__PTHREAD_CANCEL          0x3009
+#define VG_USERREQ__PTHREAD_JOIN            0x3002
+#define VG_USERREQ__PTHREAD_GET_THREADID    0x3003
+#define VG_USERREQ__PTHREAD_MUTEX_INIT      0x3004
+#define VG_USERREQ__PTHREAD_MUTEX_LOCK      0x3005
+#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK    0x3006
+#define VG_USERREQ__PTHREAD_MUTEX_DESTROY   0x3007
+#define VG_USERREQ__PTHREAD_CANCEL          0x3008
 
 /* 
 In vg_constants.h:
 #define VG_USERREQ__SIGNAL_RETURNS          0x4001
-#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4002 
+#define VG_USERREQ__PTHREAD_RETURNS         0x4002
+#define VG_USERREQ__SHUTDOWN_VALGRIND       0x4003
 */
 
 
@@ -1520,8 +1520,9 @@ extern void VG_(helper_value_check2_fail);
 extern void VG_(helper_value_check1_fail);
 extern void VG_(helper_value_check0_fail);
 
-/* NOT A FUNCTION; a bogus RETURN ADDRESS. */
+/* NOT FUNCTIONS; these are bogus RETURN ADDRESS. */
 extern void VG_(signalreturn_bogusRA)( void );
+extern void VG_(pthreadreturn_bogusRA)( void );
 
 
 /* ---------------------------------------------------------------------
index e748db1709aef5928a3e120b86dcc82afd78aab4..ff1697c4d2af135751067e6f5acb2c6b92daefdd 100644 (file)
@@ -47,9 +47,6 @@ anyone at all!
 - signals interrupting read/write and nanosleep, and take notice
   of SA_RESTART or not
 
-- return bogus RA: %EAX trashed, so pthread_joiner gets nonsense
-  exit codes
-
 - when a thread is done mark its stack as noaccess 
 
 - make signal return and .fini call be detected via request mechanism
@@ -1182,20 +1179,6 @@ VgSchedReturnCode VG_(scheduler) ( void )
     typedef unsigned long int pthread_t;
 */
 
-/* RUNS ON SIMD CPU!
-   This is the return address that pthread_create uses.
-*/
-static
-void do_pthread_create_bogusRA ( void )
-{
-   /* Tell the scheduler that this thread has returned. */
-   Int res;
-   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
-                           VG_USERREQ__PTHREAD_CREATE_BOGUSRA,
-                           0, 0, 0, 0);
-   VG_(panic)("do_pthread_create_bogusRA: shouldn't be still alive!");
-}
-
 
 static
 void do_pthread_cancel ( ThreadId  tid_canceller,
@@ -1211,17 +1194,18 @@ void do_pthread_cancel ( ThreadId  tid_canceller,
       print_sched_event(tid_cancellee, msg_buf);
    }
    vg_threads[tid_cancellee].m_eax  = (UInt)PTHREAD_CANCELED;
-   vg_threads[tid_cancellee].m_eip  = (UInt)&do_pthread_create_bogusRA;
+   vg_threads[tid_cancellee].m_eip  = (UInt)&VG_(pthreadreturn_bogusRA);
    vg_threads[tid_cancellee].status = VgTs_Runnable;
 }
 
 
 
 /* Thread tid is exiting, by returning from the function it was
-   created with.  The main complication here is to resume any thread
-   waiting to join with this one. */
+   created with.  Or possibly due to pthread_exit or cancellation.
+   The main complication here is to resume any thread waiting to join
+   with this one. */
 static 
-void do_pthread_create_exit_by_returning ( ThreadId tid )
+void handle_pthread_return ( ThreadId tid, void* retval )
 {
    ThreadId jnr; /* joiner, the thread calling pthread_join. */
    UInt*    jnr_args;
@@ -1233,7 +1217,7 @@ void do_pthread_create_exit_by_returning ( ThreadId tid )
    vg_assert(tid >= 0 && tid < VG_N_THREADS);
    vg_assert(vg_threads[tid].status != VgTs_Empty);
 
-   vg_threads[tid].retval = (void*)vg_threads[tid].m_eax;
+   vg_threads[tid].retval = retval;
 
    if (vg_threads[tid].joiner == VG_INVALID_THREADID) {
       /* No one has yet done a join on me */
@@ -1401,7 +1385,7 @@ void do_pthread_create ( ThreadId parent_tid,
 
    /* push (magical) return address */
    vg_threads[tid].m_esp -= 4;
-   * (UInt*)(vg_threads[tid].m_esp) = (UInt)do_pthread_create_bogusRA;
+   * (UInt*)(vg_threads[tid].m_esp) = (UInt)VG_(pthreadreturn_bogusRA);
 
    if (VG_(clo_instrument))
       VGM_(make_readable)( vg_threads[tid].m_esp, 2 * 4 );
@@ -1687,8 +1671,8 @@ void do_nontrivial_clientreq ( ThreadId tid )
                             (void*)arg[4] );
          break;
 
-      case VG_USERREQ__PTHREAD_CREATE_BOGUSRA:
-         do_pthread_create_exit_by_returning( tid );
+      case VG_USERREQ__PTHREAD_RETURNS:
+         handle_pthread_return( tid, (void*)arg[1] );
          break;
 
       case VG_USERREQ__PTHREAD_JOIN: