1 1.1 christos /* Simulator system call support. 2 1.1 christos 3 1.1.1.7 christos Copyright 2002-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of simulators. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1.1.6 christos /* This must come before any other includes. */ 21 1.1.1.6 christos #include "defs.h" 22 1.1 christos 23 1.1 christos #include <errno.h> 24 1.1 christos 25 1.1.1.6 christos #include "ansidecl.h" 26 1.1.1.6 christos 27 1.1 christos #include "sim-main.h" 28 1.1 christos #include "sim-syscall.h" 29 1.1.1.6 christos #include "sim/callback.h" 30 1.1 christos 31 1.1 christos /* Read/write functions for system call interface. */ 33 1.1 christos 34 1.1 christos int 35 1.1 christos sim_syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc, 36 1.1 christos unsigned long taddr, char *buf, int bytes) 37 1.1 christos { 38 1.1 christos SIM_DESC sd = (SIM_DESC) sc->p1; 39 1.1 christos SIM_CPU *cpu = (SIM_CPU *) sc->p2; 40 1.1 christos 41 1.1 christos TRACE_MEMORY (cpu, "READ (syscall) %i bytes @ 0x%08lx", bytes, taddr); 42 1.1 christos 43 1.1 christos return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes); 44 1.1 christos } 45 1.1 christos 46 1.1 christos int 47 1.1 christos sim_syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc, 48 1.1 christos unsigned long taddr, const char *buf, int bytes) 49 1.1 christos { 50 1.1 christos SIM_DESC sd = (SIM_DESC) sc->p1; 51 1.1 christos SIM_CPU *cpu = (SIM_CPU *) sc->p2; 52 1.1 christos 53 1.1 christos TRACE_MEMORY (cpu, "WRITE (syscall) %i bytes @ 0x%08lx", bytes, taddr); 54 1.1 christos 55 1.1 christos return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); 56 1.1 christos } 57 1.1 christos 58 1.1 christos /* Main syscall callback for simulators. */ 60 1.1 christos 61 1.1 christos void 62 1.1 christos sim_syscall_multi (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, 63 1.1 christos long arg4, long *result, long *result2, int *errcode) 64 1.1 christos { 65 1.1 christos SIM_DESC sd = CPU_STATE (cpu); 66 1.1 christos host_callback *cb = STATE_CALLBACK (sd); 67 1.1 christos CB_SYSCALL sc; 68 1.1 christos const char unknown_syscall[] = "<UNKNOWN SYSCALL>"; 69 1.1 christos const char *syscall; 70 1.1 christos 71 1.1 christos CB_SYSCALL_INIT (&sc); 72 1.1 christos 73 1.1 christos sc.func = func; 74 1.1 christos sc.arg1 = arg1; 75 1.1 christos sc.arg2 = arg2; 76 1.1 christos sc.arg3 = arg3; 77 1.1.1.6 christos sc.arg4 = arg4; 78 1.1.1.6 christos 79 1.1 christos sc.p1 = sd; 80 1.1 christos sc.p2 = cpu; 81 1.1 christos sc.read_mem = sim_syscall_read_mem; 82 1.1 christos sc.write_mem = sim_syscall_write_mem; 83 1.1 christos 84 1.1 christos if (cb_syscall (cb, &sc) != CB_RC_OK) 85 1.1 christos { 86 1.1 christos /* The cb_syscall func never returns an error, so this is more of a 87 1.1 christos sanity check. */ 88 1.1 christos sim_engine_abort (sd, cpu, sim_pc_get (cpu), "cb_syscall failed"); 89 1.1 christos } 90 1.1 christos 91 1.1 christos syscall = cb_target_str_syscall (cb, func); 92 1.1 christos if (!syscall) 93 1.1 christos syscall = unknown_syscall; 94 1.1 christos 95 1.1 christos if (sc.result == -1) 96 1.1 christos TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li (error = %s[%i])", 97 1.1 christos syscall, func, arg1, arg2, arg3, sc.result, 98 1.1 christos cb_target_str_errno (cb, sc.errcode), sc.errcode); 99 1.1 christos else 100 1.1 christos TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li", 101 1.1.1.6 christos syscall, func, arg1, arg2, arg3, sc.result); 102 1.1.1.6 christos 103 1.1.1.6 christos /* Handle syscalls that affect engine behavior. */ 104 1.1.1.6 christos switch (cb_target_to_host_syscall (cb, func)) 105 1.1.1.6 christos { 106 1.1.1.6 christos case CB_SYS_exit: 107 1.1.1.6 christos sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_exited, arg1); 108 1.1.1.6 christos break; 109 1.1.1.6 christos 110 1.1.1.6 christos case CB_SYS_kill: 111 1.1.1.6 christos /* TODO: Need to translate target signal to sim signal, but the sim 112 1.1.1.6 christos doesn't yet have such a mapping layer. */ 113 1.1.1.6 christos if (arg1 == (*cb->getpid) (cb)) 114 1.1.1.6 christos sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_signalled, arg2); 115 1.1 christos break; 116 1.1 christos } 117 1.1 christos 118 1.1 christos *result = sc.result; 119 1.1 christos *result2 = sc.result2; 120 1.1 christos *errcode = sc.errcode; 121 1.1 christos } 122 1.1 christos 123 1.1 christos long 124 1.1 christos sim_syscall (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, long arg4) 125 1.1 christos { 126 1.1 christos long result, result2; 127 1.1 christos int errcode; 128 1.1 christos 129 1.1 christos sim_syscall_multi (cpu, func, arg1, arg2, arg3, arg4, &result, &result2, 130 1.1 christos &errcode); 131 1.1 christos if (result == -1) 132 1.1 christos return -errcode; 133 1.1 christos else 134 return result; 135 } 136