Cleanups:
- move things around so that each arch doesn't duplicate stuff to do with
VG_(do_thread_syscall)().
- enum PXState doesn't need to be visible outside vg_proxylwp.c
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3097 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/core.h b/coregrind/core.h
index 8445462..eae7980 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -1318,18 +1318,6 @@
Exports of vg_proxylwp.c
------------------------------------------------------------------ */
-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);
@@ -1872,14 +1860,53 @@
extern const UInt VGA_(syscall_table_size);
-
-extern const Addr vga_sys_before, vga_sys_restarted,
- vga_sys_after, vga_sys_done;
-
extern void VGA_(restart_syscall)(ThreadArchState* arch);
-extern void VGA_(thread_syscall)(Int syscallno, ThreadArchState* arch,
- enum PXState* state, enum PXState poststate);
+/* 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.
+
+ Freakin' horrible...
+*/
+extern const Addr VGA_(sys_before), VGA_(sys_restarted),
+ VGA_(sys_after), VGA_(sys_done);
+
+extern void VGA_(do_thread_syscall)(UWord sys,
+ UWord arg1, UWord arg2, UWord arg3,
+ UWord arg4, UWord arg5, UWord arg6,
+ UWord *result, /*enum PXState*/Int *statep,
+ /*enum PXState*/Int poststate);
/* ---------------------------------------------------------------------
Finally - autoconf-generated settings
diff --git a/coregrind/vg_proxylwp.c b/coregrind/vg_proxylwp.c
index ae3d1f3..83ee91d 100644
--- a/coregrind/vg_proxylwp.c
+++ b/coregrind/vg_proxylwp.c
@@ -31,6 +31,18 @@
#include "core.h"
+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,
PX_SetSigmask, /* sched->proxy; proxy->sched */
@@ -300,7 +312,7 @@
/* First look to see if the EIP is within our interesting ranges
near a syscall to work out what should happen. */
- if (vga_sys_before <= ip && ip <= vga_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
indicate a restart. This is not really any different from
@@ -308,7 +320,7 @@
the proxy and machine state here. */
vg_assert(px->state == PXS_RunSyscall);
vg_assert(SYSCALL_RET(px->tst->arch) == -VKI_ERESTARTSYS);
- } else if (vga_sys_after <= ip && ip <= vga_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
the usual register contains the correct syscall return value, and
@@ -337,6 +349,30 @@
return VG_(read)(result_recv, reply, size) == size;
}
+/* 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, ThreadArchState *arch,
+ enum PXState *state , enum PXState poststate)
+{
+ VGA_(do_thread_syscall)(syscallno, // syscall no.
+ arch->vex.guest_EBX, // arg 1
+ arch->vex.guest_ECX, // arg 2
+ arch->vex.guest_EDX, // arg 3
+ arch->vex.guest_ESI, // arg 4
+ arch->vex.guest_EDI, // arg 5
+ arch->vex.guest_EBP, // arg 6
+ (UWord*)&arch->vex.guest_EAX, // result
+ state, // state to update
+ poststate); // state when syscall has finished
+}
+
+
+
/* Proxy LWP thread. This is run as a separate cloned() thread, so it
MUST NOT touch any core Valgrind data structures directly: the only
exception is while we're running a PX_RunSyscall command, we may
@@ -620,8 +656,7 @@
/* ST:4 */
- VGA_(thread_syscall)(syscallno, &tst->arch,
- &px->state, PXS_SysDone);
+ thread_syscall(syscallno, &tst->arch, &px->state, PXS_SysDone);
/* ST:5 */
diff --git a/coregrind/x86-linux/syscalls.c b/coregrind/x86-linux/syscalls.c
index 97aede5..e5cedbe 100644
--- a/coregrind/x86-linux/syscalls.c
+++ b/coregrind/x86-linux/syscalls.c
@@ -30,57 +30,20 @@
#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);
-
+// See the comment accompanying the declaration of VGA_(thread_syscall)() in
+// coregrind/core.h for an explanation of what this does, and why.
asm(
".text\n"
-" .type do_thread_syscall,@function\n"
+" .type vgArch_do_thread_syscall,@function\n"
-"do_thread_syscall:\n"
+".globl vgArch_do_thread_syscall\n"
+"vgArch_do_thread_syscall:\n"
" push %esi\n"
" push %edi\n"
" push %ebx\n"
" push %ebp\n"
-".vga_sys_before:\n"
+".vgArch_sys_before:\n"
" movl 16+ 4(%esp),%eax\n" /* syscall */
" movl 16+ 8(%esp),%ebx\n" /* arg1 */
" movl 16+12(%esp),%ecx\n" /* arg2 */
@@ -88,9 +51,9 @@
" 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"
+".vgArch_sys_restarted:\n"
" int $0x80\n"
-".vga_sys_after:\n"
+".vgArch_sys_after:\n"
" movl 16+32(%esp),%ebx\n" /* ebx = Int *res */
" movl %eax, (%ebx)\n" /* write the syscall retval */
@@ -101,51 +64,27 @@
" 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 */
+".vgArch_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"
+" .size vgArch_do_thread_syscall,.-vgArch_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"
+" .globl vgArch_sys_before\n"
+"vgArch_sys_before: .long .vgArch_sys_before\n"
+" .globl vgArch_sys_restarted\n"
+"vgArch_sys_restarted: .long .vgArch_sys_restarted\n"
+" .globl vgArch_sys_after\n"
+"vgArch_sys_after: .long .vgArch_sys_after\n"
+" .globl vgArch_sys_done\n"
+"vgArch_sys_done: .long .vgArch_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, ThreadArchState *arch,
- enum PXState *state , enum PXState poststate)
-{
- do_thread_syscall(syscallno, // syscall no.
- arch->vex.guest_EBX, // arg 1
- arch->vex.guest_ECX, // arg 2
- arch->vex.guest_EDX, // arg 3
- arch->vex.guest_ESI, // arg 4
- arch->vex.guest_EDI, // arg 5
- arch->vex.guest_EBP, // arg 6
- &arch->vex.guest_EAX, // result
- state, // state to update
- poststate); // state when syscall has finished
-}
-
-
-
// Back up to restart a system call.
void VGA_(restart_syscall)(ThreadArchState *arch)
{