[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