sim: Rework the SyscallDesc to use the dumpSimcall mechanism.
authorGabe Black <gabeblack@google.com>
Sun, 8 Dec 2019 09:36:05 +0000 (01:36 -0800)
committerGabe Black <gabeblack@google.com>
Thu, 12 Mar 2020 07:21:13 +0000 (07:21 +0000)
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>

src/sim/syscall_desc.cc
src/sim/syscall_desc.hh

index d0c96b98eafdd50ea9c3be1eecb079dceaf5b422..6c7fae5e63347ec23409a23f355c550ccdaa8ddf 100644 (file)
 
 #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();
-
-    /**
-     * 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);
+    DPRINTF_SYSCALL(Base, "Calling %s...\n", dumper(name(), tc));
 
-    /**
-     * 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());
 }
index a00b1f325f3571cf90d0a642abb1b01c3a97f80a..4f1aa1877ca5d52bed99b7cf4ef0953e9145d7bb 100644 (file)
@@ -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__