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