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