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