summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
authorSteve Reinhardt <steve.reinhardt@amd.com>2014-05-12 14:23:31 -0700
committerSteve Reinhardt <steve.reinhardt@amd.com>2014-05-12 14:23:31 -0700
commit109908c2a6322d1fa31c0b486ea2bada14a292b8 (patch)
tree08f7341bba700aeab9b3ee7974bcbad6b0cc0052 /src/sim
parent72403cb59561a37d42e5b5bc4b0499ddaf9012cf (diff)
downloadgem5-109908c2a6322d1fa31c0b486ea2bada14a292b8.tar.xz
syscall emulation: clean up & comment SyscallReturn
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/syscall_emul.cc10
-rw-r--r--src/sim/syscallreturn.hh69
2 files changed, 56 insertions, 23 deletions
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 935193e7f..61ba32955 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -69,7 +69,7 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n",
- curTick(),tc->getCpuPtr()->name(), name, retval.value());
+ curTick(), tc->getCpuPtr()->name(), name, retval.encodedValue());
if (!(flags & SyscallDesc::SuppressReturnValue))
process->setSyscallReturn(tc, retval);
@@ -366,7 +366,7 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc,
string path;
if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
- return (TheISA::IntReg)-EFAULT;
+ return -EFAULT;
// Adjust path for current working directory
path = p->fullPath(path);
@@ -390,7 +390,7 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
int index = 0;
if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
- return (TheISA::IntReg)-EFAULT;
+ return -EFAULT;
// Adjust path for current working directory
path = p->fullPath(path);
@@ -407,7 +407,7 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
int index = 0;
if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
- return (TheISA::IntReg)-EFAULT;
+ return -EFAULT;
// Adjust path for current working directory
path = p->fullPath(path);
@@ -864,7 +864,7 @@ accessFunc(SyscallDesc *desc, int callnum, LiveProcess *p, ThreadContext *tc,
{
string path;
if (!tc->getMemProxy().tryReadString(path, p->getSyscallArg(tc, index)))
- return (TheISA::IntReg)-EFAULT;
+ return -EFAULT;
// Adjust path for current working directory
path = p->fullPath(path);
diff --git a/src/sim/syscallreturn.hh b/src/sim/syscallreturn.hh
index 385ff55db..547d76610 100644
--- a/src/sim/syscallreturn.hh
+++ b/src/sim/syscallreturn.hh
@@ -33,38 +33,71 @@
#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