From 109908c2a6322d1fa31c0b486ea2bada14a292b8 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 12 May 2014 14:23:31 -0700 Subject: syscall emulation: clean up & comment SyscallReturn --- src/sim/syscall_emul.cc | 10 +++---- src/sim/syscallreturn.hh | 69 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 23 deletions(-) (limited to 'src/sim') 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 - 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 - 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 -- cgit v1.2.3