]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Moved the basic syscall stuff out of m_libcbase.c into a new module
authorNicholas Nethercote <njn@valgrind.org>
Fri, 17 Jun 2005 21:31:45 +0000 (21:31 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Fri, 17 Jun 2005 21:31:45 +0000 (21:31 +0000)
m_syscall.c.  Plus some associated cleanups.

Moved VG_(sigreturn) into m_signals.c and made it local.

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

22 files changed:
coregrind/Makefile.am
coregrind/core.h
coregrind/m_aspacemgr/aspacemgr.c
coregrind/m_libcassert.c
coregrind/m_libcbase.c
coregrind/m_libcfile.c
coregrind/m_libcmman.c
coregrind/m_libcproc.c
coregrind/m_libcsignal.c
coregrind/m_scheduler/scheduler.c
coregrind/m_signals.c
coregrind/m_syscall.c [new file with mode: 0644]
coregrind/m_syscalls/syscall-amd64-linux.S
coregrind/m_syscalls/syscall-arm-linux.S
coregrind/m_syscalls/syscall-x86-linux.S
coregrind/m_syscalls/syscalls-amd64-linux.c
coregrind/m_syscalls/syscalls-generic.c
coregrind/m_syscalls/syscalls-linux.c
coregrind/m_syscalls/syscalls-main.c
coregrind/m_syscalls/syscalls-x86-linux.c
coregrind/pub_core_libcbase.h
coregrind/pub_core_syscall.h [new file with mode: 0644]

index 213de7761aa7408efee30a27347f91efbb29895b..c9d65249ba644e23892cf1620520a316aed7e3f8 100644 (file)
@@ -114,6 +114,7 @@ stage2_SOURCES = \
        m_signals.c \
        m_skiplist.c \
        m_stacktrace.c \
+       m_syscall.c \
        m_threadmodel.c \
        m_tooliface.c \
        m_translate.c \
index ba956aa7f1688bd207360041f3d9cfac507d031a..febb40dd32e0fa4d19dcb35c41ae0431446ba6fe 100644 (file)
    A synonym for exit. */
 #define VG_USERREQ__LIBC_FREERES_DONE       0x3029
 
-/* ---------------------------------------------------------------------
-   Exports of vg_syscall.S
-   ------------------------------------------------------------------ */
-
-extern void VG_(sigreturn)(void);
-
 /* ---------------------------------------------------------------------
    Exports of vg_helpers.S
    ------------------------------------------------------------------ */
index def6a4180d751fb340bc2f716d5165a043613c01..a1eaf4447fb7ed6e84fcd4954a8ae75a415112f4 100644 (file)
@@ -40,6 +40,7 @@
 #include "pub_core_libcproc.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
+#include "pub_core_syscall.h"
 #include "pub_core_syscalls.h"
 #include "pub_core_tooliface.h"
 #include "pub_core_transtab.h"
index dea4f053f92ad59fafac58902b031096672b577b..d5825bdd21920a0a0005a388dd16cec4bd27faa4 100644 (file)
@@ -35,6 +35,7 @@
 #include "pub_core_libcproc.h"
 #include "pub_core_main.h"
 #include "pub_core_stacktrace.h"
+#include "pub_core_syscall.h"
 #include "pub_core_tooliface.h"
 #include "vki_unistd.h"
 
index 25884b5dd4fd0f4223880c534b048558be261855..1ab10d37d8701e566de2c0a3650b976cb2596cc9 100644 (file)
@@ -471,95 +471,6 @@ void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
    #undef SORT
 }
 
-/* ---------------------------------------------------------------------
-   A function for doing syscalls.
-   ------------------------------------------------------------------ */
-
-#if defined(VGP_x86_linux)
-extern UInt do_syscall_x86_linux_WRK (
-          UInt syscall_no, 
-          UInt a1, UInt a2, UInt a3,
-          UInt a4, UInt a5, UInt a6
-       );
-asm(
-"do_syscall_x86_linux_WRK:\n"
-"      push    %esi\n"
-"      push    %edi\n"
-"      push    %ebx\n"
-"      push    %ebp\n"
-"      movl    16+ 4(%esp),%eax\n"
-"      movl    16+ 8(%esp),%ebx\n"
-"      movl    16+12(%esp),%ecx\n"
-"      movl    16+16(%esp),%edx\n"
-"      movl    16+20(%esp),%esi\n"
-"      movl    16+24(%esp),%edi\n"
-"      movl    16+28(%esp),%ebp\n"
-"      int     $0x80\n"
-"      popl    %ebp\n"
-"      popl    %ebx\n"
-"      popl    %edi\n"
-"      popl    %esi\n"
-"      ret\n"
-);
-#endif
-
-
-#if defined(VGP_amd64_linux)
-/* Perform a Linux syscall with the "syscall" instruction.
-       
-   Incoming args (syscall number + up to 6 args) come in %rdi, %rsi,
-   %rdx, %rcx, %r8, %r9, and the last one on the stack (ie. the C
-   calling convention).
-
-   They are passed to the syscall in the regs %rdi, %rsi, %rdx, %r10,
-   %r8, %r9 (yes, really %r10, not %rcx), ie. the kernel's syscall
-   calling convention.
-
-   %rax holds the syscall number and gets the return value.  %rcx and
-   %r11 are clobbered by the syscall; no matter, they are caller-save
-   (the syscall clobbers no callee-save regs, so we don't have to do
-   any register saving/restoring).
-*/
-extern ULong do_syscall_amd64_linux_WRK (
-          ULong syscall_no, 
-          ULong a1, ULong a2, ULong a3,
-          ULong a4, ULong a5, ULong a6
-       );
-asm(
-"do_syscall_amd64_linux_WRK:\n"
-        /* Convert function calling convention --> syscall calling
-           convention */
-"      movq    %rdi, %rax\n"
-"      movq    %rsi, %rdi\n"
-"      movq    %rdx, %rsi\n"
-"      movq    %rcx, %rdx\n"
-"      movq    %r8,  %r10\n"
-"      movq    %r9,  %r8\n"
-"      movq    8(%rsp), %r9\n"  /* last arg from stack */
-"      syscall\n"
-"      ret\n"
-);
-#endif
-
-
-SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3, 
-                                      UWord a4, UWord a5, UWord a6 )
-{
-   SysRes res;
-
-#if defined(VGP_x86_linux)
-   UInt eax = do_syscall_x86_linux_WRK(sysno,a1,a2,a3,a4,a5,a6);
-   res = VG_(mk_SysRes_x86_linux)( eax );
-#elif defined(VGP_amd64_linux)
-   ULong rax = do_syscall_amd64_linux_WRK(sysno,a1,a2,a3,a4,a5,a6);
-   res = VG_(mk_SysRes_amd64_linux)( rax );
-#else
-#  error VG_(do_syscall): unimplemented on this platform
-#endif
-
-   return res;
-}
-
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index 3a044f5ec152a181e339be537be94b2a5ebba9da..aa217b2ed9eae0e0acee70de11837b4745ee86fd 100644 (file)
@@ -34,6 +34,7 @@
 #include "pub_core_libcfile.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
+#include "pub_core_syscall.h"
 #include "vki_unistd.h"
 
 /* ---------------------------------------------------------------------
index fc5e44f24d4f8cff9d50e23b158fc6306029aecf..d3c66f1b03b40e8c454d5bd8aa87506a4ae7af24 100644 (file)
@@ -35,6 +35,7 @@
 #include "pub_core_libcmman.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
+#include "pub_core_syscall.h"
 #include "vki_unistd.h"
 
 SysRes VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
index 021ff4eb8c041e3316aa26d66f45319fc2b446d2..bb6997cdbb462586464268788bd3ed4276bf92ed 100644 (file)
@@ -34,6 +34,7 @@
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
 #include "pub_core_mallocfree.h"
+#include "pub_core_syscall.h"
 #include "vki_unistd.h"
 
 /* ---------------------------------------------------------------------
index 3e1beccf97a6bfcf0ef2278c51912e54fde2c84b..b62e4887d734c0524eee34848470a92c1f3ef8a5 100644 (file)
@@ -32,6 +32,7 @@
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcsignal.h"
+#include "pub_core_syscall.h"
 #include "vki_unistd.h"
 
 /* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
index 49b07e015d025b9154b82f5a23c92e50c2b55228..4aa625fd83520f44fb1e657eeb764b1da482f14a 100644 (file)
@@ -77,6 +77,7 @@
 #include "pub_core_scheduler.h"
 #include "pub_core_signals.h"
 #include "pub_core_stacktrace.h"
+#include "pub_core_syscall.h"
 #include "pub_core_syscalls.h"
 #include "pub_core_tooliface.h"
 #include "pub_core_translate.h"
index e67debb0c101eb666e0343233617f73be640539d..34ceaf30ff2580d678c2a3d211b476f2c8f87a6f 100644 (file)
 #include "pub_core_signals.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_stacktrace.h"
+#include "pub_core_syscall.h"
 #include "pub_core_syscalls.h"
 #include "pub_core_tooliface.h"
+#include "vki_unistd.h"
 
 
 /* Define to give more sanity checking for signals. */
@@ -131,7 +133,7 @@ typedef struct SigQueue {
 #  define VGP_UCONTEXT_SYSCALL_NUM(uc)    ((uc)->uc_mcontext.eax)
 #  define VGP_UCONTEXT_SYSCALL_SYSRES(uc)                       \
       /* Convert the value in uc_mcontext.eax into a SysRes. */ \
-      VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
+      VG_(mk_SysRes)( (uc)->uc_mcontext.eax )
 
 #elif defined(VGP_amd64_linux)
 #  define VGP_UCONTEXT_INSTR_PTR(uc)      ((uc)->uc_mcontext.rip)
@@ -140,7 +142,7 @@ typedef struct SigQueue {
 #  define VGP_UCONTEXT_SYSCALL_NUM(uc)    ((uc)->uc_mcontext.rax)
 #  define VGP_UCONTEXT_SYSCALL_SYSRES(uc)                       \
       /* Convert the value in uc_mcontext.rax into a SysRes. */ \
-      VG_(mk_SysRes_amd64_linux)( (uc)->uc_mcontext.rax )
+      VG_(mk_SysRes)( (uc)->uc_mcontext.rax )
 
 #elif defined(VGP_arm_linux)
 #  define VGP_UCONTEXT_INSTR_PTR(uc)     ((uc)->uc_mcontext.arm_pc)
@@ -379,6 +381,30 @@ void calculate_SKSS_from_SCSS ( SKSS* dst )
    After a possible SCSS change, update SKSS and the kernel itself.
    ------------------------------------------------------------------ */
 
+// We need two levels of macro-expansion here to convert __NR_rt_sigreturn
+// to a number before converting it to a string... sigh.
+extern void my_sigreturn(void);
+
+#if defined(VGP_x86_linux)
+#  define _MYSIG(name) \
+   "my_sigreturn:\n" \
+   "   movl    $" #name ", %eax\n" \
+   "   int     $0x80\n"
+#elif defined(VGP_amd64_linux)
+#  define _MYSIG(name) \
+   "my_sigreturn:\n" \
+   "   movq    $" #name ", %rax\n" \
+   "   syscall\n"
+#else
+#  error Unknown platform
+#endif
+
+#define MYSIG(name)  _MYSIG(name)
+asm(
+   MYSIG(__NR_rt_sigreturn)
+);
+
+
 static void handle_SCSS_change ( Bool force_update )
 {
    Int  res, sig;
@@ -409,7 +435,7 @@ static void handle_SCSS_change ( Bool force_update )
 
       ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
       ksa.sa_flags    = skss.skss_per_sig[sig].skss_flags;
-      ksa.sa_restorer = VG_(sigreturn);
+      ksa.sa_restorer = my_sigreturn;
 
       /* block all signals in handler */
       VG_(sigfillset)( &ksa.sa_mask );
@@ -437,7 +463,7 @@ static void handle_SCSS_change ( Bool force_update )
          vg_assert(ksa_old.sa_flags 
                    == skss_old.skss_per_sig[sig].skss_flags);
          vg_assert(ksa_old.sa_restorer 
-                   == VG_(sigreturn));
+                   == my_sigreturn);
          VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
          VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
          vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
diff --git a/coregrind/m_syscall.c b/coregrind/m_syscall.c
new file mode 100644 (file)
index 0000000..3a24fb7
--- /dev/null
@@ -0,0 +1,163 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Doing syscalls.                                  m_syscall.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward 
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "core.h"
+#include "pub_core_syscall.h"
+
+/* ---------------------------------------------------------------------
+   Building syscall return values.
+   ------------------------------------------------------------------ */
+
+/* Make a SysRes value from an syscall return value.  This is
+   Linux-specific.
+
+   From:
+   http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
+   linux/i386/sysdep.h?
+   rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
+
+   Linux uses a negative return value to indicate syscall errors,
+   unlike most Unices, which use the condition codes' carry flag.
+
+   Since version 2.1 the return value of a system call might be
+   negative even if the call succeeded.  E.g., the 'lseek' system call
+   might return a large offset.  Therefore we must not anymore test
+   for < 0, but test for a real error by making sure the value in %eax
+   is a real error number.  Linus said he will make sure the no
+   syscall returns a value in -1 .. -4095 as a valid result so we can
+   safely test with -4095.
+*/
+SysRes VG_(mk_SysRes) ( UWord val ) {
+   SysRes res;
+#if defined(VGP_x86_linux)
+   res.isError = val >= -4095 && val <= -1;
+   res.val     = res.isError ? -val : val;
+#elif defined(VGP_amd64_linux)
+   res.isError = val >= -4095 && val <= -1;
+   res.val     = res.isError ? -val : val;
+#else
+#  error Unknown platform
+#endif
+   return res;
+}
+
+SysRes VG_(mk_SysRes_Error) ( UWord val ) {
+   SysRes r = { val, True };
+   return r;
+}
+
+SysRes VG_(mk_SysRes_Success) ( UWord val ) {
+   SysRes r = { val, False };
+   return r;
+}
+
+
+/* ---------------------------------------------------------------------
+   A function for doing syscalls.
+   ------------------------------------------------------------------ */
+
+extern UInt do_syscall_WRK (
+          UInt syscall_no, 
+          UInt a1, UInt a2, UInt a3,
+          UInt a4, UInt a5, UInt a6
+       );
+#if defined(VGP_x86_linux)
+/* Incoming args (syscall number + up to 6 args) come on the stack.
+   (ie. the C calling convention).
+
+   The syscall number goes in %eax.  The args are passed to the syscall in
+   the regs %ebx, %ecx, %edx, %esi, %edi, %ebp, ie. the kernel's syscall
+   calling convention.
+
+   %eax gets the return value.  Not sure which registers the kernel
+   clobbers, so we preserve all the callee-save regs (%esi, %edi, %ebx,
+   %ebp).
+*/
+asm(
+"do_syscall_WRK:\n"
+"      push    %esi\n"
+"      push    %edi\n"
+"      push    %ebx\n"
+"      push    %ebp\n"
+"      movl    16+ 4(%esp),%eax\n"
+"      movl    16+ 8(%esp),%ebx\n"
+"      movl    16+12(%esp),%ecx\n"
+"      movl    16+16(%esp),%edx\n"
+"      movl    16+20(%esp),%esi\n"
+"      movl    16+24(%esp),%edi\n"
+"      movl    16+28(%esp),%ebp\n"
+"      int     $0x80\n"
+"      popl    %ebp\n"
+"      popl    %ebx\n"
+"      popl    %edi\n"
+"      popl    %esi\n"
+"      ret\n"
+);
+#elif defined(VGP_amd64_linux)
+/* Incoming args (syscall number + up to 6 args) come in %rdi, %rsi,
+   %rdx, %rcx, %r8, %r9, and the last one on the stack (ie. the C
+   calling convention).
+
+   The syscall number goes in %rax.  The args are passed to the syscall in
+   the regs %rdi, %rsi, %rdx, %r10, %r8, %r9 (yes, really %r10, not %rcx),
+   ie. the kernel's syscall calling convention.
+
+   %rax gets the return value.  %rcx and %r11 are clobbered by the syscall;
+   no matter, they are caller-save (the syscall clobbers no callee-save
+   regs, so we don't have to do any register saving/restoring).
+*/
+asm(
+"do_syscall_WRK:\n"
+        /* Convert function calling convention --> syscall calling
+           convention */
+"      movq    %rdi, %rax\n"
+"      movq    %rsi, %rdi\n"
+"      movq    %rdx, %rsi\n"
+"      movq    %rcx, %rdx\n"
+"      movq    %r8,  %r10\n"
+"      movq    %r9,  %r8\n"
+"      movq    8(%rsp), %r9\n"  /* last arg from stack */
+"      syscall\n"
+"      ret\n"
+);
+#else
+#  error Unknown platform
+#endif
+
+SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3,
+                                      UWord a4, UWord a5, UWord a6 )
+{
+   UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
+   return VG_(mk_SysRes)( val );
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                        ---*/
+/*--------------------------------------------------------------------*/
index 419772a9f0074eb034450231af1ed10d27dfd9f8..d2cb0e479e3bf46e335a75143eea0ed614c73775 100644 (file)
 #include "libvex_guest_offsets.h"
 
 
-/*----------------------------------------------------------------*/
-.globl VG_(sigreturn)
-VG_(sigreturn):
-        movq    $__NR_rt_sigreturn, %rax
-        syscall
-
 /*----------------------------------------------------------------*/
 /*
        Perform a syscall for the client.  This will run a syscall
index 03370d477fd781b89536047a5a5e45773f89bcb7..e06a1174a100f0a4d2cd36bfd0b9ce57dd01abfa 100644 (file)
@@ -33,6 +33,8 @@
 
 # XXX: must reinstate comments also -- see x86-linux/syscall.S
 
+# XXX: this is now all way out of date...
+
 .globl VG_(do_syscall)
 VG_(do_syscall):
        swi
@@ -41,10 +43,6 @@ VG_(do_syscall):
 VG_(clone):
        swi
 
-.globl VG_(sigreturn)
-VG_(sigreturn):
-       swi
-
 # ToDo XXX: Assembler did not like this...
 #/* Let the linker know we don't need an executable stack */
 #.section .note.GNU-stack,"",@progbits
index 81fb6abc137d53862bc2210c0995890aa2f3bdb6..bf37f33bd3b99584441f33439177ead5e4e670b3 100644 (file)
 #include "libvex_guest_offsets.h"
                
        
-/*----------------------------------------------------------------*/
-.globl VG_(sigreturn)
-VG_(sigreturn):
-       movl    $__NR_rt_sigreturn, %eax
-       int     $0x80
-
 /*----------------------------------------------------------------*/
 /*
        Perform a syscall for the client.  This will run a syscall
index 8d17b423cf2ee306a2c5dec8e7da8c443c287f3a..09af69f29061c449854ccd4d9db88fe0694bff82 100644 (file)
@@ -41,6 +41,7 @@
 #include "pub_core_libcsignal.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_signals.h"
+#include "pub_core_syscall.h"
 #include "pub_core_syscalls.h"
 #include "pub_core_tooliface.h"
 
@@ -420,7 +421,7 @@ static SysRes do_clone ( ThreadId ptid,
             start_thread_NORETURN, stack, flags, &VG_(threads)[ctid],
             child_tidptr, parent_tidptr, NULL
          );
-   res = VG_(mk_SysRes_amd64_linux)( rax );
+   res = VG_(mk_SysRes)( rax );
 
    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
 
@@ -655,9 +656,7 @@ PRE(sys_rt_sigreturn)
       denote either success or failure, we must set up so that the
       driver logic copies it back unchanged.  Also, note %RAX is of
       the guest registers written by VG_(sigframe_destroy). */
-   SET_STATUS_from_SysRes(
-      VG_(mk_SysRes_amd64_linux)( tst->arch.vex.guest_RAX ) 
-   );
+   SET_STATUS_from_SysRes( VG_(mk_SysRes)( tst->arch.vex.guest_RAX ) );
 
    /* Check to see if some any signals arose as a result of this. */
    *flags |= SfPollAfter;
index 57309a6e442ae05e81853ce32ed1f5559241158d..16eb7c09f1ff77818808c9c1e5b1f50e8a890dd6 100644 (file)
@@ -44,6 +44,7 @@
 #include "pub_core_tooliface.h"
 #include "pub_core_options.h"
 #include "pub_core_signals.h"
+#include "pub_core_syscall.h"
 #include "pub_core_syscalls.h"
 
 #include "priv_types_n_macros.h"
index cff344619b8e3382db3e88baf848ede54d759788..fdf281210ba841a9231aafa0eb470630c089708d 100644 (file)
@@ -40,6 +40,7 @@
 #include "pub_core_tooliface.h"
 #include "pub_core_options.h"
 #include "pub_core_signals.h"
+#include "pub_core_syscall.h"
 
 #include "priv_types_n_macros.h"
 #include "priv_syscalls-generic.h"
index 619a8d678d9be42f57538db33754d86d932c439d..3af41c029b94995988cdf15052fdd33a7af07eff 100644 (file)
@@ -39,6 +39,7 @@
 #include "pub_core_tooliface.h"
 #include "pub_core_options.h"
 #include "pub_core_signals.h"
+#include "pub_core_syscall.h"
 #include "pub_core_syscalls.h"
 
 #include "priv_types_n_macros.h"
index dacfcfc4af5f75d152c33512b978c8797484d197..37dfd9b6cfa3923fd482e4d15f36fb3b3e98ec25 100644 (file)
@@ -47,6 +47,7 @@
 #include "pub_core_mallocfree.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_signals.h"
+#include "pub_core_syscall.h"
 #include "pub_core_syscalls.h"
 #include "pub_core_tooliface.h"
 
@@ -443,7 +444,7 @@ static SysRes do_clone ( ThreadId ptid,
             start_thread_NORETURN, stack, flags, &VG_(threads)[ctid],
             child_tidptr, parent_tidptr, NULL
          );
-   res = VG_(mk_SysRes_x86_linux)( eax );
+   res = VG_(mk_SysRes)( eax );
 
    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
 
@@ -1142,9 +1143,7 @@ PRE(sys_sigreturn)
       denote either success or failure, we must set up so that the
       driver logic copies it back unchanged.  Also, note %EAX is of
       the guest registers written by VG_(sigframe_destroy). */
-   SET_STATUS_from_SysRes(
-      VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX ) 
-   );
+   SET_STATUS_from_SysRes( VG_(mk_SysRes)( tst->arch.vex.guest_EAX ) );
 
    /* Check to see if some any signals arose as a result of this. */
    *flags |= SfPollAfter;
@@ -1175,9 +1174,7 @@ PRE(sys_rt_sigreturn)
       denote either success or failure, we must set up so that the
       driver logic copies it back unchanged.  Also, note %EAX is of
       the guest registers written by VG_(sigframe_destroy). */
-   SET_STATUS_from_SysRes(
-      VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX ) 
-   );
+   SET_STATUS_from_SysRes( VG_(mk_SysRes)( tst->arch.vex.guest_EAX ) );
 
    /* Check to see if some any signals arose as a result of this. */
    *flags |= SfPollAfter;
index b7289dee191d2236a7eb2fcd3b16e441353729db..5c20e8b79b93e7d5467ed86d94d8c96f59f4d6ec 100644 (file)
 
 #include "pub_tool_libcbase.h"
 
-/* ---------------------------------------------------------------------
-   Fundamental functions for doing syscalls on this platform.
-   ------------------------------------------------------------------ */
-
-/* Do a syscall on this platform, with 6 args, and return the result
-   in canonical format in a SysRes value. */
-
-// We use a full prototype for VG_(do_syscall) rather than "..." to ensure
-// that all arguments get converted to a UWord appropriately.  Not doing so
-// can cause problems when passing 32-bit integers on 64-bit platforms,
-// because the top 32-bits might not be zeroed appropriately, eg. as would
-// happen with the 6th arg on AMD64 which is passed on the stack.
-
-extern SysRes VG_(do_syscall) ( UWord sysno, 
-                                UWord, UWord, UWord, 
-                                UWord, UWord, UWord );
-
-/* Macros make life easier. */
-
-#define vgPlain_do_syscall0(s)             VG_(do_syscall)((s),0,0,0,0,0,0)
-#define vgPlain_do_syscall1(s,a)           VG_(do_syscall)((s),(a),0,0,0,0,0)
-#define vgPlain_do_syscall2(s,a,b)         VG_(do_syscall)((s),(a),(b),0,0,0,0)
-#define vgPlain_do_syscall3(s,a,b,c)       VG_(do_syscall)((s),(a),(b),(c),0,0,0)
-#define vgPlain_do_syscall4(s,a,b,c,d)     VG_(do_syscall)((s),(a),(b),\
-                                                           (c),(d),0,0)
-#define vgPlain_do_syscall5(s,a,b,c,d,e)   VG_(do_syscall)((s),(a),(b),\
-                                                           (c),(d),(e),0)
-#define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),\
-                                                           (c),(d),(e),(f))
-
-
-/* Build SysRes values -- occasionally useful. */
-
-static inline SysRes VG_(mk_SysRes_Error) ( UWord err ) {
-   SysRes r = { err, True };
-   return r;
-}
-
-static inline SysRes VG_(mk_SysRes_Success) ( UWord err ) {
-   SysRes r = { err, False };
-   return r;
-}
-
-
-/* This is absolutely the wrong place for these, but I can't figure
-   out anywhere else for them to go. */
-
-/* Make a SysRes value from an %eax syscall return value on
-   x86-linux.
-
-   From:
-   http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
-   linux/i386/sysdep.h?
-   rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
-
-   Linux uses a negative return value to indicate syscall errors,
-   unlike most Unices, which use the condition codes' carry flag.
-
-   Since version 2.1 the return value of a system call might be
-   negative even if the call succeeded.  E.g., the 'lseek' system call
-   might return a large offset.  Therefore we must not anymore test
-   for < 0, but test for a real error by making sure the value in %eax
-   is a real error number.  Linus said he will make sure the no
-   syscall returns a value in -1 .. -4095 as a valid result so we can
-   safely test with -4095.
-*/
-static inline SysRes VG_(mk_SysRes_x86_linux) ( Int eax ) {
-   SysRes res;
-   res.isError = eax >= -4095 && eax <= -1;
-   res.val     = res.isError ? -eax : eax;
-   return res;
-}
-
-/* Similarly .. */
-static inline SysRes VG_(mk_SysRes_amd64_linux) ( Long rax ) {
-   SysRes res;
-   res.isError = rax >= -4095 && rax <= -1;
-   res.val     = res.isError ? -rax : rax;
-   return res;
-}
-
-
-
 #endif   // __PUB_CORE_LIBCBASE_H
 
 /*--------------------------------------------------------------------*/
diff --git a/coregrind/pub_core_syscall.h b/coregrind/pub_core_syscall.h
new file mode 100644 (file)
index 0000000..17c3f55
--- /dev/null
@@ -0,0 +1,83 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Doing system calls.                       pub_core_syscall.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_CORE_SYSCALL_H
+#define __PUB_CORE_SYSCALL_H
+
+//--------------------------------------------------------------------
+// PURPOSE: This module contains the code for actually executing syscalls.
+//--------------------------------------------------------------------
+
+/* Do a syscall on this platform, with 6 args, and return the result
+   in canonical format in a SysRes value. */
+
+// We use a full prototype for VG_(do_syscall) rather than "..." to ensure
+// that all arguments get converted to a UWord appropriately.  Not doing so
+// can cause problems when passing 32-bit integers on 64-bit platforms,
+// because the top 32-bits might not be zeroed appropriately, eg. as would
+// happen with the 6th arg on AMD64 which is passed on the stack.
+
+extern SysRes VG_(do_syscall) ( UWord sysno, 
+                                UWord, UWord, UWord, 
+                                UWord, UWord, UWord );
+
+/* Macros make life easier. */
+
+#define vgPlain_do_syscall0(s)             VG_(do_syscall)((s),0,0,0,0,0,0)
+#define vgPlain_do_syscall1(s,a)           VG_(do_syscall)((s),(a),0,0,0,0,0)
+#define vgPlain_do_syscall2(s,a,b)         VG_(do_syscall)((s),(a),(b),0,0,0,0)
+#define vgPlain_do_syscall3(s,a,b,c)       VG_(do_syscall)((s),(a),(b),(c),0,0,0)
+#define vgPlain_do_syscall4(s,a,b,c,d)     VG_(do_syscall)((s),(a),(b),\
+                                                           (c),(d),0,0)
+#define vgPlain_do_syscall5(s,a,b,c,d,e)   VG_(do_syscall)((s),(a),(b),\
+                                                           (c),(d),(e),0)
+#define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),\
+                                                           (c),(d),(e),(f))
+
+extern SysRes VG_(mk_SysRes)         ( UWord val );
+extern SysRes VG_(mk_SysRes_Error)   ( UWord val );
+extern SysRes VG_(mk_SysRes_Success) ( UWord val );
+
+// The _WRK function is handwritten assembly.  It has some very magic
+// properties.  See comments at the top of
+// VG_(fixup_guest_state_after_syscall_interrupted) below for details.
+extern
+void VG_(do_syscall_for_client_WRK)( Int syscallno, 
+                                     void* guest_state,
+                                     const vki_sigset_t *syscall_mask,
+                                     const vki_sigset_t *restore_mask,
+                                     Int nsigwords );
+
+#endif   // __PUB_CORE_SYSCALL_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
+