]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge r6140 (some of):
authorJulian Seward <jseward@acm.org>
Tue, 17 Oct 2006 01:47:30 +0000 (01:47 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 17 Oct 2006 01:47:30 +0000 (01:47 +0000)
- track SysRes changes

- track VG_(am_find_nsegment) const-ness change

- increase number of client syscall args supported from 6 to 8

- simplify type SyscallStatus.  Simply hold a copy of the SysRes
  for the syscall rather than have this be a data structure
  incorporating something very similar to the fields of a SysRes,
  and more besides.  Change various macros in priv_types_n_macros.h
  to match.

- syswrap-main.c: instantiate the various impedance-matching
  functions for AIX.

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

coregrind/m_syswrap/priv_types_n_macros.h
coregrind/m_syswrap/syscall-ppc64-linux.S
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-generic.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-main.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-ppc64-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c

index 585c7e016f024abcc768a0df93c22a5c016af6ab..a3ec400e4bb482285e59aae16ff47be9e6bace8e 100644 (file)
@@ -57,14 +57,23 @@ typedef
       UWord arg4;
       UWord arg5;
       UWord arg6;
+      UWord arg7;
+      UWord arg8;
    }
    SyscallArgs;
 
 /* Current status of a syscall being done on behalf of the client. */
 typedef
    struct {
-      enum { SsSuccess=1, SsFailure, SsHandToKernel, SsIdle } what;
-      UWord val; /* only meaningful for .what == Success or Failure */
+      enum { 
+         /* call is complete, result is in 'res' */
+         SsComplete=1,
+         /* syscall not yet completed; must be handed to the kernel */
+         SsHandToKernel, 
+         /* not currently handling a syscall for this thread */
+         SsIdle 
+      } what;
+      SysRes sres; /* only meaningful for .what == SsComplete */
    }
    SyscallStatus;
 
@@ -78,6 +87,8 @@ typedef
       Int o_arg4;
       Int o_arg5;
       Int o_arg6;
+      Int o_arg8;
+      Int o_arg7;
       Int o_retval;
    }
    SyscallArgLayout;
@@ -121,13 +132,30 @@ typedef
 */
 
 
-/* These are defined in the relevant platform-specific files --
-   syswrap-arch-os.c */
+#if defined(VGO_linux)
+/* On Linux, finding the wrapper is easy: just look up in fixed,
+   platform-specific tables.  These are defined in the relevant
+   platform-specific files -- syswrap-arch-os.c */
 
 extern const SyscallTableEntry ML_(syscall_table)[];
 
 extern const UInt ML_(syscall_table_size);
-   
+
+#elif defined(VGP_ppc32_aix5)
+/* On AIX5 this is more complex than the simple fixed table lookup on
+   Linux, since the syscalls don't have fixed numbers.  So it's
+   simplest to use a function, which does all the required messing
+   around. */
+extern
+SyscallTableEntry* ML_(get_ppc32_aix5_syscall_entry) ( UInt sysno );
+
+#elif defined(VGP_ppc64_aix5)
+extern
+SyscallTableEntry* ML_(get_ppc64_aix5_syscall_entry) ( UInt sysno );
+
+#else
+#  error Unknown OS
+#endif   
 
 /* ---------------------------------------------------------------------
    Declaring and defining wrappers.
@@ -197,6 +225,11 @@ extern const UInt ML_(syscall_table_size);
    [sysno] = { vgSysWrap_##auxstr##_##name##_before, \
                vgSysWrap_##auxstr##_##name##_after }
 
+#define WRAPPER_PRE_NAME(auxstr, name) \
+    vgSysWrap_##auxstr##_##name##_before
+#define WRAPPER_POST_NAME(auxstr, name) \
+    vgSysWrap_##auxstr##_##name##_after
+
 /* Add a generic wrapper to a syscall table. */
 #define GENX_(sysno, name)    WRAPPER_ENTRY_X_(generic, sysno, name)
 #define GENXY(sysno, name)    WRAPPER_ENTRY_XY(generic, sysno, name)
@@ -206,6 +239,17 @@ extern const UInt ML_(syscall_table_size);
 #define LINX_(sysno, name)    WRAPPER_ENTRY_X_(linux, sysno, name) 
 #define LINXY(sysno, name)    WRAPPER_ENTRY_XY(linux, sysno, name)
 
+/* Add an AIX5-specific, arch-independent wrapper to a syscall
+   table. */
+#define AIXXY(sysno, name)                     \
+   { & sysno,                                  \
+     { & WRAPPER_PRE_NAME(aix5, name),         \
+       & WRAPPER_POST_NAME(aix5, name) }} 
+
+#define AIXX_(sysno, name)                     \
+   { & sysno,                                  \
+     { & WRAPPER_PRE_NAME(aix5, name),         \
+       NULL }} 
 
 
 /* ---------------------------------------------------------------------
@@ -224,57 +268,48 @@ extern const UInt ML_(syscall_table_size);
 #define ARG4   (arrghs->arg4)
 #define ARG5   (arrghs->arg5)
 #define ARG6   (arrghs->arg6)
+#define ARG7   (arrghs->arg7)
+#define ARG8   (arrghs->arg8)
 
-/* Reference to the syscall's current result status/value.  Note that
-   
-   (1) status->val by itself is meaningless -- you have to consider it
-       together with status->what, which is why RES uses a helper
-       function (this also has the desirable effect of turning RES
-       into a non-lvalue).
-
-   (2) post-wrappers will not get called in case of failure (unless
-       PostOnFail is set, which is rare).  This is why the assertion
-       in getRES is viable.
-
-   If you really really want to just get hold of status->val without
-   inspecting status->what, use RES_unchecked.  This is dangerous and
-   therefore discouraged.  
-*/
-#define SUCCESS       (status->what == SsSuccess)
-#define FAILURE       (status->what == SsFailure)
+/* Reference to the syscall's current result status/value.  General
+   paranoia all round. */
+#define SUCCESS       (status->what == SsComplete && !status->sres.isError)
+#define FAILURE       (status->what == SsComplete &&  status->sres.isError)
 #define SWHAT         (status->what)
-#define RES_unchecked (status->val)     /* do not use! */
-#define RES           (getRES(status))  /* use this instead, if possible */
+#define RES           (getRES(status))
+#define ERR           (getERR(status))
 
 static inline UWord getRES ( SyscallStatus* st ) {
-   vg_assert(st->what == SsSuccess);
-   return st->val;
+   vg_assert(st->what == SsComplete);
+   vg_assert(!st->sres.isError);
+   return st->sres.res;
 }
 
+static inline UWord getERR ( SyscallStatus* st ) {
+   vg_assert(st->what == SsComplete);
+   vg_assert(st->sres.isError);
+   return st->sres.err;
+}
 
 
 /* Set the current result status/value in various ways. */
 #define SET_STATUS_Success(zzz)                      \
-   do { status->what = SsSuccess;                    \
-        status->val  = (zzz);                        \
+   do { status->what = SsComplete;                   \
+        status->sres = VG_(mk_SysRes_Success)(zzz);  \
    } while (0)
 
 #define SET_STATUS_Failure(zzz)                      \
    do { Word wzz = (Word)(zzz);                      \
         /* Catch out wildly bogus error values. */   \
         vg_assert(wzz >= 0 && wzz < 10000);          \
-        status->what = SsFailure;                    \
-        status->val  = wzz;                          \
+        status->what = SsComplete;                   \
+        status->sres = VG_(mk_SysRes_Error)(wzz);    \
    } while (0)
 
 #define SET_STATUS_from_SysRes(zzz)                  \
    do {                                              \
-      SysRes zres = (zzz);                           \
-      if (zres.isError) {                            \
-         SET_STATUS_Failure(zres.val);               \
-      } else {                                       \
-         SET_STATUS_Success(zres.val);               \
-      }                                              \
+     status->what = SsComplete;                      \
+     status->sres = (zzz);                           \
    } while (0)
 
 /* A lamentable kludge */
@@ -284,16 +319,6 @@ static inline UWord getRES ( SyscallStatus* st ) {
         status->val  = wzz;                          \
    } while (0)
 
-#define SET_STATUS_from_SysRes_NO_SANITY_CHECK(zzz)  \
-   do {                                              \
-      SysRes zres = (zzz);                           \
-      if (zres.isError) {                            \
-         SET_STATUS_Failure_NO_SANITY_CHECK(zres.val); \
-      } else {                                       \
-         SET_STATUS_Success(zres.val);               \
-      }                                              \
-   } while (0)
-
 
 #define PRINT(format, args...)                       \
    if (VG_(clo_trace_syscalls))                      \
@@ -329,6 +354,7 @@ static inline UWord getRES ( SyscallStatus* st ) {
     do {                                             \
        Int here = layout->o_arg##n;                  \
        vg_assert(sizeof(t) <= sizeof(UWord));        \
+       vg_assert(here >= 0);                         \
        VG_(tdict).track_pre_reg_read(                \
           Vg_CoreSysCall, tid, s"("#a")",            \
           here, sizeof(t)                            \
@@ -343,8 +369,10 @@ static inline UWord getRES ( SyscallStatus* st ) {
 */
 #define PRRAn_BE(n,s,t,a)                            \
     do {                                             \
+       Int here = layout->o_arg##n;                  \
        Int next = layout->o_arg##n + sizeof(UWord);  \
        vg_assert(sizeof(t) <= sizeof(UWord));        \
+       vg_assert(here >= 0);                         \
        VG_(tdict).track_pre_reg_read(                \
           Vg_CoreSysCall, tid, s"("#a")",            \
           next-sizeof(t), sizeof(t)                  \
index ab9c6a1dcfebe367f8db4bdde759b9eb34103872..0fa08046a994de702f40a508f9f56b47a09c1e80 100644 (file)
@@ -7,7 +7,7 @@
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.
 
-  Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
+  Copyright (C) 2005-2006 Paul Mackerras <paulus@samba.org>
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
index 89fdec43017f02158f1b2ad3b4cddd419f46c96c..9dd60a5ec5ee2e214c3e037b5a4f019a73c4660d 100644 (file)
@@ -205,7 +205,7 @@ static SysRes do_clone ( ThreadId ptid,
    ThreadState* ptst = VG_(get_ThreadState)(ptid);
    ThreadState* ctst = VG_(get_ThreadState)(ctid);
    UWord*       stack;
-   NSegment*    seg;
+   NSegment const* seg;
    SysRes       res;
    Long         rax;
    vki_sigset_t blockall, savedmask;
index 19a694e3230163e86ccf93652ac48b9fcb1c1cd8..e644b892f09d2dd3e9d43f556bd5a6bdd43a0244 100644 (file)
@@ -177,7 +177,7 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
 #  define MIN_SIZET(_aa,_bb) (_aa) < (_bb) ? (_aa) : (_bb)
 
    Bool      ok, d;
-   NSegment* old_seg;
+   NSegment const* old_seg;
    Addr      advised;
    Bool      f_fixed   = toBool(flags & VKI_MREMAP_FIXED);
    Bool      f_maymove = toBool(flags & VKI_MREMAP_MAYMOVE);
@@ -335,14 +335,14 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
          the next segment along.  So make very sure that the proposed
          new area really is free.  This is perhaps overly
          conservative, but it fixes #129866. */
-      NSegment* segLo = VG_(am_find_nsegment)( needA );
-      NSegment* segHi = VG_(am_find_nsegment)( needA + needL - 1 );
+      NSegment const* segLo = VG_(am_find_nsegment)( needA );
+      NSegment const* segHi = VG_(am_find_nsegment)( needA + needL - 1 );
       if (segLo == NULL || segHi == NULL 
           || segLo != segHi || segLo->kind != SkFree)
          ok = False;
    }
    if (ok && advised == needA) {
-      ok = VG_(am_extend_map_client)( &d, old_seg, needL );
+      ok = VG_(am_extend_map_client)( &d, (NSegment*)old_seg, needL );
       if (ok) {
          VG_TRACK( new_mem_mmap, needA, needL, 
                                  old_seg->hasR, 
@@ -393,15 +393,15 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
          this-or-nothing) is too lenient, and may allow us to trash
          the next segment along.  So make very sure that the proposed
          new area really is free. */
-      NSegment* segLo = VG_(am_find_nsegment)( needA );
-      NSegment* segHi = VG_(am_find_nsegment)( needA + needL - 1 );
+      NSegment const* segLo = VG_(am_find_nsegment)( needA );
+      NSegment const* segHi = VG_(am_find_nsegment)( needA + needL - 1 );
       if (segLo == NULL || segHi == NULL 
           || segLo != segHi || segLo->kind != SkFree)
          ok = False;
    }
    if (!ok || advised != needA)
       goto eNOMEM;
-   ok = VG_(am_extend_map_client)( &d, old_seg, needL );
+   ok = VG_(am_extend_map_client)( &d, (NSegment*)old_seg, needL );
    if (!ok)
       goto eNOMEM;
    VG_TRACK( new_mem_mmap, needA, needL, 
@@ -703,23 +703,23 @@ void VG_(init_preopened_fds)()
       return;
    }
 
-   while ((ret = VG_(getdents)(f.val, &d, sizeof(d))) != 0) {
+   while ((ret = VG_(getdents)(f.res, &d, sizeof(d))) != 0) {
       if (ret == -1)
          goto out;
 
       if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
          Int fno = VG_(atoll)(d.d_name);
 
-         if (fno != f.val)
+         if (fno != f.res)
             if (VG_(clo_track_fds))
                record_fd_open_named(-1, fno);
       }
 
-      VG_(lseek)(f.val, d.d_off, VKI_SEEK_SET);
+      VG_(lseek)(f.res, d.d_off, VKI_SEEK_SET);
    }
 
   out:
-   VG_(close)(f.val);
+   VG_(close)(f.res);
 }
 
 static
@@ -947,7 +947,8 @@ void buf_and_len_post_check( ThreadId tid, SysRes res,
 
 static Addr do_brk ( Addr newbrk )
 {
-   NSegment *aseg, *rseg;
+   NSegment const* aseg;
+   NSegment const* rseg;
    Addr newbrkP;
    SizeT delta;
    Bool ok;
@@ -968,7 +969,7 @@ static Addr do_brk ( Addr newbrk )
    if (newbrk >= VG_(brk_base) && newbrk < VG_(brk_limit)) {
       /* shrinking the data segment.  Be lazy and don't munmap the
          excess area. */
-      NSegment* seg = VG_(am_find_nsegment)(newbrk);
+      NSegment const * seg = VG_(am_find_nsegment)(newbrk);
       if (seg && seg->hasT)
          VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk, 
                                     "do_brk(shrink)" );
@@ -982,7 +983,7 @@ static Addr do_brk ( Addr newbrk )
       if (seg) {
          /* pre: newbrk < VG_(brk_limit) 
               => newbrk <= VG_(brk_limit)-1 */
-         NSegment* seg2;
+         NSegment const * seg2;
          vg_assert(newbrk < VG_(brk_limit));
          seg2 = VG_(am_find_nsegment)( VG_(brk_limit)-1 );
          if (seg2 && seg == seg2 && seg->hasW)
@@ -998,7 +999,7 @@ static Addr do_brk ( Addr newbrk )
       aseg = VG_(am_find_nsegment)( VG_(brk_limit)-1 );
    else
       aseg = VG_(am_find_nsegment)( VG_(brk_limit) );
-   rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
+   rseg = VG_(am_next_nsegment)( (NSegment*)aseg, True/*forwards*/ );
 
    /* These should be assured by setup_client_dataseg in m_main. */
    vg_assert(aseg);
@@ -1026,7 +1027,7 @@ static Addr do_brk ( Addr newbrk )
    vg_assert(delta > 0);
    vg_assert(VG_IS_PAGE_ALIGNED(delta));
    
-   ok = VG_(am_extend_into_adjacent_reservation_client)( aseg, delta );
+   ok = VG_(am_extend_into_adjacent_reservation_client)( (NSegment*)aseg, delta );
    if (!ok) goto bad;
 
    VG_(brk_limit) = newbrk;
@@ -1163,12 +1164,12 @@ ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
 {
    SysRes r = res;
    vg_assert(!res.isError); /* guaranteed by caller */
-   if (!ML_(fd_allowed)(res.val, "socket", tid, True)) {
-      VG_(close)(res.val);
+   if (!ML_(fd_allowed)(res.res, "socket", tid, True)) {
+      VG_(close)(res.res);
       r = VG_(mk_SysRes_Error)( VKI_EMFILE );
    } else {
       if (VG_(clo_track_fds))
-         ML_(record_fd_open_nameless)(tid, res.val);
+         ML_(record_fd_open_nameless)(tid, res.res);
    }
    return r;
 }
@@ -1209,8 +1210,8 @@ ML_(generic_POST_sys_accept) ( ThreadId tid,
 {
    SysRes r = res;
    vg_assert(!res.isError); /* guaranteed by caller */
-   if (!ML_(fd_allowed)(res.val, "accept", tid, True)) {
-      VG_(close)(res.val);
+   if (!ML_(fd_allowed)(res.res, "accept", tid, True)) {
+      VG_(close)(res.res);
       r = VG_(mk_SysRes_Error)( VKI_EMFILE );
    } else {
       Addr addr_p     = arg1;
@@ -1219,7 +1220,7 @@ ML_(generic_POST_sys_accept) ( ThreadId tid,
          buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
                                   "socketcall.accept(addrlen_out)" );
       if (VG_(clo_track_fds))
-          ML_(record_fd_open_nameless)(tid, res.val);
+          ML_(record_fd_open_nameless)(tid, res.res);
    }
    return r;
 }
@@ -1712,7 +1713,7 @@ ML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
 void
 ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
 {
-   NSegment* s = VG_(am_find_nsegment)(arg0);
+   NSegment const* s = VG_(am_find_nsegment)(arg0);
 
    if (s != NULL) {
       Addr  s_start = s->start;
@@ -1890,18 +1891,18 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid,
    if (!sres.isError) {
       /* Notify aspacem and the tool. */
       ML_(notify_aspacem_and_tool_of_mmap)( 
-         (Addr)sres.val, /* addr kernel actually assigned */
+         (Addr)sres.res, /* addr kernel actually assigned */
          arg2, arg3, 
          arg4, /* the original flags value */
          arg5, arg6 
       );
       /* Load symbols? */
-      VG_(di_notify_mmap)( (Addr)sres.val, False/*allow_SkFileV*/ );
+      VG_(di_notify_mmap)( (Addr)sres.res, False/*allow_SkFileV*/ );
    }
 
    /* Stay sane */
    if (!sres.isError && (arg4 & VKI_MAP_FIXED))
-      vg_assert(sres.val == arg1);
+      vg_assert(sres.res == arg1);
 
    return sres;
 }
@@ -1961,7 +1962,7 @@ PRE(sys_exit)
    tst = VG_(get_ThreadState)(tid);
    /* Set the thread's status to be exiting, then claim that the
       syscall succeeded. */
-   tst->exitreason = VgSrc_ExitSyscall;
+   tst->exitreason = VgSrc_ExitThread;
    tst->os_state.exitcode = ARG1;
    SET_STATUS_Success(0);
 }
@@ -2370,7 +2371,7 @@ PRE(sys_execve)
    // ok, etc.
    res = VG_(pre_exec_check)((const Char*)ARG1, NULL);
    if (res.isError) {
-      SET_STATUS_Failure( res.val );
+      SET_STATUS_Failure( res.res );
       return;
    }
 
@@ -2390,7 +2391,7 @@ PRE(sys_execve)
    /* Resistance is futile.  Nuke all other threads.  POSIX mandates
       this. (Really, nuke them all, since the new process will make
       its own new thread.) */
-   VG_(nuke_all_threads_except)( tid, VgSrc_ExitSyscall );
+   VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread );
    VG_(reap_threads)(tid);
 
    // Set up the child's exe path.
@@ -2509,7 +2510,6 @@ PRE(sys_execve)
    {
       vki_sigset_t allsigs;
       vki_siginfo_t info;
-      static const struct vki_timespec zero = { 0, 0 };
 
       for (i = 1; i < VG_(max_signal); i++) {
          struct vki_sigaction sa;
@@ -2523,7 +2523,7 @@ PRE(sys_execve)
       }
 
       VG_(sigfillset)(&allsigs);
-      while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
+      while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0)
          ;
 
       VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
@@ -2548,7 +2548,7 @@ PRE(sys_execve)
   hosed:
    vg_assert(FAILURE);
    VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
-                ARG1, ARG1, ARG2, ARG3, RES_unchecked);
+                ARG1, ARG1, ARG2, ARG3, ERR);
    VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
                             "execve() failing, so I'm dying.");
    VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
@@ -4743,7 +4743,7 @@ Bool ML_(do_sigkill)(Int pid, Int tgid)
       tst->os_state.fatalsig = VKI_SIGKILL;
       
       if (!VG_(is_running_thread)(tid))
-        VG_(kill_thread)(tid);
+        VG_(get_thread_out_of_syscall)(tid);
    }
    
    return True;
@@ -4833,13 +4833,13 @@ PRE(sys_mprotect)
          The sanity check provided by the kernel is that the vma must
          have the VM_GROWSDOWN/VM_GROWSUP flag set as appropriate.  */
       UInt grows = ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP);
-      NSegment *aseg = VG_(am_find_nsegment)(ARG1);
-      NSegment *rseg;
+      NSegment const *aseg = VG_(am_find_nsegment)(ARG1);
+      NSegment const *rseg;
 
       vg_assert(aseg);
 
       if (grows == VKI_PROT_GROWSDOWN) {
-         rseg = VG_(am_next_nsegment)( aseg, False/*backwards*/ );
+         rseg = VG_(am_next_nsegment)( (NSegment*)aseg, False/*backwards*/ );
          if (rseg &&
              rseg->kind == SkResvn &&
              rseg->smode == SmUpper &&
@@ -4852,7 +4852,7 @@ PRE(sys_mprotect)
             SET_STATUS_Failure( VKI_EINVAL );
          }
       } else if (grows == VKI_PROT_GROWSUP) {
-         rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
+         rseg = VG_(am_next_nsegment)( (NSegment*)aseg, True/*forwards*/ );
          if (rseg &&
              rseg->kind == SkResvn &&
              rseg->smode == SmLower &&
@@ -4940,7 +4940,7 @@ PRE(sys_nanosleep)
 POST(sys_nanosleep)
 {
    vg_assert(SUCCESS || FAILURE);
-   if (ARG2 != 0 && FAILURE && RES_unchecked == VKI_EINTR)
+   if (ARG2 != 0 && FAILURE && ERR == VKI_EINTR)
       POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
 }
 
@@ -4974,7 +4974,7 @@ PRE(sys_open)
       sres = VG_(dup)( VG_(cl_cmdline_fd) );
       SET_STATUS_from_SysRes( sres );
       if (!sres.isError) {
-         OffT off = VG_(lseek)( sres.val, 0, VKI_SEEK_SET );
+         OffT off = VG_(lseek)( sres.res, 0, VKI_SEEK_SET );
          if (off < 0)
             SET_STATUS_Failure( VKI_EMFILE );
       }
index cd46345747dc6846ac1b20bbcd2bd13132586f43..f4d8504b594a35c8f041f68d5b3e0fddd8f5648e 100644 (file)
@@ -71,7 +71,7 @@ static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
    vg_assert(tst->status == VgTs_Init);
 
    /* make sure we get the CPU lock before doing anything significant */
-   VG_(set_running)(tid);
+   VG_(set_running)(tid, "thread_wrapper(starting new thread)");
 
    if (0)
       VG_(printf)("thread tid %d started: stack = %p\n",
@@ -325,7 +325,7 @@ SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
 # error Unknown platform
 #endif
 
-   if (!res.isError && res.val == 0) {
+   if (!res.isError && res.res == 0) {
       /* child */
       VG_(do_atfork_child)(tid);
 
@@ -333,11 +333,11 @@ SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
    } 
    else 
-   if (!res.isError && res.val > 0) {
+   if (!res.isError && res.res > 0) {
       /* parent */
       if (VG_(clo_trace_syscalls))
          VG_(printf)("   clone(fork): process %d created child %d\n", 
-                      VG_(getpid)(), res.val);
+                      VG_(getpid)(), res.res);
 
       /* restore signal mask */
       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
@@ -553,11 +553,11 @@ PRE(sys_exit_group)
          )
          continue;
 
-      VG_(threads)[t].exitreason = VgSrc_ExitSyscall;
+      VG_(threads)[t].exitreason = VgSrc_ExitThread;
       VG_(threads)[t].os_state.exitcode = ARG1;
 
       if (t != tid)
-        VG_(kill_thread)(t);   /* unblock it, if blocked */
+        VG_(get_thread_out_of_syscall)(t); /* unblock it, if blocked */
    }
 
    /* We have to claim the syscall already succeeded. */
@@ -1498,7 +1498,7 @@ PRE(sys_clock_nanosleep)
 }
 POST(sys_clock_nanosleep)
 {
-   if (ARG4 != 0 && FAILURE && RES_unchecked == VKI_EINTR)
+   if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR)
       POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
 }
 
@@ -2368,7 +2368,7 @@ PRE(sys_openat)
       sres = VG_(dup)( VG_(cl_cmdline_fd) );
       SET_STATUS_from_SysRes( sres );
       if (!sres.isError) {
-         OffT off = VG_(lseek)( sres.val, 0, VKI_SEEK_SET );
+         OffT off = VG_(lseek)( sres.res, 0, VKI_SEEK_SET );
          if (off < 0)
             SET_STATUS_Failure( VKI_EMFILE );
       }
index cc0da7d105e7497a6f7e356b3676c6479319765c..e259f2644b1c65e97c5432f54687f6ad2c599a87 100644 (file)
@@ -31,7 +31,7 @@
 #include "libvex_guest_offsets.h"
 #include "pub_core_basics.h"
 #include "pub_core_vki.h"
-#include "pub_core_basics.h"
+#include "pub_core_vkiscnums.h"
 #include "pub_core_threadstate.h"
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 
 
 /* Useful info which needs to be recorded somewhere:
-   Use of registers in syscalls (on linux) is:
-
-          NUM  ARG1  ARG2  ARG3  ARG4  ARG5  ARG6  RESULT
-   x86    eax  ebx   ecx   edx   esi   edi   ebp   eax       (== NUM)
-   amd64  rax  rdi   rsi   rdx   r10   r8    r9    rax       (== NUM)
-   ppc32  r0   r3    r4    r5    r6    r7    r8    r3+CR0.SO (== ARG1)
-   ppc64  r0   r3    r4    r5    r6    r7    r8    r3+CR0.SO (== ARG1)
+   Use of registers in syscalls is:
+
+          NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT
+   LINUX:
+   x86    eax ebx  ecx  edx  esi  edi  ebp  n/a  n/a  eax       (== NUM)
+   amd64  rax rdi  rsi  rdx  r10  r8   r9   n/a  n/a  rax       (== NUM)
+   ppc32  r0  r3   r4   r5   r6   r7   r8   n/a  n/a  r3+CR0.SO (== ARG1)
+   ppc64  r0  r3   r4   r5   r6   r7   r8   n/a  n/a  r3+CR0.SO (== ARG1)
+   AIX:
+   ppc32  r2  r3   r4   r5   r6   r7   r8   r9   r10  r3(res),r4(err)
+   ppc64  r2  r3   r4   r5   r6   r7   r8   r9   r10  r3(res),r4(err)
 */
 
 /* This is the top level of the system-call handler module.  All
    VG_(fixup_guest_state_after_syscall_interrupted) below for details.
 */
 extern
-UWord ML_(do_syscall_for_client_WRK)( Int syscallno, 
+UWord ML_(do_syscall_for_client_WRK)( Word syscallno, 
                                       void* guest_state,
                                       const vki_sigset_t *syscall_mask,
                                       const vki_sigset_t *restore_mask,
-                                      Int nsigwords );
+                                      Word nsigwords
+#                                     if defined(VGO_aix5)
+                                      , Word __nr_sigprocmask
+#                                     endif
+                                    );
 
 static
 void do_syscall_for_client ( Int syscallno,
@@ -241,6 +249,9 @@ void do_syscall_for_client ( Int syscallno,
       = ML_(do_syscall_for_client_WRK)(
            syscallno, &tst->arch.vex, 
            syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord)
+#          if defined(VGO_aix5)
+           , __NR_rt_sigprocmask
+#          endif
         );
    vg_assert2(
       err == 0,
@@ -264,38 +275,28 @@ Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 )
           && a1->arg3 == a2->arg3
           && a1->arg4 == a2->arg4
           && a1->arg5 == a2->arg5
-          && a1->arg6 == a2->arg6;
+          && a1->arg6 == a2->arg6
+          && a1->arg7 == a2->arg7
+          && a1->arg8 == a2->arg8;
 }
 
 static
 Bool eq_SyscallStatus ( SyscallStatus* s1, SyscallStatus* s2 )
 {
    return s1->what == s2->what 
-          && s1->val == s2->val;
+          && s1->sres.res == s2->sres.res
+          && s1->sres.err == s2->sres.err;
 }
 
 
-/* Convert between SysRet and SyscallStatus, to the extent possible. */
-
-/* This is unused. */
-/*
-static
-SysRes convert_SyscallStatus_to_SysRes ( SyscallStatus status )
-{
-   SysRes res;
-   vg_assert(status.what == SsSuccess || status.what == SsFailure);
-   res.isError = status.what == SsFailure;
-   res.val     = status.val;
-   return res;
-}
-*/
+/* Convert between SysRes and SyscallStatus, to the extent possible. */
 
 static
 SyscallStatus convert_SysRes_to_SyscallStatus ( SysRes res )
 {
    SyscallStatus status;
-   status.what = res.isError ? SsFailure : SsSuccess;
-   status.val  = res.val;
+   status.what = SsComplete;
+   status.sres = res;
    return status;
 }
 
@@ -317,6 +318,8 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    canonical->arg4  = gst->guest_ESI;
    canonical->arg5  = gst->guest_EDI;
    canonical->arg6  = gst->guest_EBP;
+   canonical->arg7  = 0;
+   canonical->arg8  = 0;
 
 #elif defined(VGP_amd64_linux)
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
@@ -327,6 +330,9 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    canonical->arg4  = gst->guest_R10;
    canonical->arg5  = gst->guest_R8;
    canonical->arg6  = gst->guest_R9;
+   canonical->arg7  = 0;
+   canonical->arg8  = 0;
+
 
 #elif defined(VGP_ppc32_linux)
    VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
@@ -337,6 +343,9 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    canonical->arg4  = gst->guest_GPR6;
    canonical->arg5  = gst->guest_GPR7;
    canonical->arg6  = gst->guest_GPR8;
+   canonical->arg7  = 0;
+   canonical->arg8  = 0;
+
 
 #elif defined(VGP_ppc64_linux)
    VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
@@ -347,6 +356,33 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
    canonical->arg4  = gst->guest_GPR6;
    canonical->arg5  = gst->guest_GPR7;
    canonical->arg6  = gst->guest_GPR8;
+   canonical->arg7  = 0;
+   canonical->arg8  = 0;
+
+
+#elif defined(VGP_ppc32_aix5)
+   VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
+   canonical->sysno = gst->guest_GPR2;
+   canonical->arg1  = gst->guest_GPR3;
+   canonical->arg2  = gst->guest_GPR4;
+   canonical->arg3  = gst->guest_GPR5;
+   canonical->arg4  = gst->guest_GPR6;
+   canonical->arg5  = gst->guest_GPR7;
+   canonical->arg6  = gst->guest_GPR8;
+   canonical->arg7  = gst->guest_GPR9;
+   canonical->arg8  = gst->guest_GPR10;
+
+#elif defined(VGP_ppc64_aix5)
+   VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
+   canonical->sysno = gst->guest_GPR2;
+   canonical->arg1  = gst->guest_GPR3;
+   canonical->arg2  = gst->guest_GPR4;
+   canonical->arg3  = gst->guest_GPR5;
+   canonical->arg4  = gst->guest_GPR6;
+   canonical->arg5  = gst->guest_GPR7;
+   canonical->arg6  = gst->guest_GPR8;
+   canonical->arg7  = gst->guest_GPR9;
+   canonical->arg8  = gst->guest_GPR10;
 
 #else
 #  error "getSyscallArgsFromGuestState: unknown arch"
@@ -397,6 +433,30 @@ void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
    gst->guest_GPR7 = canonical->arg5;
    gst->guest_GPR8 = canonical->arg6;
 
+#elif defined(VGP_ppc32_aix5)
+   VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
+   gst->guest_GPR2  = canonical->sysno;
+   gst->guest_GPR3  = canonical->arg1;
+   gst->guest_GPR4  = canonical->arg2;
+   gst->guest_GPR5  = canonical->arg3;
+   gst->guest_GPR6  = canonical->arg4;
+   gst->guest_GPR7  = canonical->arg5;
+   gst->guest_GPR8  = canonical->arg6;
+   gst->guest_GPR9  = canonical->arg7;
+   gst->guest_GPR10 = canonical->arg8;
+
+#elif defined(VGP_ppc64_aix5)
+   VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
+   gst->guest_GPR2  = canonical->sysno;
+   gst->guest_GPR3  = canonical->arg1;
+   gst->guest_GPR4  = canonical->arg2;
+   gst->guest_GPR5  = canonical->arg3;
+   gst->guest_GPR6  = canonical->arg4;
+   gst->guest_GPR7  = canonical->arg5;
+   gst->guest_GPR8  = canonical->arg6;
+   gst->guest_GPR9  = canonical->arg7;
+   gst->guest_GPR10 = canonical->arg8;
+
 #else
 #  error "putSyscallArgsIntoGuestState: unknown arch"
 #endif
@@ -406,103 +466,118 @@ static
 void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus*     canonical,
                                       /*IN*/ VexGuestArchState* gst_vanilla )
 {
-#if defined(VGP_x86_linux)
+#  if defined(VGP_x86_linux)
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
-   Int               i   = (Int)gst->guest_EAX;
-   canonical->what = i >= -4095 && i <= -1  ? SsFailure  : SsSuccess;
-   canonical->val  = (UWord)(canonical->what==SsFailure ? -i : i);
+   canonical->sres = VG_(mk_SysRes_x86_linux)( gst->guest_EAX );
+   canonical->what = SsComplete;
 
-#elif defined(VGP_amd64_linux)
+#  elif defined(VGP_amd64_linux)
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
-   Long                i   = (Long)gst->guest_RAX;
-   canonical->what = i >= -4095 && i <= -1  ? SsFailure  : SsSuccess;
-   canonical->val  = (UWord)(canonical->what==SsFailure ? -i : i);
-
-#elif defined(VGP_ppc32_linux)
+   canonical->sres = VG_(mk_SysRes_amd64_linux)( gst->guest_RAX );
+   canonical->what = SsComplete;
+
+#  elif defined(VGP_ppc32_linux)
+   VexGuestPPC32State* gst   = (VexGuestPPC32State*)gst_vanilla;
+   UInt                cr    = LibVEX_GuestPPC32_get_CR( gst );
+   UInt                cr0so = (cr >> 28) & 1;
+   canonical->sres = VG_(mk_SysRes_ppc32_linux)( gst->guest_GPR3, cr0so );
+   canonical->what = SsComplete;
+
+#  elif defined(VGP_ppc64_linux)
+   VexGuestPPC64State* gst   = (VexGuestPPC64State*)gst_vanilla;
+   UInt                cr    = LibVEX_GuestPPC64_get_CR( gst );
+   UInt                cr0so = (cr >> 28) & 1;
+   canonical->sres = VG_(mk_SysRes_ppc64_linux)( gst->guest_GPR3, cr0so );
+   canonical->what = SsComplete;
+
+#  elif defined(VGP_ppc32_aix5)
    VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
-   UInt                cr  = LibVEX_GuestPPC32_get_CR( gst );
-   UInt                err = (cr >> 28) & 1;  // CR0.SO
-   canonical->what = (err == 1)  ? SsFailure  : SsSuccess;
-   canonical->val  = (UWord)gst->guest_GPR3;
+   canonical->sres = VG_(mk_SysRes_ppc32_aix5)( gst->guest_GPR3, 
+                                                gst->guest_GPR4 );
+   canonical->what = SsComplete;
 
-#elif defined(VGP_ppc64_linux)
+#  elif defined(VGP_ppc64_aix5)
    VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
-   UInt                cr  = LibVEX_GuestPPC64_get_CR( gst );
-   UInt                err = (cr >> 28) & 1;  // CR0.SO
-   canonical->what = (err == 1)  ? SsFailure  : SsSuccess;
-   canonical->val  = (UWord)gst->guest_GPR3;
+   canonical->sres = VG_(mk_SysRes_ppc64_aix5)( gst->guest_GPR3, 
+                                                gst->guest_GPR4 );
+   canonical->what = SsComplete;
 
-#else
-#  error "getSyscallStatusFromGuestState: unknown arch"
-#endif
+#  else
+#    error "getSyscallStatusFromGuestState: unknown arch"
+#  endif
 }
 
 static 
 void putSyscallStatusIntoGuestState ( /*IN*/ SyscallStatus*     canonical,
                                       /*OUT*/VexGuestArchState* gst_vanilla )
 {
-#if defined(VGP_x86_linux)
+#  if defined(VGP_x86_linux)
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
-   vg_assert(canonical->what == SsSuccess 
-             || canonical->what == SsFailure);
-   if (canonical->what == SsFailure) {
+   vg_assert(canonical->what == SsComplete);
+   if (canonical->sres.isError) {
       /* This isn't exactly right, in that really a Failure with res
          not in the range 1 .. 4095 is unrepresentable in the
          Linux-x86 scheme.  Oh well. */
-      gst->guest_EAX = - (Int)canonical->val;
+      gst->guest_EAX = - (Int)canonical->sres.err;
    } else {
-      gst->guest_EAX = canonical->val;
+      gst->guest_EAX = canonical->sres.res;
    }
-#elif defined(VGP_amd64_linux)
+
+#  elif defined(VGP_amd64_linux)
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
-   vg_assert(canonical->what == SsSuccess 
-             || canonical->what == SsFailure);
-   if (canonical->what == SsFailure) {
+   vg_assert(canonical->what == SsComplete);
+   if (canonical->sres.isError) {
       /* This isn't exactly right, in that really a Failure with res
          not in the range 1 .. 4095 is unrepresentable in the
          Linux-x86 scheme.  Oh well. */
-      gst->guest_RAX = - (Long)canonical->val;
+      gst->guest_RAX = - (Long)canonical->sres.err;
    } else {
-      gst->guest_RAX = canonical->val;
+      gst->guest_RAX = canonical->sres.res;
    }
 
-#elif defined(VGP_ppc32_linux)
+#  elif defined(VGP_ppc32_linux)
    VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
    UInt old_cr = LibVEX_GuestPPC32_get_CR(gst);
-
-   vg_assert(canonical->what == SsSuccess 
-             || canonical->what == SsFailure);
-
-   gst->guest_GPR3 = canonical->val;
-
-   if (canonical->what == SsFailure) {
+   vg_assert(canonical->what == SsComplete);
+   if (canonical->sres.isError) {
       /* set CR0.SO */
       LibVEX_GuestPPC32_put_CR( old_cr | (1<<28), gst );
+      gst->guest_GPR3 = canonical->sres.err;
    } else {
       /* clear CR0.SO */
       LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), gst );
+      gst->guest_GPR3 = canonical->sres.res;
    }
 
-#elif defined(VGP_ppc64_linux)
+#  elif defined(VGP_ppc64_linux)
    VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
    UInt old_cr = LibVEX_GuestPPC64_get_CR(gst);
-
-   vg_assert(canonical->what == SsSuccess 
-             || canonical->what == SsFailure);
-
-   gst->guest_GPR3 = canonical->val;
-
-   if (canonical->what == SsFailure) {
+   vg_assert(canonical->what == SsComplete);
+   if (canonical->sres.isError) {
       /* set CR0.SO */
       LibVEX_GuestPPC64_put_CR( old_cr | (1<<28), gst );
+      gst->guest_GPR3 = canonical->sres.err;
    } else {
       /* clear CR0.SO */
       LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), gst );
+      gst->guest_GPR3 = canonical->sres.res;
    }
 
-#else
-#  error "putSyscallStatusIntoGuestState: unknown arch"
-#endif
+#  elif defined(VGP_ppc32_aix5)
+   VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
+   vg_assert(canonical->what == SsComplete);
+   gst->guest_GPR3 = canonical->sres.res;
+   gst->guest_GPR4 = canonical->sres.err;
+
+#  elif defined(VGP_ppc64_aix5)
+   VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
+   vg_assert(canonical->what == SsComplete);
+   gst->guest_GPR3 = canonical->sres.res;
+   gst->guest_GPR4 = canonical->sres.err;
+
+#  else
+#    error "putSyscallStatusIntoGuestState: unknown arch"
+#  endif
 }
 
 
@@ -521,6 +596,8 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
    layout->o_arg4   = OFFSET_x86_ESI;
    layout->o_arg5   = OFFSET_x86_EDI;
    layout->o_arg6   = OFFSET_x86_EBP;
+   layout->o_arg7   = -1; /* impossible value */
+   layout->o_arg8   = -1; /* impossible value */
    layout->o_retval = OFFSET_x86_EAX;
 
 #elif defined(VGP_amd64_linux)
@@ -531,6 +608,8 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
    layout->o_arg4   = OFFSET_amd64_R10;
    layout->o_arg5   = OFFSET_amd64_R8;
    layout->o_arg6   = OFFSET_amd64_R9;
+   layout->o_arg7   = -1; /* impossible value */
+   layout->o_arg8   = -1; /* impossible value */
    layout->o_retval = OFFSET_amd64_RAX;
 
 #elif defined(VGP_ppc32_linux)
@@ -541,6 +620,8 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
    layout->o_arg4   = OFFSET_ppc32_GPR6;
    layout->o_arg5   = OFFSET_ppc32_GPR7;
    layout->o_arg6   = OFFSET_ppc32_GPR8;
+   layout->o_arg7   = -1; /* impossible value */
+   layout->o_arg8   = -1; /* impossible value */
    layout->o_retval = OFFSET_ppc32_GPR3;
 
 #elif defined(VGP_ppc64_linux)
@@ -551,6 +632,32 @@ void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
    layout->o_arg4   = OFFSET_ppc64_GPR6;
    layout->o_arg5   = OFFSET_ppc64_GPR7;
    layout->o_arg6   = OFFSET_ppc64_GPR8;
+   layout->o_arg7   = -1; /* impossible value */
+   layout->o_arg8   = -1; /* impossible value */
+   layout->o_retval = OFFSET_ppc64_GPR3;
+
+#elif defined(VGP_ppc32_aix5)
+   layout->o_sysno  = OFFSET_ppc32_GPR2;
+   layout->o_arg1   = OFFSET_ppc32_GPR3;
+   layout->o_arg2   = OFFSET_ppc32_GPR4;
+   layout->o_arg3   = OFFSET_ppc32_GPR5;
+   layout->o_arg4   = OFFSET_ppc32_GPR6;
+   layout->o_arg5   = OFFSET_ppc32_GPR7;
+   layout->o_arg6   = OFFSET_ppc32_GPR8;
+   layout->o_arg7   = OFFSET_ppc32_GPR9;
+   layout->o_arg8   = OFFSET_ppc32_GPR10;
+   layout->o_retval = OFFSET_ppc32_GPR3;
+
+#elif defined(VGP_ppc64_aix5)
+   layout->o_sysno  = OFFSET_ppc64_GPR2;
+   layout->o_arg1   = OFFSET_ppc64_GPR3;
+   layout->o_arg2   = OFFSET_ppc64_GPR4;
+   layout->o_arg3   = OFFSET_ppc64_GPR5;
+   layout->o_arg4   = OFFSET_ppc64_GPR6;
+   layout->o_arg5   = OFFSET_ppc64_GPR7;
+   layout->o_arg6   = OFFSET_ppc64_GPR8;
+   layout->o_arg7   = OFFSET_ppc64_GPR9;
+   layout->o_arg8   = OFFSET_ppc64_GPR10;
    layout->o_retval = OFFSET_ppc64_GPR3;
 
 #else
@@ -591,13 +698,24 @@ static SyscallTableEntry bad_sys =
 
 static const SyscallTableEntry* get_syscall_entry ( UInt syscallno )
 {
-   const SyscallTableEntry* sys = &bad_sys;
+   const SyscallTableEntry* sys = NULL;
 
+#  if defined(VGO_linux)
    if (syscallno < ML_(syscall_table_size) &&
        ML_(syscall_table)[syscallno].before != NULL)
       sys = &ML_(syscall_table)[syscallno];
 
-   return sys;
+#  elif defined(VGP_ppc32_aix5)
+   sys = ML_(get_ppc32_aix5_syscall_entry) ( syscallno );
+
+#  elif defined(VGP_ppc64_aix5)
+   sys = ML_(get_ppc64_aix5_syscall_entry) ( syscallno );
+
+#  else
+#    error Unknown OS
+#  endif
+
+   return sys == NULL  ? &bad_sys  : sys;
 }
 
 
@@ -679,9 +797,11 @@ void VG_(client_syscall) ( ThreadId tid )
    sysno = sci->orig_args.sysno;
 
    /* The default what-to-do-next thing is hand the syscall to the
-      kernel, so we pre-set that here. */
+      kernel, so we pre-set that here.  Set .sres to something
+      harmless looking (is irrelevant because .what is not
+      SsComplete.) */
    sci->status.what = SsHandToKernel;
-   sci->status.val  = 0;
+   sci->status.sres = VG_(mk_SysRes_Error)(0);
    sci->flags       = 0;
 
    /* Fetch the syscall's handlers.  If no handlers exist for this
@@ -732,14 +852,13 @@ void VG_(client_syscall) ( ThreadId tid )
    */
    /* Now we proceed according to what the pre-handler decided. */
    vg_assert(sci->status.what == SsHandToKernel
-             || sci->status.what == SsSuccess
-             || sci->status.what == SsFailure);
+             || sci->status.what == SsComplete);
    vg_assert(sci->args.sysno == sci->orig_args.sysno);
 
-   if (sci->status.what == SsSuccess) {
+   if (sci->status.what == SsComplete && !sci->status.sres.isError) {
       /* The pre-handler completed the syscall itself, declaring
          success. */
-      PRINT(" --> [pre-success] Success(0x%llx)\n", (Long)sci->status.val );
+      PRINT(" --> [pre-success] Success(0x%llx)\n", (ULong)sci->status.sres.res );
                                        
       /* In this case the allowable flags are to ask for a signal-poll
          and/or a yield after the call.  Changing the args isn't
@@ -749,9 +868,9 @@ void VG_(client_syscall) ( ThreadId tid )
    }
 
    else
-   if (sci->status.what == SsFailure) {
+   if (sci->status.what == SsComplete && sci->status.sres.isError) {
       /* The pre-handler decided to fail syscall itself. */
-      PRINT(" --> [pre-fail] Failure(0x%llx)\n", (Long)sci->status.val );
+      PRINT(" --> [pre-fail] Failure(0x%llx)\n", (ULong)sci->status.sres.err );
       /* In this case, the pre-handler is also allowed to ask for the
          post-handler to be run anyway.  Changing the args is not
          allowed. */
@@ -796,7 +915,7 @@ void VG_(client_syscall) ( ThreadId tid )
          putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex );
 
          /* Drop the lock */
-         VG_(set_sleeping)(tid, VgTs_WaitSys);
+         VG_(set_sleeping)(tid, VgTs_WaitSys, "VG_(client_syscall)[async]");
 
          /* Do the call, which operates directly on the guest state,
             not on our abstracted copies of the args/result. */
@@ -811,16 +930,18 @@ void VG_(client_syscall) ( ThreadId tid )
             to the scheduler.  */
 
          /* Reacquire the lock */
-         VG_(set_running)(tid);
+         VG_(set_running)(tid, "VG_(client_syscall)[async]");
 
          /* Even more impedance matching.  Extract the syscall status
             from the guest state. */
          getSyscallStatusFromGuestState( &sci->status, &tst->arch.vex );
+         vg_assert(sci->status.what == SsComplete);
 
          PRINT("SYSCALL[%d,%d](%3d) ... [async] --> %s(0x%llx)\n",
                VG_(getpid)(), tid, sysno, 
-               sci->status.what==SsSuccess ? "Success" : "Failure",
-               (Long)sci->status.val );
+               sci->status.sres.isError ? "Failure" : "Success",
+               sci->status.sres.isError ? (ULong)sci->status.sres.err
+                                        : (ULong)sci->status.sres.res );
 
       } else {
 
@@ -830,21 +951,21 @@ void VG_(client_syscall) ( ThreadId tid )
             kernel, there's no point in flushing them back to the
             guest state.  Indeed doing so could be construed as
             incorrect. */
-
          SysRes sres 
-            = VG_(do_syscall6)(sysno, sci->args.arg1, sci->args.arg2, 
-                                      sci->args.arg3, sci->args.arg4, 
-                                      sci->args.arg5, sci->args.arg6 );
+            = VG_(do_syscall)(sysno, sci->args.arg1, sci->args.arg2, 
+                                     sci->args.arg3, sci->args.arg4, 
+                                     sci->args.arg5, sci->args.arg6,
+                                     sci->args.arg7, sci->args.arg8 );
          sci->status = convert_SysRes_to_SyscallStatus(sres);
 
          PRINT("[sync] --> %s(0x%llx)\n",
-               sci->status.what==SsSuccess ? "Success" : "Failure",
-               (Long)sci->status.val );
+               sci->status.sres.isError ? "Failure" : "Success",
+               sci->status.sres.isError ? (ULong)sci->status.sres.err
+                                        : (ULong)sci->status.sres.res );
       }
    }
 
-   vg_assert(sci->status.what == SsFailure 
-             || sci->status.what == SsSuccess);
+   vg_assert(sci->status.what == SsComplete);
 
    vg_assert(VG_(is_running_thread)(tid));
 
@@ -902,8 +1023,7 @@ void VG_(post_syscall) (ThreadId tid)
    /* Validate current syscallInfo entry.  In particular we require
       that the current .status matches what's actually in the guest
       state. */
-   vg_assert(sci->status.what == SsFailure 
-             || sci->status.what == SsSuccess);
+   vg_assert(sci->status.what == SsComplete);
 
    getSyscallStatusFromGuestState( &test_status, &tst->arch.vex );
    vg_assert(eq_SyscallStatus( &sci->status, &test_status ));
@@ -924,13 +1044,14 @@ void VG_(post_syscall) (ThreadId tid)
    VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, layout.o_retval, 
                                                   sizeof(UWord) );
 
-   /* Consider, either success or failure.  Now run the post handler if:
+   /* pre: status == Complete (asserted above) */
+   /* Consider either success or failure.  Now run the post handler if:
       - it exists, and
-      - status==Success or (status==Fail and PostOnFail is set)
+      - Success or (Failure and PostOnFail is set)
    */
    if (ent->after
-       && (sci->status.what == SsSuccess
-           || (sci->status.what == SsFailure
+       && ((!sci->status.sres.isError)
+           || (sci->status.sres.isError
                && (sci->flags & SfPostOnFail) ))) {
 
       (ent->after)( tid, &sci->args, &sci->status );
@@ -943,14 +1064,11 @@ void VG_(post_syscall) (ThreadId tid)
    putSyscallStatusIntoGuestState( &sci->status, &tst->arch.vex );
 
    /* Do any post-syscall actions required by the tool. */
-   if (VG_(needs).syscall_wrapper) {
-      SysRes res;
-      res.val     = sci->status.val;
-      res.isError = sci->status.what == SsFailure;
-      VG_TDICT_CALL(tool_post_syscall, tid, sysno, res);
-   }
+   if (VG_(needs).syscall_wrapper)
+      VG_TDICT_CALL(tool_post_syscall, tid, sysno, sci->status.sres);
 
    /* The syscall is done. */
+   vg_assert(sci->status.what == SsComplete);
    sci->status.what = SsIdle;
 
    /* The pre/post wrappers may have concluded that pending signals
@@ -1063,6 +1181,32 @@ void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
       vg_assert(p[0] == 0x44 && p[1] == 0x0 && p[2] == 0x0 && p[3] == 0x2);
    }
 
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+   /* Hmm.  This is problematic, because on AIX the kernel resumes
+      after a syscall at LR, not at the insn following SC.  Hence
+      there is no obvious way to figure out where the SC is.  Current
+      solution is to have a pseudo-register in the guest state,
+      CIA_AT_SC, which holds the address of the most recent SC
+      executed.  Backing up to that syscall then simply involves
+      copying that value back into CIA (the program counter). */
+   arch->vex.guest_CIA = arch->vex.guest_CIA_AT_SC;
+
+   /* Make sure our caller is actually sane, and we're really backing
+      back over a syscall.
+
+      sc == 44 00 00 02
+   */
+   {
+      UChar *p = (UChar *)arch->vex.guest_CIA;
+
+      if (p[0] != 0x44 || p[1] != 0x0 || p[2] != 0x0 || p[3] != 0x02)
+         VG_(message)(Vg_DebugMsg,
+                      "?! restarting over syscall at %p %02x %02x %02x %02x\n",
+                      arch->vex.guest_CIA, p[0], p[1], p[2], p[3]);
+
+      vg_assert(p[0] == 0x44 && p[1] == 0x0 && p[2] == 0x0 && p[3] == 0x2);
+   }
+
 #else
 #  error "ML_(fixup_guest_state_to_restart_syscall): unknown plat"
 #endif
@@ -1102,7 +1246,7 @@ void
 VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid, 
                                                   Addr     ip, 
                                                   UWord    sysnum, 
-                                                  SysRes   sysret,
+                                                  SysRes   sres,
                                                   Bool     restart)
 {
    /* Note that the sysnum arg seems to contain not-dependable-on info
@@ -1124,8 +1268,8 @@ VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
                    (Int)tid,
                    (ULong)ip, 
                    restart ? "True" : "False", 
-                   sysret.isError ? "True" : "False",
-                   (Long)(Word)sysret.val );
+                   sres.isError ? "True" : "False",
+                   (Long)(Word)(sres.isError ? sres.err : sres.res) );
 
    vg_assert(VG_(is_valid_tid)(tid));
    vg_assert(tid >= 1 && tid < VG_N_THREADS);
@@ -1182,8 +1326,8 @@ VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
          Write the SysRes we were supplied with back to the guest
          state. */
       if (debug)
-         VG_(printf)("  completed\n", sysret);
-      canonical = convert_SysRes_to_SyscallStatus( sysret );
+         VG_(printf)("  completed\n");
+      canonical = convert_SysRes_to_SyscallStatus( sres );
       putSyscallStatusIntoGuestState( &canonical, &th_regs->vex );
       sci->status = canonical;
       VG_(post_syscall)(tid);
index cde953f8e8adfd547b627d311c2206dec3b8e8c3..5071aad55bd80b4b553b616c22ba5ea77a801489 100644 (file)
@@ -239,7 +239,7 @@ static SysRes do_clone ( ThreadId ptid,
    ThreadState* ctst = VG_(get_ThreadState)(ctid);
    ULong        word64;
    UWord*       stack;
-   NSegment*    seg;
+   NSegment const* seg;
    SysRes       res;
    vki_sigset_t blockall, savedmask;
 
@@ -1060,7 +1060,7 @@ PRE(sys_sigreturn)
       It's a conceptual copy-n-paste from the x86 equivalent, but I'm 
       equally unclear as to whether it is needed there either.
    */
-   SET_STATUS_from_SysRes_NO_SANITY_CHECK(
+   SET_STATUS_from_SysRes(
       VG_(mk_SysRes_ppc32_linux)( 
          tst->arch.vex.guest_GPR3,
          /* get CR0.SO */
@@ -1095,7 +1095,7 @@ PRE(sys_rt_sigreturn)
    VG_(sigframe_destroy)(tid, True);
 
    /* See comments above in PRE(sys_sigreturn) about this. */
-   SET_STATUS_from_SysRes_NO_SANITY_CHECK(
+   SET_STATUS_from_SysRes(
       VG_(mk_SysRes_ppc32_linux)( 
          tst->arch.vex.guest_GPR3,
          /* get CR0.SO */
index 0f5791b3d4558a31635106cb71bae5c0f9f822d6..8350daadd536779e446ec39808d8b635ef6cee0b 100644 (file)
@@ -267,7 +267,7 @@ static SysRes do_clone ( ThreadId ptid,
    ThreadState* ctst = VG_(get_ThreadState)(ctid);
    ULong        word64;
    UWord*       stack;
-   NSegment*    seg;
+   NSegment const* seg;
    SysRes       res;
    vki_sigset_t blockall, savedmask;
 
@@ -1073,7 +1073,7 @@ PRE(sys_rt_sigreturn)
    VG_(sigframe_destroy)(tid, True);
 
    /* See comments above in PRE(sys_sigreturn) about this. */
-   SET_STATUS_from_SysRes_NO_SANITY_CHECK(
+   SET_STATUS_from_SysRes(
       VG_(mk_SysRes_ppc64_linux)( 
          tst->arch.vex.guest_GPR3,
          /* get CR0.SO */
index 26a0d9b8bed566173d8dd8a8d7bba9e630892a97..5911ce81ee6b03377770bb5a514e1bd1da697a82 100644 (file)
@@ -213,7 +213,7 @@ static SysRes do_clone ( ThreadId ptid,
    ThreadState* ptst = VG_(get_ThreadState)(ptid);
    ThreadState* ctst = VG_(get_ThreadState)(ctid);
    UWord*       stack;
-   NSegment*    seg;
+   NSegment const* seg;
    SysRes       res;
    Int          eax;
    vki_sigset_t blockall, savedmask;