[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    valgrind/coregrind
From:       Nicholas Nethercote <njn25 () cam ! ac ! uk>
Date:       2004-10-18 17:36:40
Message-ID: 20041018173640.D24DE16BE3 () office ! kde ! org
[Download RAW message or body]

CVS commit by nethercote: 

Arch-abstraction:
- factor out the horrid thread_syscall() function, which is written in assembly
  code.


  M +19 -1     core.h   1.41
  M +3 -123    vg_proxylwp.c   1.24
  M +1 -1      x86-linux/ldt.c   1.2
  M +118 -1    x86-linux/syscalls.c   1.2


--- valgrind/coregrind/core.h  #1.40:1.41
@@ -1340,4 +1340,16 @@ extern REGPARM(1)
    ------------------------------------------------------------------ */
 
+enum PXState
+{
+   PXS_BAD = -1,
+   PXS_WaitReq,         /* waiting for a request */
+   PXS_RunSyscall,      /* running a syscall */
+   PXS_IntReply,        /* request interrupted - need to send reply */
+   PXS_SysDone,         /* small window between syscall
+                           complete and results written out */
+   PXS_SigACK,          /* waiting for a signal ACK */
+};
+
+
 /* Issue a syscall for thread tid */
 extern Int  VG_(sys_issue)(int tid);
@@ -1525,5 +1537,11 @@ extern Int  VGA_(pop_signal_frame)  ( Th
 // ---------------------------------------------------------------------
 
-void VGA_(restart_syscall)(arch_thread_t *tst);
+extern const Addr vga_sys_before, vga_sys_restarted,
+                  vga_sys_after, vga_sys_done;
+
+extern void VGA_(restart_syscall)(arch_thread_t* tst);
+
+extern void VGA_(thread_syscall)(Int syscallno, ThreadState* tst, 
+                                 enum PXState* state, enum PXState poststate);
 
 /* ---------------------------------------------------------------------

--- valgrind/coregrind/vg_proxylwp.c  #1.23:1.24
@@ -32,51 +32,4 @@
 #include "core.h"
 
-/* We need our own copy of VG_(do_syscall)() to handle a special
-   race-condition.  If we've got signals unblocked, and we take a
-   signal in the gap either just before or after the syscall, we may
-   end up not running the syscall at all, or running it more than
-   once.
-
-   The solution is to make the signal handler derive the proxy's
-   precise state by looking to see which eip it is executing at
-   exception time.
-
-   Ranges:
-
-   sys_before ... sys_restarted:
-        Setting up register arguments and running state.  If
-        interrupted, then the syscall should be considered to return
-        ERESTARTSYS.
-
-   sys_restarted:
-        If interrupted and eip==sys_restarted, then either the syscall
-        was about to start running, or it has run, was interrupted and
-        the kernel wants to restart it.  eax still contains the
-        syscall number.  If interrupted, then the syscall return value
-        should be ERESTARTSYS.
-
-   sys_after:
-        If interrupted and eip==sys_after, the syscall either just
-        finished, or it was interrupted and the kernel doesn't want to
-        restart it.  Either way, eax equals the correct return value
-        (either the actual return value, or EINTR).
-
-   sys_after ... sys_done:
-        System call is complete, but the state hasn't been updated,
-        nor has the result been written back.  eax contains the return
-        value.
-*/
-
-enum PXState
-{
-   PXS_BAD = -1,
-   PXS_WaitReq,         /* waiting for a request */
-   PXS_RunSyscall,      /* running a syscall */
-   PXS_IntReply,        /* request interrupted - need to send reply */
-   PXS_SysDone,         /* small window between syscall
-                           complete and results written out */
-   PXS_SigACK,          /* waiting for a signal ACK */
-};
-
 enum RequestType {
    PX_BAD = -1,
@@ -89,77 +42,4 @@ enum RequestType {
 };
 
-extern void do_thread_syscall(Int sys, 
-                              Int arg1, Int arg2, Int arg3, Int arg4, Int arg5, Int arg6,
-                              Int *result, enum PXState *statep, enum PXState poststate);
-
-asm(
-".text\n"
-"       .type do_thread_syscall,@function\n"
-
-"do_thread_syscall:\n"
-"       push    %esi\n"
-"       push    %edi\n"
-"       push    %ebx\n"
-"       push    %ebp\n"
-".sys_before:\n"
-"       movl    16+ 4(%esp),%eax\n" /* syscall */
-"       movl    16+ 8(%esp),%ebx\n" /* arg1 */
-"       movl    16+12(%esp),%ecx\n" /* arg2 */
-"       movl    16+16(%esp),%edx\n" /* arg3 */
-"       movl    16+20(%esp),%esi\n" /* arg4 */
-"       movl    16+24(%esp),%edi\n" /* arg5 */
-"       movl    16+28(%esp),%ebp\n" /* arg6 */
-".sys_restarted:\n"
-"       int     $0x80\n"
-".sys_after:\n"
-"       movl    16+32(%esp),%ebx\n"     /* ebx = Int *res */
-"       movl    %eax, (%ebx)\n"         /* write the syscall retval */
-
-"       movl    16+36(%esp),%ebx\n"     /* ebx = enum PXState * */
-"       testl   %ebx, %ebx\n"
-"       jz      1f\n"
-
-"       movl    16+40(%esp),%ecx\n"     /* write the post state (must be after retval write) */
-"       movl    %ecx,(%ebx)\n"
-
-".sys_done:\n"                          /* OK, all clear from here */
-"1:     popl    %ebp\n"
-"       popl    %ebx\n"
-"       popl    %edi\n"
-"       popl    %esi\n"
-"       ret\n"
-"       .size do_thread_syscall,.-do_thread_syscall\n"
-".previous\n"
-
-".section .rodata\n"
-"sys_before:    .long   .sys_before\n"
-"sys_restarted: .long   .sys_restarted\n"
-"sys_after:     .long   .sys_after\n"
-"sys_done:      .long   .sys_done\n"
-".previous\n"
-);
-extern const Addr sys_before, sys_restarted, sys_after, sys_done;
-
-/* Run a syscall for a particular thread, getting the arguments from
-   the thread's registers, and returning the result in the thread's
-   eax.
-
-   Assumes that the only thread state which matters is the contents of
-   %eax-%ebp and the return value in %eax.
- */
-static void thread_syscall(Int syscallno, ThreadState *tst, 
-                           enum PXState *state , enum PXState poststate)
-{
-   do_thread_syscall(syscallno,   /* syscall no. */
-                     tst->arch.m_ebx,  /* arg 1 */
-                     tst->arch.m_ecx,  /* arg 2 */
-                     tst->arch.m_edx,  /* arg 3 */
-                     tst->arch.m_esi,  /* arg 4 */
-                     tst->arch.m_edi,  /* arg 5 */
-                     tst->arch.m_ebp,  /* arg 6 */
-                     &tst->arch.m_eax, /* result */
-                     state,       /* state to update */
-                     poststate);  /* state when syscall has finished */
-}
 
 #define VG_PROXY_MAGIC  0xef83b192
@@ -421,5 +301,5 @@ void VG_(proxy_handlesig)(const vki_ksig
    /* First look to see if the EIP is within our interesting ranges
       near a syscall to work out what should happen. */
-   if (sys_before <= ip && ip <= sys_restarted) {
+   if (vga_sys_before <= ip && ip <= vga_sys_restarted) {
       /* We are before the syscall actually ran, or it did run and
          wants to be restarted.  Either way, set the return code to
@@ -429,5 +309,5 @@ void VG_(proxy_handlesig)(const vki_ksig
       vg_assert(px->state == PXS_RunSyscall);
       vg_assert(PLATFORM_SYSCALL_RET(px->tst->arch) == -VKI_ERESTARTSYS);
-   } else if (sys_after <= ip && ip <= sys_done) {
+   } else if (vga_sys_after <= ip && ip <= vga_sys_done) {
       /* We're after the syscall.  Either it was interrupted by the
          signal, or the syscall completed normally.  In either case
@@ -741,5 +621,5 @@ static Int proxylwp(void *v)
                /* ST:4 */
                
-               thread_syscall(syscallno, tst, &px->state, PXS_SysDone);
+               VGA_(thread_syscall)(syscallno, tst, &px->state, PXS_SysDone);
 
                /* ST:5 */

--- valgrind/coregrind/x86-linux/ldt.c  #1.1:1.2
@@ -1,5 +1,5 @@
 
 /*--------------------------------------------------------------------*/
-/*--- Simulation of Local Descriptor Tables               vg_ldt.c ---*/
+/*--- Simulation of Local Descriptor Tables        x86-linux/ldt.c ---*/
 /*--------------------------------------------------------------------*/
 

--- valgrind/coregrind/x86-linux/syscalls.c  #1.1:1.2
@@ -1,5 +1,5 @@
 
 /*--------------------------------------------------------------------*/
-/*--- x86/Linux-specific syscalls, etc.                 syscalls.c ---*/
+/*--- x86/Linux-specific syscalls, etc.       x86-linux/syscalls.c ---*/
 /*--------------------------------------------------------------------*/
 
@@ -31,4 +31,121 @@
 #include "core.h"
 
+
+/* We need our own copy of VG_(do_syscall)() to handle a special
+   race-condition.  If we've got signals unblocked, and we take a
+   signal in the gap either just before or after the syscall, we may
+   end up not running the syscall at all, or running it more than
+   once.
+
+   The solution is to make the signal handler derive the proxy's
+   precise state by looking to see which eip it is executing at
+   exception time.
+
+   Ranges:
+
+   vga_sys_before ... vga_sys_restarted:
+        Setting up register arguments and running state.  If
+        interrupted, then the syscall should be considered to return
+        ERESTARTSYS.
+
+   vga_sys_restarted:
+        If interrupted and eip==vga_sys_restarted, then either the syscall
+        was about to start running, or it has run, was interrupted and
+        the kernel wants to restart it.  eax still contains the
+        syscall number.  If interrupted, then the syscall return value
+        should be ERESTARTSYS.
+
+   vga_sys_after:
+        If interrupted and eip==vga_sys_after, the syscall either just
+        finished, or it was interrupted and the kernel doesn't want to
+        restart it.  Either way, eax equals the correct return value
+        (either the actual return value, or EINTR).
+
+   vga_sys_after ... vga_sys_done:
+        System call is complete, but the state hasn't been updated,
+        nor has the result been written back.  eax contains the return
+        value.
+*/
+extern void do_thread_syscall(Int sys, 
+                              Int arg1, Int arg2, Int arg3, Int arg4,
+                              Int arg5, Int arg6,
+                              Int *result, enum PXState *statep,
+                              enum PXState poststate);
+
+asm(
+".text\n"
+"       .type do_thread_syscall,@function\n"
+
+"do_thread_syscall:\n"
+"       push    %esi\n"
+"       push    %edi\n"
+"       push    %ebx\n"
+"       push    %ebp\n"
+".vga_sys_before:\n"
+"       movl    16+ 4(%esp),%eax\n" /* syscall */
+"       movl    16+ 8(%esp),%ebx\n" /* arg1 */
+"       movl    16+12(%esp),%ecx\n" /* arg2 */
+"       movl    16+16(%esp),%edx\n" /* arg3 */
+"       movl    16+20(%esp),%esi\n" /* arg4 */
+"       movl    16+24(%esp),%edi\n" /* arg5 */
+"       movl    16+28(%esp),%ebp\n" /* arg6 */
+".vga_sys_restarted:\n"
+"       int     $0x80\n"
+".vga_sys_after:\n"
+"       movl    16+32(%esp),%ebx\n"     /* ebx = Int *res */
+"       movl    %eax, (%ebx)\n"         /* write the syscall retval */
+
+"       movl    16+36(%esp),%ebx\n"     /* ebx = enum PXState * */
+"       testl   %ebx, %ebx\n"
+"       jz      1f\n"
+
+"       movl    16+40(%esp),%ecx\n"     /* write the post state (must be after retval write) */
+"       movl    %ecx,(%ebx)\n"
+
+".vga_sys_done:\n"                              /* OK, all clear from here */
+"1:     popl    %ebp\n"
+"       popl    %ebx\n"
+"       popl    %edi\n"
+"       popl    %esi\n"
+"       ret\n"
+"       .size do_thread_syscall,.-do_thread_syscall\n"
+".previous\n"
+
+".section .rodata\n"
+"       .globl  vga_sys_before\n"
+"vga_sys_before:        .long   .vga_sys_before\n"
+"       .globl  vga_sys_restarted\n"
+"vga_sys_restarted:     .long   .vga_sys_restarted\n"
+"       .globl  vga_sys_after\n"
+"vga_sys_after: .long   .vga_sys_after\n"
+"       .globl  vga_sys_done\n"
+"vga_sys_done:  .long   .vga_sys_done\n"
+".previous\n"
+);
+
+/* Run a syscall for a particular thread, getting the arguments from
+   the thread's registers, and returning the result in the thread's
+   eax.
+
+   Assumes that the only thread state which matters is the contents of
+   %eax-%ebp and the return value in %eax.
+ */
+void VGA_(thread_syscall)(Int syscallno, ThreadState *tst, 
+                          enum PXState *state , enum PXState poststate)
+{
+   do_thread_syscall(syscallno,   /* syscall no. */
+                     tst->arch.m_ebx,  /* arg 1 */
+                     tst->arch.m_ecx,  /* arg 2 */
+                     tst->arch.m_edx,  /* arg 3 */
+                     tst->arch.m_esi,  /* arg 4 */
+                     tst->arch.m_edi,  /* arg 5 */
+                     tst->arch.m_ebp,  /* arg 6 */
+                     &tst->arch.m_eax, /* result */
+                     state,       /* state to update */
+                     poststate);  /* state when syscall has finished */
+}
+
+
+
 // Back up to restart a system call.
 void VGA_(restart_syscall)(arch_thread_t *tst)


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic