testsuite, threads: fix LD_LIBRARY_PATH in 'tls-sepdebug.exp'
[binutils-gdb.git] / sim / m32c / syscalls.c
bloba8f77263ccb00b3af3e3d094d0198f106a0af362
1 /* syscalls.c --- implement system calls for the M32C simulator.
3 Copyright (C) 2005-2024 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* This must come before any other includes. */
22 #include "defs.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <sys/time.h>
30 #include "sim/callback.h"
32 #include "cpu.h"
33 #include "mem.h"
34 #include "syscalls.h"
35 #include "target-newlib-syscall.h"
37 /* The current syscall callbacks we're using. */
38 static struct host_callback_struct *callbacks;
40 void
41 set_callbacks (struct host_callback_struct *cb)
43 callbacks = cb;
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
52 A24 ABI: arg1 in r0l (QI) or r0 (HI) or stack
53 arg2..N on stack
54 padding: qi->hi
56 return value in r0l (QI) r0 (HI) r2r0 (SI)
57 structs: pointer pushed on stack last
61 int argp, stackp;
63 static int
64 arg (int bytes)
66 int rv = 0;
67 argp++;
68 if (A16)
70 switch (argp)
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;
84 else
86 switch (argp)
88 case 1:
89 if (bytes == 1)
90 return get_reg (r0l);
91 if (bytes == 2)
92 return get_reg (r0);
93 break;
96 if (bytes == 0)
97 bytes = 2;
98 switch (bytes)
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;
117 stackp += bytes;
118 return rv;
121 static void
122 read_target (char *buffer, int address, int count, int asciiz)
124 char byte;
125 while (count > 0)
127 byte = mem_get_qi (address++);
128 *buffer++ = byte;
129 if (asciiz && (byte == 0))
130 return;
131 count--;
135 static void
136 write_target (char *buffer, int address, int count, int asciiz)
138 char byte;
139 while (count > 0)
141 byte = *buffer++;
142 mem_put_qi (address++, byte);
143 if (asciiz && (byte == 0))
144 return;
145 count--;
149 #define PTRSZ (A16 ? 2 : 3)
151 static 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"
176 void
177 m32c_syscall (int id)
179 static char buf[256];
180 int rv;
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)
188 case TARGET_NEWLIB_SYS_exit:
190 int ec = arg (2);
191 if (verbose)
192 printf ("[exit %d]\n", ec);
193 step_result = M32C_MAKE_EXITED (ec);
195 break;
197 case TARGET_NEWLIB_SYS_open:
199 int path = arg (PTRSZ);
200 int oflags = arg (2);
201 int cflags = arg (2);
203 read_target (buf, path, 256, 1);
204 if (trace)
205 printf ("open(\"%s\",0x%x,%#o) = ", buf, oflags, cflags);
207 if (callbacks)
208 /* The callback vector ignores CFLAGS. */
209 rv = callbacks->open (callbacks, buf, oflags);
210 else
212 int h_oflags = 0;
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);
226 if (trace)
227 printf ("%d\n", rv);
228 put_reg (r0, rv);
230 break;
232 case TARGET_NEWLIB_SYS_close:
234 int fd = arg (2);
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);
246 break;
248 case TARGET_NEWLIB_SYS_read:
250 int fd = arg (2);
251 int addr = arg (PTRSZ);
252 int count = arg (2);
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);
266 break;
268 case TARGET_NEWLIB_SYS_write:
270 int fd = arg (2);
271 int addr = arg (PTRSZ);
272 int count = arg (2);
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);
289 break;
291 case TARGET_NEWLIB_SYS_getpid:
292 put_reg (r0, 42);
293 break;
295 case TARGET_NEWLIB_SYS_gettimeofday:
297 int tvaddr = arg (PTRSZ);
298 struct timeval tv;
300 rv = gettimeofday (&tv, 0);
301 if (trace)
302 printf ("gettimeofday: %" PRId64 " sec %" PRId64 " usec to 0x%x\n",
303 (int64_t)tv.tv_sec, (int64_t)tv.tv_usec, tvaddr);
304 mem_put_si (tvaddr, tv.tv_sec);
305 mem_put_si (tvaddr + 4, tv.tv_usec);
306 put_reg (r0, rv);
308 break;
310 case TARGET_NEWLIB_SYS_kill:
312 int pid = arg (2);
313 int sig = arg (2);
314 if (pid == 42)
316 if (verbose)
317 printf ("[signal %d]\n", sig);
318 step_result = M32C_MAKE_STOPPED (sig);
321 break;
323 case 11:
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;
332 break;