diff options
-rw-r--r-- | sim/common/ChangeLog | 7 | ||||
-rw-r--r-- | sim/common/sim-syscall.c | 77 | ||||
-rw-r--r-- | sim/common/sim-syscall.h | 15 | ||||
-rw-r--r-- | sim/common/syscall.c | 2 | ||||
-rw-r--r-- | sim/lm32/ChangeLog | 5 | ||||
-rw-r--r-- | sim/lm32/traps.c | 28 | ||||
-rw-r--r-- | sim/m32r/ChangeLog | 6 | ||||
-rw-r--r-- | sim/m32r/traps-linux.c | 37 | ||||
-rw-r--r-- | sim/m32r/traps.c | 35 | ||||
-rw-r--r-- | sim/mcore/ChangeLog | 5 | ||||
-rw-r--r-- | sim/mcore/interp.c | 22 | ||||
-rw-r--r-- | sim/mn10300/ChangeLog | 5 | ||||
-rw-r--r-- | sim/mn10300/op_utils.c | 55 | ||||
-rw-r--r-- | sim/msp430/ChangeLog | 5 | ||||
-rw-r--r-- | sim/msp430/msp430-sim.c | 64 |
15 files changed, 197 insertions, 171 deletions
diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 2c67e49..59d92f4 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,5 +1,12 @@ 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. * sim-syscall.c: New file. * sim-syscall.h: New file. diff --git a/sim/common/sim-syscall.c b/sim/common/sim-syscall.c index 76812d3..6f4c8a3 100644 --- a/sim/common/sim-syscall.c +++ b/sim/common/sim-syscall.c @@ -19,8 +19,11 @@ #include "config.h" +#include <errno.h> + #include "sim-main.h" #include "sim-syscall.h" +#include "targ-vals.h" /* Read/write functions for system call interface. */ @@ -47,3 +50,77 @@ 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); } + +/* 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; +} diff --git a/sim/common/sim-syscall.h b/sim/common/sim-syscall.h index 3f231fe..7e74661 100644 --- a/sim/common/sim-syscall.h +++ b/sim/common/sim-syscall.h @@ -20,6 +20,21 @@ #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, diff --git a/sim/common/syscall.c b/sim/common/syscall.c index 29b73c2..0c37428 100644 --- a/sim/common/syscall.c +++ b/sim/common/syscall.c @@ -240,7 +240,7 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) #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 : diff --git a/sim/lm32/ChangeLog b/sim/lm32/ChangeLog index 4cee5da..7442ba3 100644 --- a/sim/lm32/ChangeLog +++ b/sim/lm32/ChangeLog @@ -1,5 +1,10 @@ 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. (syscall_read_mem, syscall_write_mem): Delete. (lm32bf_scall_insn): Change syscall_read_mem/syscall_write_mem diff --git a/sim/lm32/traps.c b/sim/lm32/traps.c index 810ddf7..9de0910 100644 --- a/sim/lm32/traps.c +++ b/sim/lm32/traps.c @@ -132,26 +132,18 @@ lm32bf_scall_insn (SIM_CPU * current_cpu, IADDR pc) || (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; } diff --git a/sim/m32r/ChangeLog b/sim/m32r/ChangeLog index b915747..43aa13d 100644 --- a/sim/m32r/ChangeLog +++ b/sim/m32r/ChangeLog @@ -1,5 +1,11 @@ 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. (syscall_read_mem, syscall_write_mem): Delete. (m32r_trap): Change syscall_read_mem/syscall_write_mem diff --git a/sim/m32r/traps-linux.c b/sim/m32r/traps-linux.c index 4b6384e..8fee2a0 100644 --- a/sim/m32r/traps-linux.c +++ b/sim/m32r/traps-linux.c @@ -213,28 +213,21 @@ m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num) { 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 : diff --git a/sim/m32r/traps.c b/sim/m32r/traps.c index 869b596..225c37f 100644 --- a/sim/m32r/traps.c +++ b/sim/m32r/traps.c @@ -129,27 +129,20 @@ m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num) { 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; } diff --git a/sim/mcore/ChangeLog b/sim/mcore/ChangeLog index 389983d..bc1598a 100644 --- a/sim/mcore/ChangeLog +++ b/sim/mcore/ChangeLog @@ -1,5 +1,10 @@ 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. (syscall_read_mem, syscall_write_mem): Delete. (m32r_trap): Change syscall_read_mem/syscall_write_mem diff --git a/sim/mcore/interp.c b/sim/mcore/interp.c index e77535b..64d148a 100644 --- a/sim/mcore/interp.c +++ b/sim/mcore/interp.c @@ -203,26 +203,10 @@ set_initial_gprs (SIM_CPU *scpu) 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 diff --git a/sim/mn10300/ChangeLog b/sim/mn10300/ChangeLog index 1965d5fd..ce1d326 100644 --- a/sim/mn10300/ChangeLog +++ b/sim/mn10300/ChangeLog @@ -1,5 +1,10 @@ 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. * op_utils.c: Include sim-syscall.h. (syscall_read_mem, syscall_write_mem): Delete. diff --git a/sim/mn10300/op_utils.c b/sim/mn10300/op_utils.c index 7b156f8..67bf9a3 100644 --- a/sim/mn10300/op_utils.c +++ b/sim/mn10300/op_utils.c @@ -145,6 +145,15 @@ genericBtst(unsigned32 leftOpnd, unsigned32 rightOpnd) 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 @@ -152,46 +161,24 @@ do_syscall (void) 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; } - diff --git a/sim/msp430/ChangeLog b/sim/msp430/ChangeLog index d26f3f4..146796c 100644 --- a/sim/msp430/ChangeLog +++ b/sim/msp430/ChangeLog @@ -1,5 +1,10 @@ 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_read_mem, syscall_write_mem): Delete. (maybe_perform_syscall): Change syscall_read_mem/syscall_write_mem diff --git a/sim/msp430/msp430-sim.c b/sim/msp430/msp430-sim.c index 650584a..931573e 100644 --- a/sim/msp430/msp430-sim.c +++ b/sim/msp430/msp430-sim.c @@ -1022,62 +1022,14 @@ maybe_perform_syscall (SIM_DESC sd, int call_addr) { /* 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; } |