]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/common/sim-syscall.c
Fix typo in warning in gdb/configure
[thirdparty/binutils-gdb.git] / sim / common / sim-syscall.c
index 76812d358ea5cef9f5f1aa53494006a90b091f8c..d1059f0b7552ecb544c88119ffa68b587e7a7b25 100644 (file)
@@ -1,6 +1,6 @@
 /* Simulator system call support.
 
-   Copyright 2002-2015 Free Software Foundation, Inc.
+   Copyright 2002-2024 Free Software Foundation, Inc.
 
    This file is part of simulators.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#include "config.h"
+/* This must come before any other includes.  */
+#include "defs.h"
+
+#include <errno.h>
+
+#include "ansidecl.h"
 
 #include "sim-main.h"
 #include "sim-syscall.h"
+#include "sim/callback.h"
 \f
 /* Read/write functions for system call interface.  */
 
@@ -47,3 +53,81 @@ sim_syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc
 
   return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
 }
+\f
+/* Main syscall callback for simulators.  */
+
+void
+sim_syscall_multi (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3,
+                  long arg4, long *result, long *result2, int *errcode)
+{
+  SIM_DESC sd = CPU_STATE (cpu);
+  host_callback *cb = STATE_CALLBACK (sd);
+  CB_SYSCALL sc;
+  const char unknown_syscall[] = "<UNKNOWN SYSCALL>";
+  const char *syscall;
+
+  CB_SYSCALL_INIT (&sc);
+
+  sc.func = func;
+  sc.arg1 = arg1;
+  sc.arg2 = arg2;
+  sc.arg3 = arg3;
+  sc.arg4 = arg4;
+
+  sc.p1 = sd;
+  sc.p2 = cpu;
+  sc.read_mem = sim_syscall_read_mem;
+  sc.write_mem = sim_syscall_write_mem;
+
+  if (cb_syscall (cb, &sc) != CB_RC_OK)
+    {
+      /* The cb_syscall func never returns an error, so this is more of a
+        sanity check.  */
+      sim_engine_abort (sd, cpu, sim_pc_get (cpu), "cb_syscall failed");
+    }
+
+  syscall = cb_target_str_syscall (cb, func);
+  if (!syscall)
+    syscall = unknown_syscall;
+
+  if (sc.result == -1)
+    TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li (error = %s[%i])",
+                  syscall, func, arg1, arg2, arg3, sc.result,
+                  cb_target_str_errno (cb, sc.errcode), sc.errcode);
+  else
+    TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li",
+                  syscall, func, arg1, arg2, arg3, sc.result);
+
+  /* Handle syscalls that affect engine behavior.  */
+  switch (cb_target_to_host_syscall (cb, func))
+    {
+    case CB_SYS_exit:
+      sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_exited, arg1);
+      break;
+
+    case CB_SYS_kill:
+      /* TODO: Need to translate target signal to sim signal, but the sim
+        doesn't yet have such a mapping layer.  */
+      if (arg1 == (*cb->getpid) (cb))
+       sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_signalled, arg2);
+      break;
+    }
+
+  *result = sc.result;
+  *result2 = sc.result2;
+  *errcode = sc.errcode;
+}
+
+long
+sim_syscall (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, long arg4)
+{
+  long result, result2;
+  int errcode;
+
+  sim_syscall_multi (cpu, func, arg1, arg2, arg3, arg4, &result, &result2,
+                    &errcode);
+  if (result == -1)
+    return -errcode;
+  else
+    return result;
+}