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