+2015-06-17 Mike Frysinger <vapier@gentoo.org>
+
+ * sim-syscall.c: Include errno.h and targ-vals.h.
+ (sim_syscall_multi, sim_syscall): Define.
+ * sim-syscall.h (sim_syscall_multi, sim_syscall): Declare.
+ * syscall.c (cb_syscall): Extend comment.
+
2015-06-17 Mike Frysinger <vapier@gentoo.org>
* Make-common.in (SIM_NEW_COMMON_OBJS): Add sim-syscall.o.
#include "config.h"
+#include <errno.h>
+
#include "sim-main.h"
#include "sim-syscall.h"
+#include "targ-vals.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;
+ char unknown_syscall[30];
+ const char *syscall;
+
+ CB_SYSCALL_INIT (&sc);
+
+ sc.func = func;
+ sc.arg1 = arg1;
+ sc.arg2 = arg2;
+ sc.arg3 = arg3;
+ sc.arg4 = arg4;
+
+ sc.p1 = (PTR) sd;
+ sc.p2 = (PTR) 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)
+ {
+ sprintf (unknown_syscall, "syscall_%i", func);
+ 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);
+
+ if (cb_target_to_host_syscall (cb, func) == CB_SYS_exit)
+ sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_exited, arg1);
+ else if (sc.result == -1)
+ {
+ cb->last_errno = errno;
+ sc.errcode = cb->get_errno (cb);
+ }
+
+ *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;
+}
#ifndef SIM_SYSCALL_H
#define SIM_SYSCALL_H
+/* Perform a syscall on the behalf of the target program. The error/result are
+ normalized into a single value (like a lot of operating systems do). If you
+ want the split values, see the other function below.
+
+ Note: While cb_syscall requires you handle the exit syscall yourself, that is
+ not the case with these helpers.
+
+ Note: Types here match the gdb callback interface. */
+long sim_syscall (SIM_CPU *, int func, long arg1, long arg2, long arg3,
+ long arg4);
+
+/* Same as sim_syscall, but return the split values by referenced. */
+void sim_syscall_multi (SIM_CPU *, int func, long arg1, long arg2, long arg3,
+ long arg4, long *result, long *result2, int *errcode);
+
/* Simple memory callbacks for cb_syscall's read_mem/write_mem that assume
cb_syscall's p1 and p2 are set to the SIM_DESC and SIM_CPU respectively. */
int sim_syscall_read_mem (host_callback *, struct cb_syscall *, unsigned long,
#endif /* wip */
case CB_SYS_exit :
- /* Caller must catch and handle. */
+ /* Caller must catch and handle; see sim_syscall as an example. */
break;
case CB_SYS_open :
+2015-06-17 Mike Frysinger <vapier@gentoo.org>
+
+ * traps.c (lm32bf_scall_insn): Replace call to cb_syscall with
+ sim_syscall_multi.
+
2015-06-17 Mike Frysinger <vapier@gentoo.org>
* traps.c: Include sim-syscall.h.
|| (GET_H_GR (8) == TARGET_SYS_exit))
{
/* Delegate system call to host O/S. */
- CB_SYSCALL s;
- CB_SYSCALL_INIT (&s);
- s.p1 = (PTR) sd;
- s.p2 = (PTR) current_cpu;
- s.read_mem = sim_syscall_read_mem;
- s.write_mem = sim_syscall_write_mem;
- /* Extract parameters. */
- s.func = GET_H_GR (8);
- s.arg1 = GET_H_GR (1);
- s.arg2 = GET_H_GR (2);
- s.arg3 = GET_H_GR (3);
- /* Halt the simulator if the requested system call is _exit. */
- if (s.func == TARGET_SYS_exit)
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
+ long result, result2;
+ int errcode;
+
/* Perform the system call. */
- cb_syscall (cb, &s);
+ sim_syscall_multi (current_cpu, GET_H_GR (8), GET_H_GR (1), GET_H_GR (2),
+ GET_H_GR (3), GET_H_GR (4), &result, &result2,
+ &errcode);
/* Store the return value in the CPU's registers. */
- SET_H_GR (1, s.result);
- SET_H_GR (2, s.result2);
- SET_H_GR (3, s.errcode);
+ SET_H_GR (1, result);
+ SET_H_GR (2, result2);
+ SET_H_GR (3, errcode);
+
/* Skip over scall instruction. */
return pc + 4;
}
+2015-06-17 Mike Frysinger <vapier@gentoo.org>
+
+ * traps.c (m32r_trap): Replace call to cb_syscall with
+ sim_syscall_multi.
+ * traps-linux.c (m32r_trap): Likewise.
+
2015-06-17 Mike Frysinger <vapier@gentoo.org>
* traps-linux.c: Include sim-syscall.h.
{
case TRAP_ELF_SYSCALL :
{
- CB_SYSCALL s;
-
- CB_SYSCALL_INIT (&s);
- s.func = m32rbf_h_gr_get (current_cpu, 0);
- s.arg1 = m32rbf_h_gr_get (current_cpu, 1);
- s.arg2 = m32rbf_h_gr_get (current_cpu, 2);
- s.arg3 = m32rbf_h_gr_get (current_cpu, 3);
-
- if (s.func == TARGET_SYS_exit)
- {
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
- }
-
- s.p1 = (PTR) sd;
- s.p2 = (PTR) current_cpu;
- s.read_mem = sim_syscall_read_mem;
- s.write_mem = sim_syscall_write_mem;
- cb_syscall (cb, &s);
- m32rbf_h_gr_set (current_cpu, 2, s.errcode);
- m32rbf_h_gr_set (current_cpu, 0, s.result);
- m32rbf_h_gr_set (current_cpu, 1, s.result2);
- break;
+ long result, result2;
+ int errcode;
+
+ sim_syscall_multi (current_cpu,
+ m32rbf_h_gr_get (current_cpu, 0),
+ m32rbf_h_gr_get (current_cpu, 1),
+ m32rbf_h_gr_get (current_cpu, 2),
+ m32rbf_h_gr_get (current_cpu, 3),
+ m32rbf_h_gr_get (current_cpu, 4),
+ &result, &result2, &errcode);
+
+ m32rbf_h_gr_set (current_cpu, 2, errcode);
+ m32rbf_h_gr_set (current_cpu, 0, result);
+ m32rbf_h_gr_set (current_cpu, 1, result2);
+ break;
}
case TRAP_LINUX_SYSCALL :
{
case TRAP_SYSCALL :
{
- CB_SYSCALL s;
-
- CB_SYSCALL_INIT (&s);
- s.func = m32rbf_h_gr_get (current_cpu, 0);
- s.arg1 = m32rbf_h_gr_get (current_cpu, 1);
- s.arg2 = m32rbf_h_gr_get (current_cpu, 2);
- s.arg3 = m32rbf_h_gr_get (current_cpu, 3);
-
- if (s.func == TARGET_SYS_exit)
- {
- sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
- }
-
- s.p1 = (PTR) sd;
- s.p2 = (PTR) current_cpu;
- s.read_mem = sim_syscall_read_mem;
- s.write_mem = sim_syscall_write_mem;
- cb_syscall (cb, &s);
- m32rbf_h_gr_set (current_cpu, 2, s.errcode);
- m32rbf_h_gr_set (current_cpu, 0, s.result);
- m32rbf_h_gr_set (current_cpu, 1, s.result2);
+ long result, result2;
+ int errcode;
+
+ sim_syscall_multi (current_cpu,
+ m32rbf_h_gr_get (current_cpu, 0),
+ m32rbf_h_gr_get (current_cpu, 1),
+ m32rbf_h_gr_get (current_cpu, 2),
+ m32rbf_h_gr_get (current_cpu, 3),
+ m32rbf_h_gr_get (current_cpu, 4),
+ &result, &result2, &errcode);
+
+ m32rbf_h_gr_set (current_cpu, 2, errcode);
+ m32rbf_h_gr_set (current_cpu, 0, result);
+ m32rbf_h_gr_set (current_cpu, 1, result2);
break;
}
+2015-06-17 Mike Frysinger <vapier@gentoo.org>
+
+ * interp.c (handle_trap1): Replace call to cb_syscall with
+ sim_syscall.
+
2015-06-17 Mike Frysinger <vapier@gentoo.org>
* interp.c: Include sim-syscall.h.
static void
handle_trap1 (SIM_DESC sd)
{
- host_callback *cb = STATE_CALLBACK (sd);
- CB_SYSCALL sc;
-
- CB_SYSCALL_INIT (&sc);
-
- sc.func = cpu.gr[TRAPCODE];
- sc.arg1 = cpu.gr[PARM1];
- sc.arg2 = cpu.gr[PARM2];
- sc.arg3 = cpu.gr[PARM3];
- sc.arg4 = cpu.gr[PARM4];
-
- sc.p1 = (PTR) sd;
- sc.p2 = (PTR) STATE_CPU (sd, 0);
- sc.read_mem = sim_syscall_read_mem;
- sc.write_mem = sim_syscall_write_mem;
-
- cb_syscall (cb, &sc);
-
/* XXX: We don't pass back the actual errno value. */
- cpu.gr[RET1] = sc.result;
+ cpu.gr[RET1] = sim_syscall (STATE_CPU (sd, 0), cpu.gr[TRAPCODE],
+ cpu.gr[PARM1], cpu.gr[PARM2], cpu.gr[PARM3],
+ cpu.gr[PARM4]);
}
static void
+2015-06-17 Mike Frysinger <vapier@gentoo.org>
+
+ * op_utils.c (do_syscall): Replace call to cb_syscall with
+ sim_syscall_multi.
+
2015-06-17 Mike Frysinger <vapier@gentoo.org>
* mn10300_sim.h (syscall_read_mem, syscall_write_mem): Delete.
INLINE_SIM_MAIN (void)
do_syscall (void)
{
+ /* Registers passed to trap 0. */
+
+ /* Function number. */
+ reg_t func = State.regs[0];
+ /* Parameters. */
+ reg_t parm1 = State.regs[1];
+ reg_t parm2 = load_word (State.regs[REG_SP] + 12);
+ reg_t parm3 = load_word (State.regs[REG_SP] + 16);
+ reg_t parm4 = load_word (State.regs[REG_SP] + 20);
/* We use this for simulated system calls; we may need to change
it to a reserved instruction if we conflict with uses at
int save_errno = errno;
errno = 0;
-/* Registers passed to trap 0 */
-
-/* Function number. */
-#define FUNC (State.regs[0])
-
-/* Parameters. */
-#define PARM1 (State.regs[1])
-#define PARM2 (load_word (State.regs[REG_SP] + 12))
-#define PARM3 (load_word (State.regs[REG_SP] + 16))
-
-/* Registers set by trap 0 */
-
-#define RETVAL State.regs[0] /* return value */
-#define RETERR State.regs[1] /* return error code */
-
- if ( FUNC == TARGET_SYS_exit )
+ if (func == TARGET_SYS_exit)
{
- /* EXIT - caller can look in PARM1 to work out the reason */
+ /* EXIT - caller can look in parm1 to work out the reason */
sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
- (PARM1 == 0xdead ? SIM_SIGABRT : sim_exited), PARM1);
+ (parm1 == 0xdead ? SIM_SIGABRT : sim_exited), parm1);
}
else
{
- CB_SYSCALL syscall;
-
- CB_SYSCALL_INIT (&syscall);
- syscall.arg1 = PARM1;
- syscall.arg2 = PARM2;
- syscall.arg3 = PARM3;
- syscall.func = FUNC;
- syscall.p1 = (PTR) simulator;
- syscall.p2 = (PTR) STATE_CPU (simulator, 0);
- syscall.read_mem = sim_syscall_read_mem;
- syscall.write_mem = sim_syscall_write_mem;
- cb_syscall (STATE_CALLBACK (simulator), &syscall);
- RETERR = syscall.errcode;
- RETVAL = syscall.result;
- }
+ long result, result2;
+ int errcode;
+ sim_syscall_multi (STATE_CPU (simulator, 0), func, parm1, parm2,
+ parm3, parm4, &result, &result2, &errcode);
+
+ /* Registers set by trap 0. */
+ State.regs[0] = errcode;
+ State.regs[1] = result;
+ }
errno = save_errno;
}
-
+2015-06-17 Mike Frysinger <vapier@gentoo.org>
+
+ * msp430-sim.c (maybe_perform_syscall): Replace call to cb_syscall
+ with sim_syscall.
+
2015-06-17 Mike Frysinger <vapier@gentoo.org>
* msp430-sim.c: Include sim-syscall.h.
{
/* Syscall! */
int syscall_num = call_addr & 0x3f;
- host_callback *cb = STATE_CALLBACK (sd);
- CB_SYSCALL sc;
-
- CB_SYSCALL_INIT (&sc);
-
- sc.func = syscall_num;
- sc.arg1 = MSP430_CPU (sd)->state.regs[12];
- sc.arg2 = MSP430_CPU (sd)->state.regs[13];
- sc.arg3 = MSP430_CPU (sd)->state.regs[14];
- sc.arg4 = MSP430_CPU (sd)->state.regs[15];
-
- if (TRACE_SYSCALL_P (MSP430_CPU (sd)))
- {
- const char *syscall_name = "*unknown*";
-
- switch (syscall_num)
- {
- case TARGET_SYS_exit:
- syscall_name = "exit(%d)";
- break;
- case TARGET_SYS_open:
- syscall_name = "open(%#x,%#x)";
- break;
- case TARGET_SYS_close:
- syscall_name = "close(%d)";
- break;
- case TARGET_SYS_read:
- syscall_name = "read(%d,%#x,%d)";
- break;
- case TARGET_SYS_write:
- syscall_name = "write(%d,%#x,%d)";
- break;
- }
- trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX,
- syscall_name, sc.arg1, sc.arg2, sc.arg3, sc.arg4);
- }
-
- /* Handle SYS_exit here. */
- if (syscall_num == 1)
- {
- sim_engine_halt (sd, MSP430_CPU (sd), NULL,
- MSP430_CPU (sd)->state.regs[0],
- sim_exited, sc.arg1);
- return 1;
- }
-
- sc.p1 = sd;
- sc.p2 = MSP430_CPU (sd);
- sc.read_mem = sim_syscall_read_mem;
- sc.write_mem = sim_syscall_write_mem;
-
- cb_syscall (cb, &sc);
-
- TRACE_SYSCALL (MSP430_CPU (sd), "returns %ld", sc.result);
-
- MSP430_CPU (sd)->state.regs[12] = sc.result;
+ int arg1 = MSP430_CPU (sd)->state.regs[12];
+ int arg2 = MSP430_CPU (sd)->state.regs[13];
+ int arg3 = MSP430_CPU (sd)->state.regs[14];
+ int arg4 = MSP430_CPU (sd)->state.regs[15];
+
+ MSP430_CPU (sd)->state.regs[12] = sim_syscall (MSP430_CPU (sd),
+ syscall_num, arg1, arg2,
+ arg3, arg4);
return 1;
}