# elif defined(VGA_mips32) || defined(VGA_mips64)
SysRes sres = VG_(do_syscall3)(__NR_cacheflush, (UWord) ptr,
(UWord) nbytes, (UWord) 3);
- vg_assert( sres._isError == 0 );
+ vg_assert( !sr_isError(sres) );
# elif defined(VGA_tilegx)
const HChar *start, *end;
sres = VG_(do_syscall3)(__NR_futex, (UWord)futex,
VKI_FUTEX_WAIT | VKI_FUTEX_PRIVATE_FLAG,
futex_value);
- if (sr_isError(sres) && sres._val != VKI_EAGAIN) {
- VG_(printf)("futex_wait() returned error code %ld\n", sres._val);
+ if (sr_isError(sres) && sr_Err(sres) != VKI_EAGAIN) {
+ VG_(printf)("futex_wait() returned error code %ld\n", sr_Err(sres));
vg_assert(False);
}
}
Building syscall return values.
------------------------------------------------------------------ */
-#if defined(VGO_linux)
-
/* Make a SysRes value from a syscall return value. This is
- Linux-specific.
+ platform specific. */
+
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+SysRes VG_(mk_SysRes_mips32_linux) ( UWord v0, UWord v1, UWord a3 ) {
+ /* MIPS uses a3 != 0 to flag an error */
+ SysRes res;
+ res._isError = (a3 != (UWord)0);
+ res._val = v0;
+ res._valEx = v1;
+ return res;
+}
+
+SysRes VG_(mk_SysRes_mips64_linux) ( ULong v0, ULong v1, ULong a3 ) {
+ /* MIPS uses a3 != 0 to flag an error */
+ SysRes res;
+ res._isError = (a3 != (ULong)0);
+ res._val = v0;
+ res._valEx = v1;
+ return res;
+}
+
+/* Generic constructors. */
+SysRes VG_(mk_SysRes_Error) ( UWord err ) {
+ SysRes r;
+ r._isError = True;
+ r._val = err;
+ r._valEx = 0;
+ return r;
+}
+
+SysRes VG_(mk_SysRes_Success) ( UWord res ) {
+ SysRes r;
+ r._isError = False;
+ r._val = res;
+ r._valEx = 0;
+ return r;
+}
+
+SysRes VG_(mk_SysRes_SuccessEx) ( UWord res, UWord resEx ) {
+ SysRes r;
+ r._isError = False;
+ r._val = res;
+ r._valEx = resEx;
+ return r;
+}
+
+
+#elif defined(VGO_linux) \
+ && !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux)
+
+/*
From:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
linux/i386/sysdep.h?
return res;
}
-#if defined(VGA_mips64) || defined(VGA_mips32)
-/* MIPS uses a3 != 0 to flag an error */
-SysRes VG_(mk_SysRes_mips32_linux) ( UWord v0, UWord v1, UWord a3 ) {
- SysRes res;
- res._isError = (a3 != (UWord)0);
- res._val = v0;
- res._valEx = v1;
- return res;
-}
-
-/* MIPS uses a3 != 0 to flag an error */
-SysRes VG_(mk_SysRes_mips64_linux) ( ULong v0, ULong v1, ULong a3 ) {
- SysRes res;
- res._isError = (a3 != (ULong)0);
- res._val = v0;
- res._valEx = v1;
- return res;
-}
-#endif
-
/* Generic constructors. */
SysRes VG_(mk_SysRes_Error) ( UWord err ) {
SysRes r;
-#if defined(VGA_mips64) || defined(VGA_mips32)
- r._valEx = 0;
-#endif
r._isError = True;
r._val = err;
return r;
SysRes VG_(mk_SysRes_Success) ( UWord res ) {
SysRes r;
-#if defined(VGA_mips64) || defined(VGA_mips32)
- r._valEx = 0;
-#endif
r._isError = False;
r._val = res;
return r;
}
static
-Bool eq_SyscallStatus ( SyscallStatus* s1, SyscallStatus* s2 )
+Bool eq_SyscallStatus ( UInt sysno, SyscallStatus* s1, SyscallStatus* s2 )
{
/* was: return s1->what == s2->what && sr_EQ( s1->sres, s2->sres ); */
- if (s1->what == s2->what && sr_EQ( s1->sres, s2->sres ))
+ if (s1->what == s2->what && sr_EQ( sysno, s1->sres, s2->sres ))
return True;
# if defined(VGO_darwin)
/* Darwin-specific debugging guff */
previously written the result into the guest state. */
vg_assert(sci->status.what == SsComplete);
+ /* Get the system call number. Because the pre-handler isn't
+ allowed to mess with it, it should be the same for both the
+ original and potentially-modified args. */
+ vg_assert(sci->args.sysno == sci->orig_args.sysno);
+ sysno = sci->args.sysno;
+
getSyscallStatusFromGuestState( &test_status, &tst->arch.vex );
if (!(sci->flags & SfNoWriteResult))
- vg_assert(eq_SyscallStatus( &sci->status, &test_status ));
+ vg_assert(eq_SyscallStatus( sysno, &sci->status, &test_status ));
/* Failure of the above assertion on Darwin can indicate a problem
in the syscall wrappers that pre-fail or pre-succeed the
syscall, by calling SET_STATUS_Success or SET_STATUS_Failure,
comment is completely irrelevant. */
/* Ok, looks sane */
- /* Get the system call number. Because the pre-handler isn't
- allowed to mess with it, it should be the same for both the
- original and potentially-modified args. */
- vg_assert(sci->args.sysno == sci->orig_args.sysno);
- sysno = sci->args.sysno;
- ent = get_syscall_entry(sysno);
-
/* pre: status == Complete (asserted above) */
/* Consider either success or failure. Now run the post handler if:
- it exists, and
- Success or (Failure and PostOnFail is set)
*/
+ ent = get_syscall_entry(sysno);
if (ent->after
&& ((!sr_isError(sci->status.sres))
|| (sr_isError(sci->status.sres)
return buf;
}
+/* include/pub_tool_basics.h hardcodes the following syscall numbers
+ on mips{32,64}-linux so as to avoid a module cycle. We make that
+ safe here by causing the build to fail if those numbers should ever
+ change. See comments in function sr_EQ in the mips{32,64}-linux
+ section of include/pub_tool_basics.h for more details. */
+#if defined(VGP_mips32_linux)
+STATIC_ASSERT(__NR_pipe == 4042);
+STATIC_ASSERT(__NR_pipe2 == 4328);
+#elsif defined(VGP_mips64_linux)
+STATIC_ASSERT(__NR_pipe == 5021);
+STATIC_ASSERT(__NR_pipe2 == 5287);
+#endif
+
//---------------------------------------------------------------------------
#elif defined(VGO_darwin)
//---------------------------------------------------------------------------
extern SysRes VG_(mk_SysRes_Error) ( UWord val );
extern SysRes VG_(mk_SysRes_Success) ( UWord val );
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+/* On Linux/MIPS, VG_(mk_SysRes_Success) sets the second result word
+ to zero. Here is a version that allows setting both values. */
+extern SysRes VG_(mk_SysRes_SuccessEx) ( UWord val, UWord valEx );
+#endif
/* Return a string which gives the name of an error value. Note,
typedef UInt ThreadId;
/* An abstraction of syscall return values.
- Linux:
+ Linux/MIPS32 and Linux/MIPS64:
+ When _isError == False,
+ _val and possible _valEx hold the return value. Whether
+ _valEx actually holds a valid value depends on which syscall
+ this SysRes holds of the result of.
+ When _isError == True,
+ _val holds the error code.
+
+ Linux/other:
When _isError == False,
_val holds the return value.
When _isError == True,
- _err holds the error code.
+ _val holds the error code.
Darwin:
Interpretation depends on _mode:
update both {R,E}DX and {R,E}AX (in guest state) given a SysRes,
if we're required to.
*/
-#if defined(VGO_linux)
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
typedef
struct {
Bool _isError;
UWord _val;
-#if defined(VGA_mips64) || defined(VGA_mips32)
UWord _valEx;
-#endif
}
SysRes;
+
+#elif defined(VGO_linux) \
+ && !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux)
+typedef
+ struct {
+ Bool _isError;
+ UWord _val;
+ }
+ SysRes;
+
#elif defined(VGO_darwin)
typedef
enum {
SysResMode _mode;
}
SysRes;
+
#else
# error "Unknown OS"
#endif
/* ---- And now some basic accessor functions for it. ---- */
-#if defined(VGO_linux)
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
static inline Bool sr_isError ( SysRes sr ) {
return sr._isError;
static inline UWord sr_Res ( SysRes sr ) {
return sr._isError ? 0 : sr._val;
}
-#if defined(VGA_mips64) || defined(VGA_mips32)
static inline UWord sr_ResEx ( SysRes sr ) {
return sr._isError ? 0 : sr._valEx;
}
-#endif
static inline UWord sr_Err ( SysRes sr ) {
return sr._isError ? sr._val : 0;
}
-// FIXME: this function needs to be fixed for MIPS
-static inline Bool sr_EQ ( SysRes sr1, SysRes sr2 ) {
+static inline Bool sr_EQ ( UInt sysno, SysRes sr1, SysRes sr2 ) {
+ /* This uglyness of hardcoding syscall numbers is necessary to
+ avoid having this header file be dependant on
+ include/vki/vki-scnums-mips{32,64}-linux.h. It seems pretty
+ safe given that it is inconceivable that the syscall numbers
+ for such simple syscalls would ever change. To make it
+ really safe, coregrind/m_vkiscnums.c static-asserts that these
+ syscall numbers haven't changed, so that the build wil simply
+ fail if they ever do. */
+# if defined(VGP_mips32_linux)
+ const UInt __nr_Linux = 4000;
+ const UInt __nr_pipe = __nr_Linux + 42;
+ const UInt __nr_pipe2 = __nr_Linux + 328;
+# else
+ const UInt __nr_Linux = 5000;
+ const UInt __nr_pipe = __nr_Linux + 21;
+ const UInt __nr_pipe2 = __nr_Linux + 287;
+# endif
+ Bool useEx = sysno == __nr_pipe || sysno == __nr_pipe2;
+ return sr1._val == sr2._val
+ && (useEx ? (sr1._valEx == sr2._valEx) : True)
+ && sr1._isError == sr2._isError;
+}
+
+#elif defined(VGO_linux) \
+ && !defined(VGP_mips32_linux) && !defined(VGP_mips64_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_Err ( SysRes sr ) {
+ return sr._isError ? sr._val : 0;
+}
+static inline Bool sr_EQ ( UInt sysno, SysRes sr1, SysRes sr2 ) {
+ /* sysno is ignored for Linux/not-MIPS */
return sr1._val == sr2._val
- && sr1._isError == sr2._isError;
+ && sr1._isError == sr2._isError;
}
#elif defined(VGO_darwin)
}
}
-static inline Bool sr_EQ ( SysRes sr1, SysRes sr2 ) {
+static inline Bool sr_EQ ( UInt sysno, SysRes sr1, SysRes sr2 ) {
+ /* sysno is ignored for Darwin */
return sr1._mode == sr2._mode
&& sr1._wLO == sr2._wLO && sr1._wHI == sr2._wHI;
}