]>
Commit | Line | Data |
---|---|---|
61a0c964 MF |
1 | /* Simulator system call support. |
2 | ||
1d506c26 | 3 | Copyright 2002-2024 Free Software Foundation, Inc. |
61a0c964 MF |
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 | ||
6df01ab8 MF |
20 | /* This must come before any other includes. */ |
21 | #include "defs.h" | |
61a0c964 | 22 | |
7d5c6c43 MF |
23 | #include <errno.h> |
24 | ||
843bf754 MF |
25 | #include "ansidecl.h" |
26 | ||
61a0c964 MF |
27 | #include "sim-main.h" |
28 | #include "sim-syscall.h" | |
ef5058ae | 29 | #include "sim/callback.h" |
61a0c964 MF |
30 | \f |
31 | /* Read/write functions for system call interface. */ | |
32 | ||
33 | int | |
34 | sim_syscall_read_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc, | |
35 | unsigned long taddr, char *buf, int bytes) | |
36 | { | |
37 | SIM_DESC sd = (SIM_DESC) sc->p1; | |
38 | SIM_CPU *cpu = (SIM_CPU *) sc->p2; | |
39 | ||
40 | TRACE_MEMORY (cpu, "READ (syscall) %i bytes @ 0x%08lx", bytes, taddr); | |
41 | ||
42 | return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes); | |
43 | } | |
44 | ||
45 | int | |
46 | sim_syscall_write_mem (host_callback *cb ATTRIBUTE_UNUSED, struct cb_syscall *sc, | |
47 | unsigned long taddr, const char *buf, int bytes) | |
48 | { | |
49 | SIM_DESC sd = (SIM_DESC) sc->p1; | |
50 | SIM_CPU *cpu = (SIM_CPU *) sc->p2; | |
51 | ||
52 | TRACE_MEMORY (cpu, "WRITE (syscall) %i bytes @ 0x%08lx", bytes, taddr); | |
53 | ||
54 | return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); | |
55 | } | |
7d5c6c43 MF |
56 | \f |
57 | /* Main syscall callback for simulators. */ | |
58 | ||
59 | void | |
60 | sim_syscall_multi (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, | |
61 | long arg4, long *result, long *result2, int *errcode) | |
62 | { | |
63 | SIM_DESC sd = CPU_STATE (cpu); | |
64 | host_callback *cb = STATE_CALLBACK (sd); | |
65 | CB_SYSCALL sc; | |
57b42d64 | 66 | const char unknown_syscall[] = "<UNKNOWN SYSCALL>"; |
7d5c6c43 MF |
67 | const char *syscall; |
68 | ||
69 | CB_SYSCALL_INIT (&sc); | |
70 | ||
71 | sc.func = func; | |
72 | sc.arg1 = arg1; | |
73 | sc.arg2 = arg2; | |
74 | sc.arg3 = arg3; | |
75 | sc.arg4 = arg4; | |
76 | ||
64654371 MF |
77 | sc.p1 = sd; |
78 | sc.p2 = cpu; | |
7d5c6c43 MF |
79 | sc.read_mem = sim_syscall_read_mem; |
80 | sc.write_mem = sim_syscall_write_mem; | |
81 | ||
82 | if (cb_syscall (cb, &sc) != CB_RC_OK) | |
83 | { | |
84 | /* The cb_syscall func never returns an error, so this is more of a | |
85 | sanity check. */ | |
86 | sim_engine_abort (sd, cpu, sim_pc_get (cpu), "cb_syscall failed"); | |
87 | } | |
88 | ||
89 | syscall = cb_target_str_syscall (cb, func); | |
90 | if (!syscall) | |
57b42d64 | 91 | syscall = unknown_syscall; |
7d5c6c43 MF |
92 | |
93 | if (sc.result == -1) | |
94 | TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li (error = %s[%i])", | |
95 | syscall, func, arg1, arg2, arg3, sc.result, | |
96 | cb_target_str_errno (cb, sc.errcode), sc.errcode); | |
97 | else | |
98 | TRACE_SYSCALL (cpu, "%s[%i](%#lx, %#lx, %#lx) = %li", | |
99 | syscall, func, arg1, arg2, arg3, sc.result); | |
100 | ||
2f631626 MF |
101 | /* Handle syscalls that affect engine behavior. */ |
102 | switch (cb_target_to_host_syscall (cb, func)) | |
103 | { | |
104 | case CB_SYS_exit: | |
105 | sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_exited, arg1); | |
106 | break; | |
107 | ||
108 | case CB_SYS_kill: | |
109 | /* TODO: Need to translate target signal to sim signal, but the sim | |
110 | doesn't yet have such a mapping layer. */ | |
111 | if (arg1 == (*cb->getpid) (cb)) | |
112 | sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_signalled, arg2); | |
113 | break; | |
114 | } | |
7d5c6c43 MF |
115 | |
116 | *result = sc.result; | |
117 | *result2 = sc.result2; | |
118 | *errcode = sc.errcode; | |
119 | } | |
120 | ||
121 | long | |
122 | sim_syscall (SIM_CPU *cpu, int func, long arg1, long arg2, long arg3, long arg4) | |
123 | { | |
124 | long result, result2; | |
125 | int errcode; | |
126 | ||
127 | sim_syscall_multi (cpu, func, arg1, arg2, arg3, arg4, &result, &result2, | |
128 | &errcode); | |
129 | if (result == -1) | |
130 | return -errcode; | |
131 | else | |
132 | return result; | |
133 | } |