changeset 34f48d0dac97 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=34f48d0dac97
description:
syscall emulation: clean up & comment SyscallReturn
diffstat:
src/arch/alpha/process.cc | 9 ++---
src/arch/arm/process.cc | 10 ++---
src/arch/mips/process.cc | 9 ++---
src/arch/power/process.cc | 7 +--
src/arch/sparc/process.cc | 13 +++----
src/arch/x86/process.cc | 4 +-
src/sim/syscall_emul.cc | 10 +++---
src/sim/syscallreturn.hh | 75 +++++++++++++++++++++++++++++++++-------------
8 files changed, 82 insertions(+), 55 deletions(-)
diffs (291 lines):
diff -r d51e31eef415 -r 34f48d0dac97 src/arch/alpha/process.cc
--- a/src/arch/alpha/process.cc Mon May 12 17:22:17 2014 -0400
+++ b/src/arch/alpha/process.cc Mon May 12 14:23:31 2014 -0700
@@ -220,19 +220,18 @@
}
void
-AlphaLiveProcess::setSyscallReturn(ThreadContext *tc,
- SyscallReturn return_value)
+AlphaLiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the
// return value itself in the standard return value reg (v0).
- if (return_value.successful()) {
+ if (sysret.successful()) {
// no error
tc->setIntReg(SyscallSuccessReg, 0);
- tc->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(ReturnValueReg, sysret.returnValue());
} else {
// got an error, return details
tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
- tc->setIntReg(ReturnValueReg, -return_value.value());
+ tc->setIntReg(ReturnValueReg, sysret.errnoValue());
}
}
diff -r d51e31eef415 -r 34f48d0dac97 src/arch/arm/process.cc
--- a/src/arch/arm/process.cc Mon May 12 17:22:17 2014 -0400
+++ b/src/arch/arm/process.cc Mon May 12 14:23:31 2014 -0700
@@ -454,15 +454,13 @@
}
void
-ArmLiveProcess32::setSyscallReturn(ThreadContext *tc,
- SyscallReturn return_value)
+ArmLiveProcess32::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
- tc->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(ReturnValueReg, sysret.encodedValue());
}
void
-ArmLiveProcess64::setSyscallReturn(ThreadContext *tc,
- SyscallReturn return_value)
+ArmLiveProcess64::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
- tc->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(ReturnValueReg, sysret.encodedValue());
}
diff -r d51e31eef415 -r 34f48d0dac97 src/arch/mips/process.cc
--- a/src/arch/mips/process.cc Mon May 12 17:22:17 2014 -0400
+++ b/src/arch/mips/process.cc Mon May 12 14:23:31 2014 -0700
@@ -197,16 +197,15 @@
}
void
-MipsLiveProcess::setSyscallReturn(ThreadContext *tc,
- SyscallReturn return_value)
+MipsLiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
- if (return_value.successful()) {
+ if (sysret.successful()) {
// no error
tc->setIntReg(SyscallSuccessReg, 0);
- tc->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(ReturnValueReg, sysret.returnValue());
} else {
// got an error, return details
tc->setIntReg(SyscallSuccessReg, (IntReg) -1);
- tc->setIntReg(ReturnValueReg, -return_value.value());
+ tc->setIntReg(ReturnValueReg, sysret.errnoValue());
}
}
diff -r d51e31eef415 -r 34f48d0dac97 src/arch/power/process.cc
--- a/src/arch/power/process.cc Mon May 12 17:22:17 2014 -0400
+++ b/src/arch/power/process.cc Mon May 12 14:23:31 2014 -0700
@@ -277,15 +277,14 @@
}
void
-PowerLiveProcess::setSyscallReturn(ThreadContext *tc,
- SyscallReturn return_value)
+PowerLiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
Cr cr = tc->readIntReg(INTREG_CR);
- if (return_value.successful()) {
+ if (sysret.successful()) {
cr.cr0.so = 0;
} else {
cr.cr0.so = 1;
}
tc->setIntReg(INTREG_CR, cr);
- tc->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(ReturnValueReg, sysret.encodedValue());
}
diff -r d51e31eef415 -r 34f48d0dac97 src/arch/sparc/process.cc
--- a/src/arch/sparc/process.cc Mon May 12 17:22:17 2014 -0400
+++ b/src/arch/sparc/process.cc Mon May 12 14:23:31 2014 -0700
@@ -532,26 +532,25 @@
}
void
-SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
- SyscallReturn return_value)
+SparcLiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
- if (return_value.successful()) {
+ if (sysret.successful()) {
// no error, clear XCC.C
tc->setIntReg(NumIntArchRegs + 2,
- tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
- IntReg val = return_value.value();
+ tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
+ IntReg val = sysret.returnValue();
if (pstate.am)
val = bits(val, 31, 0);
tc->setIntReg(ReturnValueReg, val);
} else {
// got an error, set XCC.C
tc->setIntReg(NumIntArchRegs + 2,
- tc->readIntReg(NumIntArchRegs + 2) | 0x11);
- IntReg val = -return_value.value();
+ tc->readIntReg(NumIntArchRegs + 2) | 0x11);
+ IntReg val = sysret.errnoValue();
if (pstate.am)
val = bits(val, 31, 0);
tc->setIntReg(ReturnValueReg, val);
diff -r d51e31eef415 -r 34f48d0dac97 src/arch/x86/process.cc
--- a/src/arch/x86/process.cc Mon May 12 17:22:17 2014 -0400
+++ b/src/arch/x86/process.cc Mon May 12 14:23:31 2014 -0700
@@ -678,9 +678,9 @@
}
void
-X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)
+X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn retval)
{
- tc->setIntReg(INTREG_RAX, return_value.value());
+ tc->setIntReg(INTREG_RAX, retval.encodedValue());
}
X86ISA::IntReg
diff -r d51e31eef415 -r 34f48d0dac97 src/sim/syscall_emul.cc
--- a/src/sim/syscall_emul.cc Mon May 12 17:22:17 2014 -0400
+++ b/src/sim/syscall_emul.cc Mon May 12 14:23:31 2014 -0700
@@ -69,7 +69,7 @@
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 @@
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 @@
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 @@
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 @@
{
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 -r d51e31eef415 -r 34f48d0dac97 src/sim/syscallreturn.hh
--- a/src/sim/syscallreturn.hh Mon May 12 17:22:17 2014 -0400
+++ b/src/sim/syscallreturn.hh Mon May 12 14:23:31 2014 -0700
@@ -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)
- {
- retval = (uint64_t)v;
- success = s;
- }
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
+ /// 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() {}
- SyscallReturn& operator=(const SyscallReturn& s)
+ /// Was the system call successful?
+ bool successful() const
{
- retval = s.retval;
- success = s.success;
- return *this;
+ return (value >= 0 || value <= -4096);
}
- bool successful() { return success; }
- uint64_t value() { return retval; }
+ /// The return value
+ int64_t returnValue() const
+ {
+ assert(successful());
+ return value;
+ }
- private:
- uint64_t retval;
- bool success;
+ /// The errno value
+ int errnoValue() const
+ {
+ assert(!successful());
+ return -value;
+ }
+
+ /// The encoded value (as described above)
+ int64_t encodedValue() const
+ {
+ return value;
+ }
+
+ private:
+
+ int64_t value;
};
#endif
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev