Arch-abstraction:
- Started overhauling the syscalls to account for different architectures;
  in particular, accounts for the fact that the __NR_foo syscall number
  often doesn't directly match with the sys_foo() function that implements the
  function in the Linux kernel.  So started introducing this indirection as
  needed.  Currently, only read() and write() have been done;  the transition
  will be staged, since doing all syscalls in one hit is a total pain.

  This will also pave the way for scalar syscall arg checking with Memcheck,
  now that it is clear what the prototypes of the relevant syscalls are.

- Removed support for 2.2 kernels in the configure test, after discussion with
  Julian.  If it causes major problems, we can consider reverting.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2948 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/configure.in b/configure.in
index 516097a..8d81164 100644
--- a/configure.in
+++ b/configure.in
@@ -123,14 +123,9 @@
         	    AC_DEFINE([KERNEL_2_4], 1, [Define to 1 if you're using Linux 2.4.x])
         	    ;;
 
-             2.2.*) 
-        	    AC_MSG_RESULT([2.2 family (${kernel})])
-        	    AC_DEFINE([KERNEL_2_2], 1, [Define to 1 if you're using Linux 2.2.x])
-        	    ;;
-
              *) 
         	    AC_MSG_RESULT([unsupported (${kernel})])
-        	    AC_MSG_ERROR([Valgrind works on kernels 2.2, 2.4, 2.6])
+        	    AC_MSG_ERROR([Valgrind works on kernels 2.4, 2.6])
         	    ;;
         esac
 
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index ea55f04..3854309 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -32,7 +32,7 @@
 
 /* All system calls are channelled through here, doing two things:
 
-   * notify the tool of the memory events (reads, writes) happening
+   * notify the tool of the events (mem/reg reads, writes) happening
 
    * perform the syscall, usually by passing it along to the kernel
      unmodified.
@@ -42,6 +42,8 @@
    having the simulator retain control.
 */
 
+#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3)  /*nothing, so far*/
+
 #define PRE_MEM_READ(zzname, zzaddr, zzlen) \
    VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
 
@@ -991,9 +993,18 @@
 
 
 /* ---------------------------------------------------------------------
-   The Main Entertainment ...
+   The Main Entertainment ... syscall wrappers
    ------------------------------------------------------------------ */
 
+/* Note: the PRE() and POST() wrappers are for the actual functions
+   implementing the system calls in the Linux kernel.  These mostly have
+   names like sys_write();  a few have names like old_mmap().  See the
+   comment for sys_info[] and related arrays for important info about the
+   __NR_foo constants and their relationship to the sys_foo() functions.
+
+   XXX: some of these are arch-specific, and should be factored out.
+*/
+
 #define MayBlock   (1 << 0)
 #define PostOnFail (1 << 1)
 
@@ -4084,10 +4095,11 @@
    }
 }
 
-PRE(read)
+PRE(sys_read)
 {
-   /* size_t read(int fd, void *buf, size_t count); */
    PRINT("read ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
+   PRE_REG_READ3(ssize_t, sys_read,
+                 unsigned int, fd, char __user *, buf, size_t, count);
 
    if (!fd_allowed(arg1, "read", tid, False))
       set_result( -VKI_EBADF );
@@ -4095,15 +4107,16 @@
       PRE_MEM_WRITE( "read(buf)", arg2, arg3 );
 }
 
-POST(read)
+POST(sys_read)
 {
    POST_MEM_WRITE( arg2, res );
 }
 
-PRE(write)
+PRE(sys_write)
 {
-   /* size_t write(int fd, const void *buf, size_t count); */
    PRINT("write ( %d, %p, %llu )", arg1, arg2, (ULong)arg3);
+   PRE_REG_READ3(ssize_t, sys_write,
+                 unsigned int, fd, const char __user *, buf, size_t, count);
    if (!fd_allowed(arg1, "write", tid, False))
       set_result( -VKI_EBADF );
    else
@@ -5625,6 +5638,30 @@
     POST_MEM_WRITE( arg2, sizeof(struct vki_timespec) );
 }
 
+
+/* ---------------------------------------------------------------------
+   Summary info about syscalls
+   ------------------------------------------------------------------ */
+
+/* Important point: for each arch/Linux platform, the name of the constant
+   for a syscall (eg. __NR_write) usually matches the name of the function
+   in the Linux kernel that implements it (eg. sys_write()).  However, this
+   is not always the case.  For example:
+      
+      __NR_lchown       --> sys_lchown16()
+      __NR_lchown32     --> sys_lchown()
+      __NR_select       --> old_select()
+      __NR__newselect   --> sys_select()
+
+   Therefore part of the role of the arrays below is to provide a mapping
+   from the __NR_foo constants to the sys_foo() PRE/POST wrappers above.
+
+   XXX: doing this in stages, so we're in transition between the old
+   SYSB_/SYSBA macros to the new SYSX_/SYS_XY macros.
+
+   XXX: some of these are arch-specific, and should be factored out.
+*/
+
 struct sys_info {
    UInt	flags;
    void	(*before)(ThreadId tid, ThreadState *tst);
@@ -5633,6 +5670,9 @@
 #define SYSB_(name, flags)	[__NR_##name] = { flags, before_##name, NULL }
 #define SYSBA(name, flags)	[__NR_##name] = { flags, before_##name, after_##name }
 
+#define SYSX_(const, name, flags)   [const] = { flags, before_##name, NULL }
+#define SYSXY(const, name, flags)   [const] = { flags, before_##name, after_##name }
+
 static void bad_before(ThreadId tid, ThreadState *tst)
 {
    VG_(message)
@@ -5818,8 +5858,10 @@
    SYSBA(nanosleep,		MayBlock|PostOnFail),
    SYSB_(_newselect,		MayBlock),
    SYSBA(open,			MayBlock),
-   SYSBA(read,			MayBlock),
-   SYSB_(write,			MayBlock),
+//   SYSBA(read,			MayBlock),
+//   SYSB_(write,			MayBlock),
+   SYSXY(__NR_read,             sys_read,       MayBlock),
+   SYSX_(__NR_write,            sys_write,      MayBlock),
    SYSBA(creat,			MayBlock),
    SYSBA(pipe,			0),
    SYSBA(poll,			MayBlock),
@@ -5923,6 +5965,11 @@
 #undef SYSB_
 #undef SYSBA
 
+
+/* ---------------------------------------------------------------------
+   Executing the syscalls
+   ------------------------------------------------------------------ */
+
 Bool VG_(pre_syscall) ( ThreadId tid )
 {
    ThreadState* tst;