config: Add a --without-python option to build process
[gem5.git] / src / sim / syscallreturn.hh
index d1c43f5845af4200853a0ddfa1823d7ad5e35c57..547d7661076cd5cb219cc4501d503b5648fb050a 100644 (file)
 #ifndef __SIM_SYSCALLRETURN_HH__
 #define __SIM_SYSCALLRETURN_HH__
 
-#include <inttypes.h>
+#include "base/types.hh"
 
+/**
+ * This class represents the return value from an emulated system call,
+ * including any errno setting.
+ *
+ * On some platforms, the return value and errno are encoded in a
+ * single signed integer.  A value less than zero but greater than
+ * -4096 indicates an error, and the value is the negation of the
+ * errno value.  Otherwise, the call was successful and the integer is
+ * the return value.  (Large negative numbers are considered
+ * successful to allow syscalls to return pointers to high memory,
+ * e.g., stack addresses.)  See, for example, Appendix A of the AMD64
+ * ABI spec at http://www.x86-64.org/documentation/abi.pdf.
+ *
+ * Other platforms use a more complex interface, returning a value and
+ * an error code in separate registers.
+ *
+ * This class is designed to support both types of interfaces.
+ */
 class SyscallReturn
 {
   public:
-    template <class T>
-    SyscallReturn(T v, bool s)
+
+    /// For simplicity, allow the object to be initialized with a
+    /// single signed integer using the same positive=success,
+    /// negative=-errno convention described above.
+    ///
+    /// Typically this constructor is used as a default type
+    /// conversion, so a bare integer is used where a SyscallReturn
+    /// value is expected, e.g., as the return value from a system
+    /// call emulation function ('return 0;' or 'return -EFAULT;').
+    SyscallReturn(int64_t v)
+        : value(v)
+    {}
+
+    ~SyscallReturn() {}
+
+    /// Was the system call successful?
+    bool successful() const
     {
-        retval = (uint64_t)v;
-        success = s;
+        return (value >= 0 || value <= -4096);
     }
 
-    template <class T>
-    SyscallReturn(T v)
+    /// The return value
+    int64_t returnValue() const
     {
-        success = (v >= 0);
-        retval = (uint64_t)v;
+        assert(successful());
+        return value;
     }
 
-    ~SyscallReturn() {}
+    /// The errno value
+    int errnoValue() const
+    {
+        assert(!successful());
+        return -value;
+    }
 
-    SyscallReturn& operator=(const SyscallReturn& s)
+    /// The encoded value (as described above)
+    int64_t encodedValue() const
     {
-        retval = s.retval;
-        success = s.success;
-        return *this;
+        return value;
     }
 
-    bool successful() { return success; }
-    uint64_t value() { return retval; }
+  private:
 
-    private:
-    uint64_t retval;
-    bool success;
+    int64_t value;
 };
 
 #endif