]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m32r/traps-linux.c
sim: syscall: unify memory 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 {
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;
61a0c964
MF
231 s.read_mem = sim_syscall_read_mem;
232 s.write_mem = sim_syscall_write_mem;
6edf0760
NC
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;
61a0c964
MF
272 s.read_mem = sim_syscall_read_mem;
273 s.write_mem = sim_syscall_write_mem;
6edf0760
NC
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
19e64aa9 364 case __NR_lchown32:
6edf0760
NC
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
19e64aa9 381 case __NR_getuid32:
6edf0760
NC
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
19e64aa9 465 case __NR_getgid32:
6edf0760
NC
466 case __NR_getgid:
467 result = getgid();
468 errcode = errno;
469 break;
470
19e64aa9 471 case __NR_geteuid32:
6edf0760
NC
472 case __NR_geteuid:
473 result = geteuid();
474 errcode = errno;
475 break;
476
19e64aa9 477 case __NR_getegid32:
6edf0760
NC
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
6edf0760
NC
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
19e64aa9 577 case __NR_getgroups32:
6edf0760
NC
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
19e64aa9
KI
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
6edf0760
NC
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
19e64aa9 826 case __NR_fchown32:
6edf0760
NC
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
6edf0760
NC
1109 case __NR_fchdir:
1110 result = fchdir(arg1);
1111 errcode = errno;
1112 break;
1113
19e64aa9 1114 case __NR_setfsuid32:
6edf0760
NC
1115 case __NR_setfsuid:
1116 result = setfsuid(arg1);
1117 errcode = errno;
1118 break;
1119
19e64aa9 1120 case __NR_setfsgid32:
6edf0760
NC
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
19e64aa9 1247 case __NR_getresuid32:
6edf0760
NC
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
19e64aa9 1278 case __NR_getresgid32:
6edf0760
NC
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
19e64aa9 1305 case __NR_chown32:
6edf0760
NC
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}