sim: Rework the SyscallDesc to use the dumpSimcall mechanism.
This greatly simplifies the doSyscall method, removes a use of getSyscallArg, and will only print arguments the target syscall is going to use. Change-Id: Id8c9c995a2506468fd99fd865f2eb31c40db8b55 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23461 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -29,54 +29,22 @@
|
||||
|
||||
#include "sim/syscall_desc.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "base/types.hh"
|
||||
#include "config/the_isa.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/process.hh"
|
||||
#include "sim/syscall_debug_macros.hh"
|
||||
|
||||
class ThreadContext;
|
||||
|
||||
void
|
||||
SyscallDesc::doSyscall(int callnum, ThreadContext *tc, Fault *fault)
|
||||
{
|
||||
RegVal arg[6] M5_VAR_USED;
|
||||
auto process = tc->getProcessPtr();
|
||||
DPRINTF_SYSCALL(Base, "Calling %s...\n", dumper(name(), tc));
|
||||
|
||||
/**
|
||||
* Step through the first six parameters for the system call and
|
||||
* retrieve their values. Note that index is incremented as a
|
||||
* side-effect of the getSyscallArg method.
|
||||
*/
|
||||
int index = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
arg[i] = process->getSyscallArg(tc, index);
|
||||
|
||||
/**
|
||||
* Linux supports up to six system call arguments through registers
|
||||
* so we want to print all six. Check to the relevant man page to
|
||||
* verify how many are actually used by a given system call.
|
||||
*/
|
||||
DPRINTF_SYSCALL(Base, "%s called w/arguments %d, %d, %d, %d, %d, %d\n",
|
||||
_name, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
|
||||
|
||||
/** Invoke the system call */
|
||||
SyscallReturn retval = executor(this, callnum, tc);
|
||||
|
||||
/**
|
||||
* If the system call needs to be restarted, most likely due to
|
||||
* blocking behavior, warn that the system call will retry;
|
||||
* alternatively, print the return value.
|
||||
*/
|
||||
if (retval.needsRetry()) {
|
||||
*fault = std::make_shared<SyscallRetryFault>();
|
||||
DPRINTF_SYSCALL(Base, "%s needs retry\n", _name);
|
||||
} else
|
||||
DPRINTF_SYSCALL(Base, "%s returns %d\n", _name, retval.encodedValue());
|
||||
|
||||
if (!retval.suppressed() && !retval.needsRetry())
|
||||
process->setSyscallReturn(tc, retval);
|
||||
if (retval.needsRetry())
|
||||
DPRINTF_SYSCALL(Base, "Needs retry.\n", name());
|
||||
else if (retval.suppressed())
|
||||
DPRINTF_SYSCALL(Base, "No return value.\n", name());
|
||||
else
|
||||
DPRINTF_SYSCALL(Base, "Returned %d.\n", retval.encodedValue());
|
||||
}
|
||||
|
||||
@@ -64,13 +64,6 @@ SyscallReturn unimplementedFunc(SyscallDesc *desc, int num,
|
||||
*/
|
||||
class SyscallDesc {
|
||||
public:
|
||||
using SyscallExecutor =
|
||||
std::function<SyscallReturn(SyscallDesc *, int num, ThreadContext *)>;
|
||||
|
||||
SyscallDesc(const char *name, SyscallExecutor sys_exec=unimplementedFunc)
|
||||
: _name(name), executor(sys_exec)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Interface for invoking the system call funcion pointer. Note that
|
||||
* this acts as a gateway for all system calls and serves a good point
|
||||
@@ -83,12 +76,22 @@ class SyscallDesc {
|
||||
|
||||
std::string name() { return _name; }
|
||||
|
||||
protected:
|
||||
using Executor =
|
||||
std::function<SyscallReturn(SyscallDesc *, int num, ThreadContext *)>;
|
||||
using Dumper = std::function<std::string(std::string, ThreadContext *)>;
|
||||
|
||||
SyscallDesc(const char *name, Executor exec, Dumper dump) :
|
||||
_name(name), executor(exec), dumper(dump)
|
||||
{}
|
||||
|
||||
private:
|
||||
/** System call name (e.g., open, mmap, clone, socket, etc.) */
|
||||
std::string _name;
|
||||
|
||||
/** Mechanism for ISAs to connect to the emul function definitions */
|
||||
SyscallExecutor executor;
|
||||
Executor executor;
|
||||
Dumper dumper;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -102,20 +105,20 @@ class SyscallDescABI : public SyscallDesc
|
||||
private:
|
||||
// Aliases to make the code below a little more concise.
|
||||
template <typename ...Args>
|
||||
using SyscallABIExecutor =
|
||||
using ABIExecutor =
|
||||
std::function<SyscallReturn(SyscallDesc *, int,
|
||||
ThreadContext *, Args...)>;
|
||||
|
||||
template <typename ...Args>
|
||||
using SyscallABIExecutorPtr =
|
||||
using ABIExecutorPtr =
|
||||
SyscallReturn (*)(SyscallDesc *, int, ThreadContext *, Args...);
|
||||
|
||||
|
||||
// Wrap an executor with guest arguments with a normal executor that gets
|
||||
// those additional arguments from the guest context.
|
||||
template <typename ...Args>
|
||||
static inline SyscallExecutor
|
||||
buildExecutor(SyscallABIExecutor<Args...> target)
|
||||
static inline Executor
|
||||
buildExecutor(ABIExecutor<Args...> target)
|
||||
{
|
||||
return [target](SyscallDesc *desc, int num,
|
||||
ThreadContext *tc) -> SyscallReturn {
|
||||
@@ -134,20 +137,31 @@ class SyscallDescABI : public SyscallDesc
|
||||
};
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
static inline Dumper
|
||||
buildDumper()
|
||||
{
|
||||
return [](std::string name, ThreadContext *tc) -> std::string {
|
||||
return dumpSimcall<ABI, SyscallReturn, Args...>(name, tc);
|
||||
};
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructors which plumb in buildExecutor.
|
||||
template <typename ...Args>
|
||||
SyscallDescABI(const char *name, SyscallABIExecutor<Args...> target) :
|
||||
SyscallDesc(name, buildExecutor<Args...>(target))
|
||||
SyscallDescABI(const char *name, ABIExecutor<Args...> target) :
|
||||
SyscallDesc(name, buildExecutor<Args...>(target),
|
||||
buildDumper<Args...>())
|
||||
{}
|
||||
|
||||
template <typename ...Args>
|
||||
SyscallDescABI(const char *name, SyscallABIExecutorPtr<Args...> target) :
|
||||
SyscallDescABI(name, SyscallABIExecutor<Args...>(target))
|
||||
SyscallDescABI(const char *name, ABIExecutorPtr<Args...> target) :
|
||||
SyscallDescABI(name, ABIExecutor<Args...>(target))
|
||||
{}
|
||||
|
||||
using SyscallDesc::SyscallDesc;
|
||||
SyscallDescABI(const char *name) :
|
||||
SyscallDescABI(name, ABIExecutor<>(unimplementedFunc))
|
||||
{}
|
||||
};
|
||||
|
||||
#endif // __SIM_SYSCALL_DESC_HH__
|
||||
|
||||
Reference in New Issue
Block a user