]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merged non-Darwin-specific parts of r9397,r9423,r9490, 9461, 9462 from the
authorNicholas Nethercote <njn@valgrind.org>
Mon, 18 May 2009 02:12:08 +0000 (02:12 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Mon, 18 May 2009 02:12:08 +0000 (02:12 +0000)
DARWIN branch.  A big ugly DARWIN/trunk sync commit, mostly to do with
changing the representation of SysRes and vki_sigset_t.  Functionality of
the trunk shouldn't be changed by it.

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

56 files changed:
cachegrind/cg_main.c
callgrind/command.c
callgrind/dump.c
coregrind/m_aspacemgr/aspacemgr-common.c
coregrind/m_aspacemgr/aspacemgr-linux.c
coregrind/m_commandline.c
coregrind/m_coredump/coredump-elf.c
coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/readelf.c
coregrind/m_errormgr.c
coregrind/m_initimg/initimg-linux.c
coregrind/m_libcfile.c
coregrind/m_libcproc.c
coregrind/m_libcsignal.c
coregrind/m_machine.c
coregrind/m_main.c
coregrind/m_mallocfree.c
coregrind/m_scheduler/scheduler.c
coregrind/m_signals.c
coregrind/m_syscall.c
coregrind/m_syswrap/priv_types_n_macros.h
coregrind/m_syswrap/syscall-amd64-linux.S
coregrind/m_syswrap/syscall-ppc32-aix5.S
coregrind/m_syswrap/syscall-ppc32-linux.S
coregrind/m_syswrap/syscall-ppc64-aix5.S
coregrind/m_syswrap/syscall-ppc64-linux.S
coregrind/m_syswrap/syscall-x86-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
coregrind/m_transtab.c
coregrind/m_ume/elf.c
coregrind/m_ume/main.c
coregrind/m_ume/script.c
coregrind/m_vki.c
coregrind/pub_core_libcfile.h
coregrind/pub_core_libcsignal.h
coregrind/pub_core_machine.h
coregrind/pub_core_signals.h
coregrind/pub_core_syscall.h
coregrind/pub_core_syswrap.h
coregrind/pub_core_trampoline.h
coregrind/pub_core_vki.h
exp-ptrcheck/h_main.c
include/pub_tool_basics.h
include/pub_tool_libcfile.h
include/vki/vki-amd64-linux.h
include/vki/vki-ppc32-linux.h
include/vki/vki-ppc64-linux.h
include/vki/vki-x86-linux.h
massif/ms_main.c
memcheck/tests/unit_libcbase.c

index 6d7ce8767d46d62294a9f295bc7a06d8014c18f7..279356bd5e102958dea1019ee2dab7aa7cb4182c 100644 (file)
@@ -1262,7 +1262,7 @@ static void fprint_CC_table_and_calc_totals(void)
 
    sres = VG_(open)(cachegrind_out_file, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY,
                                          VKI_S_IRUSR|VKI_S_IWUSR);
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       // If the file can't be opened for whatever reason (conflict
       // between multiple cachegrinded processes?), give up now.
       VG_UMSG("error: can't open cache simulation output file '%s'",
@@ -1271,7 +1271,7 @@ static void fprint_CC_table_and_calc_totals(void)
       VG_(free)(cachegrind_out_file);
       return;
    } else {
-      fd = sres.res;
+      fd = sr_Res(sres);
       VG_(free)(cachegrind_out_file);
    }
 
index 46c7f4419df3786a25b5b74776a5badedcc82777..78f57d85a51d39a072f3ca01aa4dbeb8300420ce 100644 (file)
@@ -108,18 +108,18 @@ static void setup_control(void)
 
   /* create info file to indicate that we are running */ 
   res = VG_(open)(info_file, VKI_O_WRONLY|VKI_O_TRUNC, 0);
-  if (res.isError) { 
+  if (sr_isError(res)) { 
     res = VG_(open)(info_file, VKI_O_CREAT|VKI_O_WRONLY,
                   VKI_S_IRUSR|VKI_S_IWUSR);
-    if (res.isError) {
+    if (sr_isError(res)) {
       VG_(message)(Vg_DebugMsg, 
                   "warning: can't write info file '%s'", info_file);
       info_file = 0;
       fd = -1;
     }
   }
-  if (!res.isError)
-      fd = (Int) res.res;
+  if (!sr_isError(res))
+      fd = (Int) sr_Res(res);
   if (fd>=0) {
     Char buf[512];
     Int i;
@@ -177,8 +177,8 @@ static Int createRes(Int fd)
     /* VG_(open) can return any negative number on error. Remap errors to -1,
      * to not confuse it with our special value -2
      */
-    if (res.isError) fd = -1;
-    else fd = (Int) res.res;
+    if (sr_isError(res)) fd = -1;
+    else fd = (Int) sr_Res(res);
 
     return fd;
 }
@@ -380,8 +380,8 @@ void CLG_(check_command)()
     }
     
     res = VG_(open)(current_command_file, VKI_O_RDONLY,0);
-    if (!res.isError) {
-       fd = (Int) res.res;
+    if (!sr_isError(res)) {
+        fd = (Int) sr_Res(res);
        bytesRead = VG_(read)(fd,cmdBuffer,500);
        cmdBuffer[500] = 0; /* no command overrun please */
        VG_(close)(fd);
index 17414cae18df8223c3e26afe9c1ea078e67af042..28bb8eb2989f2b64501f65423f9cac0802b6fcd1 100644 (file)
@@ -1303,20 +1303,20 @@ static int new_dumpfile(Char buf[BUF_LEN], int tid, Char* trigger)
     else {
        VG_(sprintf)(filename, "%s", out_file);
         res = VG_(open)(filename, VKI_O_WRONLY|VKI_O_APPEND, 0);
-       if (!res.isError && out_counter>1)
+       if (!sr_isError(res) && out_counter>1)
            appending = True;
     }
 
-    if (res.isError) {
+    if (sr_isError(res)) {
        res = VG_(open)(filename, VKI_O_CREAT|VKI_O_WRONLY,
                        VKI_S_IRUSR|VKI_S_IWUSR);
-       if (res.isError) {
+       if (sr_isError(res)) {
            /* If the file can not be opened for whatever reason (conflict
               between multiple supervised processes?), give up now. */
            file_err();
        }
     }
-    fd = (Int) res.res;
+    fd = (Int) sr_Res(res);
 
     CLG_DEBUG(2, "  new_dumpfile '%s'\n", filename);
 
@@ -1724,14 +1724,14 @@ void CLG_(init_dumps)()
     */ 
     VG_(strcpy)(filename, out_file);
     res = VG_(open)(filename, VKI_O_WRONLY|VKI_O_TRUNC, 0);
-    if (res.isError) { 
+    if (sr_isError(res)) { 
        res = VG_(open)(filename, VKI_O_CREAT|VKI_O_WRONLY,
                       VKI_S_IRUSR|VKI_S_IWUSR);
-       if (res.isError) {
+       if (sr_isError(res)) {
            file_err(); 
        }
     }
-    if (!res.isError) VG_(close)( (Int)res.res );
+    if (!sr_isError(res)) VG_(close)( (Int)sr_Res(res) );
 
     if (!dumps_initialized)
        init_cmdbuf();
index dd1238e52c033005f59819a789b3243ec4c0a9b5..f6f04888700340ec8bcbaf5d9819b9aad7b83734 100644 (file)
@@ -95,8 +95,8 @@ void ML_(am_assert_fail)( const HChar* expr,
 Int ML_(am_getpid)( void )
 {
    SysRes sres = VG_(do_syscall0)(__NR_getpid);
-   aspacem_assert(!sres.isError);
-   return sres.res;
+   aspacem_assert(!sr_isError(sres));
+   return sr_Res(sres);
 }
 
 
@@ -238,7 +238,7 @@ SysRes ML_(am_open) ( const Char* pathname, Int flags, Int mode )
 Int ML_(am_read) ( Int fd, void* buf, Int count)
 {
    SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
 void ML_(am_close) ( Int fd )
@@ -250,13 +250,17 @@ Int ML_(am_readlink)(HChar* path, HChar* buf, UInt bufsiz)
 {
    SysRes res;
    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
 Int ML_(am_fcntl) ( Int fd, Int cmd, Addr arg )
 {
+#  if defined(VGO_linux) || defined(VGO_aix5)
    SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
-   return res.isError ? -1 : res.res;
+#  else
+#  error "Unknown OS"
+#  endif
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
 /* Get the dev, inode and mode info for a file descriptor, if
@@ -273,7 +277,7 @@ Bool ML_(am_get_fd_d_i_m)( Int fd,
       binaries on amd64 systems where fstat seems to be broken. */
    struct vki_stat64 buf64;
    res = VG_(do_syscall2)(__NR_fstat64, fd, (UWord)&buf64);
-   if (!res.isError) {
+   if (!sr_isError(res)) {
       *dev  = (ULong)buf64.st_dev;
       *ino  = (ULong)buf64.st_ino;
       *mode = (UInt) buf64.st_mode;
@@ -281,7 +285,7 @@ Bool ML_(am_get_fd_d_i_m)( Int fd,
    }
 #  endif
    res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf);
-   if (!res.isError) {
+   if (!sr_isError(res)) {
       *dev  = (ULong)buf.st_dev;
       *ino  = (ULong)buf.st_ino;
       *mode = (UInt) buf.st_mode;
@@ -339,10 +343,10 @@ VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp )
          + VG_STACK_ACTIVE_SZB + VG_STACK_GUARD_SZB;
 
    sres = VG_(am_mmap_anon_float_valgrind)( szB );
-   if (sres.isError)
+   if (sr_isError(sres))
       return NULL;
 
-   stack = (VgStack*)sres.res;
+   stack = (VgStack*)(AddrH)sr_Res(sres);
 
    aspacem_assert(VG_IS_PAGE_ALIGNED(szB));
    aspacem_assert(VG_IS_PAGE_ALIGNED(stack));
@@ -352,7 +356,7 @@ VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp )
              (Addr) &stack[0], 
              VG_STACK_GUARD_SZB, VKI_PROT_NONE 
           );
-   if (sres.isError) goto protect_failed;
+   if (sr_isError(sres)) goto protect_failed;
    VG_(am_notify_mprotect)( 
       (Addr) &stack->bytes[0], 
       VG_STACK_GUARD_SZB, VKI_PROT_NONE 
@@ -362,7 +366,7 @@ VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp )
              (Addr) &stack->bytes[VG_STACK_GUARD_SZB + VG_STACK_ACTIVE_SZB], 
              VG_STACK_GUARD_SZB, VKI_PROT_NONE 
           );
-   if (sres.isError) goto protect_failed;
+   if (sr_isError(sres)) goto protect_failed;
    VG_(am_notify_mprotect)( 
       (Addr) &stack->bytes[VG_STACK_GUARD_SZB + VG_STACK_ACTIVE_SZB],
       VG_STACK_GUARD_SZB, VKI_PROT_NONE 
@@ -377,7 +381,7 @@ VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp )
 
    *initial_sp = (Addr)&stack->bytes[VG_STACK_GUARD_SZB + VG_STACK_ACTIVE_SZB];
    *initial_sp -= 8;
-   *initial_sp &= ~((Addr)0xF);
+   *initial_sp &= ~((Addr)0x1F); /* 32-align it */
 
    VG_(debugLog)( 1,"aspacem","allocated thread stack at 0x%llx size %d\n",
                   (ULong)(Addr)stack, szB);
index 57772dcb617cb842727579b0d9289282342200f9..4f09b67922b591d8677305d87ff0f9c3c2d5cfba 100644 (file)
@@ -2121,14 +2121,14 @@ SysRes VG_(am_mmap_file_fixed_client)
              VKI_MAP_FIXED|VKI_MAP_PRIVATE, 
              fd, offset 
           );
-   if (sres.isError)
+   if (sr_isError(sres))
       return sres;
 
-   if (sres.res != start) {
+   if (sr_Res(sres) != start) {
       /* I don't think this can happen.  It means the kernel made a
          fixed map succeed but not at the requested location.  Try to
          repair the damage, then return saying the mapping failed. */
-      (void)ML_(am_do_munmap_NO_NOTIFY)( sres.res, length );
+      (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length );
       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 
@@ -2187,14 +2187,14 @@ SysRes VG_(am_mmap_anon_fixed_client) ( Addr start, SizeT length, UInt prot )
              VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 
              0, 0 
           );
-   if (sres.isError)
+   if (sr_isError(sres))
       return sres;
 
-   if (sres.res != start) {
+   if (sr_Res(sres) != start) {
       /* I don't think this can happen.  It means the kernel made a
          fixed map succeed but not at the requested location.  Try to
          repair the damage, then return saying the mapping failed. */
-      (void)ML_(am_do_munmap_NO_NOTIFY)( sres.res, length );
+      (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length );
       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 
@@ -2244,14 +2244,14 @@ SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot )
              VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 
              0, 0 
           );
-   if (sres.isError)
+   if (sr_isError(sres))
       return sres;
 
-   if (sres.res != advised) {
+   if (sr_Res(sres) != advised) {
       /* I don't think this can happen.  It means the kernel made a
          fixed map succeed but not at the requested location.  Try to
          repair the damage, then return saying the mapping failed. */
-      (void)ML_(am_do_munmap_NO_NOTIFY)( sres.res, length );
+      (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length );
       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 
@@ -2318,21 +2318,21 @@ SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length )
              VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 
              0, 0 
           );
-   if (sres.isError)
+   if (sr_isError(sres))
       return sres;
 
-   if (sres.res != advised) {
+   if (sr_Res(sres) != advised) {
       /* I don't think this can happen.  It means the kernel made a
          fixed map succeed but not at the requested location.  Try to
          repair the damage, then return saying the mapping failed. */
-      (void)ML_(am_do_munmap_NO_NOTIFY)( sres.res, length );
+      (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length );
       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 
    /* Ok, the mapping succeeded.  Now notify the interval map. */
    init_nsegment( &seg );
    seg.kind  = SkAnonV;
-   seg.start = advised;
+   seg.start = sr_Res(sres);
    seg.end   = seg.start + VG_PGROUNDUP(length) - 1;
    seg.hasR  = True;
    seg.hasW  = True;
@@ -2348,7 +2348,7 @@ SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length )
 void* VG_(am_shadow_alloc)(SizeT size)
 {
    SysRes sres = VG_(am_mmap_anon_float_valgrind)( size );
-   return sres.isError ? NULL : (void*)sres.res;
+   return sr_isError(sres) ? NULL : (void*)sr_Res(sres);
 }
 
 /* Same comments apply as per VG_(am_sbrk_anon_float_client).  On
@@ -2396,21 +2396,21 @@ SysRes VG_(am_mmap_file_float_valgrind) ( SizeT length, UInt prot,
              VKI_MAP_FIXED|VKI_MAP_PRIVATE, 
              fd, offset 
           );
-   if (sres.isError)
+   if (sr_isError(sres))
       return sres;
 
-   if (sres.res != advised) {
+   if (sr_Res(sres) != advised) {
       /* I don't think this can happen.  It means the kernel made a
          fixed map succeed but not at the requested location.  Try to
          repair the damage, then return saying the mapping failed. */
-      (void)ML_(am_do_munmap_NO_NOTIFY)( sres.res, length );
+      (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length );
       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 
    /* Ok, the mapping succeeded.  Now notify the interval map. */
    init_nsegment( &seg );
    seg.kind   = SkFileV;
-   seg.start  = sres.res;
+   seg.start  = sr_Res(sres);
    seg.end    = seg.start + VG_PGROUNDUP(length) - 1;
    seg.offset = offset;
    seg.hasR   = toBool(prot & VKI_PROT_READ);
@@ -2467,7 +2467,7 @@ SysRes am_munmap_both_wrk ( /*OUT*/Bool* need_discard,
    d = any_Ts_in_range( start, len );
 
    sres = ML_(am_do_munmap_NO_NOTIFY)( start, len );
-   if (sres.isError)
+   if (sr_isError(sres))
       return sres;
 
    VG_(am_notify_munmap)( start, len );
@@ -2501,7 +2501,7 @@ SysRes VG_(am_munmap_valgrind)( Addr start, SizeT len )
                                   start, len, False/*valgrind*/ );
    /* If this assertion fails, it means we allowed translations to be
       made from a V-owned section.  Which shouldn't happen. */
-   if (!r.isError)
+   if (!sr_isError(r))
       aspacem_assert(!need_discard);
    return r;
 }
@@ -2693,11 +2693,11 @@ Bool VG_(am_extend_into_adjacent_reservation_client) ( NSegment* seg,
                 VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 
                 0, 0 
              );
-      if (sres.isError)
+      if (sr_isError(sres))
          return False; /* kernel bug if this happens? */
-      if (sres.res != nsegments[segR].start) {
+      if (sr_Res(sres) != nsegments[segR].start) {
          /* kernel bug if this happens? */
-        (void)ML_(am_do_munmap_NO_NOTIFY)( sres.res, delta );
+        (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), delta );
         return False;
       }
 
@@ -2728,11 +2728,11 @@ Bool VG_(am_extend_into_adjacent_reservation_client) ( NSegment* seg,
                 VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 
                 0, 0 
              );
-      if (sres.isError)
+      if (sr_isError(sres))
          return False; /* kernel bug if this happens? */
-      if (sres.res != nsegments[segA].start-delta) {
+      if (sr_Res(sres) != nsegments[segA].start-delta) {
          /* kernel bug if this happens? */
-        (void)ML_(am_do_munmap_NO_NOTIFY)( sres.res, delta );
+        (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), delta );
         return False;
       }
 
@@ -2787,12 +2787,12 @@ Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard,
    sres = ML_(am_do_extend_mapping_NO_NOTIFY)( seg->start, 
                                                seg_old_len,
                                                seg_old_len + delta );
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       AM_SANITY_CHECK;
       return False;
    } else {
       /* the area must not have moved */
-      aspacem_assert(sres.res == seg->start);
+      aspacem_assert(sr_Res(sres) == seg->start);
    }
 
    *need_discard = any_Ts_in_range( seg_copy.end+1, delta );
@@ -2852,11 +2852,11 @@ Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
 
    sres = ML_(am_do_relocate_nooverlap_mapping_NO_NOTIFY)
              ( old_addr, old_len, new_addr, new_len );
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       AM_SANITY_CHECK;
       return False;
    } else {
-      aspacem_assert(sres.res == new_addr);
+      aspacem_assert(sr_Res(sres) == new_addr);
    }
 
    *need_discard = any_Ts_in_range( old_addr, old_len )
@@ -2983,18 +2983,18 @@ static void read_procselfmaps_into_buf ( void )
    
    /* Read the initial memory mapping from the /proc filesystem. */
    fd = ML_(am_open)( "/proc/self/maps", VKI_O_RDONLY, 0 );
-   if (fd.isError)
+   if (sr_isError(fd))
       ML_(am_barf)("can't open /proc/self/maps");
 
    buf_n_tot = 0;
    do {
-      n_chunk = ML_(am_read)( fd.res, &procmap_buf[buf_n_tot],
+      n_chunk = ML_(am_read)( sr_Res(fd), &procmap_buf[buf_n_tot],
                               M_PROCMAP_BUF - buf_n_tot );
       if (n_chunk >= 0)
          buf_n_tot += n_chunk;
    } while ( n_chunk > 0 && buf_n_tot < M_PROCMAP_BUF );
 
-   ML_(am_close)(fd.res);
+   ML_(am_close)(sr_Res(fd));
 
    if (buf_n_tot >= M_PROCMAP_BUF-5)
       ML_(am_barf_toolow)("M_PROCMAP_BUF");
index 713fa4ce49e7213e0cfdaed0cf81259c165c5881..60c4d3dcc14e93e2f189c7d1e96c4cf22be40ce1 100644 (file)
@@ -64,15 +64,15 @@ static HChar* read_dot_valgrindrc ( HChar* dir )
    VG_(snprintf)(filename, VKI_PATH_MAX, "%s/.valgrindrc", 
                            ( NULL == dir ? "" : dir ) );
    fd = VG_(open)(filename, 0, VKI_S_IRUSR);
-   if ( !fd.isError ) {
-      Int res = VG_(fstat)( fd.res, &stat_buf );
+   if ( !sr_isError(fd) ) {
+      Int res = VG_(fstat)( sr_Res(fd), &stat_buf );
       // Ignore if not owned by current user or world writeable (CVE-2008-4865)
       if (!res && stat_buf.st_uid == VG_(geteuid)()
           && (!(stat_buf.st_mode & VKI_S_IWOTH))) {
          if ( stat_buf.st_size > 0 ) {
             f_clo = VG_(malloc)("commandline.rdv.1", stat_buf.st_size+1);
             vg_assert(f_clo);
-            n = VG_(read)(fd.res, f_clo, stat_buf.st_size);
+            n = VG_(read)(sr_Res(fd), f_clo, stat_buf.st_size);
             if (n == -1) n = 0;
             vg_assert(n >= 0 && n <= stat_buf.st_size+1);
             f_clo[n] = '\0';
@@ -83,7 +83,7 @@ static HChar* read_dot_valgrindrc ( HChar* dir )
                "%s was not read as it is world writeable or not owned by the "
                "current user", filename);
 
-      VG_(close)(fd.res);
+      VG_(close)(sr_Res(fd));
    }
    return f_clo;
 }
index 5ce480147319dfa520b3eb67042bcb5f4f0f845d..00699c17144d807a6293461a7fce5561a5c0e085 100644 (file)
@@ -300,12 +300,12 @@ void make_elf_coredump(ThreadId tid, const vki_siginfo_t *si, UInt max_size)
       sres = VG_(open)(buf,                       
                        VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC, 
                        VKI_S_IRUSR|VKI_S_IWUSR);
-      if (!sres.isError) {
-         core_fd = sres.res;
+      if (!sr_isError(sres)) {
+         core_fd = sr_Res(sres);
         break;
       }
 
-      if (sres.isError && sres.err != VKI_EEXIST)
+      if (sr_isError(sres) && sr_Err(sres) != VKI_EEXIST)
         return;                /* can't create file */
    }
 
index b4e2e63756d19a553ebfc6d482faef4fb4ed6e12..1aa6125e2638eaf904b5d307c6547bc3018eac03 100644 (file)
@@ -645,11 +645,11 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
 
    /* stat dereferences symlinks, so we don't expect it to succeed and
       yet produce something that is a symlink. */
-   vg_assert(statres.isError || ! VKI_S_ISLNK(statbuf.st_mode));
+   vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.st_mode));
 
    /* Don't let the stat call fail silently.  Filter out some known
       sources of noise before complaining, though. */
-   if (statres.isError) {
+   if (sr_isError(statres)) {
       DebugInfo fake_di;
       Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL;
       if (!quiet && VG_(clo_verbosity) > 1) {
@@ -726,9 +726,8 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
    /* object file. Ignore the file if we do not have read permission. */
    VG_(memset)(buf1k, 0, sizeof(buf1k));
    fd = VG_(open)( filename, VKI_O_RDONLY, 0 );
-   if (fd.isError) {
-      if (fd.err != VKI_EACCES)
-      {
+   if (sr_isError(fd)) {
+      if (sr_Err(fd) != VKI_EACCES) {
          DebugInfo fake_di;
          VG_(memset)(&fake_di, 0, sizeof(fake_di));
          fake_di.filename = filename;
@@ -736,8 +735,8 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
       }
       return 0;
    }
-   nread = VG_(read)( fd.res, buf1k, sizeof(buf1k) );
-   VG_(close)( fd.res );
+   nread = VG_(read)( sr_Res(fd), buf1k, sizeof(buf1k) );
+   VG_(close)( sr_Res(fd) );
 
    if (nread == 0)
       return 0;
@@ -948,7 +947,7 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
 
    /* See if we can find it, and check it's in-dateness. */
    sres = VG_(stat)(pdbname, &stat_buf);
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s",
                                pdbname);
    if (VG_(clo_verbosity) > 0)
@@ -965,17 +964,17 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
    }
 
    sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       VG_(message)(Vg_UserMsg, "Warning: Can't open %s", pdbname);
       goto out;
    }
 
    /* Looks promising; go on to try and read stuff from it. */
-   fd_pdbimage = sres.res;
+   fd_pdbimage = sr_Res(sres);
    n_pdbimage  = stat_buf.st_size;
    sres = VG_(am_mmap_file_float_valgrind)( n_pdbimage, VKI_PROT_READ,
                                             fd_pdbimage, 0 );
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       VG_(close)(fd_pdbimage);
       goto out;
    }
@@ -989,7 +988,7 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
    /* dump old info for this range, if any */
    discard_syms_in_range( avma_obj, total_size );
 
-   { void* pdbimage = (void*)sres.res;
+   { void* pdbimage = (void*)sr_Res(sres);
      DebugInfo* di = find_or_create_DebugInfo_for(exename, NULL/*membername*/ );
 
      /* this di must be new, since we just nuked any old stuff in the range */
index e0eef8c9cf9282fabf0b3cf55de9b65ffe911ed7..6a0329de0f8a897421e9b5b46ba58a7c20b94773 100644 (file)
@@ -919,11 +919,11 @@ Addr open_debug_file( Char* name, UInt crc, /*OUT*/UWord* size )
    UInt calccrc;
 
    fd = VG_(open)(name, VKI_O_RDONLY, 0);
-   if (fd.isError)
+   if (sr_isError(fd))
       return 0;
 
-   if (VG_(fstat)(fd.res, &stat_buf) != 0) {
-      VG_(close)(fd.res);
+   if (VG_(fstat)(sr_Res(fd), &stat_buf) != 0) {
+      VG_(close)(sr_Res(fd));
       return 0;
    }
 
@@ -933,24 +933,24 @@ Addr open_debug_file( Char* name, UInt crc, /*OUT*/UWord* size )
    *size = stat_buf.st_size;
    
    sres = VG_(am_mmap_file_float_valgrind)
-             ( *size, VKI_PROT_READ, fd.res, 0 );
+             ( *size, VKI_PROT_READ, sr_Res(fd), 0 );
 
-   VG_(close)(fd.res);
+   VG_(close)(sr_Res(fd));
    
-   if (sres.isError)
+   if (sr_isError(sres))
       return 0;
 
-   calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sres.res, *size);
+   calccrc = calc_gnu_debuglink_crc32(0, (UChar*)sr_Res(sres), *size);
    if (calccrc != crc) {
-      SysRes res = VG_(am_munmap_valgrind)(sres.res, *size);
-      vg_assert(!res.isError);
+      SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
+      vg_assert(!sr_isError(res));
       if (VG_(clo_verbosity) > 1)
          VG_(message)(Vg_DebugMsg, 
             ".. CRC mismatch (computed %08x wanted %08x)", calccrc, crc);
       return 0;
    }
    
-   return sres.res;
+   return sr_Res(sres);
 }
 
 /*
@@ -1126,32 +1126,32 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
       thereafter; it is only aboard transiently. */
 
    fd = VG_(open)(di->filename, VKI_O_RDONLY, 0);
-   if (fd.isError) {
+   if (sr_isError(fd)) {
       ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!");
       return False;
    }
 
-   { Long n_oimageLL = VG_(fsize)(fd.res);
+   { Long n_oimageLL = VG_(fsize)(sr_Res(fd));
      if (n_oimageLL <= 0) {
         ML_(symerr)(di, True, "Can't stat .so/.exe (to determine its size)?!");
-        VG_(close)(fd.res);
+        VG_(close)(sr_Res(fd));
         return False;
      }
      n_oimage = (UWord)(ULong)n_oimageLL;
    }
 
    sres = VG_(am_mmap_file_float_valgrind)
-             ( n_oimage, VKI_PROT_READ, fd.res, 0 );
+             ( n_oimage, VKI_PROT_READ, sr_Res(fd), 0 );
 
-   VG_(close)(fd.res);
+   VG_(close)(sr_Res(fd));
 
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       VG_(message)(Vg_UserMsg, "warning: mmap failed on %s", di->filename );
       VG_(message)(Vg_UserMsg, "         no symbols or debug info loaded" );
       return False;
    }
 
-   oimage = sres.res;
+   oimage = sr_Res(sres);
    /* Check against wraparound.  am_mmap_file_float_valgrind should
       not produce a wrapped-around mapping. */
    vg_assert(n_oimage > 0);
@@ -2040,10 +2040,10 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
    /* Last, but not least, heave the image(s) back overboard. */
    if (dimage) {
       m_res = VG_(am_munmap_valgrind) ( dimage, n_dimage );
-      vg_assert(!m_res.isError);
+      vg_assert(!sr_isError(m_res));
    }
    m_res = VG_(am_munmap_valgrind) ( oimage, n_oimage );
-   vg_assert(!m_res.isError);
+   vg_assert(!sr_isError(m_res));
    return res;
   } 
 }
index e784d0fc85a61579c5a3f50564feea23d5ac4a5c..14bdd7f1a5b7d4ad679e3fd7669f5a028e924cb8 100644 (file)
@@ -953,13 +953,13 @@ static void load_one_suppressions_file ( Char* filename )
    SuppLoc tmp_callers[VG_MAX_SUPP_CALLERS];
 
    sres = VG_(open)( filename, VKI_O_RDONLY, 0 );
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       if (VG_(clo_xml))
          VG_UMSG("</valgrindoutput>\n");
       VG_UMSG("FATAL: can't open suppressions file \"%s\"", filename );
       VG_(exit)(1);
    }
-   fd = sres.res;
+   fd = sr_Res(sres);
 
 #  define BOMB(S)  { err_str = S;  goto syntax_error; }
 
index e80dc22024da7e21eaa9be3c984f8158d6c876e4..ec8ca0a31ce7a50e41e1f15edccee478706d4caa 100644 (file)
@@ -189,8 +189,8 @@ static void load_client ( /*OUT*/ExeInfo* info,
    /* Get hold of a file descriptor which refers to the client
       executable.  This is needed for attaching to GDB. */
    res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
-   if (!res.isError)
-      VG_(cl_exec_fd) = res.res;
+   if (!sr_isError(res))
+      VG_(cl_exec_fd) = sr_Res(res);
 
    /* Copy necessary bits of 'info' that were filled in */
    *client_ip  = info->init_ip;
@@ -625,7 +625,7 @@ Addr setup_client_stack( void*  init_sp,
                 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
              );
      }
-     if ((!ok) || res.isError) {
+     if ((!ok) || sr_isError(res)) {
         /* Allocation of the stack failed.  We have to stop. */
         VG_(printf)("valgrind: "
                     "I failed to allocate space for the application's stack.\n");
@@ -636,7 +636,7 @@ Addr setup_client_stack( void*  init_sp,
      }
 
      vg_assert(ok);
-     vg_assert(!res.isError); 
+     vg_assert(!sr_isError(res)); 
    }
 
    /* ==================== create client stack ==================== */
@@ -866,8 +866,8 @@ static void setup_client_dataseg ( SizeT max_size )
              anon_size, 
              VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
           );
-   vg_assert(!sres.isError);
-   vg_assert(sres.res == anon_start);
+   vg_assert(!sr_isError(sres));
+   vg_assert(sr_Res(sres) == anon_start);
 }
 
 
index 99da85c218cbda2d375fe431169bccf47a28ad2e..9a972bf102b6bd4ca18dec851018a72dbb9ac11b 100644 (file)
@@ -107,11 +107,11 @@ Int VG_(read) ( Int fd, void* buf, Int count)
 {
    Int    ret;
    SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
-   if (res.isError) {
-      ret = - (Int)(Word)res.err;
+   if (sr_isError(res)) {
+      ret = - (Int)(Word)sr_Err(res);
       vg_assert(ret < 0);
    } else {
-      ret = (Int)(Word)res.res;
+      ret = (Int)(Word)sr_Res(res);
       vg_assert(ret >= 0);
    }
    return ret;
@@ -121,26 +121,37 @@ Int VG_(write) ( Int fd, const void* buf, Int count)
 {
    Int    ret;
    SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
-   if (res.isError) {
-      ret = - (Int)(Word)res.err;
+   if (sr_isError(res)) {
+      ret = - (Int)(Word)sr_Err(res);
       vg_assert(ret < 0);
    } else {
-      ret = (Int)(Word)res.res;
+      ret = (Int)(Word)sr_Res(res);
       vg_assert(ret >= 0);
    }
    return ret;
 }
 
+
 Int VG_(pipe) ( Int fd[2] )
 {
+#  if defined(VGO_linux) || defined(VGO_aix5)
    SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
-   return res.isError ? -1 : 0;
+   return sr_isError(res) ? -1 : 0;
+#  else
+#    error "Unknown OS"
+#  endif
 }
 
 OffT VG_(lseek) ( Int fd, OffT offset, Int whence )
 {
+#if defined(VGO_linux) || defined(VGO_aix5)
+   /* all other platforms */
    SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
-   return res.isError ? (-1) : res.res;
+   vg_assert(sizeof(OffT) == sizeof(Word));
+#  else
+#    error "Unknown plat"
+#  endif
+   return sr_isError(res) ? (-1) : sr_Res(res);
    /* if you change the error-reporting conventions of this, also
       change VG_(pread) and all other usage points. */
 }
@@ -155,11 +166,11 @@ OffT VG_(lseek) ( Int fd, OffT offset, Int whence )
       (_p_vgstat)->st_dev        = (ULong)( (_p_vkistat)->st_dev ); \
       (_p_vgstat)->st_ino        = (ULong)( (_p_vkistat)->st_ino ); \
       (_p_vgstat)->st_nlink      = (ULong)( (_p_vkistat)->st_nlink ); \
-      (_p_vgstat)->st_mode       = (UInt)( (_p_vkistat)->st_mode ); \
-      (_p_vgstat)->st_uid        = (UInt)( (_p_vkistat)->st_uid ); \
-      (_p_vgstat)->st_gid        = (UInt)( (_p_vkistat)->st_gid ); \
+      (_p_vgstat)->st_mode       = (UInt) ( (_p_vkistat)->st_mode ); \
+      (_p_vgstat)->st_uid        = (UInt) ( (_p_vkistat)->st_uid ); \
+      (_p_vgstat)->st_gid        = (UInt) ( (_p_vkistat)->st_gid ); \
       (_p_vgstat)->st_rdev       = (ULong)( (_p_vkistat)->st_rdev ); \
-      (_p_vgstat)->st_size       = (Long)( (_p_vkistat)->st_size ); \
+      (_p_vgstat)->st_size       = (Long) ( (_p_vkistat)->st_size ); \
       (_p_vgstat)->st_blksize    = (ULong)( (_p_vkistat)->st_blksize ); \
       (_p_vgstat)->st_blocks     = (ULong)( (_p_vkistat)->st_blocks ); \
       (_p_vgstat)->st_atime      = (ULong)( (_p_vkistat)->st_atime ); \
@@ -170,28 +181,32 @@ OffT VG_(lseek) ( Int fd, OffT offset, Int whence )
       (_p_vgstat)->st_ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
    } while (0)
 
-SysRes VG_(stat) ( Char* file_name, struct vg_stat* vgbuf )
+SysRes VG_(stat) ( const Char* file_name, struct vg_stat* vgbuf )
 {
    SysRes res;
    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
+
 #  if defined(VGO_linux)
+   /* First try with stat64.  If that doesn't work out, fall back to
+      the vanilla version. */
 #  if defined(__NR_stat64)
    { struct vki_stat64 buf64;
      res = VG_(do_syscall2)(__NR_stat64, (UWord)file_name, (UWord)&buf64);
-     if (!(res.isError && res.err == VKI_ENOSYS)) {
+     if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
         /* Success, or any failure except ENOSYS */
-        if (!res.isError)
+        if (!sr_isError(res))
            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
         return res;
      }
    }
-#  endif /* if defined(__NR_stat64) */
+#  endif /* defined(__NR_stat64) */
    { struct vki_stat buf;
      res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf);
-     if (!res.isError)
+     if (!sr_isError(res))
         TRANSLATE_TO_vg_stat(vgbuf, &buf);
      return res;
    }
+
 #  elif defined(VGO_aix5)
    { struct vki_stat buf;
      res = VG_(do_syscall4)(__NR_AIX5_statx,
@@ -199,7 +214,7 @@ SysRes VG_(stat) ( Char* file_name, struct vg_stat* vgbuf )
                             (UWord)&buf,
                             sizeof(struct vki_stat),
                             VKI_STX_NORMAL);
-     if (!res.isError) {
+     if (!sr_isError(res)) {
         VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
         vgbuf->st_dev  = (ULong)buf.st_dev;
         vgbuf->st_ino  = (ULong)buf.st_ino;
@@ -210,6 +225,7 @@ SysRes VG_(stat) ( Char* file_name, struct vg_stat* vgbuf )
      }
      return res;
    }
+
 #  else
 #    error Unknown OS
 #  endif
@@ -219,26 +235,31 @@ Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf )
 {
    SysRes res;
    VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
+
 #  if defined(VGO_linux)
+   /* First try with fstat64.  If that doesn't work out, fall back to
+      the vanilla version. */
 #  if defined(__NR_fstat64)
    { struct vki_stat64 buf64;
      res = VG_(do_syscall2)(__NR_fstat64, (UWord)fd, (UWord)&buf64);
-     if (!(res.isError && res.err == VKI_ENOSYS)) {
+     if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
         /* Success, or any failure except ENOSYS */
-        if (!res.isError)
+        if (!sr_isError(res))
            TRANSLATE_TO_vg_stat(vgbuf, &buf64);
-        return res.isError ? (-1) : 0;
+        return sr_isError(res) ? (-1) : 0;
      }
    }
 #  endif /* if defined(__NR_fstat64) */
    { struct vki_stat buf;
      res = VG_(do_syscall2)(__NR_fstat, (UWord)fd, (UWord)&buf);
-     if (!res.isError)
+     if (!sr_isError(res))
         TRANSLATE_TO_vg_stat(vgbuf, &buf);
-     return res.isError ? (-1) : 0;
+     return sr_isError(res) ? (-1) : 0;
    }
+
 #  elif defined(VGO_aix5)
    I_die_here;
+
 #  else
 #    error Unknown OS
 #  endif
@@ -258,7 +279,7 @@ Bool VG_(is_dir) ( HChar* f )
 {
    struct vg_stat buf;
    SysRes res = VG_(stat)(f, &buf);
-   return res.isError ? False
+   return sr_isError(res) ? False
                       : VKI_S_ISDIR(buf.st_mode) ? True : False;
 }
 
@@ -282,19 +303,19 @@ SysRes VG_(dup2) ( Int oldfd, Int newfd )
 Int VG_(fcntl) ( Int fd, Int cmd, Int arg )
 {
    SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
 Int VG_(rename) ( Char* old_name, Char* new_name )
 {
    SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
-   return res.isError ? (-1) : 0;
+   return sr_isError(res) ? (-1) : 0;
 }
 
 Int VG_(unlink) ( Char* file_name )
 {
    SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
-   return res.isError ? (-1) : 0;
+   return sr_isError(res) ? (-1) : 0;
 }
 
 /* The working directory at startup.  AIX doesn't provide an easy
@@ -322,7 +343,7 @@ Bool VG_(record_startup_wd) ( void )
    { SysRes res
         = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
      vg_assert(startup_wd[szB-1] == 0);
-     if (res.isError) {
+     if (sr_isError(res)) {
         return False;
      } else {
         startup_wd_acquired = True;
@@ -369,15 +390,19 @@ Int VG_(readlink) (Char* path, Char* buf, UInt bufsiz)
    SysRes res;
    /* res = readlink( path, buf, bufsiz ); */
    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
-Int VG_(getdents) (UInt fd, struct vki_dirent *dirp, UInt count)
+Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count)
 {
+#  if defined(VGO_linux) || defined(VGO_aix5)
    SysRes res;
    /* res = getdents( fd, dirp, count ); */
    res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
+#  else
+#    error "Unknown OS"
+#  endif
 }
 
 /* Check accessibility of a file.  Returns zero for access granted,
@@ -389,19 +414,21 @@ Int VG_(access) ( HChar* path, Bool irusr, Bool iwusr, Bool ixusr )
       the kernel interfaces.  Therefore I reluctantly resort to
       hardwiring in these magic numbers that I determined by
       experimentation. */
-   UWord w = (irusr ? 4/*R_OK*/ : 0)
-             | (iwusr ? 2/*W_OK*/ : 0)
-             | (ixusr ? 1/*X_OK*/ : 0);
-   SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
-   return res.isError ? 1 : 0;
-#  elif defined(VGO_aix5)
+#  define VKI_R_OK 4
+#  define VKI_W_OK 2
+#  define VKI_X_OK 1
+#  endif
+
    UWord w = (irusr ? VKI_R_OK : 0)
              | (iwusr ? VKI_W_OK : 0)
              | (ixusr ? VKI_X_OK : 0);
    SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
-   return res.isError ? 1 : 0;   
-#  else
-#    error "Don't know how to do VG_(access) on this OS"
+   return sr_isError(res) ? 1 : 0;   
+
+#  if defined(VGO_linux)
+#  undef VKI_R_OK
+#  undef VKI_W_OK
+#  undef VKI_X_OK
 #  endif
 }
 
@@ -434,8 +461,8 @@ Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
    if (is_setuid)
       *is_setuid = False;
 
-   if (res.isError) {
-      return res.err;
+   if (sr_isError(res)) {
+      return sr_Err(res);
    }
 
    if ( (st.st_mode & (VKI_S_ISUID | VKI_S_ISGID)) && !allow_setuid ) {
@@ -477,12 +504,22 @@ Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
    return 0;
 }
 
+/* Note this moves (or at least, is believed to move) the file pointer
+   on Linux and AIX5 but doesn't on Darwin.  This inconsistency should
+   be fixed. */
 SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset )
 {
-   OffT off = VG_(lseek)( fd, (OffT)offset, VKI_SEEK_SET);
+   SysRes res;
+#  if defined(VGO_linux) || defined(VGO_aix5)
+   /* Linux, AIX5 */
+   OffT off = VG_(lseek)( fd, offset, VKI_SEEK_SET);
    if (off < 0)
       return VG_(mk_SysRes_Error)( VKI_EINVAL );
-   return VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count );
+   res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count );
+   return res;
+#  else
+#    error "Unknown platform"
+#  endif
 }
 
 /* Create and open (-rw------) a tmp file name incorporating said arg.
@@ -515,10 +552,10 @@ Int VG_(mkstemp) ( HChar* part_of_name, /*OUT*/HChar* fullname )
       sres = VG_(open)(buf,
                        VKI_O_CREAT|VKI_O_RDWR|VKI_O_EXCL|VKI_O_TRUNC,
                        VKI_S_IRUSR|VKI_S_IWUSR);
-      if (sres.isError)
+      if (sr_isError(sres))
          continue;
       /* VG_(safe_fd) doesn't return if it fails. */
-      fd = VG_(safe_fd)( sres.res );
+      fd = VG_(safe_fd)( sr_Res(sres) );
       if (fullname)
          VG_(strcpy)( fullname, buf );
       return fd;
@@ -601,9 +638,7 @@ UShort VG_(ntohs) ( UShort x )
 */
 Int VG_(connect_via_socket)( UChar* str )
 {
-#if defined(VGO_aix5)
-   I_die_here;
-#else /* Yay, Linux */
+#  if defined(VGO_linux)
    Int sd, res;
    struct vki_sockaddr_in servAddr;
    UInt   ip   = 0;
@@ -638,7 +673,13 @@ Int VG_(connect_via_socket)( UChar* str )
    }
 
    return sd;
-#endif
+
+#  elif defined(VGO_aix5)
+   I_die_here;
+
+#  else
+#    error "Unknown OS"
+#  endif
 }
 
 
@@ -689,28 +730,30 @@ static Int parse_inet_addr_and_port ( UChar* str, UInt* ip_addr, UShort* port )
 static
 Int my_socket ( Int domain, Int type, Int protocol )
 {
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
+      || defined(VGP_ppc64_linux)
    SysRes res;
    UWord  args[3];
    args[0] = domain;
    args[1] = type;
    args[2] = protocol;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_amd64_linux)
+#  elif defined(VGP_amd64_linux)
    SysRes res;
    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#  elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    I_die_here;
 
-#else
-#  error Unknown arch
-#endif
+#  else
+#    error "Unknown arch"
+#  endif
 }
 
+
 static
 Int my_connect ( Int sockfd,
 #                if defined(VGO_linux)
@@ -720,26 +763,27 @@ Int my_connect ( Int sockfd,
 #                endif
                  Int addrlen )
 {
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
+      || defined(VGP_ppc64_linux)
    SysRes res;
    UWord  args[3];
    args[0] = sockfd;
    args[1] = (UWord)serv_addr;
    args[2] = addrlen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_amd64_linux)
+#  elif defined(VGP_amd64_linux)
    SysRes res;
    res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#  elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    I_die_here;
 
-#else
-#  error Unknown arch
-#endif
+#  else
+#    error "Unknown arch"
+#  endif
 }
 
 Int VG_(write_socket)( Int sd, void *msg, Int count )
@@ -749,7 +793,8 @@ Int VG_(write_socket)( Int sd, void *msg, Int count )
       errors on stream oriented sockets when the other end breaks the
       connection. The EPIPE error is still returned. */
 
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
+      || defined(VGP_ppc64_linux)
    SysRes res;
    UWord  args[4];
    args[0] = sd;
@@ -757,76 +802,79 @@ Int VG_(write_socket)( Int sd, void *msg, Int count )
    args[2] = count;
    args[3] = VKI_MSG_NOSIGNAL;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_amd64_linux)
+#  elif defined(VGP_amd64_linux)
    SysRes res;
    res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg, 
                                        count, VKI_MSG_NOSIGNAL, 0,0);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#  elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    I_die_here;
 
-#else
-#  error Unknown arch
-#endif
+#  else
+#    error "Unknown platform"
+#  endif
 }
 
 Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
 {
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
+      || defined(VGP_ppc64_linux)
    SysRes res;
    UWord  args[3];
    args[0] = sd;
    args[1] = (UWord)name;
    args[2] = (UWord)namelen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_amd64_linux)
+#  elif defined(VGP_amd64_linux)
    SysRes res;
    res = VG_(do_syscall3)( __NR_getsockname,
                            (UWord)sd, (UWord)name, (UWord)namelen );
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#  elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    I_die_here;
 
-#else
-#  error Unknown arch
-#endif
+#  else
+#    error "Unknown platform"
+#  endif
 }
 
 Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
 {
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
+      || defined(VGP_ppc64_linux)
    SysRes res;
    UWord  args[3];
    args[0] = sd;
    args[1] = (UWord)name;
    args[2] = (UWord)namelen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_amd64_linux)
+#  elif defined(VGP_amd64_linux)
    SysRes res;
    res = VG_(do_syscall3)( __NR_getpeername,
                            (UWord)sd, (UWord)name, (UWord)namelen );
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#  elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    I_die_here;
 
-#else
-#  error Unknown arch
-#endif
+#  else
+#    error "Unknown platform"
+#  endif
 }
 
 Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
                       Int *optlen)
 {
-#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+#  if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
+      || defined(VGP_ppc64_linux)
    SysRes res;
    UWord  args[5];
    args[0] = sd;
@@ -835,26 +883,24 @@ Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
    args[3] = (UWord)optval;
    args[4] = (UWord)optlen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_amd64_linux)
+#  elif defined(VGP_amd64_linux)
    SysRes res;
    res = VG_(do_syscall5)( __NR_getsockopt,
                            (UWord)sd, (UWord)level, (UWord)optname, 
                            (UWord)optval, (UWord)optlen );
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 
-#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#  elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    I_die_here;
 
-#else
-#  error Unknown arch
-#endif
+#  else
+#    error "Unknown platform"
+#  endif
 }
 
 
-
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
-
index 0af540a27dd599de2e9027c1493fe228ba580e95..86ebd23a714198af2325723db7da451943dc85a8 100644 (file)
@@ -128,6 +128,7 @@ Char **VG_(env_setenv) ( Char ***envp, const Char* varname, const Char *val )
    return oldenv;
 }
 
+
 /* Walk through a colon-separated environment variable, and remove the
    entries which match remove_pattern.  It slides everything down over
    the removed entries, and pads the remaining space with '\0'.  It
@@ -231,15 +232,15 @@ Int VG_(waitpid)(Int pid, Int *status, Int options)
 {
 #  if defined(VGO_linux)
    SysRes res = VG_(do_syscall4)(__NR_wait4, pid, (UWord)status, options, 0);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 #  elif defined(VGO_aix5)
    /* magic number 4 obtained by truss-ing a C program doing
       'waitpid'.  Note status and pid args opposite way round from
       POSIX. */
    SysRes res = VG_(do_syscall5)(__NR_AIX5_kwaitpid, 
                                  (UWord)status, pid, 4 | options,0,0);
-   if (0) VG_(printf)("waitpid: got 0x%lx 0x%lx\n", res.res, res.err);
-   return res.isError ? -1 : res.res;
+   if (0) VG_(printf)("waitpid: got 0x%lx 0x%lx\n", sr_Res(res), res.err);
+   return sr_isError(res) ? -1 : sr_Res(res);
 #  else
 #    error Unknown OS
 #  endif
@@ -286,7 +287,7 @@ void VG_(execv) ( Char* filename, Char** argv )
    res = VG_(do_syscall3)(__NR_execve,
                           (UWord)filename, (UWord)argv, (UWord)envp);
 
-   VG_(printf)("EXEC failed, errno = %ld\n", res.res);
+   VG_(printf)("EXEC failed, errno = %lld\n", (Long)sr_Err(res));
 }
 
 /* Return -1 if error, else 0.  NOTE does not indicate return code of
@@ -308,7 +309,6 @@ Int VG_(system) ( Char* cmd )
       VG_(exit)(1);
    } else {
       /* parent */
-      Int ir, zzz;
       /* We have to set SIGCHLD to its default behaviour in order that
          VG_(waitpid) works (at least on AIX).  According to the Linux
          man page for waitpid:
@@ -321,8 +321,10 @@ Int VG_(system) ( Char* cmd )
          set to ECHILD.  (The original POSIX standard left the
          behaviour of setting SIGCHLD to SIG_IGN unspecified.)
       */
-      struct vki_sigaction sa, saved_sa;
-      VG_(memset)( &sa, 0, sizeof(struct vki_sigaction) );
+      Int ir, zzz;
+      vki_sigaction_toK_t sa, sa2;
+      vki_sigaction_fromK_t saved_sa;
+      VG_(memset)( &sa, 0, sizeof(sa) );
       VG_(sigemptyset)(&sa.sa_mask);
       sa.ksa_handler = VKI_SIG_DFL;
       sa.sa_flags    = 0;
@@ -331,9 +333,9 @@ Int VG_(system) ( Char* cmd )
 
       zzz = VG_(waitpid)(pid, NULL, 0);
 
-      ir = VG_(sigaction)(VKI_SIGCHLD, &saved_sa, NULL);
+      VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &sa2 );
+      ir = VG_(sigaction)(VKI_SIGCHLD, &sa2, NULL);
       vg_assert(ir == 0);
-
       return zzz == -1 ? -1 : 0;
    }
 }
@@ -350,9 +352,9 @@ Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
 #  ifdef __NR_ugetrlimit
    res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
 #  endif
-   if (res.isError && res.err == VKI_ENOSYS)
+   if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
       res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
 
@@ -362,7 +364,7 @@ Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
    SysRes res;
    /* res = setrlimit( resource, rlim ); */
    res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
 /* ---------------------------------------------------------------------
@@ -371,18 +373,10 @@ Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
 
 Int VG_(gettid)(void)
 {
-#  if defined(VGO_aix5)
-   SysRes res;
-   Int    r;
-   vg_assert(__NR_AIX5__thread_self != __NR_AIX5_UNKNOWN);
-   res = VG_(do_syscall0)(__NR_AIX5__thread_self);
-   r = res.res;
-   return r;
-
-#  else
+#  if defined(VGO_linux)
    SysRes res = VG_(do_syscall0)(__NR_gettid);
 
-   if (res.isError && res.res == VKI_ENOSYS) {
+   if (sr_isError(res) && sr_Res(res) == VKI_ENOSYS) {
       Char pid[16];      
       /*
        * The gettid system call does not exist. The obvious assumption
@@ -400,10 +394,10 @@ Int VG_(gettid)(void)
 
       res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
                              (UWord)pid, sizeof(pid));
-      if (!res.isError && res.res > 0) {
+      if (!sr_isError(res) && sr_Res(res) > 0) {
          Char* s;
-         pid[res.res] = '\0';
-         res.res = VG_(strtoll10)(pid, &s);
+         pid[sr_Res(res)] = '\0';
+         res = VG_(mk_SysRes_Success)(  VG_(strtoll10)(pid, &s) );
          if (*s != '\0') {
             VG_(message)(Vg_DebugMsg, 
                "Warning: invalid file name linked to by /proc/self: %s", pid);
@@ -411,7 +405,18 @@ Int VG_(gettid)(void)
       }
    }
 
-   return res.res;
+   return sr_Res(res);
+
+#  elif defined(VGO_aix5)
+   SysRes res;
+   Int    r;
+   vg_assert(__NR_AIX5__thread_self != __NR_AIX5_UNKNOWN);
+   res = VG_(do_syscall0)(__NR_AIX5__thread_self);
+   r = sr_Res(res);
+   return r;
+
+#  else
+#    error "Unknown OS"
 #  endif
 }
 
@@ -419,32 +424,32 @@ Int VG_(gettid)(void)
 Int VG_(getpid) ( void )
 {
    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
-   return VG_(do_syscall0)(__NR_getpid) . res;
+   return sr_Res( VG_(do_syscall0)(__NR_getpid) );
 }
 
 Int VG_(getpgrp) ( void )
 {
    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
-   return VG_(do_syscall0)(__NR_getpgrp) . res;
+   return sr_Res( VG_(do_syscall0)(__NR_getpgrp) );
 }
 
 Int VG_(getppid) ( void )
 {
    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
-   return VG_(do_syscall0)(__NR_getppid) . res;
+   return sr_Res( VG_(do_syscall0)(__NR_getppid) );
 }
 
 Int VG_(geteuid) ( void )
 {
    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
 #  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
-   return VG_(do_syscall1)(__NR_AIX5_getuidx, 1) . res;
+   return sr_Res( VG_(do_syscall1)(__NR_AIX5_getuidx, 1) );
 #  elif defined(__NR_geteuid32)
    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
    // than 65536 cause problems, as bug #151209 showed.
-   return VG_(do_syscall0)(__NR_geteuid32) . res;
+   return sr_Res( VG_(do_syscall0)(__NR_geteuid32) );
 #  else
-   return VG_(do_syscall0)(__NR_geteuid) . res;
+   return sr_Res( VG_(do_syscall0)(__NR_geteuid) );
 #  endif
 }
 
@@ -452,13 +457,13 @@ Int VG_(getegid) ( void )
 {
    /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
 #  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
-   return VG_(do_syscall1)(__NR_AIX5_getgidx, 1) . res;
+   return sr_Res( VG_(do_syscall1)(__NR_AIX5_getgidx, 1) );
 #  elif defined(__NR_getegid32)
    // We use the 32-bit version if it's supported.  Otherwise, IDs greater
    // than 65536 cause problems, as bug #151209 showed.
-   return VG_(do_syscall0)(__NR_getegid32) . res;
+   return sr_Res( VG_(do_syscall0)(__NR_getegid32) );
 #  else
-   return VG_(do_syscall0)(__NR_getegid) . res;
+   return sr_Res( VG_(do_syscall0)(__NR_getegid) );
 #  endif
 }
 
@@ -475,21 +480,21 @@ Int VG_(getgroups)( Int size, UInt* list )
    if (size < 0) return -1;
    if (size > 64) size = 64;
    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list16);
-   if (sres.isError)
+   if (sr_isError(sres))
       return -1;
-   if (sres.res > size)
+   if (sr_Res(sres) > size)
       return -1;
-   for (i = 0; i < sres.res; i++)
+   for (i = 0; i < sr_Res(sres); i++)
       list[i] = (UInt)list16[i];
-   return sres.res;
+   return sr_Res(sres);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) \
         || defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
    SysRes sres;
    sres = VG_(do_syscall2)(__NR_getgroups, size, (Addr)list);
-   if (sres.isError)
+   if (sr_isError(sres))
       return -1;
-   return sres.res;
+   return sr_Res(sres);
 
 #  else
 #     error "VG_(getgroups): needs implementation on this platform"
@@ -504,9 +509,9 @@ Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
 {
    SysRes res;
    res = VG_(do_syscall4)(__NR_ptrace, request, pid, (UWord)addr, (UWord)data);
-   if (res.isError)
+   if (sr_isError(res))
       return -1;
-   return res.res;
+   return sr_Res(res);
 }
 
 /* ---------------------------------------------------------------------
@@ -515,11 +520,16 @@ Int VG_(ptrace) ( Int request, Int pid, void *addr, void *data )
 
 Int VG_(fork) ( void )
 {
+#  if defined(VGO_linux) || defined(VGO_aix5)
    SysRes res;
    res = VG_(do_syscall0)(__NR_fork);
-   if (res.isError)
+   if (sr_isError(res))
       return -1;
-   return res.res;
+   return sr_Res(res);
+
+#  else
+#    error "Unknown OS"
+#  endif
 }
 
 /* ---------------------------------------------------------------------
@@ -532,7 +542,22 @@ UInt VG_(read_millisecond_timer) ( void )
    static ULong base = 0;
    ULong  now;
 
-#  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#  if defined(VGO_linux)
+   { SysRes res;
+     struct vki_timespec ts_now;
+     res = VG_(do_syscall2)(__NR_clock_gettime, VKI_CLOCK_MONOTONIC,
+                            (UWord)&ts_now);
+     if (sr_isError(res) == 0) {
+        now = ts_now.tv_sec * 1000000ULL + ts_now.tv_nsec / 1000;
+     } else {
+       struct vki_timeval tv_now;
+       res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
+       vg_assert(! sr_isError(res));
+       now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
+     }
+   }
+
+#  elif defined(VGO_aix5)
    /* AIX requires a totally different implementation since
       sys_gettimeofday doesn't exist.  We use the POWER real-time
       register facility.  This will SIGILL on PowerPC 970 on AIX,
@@ -550,31 +575,19 @@ UInt VG_(read_millisecond_timer) ( void )
    vg_assert(nsec < 1000*1000*1000);
    now  = ((ULong)sec1) * 1000000ULL;
    now += (ULong)(nsec / 1000);
-#  else
 
-   struct vki_timespec ts_now;
-   SysRes res;
-   res = VG_(do_syscall2)(__NR_clock_gettime, VKI_CLOCK_MONOTONIC,
-                          (UWord)&ts_now);
-   if (res.isError == 0)
-   {
-     now = ts_now.tv_sec * 1000000ULL + ts_now.tv_nsec / 1000;
-   }
-   else
-   {
-     struct vki_timeval tv_now;
-     res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
-     vg_assert(! res.isError);
-     now = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
-   }
+#  else
+#    error "Unknown OS"
 #  endif
-   
+
+   /* COMMON CODE */  
    if (base == 0)
       base = now;
 
    return (now - base) / 1000;
 }
 
+
 /* ---------------------------------------------------------------------
    atfork()
    ------------------------------------------------------------------ */
index 0fbc353e5d889b58ebe246194f628717f2c35f39..edd9a674aa240ece14d90d01ac1a77688c61a313 100644 (file)
    success and -1 on error.  */
 /* I believe the indexing scheme in ->sig[] is also correct for
    32- and 64-bit AIX (verified 27 July 06). */
+/* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
+   either 32 or 64, and hence the sig[] words can either be 32- or
+   64-bits.  And which they are it doesn't necessarily follow from the
+   host word size. */
 
 Int VG_(sigfillset)( vki_sigset_t* set )
 {
@@ -48,7 +52,7 @@ Int VG_(sigfillset)( vki_sigset_t* set )
    if (set == NULL)
       return -1;
    for (i = 0; i < _VKI_NSIG_WORDS; i++)
-      set->sig[i] = ~(UWord)0x0;
+      set->sig[i] = ~0;
    return 0;
 }
 
@@ -58,7 +62,7 @@ Int VG_(sigemptyset)( vki_sigset_t* set )
    if (set == NULL)
       return -1;
    for (i = 0; i < _VKI_NSIG_WORDS; i++)
-      set->sig[i] = 0x0;
+      set->sig[i] = 0;
    return 0;
 }
 
@@ -67,7 +71,7 @@ Bool VG_(isemptysigset)( const vki_sigset_t* set )
    Int i;
    vg_assert(set != NULL);
    for (i = 0; i < _VKI_NSIG_WORDS; i++)
-      if (set->sig[i] != 0x0) return False;
+      if (set->sig[i] != 0) return False;
    return True;
 }
 
@@ -76,7 +80,7 @@ Bool VG_(isfullsigset)( const vki_sigset_t* set )
    Int i;
    vg_assert(set != NULL);
    for (i = 0; i < _VKI_NSIG_WORDS; i++)
-      if (set->sig[i] != ~(UWord)0x0) return False;
+      if (set->sig[i] != ~0) return False;
    return True;
 }
 
@@ -97,7 +101,7 @@ Int VG_(sigaddset)( vki_sigset_t* set, Int signum )
    if (signum < 1 || signum > _VKI_NSIG)
       return -1;
    signum--;
-   set->sig[signum / _VKI_NSIG_BPW] |= (1UL << (signum % _VKI_NSIG_BPW));
+   set->sig[signum / _VKI_NSIG_BPW] |= (1ULL << (signum % _VKI_NSIG_BPW));
    return 0;
 }
 
@@ -108,7 +112,7 @@ Int VG_(sigdelset)( vki_sigset_t* set, Int signum )
    if (signum < 1 || signum > _VKI_NSIG)
       return -1;
    signum--;
-   set->sig[signum / _VKI_NSIG_BPW] &= ~(1UL << (signum % _VKI_NSIG_BPW));
+   set->sig[signum / _VKI_NSIG_BPW] &= ~(1ULL << (signum % _VKI_NSIG_BPW));
    return 0;
 }
 
@@ -143,45 +147,100 @@ void VG_(sigdelset_from_set)( vki_sigset_t* dst, vki_sigset_t* src )
       dst->sig[i] &= ~(src->sig[i]);
 }
 
+/* dst = dst `intersect` src. */
+void VG_(sigintersectset)( vki_sigset_t* dst, vki_sigset_t* src )
+{
+   Int i;
+   vg_assert(dst != NULL && src != NULL);
+   for (i = 0; i < _VKI_NSIG_WORDS; i++)
+      dst->sig[i] &= src->sig[i];
+}
+
+/* dst = ~src */
+void VG_(sigcomplementset)( vki_sigset_t* dst, vki_sigset_t* src )
+{
+   Int i;
+   vg_assert(dst != NULL && src != NULL);
+   for (i = 0; i < _VKI_NSIG_WORDS; i++)
+      dst->sig[i] = ~ src->sig[i];
+}
+
 
 /* The functions sigaction, sigprocmask, sigpending and sigsuspend
    return 0 on success and -1 on error.  
 */
 Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
 {
+#  if defined(VGO_linux) || defined(VGO_aix5)
+#  if defined(__NR_rt_sigprocmask)
    SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask, 
                                  how, (UWord)set, (UWord)oldset, 
                                  _VKI_NSIG_WORDS * sizeof(UWord));
-   return res.isError ? -1 : 0;
+#  else
+   SysRes res = VG_(do_syscall3)(__NR_sigprocmask, 
+                                 how, (UWord)set, (UWord)oldset);
+#  endif
+
+#  else
+#    error "Unknown OS"
+#  endif
+   return sr_isError(res) ? -1 : 0;
 }
 
 
-Int VG_(sigaction) ( Int signum, const struct vki_sigaction* act,  
-                     struct vki_sigaction* oldact)
+Int VG_(sigaction) ( Int signum, 
+                     const vki_sigaction_toK_t* act,  
+                     vki_sigaction_fromK_t* oldact)
 {
+#  if defined(VGO_linux) || defined(VGO_aix5)
+   /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
+      identical types. */
    SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
                                  signum, (UWord)act, (UWord)oldact, 
                                  _VKI_NSIG_WORDS * sizeof(UWord));
-   return res.isError ? -1 : 0;
+   return sr_isError(res) ? -1 : 0;
+
+#  else
+#    error "Unsupported OS"
+#  endif
+}
+
+
+/* See explanation in pub_core_libcsignal.h. */
+void 
+VG_(convert_sigaction_fromK_to_toK)( vki_sigaction_fromK_t* fromK,
+                                     /*OUT*/vki_sigaction_toK_t* toK )
+{
+#  if defined(VGO_linux) || defined(VGO_aix5)
+   *toK = *fromK;
+#  else
+#    error "Unsupported OS"
+#  endif
 }
 
 
 Int VG_(kill)( Int pid, Int signo )
 {
    SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
-   return res.isError ? -1 : 0;
+   return sr_isError(res) ? -1 : 0;
 }
 
 
 Int VG_(tkill)( ThreadId tid, Int signo )
 {
+#  if defined(__NR_tkill)
    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
    res = VG_(do_syscall2)(__NR_tkill, tid, signo);
-   if (res.isError && res.err == VKI_ENOSYS)
+   if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
       res = VG_(do_syscall2)(__NR_kill, tid, signo);
-   return res.isError ? -1 : 0;
+   return sr_isError(res) ? -1 : 0;
+
+#  else
+#    error "Unsupported plat"
+#  endif
 }
 
+/* ---------------------- sigtimedwait_zero ----------------------- */
 
 /* A cut-down version of POSIX sigtimedwait: poll for pending signals
    mentioned in the sigset_t, and if any are present, select one
@@ -199,6 +258,8 @@ Int VG_(tkill)( ThreadId tid, Int signo )
    obscure ways.  I suspect it's only thread-safe because V forces
    single-threadedness. */
 
+/* ---------- sigtimedwait_zero: Linux ----------- */
+
 #if defined(VGO_linux)
 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set, 
                             vki_siginfo_t *info )
@@ -206,9 +267,11 @@ Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
    static const struct vki_timespec zero = { 0, 0 };
    SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info, 
                                  (UWord)&zero, sizeof(*set));
-   return res.isError ? -1 : res.res;
+   return sr_isError(res) ? -1 : sr_Res(res);
 }
 
+/* ---------- sigtimedwait_zero: AIX5 ----------- */
+
 #elif defined(VGO_aix5)
 /* The general idea is:
    - use sigpending to find out which signals are pending
@@ -254,8 +317,7 @@ Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
   vg_assert(ir == 0);
 
   /* pending = pending `intersect` blocked */
-  for (i = 0; i < _VKI_NSIG_WORDS; i++)
-     pending.sig[i] &= blocked.sig[i];
+  VG_(sigintersectset)(&pending, blocked);
 
   /* decide which signal we're going to snarf */
   for (i = 1; i < _VKI_NSIG; i++)
index 8d5901f4436c24aae59911df414e441daad0278a..85a8099f717e3d243904011cacb7ae4801c6fe12 100644 (file)
@@ -401,13 +401,20 @@ Bool VG_(machine_get_hwcaps)( void )
         AT_PLATFORM entries in the ELF auxiliary table -- see also
         the_iifii.client_auxv in m_main.c.
       */
-     vki_sigset_t         saved_set, tmp_set;
-     struct vki_sigaction saved_sigill_act, tmp_sigill_act;
-     struct vki_sigaction saved_sigfpe_act, tmp_sigfpe_act;
+     vki_sigset_t          saved_set, tmp_set;
+     vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
+     vki_sigaction_toK_t     tmp_sigill_act,   tmp_sigfpe_act;
 
      volatile Bool have_F, have_V, have_FX, have_GX;
      Int r;
 
+     /* This is a kludge.  Really we ought to back-convert saved_act
+        into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
+        since that's a no-op on all ppc32 platforms so far supported,
+        it's not worth the typing effort.  At least include most basic
+        sanity check: */
+     vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
+
      VG_(sigemptyset)(&tmp_set);
      VG_(sigaddset)(&tmp_set, VKI_SIGILL);
      VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
@@ -512,19 +519,29 @@ Bool VG_(machine_get_hwcaps)( void )
 #elif defined(VGA_ppc64)
    {
      /* Same instruction set detection algorithm as for ppc32. */
-     vki_sigset_t         saved_set, tmp_set;
-     struct vki_sigaction saved_sigill_act, tmp_sigill_act;
-     struct vki_sigaction saved_sigfpe_act, tmp_sigfpe_act;
+     vki_sigset_t          saved_set, tmp_set;
+     vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
+     vki_sigaction_toK_t     tmp_sigill_act,   tmp_sigfpe_act;
 
      volatile Bool have_F, have_V, have_FX, have_GX;
+     Int r;
+
+     /* This is a kludge.  Really we ought to back-convert saved_act
+        into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
+        since that's a no-op on all ppc64 platforms so far supported,
+        it's not worth the typing effort.  At least include most basic
+        sanity check: */
+     vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
 
      VG_(sigemptyset)(&tmp_set);
      VG_(sigaddset)(&tmp_set, VKI_SIGILL);
      VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
 
-     VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
+     r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
+     vg_assert(r == 0);
 
-     VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
+     r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
+     vg_assert(r == 0);
      tmp_sigill_act = saved_sigill_act;
 
      VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
index c8f271daaf54052642d0115cc1118e263c806c1b..a913dadb7ff272f3ab1f75adf4cf75631f20a397 100644 (file)
@@ -614,12 +614,12 @@ static Bool main_process_cmd_line_options( const HChar* toolname )
          sres = VG_(open)(logfilename, 
                           VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, 
                           VKI_S_IRUSR|VKI_S_IWUSR);
-         if (!sres.isError) {
-            tmp_log_fd = sres.res;
+         if (!sr_isError(sres)) {
+            tmp_log_fd = sr_Res(sres);
          } else {
             VG_(message)(Vg_UserMsg, 
                          "Can't create log file '%s' (%s); giving up!", 
-                         logfilename, VG_(strerror)(sres.err));
+                         logfilename, VG_(strerror)(sr_Err(sres)));
             VG_(err_bad_option)(
                "--log-file=<file> (didn't work out for some reason.)");
             /*NOTREACHED*/
@@ -903,12 +903,12 @@ static void print_preamble(Bool logging_to_fd, const char* toolname)
 
       VG_(message)(Vg_DebugMsg, "Contents of /proc/version:");
       fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
-      if (fd.isError) {
+      if (sr_isError(fd)) {
          VG_(message)(Vg_DebugMsg, "  can't open /proc/version");
       } else {
 #        define BUF_LEN    256
          Char version_buf[BUF_LEN];
-         Int n = VG_(read) ( fd.res, version_buf, BUF_LEN );
+         Int n = VG_(read) ( sr_Res(fd), version_buf, BUF_LEN );
          vg_assert(n <= BUF_LEN);
          if (n > 0) {
             version_buf[n-1] = '\0';
@@ -916,7 +916,7 @@ static void print_preamble(Bool logging_to_fd, const char* toolname)
          } else {
             VG_(message)(Vg_DebugMsg, "  (empty?)");
          }
-         VG_(close)(fd.res);
+         VG_(close)(sr_Res(fd));
 #        undef BUF_LEN
       }
 
@@ -1945,6 +1945,9 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
    //--------------------------------------------------------------
    // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
    VG_(debugLog)(1, "main", "Initialise signal management\n");
+   /* Check that the kernel-interface signal definitions look sane */
+   VG_(vki_do_initial_consistency_checks)();
+   /* .. and go on to use them. */
    VG_(sigstartup_actions)();
 
    //--------------------------------------------------------------
index 966d965e4d75fc6e129ec7baa2093cc3e51147c7..275b9997fc2be06e8b102c726900c414e6e3c298 100644 (file)
@@ -641,6 +641,7 @@ void VG_(out_of_memory_NORETURN) ( HChar* who, SizeT szB )
    } else {
       VG_(debugLog)(0,"mallocfree", s1, who, (ULong)szB, tot_alloc);
    }
+
    VG_(exit)(1);
 }
 
@@ -672,9 +673,9 @@ Superblock* newSuperblock ( Arena* a, SizeT cszB )
       // client allocation -- return 0 to client if it fails
       sres = VG_(am_sbrk_anon_float_client)
                 ( cszB, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC );
-      if (sres.isError)
+      if (sr_isError(sres))
          return 0;
-      sb = (Superblock*)sres.res;
+      sb = (Superblock*)(AddrH)sr_Res(sres);
       // Mark this segment as containing client heap.  The leak
       // checker needs to be able to identify such segments so as not
       // to use them as sources of roots during leak checks.
@@ -684,12 +685,12 @@ Superblock* newSuperblock ( Arena* a, SizeT cszB )
    } else {
       // non-client allocation -- abort if it fails
       sres = VG_(am_sbrk_anon_float_valgrind)( cszB );
-      if (sres.isError) {
+      if (sr_isError(sres)) {
          VG_(out_of_memory_NORETURN)("newSuperblock", cszB);
          /* NOTREACHED */
          sb = NULL; /* keep gcc happy */
       } else {
-         sb = (Superblock*)sres.res;
+         sb = (Superblock*)(AddrH)sr_Res(sres);
       }
    }
    vg_assert(NULL != sb);
@@ -1327,12 +1328,12 @@ void* VG_(arena_malloc) ( ArenaId aid, HChar* cc, SizeT req_pszB )
       Superblock ** array;
       SysRes sres = VG_(am_sbrk_anon_float_valgrind)(sizeof(Superblock *) *
                                                      a->sblocks_size * 2);
-      if (sres.isError) {
+      if (sr_isError(sres)) {
          VG_(out_of_memory_NORETURN)("arena_init", sizeof(Superblock *) * 
                                                    a->sblocks_size * 2);
          /* NOTREACHED */
       }
-      array = (Superblock**) sres.res;
+      array = (Superblock**)(AddrH)sr_Res(sres);
       for (i = 0; i < a->sblocks_used; ++i) array[i] = a->sblocks[i];
 
       a->sblocks_size *= 2;
index e1e0f1ce1ae1bb6dd007559d8a4b9bed0e7b4fbb..3752e85caf5e7eb64d81c6fda033d8324ab783d2 100644 (file)
@@ -1148,13 +1148,11 @@ VgSchedReturnCode VG_(scheduler) ( ThreadId tid )
             guest_EIP to point at the code to execute after the
             sysenter, since Vex-generated code will not have set it --
             vex does not know what it should be.  Vex sets the next
-            address to zero, so if you don't guest_EIP, the thread will
-            jump to zero afterwards and probably die as a result. */
-#        if defined(VGA_x86)
-         //FIXME: VG_(threads)[tid].arch.vex.guest_EIP = ....
-         //handle_sysenter_x86(tid);
+            address to zero, so if you don't set guest_EIP, the thread
+            will jump to zero afterwards and probably die as a result. */
+#        if defined(VGP_x86_linux)
          vg_assert2(0, "VG_(scheduler), phase 3: "
-                       "sysenter_x86 on not yet implemented");
+                       "sysenter_x86 on x86-linux is not supported");
 #        else
          vg_assert2(0, "VG_(scheduler), phase 3: "
                        "sysenter_x86 on non-x86 platform?!?!");
index e673a4352114f3ce8c35a17f3e1553a544ab6c44..0b1150aace89c7a8e338aa73194104633440d586 100644 (file)
@@ -251,16 +251,16 @@ typedef struct SigQueue {
 
 /* ------ Macros for pulling stuff out of ucontexts ------ */
 
-/* Q: what does UCONTEXT_SYSCALL_SYSRES do?  A: let's suppose the
+/* Q: what does VG_UCONTEXT_SYSCALL_SYSRES do?  A: let's suppose the
    machine context (uc) reflects the situation that a syscall had just
    completed, quite literally -- that is, that the program counter was
    now at the instruction following the syscall.  (or we're slightly
    downstream, but we're sure no relevant register has yet changed
-   value.)  Then UCONTEXT_SYSCALL_SYSRES returns a SysRes reflecting
+   value.)  Then VG_UCONTEXT_SYSCALL_SYSRES returns a SysRes reflecting
    the result of the syscall; it does this by fishing relevant bits of
    the machine state out of the uc.  Of course if the program counter
    was somewhere else entirely then the result is likely to be
-   meaningless, so the caller of UCONTEXT_SYSCALL_SYSRES has to be
+   meaningless, so the caller of VG_UCONTEXT_SYSCALL_SYSRES has to be
    very careful to pay attention to the results only when it is sure
    that the said constraint on the program counter is indeed valid. */
 #if defined(VGP_x86_linux)
@@ -491,6 +491,10 @@ typedef
       UInt  scss_flags;
       vki_sigset_t scss_mask;
       void* scss_restorer; /* where sigreturn goes */
+      void* scss_sa_tramp; /* sa_tramp setting, Darwin only */
+      /* re _restorer and _sa_tramp, we merely record the values
+         supplied when the client does 'sigaction' and give them back
+         when requested.  Otherwise they are simply ignored. */
    }
    SCSS_Per_Signal;
 
@@ -748,7 +752,8 @@ static void handle_SCSS_change ( Bool force_update )
 {
    Int  res, sig;
    SKSS skss_old;
-   struct vki_sigaction ksa, ksa_old;
+   vki_sigaction_toK_t   ksa;
+   vki_sigaction_fromK_t ksa_old;
 
    /* Remember old SKSS and calculate new one. */
    skss_old = skss;
@@ -775,7 +780,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;
 #     if !defined(VGP_ppc32_linux) && !defined(VGP_ppc32_aix5) \
-                                   && !defined(VGP_ppc64_aix5)
+         && !defined(VGP_ppc64_aix5)
       ksa.sa_restorer = my_sigreturn;
 #     endif
       /* Re above ifdef (also the assertion below), PaulM says:
@@ -791,11 +796,12 @@ static void handle_SCSS_change ( Bool force_update )
 
       if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
          VG_DMSG("setting ksig %d to: hdlr %p, flags 0x%lx, "
-                 "mask(63..0) 0x%lx 0x%lx",
+                 "mask(msb..lsb) 0x%llx 0x%llx",
                  sig, ksa.ksa_handler,
                  (UWord)ksa.sa_flags,
-                 (UWord)ksa.sa_mask.sig[1], 
-                 (UWord)ksa.sa_mask.sig[0]);
+                 _VKI_NSIG_WORDS > 1 ? (ULong)ksa.sa_mask.sig[1] : 0,
+                 (ULong)ksa.sa_mask.sig[0]
+         );
 
       res = VG_(sigaction)( sig, &ksa, &ksa_old );
       vg_assert(res == 0);
@@ -808,7 +814,7 @@ static void handle_SCSS_change ( Bool force_update )
          vg_assert(ksa_old.sa_flags 
                    == skss_old.skss_per_sig[sig].skss_flags);
 #        if !defined(VGP_ppc32_linux) && !defined(VGP_ppc32_aix5) \
-                                      && !defined(VGP_ppc64_aix5)
+            && !defined(VGP_ppc64_aix5)
          vg_assert(ksa_old.sa_restorer 
                    == my_sigreturn);
 #        endif
@@ -894,8 +900,8 @@ SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss
 
 
 SysRes VG_(do_sys_sigaction) ( Int signo, 
-                               const struct vki_sigaction *new_act, 
-                               struct vki_sigaction *old_act )
+                               const vki_sigaction_toK_t* new_act, 
+                               vki_sigaction_fromK_t* old_act )
 {
    if (VG_(clo_trace_signals))
       VG_EMSG("sys_sigaction: sigNo %d, "
@@ -940,11 +946,13 @@ SysRes VG_(do_sys_sigaction) ( Int signo,
       scss.scss_per_sig[signo].scss_flags    = new_act->sa_flags;
       scss.scss_per_sig[signo].scss_mask     = new_act->sa_mask;
 
-      scss.scss_per_sig[signo].scss_restorer = 0;
+      scss.scss_per_sig[signo].scss_restorer = NULL;
 #     if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
       scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
 #     endif
 
+      scss.scss_per_sig[signo].scss_sa_tramp = NULL;
+
       VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
       VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
    }
@@ -1069,16 +1077,16 @@ SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
                                  vki_sigset_t* oldset )
 {
    switch(how) {
-   case VKI_SIG_BLOCK:
-   case VKI_SIG_UNBLOCK:
-   case VKI_SIG_SETMASK:
-      vg_assert(VG_(is_valid_tid)(tid));
-      do_setmask ( tid, how, set, oldset );
-      return VG_(mk_SysRes_Success)( 0 );
+      case VKI_SIG_BLOCK:
+      case VKI_SIG_UNBLOCK:
+      case VKI_SIG_SETMASK:
+         vg_assert(VG_(is_valid_tid)(tid));
+         do_setmask ( tid, how, set, oldset );
+         return VG_(mk_SysRes_Success)( 0 );
 
-   default:
-      VG_DMSG("sigprocmask: unknown 'how' field %d", how);
-      return VG_(mk_SysRes_Error)( VKI_EINVAL );
+      default:
+         VG_DMSG("sigprocmask: unknown 'how' field %d", how);
+         return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 }
 
@@ -1220,14 +1228,18 @@ static const Char *signame(Int sigNo)
       case VKI_SIGPROF:   return "SIGPROF";
       case VKI_SIGWINCH:  return "SIGWINCH";
       case VKI_SIGIO:     return "SIGIO";
+#     if defined(VKI_SIGPWR)
       case VKI_SIGPWR:    return "SIGPWR";
+#     endif
 #     if defined(VKI_SIGUNUSED)
       case VKI_SIGUNUSED: return "SIGUNUSED";
 #     endif
 
+#  if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
    case VKI_SIGRTMIN ... VKI_SIGRTMAX:
       VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
       return buf;
+#  endif
 
    default:
       VG_(sprintf)(buf, "SIG%d", sigNo);
@@ -1238,8 +1250,9 @@ static const Char *signame(Int sigNo)
 /* Hit ourselves with a signal using the default handler */
 void VG_(kill_self)(Int sigNo)
 {
-   vki_sigset_t                mask, origmask;
-   struct vki_sigaction sa, origsa;   
+   vki_sigset_t                 mask, origmask;
+   vki_sigaction_toK_t   sa, origsa2;
+   vki_sigaction_fromK_t origsa;   
 
    sa.ksa_handler = VKI_SIG_DFL;
    sa.sa_flags = 0;
@@ -1256,7 +1269,8 @@ void VG_(kill_self)(Int sigNo)
 
    VG_(kill)(VG_(getpid)(), sigNo);
 
-   VG_(sigaction)(sigNo, &origsa, NULL);
+   VG_(convert_sigaction_fromK_to_toK)( &origsa, &origsa2 );
+   VG_(sigaction)(sigNo, &origsa2, NULL);
    VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
 }
 
@@ -1302,35 +1316,39 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid)
    vg_assert(VG_(is_running_thread)(tid));
    
    switch(sigNo) {
-   case VKI_SIGQUIT:   /* core */
-   case VKI_SIGILL:    /* core */
-   case VKI_SIGABRT:   /* core */
-   case VKI_SIGFPE:    /* core */
-   case VKI_SIGSEGV:   /* core */
-   case VKI_SIGBUS:    /* core */
-   case VKI_SIGTRAP:   /* core */
-   case VKI_SIGXCPU:   /* core */
-   case VKI_SIGXFSZ:   /* core */
-      terminate = True;
-      core = True;
-      break;
-
-   case VKI_SIGHUP:    /* term */
-   case VKI_SIGINT:    /* term */
-   case VKI_SIGKILL:   /* term - we won't see this */
-   case VKI_SIGPIPE:   /* term */
-   case VKI_SIGALRM:   /* term */
-   case VKI_SIGTERM:   /* term */
-   case VKI_SIGUSR1:   /* term */
-   case VKI_SIGUSR2:   /* term */
-   case VKI_SIGIO:     /* term */
-   case VKI_SIGPWR:    /* term */
-   case VKI_SIGSYS:    /* term */
-   case VKI_SIGPROF:   /* term */
-   case VKI_SIGVTALRM: /* term */
-   case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
-      terminate = True;
-      break;
+      case VKI_SIGQUIT:        /* core */
+      case VKI_SIGILL: /* core */
+      case VKI_SIGABRT:        /* core */
+      case VKI_SIGFPE: /* core */
+      case VKI_SIGSEGV:        /* core */
+      case VKI_SIGBUS: /* core */
+      case VKI_SIGTRAP:        /* core */
+      case VKI_SIGXCPU:        /* core */
+      case VKI_SIGXFSZ:        /* core */
+         terminate = True;
+         core = True;
+         break;
+
+      case VKI_SIGHUP: /* term */
+      case VKI_SIGINT: /* term */
+      case VKI_SIGKILL:        /* term - we won't see this */
+      case VKI_SIGPIPE:        /* term */
+      case VKI_SIGALRM:        /* term */
+      case VKI_SIGTERM:        /* term */
+      case VKI_SIGUSR1:        /* term */
+      case VKI_SIGUSR2:        /* term */
+      case VKI_SIGIO:  /* term */
+#     if defined(VKI_SIGPWR)
+      case VKI_SIGPWR: /* term */
+#     endif
+      case VKI_SIGSYS: /* term */
+      case VKI_SIGPROF:        /* term */
+      case VKI_SIGVTALRM:      /* term */
+#     if defined(VKI_SIGRTMIN) && defined(VKI_SIGRTMAX)
+      case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
+#     endif
+         terminate = True;
+         break;
    }
 
    vg_assert(!core || (core && terminate));
@@ -1560,7 +1578,6 @@ static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info,
       if (!(handler->scss_flags & VKI_SA_NOMASK)) {
         VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
         VG_(sigaddset)(&tst->sig_mask, sigNo);
-
         tst->tmp_sig_mask = tst->sig_mask;
       }
    }
@@ -1646,12 +1663,13 @@ void VG_(synth_sigtrap)(ThreadId tid)
    VG_(memset)(&uc,   0, sizeof(uc));
    info.si_signo = VKI_SIGTRAP;
    info.si_code = VKI_TRAP_BRKPT; /* tjh: only ever called for a brkpt ins */
-#if defined(VGA_x86) || defined(VGA_amd64)
+
+#  if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
    uc.uc_mcontext.trapno = 3;     /* tjh: this is the x86 trap number
                                           for a breakpoint trap... */
    uc.uc_mcontext.err = 0;        /* tjh: no error code for x86
                                           breakpoint trap... */
-#endif
+#  endif
 
    resume_scheduler(tid);
    deliver_signal(tid, &info, &uc);
@@ -1773,6 +1791,7 @@ void async_signalhandler ( Int sigNo,
 {
    ThreadId     tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
    ThreadState* tst = VG_(get_ThreadState)(tid);
+   SysRes       sres;
 
    /* The thread isn't currently running, make it so before going on */
    vg_assert(tst->status == VgTs_WaitSys);
@@ -1784,19 +1803,59 @@ void async_signalhandler ( Int sigNo,
       VG_DMSG("async signal handler: signal=%d, tid=%d, si_code=%d",
               sigNo, tid, info->si_code);
 
-   /* Update thread state properly */
+   /* Update thread state properly.  The signal can only have been
+      delivered whilst we were in
+      coregrind/m_syswrap/syscall-<PLAT>.S, and only then in the
+      window between the two sigprocmask calls, since at all other
+      times, we run with async signals on the host blocked.  Hence
+      make enquiries on the basis that we were in or very close to a
+      syscall, and attempt to fix up the guest state accordingly.
+
+      (normal async signals occurring during computation are blocked,
+      but periodically polled for using VG_(sigtimedwait_zero), and
+      delivered at a point convenient for us.  Hence this routine only
+      deals with signals that are delivered to a thread during a
+      syscall.) */
+
+   /* First, extract a SysRes from the ucontext_t* given to this
+      handler.  If it is subsequently established by
+      VG_(fixup_guest_state_after_syscall_interrupted) that the
+      syscall was complete but the results had not been committed yet
+      to the guest state, then it'll have to commit the results itself
+      "by hand", and so we need to extract the SysRes.  Of course if
+      the thread was not in that particular window then the
+      SysRes will be meaningless, but that's OK too because
+      VG_(fixup_guest_state_after_syscall_interrupted) will detect
+      that the thread was not in said window and ignore the SysRes. */
+
+   sres = VG_UCONTEXT_SYSCALL_SYSRES(uc);
+
+   /* (1) */
    VG_(fixup_guest_state_after_syscall_interrupted)(
       tid, 
       VG_UCONTEXT_INSTR_PTR(uc), 
-      VG_UCONTEXT_SYSCALL_NUM(uc), 
-      VG_UCONTEXT_SYSCALL_SYSRES(uc),  
+      sres,  
       !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
    );
 
+   /* (2) */
    /* Set up the thread's state to deliver a signal */
    if (!is_sig_ign(info->si_signo))
       deliver_signal(tid, info, uc);
 
+   /* It's crucial that (1) and (2) happen in the order (1) then (2)
+      and not the other way around.  (1) fixes up the guest thread
+      state to reflect the fact that the syscall was interrupted --
+      either to restart the syscall or to return EINTR.  (2) then sets
+      up the thread state to deliver the signal.  Then we resume
+      execution.  First, the signal handler is run, since that's the
+      second adjustment we made to the thread state.  If that returns,
+      then we resume at the guest state created by (1), viz, either
+      the syscall returns EINTR or is restarted.
+
+      If (2) was done before (1) the outcome would be completely
+      different, and wrong. */
+
    /* longjmp back to the thread's main loop to start executing the
       handler. */
    resume_scheduler(tid);
@@ -2007,6 +2066,7 @@ static Bool extend_stack_if_appropriate(ThreadId tid, vki_siginfo_t* info)
    }
 }
 
+
 static
 void sync_signalhandler_from_kernel ( ThreadId tid,
          Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
@@ -2170,7 +2230,7 @@ static void sigvgkill_handler(int signo, vki_siginfo_t *si,
 }
 
 static __attribute((unused))
-void pp_ksigaction ( struct vki_sigaction* sa )
+void pp_ksigaction ( vki_sigaction_toK_t* sa )
 {
    Int i;
    VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n", 
@@ -2194,7 +2254,7 @@ void pp_ksigaction ( struct vki_sigaction* sa )
  */
 void VG_(set_default_handler)(Int signo)
 {
-   struct vki_sigaction sa;   
+   vki_sigaction_toK_t sa;   
 
    sa.ksa_handler = VKI_SIG_DFL;
    sa.sa_flags = 0;
@@ -2214,14 +2274,11 @@ void VG_(poll_signals)(ThreadId tid)
    vki_siginfo_t si, *sip;
    vki_sigset_t pollset;
    ThreadState *tst = VG_(get_ThreadState)(tid);
-   Int i;
    vki_sigset_t saved_mask;
 
    /* look for all the signals this thread isn't blocking */
-   for(i = 0; i < _VKI_NSIG_WORDS; i++)
-      pollset.sig[i] = ~tst->sig_mask.sig[i];
-
-   //VG_(printf)("tid %d pollset=%08x%08x\n", tid, pollset.sig[1], pollset.sig[0]);
+   /* pollset = ~tst->sig_mask */
+   VG_(sigcomplementset)( &pollset, &tst->sig_mask );
 
    block_all_host_signals(&saved_mask); // protect signal queue
 
@@ -2261,9 +2318,18 @@ void VG_(poll_signals)(ThreadId tid)
 */
 void VG_(sigstartup_actions) ( void )
 {
-   Int i, ret;
+   Int i, ret, vKI_SIGRTMIN;
    vki_sigset_t saved_procmask;
-   struct vki_sigaction sa;
+   vki_sigaction_fromK_t sa;
+
+   VG_(memset)(&scss, 0, sizeof(scss));
+   VG_(memset)(&skss, 0, sizeof(skss));
+
+#  if defined(VKI_SIGRTMIN)
+   vKI_SIGRTMIN = VKI_SIGRTMIN;
+#  else
+   vKI_SIGRTMIN = 0; /* eg Darwin */
+#  endif
 
    /* VG_(printf)("SIGSTARTUP\n"); */
    /* Block all signals.  saved_procmask remembers the previous mask,
@@ -2281,8 +2347,9 @@ void VG_(sigstartup_actions) ( void )
 
       /* Try setting it back to see if this signal is really
         available */
-      if (i >= VKI_SIGRTMIN) {
-        struct vki_sigaction tsa;
+      if (vKI_SIGRTMIN > 0 /* it actually exists on this platform */
+          && i >= vKI_SIGRTMIN) {
+         vki_sigaction_toK_t tsa, sa2;
 
         tsa.ksa_handler = (void *)sync_signalhandler;
         tsa.sa_flags = VKI_SA_SIGINFO;
@@ -2297,7 +2364,8 @@ void VG_(sigstartup_actions) ( void )
            break;
         }
 
-        ret = VG_(sigaction)(i, &sa, NULL);
+         VG_(convert_sigaction_fromK_to_toK)( &sa, &sa2 );
+        ret = VG_(sigaction)(i, &sa2, NULL);
         vg_assert(ret == 0);
       }
 
@@ -2310,10 +2378,13 @@ void VG_(sigstartup_actions) ( void )
       scss.scss_per_sig[i].scss_handler  = sa.ksa_handler;
       scss.scss_per_sig[i].scss_flags    = sa.sa_flags;
       scss.scss_per_sig[i].scss_mask     = sa.sa_mask;
-      scss.scss_per_sig[i].scss_restorer = 0;
+
+      scss.scss_per_sig[i].scss_restorer = NULL;
 #     if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
       scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
 #     endif
+
+      scss.scss_per_sig[i].scss_sa_tramp = NULL;
    }
 
    if (VG_(clo_trace_signals))
index 676254a5abb16a95befbe43175c323850d5a27c6..0970e6b837356dfb089d1fe35823987386e07cde 100644 (file)
@@ -37,7 +37,9 @@
    Building syscall return values.
    ------------------------------------------------------------------ */
 
-/* Make a SysRes value from an syscall return value.  This is
+#if defined(VGO_linux)
+
+/* Make a SysRes value from a syscall return value.  This is
    Linux-specific.
 
    From:
    syscall returns a value in -1 .. -4095 as a valid result so we can
    safely test with -4095.
 */
-SysRes VG_(mk_SysRes_x86_linux) ( UInt val ) {
+
+SysRes VG_(mk_SysRes_x86_linux) ( Int val ) {
    SysRes res;
-   res.isError = val >= -4095 && val <= -1;
-   if (res.isError) {
-      res.err = -val;
-      res.res = 0;
+   res._isError = val >= -4095 && val <= -1;
+   if (res._isError) {
+      res._val = (UInt)(-val);
    } else {
-      res.err = 0;
-      res.res = val;
+      res._val = (UInt)val;
    }
    return res;
 }
 
 /* Similarly .. */
-SysRes VG_(mk_SysRes_amd64_linux) ( ULong val ) {
+SysRes VG_(mk_SysRes_amd64_linux) ( Long val ) {
    SysRes res;
-   res.isError = val >= -4095 && val <= -1;
-   if (res.isError) {
-      res.err = -val;
-      res.res = 0;
+   res._isError = val >= -4095 && val <= -1;
+   if (res._isError) {
+      res._val = (ULong)(-val);
    } else {
-      res.err = 0;
-      res.res = val;
+      res._val = (ULong)val;
    }
    return res;
 }
@@ -87,31 +86,37 @@ SysRes VG_(mk_SysRes_amd64_linux) ( ULong val ) {
 /* Note this must be in the bottom bit of the second arg */
 SysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so ) {
    SysRes res;
-   res.isError = (cr0so & 1) != 0;
-   if (res.isError) {
-      res.err = val;
-      res.res = 0;
-   } else {
-      res.err = 0;
-      res.res = val;
-   }
+   res._isError = (cr0so & 1) != 0;
+   res._val     = val;
    return res;
 }
 
 /* As per ppc32 version, cr0.so must be in l.s.b. of 2nd arg */
 SysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong cr0so ) {
    SysRes res;
-   res.isError = (cr0so & 1) != 0;
-   if (res.isError) {
-      res.err = val;
-      res.res = 0;
-   } else {
-      res.err = 0;
-      res.res = val;
-   }
+   res._isError = (cr0so & 1) != 0;
+   res._val     = val;
    return res;
 }
 
+/* Generic constructors. */
+SysRes VG_(mk_SysRes_Error) ( UWord err ) {
+   SysRes r;
+   r._isError = True;
+   r._val     = err;
+   return r;
+}
+
+SysRes VG_(mk_SysRes_Success) ( UWord res ) {
+   SysRes r;
+   r._isError = False;
+   r._val     = res;
+   return r;
+}
+
+
+#elif defined(VGO_aix5)
+
 /* AIX scheme: we have to record both 'res' (r3) and 'err' (r4).  If
    'err' is nonzero then the call has failed, but it could still be
    that AIX userspace will ignore 'err' and instead consult 'res' to
@@ -135,23 +140,28 @@ SysRes VG_(mk_SysRes_ppc64_aix5) ( ULong res, ULong err ) {
 /* Generic constructors. */
 SysRes VG_(mk_SysRes_Error) ( UWord err ) {
    SysRes r;
-   r.res     = 0;
-   r.err     = err;
-   r.isError = True;
+   r._res     = 0;
+   r._err     = err;
+   r._isError = True;
    return r;
 }
 
 SysRes VG_(mk_SysRes_Success) ( UWord res ) {
    SysRes r;
-   r.res     = res;
-   r.err     = 0;
-   r.isError = False;
+   r._res     = res;
+   r._err     = 0;
+   r._isError = False;
    return r;
 }
 
 
+#else
+#  error "Unknown OS"
+#endif
+
+
 /* ---------------------------------------------------------------------
-   A function for doing syscalls.
+   VG_(do_syscall): A function for doing syscalls.
    ------------------------------------------------------------------ */
 
 #if defined(VGP_x86_linux)
@@ -268,7 +278,7 @@ asm(
    different from the ppc32 case.  The single arg register points to a
    7-word block containing the syscall # and the 6 args.  The syscall
    result proper is put in [0] of the block, and %cr0.so is in the
-   bottom but of [1]. */
+   bottom bit of [1]. */
 extern void do_syscall_WRK ( ULong* argblock );
 asm(
 ".align   2\n"
@@ -455,37 +465,40 @@ static void do_syscall_WRK ( UWord* res_r3, UWord* res_r4,
 #endif
 
 
+/* Finally, the generic code.  This sends the call to the right
+   helper. */
+
 SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3,
                                       UWord a4, UWord a5, UWord a6,
                                       UWord a7, UWord a8 )
 {
-#if defined(VGP_x86_linux)
-  UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
-  return VG_(mk_SysRes_x86_linux)( val );
-
-#elif defined(VGP_amd64_linux)
-  UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
-  return VG_(mk_SysRes_amd64_linux)( val );
-
-#elif defined(VGP_ppc32_linux)
-  ULong ret     = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
-  UInt  val     = (UInt)(ret>>32);
-  UInt  cr0so   = (UInt)(ret);
-  return VG_(mk_SysRes_ppc32_linux)( val, cr0so );
-
-#elif defined(VGP_ppc64_linux)
-  ULong argblock[7];
-  argblock[0] = sysno;
-  argblock[1] = a1;
-  argblock[2] = a2;
-  argblock[3] = a3;
-  argblock[4] = a4;
-  argblock[5] = a5;
-  argblock[6] = a6;
-  do_syscall_WRK( &argblock[0] );
-  return VG_(mk_SysRes_ppc64_linux)( argblock[0], argblock[1] );
-
-#elif defined(VGP_ppc32_aix5)
+#  if defined(VGP_x86_linux)
+   UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
+   return VG_(mk_SysRes_x86_linux)( val );
+
+#  elif defined(VGP_amd64_linux)
+   UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
+   return VG_(mk_SysRes_amd64_linux)( val );
+
+#  elif defined(VGP_ppc32_linux)
+   ULong ret     = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
+   UInt  val     = (UInt)(ret>>32);
+   UInt  cr0so   = (UInt)(ret);
+   return VG_(mk_SysRes_ppc32_linux)( val, cr0so );
+
+#  elif defined(VGP_ppc64_linux)
+   ULong argblock[7];
+   argblock[0] = sysno;
+   argblock[1] = a1;
+   argblock[2] = a2;
+   argblock[3] = a3;
+   argblock[4] = a4;
+   argblock[5] = a5;
+   argblock[6] = a6;
+   do_syscall_WRK( &argblock[0] );
+   return VG_(mk_SysRes_ppc64_linux)( argblock[0], argblock[1] );
+
+#  elif defined(VGP_ppc32_aix5)
    UWord res;
    UWord err;
    do_syscall_WRK( &res, &err, 
@@ -502,10 +515,9 @@ SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3,
       if (res == 0)
          err = 0;
    }
-
    return VG_(mk_SysRes_ppc32_aix5)( res, err );
 
-#elif defined(VGP_ppc64_aix5)
+#  elif defined(VGP_ppc64_aix5)
    UWord res;
    UWord err;
    do_syscall_WRK( &res, &err, 
@@ -522,7 +534,6 @@ SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3,
       if (res == 0)
          err = 0;
    }
-
    return VG_(mk_SysRes_ppc64_aix5)( res, err );
 
 #else
@@ -556,7 +567,9 @@ const HChar* VG_(strerror) ( UWord errnum )
       case VKI_EMFILE:      return "Too many open files";
       case VKI_ENOSYS:      return "Function not implemented";
       case VKI_EOVERFLOW:   return "Value too large for defined data type";
+#     if defined(VKI_ERESTARTSYS)
       case VKI_ERESTARTSYS: return "ERESTARTSYS";
+#     endif
       default:              return "VG_(strerror): unknown error";
    }
 }
index 28c0ab95e12a510dad886badb220e9e5e0cdf9a6..bdb4b4fc607b72e9cae910f0971dab2cfdf18d8e 100644 (file)
@@ -81,6 +81,18 @@ typedef
 typedef
    struct {
       Int o_sysno;
+#     if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
+         || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+      Int o_arg1;
+      Int o_arg2;
+      Int o_arg3;
+      Int o_arg4;
+      Int o_arg5;
+      Int o_arg6;
+      Int uu_arg7;
+      Int uu_arg8;
+      Int o_retval;
+#     elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
       Int o_arg1;
       Int o_arg2;
       Int o_arg3;
@@ -90,6 +102,9 @@ typedef
       Int o_arg7;
       Int o_arg8;
       Int o_retval;
+#     else
+#       error "Unknown platform"
+#     endif
    }
    SyscallArgLayout;
 
@@ -274,22 +289,29 @@ SyscallTableEntry* ML_(get_ppc64_aix5_syscall_entry) ( UInt sysno );
 
 /* 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 SUCCESS       (status->what == SsComplete && !sr_isError(status->sres))
+#define FAILURE       (status->what == SsComplete &&  sr_isError(status->sres))
 #define SWHAT         (status->what)
 #define RES           (getRES(status))
+#define RESHI         (getRESHI(status))
 #define ERR           (getERR(status))
 
 static inline UWord getRES ( SyscallStatus* st ) {
    vg_assert(st->what == SsComplete);
-   vg_assert(!st->sres.isError);
-   return st->sres.res;
+   vg_assert(!sr_isError(st->sres));
+   return sr_Res(st->sres);
+}
+
+static inline UWord getRESHI ( SyscallStatus* st ) {
+   vg_assert(st->what == SsComplete);
+   vg_assert(!sr_isError(st->sres));
+   return sr_ResHI(st->sres);
 }
 
 static inline UWord getERR ( SyscallStatus* st ) {
    vg_assert(st->what == SsComplete);
-   vg_assert(st->sres.isError);
-   return st->sres.err;
+   vg_assert(sr_isError(st->sres));
+   return sr_Err(st->sres);
 }
 
 
index b6f913a009e0eb40e8aeb58b662f3d10b97d0f55..c539f885fe0f2b7492343240319cb36ac45be5f1 100644 (file)
@@ -66,7 +66,7 @@
                                  void* guest_state,            // rsi
                                  const vki_sigset_t *sysmask,  // rdx
                                  const vki_sigset_t *postmask, // rcx
-                                 Int nsigwords)                // r8
+                                 Int sigsetSzB)                // r8
                                   
 */
 
@@ -113,7 +113,7 @@ ML_(do_syscall_for_client_WRK):
        movq    $VKI_SIG_SETMASK, %rdi          // how
        movq    %rdx, %rsi                      // sysmask
        movq    %rcx, %rdx                      // postmask
-       movq    %r8, %r10                       // nsigwords
+       movq    %r8, %r10                       // sigsetSzB
        syscall
 
        POP_di_si_dx_cx_8
@@ -155,7 +155,7 @@ ML_(do_syscall_for_client_WRK):
        movq    $VKI_SIG_SETMASK, %rdi          // how
        movq    %rcx, %rsi                      // postmask
        xorq    %rdx, %rdx                      // NULL
-       movq    %r8, %r10                       // nsigwords
+       movq    %r8, %r10                       // sigsetSzB
        syscall
 
        POP_di_si_dx_cx_8
index b1e1a19e8f7f7c12a5b1403523d1dc143c700eaa..c5dbcdd6a4d17edc00787d5d6860204b4f912f3d 100644 (file)
@@ -72,7 +72,7 @@
                                  void* guest_state,            // r4
                                  const vki_sigset_t *sysmask,  // r5
                                  const vki_sigset_t *postmask, // r6
-                                 Int nsigwords,                // r7
+                                 Int sigsetSzB,                // r7
                                  Int __nr_sigprocmask)         // r8
 */
        .file   "syscall-ppc32-aix6.S"
@@ -101,7 +101,7 @@ ML_(do_syscall_for_client_WRK):
         mr      31,3            /* syscall number */
         mr      30,4            /* guest_state */
         mr      29,6            /* postmask */
-        mr      28,7            /* nsigwords */
+        mr      28,7            /* sigsetSzB */
        mr      27,8            /* __nr_sigprocmask */
 
 Lvg1:   /* Even though we can't take a signal until the sigprocmask 
@@ -114,7 +114,7 @@ Lvg1:   /* Even though we can't take a signal until the sigprocmask
         li      3,VKI_SIG_SETMASK
         mr      4,5
         mr      5,6
-       mr      6,7     /* nsigwords -- needed on AIX ? */
+       mr      6,7     /* sigsetSzB -- needed on AIX ? */
 
        /* actually do the sigprocmask */
        crorc   6,6,6
@@ -164,7 +164,7 @@ Lvg4:   mr  2,27
         li      3,VKI_SIG_SETMASK
         mr      4,29
         li      5,0
-        mr      6,28   /* nsigwords -- needed on AIX ? */
+        mr      6,28   /* sigsetSzB -- needed on AIX ? */
 
        /* actually do the sigprocmask */
        crorc   6,6,6
index a88dcc3f0019865a039c76693908161b85920a61..48b174d1c933c2e72a1edc86736899332c52c1a4 100644 (file)
@@ -66,7 +66,7 @@
                                  void* guest_state,            // r4
                                  const vki_sigset_t *sysmask,  // r5
                                  const vki_sigset_t *postmask, // r6
-                                 Int nsigwords)                // r7
+                                 Int sigsetSzB)                // r7
 */
 /* from vki_arch.h */
 #define VKI_SIG_SETMASK 2
@@ -82,7 +82,7 @@ ML_(do_syscall_for_client_WRK):
         mr      31,3            /* syscall number */
         mr      30,4            /* guest_state */
         mr      29,6            /* postmask */
-        mr      28,7            /* nsigwords */
+        mr      28,7            /* sigsetSzB */
 
         /* set the signal mask for doing the system call */
         /* set up for sigprocmask(SIG_SETMASK, sysmask, postmask) */
index bbf3909e074568c3212a4ae5ac039a64014e19ba..5d308e171e62c3c9092f0b8aa7e4e96dbca2e351 100644 (file)
@@ -72,7 +72,7 @@
                                  void* guest_state,            // r4
                                  const vki_sigset_t *sysmask,  // r5
                                  const vki_sigset_t *postmask, // r6
-                                 Int nsigwords,                // r7
+                                 Int sigsetSzB,                // r7
                                  Int __nr_sigprocmask)         // r8
 */
        .file   "syscall-ppc64-aix6.S"
@@ -101,7 +101,7 @@ ML_(do_syscall_for_client_WRK):
         mr      31,3            /* syscall number */
         mr      30,4            /* guest_state */
         mr      29,6            /* postmask */
-        mr      28,7            /* nsigwords */
+        mr      28,7            /* sigsetSzB */
        mr      27,8            /* __nr_sigprocmask */
 
 Lvg1:   /* Even though we can't take a signal until the sigprocmask 
@@ -114,7 +114,7 @@ Lvg1:   /* Even though we can't take a signal until the sigprocmask
         li      3,VKI_SIG_SETMASK
         mr      4,5
         mr      5,6
-       mr      6,7     /* nsigwords -- needed on AIX ? */
+       mr      6,7     /* sigsetSzB -- needed on AIX ? */
 
        /* actually do the sigprocmask */
        crorc   6,6,6
@@ -164,7 +164,7 @@ Lvg4:   mr  2,27
         li      3,VKI_SIG_SETMASK
         mr      4,29
         li      5,0
-        mr      6,28   /* nsigwords -- needed on AIX ? */
+        mr      6,28   /* sigsetSzB -- needed on AIX ? */
 
        /* actually do the sigprocmask */
        crorc   6,6,6
index 5e17995e3be4e49548d98915b921deb55607c438..479300b4a497d8378b21afe47ecdae8512b2c6cb 100644 (file)
@@ -66,7 +66,7 @@
                                  void* guest_state,            // r4
                                  const vki_sigset_t *sysmask,  // r5
                                  const vki_sigset_t *postmask, // r6
-                                 Int nsigwords)                // r7
+                                 Int sigsetSzB)                // r7
 */
 /* from vki_arch.h */
 #define VKI_SIG_SETMASK 2
@@ -90,7 +90,7 @@ ML_(do_syscall_for_client_WRK):
         mr      31,3            /* syscall number */
         mr      30,4            /* guest_state */
         mr      29,6            /* postmask */
-        mr      28,7            /* nsigwords */
+        mr      28,7            /* sigsetSzB */
 
         /* set the signal mask for doing the system call */
         /* set up for sigprocmask(SIG_SETMASK, sysmask, postmask) */
index 4806f5178f158f4dddab52b0371e7ca7d13d9827..d7001891d2aed7a92696f9387b3163f33ab24442 100644 (file)
@@ -67,7 +67,7 @@
                                  void* guest_state,            // 4
                                  const vki_sigset_t *sysmask,  // 8
                                  const vki_sigset_t *postmask, // 12
-                                 Int nsigwords)                // 16
+                                 Int sigsetSzB)                // 16
                                   
 */
 
index 995d067ba32443485468ca3879267f00e5367e77..27e158bc9249d718cc0ab361eb22a9c3ed269ef9 100644 (file)
@@ -297,7 +297,7 @@ static SysRes do_clone ( ThreadId ptid,
    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
 
   out:
-   if (res.isError) {
+   if (sr_isError(res)) {
       /* clone failed */
       VG_(cleanup_thread)(&ctst->arch);
       ctst->status = VgTs_Empty;
index 4d0326237c0ecdf71e963f733af603e99a92f686..5871bc3669c2a245f211fa78c1f7a77a394daba3 100644 (file)
@@ -481,7 +481,7 @@ SysRes do_mremap( Addr old_addr, SizeT old_len,
   shrink_in_place:
    {
    SysRes sres = VG_(am_munmap_client)( &d, old_addr+new_len, old_len-new_len );
-   if (sres.isError)
+   if (sr_isError(sres))
       return sres;
    VG_TRACK( die_mem_munmap, old_addr+new_len, old_len-new_len );
    if (d)
@@ -765,12 +765,12 @@ void VG_(init_preopened_fds)(void)
    SysRes f;
 
    f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
-   if (f.isError) {
+   if (sr_isError(f)) {
       init_preopened_fds_without_proc_self_fd();
       return;
    }
 
-   while ((ret = VG_(getdents)(f.res, &d, sizeof(d))) != 0) {
+   while ((ret = VG_(getdents)(sr_Res(f), &d, sizeof(d))) != 0) {
       if (ret == -1)
          goto out;
 
@@ -778,7 +778,7 @@ void VG_(init_preopened_fds)(void)
          Char* s;
          Int fno = VG_(strtoll10)(d.d_name, &s);
          if (*s == '\0') {
-            if (fno != f.res)
+            if (fno != sr_Res(f))
                if (VG_(clo_track_fds))
                   ML_(record_fd_open_named)(-1, fno);
          } else {
@@ -787,11 +787,11 @@ void VG_(init_preopened_fds)(void)
          }
       }
 
-      VG_(lseek)(f.res, d.d_off, VKI_SEEK_SET);
+      VG_(lseek)(sr_Res(f), d.d_off, VKI_SEEK_SET);
    }
 
   out:
-   VG_(close)(f.res);
+   VG_(close)(sr_Res(f));
 
 #else
 #  error Unknown OS
@@ -985,7 +985,8 @@ void ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p,
    if (VG_(tdict).track_pre_mem_write) {
       UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
       if (buflen_in > 0) {
-         VG_(tdict).track_pre_mem_write( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
+         VG_(tdict).track_pre_mem_write(
+            Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
       }
    }
 }
@@ -993,7 +994,7 @@ void ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p,
 void ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res,
                                    Addr buf_p, Addr buflen_p, Char* s )
 {
-   if (!res.isError && VG_(tdict).track_post_mem_write) {
+   if (!sr_isError(res) && VG_(tdict).track_post_mem_write) {
       UInt buflen_out = deref_UInt( tid, buflen_p, s);
       if (buflen_out > 0 && buf_p != (Addr)NULL) {
          VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
@@ -1216,7 +1217,7 @@ ML_(generic_POST_sys_socketpair) ( ThreadId tid,
    SysRes r = res;
    Int fd1 = ((Int*)arg3)[0];
    Int fd2 = ((Int*)arg3)[1];
-   vg_assert(!res.isError); /* guaranteed by caller */
+   vg_assert(!sr_isError(res)); /* guaranteed by caller */
    POST_MEM_WRITE( arg3, 2*sizeof(int) );
    if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
        !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
@@ -1239,13 +1240,13 @@ SysRes
 ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
 {
    SysRes r = res;
-   vg_assert(!res.isError); /* guaranteed by caller */
-   if (!ML_(fd_allowed)(res.res, "socket", tid, True)) {
-      VG_(close)(res.res);
+   vg_assert(!sr_isError(res)); /* guaranteed by caller */
+   if (!ML_(fd_allowed)(sr_Res(res), "socket", tid, True)) {
+      VG_(close)(sr_Res(res));
       r = VG_(mk_SysRes_Error)( VKI_EMFILE );
    } else {
       if (VG_(clo_track_fds))
-         ML_(record_fd_open_nameless)(tid, res.res);
+         ML_(record_fd_open_nameless)(tid, sr_Res(res));
    }
    return r;
 }
@@ -1285,9 +1286,9 @@ ML_(generic_POST_sys_accept) ( ThreadId tid,
                                UWord arg0, UWord arg1, UWord arg2 )
 {
    SysRes r = res;
-   vg_assert(!res.isError); /* guaranteed by caller */
-   if (!ML_(fd_allowed)(res.res, "accept", tid, True)) {
-      VG_(close)(res.res);
+   vg_assert(!sr_isError(res)); /* guaranteed by caller */
+   if (!ML_(fd_allowed)(sr_Res(res), "accept", tid, True)) {
+      VG_(close)(sr_Res(res));
       r = VG_(mk_SysRes_Error)( VKI_EMFILE );
    } else {
       Addr addr_p     = arg1;
@@ -1296,7 +1297,7 @@ ML_(generic_POST_sys_accept) ( ThreadId tid,
          ML_(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.res);
+          ML_(record_fd_open_nameless)(tid, sr_Res(res));
    }
    return r;
 }
@@ -1364,7 +1365,7 @@ ML_(generic_POST_sys_recvfrom) ( ThreadId tid,
    Addr from_p     = arg4;
    Addr fromlen_p  = arg5;
 
-   vg_assert(!res.isError); /* guaranteed by caller */
+   vg_assert(!sr_isError(res)); /* guaranteed by caller */
    if (from_p != (Addr)NULL) 
       ML_(buf_and_len_post_check) ( tid, res, from_p, fromlen_p,
                                     "socketcall.recvfrom(fromlen_out)" );
@@ -1451,7 +1452,7 @@ ML_(generic_POST_sys_getsockname) ( ThreadId tid,
 {
    Addr name_p     = arg1;
    Addr namelen_p  = arg2;
-   vg_assert(!res.isError); /* guaranteed by caller */
+   vg_assert(!sr_isError(res)); /* guaranteed by caller */
    ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
                                  "socketcall.getsockname(namelen_out)" );
 }
@@ -1478,7 +1479,7 @@ ML_(generic_POST_sys_getpeername) ( ThreadId tid,
 {
    Addr name_p     = arg1;
    Addr namelen_p  = arg2;
-   vg_assert(!res.isError); /* guaranteed by caller */
+   vg_assert(!sr_isError(res)); /* guaranteed by caller */
    ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
                                  "socketcall.getpeername(namelen_out)" );
 }
@@ -1565,7 +1566,7 @@ UInt get_sem_count( Int semid )
    res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
                           VKI_IPC_STAT, (UWord)&arg);
 #  endif
-   if (res.isError)
+   if (sr_isError(res))
       return 0;
 
    return buf.sem_nsems;
@@ -1658,15 +1659,20 @@ ML_(generic_POST_sys_semctl) ( ThreadId tid,
 static
 UInt get_shm_size ( Int shmid )
 {
-#  ifdef __NR_shmctl
+#ifdef __NR_shmctl
+#  ifdef VKI_IPC_64
    struct vki_shmid64_ds buf;
    SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
 #  else
+   struct vki_shmid_ds buf;
+   SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
+#  endif
+#else
    struct vki_shmid_ds buf;
    SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
                                  VKI_IPC_STAT, 0, (UWord)&buf);
-#  endif
-   if (__res.isError)
+#endif
+   if (sr_isError(__res))
       return 0;
  
    return buf.shm_segsz;
@@ -1916,7 +1922,7 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid,
       of address.  If we were originally asked for a hinted mapping,
       there is still a last chance: try again at any address.
       Hence: */
-   if (mreq.rkind == MHint && sres.isError) {
+   if (mreq.rkind == MHint && sr_isError(sres)) {
       mreq.start = 0;
       mreq.len   = arg2;
       mreq.rkind = MAny;
@@ -1931,11 +1937,11 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid,
                                        arg5, arg6);
    }
 
-   if (!sres.isError) {
+   if (!sr_isError(sres)) {
       ULong di_handle;
       /* Notify aspacem. */
       notify_core_of_mmap(
-         (Addr)sres.res, /* addr kernel actually assigned */
+         (Addr)sr_Res(sres), /* addr kernel actually assigned */
          arg2, /* length */
          arg3, /* prot */
          arg4, /* the original flags value */
@@ -1943,10 +1949,11 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid,
          arg6  /* offset */
       );
       /* Load symbols? */
-      di_handle = VG_(di_notify_mmap)( (Addr)sres.res, False/*allow_SkFileV*/ );
+      di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres), 
+                                       False/*allow_SkFileV*/ );
       /* Notify the tool. */
       notify_tool_of_mmap(
-         (Addr)sres.res, /* addr kernel actually assigned */
+         (Addr)sr_Res(sres), /* addr kernel actually assigned */
          arg2, /* length */
          arg3, /* prot */
          di_handle /* so the tool can refer to the read debuginfo later,
@@ -1955,8 +1962,8 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid,
    }
 
    /* Stay sane */
-   if (!sres.isError && (arg4 & VKI_MAP_FIXED))
-      vg_assert(sres.res == arg1);
+   if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED))
+      vg_assert(sr_Res(sres) == arg1);
 
    return sres;
 }
@@ -2429,8 +2436,8 @@ PRE(sys_execve)
    // we are not simulating them, that is, they to be run natively.
    setuid_allowed = VG_(clo_trace_children)  ? False  : True;
    res = VG_(pre_exec_check)((const Char*)ARG1, NULL, setuid_allowed);
-   if (res.isError) {
-      SET_STATUS_Failure( res.err );
+   if (sr_isError(res)) {
+      SET_STATUS_Failure( sr_Err(res) );
       return;
    }
 
@@ -2572,14 +2579,20 @@ PRE(sys_execve)
       vki_sigset_t allsigs;
       vki_siginfo_t info;
 
+      /* What this loop does: it queries SCSS (the signal state that
+         the client _thinks_ the kernel is in) by calling
+         VG_(do_sys_sigaction), and modifies the real kernel signal
+         state accordingly. */
       for (i = 1; i < VG_(max_signal); i++) {
-         struct vki_sigaction sa;
-         VG_(do_sys_sigaction)(i, NULL, &sa);
-         if (sa.ksa_handler == VKI_SIG_IGN)
-            VG_(sigaction)(i, &sa, NULL);
+         vki_sigaction_fromK_t sa_f;
+         vki_sigaction_toK_t   sa_t;
+         VG_(do_sys_sigaction)(i, NULL, &sa_f);
+         VG_(convert_sigaction_fromK_to_toK)(&sa_f, &sa_t);
+         if (sa_t.ksa_handler == VKI_SIG_IGN)
+            VG_(sigaction)(i, &sa_t, NULL);
          else {
-            sa.ksa_handler = VKI_SIG_DFL;
-            VG_(sigaction)(i, &sa, NULL);
+            sa_t.ksa_handler = VKI_SIG_DFL;
+            VG_(sigaction)(i, &sa_t, NULL);
          }
       }
 
@@ -2792,6 +2805,7 @@ static vki_sigset_t fork_saved_mask;
 // ignore the various args it gets, and so it looks arch-neutral.  Hmm.
 PRE(sys_fork)
 {
+   UWord result;
    vki_sigset_t mask;
 
    PRINT("sys_fork ( )");
@@ -2804,6 +2818,10 @@ PRE(sys_fork)
 
    SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
 
+   if (!SUCCESS) return;
+
+   result = RES;
+
    VG_(do_atfork_pre)(tid);
 
    if (SUCCESS && RES == 0) {
@@ -3148,7 +3166,11 @@ PRE(sys_kill)
    if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1))
       SET_STATUS_Success(0);
    else
-      SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
+      /* re syscall3: Darwin has a 3rd arg, which is a flag (boolean)
+         affecting how posix-compliant the call is.  I guess it is
+         harmless to pass the 3rd arg on other platforms; hence pass
+         it on all. */
+      SET_STATUS_from_SysRes( VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3) );
 
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugMsg, "kill: sent signal %ld to pid %ld",
@@ -3341,8 +3363,8 @@ PRE(sys_open)
            || VG_(strcmp)((Char *)ARG1, "/proc/self/cmdline") == 0)) {
       sres = VG_(dup)( VG_(cl_cmdline_fd) );
       SET_STATUS_from_SysRes( sres );
-      if (!sres.isError) {
-         OffT off = VG_(lseek)( sres.res, 0, VKI_SEEK_SET );
+      if (!sr_isError(sres)) {
+         OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
          if (off < 0)
             SET_STATUS_Failure( VKI_EMFILE );
       }
@@ -3848,7 +3870,6 @@ PRE(sys_pause)
    PRE_REG_READ0(long, "pause");
 }
 
-// XXX: x86-specific
 PRE(sys_sigaltstack)
 {
    PRINT("sigaltstack ( %#lx, %#lx )",ARG1,ARG2);
index a1023a1773ba3e6718f0a57ccdf7b75ac9a3265f..a753a2ad69904b80259b55998c8cf29079609436 100644 (file)
@@ -331,7 +331,7 @@ SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
 # error Unknown platform
 #endif
 
-   if (!res.isError && res.res == 0) {
+   if (!sr_isError(res) && sr_Res(res) == 0) {
       /* child */
       VG_(do_atfork_child)(tid);
 
@@ -346,13 +346,13 @@ SysRes ML_(do_fork_clone) ( ThreadId tid, UInt flags,
          VG_(clo_log_fd) = -1;
    } 
    else 
-   if (!res.isError && res.res > 0) {
+   if (!sr_isError(res) && sr_Res(res) > 0) {
       /* parent */
       VG_(do_atfork_parent)(tid);
 
       if (VG_(clo_trace_syscalls))
          VG_(printf)("   clone(fork): process %d created child %ld\n",
-                      VG_(getpid)(), res.res);
+                      VG_(getpid)(), sr_Res(res));
 
       /* restore signal mask */
       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
@@ -1744,9 +1744,9 @@ static Bool linux_kernel_2_6_22(void)
 
    if (result == -1) {
       res = VG_(open)("/proc/sys/kernel/osrelease", 0, 0);
-      if (res.isError)
+      if (sr_isError(res))
          return False;
-      fd = res.res;
+      fd = sr_Res(res);
       read = VG_(read)(fd, release, sizeof(release) - 1);
       vg_assert(read >= 0);
       release[read] = 0;
@@ -2482,7 +2482,7 @@ PRE(sys_rt_sigaction)
                  struct sigaction *, oldact, vki_size_t, sigsetsize);
 
    if (ARG2 != 0) {
-      struct vki_sigaction *sa = (struct vki_sigaction *)ARG2;
+      vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2;
       PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
       PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
       PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
@@ -2490,22 +2490,22 @@ PRE(sys_rt_sigaction)
          PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
    }
    if (ARG3 != 0)
-      PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
+      PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(vki_sigaction_fromK_t));
 
    // XXX: doesn't seem right to be calling do_sys_sigaction for
    // sys_rt_sigaction... perhaps this function should be renamed
    // VG_(do_sys_rt_sigaction)()  --njn
 
    SET_STATUS_from_SysRes(
-      VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
-                            (struct vki_sigaction *)ARG3)
+      VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2,
+                            (vki_sigaction_fromK_t *)ARG3)
    );
 }
 POST(sys_rt_sigaction)
 {
    vg_assert(SUCCESS);
    if (RES == 0 && ARG3 != 0)
-      POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
+      POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
 }
 
 PRE(sys_rt_sigprocmask)
@@ -2735,8 +2735,8 @@ PRE(sys_openat)
            || VG_(strcmp)((Char *)ARG2, "/proc/self/cmdline") == 0)) {
       sres = VG_(dup)( VG_(cl_cmdline_fd) );
       SET_STATUS_from_SysRes( sres );
-      if (!sres.isError) {
-         OffT off = VG_(lseek)( sres.res, 0, VKI_SEEK_SET );
+      if (!sr_isError(sres)) {
+         OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
          if (off < 0)
             SET_STATUS_Failure( VKI_EMFILE );
       }
@@ -5217,7 +5217,7 @@ ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
 {
    Addr optval_p = arg3;
    Addr optlen_p = arg4;
-   vg_assert(!res.isError); /* guaranteed by caller */
+   vg_assert(!sr_isError(res)); /* guaranteed by caller */
    if (optval_p != (Addr)NULL) {
       ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p,
                                     "socketcall.getsockopt(optlen_out)" );
index 63a03f6e3fb66f569d91c4d25a8aa027e09d841f..3e589e30746b71355f25d24868830a783cddcfe5 100644 (file)
    in coregrind/m_syswrap/syscall-$PLAT.S.  It has some very magic
    properties.  See comments at the top of
    VG_(fixup_guest_state_after_syscall_interrupted) below for details.
+
+   This function (these functions) are required to return zero in case
+   of success (even if the syscall itself failed), and nonzero if the
+   sigprocmask-swizzling calls failed.  We don't actually care about
+   the failure values from sigprocmask, although most of the assembly
+   implementations do attempt to return that, using the convention
+   0 for success, or 0x8000 | error-code for failure.
 */
+#if defined(VGO_linux)
+extern
+UWord ML_(do_syscall_for_client_WRK)( Word syscallno, 
+                                      void* guest_state,
+                                      const vki_sigset_t *syscall_mask,
+                                      const vki_sigset_t *restore_mask,
+                                      Word sigsetSzB );
+#elif defined(VGO_aix5)
 extern
 UWord ML_(do_syscall_for_client_WRK)( Word syscallno, 
                                       void* guest_state,
                                       const vki_sigset_t *syscall_mask,
                                       const vki_sigset_t *restore_mask,
-                                      Word nsigwords
-#                                     if defined(VGO_aix5)
-                                      , Word __nr_sigprocmask
-#                                     endif
-                                    );
+                                      Word sigsetSzB, /* unused */
+                                      Word __nr_sigprocmask );
+#else
+#  error "Unknown OS"
+#endif
+
 
 static
 void do_syscall_for_client ( Int syscallno,
@@ -250,14 +266,21 @@ void do_syscall_for_client ( Int syscallno,
                              const vki_sigset_t* syscall_mask )
 {
    vki_sigset_t saved;
-   UWord err 
-      = 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
-        );
+   UWord err;
+#  if defined(VGO_linux)
+   err = ML_(do_syscall_for_client_WRK)(
+            syscallno, &tst->arch.vex, 
+            syscall_mask, &saved, sizeof(vki_sigset_t)
+         );
+#  elif defined(VGO_aix5)
+   err = ML_(do_syscall_for_client_WRK)(
+            syscallno, &tst->arch.vex, 
+            syscall_mask, &saved, 0/*unused:sigsetSzB*/,
+            __NR_rt_sigprocmask
+         );
+#  else
+#    error "Unknown OS"
+#  endif
    vg_assert2(
       err == 0,
       "ML_(do_syscall_for_client_WRK): sigprocmask error %d",
@@ -266,7 +289,6 @@ void do_syscall_for_client ( Int syscallno,
 }
 
 
-
 /* ---------------------------------------------------------------------
    Impedance matchers and misc helpers
    ------------------------------------------------------------------ */
@@ -288,12 +310,12 @@ Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 )
 static
 Bool eq_SyscallStatus ( SyscallStatus* s1, SyscallStatus* s2 )
 {
-   return s1->what == s2->what 
-          && s1->sres.res == s2->sres.res
-          && s1->sres.err == s2->sres.err;
+   /* was: return s1->what == s2->what && sr_EQ( s1->sres, s2->sres ); */
+   if (s1->what == s2->what && sr_EQ( s1->sres, s2->sres ))
+      return True;
+   return False;
 }
 
-
 /* Convert between SysRes and SyscallStatus, to the extent possible. */
 
 static
@@ -519,53 +541,53 @@ void putSyscallStatusIntoGuestState ( /*IN*/ SyscallStatus*     canonical,
 #  if defined(VGP_x86_linux)
    VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
    vg_assert(canonical->what == SsComplete);
-   if (canonical->sres.isError) {
+   if (sr_isError(canonical->sres)) {
       /* 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->sres.err;
+      gst->guest_EAX = - (Int)sr_Err(canonical->sres);
    } else {
-      gst->guest_EAX = canonical->sres.res;
+      gst->guest_EAX = sr_Res(canonical->sres);
    }
 
 #  elif defined(VGP_amd64_linux)
    VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
    vg_assert(canonical->what == SsComplete);
-   if (canonical->sres.isError) {
+   if (sr_isError(canonical->sres)) {
       /* 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->sres.err;
+      gst->guest_RAX = - (Long)sr_Err(canonical->sres);
    } else {
-      gst->guest_RAX = canonical->sres.res;
+      gst->guest_RAX = sr_Res(canonical->sres);
    }
 
 #  elif defined(VGP_ppc32_linux)
    VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
    UInt old_cr = LibVEX_GuestPPC32_get_CR(gst);
    vg_assert(canonical->what == SsComplete);
-   if (canonical->sres.isError) {
+   if (sr_isError(canonical->sres)) {
       /* set CR0.SO */
       LibVEX_GuestPPC32_put_CR( old_cr | (1<<28), gst );
-      gst->guest_GPR3 = canonical->sres.err;
+      gst->guest_GPR3 = sr_Err(canonical->sres);
    } else {
       /* clear CR0.SO */
       LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), gst );
-      gst->guest_GPR3 = canonical->sres.res;
+      gst->guest_GPR3 = sr_Res(canonical->sres);
    }
 
 #  elif defined(VGP_ppc64_linux)
    VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
    UInt old_cr = LibVEX_GuestPPC64_get_CR(gst);
    vg_assert(canonical->what == SsComplete);
-   if (canonical->sres.isError) {
+   if (sr_isError(canonical->sres)) {
       /* set CR0.SO */
       LibVEX_GuestPPC64_put_CR( old_cr | (1<<28), gst );
-      gst->guest_GPR3 = canonical->sres.err;
+      gst->guest_GPR3 = sr_Err(canonical->sres);
    } else {
       /* clear CR0.SO */
       LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), gst );
-      gst->guest_GPR3 = canonical->sres.res;
+      gst->guest_GPR3 = sr_Res(canonical->sres);
    }
 
 #  elif defined(VGP_ppc32_aix5)
@@ -601,8 +623,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->uu_arg7  = -1; /* impossible value */
+   layout->uu_arg8  = -1; /* impossible value */
    layout->o_retval = OFFSET_x86_EAX;
 
 #elif defined(VGP_amd64_linux)
@@ -613,8 +635,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->uu_arg7  = -1; /* impossible value */
+   layout->uu_arg8  = -1; /* impossible value */
    layout->o_retval = OFFSET_amd64_RAX;
 
 #elif defined(VGP_ppc32_linux)
@@ -625,8 +647,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->uu_arg7  = -1; /* impossible value */
+   layout->uu_arg8  = -1; /* impossible value */
    layout->o_retval = OFFSET_ppc32_GPR3;
 
 #elif defined(VGP_ppc64_linux)
@@ -637,8 +659,8 @@ 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->uu_arg7  = -1; /* impossible value */
+   layout->uu_arg8  = -1; /* impossible value */
    layout->o_retval = OFFSET_ppc64_GPR3;
 
 #elif defined(VGP_ppc32_aix5)
@@ -956,14 +978,15 @@ void VG_(client_syscall) ( ThreadId tid )
              || sci->status.what == SsComplete);
    vg_assert(sci->args.sysno == sci->orig_args.sysno);
 
-   if (sci->status.what == SsComplete && !sci->status.sres.isError) {
+   if (sci->status.what == SsComplete && !sr_isError(sci->status.sres)) {
       /* The pre-handler completed the syscall itself, declaring
          success. */
       if (sci->flags & SfNoWriteResult) {
          PRINT(" --> [pre-success] NoWriteResult\n");
       } else {
-         PRINT(" --> [pre-success] Success(0x%llx)\n",
-               (ULong)sci->status.sres.res );
+         PRINT(" --> [pre-success] Success(0x%llx:0x%llx)\n",
+               (ULong)sr_ResHI(sci->status.sres),
+               (ULong)sr_Res(sci->status.sres));
       }                                      
       /* 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
@@ -974,9 +997,9 @@ void VG_(client_syscall) ( ThreadId tid )
    }
 
    else
-   if (sci->status.what == SsComplete && sci->status.sres.isError) {
+   if (sci->status.what == SsComplete && sr_isError(sci->status.sres)) {
       /* The pre-handler decided to fail syscall itself. */
-      PRINT(" --> [pre-fail] Failure(0x%llx)\n", (ULong)sci->status.sres.err );
+      PRINT(" --> [pre-fail] Failure(0x%llx)\n", (ULong)sr_Err(sci->status.sres));
       /* 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. */
@@ -1020,8 +1043,12 @@ void VG_(client_syscall) ( ThreadId tid )
          vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
          putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex );
 
-         /* Drop the lock */
+         /* Drop the bigLock */
          VG_(release_BigLock)(tid, VgTs_WaitSys, "VG_(client_syscall)[async]");
+         /* Urr.  We're now in a race against other threads trying to
+            acquire the bigLock.  I guess that doesn't matter provided
+            that do_syscall_for_client only touches thread-local
+            state. */
 
          /* Do the call, which operates directly on the guest state,
             not on our abstracted copies of the args/result. */
@@ -1043,11 +1070,22 @@ void VG_(client_syscall) ( ThreadId tid )
          getSyscallStatusFromGuestState( &sci->status, &tst->arch.vex );
          vg_assert(sci->status.what == SsComplete);
 
-         PRINT("SYSCALL[%d,%d](%3ld) ... [async] --> %s(0x%llx)\n",
-               VG_(getpid)(), tid, sysno, 
-               sci->status.sres.isError ? "Failure" : "Success",
-               sci->status.sres.isError ? (ULong)sci->status.sres.err
-                                        : (ULong)sci->status.sres.res );
+         /* Be decorative, if required. */
+         if (VG_(clo_trace_syscalls)) {
+            Bool failed = sr_isError(sci->status.sres);
+            Word tmp_sysno = sysno;
+            if (failed) {
+               PRINT("SYSCALL[%d,%d](%5ld) ... [async] --> Failure(0x%llx)\n",
+                     VG_(getpid)(), tid, tmp_sysno, 
+                     (ULong)sr_Err(sci->status.sres));
+            } else {
+               PRINT("SYSCALL[%d,%d](%5ld) ... [async] --> "
+                     "Success(0x%llx:0x%llx)\n",
+                     VG_(getpid)(), tid, tmp_sysno, 
+                     (ULong)sr_ResHI(sci->status.sres),
+                     (ULong)sr_Res(sci->status.sres) );
+            }
+         }
 
       } else {
 
@@ -1064,10 +1102,18 @@ void VG_(client_syscall) ( ThreadId tid )
                                      sci->args.arg7, sci->args.arg8 );
          sci->status = convert_SysRes_to_SyscallStatus(sres);
 
-         PRINT("[sync] --> %s(0x%llx)\n",
-               sci->status.sres.isError ? "Failure" : "Success",
-               sci->status.sres.isError ? (ULong)sci->status.sres.err
-                                        : (ULong)sci->status.sres.res );
+         /* Be decorative, if required. */
+         if (VG_(clo_trace_syscalls)) {
+            Bool failed = sr_isError(sci->status.sres);
+            if (failed) {
+               PRINT("[sync] --> Failure(0x%llx)\n",
+                     (ULong)sr_Err(sci->status.sres) );
+            } else {
+               PRINT("[sync] --> Success(0x%llx:0x%llx)\n",
+                     (ULong)sr_ResHI(sci->status.sres),
+                     (ULong)sr_Res(sci->status.sres) );
+            }
+         }
       }
    }
 
@@ -1159,8 +1205,8 @@ void VG_(post_syscall) (ThreadId tid)
       - Success or (Failure and PostOnFail is set)
    */
    if (ent->after
-       && ((!sci->status.sres.isError)
-           || (sci->status.sres.isError
+       && ((!sr_isError(sci->status.sres))
+           || (sr_isError(sci->status.sres)
                && (sci->flags & SfPostOnFail) ))) {
 
       (ent->after)( tid, &sci->args, &sci->status );
@@ -1355,14 +1401,17 @@ void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
 void 
 VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid, 
                                                   Addr     ip, 
-                                                  UWord    sysnum, 
                                                   SysRes   sres,
                                                   Bool     restart)
 {
    /* Note that the sysnum arg seems to contain not-dependable-on info
       (I think it depends on the state the real syscall was in at
       interrupt) and so is ignored, apart from in the following
-      printf. */
+      printf.
+
+      Furthermore, 'sres' is only used in the case where the syscall
+      is complete, but the result has not been committed to the guest
+      state yet.  */
 
    static const Bool debug = False;
 
@@ -1372,14 +1421,13 @@ VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
    SyscallInfo*     sci;
 
    if (debug)
-      VG_(printf)( "interrupted_syscall %d: tid=%d, IP=0x%llx, "
+      VG_(printf)( "interrupted_syscall: tid=%d, IP=0x%llx, "
                    "restart=%s, sysret.isError=%s, sysret.val=%lld\n", 
-                   (Int)sysnum,
                    (Int)tid,
                    (ULong)ip, 
                    restart ? "True" : "False", 
-                   sres.isError ? "True" : "False",
-                   (Long)(Word)(sres.isError ? sres.err : sres.res) );
+                   sr_isError(sres) ? "True" : "False",
+                   (Long)(sr_isError(sres) ? sr_Err(sres) : sr_Res(sres)) );
 
    vg_assert(VG_(is_valid_tid)(tid));
    vg_assert(tid >= 1 && tid < VG_N_THREADS);
index 60c2886fad9ca1328df474e684955f427a36e7a1..c2bd8e41bf4cffffef2b1d02e7993fcfb49de274 100644 (file)
@@ -349,7 +349,7 @@ static SysRes do_clone ( ThreadId ptid,
    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
 
   out:
-   if (res.isError) {
+   if (sr_isError(res)) {
       /* clone failed */
       VG_(cleanup_thread)(&ctst->arch);
       ctst->status = VgTs_Empty;
@@ -1379,8 +1379,8 @@ void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
 }
 PRE(sys_sigaction)
 {
-   struct vki_sigaction new, old;
-   struct vki_sigaction *newp, *oldp;
+   vki_sigaction_toK_t   new, *newp;
+   vki_sigaction_fromK_t old, *oldp;
 
    PRINT("sys_sigaction ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
    PRE_REG_READ3(int, "sigaction",
index 2ee91e4eb7c7c172d2af420e0b16c57ffd1c8932..dc82f4ac107d3b3c2b2f77e0ac7dae3e48232d72 100644 (file)
@@ -379,7 +379,7 @@ static SysRes do_clone ( ThreadId ptid,
    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
 
   out:
-   if (res.isError) {
+   if (sr_isError(res)) {
       /* clone failed */
       VG_(cleanup_thread)(&ctst->arch);
       ctst->status = VgTs_Empty;
index 6207a5475607244ae87ecab6f281674805bafe4f..d72892ba5d371b9e573e77f98f46cdc6caac5900 100644 (file)
@@ -299,7 +299,7 @@ static SysRes do_clone ( ThreadId ptid,
                     ptst->arch.vex.guest_ESP,
                     ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
       res = sys_set_thread_area(ctid, tlsinfo);
-      if (res.isError)
+      if (sr_isError(res))
         goto out;
    }
 
@@ -318,7 +318,7 @@ static SysRes do_clone ( ThreadId ptid,
    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
 
   out:
-   if (res.isError) {
+   if (sr_isError(res)) {
       /* clone failed */
       VG_(cleanup_thread)(&ctst->arch);
       ctst->status = VgTs_Empty;
@@ -1680,8 +1680,8 @@ void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
 }
 PRE(sys_sigaction)
 {
-   struct vki_sigaction new, old;
-   struct vki_sigaction *newp, *oldp;
+   vki_sigaction_toK_t   new, *newp;
+   vki_sigaction_fromK_t old, *oldp;
 
    PRINT("sys_sigaction ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
    PRE_REG_READ3(int, "sigaction",
@@ -1711,9 +1711,8 @@ PRE(sys_sigaction)
 
    if (ARG2 != 0) {
       struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
-
       new.ksa_handler = oldnew->ksa_handler;
-      new.sa_flags = oldnew->sa_flags;
+      new.sa_flags    = oldnew->sa_flags;
       new.sa_restorer = oldnew->sa_restorer;
       convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
       newp = &new;
@@ -1723,9 +1722,8 @@ PRE(sys_sigaction)
 
    if (ARG3 != 0 && SUCCESS && RES == 0) {
       struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
-
       oldold->ksa_handler = oldp->ksa_handler;
-      oldold->sa_flags = oldp->sa_flags;
+      oldold->sa_flags    = oldp->sa_flags;
       oldold->sa_restorer = oldp->sa_restorer;
       oldold->sa_mask = oldp->sa_mask.sig[0];
    }
index 956e2991b99930a5d72e1ffc9e457184ad925306..a224b48760e696938d4f24b5f05e1b4ec0dabc64 100644 (file)
@@ -714,21 +714,21 @@ static void initialiseSector ( Int sno )
       VG_(debugLog)(1,"transtab", "allocate sector %d\n", sno);
 
       sres = VG_(am_mmap_anon_float_valgrind)( 8 * tc_sector_szQ );
-      if (sres.isError) {
+      if (sr_isError(sres)) {
          VG_(out_of_memory_NORETURN)("initialiseSector(TC)", 
                                      8 * tc_sector_szQ );
         /*NOTREACHED*/
       }
-      sec->tc = (ULong*)sres.res;
+      sec->tc = (ULong*)(AddrH)sr_Res(sres);
 
       sres = VG_(am_mmap_anon_float_valgrind)
                 ( N_TTES_PER_SECTOR * sizeof(TTEntry) );
-      if (sres.isError) {
+      if (sr_isError(sres)) {
          VG_(out_of_memory_NORETURN)("initialiseSector(TT)", 
                                      N_TTES_PER_SECTOR * sizeof(TTEntry) );
         /*NOTREACHED*/
       }
-      sec->tt = (TTEntry*)sres.res;
+      sec->tt = (TTEntry*)(AddrH)sr_Res(sres);
 
       for (i = 0; i < N_TTES_PER_SECTOR; i++) {
          sec->tt[i].status   = Empty;
@@ -1313,12 +1313,14 @@ static void init_unredir_tt_tc ( void )
 {
    Int i;
    if (unredir_tc == NULL) {
-      SysRes sres = VG_(am_mmap_anon_float_valgrind)( N_UNREDIR_TT * UNREDIR_SZB );
-      if (sres.isError) {
-         VG_(out_of_memory_NORETURN)("init_unredir_tt_tc", N_UNREDIR_TT * UNREDIR_SZB);
+      SysRes sres = VG_(am_mmap_anon_float_valgrind)
+                       ( N_UNREDIR_TT * UNREDIR_SZB );
+      if (sr_isError(sres)) {
+         VG_(out_of_memory_NORETURN)("init_unredir_tt_tc",
+                                     N_UNREDIR_TT * UNREDIR_SZB);
          /*NOTREACHED*/
       }
-      unredir_tc = (ULong *)sres.res;
+      unredir_tc = (ULong *)(AddrH)sr_Res(sres);
    }
    unredir_tc_used = 0;
    for (i = 0; i < N_UNREDIR_TT; i++)
index b3edc2072692e74865e930e4d948b9c6ac912302..f7719605cfd13d9cd6e18549c803023c761d695f 100644 (file)
@@ -72,12 +72,12 @@ struct elfinfo
 
 static void check_mmap(SysRes res, Addr base, SizeT len)
 {
-   if (res.isError) {
+   if (sr_isError(res)) {
       VG_(printf)("valgrind: mmap(0x%llx, %lld) failed in UME "
                   "with error %lu (%s).\n", 
                   (ULong)base, (Long)len, 
-                  res.err, VG_(strerror)(res.err) );
-      if (res.err == VKI_EINVAL) {
+                  sr_Err(res), VG_(strerror)(sr_Err(res)) );
+      if (sr_Err(res) == VKI_EINVAL) {
          VG_(printf)("valgrind: this can be caused by executables with "
                      "very large text, data or bss segments.\n");
       }
@@ -100,9 +100,9 @@ struct elfinfo *readelf(Int fd, const char *filename)
    e->fd = fd;
 
    sres = VG_(pread)(fd, &e->e, sizeof(e->e), 0);
-   if (sres.isError || sres.res != sizeof(e->e)) {
+   if (sr_isError(sres) || sr_Res(sres) != sizeof(e->e)) {
       VG_(printf)("valgrind: %s: can't read ELF header: %s\n", 
-                  filename, VG_(strerror)(sres.err));
+                  filename, VG_(strerror)(sr_Err(sres)));
       goto bad;
    }
 
@@ -140,9 +140,9 @@ struct elfinfo *readelf(Int fd, const char *filename)
    vg_assert(e->p);
 
    sres = VG_(pread)(fd, e->p, phsz, e->e.e_phoff);
-   if (sres.isError || sres.res != phsz) {
+   if (sr_isError(sres) || sr_Res(sres) != phsz) {
       VG_(printf)("valgrind: can't read phdr: %s\n", 
-                  VG_(strerror)(sres.err));
+                  VG_(strerror)(sr_Err(sres)));
       VG_(free)(e->p);
       goto bad;
    }
@@ -373,11 +373,11 @@ Int VG_(load_ELF)(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
          buf[ph->p_filesz] = '\0';
 
          sres = VG_(open)(buf, VKI_O_RDONLY, 0);
-         if (sres.isError) {
+         if (sr_isError(sres)) {
             VG_(printf)("valgrind: m_ume.c: can't open interpreter\n");
             VG_(exit)(1);
          }
-         intfd = sres.res;
+         intfd = sr_Res(sres);
 
          interp = readelf(intfd, buf);
          if (interp == NULL) {
index 786e176b177b921097c8af2db35a63756ef00c34..b2fb502a9ebc26c34d3687d84b09301cb8892a6b 100644 (file)
@@ -52,12 +52,12 @@ typedef struct {
 } ExeHandler;
 
 static ExeHandler exe_handlers[] = {
-#if defined(HAVE_ELF)
+#  if defined(HAVE_ELF)
    { "ELF",    VG_(match_ELF),    VG_(load_ELF) },
-#endif
-#if defined(HAVE_SCRIPT)
+#  endif
+#  if defined(HAVE_SCRIPT)
    { "script", VG_(match_script), VG_(load_script) },
-#endif
+#  endif
 };
 #define EXE_HANDLER_COUNT (sizeof(exe_handlers)/sizeof(exe_handlers[0]))
 
@@ -74,10 +74,10 @@ VG_(pre_exec_check)(const HChar* exe_name, Int* out_fd, Bool allow_setuid)
 
    // Check it's readable
    res = VG_(open)(exe_name, VKI_O_RDONLY, 0);
-   if (res.isError) {
+   if (sr_isError(res)) {
       return res;
    }
-   fd = res.res;
+   fd = sr_Res(res);
 
    // Check we have execute permissions
    ret = VG_(check_executable)(&is_setuid, (HChar*)exe_name, allow_setuid);
@@ -100,11 +100,11 @@ VG_(pre_exec_check)(const HChar* exe_name, Int* out_fd, Bool allow_setuid)
       bufsz = fsz;
 
    res = VG_(pread)(fd, buf, bufsz, 0);
-   if (res.isError || res.res != bufsz) {
+   if (sr_isError(res) || sr_Res(res) != bufsz) {
       VG_(close)(fd);
       return VG_(mk_SysRes_Error)(VKI_EACCES);
    }
-   bufsz = res.res;
+   bufsz = sr_Res(res);
 
    // Look for a matching executable format
    for (i = 0; i < EXE_HANDLER_COUNT; i++) {
@@ -119,7 +119,7 @@ VG_(pre_exec_check)(const HChar* exe_name, Int* out_fd, Bool allow_setuid)
    }
 
    // Write the 'out_fd' param if necessary, or close the file.
-   if (!res.isError && out_fd) {
+   if (!sr_isError(res) && out_fd) {
       *out_fd = fd; 
    } else { 
       VG_(close)(fd);
@@ -140,13 +140,13 @@ Int VG_(do_exec_inner)(const HChar* exe, ExeInfo* info)
    Int ret;
 
    res = VG_(pre_exec_check)(exe, &fd, False/*allow_setuid*/);
-   if (res.isError)
-      return res.err;
+   if (sr_isError(res))
+      return sr_Err(res);
 
-   vg_assert2(res.res >= 0 && res.res < EXE_HANDLER_COUNT, 
+   vg_assert2(sr_Res(res) >= 0 && sr_Res(res) < EXE_HANDLER_COUNT, 
               "invalid VG_(pre_exec_check) result");
 
-   ret = (*exe_handlers[res.res].load_fn)(fd, exe, info);
+   ret = (*exe_handlers[sr_Res(res)].load_fn)(fd, exe, info);
 
    VG_(close)(fd);
 
@@ -157,9 +157,9 @@ Int VG_(do_exec_inner)(const HChar* exe, ExeInfo* info)
 static Bool is_hash_bang_file(Char* f)
 {
    SysRes res = VG_(open)(f, VKI_O_RDONLY, 0);
-   if (!res.isError) {
+   if (!sr_isError(res)) {
       Char buf[3] = {0,0,0};
-      Int fd = res.res;
+      Int fd = sr_Res(res);
       Int n  = VG_(read)(fd, buf, 2); 
       if (n == 2 && VG_STREQ("#!", buf))
          return True;
@@ -173,9 +173,9 @@ static Bool is_hash_bang_file(Char* f)
 static Bool is_binary_file(Char* f)
 {
    SysRes res = VG_(open)(f, VKI_O_RDONLY, 0);
-   if (!res.isError) {
+   if (!sr_isError(res)) {
       UChar buf[80];
-      Int fd = res.res;
+      Int fd = sr_Res(res);
       Int n  = VG_(read)(fd, buf, 80); 
       Int i;
       for (i = 0; i < n; i++) {
@@ -235,7 +235,7 @@ static Int do_exec_shell_followup(Int ret, HChar* exe_name, ExeInfo* info)
    
       // Was it a directory?
       res = VG_(stat)(exe_name, &st);
-      if (!res.isError && VKI_S_ISDIR(st.st_mode)) {
+      if (!sr_isError(res) && VKI_S_ISDIR(st.st_mode)) {
          VG_(printf)("valgrind: %s: is a directory\n", exe_name);
       
       // Was it not executable?
index 8df563e569988cb6d3cdc1e7acc3d906f733c780..9b875c9ac539a9f514ee05a45745df726b23a1d8 100644 (file)
@@ -90,11 +90,11 @@ Int VG_(load_script)(Int fd, const HChar* name, ExeInfo* info)
 
    // Read the first part of the file.
    res = VG_(pread)(fd, hdr, len, 0);
-   if (res.isError) {
+   if (sr_isError(res)) {
       VG_(close)(fd);
       return VKI_EACCES;
    } else {
-      len = res.res;
+      len = sr_Res(res);
    }
 
    vg_assert('#' == hdr[0] && '!' == hdr[1]);
index 6d0631c08d44a9decbcb96dbf6b0246961bd9d79..25beafbf62520e200c43de9abcd3fc68b2e1a8ad 100644 (file)
@@ -30,6 +30,7 @@
 */
 
 #include "pub_core_basics.h"
+#include "pub_core_libcassert.h"
 #include "pub_core_vki.h"     /* self */
 
 /* We have pub_{core,tool}_vki.h.  This is the matching implementation
@@ -47,6 +48,52 @@ unsigned long VKI_PAGE_SIZE  = 1UL << 12;
 #endif
 
 
+/* Do initial consistency checks on some of the definitions to do with
+   signals (vki_sigset_t and vki_sigaction_{toK,fromK}_t).  This stuff
+   is fragile enough that it's important to check at startup that
+   the world looks like what we expect it to look like. 
+
+   The most important thing is to check that the definition of signal
+   sets for this platform is right.  A signal set consists of some
+   number _VKI_NSIG_WORDS of 32- or 64-bit words.  Because the kernel
+   itself has some indexing scheme to set/clear individual bits in the
+   set, we must make sure we use the same layout/scheme: where this
+   requirement bites us is in the VG_(sigfillset) etc functions in
+   m_libcsignal.c.  So we check carefully here that it's all sensible.
+*/
+void VG_(vki_do_initial_consistency_checks) ( void )
+{
+   /* --- Platform-independent checks on signal sets --- */
+
+   vki_sigset_t set;
+   // Set's size must agree with _VKI_NSIG
+   vg_assert( 8 * sizeof(set) == _VKI_NSIG );
+   // Set's word size must agree with _VKI_NSIG_BPW
+   vg_assert( 8 * sizeof(set.sig[0]) == _VKI_NSIG_BPW );
+   // The set elements are 32- or 64-bit
+   vg_assert( _VKI_NSIG_BPW == 32 || _VKI_NSIG_BPW == 64 );
+
+   /* --- Platform-specific checks on signal sets --- */
+
+#  if defined(VGO_linux) || defined(VGO_aix5)
+   /* nothing to check */
+#  else
+#    error "Unknown plat"
+#  endif
+
+   /* --- Platform-specific checks on sigactions --- */
+
+#  if defined(VGO_linux) || defined(VGO_aix5)
+   /* the toK- and fromK- forms are identical */
+   vg_assert( sizeof(vki_sigaction_toK_t) 
+              == sizeof(vki_sigaction_fromK_t) );
+
+#  else
+#     error "Unknown OS" 
+#  endif
+}
+
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                  m_vki.c ---*/
 /*--------------------------------------------------------------------*/
index 310a5d70e6c75baeccc55bc91f4b62027c23d372..4ff074f821ca69f5481028be7ca2d660c4e2a785 100644 (file)
@@ -74,6 +74,9 @@ extern Int VG_(access) ( HChar* path, Bool irusr, Bool iwusr, Bool ixusr );
 extern Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
                                  HChar* f, Bool allow_setuid);
 
+/* Note this moves (or at least, is believed to move) the file pointer
+   on Linux and AIX5 but doesn't on Darwin.  This inconsistency should
+   be fixed. */
 extern SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset );
 
 /* Create and open (-rw------) a tmp file name incorporating said arg.
index 9e8ebe713cece2e2d890043aed5ee923f6497ea4..c323fc0afd857a4036f91567a0a9f26b0b6bf131 100644 (file)
@@ -57,13 +57,23 @@ extern Int  VG_(sigismember) ( const vki_sigset_t* set, Int signum );
 
 extern void VG_(sigaddset_from_set) ( vki_sigset_t* dst, vki_sigset_t* src );
 extern void VG_(sigdelset_from_set) ( vki_sigset_t* dst, vki_sigset_t* src );
+extern void VG_(sigintersectset)    ( vki_sigset_t* dst, vki_sigset_t* src );
+extern void VG_(sigcomplementset)   ( vki_sigset_t* dst, vki_sigset_t* src );
 
 /* --- Mess with the kernel's sig state --- */
 /* VG_(sigprocmask) is in pub_tool_libcsignal.h. */
 
 extern Int VG_(sigaction)   ( Int signum,
-                              const struct vki_sigaction* act,
-                              struct vki_sigaction* oldact );
+                              const vki_sigaction_toK_t* act,
+                              vki_sigaction_fromK_t* oldact );
+
+/* Convert a sigaction which you got from the kernel (a _fromK_t) to
+   one which you can give back to the kernel (a _toK_t).  On Linux and
+   AIX, vki_sigaction_{toK,fromK}_t are identical, so this is a no-op
+   (structure copy), but on Darwin it's not a no-op. */
+extern void VG_(convert_sigaction_fromK_to_toK)(
+               vki_sigaction_fromK_t*, /*OUT*/vki_sigaction_toK_t*);
+
 
 extern Int VG_(kill)        ( Int pid, Int signo );
 extern Int VG_(tkill)       ( ThreadId tid, Int signo );
index 5da26dcc8fcea7f791054f662013755ecb57cfca..9a26c547eb518a634ffb7106d096d7744b72bce8 100644 (file)
@@ -91,6 +91,7 @@
 
 // Offsets for the Vex state
 #define VG_O_STACK_PTR        (offsetof(VexGuestArchState, VG_STACK_PTR))
+#define VG_O_INSTR_PTR        (offsetof(VexGuestArchState, VG_INSTR_PTR))
 
 
 //-------------------------------------------------------------
index 9d174ae07920acec2f6778ef663a1f188b59c7f3..6d6f68364c9ec694c3122d528e3f15eff52d5614 100644 (file)
@@ -54,8 +54,8 @@ extern void VG_(poll_signals) ( ThreadId );
 extern SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss,
                                                       vki_stack_t* oss );
 extern SysRes VG_(do_sys_sigaction)   ( Int signo, 
-                                        const struct vki_sigaction *new_act, 
-                                        struct vki_sigaction *old_act );
+                                        const vki_sigaction_toK_t* new_act, 
+                                        vki_sigaction_fromK_t* old_act );
 extern SysRes VG_(do_sys_sigprocmask) ( ThreadId tid, Int how, 
                                         vki_sigset_t* set,
                                         vki_sigset_t* oldset );
index 995475409174a74c43029ced0ced2990d8a71b64..7cabdcb65df99c63c68805bad4183ec0ff5e89f2 100644 (file)
@@ -65,8 +65,8 @@ extern SysRes VG_(do_syscall) ( UWord sysno,
 #define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),(c),\
                                                            (d),(e),(f),0,0)
 
-extern SysRes VG_(mk_SysRes_x86_linux)   ( UInt  val );
-extern SysRes VG_(mk_SysRes_amd64_linux) ( ULong val );
+extern SysRes VG_(mk_SysRes_x86_linux)   ( Int  val );
+extern SysRes VG_(mk_SysRes_amd64_linux) ( Long val );
 extern SysRes VG_(mk_SysRes_ppc32_linux) ( UInt  val, UInt  cr0so );
 extern SysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong cr0so );
 extern SysRes VG_(mk_SysRes_ppc32_aix5)  ( UInt val, UInt err );
@@ -75,6 +75,7 @@ extern SysRes VG_(mk_SysRes_Error)       ( UWord val );
 extern SysRes VG_(mk_SysRes_Success)     ( UWord val );
 
 
+
 /* Return a string which gives the name of an error value.  Note,
    unlike the standard C syserror fn, the returned string is not
    malloc-allocated or writable -- treat it as a constant. */
index 57bfa074f1d951333d3d72604a6b240535659025..89f0d8cbb2d067a0765d4f914b6eed3c22d5d78c 100644 (file)
@@ -51,7 +51,6 @@ extern void VG_(clear_syscallInfo) ( Int tid );
 extern void VG_(fixup_guest_state_after_syscall_interrupted)(
                ThreadId tid,
                Addr     ip, 
-               UWord    sysnum,
                SysRes   sysret,
                Bool     restart
             );
index 630e52b812816dc35bb532bada5af8dcea9bb8e7..cbda7ab5715ae52c2073e7b3daf2d53e81bb692f 100644 (file)
@@ -111,7 +111,7 @@ extern void VG_(ppctoc_magic_redirect_return_stub);
 /* See comment for ppc32_aix5 equivalent above. */
 extern void VG_(ppc64_aix5_do_preloads_then_start_client);
 #endif
+
 #endif   // __PUB_CORE_TRAMPOLINE_H
 
 /*--------------------------------------------------------------------*/
index e01df8bccedccdfca79dc0e3ef9574cd540ea0a9..c5afeb01fd8742d9a163eb9afaf92076b76aeb16 100644 (file)
 
 #include "pub_tool_vki.h"
 
+/* Do initial consistency checks on some of the definitions to do with
+   signals (vki_sigset_t and vki_sigaction_{toK,fromK}_t).  This stuff
+   is fragile enough that it's important to check at startup that
+   the world looks like what we expect it to look like. */
+void VG_(vki_do_initial_consistency_checks)(void);
+
 #endif // __PUB_CORE_VKI_H
 
 /*--------------------------------------------------------------------*/
index c452e7e95b401580adfa976b9ad454b62fb9ab5d..50f4154cd5147a613a39b8b673783f2b3b9ffa7e 100644 (file)
@@ -2549,7 +2549,7 @@ void h_post_syscall ( ThreadId tid, UInt sysno, SysRes res )
        || (sysno == __NR_AIX5_kload && __NR_AIX5_kload != __NR_AIX5_UNKNOWN)
 #      endif
       ) {
-      if (res.isError) {
+      if (sr_isError(res)) {
          // mmap() had an error, return value is a small negative integer
          VG_(set_syscall_return_shadows)( tid, /*val*/ (UWord)NONPTR, 0,
                                                /*err*/ (UWord)NONPTR, 0 );
@@ -2566,7 +2566,7 @@ void h_post_syscall ( ThreadId tid, UInt sysno, SysRes res )
    // notification via new_mem_mmap.  Just set the return value shadow.
 #  if defined(__NR_shmat)
    if (sysno == __NR_shmat) {
-      if (res.isError) {
+      if (sr_isError(res)) {
          VG_(set_syscall_return_shadows)( tid, /*val*/ (UWord)NONPTR, 0,
                                                /*err*/ (UWord)NONPTR, 0 );
          if (0) VG_(printf)("ZZZZZZZ shmat res -> NONPTR\n");
index 9bff837fcbbbea7f83106bb40054b572929193c9..89d66f5a6132e1f6ee39fe290bdc9685d39bb415 100644 (file)
@@ -135,32 +135,88 @@ typedef UInt ThreadId;
 
 /* An abstraction of syscall return values.
    Linux:
-      When .isError == False, 
-         res holds the return value, and err is zero.
-      When .isError == True,  
-         err holds the error code, and res is zero.
+      When _isError == False, 
+         _val holds the return value.
+      When _isError == True,  
+         _err holds the error code.
 
    AIX:
-      res is the POSIX result of the syscall.
-      err is the corresponding errno value.
-      isError === err==0
+      _res is the POSIX result of the syscall.
+      _err is the corresponding errno value.
+      _isError === _err==0
 
-      Unlike on Linux, it is possible for 'err' to be nonzero (thus an
-      error has occurred), nevertheless 'res' is also nonzero.  AIX
-      userspace does not appear to consistently inspect 'err' to
+      Unlike on Linux, it is possible for _err to be nonzero (thus an
+      error has occurred), nevertheless _res is also nonzero.  AIX
+      userspace does not appear to consistently inspect _err to
       determine whether or not an error has occurred.  For example,
-      sys_open() will return -1 for 'val' if a file cannot be opened,
-      as well as the relevant errno value in 'err', but AIX userspace
-      then consults 'val' to figure out if the syscall failed, rather
-      than looking at 'err'.  Hence we need to represent them both.
+      sys_open() will return -1 for _val if a file cannot be opened,
+      as well as the relevant errno value in _err, but AIX userspace
+      then consults _val to figure out if the syscall failed, rather
+      than looking at _err.  Hence we need to represent them both.
+
+   Darwin:
+      Interpretation depends on _mode:
+      MACH, MDEP:
+         these can never 'fail' (apparently).  The result of the
+         syscall is a single host word, _wLO.
+      UNIX:
+         Can record a double-word error or a double-word result:
+         When _mode is SysRes_UNIX_OK,  _wHI:_wLO holds the result.
+         When _mode is SysRes_UNIX_ERR, _wHI:_wLO holds the error code.
+         Probably the high word of an error is always ignored by
+         userspace, but we have to record it, so that we can correctly
+         update both EDX and EAX (in guest state) given a SysRes, if
+         we're required to.
 */
+#if defined(VGO_linux)
 typedef
    struct {
-      UWord res;
-      UWord err;
-      Bool  isError;
+      UWord _val;
+      Bool  _isError;
    }
    SysRes;
+#elif defined(VGO_aix5)
+typedef
+   struct {
+      UWord _res;
+      UWord _err;
+      Bool  _isError;
+   }
+   SysRes;
+#else
+#  error "Unknown OS"
+#endif
+
+
+/* ---- And now some basic accessor functions for it. ---- */
+
+#if defined(VGO_linux)
+
+static inline Bool sr_isError ( SysRes sr ) {
+   return sr._isError;
+}
+static inline UWord sr_Res ( SysRes sr ) {
+   return sr._isError ? 0 : sr._val;
+}
+static inline UWord sr_ResHI ( SysRes sr ) {
+   return 0;
+}
+static inline UWord sr_Err ( SysRes sr ) {
+   return sr._isError ? sr._val : 0;
+}
+static inline Bool sr_EQ ( SysRes sr1, SysRes sr2 ) {
+   return sr1._val == sr2._val 
+          && ((sr1._isError && sr2._isError) 
+              || (!sr1._isError && !sr2._isError));
+}
+
+#elif defined(VGO_aix5)
+#  error "need to define SysRes accessors on AIX5 (copy from 3.4.1 sources)"
+
+
+#else
+#  error "Unknown OS"
+#endif
 
 
 /* ---------------------------------------------------------------------
index f870109f3ff34d347420c158334094c4df49b326..63fb0b39a5df7508b9f96c72400dd7fa67414bfa 100644 (file)
@@ -70,7 +70,7 @@ extern Int    VG_(write)  ( Int fd, const void* buf, Int count);
 extern Int    VG_(pipe)   ( Int fd[2] );
 extern OffT   VG_(lseek)  ( Int fd, OffT offset, Int whence );
 
-extern SysRes VG_(stat)   ( Char* file_name, struct vg_stat* buf );
+extern SysRes VG_(stat)   ( const Char* file_name, struct vg_stat* buf );
 extern Int    VG_(fstat)  ( Int   fd,        struct vg_stat* buf );
 extern SysRes VG_(dup)    ( Int oldfd );
 extern SysRes VG_(dup2)   ( Int oldfd, Int newfd );
@@ -78,7 +78,7 @@ extern Int    VG_(rename) ( Char* old_name, Char* new_name );
 extern Int    VG_(unlink) ( Char* file_name );
 
 extern Int    VG_(readlink)( Char* path, Char* buf, UInt bufsize );
-extern Int    VG_(getdents)( UInt fd, struct vki_dirent *dirp, UInt count );
+extern Int    VG_(getdents)( Int fd, struct vki_dirent *dirp, UInt count );
 
 /* Copy the working directory at startup into buf[0 .. size-1], or return
    False if buf is too small. */
index 50e7dcbc3ecf63a32bbdb6a644957945596a7aa7..bc5c4551215623df8df327afd51d4cc2223ade2b 100644 (file)
@@ -143,7 +143,7 @@ typedef __vki_restorefn_t __user *__vki_sigrestore_t;
 #define VKI_SIG_DFL    ((__vki_sighandler_t)0) /* default signal handling */
 #define VKI_SIG_IGN    ((__vki_sighandler_t)1) /* ignore signal */
 
-struct vki_sigaction {
+struct vki_sigaction_base {
         // [[Nb: a 'k' prefix is added to "sa_handler" because
         // bits/sigaction.h (which gets dragged in somehow via signal.h)
         // #defines it as something else.  Since that is done for glibc's
@@ -154,6 +154,12 @@ struct vki_sigaction {
        vki_sigset_t sa_mask;           /* mask last for extensibility */
 };
 
+/* On Linux we use the same type for passing sigactions to
+   and from the kernel.  Hence: */
+typedef  struct vki_sigaction_base  vki_sigaction_toK_t;
+typedef  struct vki_sigaction_base  vki_sigaction_fromK_t;
+
+
 typedef struct vki_sigaltstack {
        void __user *ss_sp;
        int ss_flags;
index 074a8f84ec8d9d7a5cb84b220c93bb4ceac867b7..69932c04cab43ea7e03f2cecbeb941666e6f3d3a 100644 (file)
@@ -154,6 +154,10 @@ typedef struct {
 #define VKI_SS_ONSTACK         1
 #define VKI_SS_DISABLE         2
 
+/* These are 'legacy' sigactions in which the size of sa_mask is fixed
+   (cannot be expanded at any future point) because it is sandwiched
+   between two other fields.
+   (there is identical kludgery in vki-x86-linux.h) */
 struct vki_old_sigaction {
         // [[Nb: a 'k' prefix is added to "sa_handler" because
         // bits/sigaction.h (which gets dragged in somehow via signal.h)
@@ -165,7 +169,7 @@ struct vki_old_sigaction {
         __vki_sigrestore_t sa_restorer;
 };
 
-struct vki_sigaction {
+struct vki_sigaction_base {
         // [[See comment about extra 'k' above]]
        __vki_sighandler_t ksa_handler;
        unsigned long sa_flags;
@@ -173,6 +177,12 @@ struct vki_sigaction {
        vki_sigset_t sa_mask;           /* mask last for extensibility */
 };
 
+/* On Linux we use the same type for passing sigactions to
+   and from the kernel.  Hence: */
+typedef  struct vki_sigaction_base  vki_sigaction_toK_t;
+typedef  struct vki_sigaction_base  vki_sigaction_fromK_t;
+
+
 typedef struct vki_sigaltstack {
        void __user *ss_sp;
        int ss_flags;
index 063fc55a47878e4bdd7958f8e01523bd732b557f..610a16361708bd0f3ad065e89f3480c09cdc9f16 100644 (file)
@@ -164,13 +164,19 @@ struct vki_old_sigaction {
   __vki_sigrestore_t sa_restorer;
 };
 
-struct vki_sigaction {
+struct vki_sigaction_base {
   __vki_sighandler_t ksa_handler;
   unsigned long sa_flags;
   __vki_sigrestore_t sa_restorer;
   vki_sigset_t sa_mask;               /* mask last for extensibility */
 };
 
+/* On Linux we use the same type for passing sigactions to
+   and from the kernel.  Hence: */
+typedef  struct vki_sigaction_base  vki_sigaction_toK_t;
+typedef  struct vki_sigaction_base  vki_sigaction_fromK_t;
+
+
 typedef struct vki_sigaltstack {
   void __user *ss_sp;
   int ss_flags;
index 13a4e4e9682de86040ab6283cbfa28e6fb9bb4c9..08aed502f6fee44f1150c9239a0630497355a9df 100644 (file)
@@ -149,6 +149,10 @@ typedef struct {
 #define VKI_SS_ONSTACK 1
 #define VKI_SS_DISABLE 2
 
+/* These are 'legacy' sigactions in which the size of sa_mask is fixed
+   (cannot be expanded at any future point) because it is sandwiched
+   between two other fields.
+   (there is identical kludgery in vki-ppc32-linux.h) */
 struct vki_old_sigaction {
         // [[Nb: a 'k' prefix is added to "sa_handler" because
         // bits/sigaction.h (which gets dragged in somehow via signal.h)
@@ -160,7 +164,7 @@ struct vki_old_sigaction {
         __vki_sigrestore_t sa_restorer;
 };
 
-struct vki_sigaction {
+struct vki_sigaction_base {
         // [[See comment about extra 'k' above]]
        __vki_sighandler_t ksa_handler;
        unsigned long sa_flags;
@@ -168,6 +172,12 @@ struct vki_sigaction {
        vki_sigset_t sa_mask;           /* mask last for extensibility */
 };
 
+/* On Linux we use the same type for passing sigactions to
+   and from the kernel.  Hence: */
+typedef  struct vki_sigaction_base  vki_sigaction_toK_t;
+typedef  struct vki_sigaction_base  vki_sigaction_fromK_t;
+
+
 typedef struct vki_sigaltstack {
        void __user *ss_sp;
        int ss_flags;
index 7cd2603f4a85a4e381ae210426d75ebaf90b344f..f2e84e776fbb9dddaa8249874766d4989785f5c4 100644 (file)
@@ -2141,7 +2141,7 @@ static void write_snapshots_to_file(void)
 
    sres = VG_(open)(massif_out_file, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY,
                                      VKI_S_IRUSR|VKI_S_IWUSR);
-   if (sres.isError) {
+   if (sr_isError(sres)) {
       // If the file can't be opened for whatever reason (conflict
       // between multiple cachegrinded processes?), give up now.
       VG_UMSG("error: can't open output file '%s'", massif_out_file );
@@ -2149,7 +2149,7 @@ static void write_snapshots_to_file(void)
       VG_(free)(massif_out_file);
       return;
    } else {
-      fd = sres.res;
+      fd = sr_Res(sres);
       VG_(free)(massif_out_file);
    }
 
index fab5d2865fdb587fa787d5b5a29647c3e6f38d67..0aef0806ea768b31a6d000864898605bf79abf50 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "pub_tool_basics.h"  /* UInt et al, needed for pub_tool_vki.h */
 #include "pub_tool_vki.h"
 #include "m_libcbase.c"