[PATCH 47/57][Arm][OBJDUMP] Add support for MVE instructions: vaddv, vmlaldav, vmlada...
[binutils-gdb.git] / sim / m32r / traps-linux.c
bloba4df108a8736a8e07513f6b9f441b926849a134b
1 /* m32r exception, interrupt, and trap (EIT) support
2 Copyright (C) 1998-2019 Free Software Foundation, Inc.
3 Contributed by Renesas.
5 This file is part of GDB, the GNU debugger.
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.
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.
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/>. */
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>
46 #define TRAP_ELF_SYSCALL 0
47 #define TRAP_LINUX_SYSCALL 2
48 #define TRAP_FLUSH_CACHE 12
50 /* The semantic code invokes this for invalid (unrecognized) instructions. */
52 SEM_PC
53 sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
55 SIM_DESC sd = CPU_STATE (current_cpu);
57 #if 0
58 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
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);
67 h_bpc_set (current_cpu, cia);
69 sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
70 EIT_RSVD_INSN_ADDR);
72 else
73 #endif
74 sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
75 return vpc;
78 /* Process an address exception. */
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)
85 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
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)
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);
95 else if (MACH_NUM (CPU_MACH (current_cpu)) == MACH_M32RX)
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);
101 else
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);
107 m32rbf_h_cr_set (current_cpu, H_CR_BPC, cia);
109 sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
110 EIT_ADDR_EXCP_ADDR);
112 else
113 sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
114 transfer, sig);
117 /* Translate target's address to host's address. */
119 static void *
120 t2h_addr (host_callback *cb, struct cb_syscall *sc,
121 unsigned long taddr)
123 void *addr;
124 SIM_DESC sd = (SIM_DESC) sc->p1;
125 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
127 if (taddr == 0)
128 return NULL;
130 return sim_core_trans_addr (sd, cpu, read_map, taddr);
133 static unsigned int
134 conv_endian (unsigned int tvalue)
136 unsigned int hvalue;
137 unsigned int t1, t2, t3, t4;
139 if (HOST_BYTE_ORDER == BFD_ENDIAN_LITTLE)
141 t1 = tvalue & 0xff000000;
142 t2 = tvalue & 0x00ff0000;
143 t3 = tvalue & 0x0000ff00;
144 t4 = tvalue & 0x000000ff;
146 hvalue = t1 >> 24;
147 hvalue += t2 >> 8;
148 hvalue += t3 << 8;
149 hvalue += t4 << 24;
151 else
152 hvalue = tvalue;
154 return hvalue;
157 static unsigned short
158 conv_endian16 (unsigned short tvalue)
160 unsigned short hvalue;
161 unsigned short t1, t2;
163 if (HOST_BYTE_ORDER == BFD_ENDIAN_LITTLE)
165 t1 = tvalue & 0xff00;
166 t2 = tvalue & 0x00ff;
168 hvalue = t1 >> 8;
169 hvalue += t2 << 8;
171 else
172 hvalue = tvalue;
174 return hvalue;
177 static void
178 translate_endian(void *addr, size_t size)
180 unsigned int *p = (unsigned int *) addr;
181 int i;
183 for (i = 0; i <= size - 4; i += 4,p++)
184 *p = conv_endian(*p);
186 if (i <= size - 2)
187 *((unsigned short *) p) = conv_endian16(*((unsigned short *) p));
190 /* Trap support.
191 The result is the pc address to continue at.
192 Preprocessing like saving the various registers has already been done. */
195 m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num)
197 SIM_DESC sd = CPU_STATE (current_cpu);
198 host_callback *cb = STATE_CALLBACK (sd);
200 switch (num)
202 case TRAP_ELF_SYSCALL :
204 long result, result2;
205 int errcode;
207 sim_syscall_multi (current_cpu,
208 m32rbf_h_gr_get (current_cpu, 0),
209 m32rbf_h_gr_get (current_cpu, 1),
210 m32rbf_h_gr_get (current_cpu, 2),
211 m32rbf_h_gr_get (current_cpu, 3),
212 m32rbf_h_gr_get (current_cpu, 4),
213 &result, &result2, &errcode);
215 m32rbf_h_gr_set (current_cpu, 2, errcode);
216 m32rbf_h_gr_set (current_cpu, 0, result);
217 m32rbf_h_gr_set (current_cpu, 1, result2);
218 break;
221 case TRAP_LINUX_SYSCALL :
223 CB_SYSCALL s;
224 unsigned int func, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
225 int result, result2, errcode;
227 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
229 /* The new pc is the trap vector entry.
230 We assume there's a branch there to some handler.
231 Use cr5 as EVB (EIT Vector Base) register. */
232 USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
233 return new_pc;
236 func = m32rbf_h_gr_get (current_cpu, 7);
237 arg1 = m32rbf_h_gr_get (current_cpu, 0);
238 arg2 = m32rbf_h_gr_get (current_cpu, 1);
239 arg3 = m32rbf_h_gr_get (current_cpu, 2);
240 arg4 = m32rbf_h_gr_get (current_cpu, 3);
241 arg5 = m32rbf_h_gr_get (current_cpu, 4);
242 arg6 = m32rbf_h_gr_get (current_cpu, 5);
243 arg7 = m32rbf_h_gr_get (current_cpu, 6);
245 CB_SYSCALL_INIT (&s);
246 s.func = func;
247 s.arg1 = arg1;
248 s.arg2 = arg2;
249 s.arg3 = arg3;
251 s.p1 = (PTR) sd;
252 s.p2 = (PTR) current_cpu;
253 s.read_mem = sim_syscall_read_mem;
254 s.write_mem = sim_syscall_write_mem;
256 result = 0;
257 result2 = 0;
258 errcode = 0;
260 switch (func)
262 case __NR_exit:
263 sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
264 break;
266 case __NR_read:
267 result = read(arg1, t2h_addr(cb, &s, arg2), arg3);
268 errcode = errno;
269 break;
271 case __NR_write:
272 result = write(arg1, t2h_addr(cb, &s, arg2), arg3);
273 errcode = errno;
274 break;
276 case __NR_open:
277 result = open((char *) t2h_addr(cb, &s, arg1), arg2, arg3);
278 errcode = errno;
279 break;
281 case __NR_close:
282 result = close(arg1);
283 errcode = errno;
284 break;
286 case __NR_creat:
287 result = creat((char *) t2h_addr(cb, &s, arg1), arg2);
288 errcode = errno;
289 break;
291 case __NR_link:
292 result = link((char *) t2h_addr(cb, &s, arg1),
293 (char *) t2h_addr(cb, &s, arg2));
294 errcode = errno;
295 break;
297 case __NR_unlink:
298 result = unlink((char *) t2h_addr(cb, &s, arg1));
299 errcode = errno;
300 break;
302 case __NR_chdir:
303 result = chdir((char *) t2h_addr(cb, &s, arg1));
304 errcode = errno;
305 break;
307 case __NR_time:
309 time_t t;
311 if (arg1 == 0)
313 result = (int) time(NULL);
314 errcode = errno;
316 else
318 result = (int) time(&t);
319 errcode = errno;
321 if (result != 0)
322 break;
324 translate_endian((void *) &t, sizeof(t));
325 if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t)) != sizeof(t))
327 result = -1;
328 errcode = EINVAL;
332 break;
334 case __NR_mknod:
335 result = mknod((char *) t2h_addr(cb, &s, arg1),
336 (mode_t) arg2, (dev_t) arg3);
337 errcode = errno;
338 break;
340 case __NR_chmod:
341 result = chmod((char *) t2h_addr(cb, &s, arg1), (mode_t) arg2);
342 errcode = errno;
343 break;
345 case __NR_lchown32:
346 case __NR_lchown:
347 result = lchown((char *) t2h_addr(cb, &s, arg1),
348 (uid_t) arg2, (gid_t) arg3);
349 errcode = errno;
350 break;
352 case __NR_lseek:
353 result = (int) lseek(arg1, (off_t) arg2, arg3);
354 errcode = errno;
355 break;
357 case __NR_getpid:
358 result = getpid();
359 errcode = errno;
360 break;
362 case __NR_getuid32:
363 case __NR_getuid:
364 result = getuid();
365 errcode = errno;
366 break;
368 case __NR_utime:
370 struct utimbuf buf;
372 if (arg2 == 0)
374 result = utime((char *) t2h_addr(cb, &s, arg1), NULL);
375 errcode = errno;
377 else
379 buf = *((struct utimbuf *) t2h_addr(cb, &s, arg2));
380 translate_endian((void *) &buf, sizeof(buf));
381 result = utime((char *) t2h_addr(cb, &s, arg1), &buf);
382 errcode = errno;
385 break;
387 case __NR_access:
388 result = access((char *) t2h_addr(cb, &s, arg1), arg2);
389 errcode = errno;
390 break;
392 case __NR_ftime:
394 struct timeb t;
396 result = ftime(&t);
397 errcode = errno;
399 if (result != 0)
400 break;
402 t.time = conv_endian(t.time);
403 t.millitm = conv_endian16(t.millitm);
404 t.timezone = conv_endian16(t.timezone);
405 t.dstflag = conv_endian16(t.dstflag);
406 if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t))
407 != sizeof(t))
409 result = -1;
410 errcode = EINVAL;
414 case __NR_sync:
415 sync();
416 result = 0;
417 break;
419 case __NR_rename:
420 result = rename((char *) t2h_addr(cb, &s, arg1),
421 (char *) t2h_addr(cb, &s, arg2));
422 errcode = errno;
423 break;
425 case __NR_mkdir:
426 result = mkdir((char *) t2h_addr(cb, &s, arg1), arg2);
427 errcode = errno;
428 break;
430 case __NR_rmdir:
431 result = rmdir((char *) t2h_addr(cb, &s, arg1));
432 errcode = errno;
433 break;
435 case __NR_dup:
436 result = dup(arg1);
437 errcode = errno;
438 break;
440 case __NR_brk:
441 result = brk((void *) arg1);
442 errcode = errno;
443 //result = arg1;
444 break;
446 case __NR_getgid32:
447 case __NR_getgid:
448 result = getgid();
449 errcode = errno;
450 break;
452 case __NR_geteuid32:
453 case __NR_geteuid:
454 result = geteuid();
455 errcode = errno;
456 break;
458 case __NR_getegid32:
459 case __NR_getegid:
460 result = getegid();
461 errcode = errno;
462 break;
464 case __NR_ioctl:
465 result = ioctl(arg1, arg2, arg3);
466 errcode = errno;
467 break;
469 case __NR_fcntl:
470 result = fcntl(arg1, arg2, arg3);
471 errcode = errno;
472 break;
474 case __NR_dup2:
475 result = dup2(arg1, arg2);
476 errcode = errno;
477 break;
479 case __NR_getppid:
480 result = getppid();
481 errcode = errno;
482 break;
484 case __NR_getpgrp:
485 result = getpgrp();
486 errcode = errno;
487 break;
489 case __NR_getrlimit:
491 struct rlimit rlim;
493 result = getrlimit(arg1, &rlim);
494 errcode = errno;
496 if (result != 0)
497 break;
499 translate_endian((void *) &rlim, sizeof(rlim));
500 if ((s.write_mem) (cb, &s, arg2, (char *) &rlim, sizeof(rlim))
501 != sizeof(rlim))
503 result = -1;
504 errcode = EINVAL;
507 break;
509 case __NR_getrusage:
511 struct rusage usage;
513 result = getrusage(arg1, &usage);
514 errcode = errno;
516 if (result != 0)
517 break;
519 translate_endian((void *) &usage, sizeof(usage));
520 if ((s.write_mem) (cb, &s, arg2, (char *) &usage, sizeof(usage))
521 != sizeof(usage))
523 result = -1;
524 errcode = EINVAL;
527 break;
529 case __NR_gettimeofday:
531 struct timeval tv;
532 struct timezone tz;
534 result = gettimeofday(&tv, &tz);
535 errcode = errno;
537 if (result != 0)
538 break;
540 translate_endian((void *) &tv, sizeof(tv));
541 if ((s.write_mem) (cb, &s, arg1, (char *) &tv, sizeof(tv))
542 != sizeof(tv))
544 result = -1;
545 errcode = EINVAL;
548 translate_endian((void *) &tz, sizeof(tz));
549 if ((s.write_mem) (cb, &s, arg2, (char *) &tz, sizeof(tz))
550 != sizeof(tz))
552 result = -1;
553 errcode = EINVAL;
556 break;
558 case __NR_getgroups32:
559 case __NR_getgroups:
561 gid_t *list;
563 if (arg1 > 0)
564 list = (gid_t *) malloc(arg1 * sizeof(gid_t));
566 result = getgroups(arg1, list);
567 errcode = errno;
569 if (result != 0)
570 break;
572 translate_endian((void *) list, arg1 * sizeof(gid_t));
573 if (arg1 > 0)
574 if ((s.write_mem) (cb, &s, arg2, (char *) list, arg1 * sizeof(gid_t))
575 != arg1 * sizeof(gid_t))
577 result = -1;
578 errcode = EINVAL;
581 break;
583 case __NR_select:
585 int n;
586 fd_set readfds;
587 fd_set *treadfdsp;
588 fd_set *hreadfdsp;
589 fd_set writefds;
590 fd_set *twritefdsp;
591 fd_set *hwritefdsp;
592 fd_set exceptfds;
593 fd_set *texceptfdsp;
594 fd_set *hexceptfdsp;
595 struct timeval *ttimeoutp;
596 struct timeval timeout;
598 n = arg1;
600 treadfdsp = (fd_set *) arg2;
601 if (treadfdsp != NULL)
603 readfds = *((fd_set *) t2h_addr(cb, &s, (unsigned int) treadfdsp));
604 translate_endian((void *) &readfds, sizeof(readfds));
605 hreadfdsp = &readfds;
607 else
608 hreadfdsp = NULL;
610 twritefdsp = (fd_set *) arg3;
611 if (twritefdsp != NULL)
613 writefds = *((fd_set *) t2h_addr(cb, &s, (unsigned int) twritefdsp));
614 translate_endian((void *) &writefds, sizeof(writefds));
615 hwritefdsp = &writefds;
617 else
618 hwritefdsp = NULL;
620 texceptfdsp = (fd_set *) arg4;
621 if (texceptfdsp != NULL)
623 exceptfds = *((fd_set *) t2h_addr(cb, &s, (unsigned int) texceptfdsp));
624 translate_endian((void *) &exceptfds, sizeof(exceptfds));
625 hexceptfdsp = &exceptfds;
627 else
628 hexceptfdsp = NULL;
630 ttimeoutp = (struct timeval *) arg5;
631 timeout = *((struct timeval *) t2h_addr(cb, &s, (unsigned int) ttimeoutp));
632 translate_endian((void *) &timeout, sizeof(timeout));
634 result = select(n, hreadfdsp, hwritefdsp, hexceptfdsp, &timeout);
635 errcode = errno;
637 if (result != 0)
638 break;
640 if (treadfdsp != NULL)
642 translate_endian((void *) &readfds, sizeof(readfds));
643 if ((s.write_mem) (cb, &s, (unsigned long) treadfdsp,
644 (char *) &readfds, sizeof(readfds)) != sizeof(readfds))
646 result = -1;
647 errcode = EINVAL;
651 if (twritefdsp != NULL)
653 translate_endian((void *) &writefds, sizeof(writefds));
654 if ((s.write_mem) (cb, &s, (unsigned long) twritefdsp,
655 (char *) &writefds, sizeof(writefds)) != sizeof(writefds))
657 result = -1;
658 errcode = EINVAL;
662 if (texceptfdsp != NULL)
664 translate_endian((void *) &exceptfds, sizeof(exceptfds));
665 if ((s.write_mem) (cb, &s, (unsigned long) texceptfdsp,
666 (char *) &exceptfds, sizeof(exceptfds)) != sizeof(exceptfds))
668 result = -1;
669 errcode = EINVAL;
673 translate_endian((void *) &timeout, sizeof(timeout));
674 if ((s.write_mem) (cb, &s, (unsigned long) ttimeoutp,
675 (char *) &timeout, sizeof(timeout)) != sizeof(timeout))
677 result = -1;
678 errcode = EINVAL;
681 break;
683 case __NR_symlink:
684 result = symlink((char *) t2h_addr(cb, &s, arg1),
685 (char *) t2h_addr(cb, &s, arg2));
686 errcode = errno;
687 break;
689 case __NR_readlink:
690 result = readlink((char *) t2h_addr(cb, &s, arg1),
691 (char *) t2h_addr(cb, &s, arg2),
692 arg3);
693 errcode = errno;
694 break;
696 case __NR_readdir:
697 result = (int) readdir((DIR *) t2h_addr(cb, &s, arg1));
698 errcode = errno;
699 break;
701 #if 0
702 case __NR_mmap:
704 result = (int) mmap((void *) t2h_addr(cb, &s, arg1),
705 arg2, arg3, arg4, arg5, arg6);
706 errcode = errno;
708 if (errno == 0)
710 sim_core_attach (sd, NULL,
711 0, access_read_write_exec, 0,
712 result, arg2, 0, NULL, NULL);
715 break;
716 #endif
717 case __NR_mmap2:
719 void *addr;
720 size_t len;
721 int prot, flags, fildes;
722 off_t off;
724 addr = (void *) t2h_addr(cb, &s, arg1);
725 len = arg2;
726 prot = arg3;
727 flags = arg4;
728 fildes = arg5;
729 off = arg6 << 12;
731 result = (int) mmap(addr, len, prot, flags, fildes, off);
732 errcode = errno;
733 if (result != -1)
735 char c;
736 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
737 sim_core_attach (sd, NULL,
738 0, access_read_write_exec, 0,
739 result, len, 0, NULL, NULL);
742 break;
744 case __NR_mmap:
746 void *addr;
747 size_t len;
748 int prot, flags, fildes;
749 off_t off;
751 addr = *((void **) t2h_addr(cb, &s, arg1));
752 len = *((size_t *) t2h_addr(cb, &s, arg1 + 4));
753 prot = *((int *) t2h_addr(cb, &s, arg1 + 8));
754 flags = *((int *) t2h_addr(cb, &s, arg1 + 12));
755 fildes = *((int *) t2h_addr(cb, &s, arg1 + 16));
756 off = *((off_t *) t2h_addr(cb, &s, arg1 + 20));
758 addr = (void *) conv_endian((unsigned int) addr);
759 len = conv_endian(len);
760 prot = conv_endian(prot);
761 flags = conv_endian(flags);
762 fildes = conv_endian(fildes);
763 off = conv_endian(off);
765 //addr = (void *) t2h_addr(cb, &s, (unsigned int) addr);
766 result = (int) mmap(addr, len, prot, flags, fildes, off);
767 errcode = errno;
769 //if (errno == 0)
770 if (result != -1)
772 char c;
773 if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
774 sim_core_attach (sd, NULL,
775 0, access_read_write_exec, 0,
776 result, len, 0, NULL, NULL);
779 break;
781 case __NR_munmap:
783 result = munmap((void *)arg1, arg2);
784 errcode = errno;
785 if (result != -1)
787 sim_core_detach (sd, NULL, 0, arg2, result);
790 break;
792 case __NR_truncate:
793 result = truncate((char *) t2h_addr(cb, &s, arg1), arg2);
794 errcode = errno;
795 break;
797 case __NR_ftruncate:
798 result = ftruncate(arg1, arg2);
799 errcode = errno;
800 break;
802 case __NR_fchmod:
803 result = fchmod(arg1, arg2);
804 errcode = errno;
805 break;
807 case __NR_fchown32:
808 case __NR_fchown:
809 result = fchown(arg1, arg2, arg3);
810 errcode = errno;
811 break;
813 case __NR_statfs:
815 struct statfs statbuf;
817 result = statfs((char *) t2h_addr(cb, &s, arg1), &statbuf);
818 errcode = errno;
820 if (result != 0)
821 break;
823 translate_endian((void *) &statbuf, sizeof(statbuf));
824 if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf))
825 != sizeof(statbuf))
827 result = -1;
828 errcode = EINVAL;
831 break;
833 case __NR_fstatfs:
835 struct statfs statbuf;
837 result = fstatfs(arg1, &statbuf);
838 errcode = errno;
840 if (result != 0)
841 break;
843 translate_endian((void *) &statbuf, sizeof(statbuf));
844 if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf))
845 != sizeof(statbuf))
847 result = -1;
848 errcode = EINVAL;
851 break;
853 case __NR_syslog:
854 result = syslog(arg1, (char *) t2h_addr(cb, &s, arg2));
855 errcode = errno;
856 break;
858 case __NR_setitimer:
860 struct itimerval value, ovalue;
862 value = *((struct itimerval *) t2h_addr(cb, &s, arg2));
863 translate_endian((void *) &value, sizeof(value));
865 if (arg2 == 0)
867 result = setitimer(arg1, &value, NULL);
868 errcode = errno;
870 else
872 result = setitimer(arg1, &value, &ovalue);
873 errcode = errno;
875 if (result != 0)
876 break;
878 translate_endian((void *) &ovalue, sizeof(ovalue));
879 if ((s.write_mem) (cb, &s, arg3, (char *) &ovalue, sizeof(ovalue))
880 != sizeof(ovalue))
882 result = -1;
883 errcode = EINVAL;
887 break;
889 case __NR_getitimer:
891 struct itimerval value;
893 result = getitimer(arg1, &value);
894 errcode = errno;
896 if (result != 0)
897 break;
899 translate_endian((void *) &value, sizeof(value));
900 if ((s.write_mem) (cb, &s, arg2, (char *) &value, sizeof(value))
901 != sizeof(value))
903 result = -1;
904 errcode = EINVAL;
907 break;
909 case __NR_stat:
911 char *buf;
912 int buflen;
913 struct stat statbuf;
915 result = stat((char *) t2h_addr(cb, &s, arg1), &statbuf);
916 errcode = errno;
917 if (result < 0)
918 break;
920 buflen = cb_host_to_target_stat (cb, NULL, NULL);
921 buf = xmalloc (buflen);
922 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
924 /* The translation failed. This is due to an internal
925 host program error, not the target's fault. */
926 free (buf);
927 result = -1;
928 errcode = ENOSYS;
929 break;
931 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
933 free (buf);
934 result = -1;
935 errcode = EINVAL;
936 break;
938 free (buf);
940 break;
942 case __NR_lstat:
944 char *buf;
945 int buflen;
946 struct stat statbuf;
948 result = lstat((char *) t2h_addr(cb, &s, arg1), &statbuf);
949 errcode = errno;
950 if (result < 0)
951 break;
953 buflen = cb_host_to_target_stat (cb, NULL, NULL);
954 buf = xmalloc (buflen);
955 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
957 /* The translation failed. This is due to an internal
958 host program error, not the target's fault. */
959 free (buf);
960 result = -1;
961 errcode = ENOSYS;
962 break;
964 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
966 free (buf);
967 result = -1;
968 errcode = EINVAL;
969 break;
971 free (buf);
973 break;
975 case __NR_fstat:
977 char *buf;
978 int buflen;
979 struct stat statbuf;
981 result = fstat(arg1, &statbuf);
982 errcode = errno;
983 if (result < 0)
984 break;
986 buflen = cb_host_to_target_stat (cb, NULL, NULL);
987 buf = xmalloc (buflen);
988 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
990 /* The translation failed. This is due to an internal
991 host program error, not the target's fault. */
992 free (buf);
993 result = -1;
994 errcode = ENOSYS;
995 break;
997 if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
999 free (buf);
1000 result = -1;
1001 errcode = EINVAL;
1002 break;
1004 free (buf);
1006 break;
1008 case __NR_sysinfo:
1010 struct sysinfo info;
1012 result = sysinfo(&info);
1013 errcode = errno;
1015 if (result != 0)
1016 break;
1018 info.uptime = conv_endian(info.uptime);
1019 info.loads[0] = conv_endian(info.loads[0]);
1020 info.loads[1] = conv_endian(info.loads[1]);
1021 info.loads[2] = conv_endian(info.loads[2]);
1022 info.totalram = conv_endian(info.totalram);
1023 info.freeram = conv_endian(info.freeram);
1024 info.sharedram = conv_endian(info.sharedram);
1025 info.bufferram = conv_endian(info.bufferram);
1026 info.totalswap = conv_endian(info.totalswap);
1027 info.freeswap = conv_endian(info.freeswap);
1028 info.procs = conv_endian16(info.procs);
1029 #if LINUX_VERSION_CODE >= 0x20400
1030 info.totalhigh = conv_endian(info.totalhigh);
1031 info.freehigh = conv_endian(info.freehigh);
1032 info.mem_unit = conv_endian(info.mem_unit);
1033 #endif
1034 if ((s.write_mem) (cb, &s, arg1, (char *) &info, sizeof(info))
1035 != sizeof(info))
1037 result = -1;
1038 errcode = EINVAL;
1041 break;
1043 #if 0
1044 case __NR_ipc:
1046 result = ipc(arg1, arg2, arg3, arg4,
1047 (void *) t2h_addr(cb, &s, arg5), arg6);
1048 errcode = errno;
1050 break;
1051 #endif
1053 case __NR_fsync:
1054 result = fsync(arg1);
1055 errcode = errno;
1056 break;
1058 case __NR_uname:
1059 /* utsname contains only arrays of char, so it is not necessary
1060 to translate endian. */
1061 result = uname((struct utsname *) t2h_addr(cb, &s, arg1));
1062 errcode = errno;
1063 break;
1065 case __NR_adjtimex:
1067 struct timex buf;
1069 result = adjtimex(&buf);
1070 errcode = errno;
1072 if (result != 0)
1073 break;
1075 translate_endian((void *) &buf, sizeof(buf));
1076 if ((s.write_mem) (cb, &s, arg1, (char *) &buf, sizeof(buf))
1077 != sizeof(buf))
1079 result = -1;
1080 errcode = EINVAL;
1083 break;
1085 case __NR_mprotect:
1086 result = mprotect((void *) arg1, arg2, arg3);
1087 errcode = errno;
1088 break;
1090 case __NR_fchdir:
1091 result = fchdir(arg1);
1092 errcode = errno;
1093 break;
1095 case __NR_setfsuid32:
1096 case __NR_setfsuid:
1097 result = setfsuid(arg1);
1098 errcode = errno;
1099 break;
1101 case __NR_setfsgid32:
1102 case __NR_setfsgid:
1103 result = setfsgid(arg1);
1104 errcode = errno;
1105 break;
1107 #if 0
1108 case __NR__llseek:
1110 loff_t buf;
1112 result = _llseek(arg1, arg2, arg3, &buf, arg5);
1113 errcode = errno;
1115 if (result != 0)
1116 break;
1118 translate_endian((void *) &buf, sizeof(buf));
1119 if ((s.write_mem) (cb, &s, t2h_addr(cb, &s, arg4),
1120 (char *) &buf, sizeof(buf)) != sizeof(buf))
1122 result = -1;
1123 errcode = EINVAL;
1126 break;
1128 case __NR_getdents:
1130 struct dirent dir;
1132 result = getdents(arg1, &dir, arg3);
1133 errcode = errno;
1135 if (result != 0)
1136 break;
1138 dir.d_ino = conv_endian(dir.d_ino);
1139 dir.d_off = conv_endian(dir.d_off);
1140 dir.d_reclen = conv_endian16(dir.d_reclen);
1141 if ((s.write_mem) (cb, &s, arg2, (char *) &dir, sizeof(dir))
1142 != sizeof(dir))
1144 result = -1;
1145 errcode = EINVAL;
1148 break;
1149 #endif
1151 case __NR_flock:
1152 result = flock(arg1, arg2);
1153 errcode = errno;
1154 break;
1156 case __NR_msync:
1157 result = msync((void *) arg1, arg2, arg3);
1158 errcode = errno;
1159 break;
1161 case __NR_readv:
1163 struct iovec vector;
1165 vector = *((struct iovec *) t2h_addr(cb, &s, arg2));
1166 translate_endian((void *) &vector, sizeof(vector));
1168 result = readv(arg1, &vector, arg3);
1169 errcode = errno;
1171 break;
1173 case __NR_writev:
1175 struct iovec vector;
1177 vector = *((struct iovec *) t2h_addr(cb, &s, arg2));
1178 translate_endian((void *) &vector, sizeof(vector));
1180 result = writev(arg1, &vector, arg3);
1181 errcode = errno;
1183 break;
1185 case __NR_fdatasync:
1186 result = fdatasync(arg1);
1187 errcode = errno;
1188 break;
1190 case __NR_mlock:
1191 result = mlock((void *) t2h_addr(cb, &s, arg1), arg2);
1192 errcode = errno;
1193 break;
1195 case __NR_munlock:
1196 result = munlock((void *) t2h_addr(cb, &s, arg1), arg2);
1197 errcode = errno;
1198 break;
1200 case __NR_nanosleep:
1202 struct timespec req, rem;
1204 req = *((struct timespec *) t2h_addr(cb, &s, arg2));
1205 translate_endian((void *) &req, sizeof(req));
1207 result = nanosleep(&req, &rem);
1208 errcode = errno;
1210 if (result != 0)
1211 break;
1213 translate_endian((void *) &rem, sizeof(rem));
1214 if ((s.write_mem) (cb, &s, arg2, (char *) &rem, sizeof(rem))
1215 != sizeof(rem))
1217 result = -1;
1218 errcode = EINVAL;
1221 break;
1223 case __NR_mremap: /* FIXME */
1224 result = (int) mremap((void *) t2h_addr(cb, &s, arg1), arg2, arg3, arg4);
1225 errcode = errno;
1226 break;
1228 case __NR_getresuid32:
1229 case __NR_getresuid:
1231 uid_t ruid, euid, suid;
1233 result = getresuid(&ruid, &euid, &suid);
1234 errcode = errno;
1236 if (result != 0)
1237 break;
1239 *((uid_t *) t2h_addr(cb, &s, arg1)) = conv_endian(ruid);
1240 *((uid_t *) t2h_addr(cb, &s, arg2)) = conv_endian(euid);
1241 *((uid_t *) t2h_addr(cb, &s, arg3)) = conv_endian(suid);
1243 break;
1245 case __NR_poll:
1247 struct pollfd ufds;
1249 ufds = *((struct pollfd *) t2h_addr(cb, &s, arg1));
1250 ufds.fd = conv_endian(ufds.fd);
1251 ufds.events = conv_endian16(ufds.events);
1252 ufds.revents = conv_endian16(ufds.revents);
1254 result = poll(&ufds, arg2, arg3);
1255 errcode = errno;
1257 break;
1259 case __NR_getresgid32:
1260 case __NR_getresgid:
1262 uid_t rgid, egid, sgid;
1264 result = getresgid(&rgid, &egid, &sgid);
1265 errcode = errno;
1267 if (result != 0)
1268 break;
1270 *((uid_t *) t2h_addr(cb, &s, arg1)) = conv_endian(rgid);
1271 *((uid_t *) t2h_addr(cb, &s, arg2)) = conv_endian(egid);
1272 *((uid_t *) t2h_addr(cb, &s, arg3)) = conv_endian(sgid);
1274 break;
1276 case __NR_pread:
1277 result = pread(arg1, (void *) t2h_addr(cb, &s, arg2), arg3, arg4);
1278 errcode = errno;
1279 break;
1281 case __NR_pwrite:
1282 result = pwrite(arg1, (void *) t2h_addr(cb, &s, arg2), arg3, arg4);
1283 errcode = errno;
1284 break;
1286 case __NR_chown32:
1287 case __NR_chown:
1288 result = chown((char *) t2h_addr(cb, &s, arg1), arg2, arg3);
1289 errcode = errno;
1290 break;
1292 case __NR_getcwd:
1293 result = (int) getcwd((char *) t2h_addr(cb, &s, arg1), arg2);
1294 errcode = errno;
1295 break;
1297 case __NR_sendfile:
1299 off_t offset;
1301 offset = *((off_t *) t2h_addr(cb, &s, arg3));
1302 offset = conv_endian(offset);
1304 result = sendfile(arg1, arg2, &offset, arg3);
1305 errcode = errno;
1307 if (result != 0)
1308 break;
1310 *((off_t *) t2h_addr(cb, &s, arg3)) = conv_endian(offset);
1312 break;
1314 default:
1315 result = -1;
1316 errcode = ENOSYS;
1317 break;
1320 if (result == -1)
1321 m32rbf_h_gr_set (current_cpu, 0, -errcode);
1322 else
1323 m32rbf_h_gr_set (current_cpu, 0, result);
1324 break;
1327 case TRAP_BREAKPOINT:
1328 sim_engine_halt (sd, current_cpu, NULL, pc,
1329 sim_stopped, SIM_SIGTRAP);
1330 break;
1332 case TRAP_FLUSH_CACHE:
1333 /* Do nothing. */
1334 break;
1336 default :
1338 /* Use cr5 as EVB (EIT Vector Base) register. */
1339 USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
1340 return new_pc;
1344 /* Fake an "rte" insn. */
1345 /* FIXME: Should duplicate all of rte processing. */
1346 return (pc & -4) + 4;