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