Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / sim / rx / syscalls.c
CommitLineData
4f8d4a38
DD
1/* syscalls.c --- implement system calls for the RX simulator.
2
88b9d363 3Copyright (C) 2005-2022 Free Software Foundation, Inc.
4f8d4a38
DD
4Contributed by Red Hat, Inc.
5
6This file is part of the GNU simulators.
7
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.
12
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.
17
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
6df01ab8
MF
21/* This must come before any other includes. */
22#include "defs.h"
4f8d4a38
DD
23
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"
4f8d4a38
DD
31
32#include "cpu.h"
33#include "mem.h"
34#include "syscalls.h"
b3d4da0f 35#include "targ-vals.h"
4f8d4a38
DD
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
d98bfeb0
KB
46struct host_callback_struct *
47get_callbacks (void)
48{
49 return callbacks;
50}
51
4f8d4a38
DD
52
53/* Arguments 1..4 are in R1..R4, remainder on stack.
54
55 Return value in R1..R4 as needed.
56 structs bigger than 16 bytes: pointer pushed on stack last
57
58 We only support arguments that fit in general registers.
59
60 The system call number is in R5. We expect ssycalls to look like
61 this in libgloss:
62
63 _exit:
64 mov #SYS_exit, r5
65 int #255
66 rts
67*/
68
69int argp, stackp;
70
71static int
1c3e93a4 72arg (void)
4f8d4a38
DD
73{
74 int rv = 0;
75 argp++;
76
77 if (argp < 4)
78 return get_reg (argp);
79
80 rv = mem_get_si (get_reg (sp) + stackp);
81 stackp += 4;
82 return rv;
83}
84
85static void
86read_target (char *buffer, int address, int count, int asciiz)
87{
88 char byte;
89 while (count > 0)
90 {
91 byte = mem_get_qi (address++);
92 *buffer++ = byte;
93 if (asciiz && (byte == 0))
94 return;
95 count--;
96 }
97}
98
99static void
100write_target (char *buffer, int address, int count, int asciiz)
101{
102 char byte;
103 while (count > 0)
104 {
105 byte = *buffer++;
106 mem_put_qi (address++, byte);
107 if (asciiz && (byte == 0))
108 return;
109 count--;
110 }
111}
112
113#define PTRSZ (A16 ? 2 : 3)
114
115static char *callnames[] = {
116 "SYS_zero",
117 "SYS_exit",
118 "SYS_open",
119 "SYS_close",
120 "SYS_read",
121 "SYS_write",
122 "SYS_lseek",
123 "SYS_unlink",
124 "SYS_getpid",
125 "SYS_kill",
126 "SYS_fstat",
127 "SYS_sbrk",
128 "SYS_argvlen",
129 "SYS_argv",
130 "SYS_chdir",
131 "SYS_stat",
132 "SYS_chmod",
133 "SYS_utime",
134 "SYS_time",
135 "SYS_gettimeofday",
136 "SYS_times",
137 "SYS_link"
138};
139
140int
141rx_syscall (int id)
142{
143 static char buf[256];
144 int rv;
145
146 argp = 0;
147 stackp = 4;
148 if (trace)
b3d4da0f 149 printf ("\033[31m/* SYSCALL(%d) = %s */\033[0m\n", id, id <= TARGET_SYS_link ? callnames[id] : "unknown");
4f8d4a38
DD
150 switch (id)
151 {
b3d4da0f 152 case TARGET_SYS_exit:
4f8d4a38
DD
153 {
154 int ec = arg ();
155 if (verbose)
156 printf ("[exit %d]\n", ec);
157 return RX_MAKE_EXITED (ec);
158 }
159 break;
160
b3d4da0f 161 case TARGET_SYS_open:
4f8d4a38 162 {
783a7b12 163 int oflags, cflags;
4f8d4a38
DD
164 int path = arg ();
165 /* The open function is defined as taking a variable number of arguments
166 because the third parameter to it is optional:
167 open (const char * filename, int flags, ...);
168 Hence the oflags and cflags arguments will be on the stack and we need
169 to skip the (empty) argument registers r3 and r4. */
170 argp = 4;
783a7b12
AB
171 oflags = arg ();
172 cflags = arg ();
4f8d4a38
DD
173
174 read_target (buf, path, 256, 1);
175 if (trace)
176 printf ("open(\"%s\",0x%x,%#o) = ", buf, oflags, cflags);
177
178 if (callbacks)
179 /* The callback vector ignores CFLAGS. */
180 rv = callbacks->open (callbacks, buf, oflags);
181 else
182 {
183 int h_oflags = 0;
184
185 if (oflags & 0x0001)
186 h_oflags |= O_WRONLY;
187 if (oflags & 0x0002)
188 h_oflags |= O_RDWR;
189 if (oflags & 0x0200)
190 h_oflags |= O_CREAT;
191 if (oflags & 0x0008)
192 h_oflags |= O_APPEND;
193 if (oflags & 0x0400)
194 h_oflags |= O_TRUNC;
195 rv = open (buf, h_oflags, cflags);
196 }
197 if (trace)
198 printf ("%d\n", rv);
199 put_reg (1, rv);
200 }
201 break;
202
b3d4da0f 203 case TARGET_SYS_close:
4f8d4a38
DD
204 {
205 int fd = arg ();
206
207 if (callbacks)
208 rv = callbacks->close (callbacks, fd);
209 else if (fd > 2)
210 rv = close (fd);
211 else
212 rv = 0;
213 if (trace)
214 printf ("close(%d) = %d\n", fd, rv);
215 put_reg (1, rv);
216 }
217 break;
218
b3d4da0f 219 case TARGET_SYS_read:
4f8d4a38
DD
220 {
221 int fd = arg ();
222 int addr = arg ();
223 int count = arg ();
224
225 if (count > sizeof (buf))
226 count = sizeof (buf);
227 if (callbacks)
228 rv = callbacks->read (callbacks, fd, buf, count);
229 else
230 rv = read (fd, buf, count);
231 if (trace)
232 printf ("read(%d,%d) = %d\n", fd, count, rv);
233 if (rv > 0)
234 write_target (buf, addr, rv, 0);
235 put_reg (1, rv);
236 }
237 break;
238
b3d4da0f 239 case TARGET_SYS_write:
4f8d4a38
DD
240 {
241 int fd = arg ();
242 int addr = arg ();
243 int count = arg ();
244
245 if (count > sizeof (buf))
246 count = sizeof (buf);
247 if (trace)
248 printf ("write(%d,0x%x,%d)\n", fd, addr, count);
249 read_target (buf, addr, count, 0);
250 if (trace)
251 fflush (stdout);
252 if (callbacks)
253 rv = callbacks->write (callbacks, fd, buf, count);
254 else
255 rv = write (fd, buf, count);
256 if (trace)
257 printf ("write(%d,%d) = %d\n", fd, count, rv);
258 put_reg (1, rv);
259 }
260 break;
261
b3d4da0f 262 case TARGET_SYS_getpid:
4f8d4a38
DD
263 put_reg (1, 42);
264 break;
265
b3d4da0f 266 case TARGET_SYS_gettimeofday:
4f8d4a38
DD
267 {
268 int tvaddr = arg ();
269 struct timeval tv;
270
271 rv = gettimeofday (&tv, 0);
272 if (trace)
273 printf ("gettimeofday: %ld sec %ld usec to 0x%x\n", tv.tv_sec,
274 tv.tv_usec, tvaddr);
275 mem_put_si (tvaddr, tv.tv_sec);
276 mem_put_si (tvaddr + 4, tv.tv_usec);
277 put_reg (1, rv);
278 }
279 break;
280
b3d4da0f 281 case TARGET_SYS_kill:
4f8d4a38
DD
282 {
283 int pid = arg ();
284 int sig = arg ();
285 if (pid == 42)
286 {
287 if (verbose)
288 printf ("[signal %d]\n", sig);
289 return RX_MAKE_STOPPED (sig);
290 }
291 }
292 break;
293
294 case 11:
295 {
296 int heaptop_arg = arg ();
297 if (trace)
298 printf ("sbrk: heap top set to %x\n", heaptop_arg);
299 heaptop = heaptop_arg;
300 if (heapbottom == 0)
301 heapbottom = heaptop_arg;
302 }
303 break;
304
305 case 255:
306 {
307 int addr = arg ();
308 mem_put_si (addr, rx_cycles + mem_usage_cycles());
309 }
310 break;
311
312 }
313 return RX_MAKE_STEPPED ();
314}
This page took 0.631759 seconds and 4 git commands to generate.