Converted the last syscalls.  Phew.  Still some cleaning up to do, esp. with
socketcall() and ipc() which are done too simplistically.

Also, VG_([gs]et_thread_area)() both now return -VKI_EFAULT if they are given a
NULL pointer.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3024 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 0831070..c2203a0 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -76,30 +76,34 @@
 	vg_toolint.c \
 	vg_translate.c \
 	vg_transtab.c
+
+stage2_extra= \
+	demangle/libdemangle.a \
+	${VG_ARCH}/libarch.a \
+	${VG_PLATFORM}/libplatform.a
+
 ## Test repeated in both arms of the if-then-else because older versions of
 ## automake don't seem to like having += within an if-then-else.
 if USE_PIE
 stage2_CFLAGS = $(AM_CFLAGS) -fpie
-stage2_DEPENDENCIES = $(srcdir)/valgrind.vs
+stage2_DEPENDENCIES = \
+	$(srcdir)/valgrind.vs \
+	$(stage2_extra)
 stage2_LDFLAGS = -Wl,--export-dynamic -g \
 	-Wl,-version-script $(srcdir)/valgrind.vs \
 	-pie
 else
 stage2_CFLAGS = $(AM_CFLAGS)
-stage2_DEPENDENCIES = $(srcdir)/valgrind.vs ${VG_ARCH}/stage2.lds
+stage2_DEPENDENCIES = \
+	$(srcdir)/valgrind.vs ${VG_ARCH}/stage2.lds \
+	$(stage2_extra)
 stage2_LDFLAGS = -Wl,--export-dynamic -g \
 	-Wl,-version-script $(srcdir)/valgrind.vs \
 	-Wl,-defsym,kickstart_base=@KICKSTART_BASE@ -Wl,-T,${VG_ARCH}/stage2.lds
 endif
 
-stage2_LDADD= \
-	demangle/cp-demangle.o \
-	demangle/cplus-dem.o \
-	demangle/dyn-string.o \
-	demangle/safe-ctype.o \
-	${VG_ARCH}/libarch.a \
-	${VG_PLATFORM}/libplatform.a \
-	-ldl
+stage2_LDADD= $(stage2_extra) -ldl
+
 
 vg_intercept.c: $(srcdir)/gen_intercepts.pl $(srcdir)/vg_intercept.c.base
 	rm -f $@
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index 0e7899f..235a1dc 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -1245,22 +1245,21 @@
    }
 }
 
-PRE(set_thread_area)
+PREx(sys_set_thread_area, Special)
 {
-   PRINT("set_thread_area ( %p )", arg1);
-
-   PRE_MEM_READ( "set_thread_area(ptr)", arg1, 
-		 sizeof(vki_modify_ldt_t) );
+   PRINT("sys_set_thread_area ( %p )", arg1);
+   PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
+   PRE_MEM_READ( "set_thread_area(u_info)", arg1, sizeof(vki_modify_ldt_t) );
 
    /* "do" the syscall ourselves; the kernel never sees it */
    set_result( VG_(sys_set_thread_area)( tid, (void *)arg1 ) );
 }
 
-PRE(get_thread_area)
+PREx(sys_get_thread_area, Special)
 {
-   PRINT("get_thread_area ( %p )", arg1);
-   PRE_MEM_WRITE( "get_thread_area(ptr)", arg1, 
-		  sizeof(vki_modify_ldt_t) );
+   PRINT("sys_get_thread_area ( %p )", arg1);
+   PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
+   PRE_MEM_WRITE( "get_thread_area(u_info)", arg1, sizeof(vki_modify_ldt_t) );
 
    /* "do" the syscall ourselves; the kernel never sees it */
    set_result( VG_(sys_get_thread_area)( tid, (void *)arg1 ) );
@@ -1502,22 +1501,23 @@
 // versions of LiS (Linux Streams).  They are not part of the kernel.
 // Therefore, we have to provide this type ourself, rather than getting it
 // from the kernel sources.
-struct pmsg_strbuf {
+struct vki_pmsg_strbuf {
    int     maxlen;         /* no. of bytes in buffer */
    int     len;            /* no. of bytes returned */
    vki_caddr_t buf;        /* pointer to data */
 };
 
-PRE(getpmsg)
+PREx(sys_getpmsg, MayBlock)
 {
    /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
-   /* int getpmsg(int fd, struct strbuf *ctrl, struct strbuf *data, 
-      int *bandp, int *flagsp); */
-   struct pmsg_strbuf *ctrl;
-   struct pmsg_strbuf *data;
-   PRINT("getpmsg ( %d, %p, %p, %p, %p )", arg1,arg2,arg3,arg4,arg5);
-   ctrl = (struct pmsg_strbuf *)arg2;
-   data = (struct pmsg_strbuf *)arg3;
+   struct vki_pmsg_strbuf *ctrl;
+   struct vki_pmsg_strbuf *data;
+   PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", arg1,arg2,arg3,arg4,arg5);
+   PRE_REG_READ5(int, "getpmsg",
+                 int, fd, struct strbuf *, ctrl, struct strbuf *, data, 
+                 int *, bandp, int *, flagsp);
+   ctrl = (struct vki_pmsg_strbuf *)arg2;
+   data = (struct vki_pmsg_strbuf *)arg3;
    if (ctrl && ctrl->maxlen > 0)
       PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
    if (data && data->maxlen > 0)
@@ -1528,13 +1528,13 @@
       PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)arg5, sizeof(int));
 }
 
-POST(getpmsg)
+POSTx(sys_getpmsg)
 {
-   struct pmsg_strbuf *ctrl;
-   struct pmsg_strbuf *data;
+   struct vki_pmsg_strbuf *ctrl;
+   struct vki_pmsg_strbuf *data;
 
-   ctrl = (struct pmsg_strbuf *)arg2;
-   data = (struct pmsg_strbuf *)arg3;
+   ctrl = (struct vki_pmsg_strbuf *)arg2;
+   data = (struct vki_pmsg_strbuf *)arg3;
    if (res == 0 && ctrl && ctrl->len > 0) {
       POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
    }
@@ -1543,16 +1543,17 @@
    }
 }
 
-PRE(putpmsg)
+PREx(sys_putpmsg, MayBlock)
 {
    /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
-   /* int putpmsg(int fd, struct strbuf *ctrl, struct strbuf *data, 
-      int band, int flags); */
-   struct pmsg_strbuf *ctrl;
-   struct pmsg_strbuf *data;
-   PRINT("putpmsg ( %d, %p, %p, %d, %d )", arg1,arg2,arg3,arg4,arg5);
-   ctrl = (struct pmsg_strbuf *)arg2;
-   data = (struct pmsg_strbuf *)arg3;
+   struct vki_pmsg_strbuf *ctrl;
+   struct vki_pmsg_strbuf *data;
+   PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", arg1,arg2,arg3,arg4,arg5);
+   PRE_REG_READ5(int, "putpmsg",
+                 int, fd, struct strbuf *, ctrl, struct strbuf *, data, 
+                 int, band, int, flags);
+   ctrl = (struct vki_pmsg_strbuf *)arg2;
+   data = (struct vki_pmsg_strbuf *)arg3;
    if (ctrl && ctrl->len > 0)
       PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
    if (data && data->len > 0)
@@ -5858,10 +5859,13 @@
 #define SIG_SIM   0
 #endif
 
-PRE(sigaltstack)
+// XXX: x86-specific
+PREx(sys_sigaltstack, SIG_SIM)
 {
    /* int sigaltstack(const stack_t *ss, stack_t *oss); */
    PRINT("sigaltstack ( %p, %p )",arg1,arg2);
+   PRE_REG_READ2(int, "sigaltstack",
+                 const vki_stack_t *, ss, vki_stack_t *, oss);
    if (arg1 != (UWord)NULL) {
       PRE_MEM_READ( "sigaltstack(ss)", arg1, sizeof(vki_stack_t) );
    }
@@ -5873,7 +5877,7 @@
       VG_(do_sys_sigaltstack) (tid);
 }
 
-POST(sigaltstack)
+POSTx(sys_sigaltstack)
 {
    if (res == 0 && arg2 != (UWord)NULL)
       POST_MEM_WRITE( arg2, sizeof(vki_stack_t));
@@ -6680,10 +6684,10 @@
    SYSXY(__NR_capget,           sys_capget),       // 184 * L?
 
    SYSX_(__NR_capset,           sys_capset),       // 185 * L?
-   SYSBA(__NR_sigaltstack,      sys_sigaltstack, SIG_SIM), // 186 
+   SYSXY(__NR_sigaltstack,      sys_sigaltstack),  // 186 (x86) (XPG4-UNIX)
    SYSXY(__NR_sendfile,         sys_sendfile),     // 187 * L
-   SYSBA(__NR_getpmsg,          sys_ni_syscall, MayBlock), // 188 ...
-   SYSB_(__NR_putpmsg,          sys_ni_syscall, MayBlock), // 189 ...
+   SYSXY(__NR_getpmsg,          sys_getpmsg),      // 188 (?) (?)
+   SYSX_(__NR_putpmsg,          sys_putpmsg),      // 189 (?) (?)
 
    // Nb: we convert vfork() to fork() in VG_(pre_syscall)().
    //   (__NR_vfork,            sys_vfork),        // 190 -- Valgrind avoids
@@ -6752,8 +6756,8 @@
    SYSXY(__NR_futex,            sys_futex),              // 240 * L
    SYSX_(__NR_sched_setaffinity,sys_sched_setaffinity),  // 241 * L?
    SYSXY(__NR_sched_getaffinity,sys_sched_getaffinity),  // 242 * L?
-   SYSB_(__NR_set_thread_area,  sys_set_thread_area, Special), // 243 
-   SYSB_(__NR_get_thread_area,  sys_get_thread_area, Special), // 244  
+   SYSX_(__NR_set_thread_area,  sys_set_thread_area), // 243 (x86-only) L
+   SYSX_(__NR_get_thread_area,  sys_get_thread_area), // 244 (x86-only) L
 
    SYSX_(__NR_io_setup,         sys_io_setup),        // 245 * L
    SYSX_(__NR_io_destroy,       sys_io_destroy),      // 246 * L
diff --git a/coregrind/x86-linux/ldt.c b/coregrind/x86-linux/ldt.c
index 97ccbcd..3bcaef1 100644
--- a/coregrind/x86-linux/ldt.c
+++ b/coregrind/x86-linux/ldt.c
@@ -420,7 +420,12 @@
 Int VG_(sys_set_thread_area) ( ThreadId tid,
                                vki_modify_ldt_t* info )
 {
-   Int idx = info->entry_number;
+   Int idx;
+
+   if (info == NULL)
+      return -VKI_EFAULT;
+
+   idx = info->entry_number;
 
    if (idx == -1) {
       for (idx = 0; idx < VKI_GDT_ENTRY_TLS_ENTRIES; idx++) {
@@ -454,9 +459,14 @@
 Int VG_(sys_get_thread_area) ( ThreadId tid,
                                vki_modify_ldt_t* info )
 {
-   Int idx = info->entry_number;
+   Int idx;
    VgLdtEntry* tls;
 
+   if (info == NULL)
+      return -VKI_EFAULT;
+
+   idx = info->entry_number;
+
    if (idx < VKI_GDT_ENTRY_TLS_MIN || idx > VKI_GDT_ENTRY_TLS_MAX)
       return -VKI_EINVAL;
 
diff --git a/memcheck/tests/scalar.c b/memcheck/tests/scalar.c
index 25665ad..e440e31 100644
--- a/memcheck/tests/scalar.c
+++ b/memcheck/tests/scalar.c
@@ -798,20 +798,35 @@
    SY(__NR_capset, x0, x0); FAIL;
 
    // __NR_sigaltstack 186
- //GO(__NR_sigaltstack, ".s .m");
- //SY(__NR_sigaltstack); FAIL;
+   {
+      struct our_sigaltstack {
+              void *ss_sp;
+              int ss_flags;
+              size_t ss_size;
+      } ss;
+      ss.ss_sp     = NULL;
+      ss.ss_flags  = 0;
+      ss.ss_size   = 0;
+      VALGRIND_MAKE_NOACCESS(& ss, sizeof(struct our_sigaltstack));
+      GO(__NR_sigaltstack, "2s 2m");
+      SY(__NR_sigaltstack, x0+&ss, x0+&ss); SUCC;
+   }
 
    // __NR_sendfile 187
    GO(__NR_sendfile, "4s 1m");
    SY(__NR_sendfile, x0, x0, x0+1, x0); FAIL;
 
    // __NR_getpmsg 188
- //GO(__NR_getpmsg, ".s .m");
- //SY(__NR_getpmsg); FAIL;
+   // Could do 5s 4m with more effort, but I can't be bothered for this
+   // crappy non-standard syscall.
+   GO(__NR_getpmsg, "5s 0m");
+   SY(__NR_getpmsg, x0, x0, x0, x0); FAIL;
 
    // __NR_putpmsg 189
- //GO(__NR_putpmsg, ".s .m");
- //SY(__NR_putpmsg); FAIL;
+   // Could do 5s 2m with more effort, but I can't be bothered for this
+   // crappy non-standard syscall.
+   GO(__NR_putpmsg, "5s 0m");
+   SY(__NR_putpmsg, x0, x0, x0, x0, x0); FAIL;
 
    // __NR_vfork 190
    GO(__NR_vfork, "other");
@@ -1030,12 +1045,12 @@
    SY(__NR_sched_getaffinity, x0, x0+1, x0); FAIL;
 
    // __NR_set_thread_area 243
- //GO(__NR_set_thread_area, ".s .m");
- //SY(__NR_set_thread_area); FAIL;
+   GO(__NR_set_thread_area, "1s 1m");
+   SY(__NR_set_thread_area, x0); FAILx(EFAULT);
 
    // __NR_get_thread_area 244
- //GO(__NR_get_thread_area, ".s .m");
- //SY(__NR_get_thread_area); FAIL;
+   GO(__NR_get_thread_area, "1s 1m");
+   SY(__NR_get_thread_area, x0); FAILx(EFAULT);
 
    // __NR_io_setup 245
    GO(__NR_io_setup, "2s 1m");
diff --git a/memcheck/tests/scalar.stderr.exp b/memcheck/tests/scalar.stderr.exp
index 313da02..6621e1b 100644
--- a/memcheck/tests/scalar.stderr.exp
+++ b/memcheck/tests/scalar.stderr.exp
@@ -2615,6 +2615,33 @@
    by 0x........: ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 -----------------------------------------------------
+186:    __NR_sigaltstack 2s 2m
+-----------------------------------------------------
+
+Syscall param sigaltstack(ss) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param sigaltstack(oss) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param sigaltstack(ss) points to unaddressable byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+ Address 0x........ is 0 bytes inside a block of size 12 client-defined
+   at 0x........: main (scalar.c:810)
+
+Syscall param sigaltstack(oss) points to unaddressable byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+ Address 0x........ is 0 bytes inside a block of size 12 client-defined
+   at 0x........: main (scalar.c:810)
+-----------------------------------------------------
 187:       __NR_sendfile 4s 1m
 -----------------------------------------------------
 
@@ -2644,6 +2671,62 @@
    by 0x........: ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 -----------------------------------------------------
+188:        __NR_getpmsg 5s 0m
+-----------------------------------------------------
+
+Syscall param getpmsg(fd) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param getpmsg(ctrl) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param getpmsg(data) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param getpmsg(bandp) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param getpmsg(flagsp) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+-----------------------------------------------------
+189:        __NR_putpmsg 5s 0m
+-----------------------------------------------------
+
+Syscall param putpmsg(fd) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param putpmsg(ctrl) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param putpmsg(data) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param putpmsg(band) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param putpmsg(flags) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+-----------------------------------------------------
 190:          __NR_vfork other
 -----------------------------------------------------
 -----------------------------------------------------
@@ -3708,6 +3791,34 @@
    by 0x........: ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 -----------------------------------------------------
+243:__NR_set_thread_area 1s 1m
+-----------------------------------------------------
+
+Syscall param set_thread_area(u_info) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param set_thread_area(u_info) points to unaddressable byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+-----------------------------------------------------
+244:__NR_get_thread_area 1s 1m
+-----------------------------------------------------
+
+Syscall param get_thread_area(u_info) contains uninitialised byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+
+Syscall param get_thread_area(u_info) points to unaddressable byte(s)
+   at 0x........: syscall (in /...libc...)
+   by 0x........: __libc_start_main (...libc...)
+   by 0x........: ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+-----------------------------------------------------
 245:       __NR_io_setup 2s 1m
 -----------------------------------------------------