]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m32r/traps.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / sim / m32r / traps.c
CommitLineData
c906108c 1/* m32r exception, interrupt, and trap (EIT) support
1d506c26 2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
fe41f721 3 Contributed by Cygnus Solutions & Renesas.
c906108c 4
16b47b25 5 This file is part of GDB, the GNU debugger.
c906108c 6
16b47b25
NC
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
4744ac1b
JB
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
c906108c 11
16b47b25
NC
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.
c906108c 16
4744ac1b
JB
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/>. */
c906108c 19
6df01ab8
MF
20/* This must come before any other includes. */
21#include "defs.h"
22
fe41f721 23#include "portability.h"
c906108c 24#include "sim-main.h"
1fef66b0 25#include "sim-signal.h"
61a0c964 26#include "sim-syscall.h"
fe41f721
MF
27#include "sim/callback.h"
28#include "syscall.h"
fe41f721
MF
29#include <dirent.h>
30#include <errno.h>
31#include <fcntl.h>
32a046ab 32#include <stdlib.h>
fe41f721
MF
33#include <time.h>
34#include <unistd.h>
35#include <utime.h>
fe7f0b01
MF
36/* TODO: The Linux syscall emulation needs work to support non-Linux hosts.
37 Use an OS hack for now so the CPU emulation is available everywhere.
38 NB: The emulation is also missing argument conversion (endian & bitsize)
39 even on Linux hosts. */
40#ifdef __linux__
9c80f001
MF
41#include <syslog.h>
42#include <sys/file.h>
43#include <sys/fsuid.h>
44#include <sys/ioctl.h>
fe41f721
MF
45#include <sys/mman.h>
46#include <sys/poll.h>
47#include <sys/resource.h>
9c80f001 48#include <sys/sendfile.h>
fe41f721
MF
49#include <sys/sysinfo.h>
50#include <sys/stat.h>
51#include <sys/time.h>
52#include <sys/timeb.h>
53#include <sys/timex.h>
54#include <sys/types.h>
55#include <sys/uio.h>
56#include <sys/utsname.h>
57#include <sys/vfs.h>
58#include <linux/sysctl.h>
59#include <linux/types.h>
60#include <linux/unistd.h>
fe7f0b01 61#endif
c906108c 62
f51d9c6a
MF
63#include "m32r-sim.h"
64
fe41f721 65#define TRAP_LINUX_SYSCALL 2
16b47b25 66#define TRAP_FLUSH_CACHE 12
0b2e03b4 67/* The semantic code invokes this for invalid (unrecognized) instructions. */
c906108c 68
16b47b25
NC
69SEM_PC
70sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC pc)
c906108c
SS
71{
72 SIM_DESC sd = CPU_STATE (current_cpu);
73
74#if 0
75 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
76 {
77 h_bsm_set (current_cpu, h_sm_get (current_cpu));
78 h_bie_set (current_cpu, h_ie_get (current_cpu));
79 h_bcond_set (current_cpu, h_cond_get (current_cpu));
80 /* sm not changed */
81 h_ie_set (current_cpu, 0);
82 h_cond_set (current_cpu, 0);
83
84 h_bpc_set (current_cpu, cia);
85
86 sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
87 EIT_RSVD_INSN_ADDR);
88 }
89 else
90#endif
91 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
16b47b25
NC
92
93 return pc;
c906108c
SS
94}
95
96/* Process an address exception. */
97
98void
99m32r_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
100 unsigned int map, int nr_bytes, address_word addr,
101 transfer_type transfer, sim_core_signals sig)
102{
103 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
104 {
16b47b25
NC
105 m32rbf_h_cr_set (current_cpu, H_CR_BBPC,
106 m32rbf_h_cr_get (current_cpu, H_CR_BPC));
107 switch (MACH_NUM (CPU_MACH (current_cpu)))
108 {
109 case MACH_M32R:
110 m32rbf_h_bpsw_set (current_cpu, m32rbf_h_psw_get (current_cpu));
111 /* sm not changed. */
112 m32rbf_h_psw_set (current_cpu, m32rbf_h_psw_get (current_cpu) & 0x80);
113 break;
114 case MACH_M32RX:
115 m32rxf_h_bpsw_set (current_cpu, m32rxf_h_psw_get (current_cpu));
116 /* sm not changed. */
117 m32rxf_h_psw_set (current_cpu, m32rxf_h_psw_get (current_cpu) & 0x80);
118 break;
119 case MACH_M32R2:
120 m32r2f_h_bpsw_set (current_cpu, m32r2f_h_psw_get (current_cpu));
121 /* sm not changed. */
122 m32r2f_h_psw_set (current_cpu, m32r2f_h_psw_get (current_cpu) & 0x80);
123 break;
124 default:
125 abort ();
126 }
fe41f721 127
16b47b25 128 m32rbf_h_cr_set (current_cpu, H_CR_BPC, cia);
c906108c
SS
129
130 sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
131 EIT_ADDR_EXCP_ADDR);
132 }
133 else
134 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
135 transfer, sig);
136}
137\f
fe41f721
MF
138/* Translate target's address to host's address. */
139
140static void *
141t2h_addr (host_callback *cb, struct cb_syscall *sc,
142 unsigned long taddr)
143{
fe41f721
MF
144 SIM_DESC sd = (SIM_DESC) sc->p1;
145 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
146
147 if (taddr == 0)
148 return NULL;
149
150 return sim_core_trans_addr (sd, cpu, read_map, taddr);
151}
152
153/* TODO: These functions are a big hack and assume that the host runtime has
154 type sizes and struct layouts that match the target. So the Linux emulation
155 probaly only really works in 32-bit runtimes. */
156
157static void
158translate_endian_h2t (void *addr, size_t size)
159{
160 unsigned int *p = (unsigned int *) addr;
161 int i;
162
163 for (i = 0; i <= size - 4; i += 4,p++)
164 *p = H2T_4 (*p);
165
166 if (i <= size - 2)
167 *((unsigned short *) p) = H2T_2 (*((unsigned short *) p));
168}
169
170static void
171translate_endian_t2h (void *addr, size_t size)
172{
173 unsigned int *p = (unsigned int *) addr;
174 int i;
175
176 for (i = 0; i <= size - 4; i += 4,p++)
177 *p = T2H_4 (*p);
178
179 if (i <= size - 2)
180 *((unsigned short *) p) = T2H_2 (*((unsigned short *) p));
181}
182
c906108c
SS
183/* Trap support.
184 The result is the pc address to continue at.
185 Preprocessing like saving the various registers has already been done. */
186
187USI
188m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num)
189{
190 SIM_DESC sd = CPU_STATE (current_cpu);
191 host_callback *cb = STATE_CALLBACK (sd);
192
c906108c 193 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
fe41f721 194 goto case_default;
c906108c
SS
195
196 switch (num)
197 {
fe41f721 198 case TRAP_SYSCALL:
c906108c 199 {
7d5c6c43
MF
200 long result, result2;
201 int errcode;
202
203 sim_syscall_multi (current_cpu,
204 m32rbf_h_gr_get (current_cpu, 0),
205 m32rbf_h_gr_get (current_cpu, 1),
206 m32rbf_h_gr_get (current_cpu, 2),
207 m32rbf_h_gr_get (current_cpu, 3),
208 m32rbf_h_gr_get (current_cpu, 4),
209 &result, &result2, &errcode);
210
211 m32rbf_h_gr_set (current_cpu, 2, errcode);
212 m32rbf_h_gr_set (current_cpu, 0, result);
213 m32rbf_h_gr_set (current_cpu, 1, result2);
c906108c
SS
214 break;
215 }
216
fe7f0b01 217#ifdef __linux__
fe41f721
MF
218 case TRAP_LINUX_SYSCALL:
219 {
220 CB_SYSCALL s;
54af6227 221 unsigned int func, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
c66061f4 222 int result, errcode;
fe41f721
MF
223
224 if (STATE_ENVIRONMENT (sd) != USER_ENVIRONMENT)
225 goto case_default;
226
227 func = m32rbf_h_gr_get (current_cpu, 7);
228 arg1 = m32rbf_h_gr_get (current_cpu, 0);
229 arg2 = m32rbf_h_gr_get (current_cpu, 1);
230 arg3 = m32rbf_h_gr_get (current_cpu, 2);
231 arg4 = m32rbf_h_gr_get (current_cpu, 3);
232 arg5 = m32rbf_h_gr_get (current_cpu, 4);
233 arg6 = m32rbf_h_gr_get (current_cpu, 5);
234 arg7 = m32rbf_h_gr_get (current_cpu, 6);
235
54af6227
MF
236 CB_SYSCALL_INIT (&s);
237 s.func = func;
238 s.arg1 = arg1;
239 s.arg2 = arg2;
240 s.arg3 = arg3;
241 s.arg4 = arg4;
242 s.arg5 = arg5;
243 s.arg6 = arg6;
244 s.arg7 = arg7;
245
845cbaa9
AM
246 s.p1 = sd;
247 s.p2 = current_cpu;
54af6227
MF
248 s.read_mem = sim_syscall_read_mem;
249 s.write_mem = sim_syscall_write_mem;
250
251 result = 0;
54af6227
MF
252 errcode = 0;
253
254 switch (func)
255 {
256 case TARGET_LINUX_SYS_exit:
fe41f721 257 sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
54af6227
MF
258 break;
259
260 case TARGET_LINUX_SYS_read:
261 result = read (arg1, t2h_addr (cb, &s, arg2), arg3);
262 errcode = errno;
263 break;
264
265 case TARGET_LINUX_SYS_write:
266 result = write (arg1, t2h_addr (cb, &s, arg2), arg3);
267 errcode = errno;
268 break;
269
270 case TARGET_LINUX_SYS_open:
271 result = open ((char *) t2h_addr (cb, &s, arg1), arg2, arg3);
272 errcode = errno;
273 break;
274
275 case TARGET_LINUX_SYS_close:
276 result = close (arg1);
277 errcode = errno;
278 break;
279
280 case TARGET_LINUX_SYS_creat:
281 result = creat ((char *) t2h_addr (cb, &s, arg1), arg2);
282 errcode = errno;
283 break;
284
285 case TARGET_LINUX_SYS_link:
286 result = link ((char *) t2h_addr (cb, &s, arg1),
287 (char *) t2h_addr (cb, &s, arg2));
288 errcode = errno;
289 break;
290
291 case TARGET_LINUX_SYS_unlink:
292 result = unlink ((char *) t2h_addr (cb, &s, arg1));
293 errcode = errno;
294 break;
295
296 case TARGET_LINUX_SYS_chdir:
297 result = chdir ((char *) t2h_addr (cb, &s, arg1));
298 errcode = errno;
299 break;
300
301 case TARGET_LINUX_SYS_time:
302 {
303 time_t t;
304
305 if (arg1 == 0)
306 {
307 result = (int) time (NULL);
308 errcode = errno;
309 }
310 else
311 {
312 result = (int) time (&t);
313 errcode = errno;
314
315 if (result != 0)
316 break;
317
318 t = H2T_4 (t);
319 if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t)) != sizeof(t))
320 {
321 result = -1;
322 errcode = EINVAL;
323 }
324 }
325 }
326 break;
327
328 case TARGET_LINUX_SYS_mknod:
329 result = mknod ((char *) t2h_addr (cb, &s, arg1),
330 (mode_t) arg2, (dev_t) arg3);
331 errcode = errno;
332 break;
333
334 case TARGET_LINUX_SYS_chmod:
335 result = chmod ((char *) t2h_addr (cb, &s, arg1), (mode_t) arg2);
336 errcode = errno;
337 break;
338
339 case TARGET_LINUX_SYS_lchown32:
340 case TARGET_LINUX_SYS_lchown:
341 result = lchown ((char *) t2h_addr (cb, &s, arg1),
342 (uid_t) arg2, (gid_t) arg3);
343 errcode = errno;
344 break;
345
346 case TARGET_LINUX_SYS_lseek:
347 result = (int) lseek (arg1, (off_t) arg2, arg3);
348 errcode = errno;
349 break;
350
351 case TARGET_LINUX_SYS_getpid:
352 result = getpid ();
353 errcode = errno;
354 break;
355
356 case TARGET_LINUX_SYS_getuid32:
357 case TARGET_LINUX_SYS_getuid:
358 result = getuid ();
359 errcode = errno;
360 break;
361
362 case TARGET_LINUX_SYS_utime:
363 {
364 struct utimbuf buf;
365
366 if (arg2 == 0)
367 {
368 result = utime ((char *) t2h_addr (cb, &s, arg1), NULL);
369 errcode = errno;
370 }
371 else
372 {
373 buf = *((struct utimbuf *) t2h_addr (cb, &s, arg2));
374 translate_endian_t2h (&buf, sizeof(buf));
375 result = utime ((char *) t2h_addr (cb, &s, arg1), &buf);
376 errcode = errno;
377 }
378 }
379 break;
380
381 case TARGET_LINUX_SYS_access:
382 result = access ((char *) t2h_addr (cb, &s, arg1), arg2);
383 errcode = errno;
384 break;
385
386 case TARGET_LINUX_SYS_ftime:
387 {
388 struct timeb t;
b1f974fa 389 struct timespec ts;
54af6227 390
b1f974fa 391 result = clock_gettime (CLOCK_REALTIME, &ts);
54af6227
MF
392 errcode = errno;
393
394 if (result != 0)
395 break;
396
b1f974fa
MF
397 t.time = H2T_4 (ts.tv_sec);
398 t.millitm = H2T_2 (ts.tv_nsec / 1000000);
399 /* POSIX.1-2001 says the contents of the timezone and dstflag
400 members of tp after a call to ftime() are unspecified. */
401 t.timezone = H2T_2 (0);
402 t.dstflag = H2T_2 (0);
54af6227
MF
403 if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t))
404 != sizeof(t))
405 {
406 result = -1;
407 errcode = EINVAL;
408 }
409 }
dbd4aebe 410 break;
54af6227
MF
411
412 case TARGET_LINUX_SYS_sync:
413 sync ();
414 result = 0;
415 break;
416
417 case TARGET_LINUX_SYS_rename:
418 result = rename ((char *) t2h_addr (cb, &s, arg1),
419 (char *) t2h_addr (cb, &s, arg2));
420 errcode = errno;
421 break;
422
423 case TARGET_LINUX_SYS_mkdir:
424 result = mkdir ((char *) t2h_addr (cb, &s, arg1), arg2);
425 errcode = errno;
426 break;
427
428 case TARGET_LINUX_SYS_rmdir:
429 result = rmdir ((char *) t2h_addr (cb, &s, arg1));
430 errcode = errno;
431 break;
432
433 case TARGET_LINUX_SYS_dup:
434 result = dup (arg1);
435 errcode = errno;
436 break;
437
438 case TARGET_LINUX_SYS_brk:
08a7937f 439 result = brk ((void *) (uintptr_t) arg1);
54af6227
MF
440 errcode = errno;
441 //result = arg1;
442 break;
443
444 case TARGET_LINUX_SYS_getgid32:
445 case TARGET_LINUX_SYS_getgid:
446 result = getgid ();
447 errcode = errno;
448 break;
449
450 case TARGET_LINUX_SYS_geteuid32:
451 case TARGET_LINUX_SYS_geteuid:
452 result = geteuid ();
453 errcode = errno;
454 break;
455
456 case TARGET_LINUX_SYS_getegid32:
457 case TARGET_LINUX_SYS_getegid:
458 result = getegid ();
459 errcode = errno;
460 break;
461
462 case TARGET_LINUX_SYS_ioctl:
463 result = ioctl (arg1, arg2, arg3);
464 errcode = errno;
465 break;
466
467 case TARGET_LINUX_SYS_fcntl:
468 result = fcntl (arg1, arg2, arg3);
469 errcode = errno;
470 break;
471
472 case TARGET_LINUX_SYS_dup2:
473 result = dup2 (arg1, arg2);
474 errcode = errno;
475 break;
476
477 case TARGET_LINUX_SYS_getppid:
478 result = getppid ();
479 errcode = errno;
480 break;
481
482 case TARGET_LINUX_SYS_getpgrp:
483 result = getpgrp ();
484 errcode = errno;
485 break;
486
487 case TARGET_LINUX_SYS_getrlimit:
488 {
489 struct rlimit rlim;
490
491 result = getrlimit (arg1, &rlim);
492 errcode = errno;
493
494 if (result != 0)
495 break;
496
497 translate_endian_h2t (&rlim, sizeof(rlim));
498 if ((s.write_mem) (cb, &s, arg2, (char *) &rlim, sizeof(rlim))
499 != sizeof(rlim))
500 {
501 result = -1;
502 errcode = EINVAL;
503 }
504 }
505 break;
506
507 case TARGET_LINUX_SYS_getrusage:
508 {
509 struct rusage usage;
510
511 result = getrusage (arg1, &usage);
512 errcode = errno;
513
514 if (result != 0)
515 break;
516
517 translate_endian_h2t (&usage, sizeof(usage));
518 if ((s.write_mem) (cb, &s, arg2, (char *) &usage, sizeof(usage))
519 != sizeof(usage))
520 {
521 result = -1;
522 errcode = EINVAL;
523 }
524 }
525 break;
526
527 case TARGET_LINUX_SYS_gettimeofday:
528 {
529 struct timeval tv;
530 struct timezone tz;
531
532 result = gettimeofday (&tv, &tz);
533 errcode = errno;
534
535 if (result != 0)
536 break;
537
538 translate_endian_h2t (&tv, sizeof(tv));
539 if ((s.write_mem) (cb, &s, arg1, (char *) &tv, sizeof(tv))
540 != sizeof(tv))
541 {
542 result = -1;
543 errcode = EINVAL;
544 }
545
546 translate_endian_h2t (&tz, sizeof(tz));
547 if ((s.write_mem) (cb, &s, arg2, (char *) &tz, sizeof(tz))
548 != sizeof(tz))
549 {
550 result = -1;
551 errcode = EINVAL;
552 }
553 }
554 break;
555
556 case TARGET_LINUX_SYS_getgroups32:
557 case TARGET_LINUX_SYS_getgroups:
558 {
45f8296e 559 gid_t *list = NULL;
54af6227
MF
560
561 if (arg1 > 0)
562 list = (gid_t *) malloc (arg1 * sizeof(gid_t));
563
564 result = getgroups (arg1, list);
565 errcode = errno;
566
567 if (result != 0)
568 break;
569
570 translate_endian_h2t (list, arg1 * sizeof(gid_t));
571 if (arg1 > 0)
572 if ((s.write_mem) (cb, &s, arg2, (char *) list, arg1 * sizeof(gid_t))
573 != arg1 * sizeof(gid_t))
574 {
575 result = -1;
576 errcode = EINVAL;
577 }
578 }
579 break;
580
581 case TARGET_LINUX_SYS_select:
582 {
583 int n;
584 fd_set readfds;
08a7937f 585 unsigned int treadfdsp;
54af6227
MF
586 fd_set *hreadfdsp;
587 fd_set writefds;
08a7937f 588 unsigned int twritefdsp;
54af6227
MF
589 fd_set *hwritefdsp;
590 fd_set exceptfds;
08a7937f 591 unsigned int texceptfdsp;
54af6227 592 fd_set *hexceptfdsp;
08a7937f 593 unsigned int ttimeoutp;
54af6227
MF
594 struct timeval timeout;
595
596 n = arg1;
597
08a7937f
MF
598 treadfdsp = arg2;
599 if (treadfdsp !=0)
54af6227 600 {
08a7937f 601 readfds = *((fd_set *) t2h_addr (cb, &s, treadfdsp));
54af6227
MF
602 translate_endian_t2h (&readfds, sizeof(readfds));
603 hreadfdsp = &readfds;
604 }
605 else
606 hreadfdsp = NULL;
607
08a7937f
MF
608 twritefdsp = arg3;
609 if (twritefdsp != 0)
54af6227 610 {
08a7937f 611 writefds = *((fd_set *) t2h_addr (cb, &s, twritefdsp));
54af6227
MF
612 translate_endian_t2h (&writefds, sizeof(writefds));
613 hwritefdsp = &writefds;
614 }
615 else
616 hwritefdsp = NULL;
617
08a7937f
MF
618 texceptfdsp = arg4;
619 if (texceptfdsp != 0)
54af6227 620 {
08a7937f 621 exceptfds = *((fd_set *) t2h_addr (cb, &s, texceptfdsp));
54af6227
MF
622 translate_endian_t2h (&exceptfds, sizeof(exceptfds));
623 hexceptfdsp = &exceptfds;
624 }
625 else
626 hexceptfdsp = NULL;
627
08a7937f
MF
628 ttimeoutp = arg5;
629 timeout = *((struct timeval *) t2h_addr (cb, &s, ttimeoutp));
54af6227
MF
630 translate_endian_t2h (&timeout, sizeof(timeout));
631
632 result = select (n, hreadfdsp, hwritefdsp, hexceptfdsp, &timeout);
633 errcode = errno;
634
635 if (result != 0)
636 break;
637
08a7937f 638 if (treadfdsp != 0)
54af6227
MF
639 {
640 translate_endian_h2t (&readfds, sizeof(readfds));
08a7937f 641 if ((s.write_mem) (cb, &s, treadfdsp,
54af6227
MF
642 (char *) &readfds, sizeof(readfds)) != sizeof(readfds))
643 {
644 result = -1;
645 errcode = EINVAL;
646 }
647 }
648
08a7937f 649 if (twritefdsp != 0)
54af6227
MF
650 {
651 translate_endian_h2t (&writefds, sizeof(writefds));
08a7937f 652 if ((s.write_mem) (cb, &s, twritefdsp,
54af6227
MF
653 (char *) &writefds, sizeof(writefds)) != sizeof(writefds))
654 {
655 result = -1;
656 errcode = EINVAL;
657 }
658 }
659
08a7937f 660 if (texceptfdsp != 0)
54af6227
MF
661 {
662 translate_endian_h2t (&exceptfds, sizeof(exceptfds));
08a7937f 663 if ((s.write_mem) (cb, &s, texceptfdsp,
54af6227
MF
664 (char *) &exceptfds, sizeof(exceptfds)) != sizeof(exceptfds))
665 {
666 result = -1;
667 errcode = EINVAL;
668 }
669 }
670
671 translate_endian_h2t (&timeout, sizeof(timeout));
08a7937f 672 if ((s.write_mem) (cb, &s, ttimeoutp,
54af6227
MF
673 (char *) &timeout, sizeof(timeout)) != sizeof(timeout))
674 {
675 result = -1;
676 errcode = EINVAL;
677 }
678 }
679 break;
680
681 case TARGET_LINUX_SYS_symlink:
682 result = symlink ((char *) t2h_addr (cb, &s, arg1),
683 (char *) t2h_addr (cb, &s, arg2));
684 errcode = errno;
685 break;
686
687 case TARGET_LINUX_SYS_readlink:
688 result = readlink ((char *) t2h_addr (cb, &s, arg1),
689 (char *) t2h_addr (cb, &s, arg2),
690 arg3);
691 errcode = errno;
692 break;
693
694 case TARGET_LINUX_SYS_readdir:
08a7937f 695#if SIZEOF_VOID_P == 4
54af6227
MF
696 result = (int) readdir ((DIR *) t2h_addr (cb, &s, arg1));
697 errcode = errno;
08a7937f
MF
698#else
699 result = 0;
700 errcode = ENOSYS;
701#endif
54af6227 702 break;
fe41f721
MF
703
704#if 0
54af6227
MF
705 case TARGET_LINUX_SYS_mmap:
706 {
707 result = (int) mmap ((void *) t2h_addr (cb, &s, arg1),
708 arg2, arg3, arg4, arg5, arg6);
709 errcode = errno;
710
711 if (errno == 0)
712 {
713 sim_core_attach (sd, NULL,
714 0, access_read_write_exec, 0,
715 result, arg2, 0, NULL, NULL);
716 }
717 }
718 break;
fe41f721 719#endif
54af6227
MF
720 case TARGET_LINUX_SYS_mmap2:
721 {
08a7937f 722#if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */
54af6227
MF
723 void *addr;
724 size_t len;
725 int prot, flags, fildes;
726 off_t off;
727
728 addr = (void *) t2h_addr (cb, &s, arg1);
729 len = arg2;
730 prot = arg3;
731 flags = arg4;
732 fildes = arg5;
733 off = arg6 << 12;
734
735 result = (int) mmap (addr, len, prot, flags, fildes, off);
736 errcode = errno;
737 if (result != -1)
738 {
739 char c;
fe41f721 740 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
54af6227
MF
741 sim_core_attach (sd, NULL,
742 0, access_read_write_exec, 0,
743 result, len, 0, NULL, NULL);
744 }
08a7937f
MF
745#else
746 result = 0;
747 errcode = ENOSYS;
748#endif
54af6227
MF
749 }
750 break;
751
752 case TARGET_LINUX_SYS_mmap:
753 {
08a7937f 754#if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */
54af6227
MF
755 void *addr;
756 size_t len;
757 int prot, flags, fildes;
758 off_t off;
759
760 addr = *((void **) t2h_addr (cb, &s, arg1));
761 len = *((size_t *) t2h_addr (cb, &s, arg1 + 4));
762 prot = *((int *) t2h_addr (cb, &s, arg1 + 8));
763 flags = *((int *) t2h_addr (cb, &s, arg1 + 12));
764 fildes = *((int *) t2h_addr (cb, &s, arg1 + 16));
765 off = *((off_t *) t2h_addr (cb, &s, arg1 + 20));
766
767 addr = (void *) T2H_4 ((unsigned int) addr);
768 len = T2H_4 (len);
769 prot = T2H_4 (prot);
770 flags = T2H_4 (flags);
771 fildes = T2H_4 (fildes);
772 off = T2H_4 (off);
773
774 //addr = (void *) t2h_addr (cb, &s, (unsigned int) addr);
775 result = (int) mmap (addr, len, prot, flags, fildes, off);
776 errcode = errno;
777
778 //if (errno == 0)
779 if (result != -1)
780 {
781 char c;
fe41f721 782 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
54af6227
MF
783 sim_core_attach (sd, NULL,
784 0, access_read_write_exec, 0,
785 result, len, 0, NULL, NULL);
786 }
08a7937f
MF
787#else
788 result = 0;
789 errcode = ENOSYS;
790#endif
54af6227
MF
791 }
792 break;
793
794 case TARGET_LINUX_SYS_munmap:
08a7937f 795 result = munmap ((void *) (uintptr_t) arg1, arg2);
54af6227
MF
796 errcode = errno;
797 if (result != -1)
798 sim_core_detach (sd, NULL, 0, arg2, result);
799 break;
800
801 case TARGET_LINUX_SYS_truncate:
802 result = truncate ((char *) t2h_addr (cb, &s, arg1), arg2);
803 errcode = errno;
804 break;
805
806 case TARGET_LINUX_SYS_ftruncate:
807 result = ftruncate (arg1, arg2);
808 errcode = errno;
809 break;
810
811 case TARGET_LINUX_SYS_fchmod:
812 result = fchmod (arg1, arg2);
813 errcode = errno;
814 break;
815
816 case TARGET_LINUX_SYS_fchown32:
817 case TARGET_LINUX_SYS_fchown:
818 result = fchown (arg1, arg2, arg3);
819 errcode = errno;
820 break;
821
822 case TARGET_LINUX_SYS_statfs:
823 {
824 struct statfs statbuf;
825
826 result = statfs ((char *) t2h_addr (cb, &s, arg1), &statbuf);
827 errcode = errno;
828
829 if (result != 0)
830 break;
831
832 translate_endian_h2t (&statbuf, sizeof(statbuf));
833 if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf))
834 != sizeof(statbuf))
835 {
836 result = -1;
837 errcode = EINVAL;
838 }
839 }
840 break;
841
842 case TARGET_LINUX_SYS_fstatfs:
843 {
844 struct statfs statbuf;
845
846 result = fstatfs (arg1, &statbuf);
847 errcode = errno;
848
849 if (result != 0)
850 break;
851
852 translate_endian_h2t (&statbuf, sizeof(statbuf));
853 if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf))
854 != sizeof(statbuf))
855 {
856 result = -1;
857 errcode = EINVAL;
858 }
859 }
860 break;
861
862 case TARGET_LINUX_SYS_syslog:
c26f7543
MF
863 syslog (arg1, "%s", (char *) t2h_addr (cb, &s, arg2));
864 result = 0;
54af6227
MF
865 errcode = errno;
866 break;
867
868 case TARGET_LINUX_SYS_setitimer:
869 {
870 struct itimerval value, ovalue;
871
872 value = *((struct itimerval *) t2h_addr (cb, &s, arg2));
873 translate_endian_t2h (&value, sizeof(value));
874
875 if (arg2 == 0)
876 {
877 result = setitimer (arg1, &value, NULL);
878 errcode = errno;
879 }
880 else
881 {
882 result = setitimer (arg1, &value, &ovalue);
883 errcode = errno;
884
885 if (result != 0)
886 break;
887
888 translate_endian_h2t (&ovalue, sizeof(ovalue));
889 if ((s.write_mem) (cb, &s, arg3, (char *) &ovalue, sizeof(ovalue))
890 != sizeof(ovalue))
891 {
892 result = -1;
893 errcode = EINVAL;
894 }
895 }
896 }
897 break;
898
899 case TARGET_LINUX_SYS_getitimer:
900 {
901 struct itimerval value;
902
903 result = getitimer (arg1, &value);
904 errcode = errno;
905
906 if (result != 0)
907 break;
908
909 translate_endian_h2t (&value, sizeof(value));
910 if ((s.write_mem) (cb, &s, arg2, (char *) &value, sizeof(value))
911 != sizeof(value))
912 {
913 result = -1;
914 errcode = EINVAL;
915 }
916 }
917 break;
918
919 case TARGET_LINUX_SYS_stat:
920 {
921 char *buf;
922 int buflen;
923 struct stat statbuf;
924
925 result = stat ((char *) t2h_addr (cb, &s, arg1), &statbuf);
926 errcode = errno;
927 if (result < 0)
928 break;
929
930 buflen = cb_host_to_target_stat (cb, NULL, NULL);
931 buf = xmalloc (buflen);
932 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
933 {
934 /* The translation failed. This is due to an internal
935 host program error, not the target's fault. */
936 free (buf);
937 result = -1;
938 errcode = ENOSYS;
939 break;
940 }
941 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
942 {
943 free (buf);
944 result = -1;
945 errcode = EINVAL;
946 break;
947 }
948 free (buf);
949 }
950 break;
951
952 case TARGET_LINUX_SYS_lstat:
953 {
954 char *buf;
955 int buflen;
956 struct stat statbuf;
957
958 result = lstat ((char *) t2h_addr (cb, &s, arg1), &statbuf);
959 errcode = errno;
960 if (result < 0)
961 break;
962
963 buflen = cb_host_to_target_stat (cb, NULL, NULL);
964 buf = xmalloc (buflen);
965 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
966 {
967 /* The translation failed. This is due to an internal
968 host program error, not the target's fault. */
969 free (buf);
970 result = -1;
971 errcode = ENOSYS;
972 break;
973 }
974 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
975 {
976 free (buf);
977 result = -1;
978 errcode = EINVAL;
979 break;
980 }
981 free (buf);
982 }
983 break;
984
985 case TARGET_LINUX_SYS_fstat:
986 {
987 char *buf;
988 int buflen;
989 struct stat statbuf;
990
991 result = fstat (arg1, &statbuf);
992 errcode = errno;
993 if (result < 0)
994 break;
995
996 buflen = cb_host_to_target_stat (cb, NULL, NULL);
997 buf = xmalloc (buflen);
998 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
999 {
1000 /* The translation failed. This is due to an internal
1001 host program error, not the target's fault. */
1002 free (buf);
1003 result = -1;
1004 errcode = ENOSYS;
1005 break;
1006 }
1007 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
1008 {
1009 free (buf);
1010 result = -1;
1011 errcode = EINVAL;
1012 break;
1013 }
1014 free (buf);
1015 }
1016 break;
1017
1018 case TARGET_LINUX_SYS_sysinfo:
1019 {
1020 struct sysinfo info;
1021
1022 result = sysinfo (&info);
1023 errcode = errno;
1024
1025 if (result != 0)
1026 break;
1027
1028 info.uptime = H2T_4 (info.uptime);
1029 info.loads[0] = H2T_4 (info.loads[0]);
1030 info.loads[1] = H2T_4 (info.loads[1]);
1031 info.loads[2] = H2T_4 (info.loads[2]);
1032 info.totalram = H2T_4 (info.totalram);
1033 info.freeram = H2T_4 (info.freeram);
1034 info.sharedram = H2T_4 (info.sharedram);
1035 info.bufferram = H2T_4 (info.bufferram);
1036 info.totalswap = H2T_4 (info.totalswap);
1037 info.freeswap = H2T_4 (info.freeswap);
1038 info.procs = H2T_2 (info.procs);
fe41f721 1039#if LINUX_VERSION_CODE >= 0x20400
54af6227
MF
1040 info.totalhigh = H2T_4 (info.totalhigh);
1041 info.freehigh = H2T_4 (info.freehigh);
1042 info.mem_unit = H2T_4 (info.mem_unit);
fe41f721 1043#endif
54af6227
MF
1044 if ((s.write_mem) (cb, &s, arg1, (char *) &info, sizeof(info))
1045 != sizeof(info))
1046 {
1047 result = -1;
1048 errcode = EINVAL;
1049 }
1050 }
1051 break;
fe41f721
MF
1052
1053#if 0
54af6227
MF
1054 case TARGET_LINUX_SYS_ipc:
1055 {
1056 result = ipc (arg1, arg2, arg3, arg4,
1057 (void *) t2h_addr (cb, &s, arg5), arg6);
1058 errcode = errno;
1059 }
1060 break;
fe41f721
MF
1061#endif
1062
54af6227
MF
1063 case TARGET_LINUX_SYS_fsync:
1064 result = fsync (arg1);
1065 errcode = errno;
1066 break;
1067
1068 case TARGET_LINUX_SYS_uname:
1069 /* utsname contains only arrays of char, so it is not necessary
1070 to translate endian. */
1071 result = uname ((struct utsname *) t2h_addr (cb, &s, arg1));
1072 errcode = errno;
1073 break;
1074
1075 case TARGET_LINUX_SYS_adjtimex:
1076 {
1077 struct timex buf;
1078
1079 result = adjtimex (&buf);
1080 errcode = errno;
1081
1082 if (result != 0)
1083 break;
1084
1085 translate_endian_h2t (&buf, sizeof(buf));
1086 if ((s.write_mem) (cb, &s, arg1, (char *) &buf, sizeof(buf))
1087 != sizeof(buf))
1088 {
1089 result = -1;
1090 errcode = EINVAL;
1091 }
1092 }
1093 break;
1094
1095 case TARGET_LINUX_SYS_mprotect:
08a7937f 1096 result = mprotect ((void *) (uintptr_t) arg1, arg2, arg3);
54af6227
MF
1097 errcode = errno;
1098 break;
1099
1100 case TARGET_LINUX_SYS_fchdir:
1101 result = fchdir (arg1);
1102 errcode = errno;
1103 break;
1104
1105 case TARGET_LINUX_SYS_setfsuid32:
1106 case TARGET_LINUX_SYS_setfsuid:
1107 result = setfsuid (arg1);
1108 errcode = errno;
1109 break;
1110
1111 case TARGET_LINUX_SYS_setfsgid32:
1112 case TARGET_LINUX_SYS_setfsgid:
1113 result = setfsgid (arg1);
1114 errcode = errno;
1115 break;
fe41f721
MF
1116
1117#if 0
54af6227
MF
1118 case TARGET_LINUX_SYS__llseek:
1119 {
1120 loff_t buf;
1121
1122 result = _llseek (arg1, arg2, arg3, &buf, arg5);
1123 errcode = errno;
1124
1125 if (result != 0)
1126 break;
1127
1128 translate_endian_h2t (&buf, sizeof(buf));
1129 if ((s.write_mem) (cb, &s, t2h_addr (cb, &s, arg4),
1130 (char *) &buf, sizeof(buf)) != sizeof(buf))
1131 {
1132 result = -1;
1133 errcode = EINVAL;
1134 }
1135 }
1136 break;
1137
1138 case TARGET_LINUX_SYS_getdents:
1139 {
1140 struct dirent dir;
1141
1142 result = getdents (arg1, &dir, arg3);
1143 errcode = errno;
1144
1145 if (result != 0)
1146 break;
1147
1148 dir.d_ino = H2T_4 (dir.d_ino);
1149 dir.d_off = H2T_4 (dir.d_off);
1150 dir.d_reclen = H2T_2 (dir.d_reclen);
1151 if ((s.write_mem) (cb, &s, arg2, (char *) &dir, sizeof(dir))
1152 != sizeof(dir))
1153 {
1154 result = -1;
1155 errcode = EINVAL;
1156 }
1157 }
1158 break;
fe41f721
MF
1159#endif
1160
54af6227
MF
1161 case TARGET_LINUX_SYS_flock:
1162 result = flock (arg1, arg2);
1163 errcode = errno;
1164 break;
1165
1166 case TARGET_LINUX_SYS_msync:
08a7937f 1167 result = msync ((void *) (uintptr_t) arg1, arg2, arg3);
54af6227
MF
1168 errcode = errno;
1169 break;
1170
1171 case TARGET_LINUX_SYS_readv:
1172 {
1173 struct iovec vector;
1174
1175 vector = *((struct iovec *) t2h_addr (cb, &s, arg2));
1176 translate_endian_t2h (&vector, sizeof(vector));
1177
1178 result = readv (arg1, &vector, arg3);
1179 errcode = errno;
1180 }
1181 break;
1182
1183 case TARGET_LINUX_SYS_writev:
1184 {
1185 struct iovec vector;
1186
1187 vector = *((struct iovec *) t2h_addr (cb, &s, arg2));
1188 translate_endian_t2h (&vector, sizeof(vector));
1189
1190 result = writev (arg1, &vector, arg3);
1191 errcode = errno;
1192 }
1193 break;
1194
1195 case TARGET_LINUX_SYS_fdatasync:
1196 result = fdatasync (arg1);
1197 errcode = errno;
1198 break;
1199
1200 case TARGET_LINUX_SYS_mlock:
1201 result = mlock ((void *) t2h_addr (cb, &s, arg1), arg2);
1202 errcode = errno;
1203 break;
1204
1205 case TARGET_LINUX_SYS_munlock:
1206 result = munlock ((void *) t2h_addr (cb, &s, arg1), arg2);
1207 errcode = errno;
1208 break;
1209
1210 case TARGET_LINUX_SYS_nanosleep:
1211 {
1212 struct timespec req, rem;
1213
1214 req = *((struct timespec *) t2h_addr (cb, &s, arg2));
1215 translate_endian_t2h (&req, sizeof(req));
1216
1217 result = nanosleep (&req, &rem);
1218 errcode = errno;
1219
1220 if (result != 0)
1221 break;
1222
1223 translate_endian_h2t (&rem, sizeof(rem));
1224 if ((s.write_mem) (cb, &s, arg2, (char *) &rem, sizeof(rem))
1225 != sizeof(rem))
1226 {
1227 result = -1;
1228 errcode = EINVAL;
1229 }
1230 }
1231 break;
1232
1233 case TARGET_LINUX_SYS_mremap: /* FIXME */
08a7937f 1234#if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */
54af6227
MF
1235 result = (int) mremap ((void *) t2h_addr (cb, &s, arg1), arg2, arg3, arg4);
1236 errcode = errno;
08a7937f
MF
1237#else
1238 result = -1;
1239 errcode = ENOSYS;
1240#endif
54af6227
MF
1241 break;
1242
1243 case TARGET_LINUX_SYS_getresuid32:
1244 case TARGET_LINUX_SYS_getresuid:
1245 {
1246 uid_t ruid, euid, suid;
1247
1248 result = getresuid (&ruid, &euid, &suid);
1249 errcode = errno;
1250
1251 if (result != 0)
1252 break;
1253
1254 *((uid_t *) t2h_addr (cb, &s, arg1)) = H2T_4 (ruid);
1255 *((uid_t *) t2h_addr (cb, &s, arg2)) = H2T_4 (euid);
1256 *((uid_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (suid);
1257 }
1258 break;
1259
1260 case TARGET_LINUX_SYS_poll:
1261 {
1262 struct pollfd ufds;
1263
1264 ufds = *((struct pollfd *) t2h_addr (cb, &s, arg1));
1265 ufds.fd = T2H_4 (ufds.fd);
1266 ufds.events = T2H_2 (ufds.events);
1267 ufds.revents = T2H_2 (ufds.revents);
1268
1269 result = poll (&ufds, arg2, arg3);
1270 errcode = errno;
1271 }
1272 break;
1273
1274 case TARGET_LINUX_SYS_getresgid32:
1275 case TARGET_LINUX_SYS_getresgid:
1276 {
1277 uid_t rgid, egid, sgid;
1278
1279 result = getresgid (&rgid, &egid, &sgid);
1280 errcode = errno;
1281
1282 if (result != 0)
1283 break;
1284
1285 *((uid_t *) t2h_addr (cb, &s, arg1)) = H2T_4 (rgid);
1286 *((uid_t *) t2h_addr (cb, &s, arg2)) = H2T_4 (egid);
1287 *((uid_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (sgid);
1288 }
1289 break;
1290
1291 case TARGET_LINUX_SYS_pread:
1292 result = pread (arg1, (void *) t2h_addr (cb, &s, arg2), arg3, arg4);
1293 errcode = errno;
1294 break;
1295
1296 case TARGET_LINUX_SYS_pwrite:
1297 result = pwrite (arg1, (void *) t2h_addr (cb, &s, arg2), arg3, arg4);
1298 errcode = errno;
1299 break;
1300
1301 case TARGET_LINUX_SYS_chown32:
1302 case TARGET_LINUX_SYS_chown:
1303 result = chown ((char *) t2h_addr (cb, &s, arg1), arg2, arg3);
1304 errcode = errno;
1305 break;
1306
1307 case TARGET_LINUX_SYS_getcwd:
08a7937f
MF
1308 {
1309 void *ret;
1310
1311 ret = getcwd ((char *) t2h_addr (cb, &s, arg1), arg2);
1312 result = ret == NULL ? 0 : arg1;
1313 errcode = errno;
1314 }
54af6227
MF
1315 break;
1316
1317 case TARGET_LINUX_SYS_sendfile:
1318 {
1319 off_t offset;
1320
1321 offset = *((off_t *) t2h_addr (cb, &s, arg3));
1322 offset = T2H_4 (offset);
1323
1324 result = sendfile (arg1, arg2, &offset, arg3);
1325 errcode = errno;
1326
1327 if (result != 0)
1328 break;
1329
1330 *((off_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (offset);
1331 }
1332 break;
1333
1334 default:
1335 result = -1;
1336 errcode = ENOSYS;
1337 break;
1338 }
1339
1340 if (result == -1)
fe41f721 1341 m32rbf_h_gr_set (current_cpu, 0, -errcode);
54af6227 1342 else
fe41f721
MF
1343 m32rbf_h_gr_set (current_cpu, 0, result);
1344 break;
1345 }
fe7f0b01 1346#endif
fe41f721 1347
c906108c
SS
1348 case TRAP_BREAKPOINT:
1349 sim_engine_halt (sd, current_cpu, NULL, pc,
1350 sim_stopped, SIM_SIGTRAP);
1351 break;
1352
16b47b25
NC
1353 case TRAP_FLUSH_CACHE:
1354 /* Do nothing. */
1355 break;
1356
fe41f721
MF
1357 case_default:
1358 default:
c906108c 1359 {
fe41f721
MF
1360 /* The new pc is the trap vector entry.
1361 We assume there's a branch there to some handler.
1362 Use cr5 as EVB (EIT Vector Base) register. */
16b47b25 1363 /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
fe41f721 1364 USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
c906108c
SS
1365 return new_pc;
1366 }
1367 }
1368
1369 /* Fake an "rte" insn. */
1370 /* FIXME: Should duplicate all of rte processing. */
1371 return (pc & -4) + 4;
1372}