Home | History | Annotate | Line # | Download | only in common
      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