sim-syscall.c revision 1.1.1.3 1 1.1 christos /* Simulator system call support.
2 1.1 christos
3 1.1.1.3 christos Copyright 2002-2017 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 christos #include "config.h"
21 1.1 christos
22 1.1 christos #include <errno.h>
23 1.1 christos
24 1.1 christos #include "sim-main.h"
25 1.1 christos #include "sim-syscall.h"
26 1.1 christos #include "targ-vals.h"
27 1.1 christos
28 1.1 christos /* Read/write functions for system call interface. */
30 1.1 christos
31 1.1 christos int
32 1.1 christos sim_syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc,
33 1.1 christos unsigned long taddr, char *buf, int bytes)
34 1.1 christos {
35 1.1 christos SIM_DESC sd = (SIM_DESC) sc->p1;
36 1.1 christos SIM_CPU *cpu = (SIM_CPU *) sc->p2;
37 1.1 christos
38 1.1 christos TRACE_MEMORY (cpu, "READ (syscall) %i bytes @ 0x%08lx", bytes, taddr);
39 1.1 christos
40 1.1 christos return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
41 1.1 christos }
42 1.1 christos
43 1.1 christos int
44 1.1 christos sim_syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc,
45 1.1 christos unsigned long taddr, const char *buf, int bytes)
46 1.1 christos {
47 1.1 christos SIM_DESC sd = (SIM_DESC) sc->p1;
48 1.1 christos SIM_CPU *cpu = (SIM_CPU *) sc->p2;
49 1.1 christos
50 1.1 christos TRACE_MEMORY (cpu, "WRITE (syscall) %i bytes @ 0x%08lx", bytes, taddr);
51 1.1 christos
52 1.1 christos return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
53 1.1 christos }
54 1.1 christos
55 1.1 christos /* Main syscall callback for simulators. */
57 1.1 christos
58 1.1 christos void
59 1.1 christos sim_syscall_multi (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3,
60 1.1 christos long arg4, long *result, long *result2, int *errcode)
61 1.1 christos {
62 1.1 christos SIM_DESC sd = CPU_STATE (cpu);
63 1.1 christos host_callback *cb = STATE_CALLBACK (sd);
64 1.1 christos CB_SYSCALL sc;
65 1.1 christos const char unknown_syscall[] = "<UNKNOWN SYSCALL>";
66 1.1 christos const char *syscall;
67 1.1 christos
68 1.1 christos CB_SYSCALL_INIT (&sc);
69 1.1 christos
70 1.1 christos sc.func = func;
71 1.1 christos sc.arg1 = arg1;
72 1.1 christos sc.arg2 = arg2;
73 1.1 christos sc.arg3 = arg3;
74 1.1 christos sc.arg4 = arg4;
75 1.1 christos
76 1.1 christos sc.p1 = (PTR) sd;
77 1.1 christos sc.p2 = (PTR) cpu;
78 1.1 christos sc.read_mem = sim_syscall_read_mem;
79 1.1 christos sc.write_mem = sim_syscall_write_mem;
80 1.1 christos
81 1.1 christos if (cb_syscall (cb, &sc) != CB_RC_OK)
82 1.1 christos {
83 1.1 christos /* The cb_syscall func never returns an error, so this is more of a
84 1.1 christos sanity check. */
85 1.1 christos sim_engine_abort (sd, cpu, sim_pc_get (cpu), "cb_syscall failed");
86 1.1 christos }
87 1.1 christos
88 1.1 christos syscall = cb_target_str_syscall (cb, func);
89 1.1 christos if (!syscall)
90 1.1 christos syscall = unknown_syscall;
91 1.1 christos
92 1.1 christos if (sc.result == -1)
93 1.1 christos TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li (error = %s[%i])",
94 1.1 christos syscall, func, arg1, arg2, arg3, sc.result,
95 1.1 christos cb_target_str_errno (cb, sc.errcode), sc.errcode);
96 1.1 christos else
97 1.1 christos TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li",
98 1.1 christos syscall, func, arg1, arg2, arg3, sc.result);
99 1.1 christos
100 1.1 christos if (cb_target_to_host_syscall (cb, func) == CB_SYS_exit)
101 1.1 christos sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_exited, arg1);
102 1.1 christos else if (sc.result == -1)
103 1.1 christos {
104 1.1 christos cb->last_errno = errno;
105 1.1 christos sc.errcode = cb->get_errno (cb);
106 1.1 christos }
107 1.1 christos
108 1.1 christos *result = sc.result;
109 1.1 christos *result2 = sc.result2;
110 1.1 christos *errcode = sc.errcode;
111 1.1 christos }
112 1.1 christos
113 1.1 christos long
114 1.1 christos sim_syscall (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, long arg4)
115 1.1 christos {
116 1.1 christos long result, result2;
117 1.1 christos int errcode;
118 1.1 christos
119 1.1 christos sim_syscall_multi (cpu, func, arg1, arg2, arg3, arg4, &result, &result2,
120 1.1 christos &errcode);
121 1.1 christos if (result == -1)
122 1.1 christos return -errcode;
123 1.1 christos else
124 return result;
125 }
126