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