Moved the basic syscall stuff out of m_libcbase.c into a new module
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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_syscall.c b/coregrind/m_syscall.c
new file mode 100644
index 0000000..3a24fb7
--- /dev/null
+++ b/coregrind/m_syscall.c
@@ -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                                                        ---*/
+/*--------------------------------------------------------------------*/