1212397c6Schristos /* Simulator system call support. 2212397c6Schristos 3*88241920Schristos Copyright 2002-2024 Free Software Foundation, Inc. 4212397c6Schristos 5212397c6Schristos This file is part of simulators. 6212397c6Schristos 7212397c6Schristos This program is free software; you can redistribute it and/or modify 8212397c6Schristos it under the terms of the GNU General Public License as published by 9212397c6Schristos the Free Software Foundation; either version 3 of the License, or 10212397c6Schristos (at your option) any later version. 11212397c6Schristos 12212397c6Schristos This program is distributed in the hope that it will be useful, 13212397c6Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14212397c6Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15212397c6Schristos GNU General Public License for more details. 16212397c6Schristos 17212397c6Schristos You should have received a copy of the GNU General Public License 18212397c6Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19212397c6Schristos 204b169a6bSchristos /* This must come before any other includes. */ 214b169a6bSchristos #include "defs.h" 22212397c6Schristos 23212397c6Schristos #include <errno.h> 24212397c6Schristos 254b169a6bSchristos #include "ansidecl.h" 264b169a6bSchristos 27212397c6Schristos #include "sim-main.h" 28212397c6Schristos #include "sim-syscall.h" 294b169a6bSchristos #include "sim/callback.h" 30212397c6Schristos 31212397c6Schristos /* Read/write functions for system call interface. */ 32212397c6Schristos 33212397c6Schristos int 34212397c6Schristos sim_syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc, 35212397c6Schristos unsigned long taddr, char *buf, int bytes) 36212397c6Schristos { 37212397c6Schristos SIM_DESC sd = (SIM_DESC) sc->p1; 38212397c6Schristos SIM_CPU *cpu = (SIM_CPU *) sc->p2; 39212397c6Schristos 40212397c6Schristos TRACE_MEMORY (cpu, "READ (syscall) %i bytes @ 0x%08lx", bytes, taddr); 41212397c6Schristos 42212397c6Schristos return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes); 43212397c6Schristos } 44212397c6Schristos 45212397c6Schristos int 46212397c6Schristos sim_syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc, 47212397c6Schristos unsigned long taddr, const char *buf, int bytes) 48212397c6Schristos { 49212397c6Schristos SIM_DESC sd = (SIM_DESC) sc->p1; 50212397c6Schristos SIM_CPU *cpu = (SIM_CPU *) sc->p2; 51212397c6Schristos 52212397c6Schristos TRACE_MEMORY (cpu, "WRITE (syscall) %i bytes @ 0x%08lx", bytes, taddr); 53212397c6Schristos 54212397c6Schristos return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); 55212397c6Schristos } 56212397c6Schristos 57212397c6Schristos /* Main syscall callback for simulators. */ 58212397c6Schristos 59212397c6Schristos void 60212397c6Schristos sim_syscall_multi (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, 61212397c6Schristos long arg4, long *result, long *result2, int *errcode) 62212397c6Schristos { 63212397c6Schristos SIM_DESC sd = CPU_STATE (cpu); 64212397c6Schristos host_callback *cb = STATE_CALLBACK (sd); 65212397c6Schristos CB_SYSCALL sc; 66212397c6Schristos const char unknown_syscall[] = "<UNKNOWN SYSCALL>"; 67212397c6Schristos const char *syscall; 68212397c6Schristos 69212397c6Schristos CB_SYSCALL_INIT (&sc); 70212397c6Schristos 71212397c6Schristos sc.func = func; 72212397c6Schristos sc.arg1 = arg1; 73212397c6Schristos sc.arg2 = arg2; 74212397c6Schristos sc.arg3 = arg3; 75212397c6Schristos sc.arg4 = arg4; 76212397c6Schristos 774b169a6bSchristos sc.p1 = sd; 784b169a6bSchristos sc.p2 = cpu; 79212397c6Schristos sc.read_mem = sim_syscall_read_mem; 80212397c6Schristos sc.write_mem = sim_syscall_write_mem; 81212397c6Schristos 82212397c6Schristos if (cb_syscall (cb, &sc) != CB_RC_OK) 83212397c6Schristos { 84212397c6Schristos /* The cb_syscall func never returns an error, so this is more of a 85212397c6Schristos sanity check. */ 86212397c6Schristos sim_engine_abort (sd, cpu, sim_pc_get (cpu), "cb_syscall failed"); 87212397c6Schristos } 88212397c6Schristos 89212397c6Schristos syscall = cb_target_str_syscall (cb, func); 90212397c6Schristos if (!syscall) 91212397c6Schristos syscall = unknown_syscall; 92212397c6Schristos 93212397c6Schristos if (sc.result == -1) 94212397c6Schristos TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li (error = %s[%i])", 95212397c6Schristos syscall, func, arg1, arg2, arg3, sc.result, 96212397c6Schristos cb_target_str_errno (cb, sc.errcode), sc.errcode); 97212397c6Schristos else 98212397c6Schristos TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li", 99212397c6Schristos syscall, func, arg1, arg2, arg3, sc.result); 100212397c6Schristos 1014b169a6bSchristos /* Handle syscalls that affect engine behavior. */ 1024b169a6bSchristos switch (cb_target_to_host_syscall (cb, func)) 1034b169a6bSchristos { 1044b169a6bSchristos case CB_SYS_exit: 105212397c6Schristos sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_exited, arg1); 1064b169a6bSchristos break; 1074b169a6bSchristos 1084b169a6bSchristos case CB_SYS_kill: 1094b169a6bSchristos /* TODO: Need to translate target signal to sim signal, but the sim 1104b169a6bSchristos doesn't yet have such a mapping layer. */ 1114b169a6bSchristos if (arg1 == (*cb->getpid) (cb)) 1124b169a6bSchristos sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_signalled, arg2); 1134b169a6bSchristos break; 1144b169a6bSchristos } 115212397c6Schristos 116212397c6Schristos *result = sc.result; 117212397c6Schristos *result2 = sc.result2; 118212397c6Schristos *errcode = sc.errcode; 119212397c6Schristos } 120212397c6Schristos 121212397c6Schristos long 122212397c6Schristos sim_syscall (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, long arg4) 123212397c6Schristos { 124212397c6Schristos long result, result2; 125212397c6Schristos int errcode; 126212397c6Schristos 127212397c6Schristos sim_syscall_multi (cpu, func, arg1, arg2, arg3, arg4, &result, &result2, 128212397c6Schristos &errcode); 129212397c6Schristos if (result == -1) 130212397c6Schristos return -errcode; 131212397c6Schristos else 132212397c6Schristos return result; 133212397c6Schristos } 134