]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m32c/syscalls.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / sim / m32c / syscalls.c
CommitLineData
d45a4bef
JB
1/* syscalls.c --- implement system calls for the M32C simulator.
2
1d506c26 3Copyright (C) 2005-2024 Free Software Foundation, Inc.
d45a4bef
JB
4Contributed by Red Hat, Inc.
5
6This file is part of the GNU simulators.
7
4744ac1b
JB
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
d45a4bef 12
4744ac1b
JB
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
d45a4bef
JB
17
18You should have received a copy of the GNU General Public License
4744ac1b 19along with this program. If not, see <http://www.gnu.org/licenses/>. */
d45a4bef 20
6df01ab8
MF
21/* This must come before any other includes. */
22#include "defs.h"
23
d45a4bef
JB
24#include <stdio.h>
25#include <stdlib.h>
26#include <fcntl.h>
27#include <unistd.h>
28#include <sys/time.h>
29
df68e12b 30#include "sim/callback.h"
d45a4bef
JB
31
32#include "cpu.h"
33#include "mem.h"
34#include "syscalls.h"
e38330f8 35#include "target-newlib-syscall.h"
d45a4bef
JB
36
37/* The current syscall callbacks we're using. */
38static struct host_callback_struct *callbacks;
39
40void
41set_callbacks (struct host_callback_struct *cb)
42{
43 callbacks = cb;
44}
45
46
47/* A16 ABI: arg1 in r1l (QI) or r1 (HI) or stack
48 arg2 in r2 (HI) or stack
49 arg3..N on stack
50 padding: none
51
52 A24 ABI: arg1 in r0l (QI) or r0 (HI) or stack
53 arg2..N on stack
54 padding: qi->hi
55
56 return value in r0l (QI) r0 (HI) r2r0 (SI)
57 structs: pointer pushed on stack last
58
59*/
60
61int argp, stackp;
62
63static int
64arg (int bytes)
65{
66 int rv = 0;
67 argp++;
68 if (A16)
69 {
70 switch (argp)
71 {
72 case 1:
73 if (bytes == 1)
74 return get_reg (r1l);
75 if (bytes == 2)
76 return get_reg (r1);
77 break;
78 case 2:
79 if (bytes == 2)
80 return get_reg (r2);
81 break;
82 }
83 }
84 else
85 {
86 switch (argp)
87 {
88 case 1:
89 if (bytes == 1)
90 return get_reg (r0l);
91 if (bytes == 2)
92 return get_reg (r0);
93 break;
94 }
95 }
96 if (bytes == 0)
97 bytes = 2;
98 switch (bytes)
99 {
100 case 1:
101 rv = mem_get_qi (get_reg (sp) + stackp);
102 if (A24)
103 stackp++;
104 break;
105 case 2:
106 rv = mem_get_hi (get_reg (sp) + stackp);
107 break;
108 case 3:
109 rv = mem_get_psi (get_reg (sp) + stackp);
110 if (A24)
111 stackp++;
112 break;
113 case 4:
114 rv = mem_get_si (get_reg (sp) + stackp);
115 break;
116 }
117 stackp += bytes;
118 return rv;
119}
120
121static void
122read_target (char *buffer, int address, int count, int asciiz)
123{
124 char byte;
125 while (count > 0)
126 {
127 byte = mem_get_qi (address++);
128 *buffer++ = byte;
129 if (asciiz && (byte == 0))
130 return;
131 count--;
132 }
133}
134
135static void
136write_target (char *buffer, int address, int count, int asciiz)
137{
138 char byte;
139 while (count > 0)
140 {
141 byte = *buffer++;
142 mem_put_qi (address++, byte);
143 if (asciiz && (byte == 0))
144 return;
145 count--;
146 }
147}
148
149#define PTRSZ (A16 ? 2 : 3)
150
151static char *callnames[] = {
152 "SYS_zero",
153 "SYS_exit",
154 "SYS_open",
155 "SYS_close",
156 "SYS_read",
157 "SYS_write",
158 "SYS_lseek",
159 "SYS_unlink",
160 "SYS_getpid",
161 "SYS_kill",
162 "SYS_fstat",
163 "SYS_sbrk",
164 "SYS_argvlen",
165 "SYS_argv",
166 "SYS_chdir",
167 "SYS_stat",
168 "SYS_chmod",
169 "SYS_utime",
170 "SYS_time",
171 "SYS_gettimeofday",
172 "SYS_times",
173 "SYS_link"
174};
175
176void
177m32c_syscall (int id)
178{
179 static char buf[256];
180 int rv;
181
182 argp = 0;
183 stackp = A16 ? 3 : 4;
184 if (trace)
185 printf ("\033[31m/* SYSCALL(%d) = %s */\033[0m\n", id, callnames[id]);
186 switch (id)
187 {
e38330f8 188 case TARGET_NEWLIB_SYS_exit:
d45a4bef
JB
189 {
190 int ec = arg (2);
191 if (verbose)
192 printf ("[exit %d]\n", ec);
193 step_result = M32C_MAKE_EXITED (ec);
194 }
195 break;
196
e38330f8 197 case TARGET_NEWLIB_SYS_open:
d45a4bef
JB
198 {
199 int path = arg (PTRSZ);
200 int oflags = arg (2);
201 int cflags = arg (2);
202
203 read_target (buf, path, 256, 1);
204 if (trace)
205 printf ("open(\"%s\",0x%x,%#o) = ", buf, oflags, cflags);
206
207 if (callbacks)
208 /* The callback vector ignores CFLAGS. */
209 rv = callbacks->open (callbacks, buf, oflags);
210 else
211 {
212 int h_oflags = 0;
213
214 if (oflags & 0x0001)
215 h_oflags |= O_WRONLY;
216 if (oflags & 0x0002)
217 h_oflags |= O_RDWR;
218 if (oflags & 0x0200)
219 h_oflags |= O_CREAT;
220 if (oflags & 0x0008)
221 h_oflags |= O_APPEND;
222 if (oflags & 0x0400)
223 h_oflags |= O_TRUNC;
224 rv = open (buf, h_oflags, cflags);
225 }
226 if (trace)
227 printf ("%d\n", rv);
228 put_reg (r0, rv);
229 }
230 break;
231
e38330f8 232 case TARGET_NEWLIB_SYS_close:
d45a4bef
JB
233 {
234 int fd = arg (2);
235
236 if (callbacks)
237 rv = callbacks->close (callbacks, fd);
238 else if (fd > 2)
239 rv = close (fd);
240 else
241 rv = 0;
242 if (trace)
243 printf ("close(%d) = %d\n", fd, rv);
244 put_reg (r0, rv);
245 }
246 break;
247
e38330f8 248 case TARGET_NEWLIB_SYS_read:
d45a4bef
JB
249 {
250 int fd = arg (2);
251 int addr = arg (PTRSZ);
252 int count = arg (2);
253
254 if (count > sizeof (buf))
255 count = sizeof (buf);
256 if (callbacks)
257 rv = callbacks->read (callbacks, fd, buf, count);
258 else
259 rv = read (fd, buf, count);
260 if (trace)
261 printf ("read(%d,%d) = %d\n", fd, count, rv);
262 if (rv > 0)
263 write_target (buf, addr, rv, 0);
264 put_reg (r0, rv);
265 }
266 break;
267
e38330f8 268 case TARGET_NEWLIB_SYS_write:
d45a4bef
JB
269 {
270 int fd = arg (2);
271 int addr = arg (PTRSZ);
272 int count = arg (2);
273
274 if (count > sizeof (buf))
275 count = sizeof (buf);
276 if (trace)
277 printf ("write(%d,0x%x,%d)\n", fd, addr, count);
278 read_target (buf, addr, count, 0);
279 if (trace)
280 fflush (stdout);
281 if (callbacks)
282 rv = callbacks->write (callbacks, fd, buf, count);
283 else
284 rv = write (fd, buf, count);
285 if (trace)
286 printf ("write(%d,%d) = %d\n", fd, count, rv);
287 put_reg (r0, rv);
288 }
289 break;
290
e38330f8 291 case TARGET_NEWLIB_SYS_getpid:
d45a4bef
JB
292 put_reg (r0, 42);
293 break;
294
e38330f8 295 case TARGET_NEWLIB_SYS_gettimeofday:
d45a4bef
JB
296 {
297 int tvaddr = arg (PTRSZ);
298 struct timeval tv;
299
300 rv = gettimeofday (&tv, 0);
301 if (trace)
33b90f59
ST
302 printf ("gettimeofday: %" PRId64 " sec %" PRId64 " usec to 0x%x\n",
303 (int64_t)tv.tv_sec, (int64_t)tv.tv_usec, tvaddr);
d45a4bef
JB
304 mem_put_si (tvaddr, tv.tv_sec);
305 mem_put_si (tvaddr + 4, tv.tv_usec);
306 put_reg (r0, rv);
307 }
308 break;
309
e38330f8 310 case TARGET_NEWLIB_SYS_kill:
d45a4bef
JB
311 {
312 int pid = arg (2);
313 int sig = arg (2);
314 if (pid == 42)
315 {
316 if (verbose)
317 printf ("[signal %d]\n", sig);
318 step_result = M32C_MAKE_STOPPED (sig);
319 }
320 }
321 break;
322
323 case 11:
324 {
325 int heaptop_arg = arg (PTRSZ);
326 if (trace)
327 printf ("sbrk: heap top set to %x\n", heaptop_arg);
328 heaptop = heaptop_arg;
329 if (heapbottom == 0)
330 heapbottom = heaptop_arg;
331 }
332 break;
333
334 }
335}