/* 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. */
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;
+}