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