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