1 /* m32r exception, interrupt, and trap (EIT) support
2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions & 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 /* This must come before any other includes. */
23 #include "portability.h"
25 #include "sim-signal.h"
26 #include "sim-syscall.h"
27 #include "sim/callback.h"
36 /* TODO: The Linux syscall emulation needs work to support non-Linux hosts.
37 Use an OS hack for now so the CPU emulation is available everywhere.
38 NB: The emulation is also missing argument conversion (endian & bitsize)
39 even on Linux hosts. */
43 #include <sys/fsuid.h>
44 #include <sys/ioctl.h>
47 #include <sys/resource.h>
48 #include <sys/sendfile.h>
49 #include <sys/sysinfo.h>
52 #include <sys/timeb.h>
53 #include <sys/timex.h>
54 #include <sys/types.h>
56 #include <sys/utsname.h>
58 #include <linux/sysctl.h>
59 #include <linux/types.h>
60 #include <linux/unistd.h>
65 #define TRAP_LINUX_SYSCALL 2
66 #define TRAP_FLUSH_CACHE 12
67 /* The semantic code invokes this for invalid (unrecognized) instructions. */
70 sim_engine_invalid_insn (SIM_CPU
*current_cpu
, IADDR cia
, SEM_PC pc
)
72 SIM_DESC sd
= CPU_STATE (current_cpu
);
75 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
)
77 h_bsm_set (current_cpu
, h_sm_get (current_cpu
));
78 h_bie_set (current_cpu
, h_ie_get (current_cpu
));
79 h_bcond_set (current_cpu
, h_cond_get (current_cpu
));
81 h_ie_set (current_cpu
, 0);
82 h_cond_set (current_cpu
, 0);
84 h_bpc_set (current_cpu
, cia
);
86 sim_engine_restart (CPU_STATE (current_cpu
), current_cpu
, NULL
,
91 sim_engine_halt (sd
, current_cpu
, NULL
, cia
, sim_stopped
, SIM_SIGILL
);
96 /* Process an address exception. */
99 m32r_core_signal (SIM_DESC sd
, SIM_CPU
*current_cpu
, sim_cia cia
,
100 unsigned int map
, int nr_bytes
, address_word addr
,
101 transfer_type transfer
, sim_core_signals sig
)
103 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
)
105 m32rbf_h_cr_set (current_cpu
, H_CR_BBPC
,
106 m32rbf_h_cr_get (current_cpu
, H_CR_BPC
));
107 switch (MACH_NUM (CPU_MACH (current_cpu
)))
110 m32rbf_h_bpsw_set (current_cpu
, m32rbf_h_psw_get (current_cpu
));
111 /* sm not changed. */
112 m32rbf_h_psw_set (current_cpu
, m32rbf_h_psw_get (current_cpu
) & 0x80);
115 m32rxf_h_bpsw_set (current_cpu
, m32rxf_h_psw_get (current_cpu
));
116 /* sm not changed. */
117 m32rxf_h_psw_set (current_cpu
, m32rxf_h_psw_get (current_cpu
) & 0x80);
120 m32r2f_h_bpsw_set (current_cpu
, m32r2f_h_psw_get (current_cpu
));
121 /* sm not changed. */
122 m32r2f_h_psw_set (current_cpu
, m32r2f_h_psw_get (current_cpu
) & 0x80);
128 m32rbf_h_cr_set (current_cpu
, H_CR_BPC
, cia
);
130 sim_engine_restart (CPU_STATE (current_cpu
), current_cpu
, NULL
,
134 sim_core_signal (sd
, current_cpu
, cia
, map
, nr_bytes
, addr
,
138 /* Translate target's address to host's address. */
141 t2h_addr (host_callback
*cb
, struct cb_syscall
*sc
,
144 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
145 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
150 return sim_core_trans_addr (sd
, cpu
, read_map
, taddr
);
153 /* TODO: These functions are a big hack and assume that the host runtime has
154 type sizes and struct layouts that match the target. So the Linux emulation
155 probaly only really works in 32-bit runtimes. */
158 translate_endian_h2t (void *addr
, size_t size
)
160 unsigned int *p
= (unsigned int *) addr
;
163 for (i
= 0; i
<= size
- 4; i
+= 4,p
++)
167 *((unsigned short *) p
) = H2T_2 (*((unsigned short *) p
));
171 translate_endian_t2h (void *addr
, size_t size
)
173 unsigned int *p
= (unsigned int *) addr
;
176 for (i
= 0; i
<= size
- 4; i
+= 4,p
++)
180 *((unsigned short *) p
) = T2H_2 (*((unsigned short *) p
));
184 The result is the pc address to continue at.
185 Preprocessing like saving the various registers has already been done. */
188 m32r_trap (SIM_CPU
*current_cpu
, PCADDR pc
, int num
)
190 SIM_DESC sd
= CPU_STATE (current_cpu
);
191 host_callback
*cb
= STATE_CALLBACK (sd
);
193 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
)
200 long result
, result2
;
203 sim_syscall_multi (current_cpu
,
204 m32rbf_h_gr_get (current_cpu
, 0),
205 m32rbf_h_gr_get (current_cpu
, 1),
206 m32rbf_h_gr_get (current_cpu
, 2),
207 m32rbf_h_gr_get (current_cpu
, 3),
208 m32rbf_h_gr_get (current_cpu
, 4),
209 &result
, &result2
, &errcode
);
211 m32rbf_h_gr_set (current_cpu
, 2, errcode
);
212 m32rbf_h_gr_set (current_cpu
, 0, result
);
213 m32rbf_h_gr_set (current_cpu
, 1, result2
);
218 case TRAP_LINUX_SYSCALL
:
221 unsigned int func
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
;
224 if (STATE_ENVIRONMENT (sd
) != USER_ENVIRONMENT
)
227 func
= m32rbf_h_gr_get (current_cpu
, 7);
228 arg1
= m32rbf_h_gr_get (current_cpu
, 0);
229 arg2
= m32rbf_h_gr_get (current_cpu
, 1);
230 arg3
= m32rbf_h_gr_get (current_cpu
, 2);
231 arg4
= m32rbf_h_gr_get (current_cpu
, 3);
232 arg5
= m32rbf_h_gr_get (current_cpu
, 4);
233 arg6
= m32rbf_h_gr_get (current_cpu
, 5);
234 arg7
= m32rbf_h_gr_get (current_cpu
, 6);
236 CB_SYSCALL_INIT (&s
);
248 s
.read_mem
= sim_syscall_read_mem
;
249 s
.write_mem
= sim_syscall_write_mem
;
256 case TARGET_LINUX_SYS_exit
:
257 sim_engine_halt (sd
, current_cpu
, NULL
, pc
, sim_exited
, arg1
);
260 case TARGET_LINUX_SYS_read
:
261 result
= read (arg1
, t2h_addr (cb
, &s
, arg2
), arg3
);
265 case TARGET_LINUX_SYS_write
:
266 result
= write (arg1
, t2h_addr (cb
, &s
, arg2
), arg3
);
270 case TARGET_LINUX_SYS_open
:
271 result
= open ((char *) t2h_addr (cb
, &s
, arg1
), arg2
, arg3
);
275 case TARGET_LINUX_SYS_close
:
276 result
= close (arg1
);
280 case TARGET_LINUX_SYS_creat
:
281 result
= creat ((char *) t2h_addr (cb
, &s
, arg1
), arg2
);
285 case TARGET_LINUX_SYS_link
:
286 result
= link ((char *) t2h_addr (cb
, &s
, arg1
),
287 (char *) t2h_addr (cb
, &s
, arg2
));
291 case TARGET_LINUX_SYS_unlink
:
292 result
= unlink ((char *) t2h_addr (cb
, &s
, arg1
));
296 case TARGET_LINUX_SYS_chdir
:
297 result
= chdir ((char *) t2h_addr (cb
, &s
, arg1
));
301 case TARGET_LINUX_SYS_time
:
307 result
= (int) time (NULL
);
312 result
= (int) time (&t
);
319 if ((s
.write_mem
) (cb
, &s
, arg1
, (char *) &t
, sizeof(t
)) != sizeof(t
))
328 case TARGET_LINUX_SYS_mknod
:
329 result
= mknod ((char *) t2h_addr (cb
, &s
, arg1
),
330 (mode_t
) arg2
, (dev_t
) arg3
);
334 case TARGET_LINUX_SYS_chmod
:
335 result
= chmod ((char *) t2h_addr (cb
, &s
, arg1
), (mode_t
) arg2
);
339 case TARGET_LINUX_SYS_lchown32
:
340 case TARGET_LINUX_SYS_lchown
:
341 result
= lchown ((char *) t2h_addr (cb
, &s
, arg1
),
342 (uid_t
) arg2
, (gid_t
) arg3
);
346 case TARGET_LINUX_SYS_lseek
:
347 result
= (int) lseek (arg1
, (off_t
) arg2
, arg3
);
351 case TARGET_LINUX_SYS_getpid
:
356 case TARGET_LINUX_SYS_getuid32
:
357 case TARGET_LINUX_SYS_getuid
:
362 case TARGET_LINUX_SYS_utime
:
368 result
= utime ((char *) t2h_addr (cb
, &s
, arg1
), NULL
);
373 buf
= *((struct utimbuf
*) t2h_addr (cb
, &s
, arg2
));
374 translate_endian_t2h (&buf
, sizeof(buf
));
375 result
= utime ((char *) t2h_addr (cb
, &s
, arg1
), &buf
);
381 case TARGET_LINUX_SYS_access
:
382 result
= access ((char *) t2h_addr (cb
, &s
, arg1
), arg2
);
386 case TARGET_LINUX_SYS_ftime
:
391 result
= clock_gettime (CLOCK_REALTIME
, &ts
);
397 t
.time
= H2T_4 (ts
.tv_sec
);
398 t
.millitm
= H2T_2 (ts
.tv_nsec
/ 1000000);
399 /* POSIX.1-2001 says the contents of the timezone and dstflag
400 members of tp after a call to ftime() are unspecified. */
401 t
.timezone
= H2T_2 (0);
402 t
.dstflag
= H2T_2 (0);
403 if ((s
.write_mem
) (cb
, &s
, arg1
, (char *) &t
, sizeof(t
))
412 case TARGET_LINUX_SYS_sync
:
417 case TARGET_LINUX_SYS_rename
:
418 result
= rename ((char *) t2h_addr (cb
, &s
, arg1
),
419 (char *) t2h_addr (cb
, &s
, arg2
));
423 case TARGET_LINUX_SYS_mkdir
:
424 result
= mkdir ((char *) t2h_addr (cb
, &s
, arg1
), arg2
);
428 case TARGET_LINUX_SYS_rmdir
:
429 result
= rmdir ((char *) t2h_addr (cb
, &s
, arg1
));
433 case TARGET_LINUX_SYS_dup
:
438 case TARGET_LINUX_SYS_brk
:
439 result
= brk ((void *) (uintptr_t) arg1
);
444 case TARGET_LINUX_SYS_getgid32
:
445 case TARGET_LINUX_SYS_getgid
:
450 case TARGET_LINUX_SYS_geteuid32
:
451 case TARGET_LINUX_SYS_geteuid
:
456 case TARGET_LINUX_SYS_getegid32
:
457 case TARGET_LINUX_SYS_getegid
:
462 case TARGET_LINUX_SYS_ioctl
:
463 result
= ioctl (arg1
, arg2
, arg3
);
467 case TARGET_LINUX_SYS_fcntl
:
468 result
= fcntl (arg1
, arg2
, arg3
);
472 case TARGET_LINUX_SYS_dup2
:
473 result
= dup2 (arg1
, arg2
);
477 case TARGET_LINUX_SYS_getppid
:
482 case TARGET_LINUX_SYS_getpgrp
:
487 case TARGET_LINUX_SYS_getrlimit
:
491 result
= getrlimit (arg1
, &rlim
);
497 translate_endian_h2t (&rlim
, sizeof(rlim
));
498 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &rlim
, sizeof(rlim
))
507 case TARGET_LINUX_SYS_getrusage
:
511 result
= getrusage (arg1
, &usage
);
517 translate_endian_h2t (&usage
, sizeof(usage
));
518 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &usage
, sizeof(usage
))
527 case TARGET_LINUX_SYS_gettimeofday
:
532 result
= gettimeofday (&tv
, &tz
);
538 translate_endian_h2t (&tv
, sizeof(tv
));
539 if ((s
.write_mem
) (cb
, &s
, arg1
, (char *) &tv
, sizeof(tv
))
546 translate_endian_h2t (&tz
, sizeof(tz
));
547 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &tz
, sizeof(tz
))
556 case TARGET_LINUX_SYS_getgroups32
:
557 case TARGET_LINUX_SYS_getgroups
:
562 list
= (gid_t
*) malloc (arg1
* sizeof(gid_t
));
564 result
= getgroups (arg1
, list
);
570 translate_endian_h2t (list
, arg1
* sizeof(gid_t
));
572 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) list
, arg1
* sizeof(gid_t
))
573 != arg1
* sizeof(gid_t
))
581 case TARGET_LINUX_SYS_select
:
585 unsigned int treadfdsp
;
588 unsigned int twritefdsp
;
591 unsigned int texceptfdsp
;
593 unsigned int ttimeoutp
;
594 struct timeval timeout
;
601 readfds
= *((fd_set
*) t2h_addr (cb
, &s
, treadfdsp
));
602 translate_endian_t2h (&readfds
, sizeof(readfds
));
603 hreadfdsp
= &readfds
;
611 writefds
= *((fd_set
*) t2h_addr (cb
, &s
, twritefdsp
));
612 translate_endian_t2h (&writefds
, sizeof(writefds
));
613 hwritefdsp
= &writefds
;
619 if (texceptfdsp
!= 0)
621 exceptfds
= *((fd_set
*) t2h_addr (cb
, &s
, texceptfdsp
));
622 translate_endian_t2h (&exceptfds
, sizeof(exceptfds
));
623 hexceptfdsp
= &exceptfds
;
629 timeout
= *((struct timeval
*) t2h_addr (cb
, &s
, ttimeoutp
));
630 translate_endian_t2h (&timeout
, sizeof(timeout
));
632 result
= select (n
, hreadfdsp
, hwritefdsp
, hexceptfdsp
, &timeout
);
640 translate_endian_h2t (&readfds
, sizeof(readfds
));
641 if ((s
.write_mem
) (cb
, &s
, treadfdsp
,
642 (char *) &readfds
, sizeof(readfds
)) != sizeof(readfds
))
651 translate_endian_h2t (&writefds
, sizeof(writefds
));
652 if ((s
.write_mem
) (cb
, &s
, twritefdsp
,
653 (char *) &writefds
, sizeof(writefds
)) != sizeof(writefds
))
660 if (texceptfdsp
!= 0)
662 translate_endian_h2t (&exceptfds
, sizeof(exceptfds
));
663 if ((s
.write_mem
) (cb
, &s
, texceptfdsp
,
664 (char *) &exceptfds
, sizeof(exceptfds
)) != sizeof(exceptfds
))
671 translate_endian_h2t (&timeout
, sizeof(timeout
));
672 if ((s
.write_mem
) (cb
, &s
, ttimeoutp
,
673 (char *) &timeout
, sizeof(timeout
)) != sizeof(timeout
))
681 case TARGET_LINUX_SYS_symlink
:
682 result
= symlink ((char *) t2h_addr (cb
, &s
, arg1
),
683 (char *) t2h_addr (cb
, &s
, arg2
));
687 case TARGET_LINUX_SYS_readlink
:
688 result
= readlink ((char *) t2h_addr (cb
, &s
, arg1
),
689 (char *) t2h_addr (cb
, &s
, arg2
),
694 case TARGET_LINUX_SYS_readdir
:
695 #if SIZEOF_VOID_P == 4
696 result
= (int) readdir ((DIR *) t2h_addr (cb
, &s
, arg1
));
705 case TARGET_LINUX_SYS_mmap
:
707 result
= (int) mmap ((void *) t2h_addr (cb
, &s
, arg1
),
708 arg2
, arg3
, arg4
, arg5
, arg6
);
713 sim_core_attach (sd
, NULL
,
714 0, access_read_write_exec
, 0,
715 result
, arg2
, 0, NULL
, NULL
);
720 case TARGET_LINUX_SYS_mmap2
:
722 #if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */
725 int prot
, flags
, fildes
;
728 addr
= (void *) t2h_addr (cb
, &s
, arg1
);
735 result
= (int) mmap (addr
, len
, prot
, flags
, fildes
, off
);
740 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, result
, 1) == 0)
741 sim_core_attach (sd
, NULL
,
742 0, access_read_write_exec
, 0,
743 result
, len
, 0, NULL
, NULL
);
752 case TARGET_LINUX_SYS_mmap
:
754 #if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */
757 int prot
, flags
, fildes
;
760 addr
= *((void **) t2h_addr (cb
, &s
, arg1
));
761 len
= *((size_t *) t2h_addr (cb
, &s
, arg1
+ 4));
762 prot
= *((int *) t2h_addr (cb
, &s
, arg1
+ 8));
763 flags
= *((int *) t2h_addr (cb
, &s
, arg1
+ 12));
764 fildes
= *((int *) t2h_addr (cb
, &s
, arg1
+ 16));
765 off
= *((off_t
*) t2h_addr (cb
, &s
, arg1
+ 20));
767 addr
= (void *) T2H_4 ((unsigned int) addr
);
770 flags
= T2H_4 (flags
);
771 fildes
= T2H_4 (fildes
);
774 //addr = (void *) t2h_addr (cb, &s, (unsigned int) addr);
775 result
= (int) mmap (addr
, len
, prot
, flags
, fildes
, off
);
782 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, result
, 1) == 0)
783 sim_core_attach (sd
, NULL
,
784 0, access_read_write_exec
, 0,
785 result
, len
, 0, NULL
, NULL
);
794 case TARGET_LINUX_SYS_munmap
:
795 result
= munmap ((void *) (uintptr_t) arg1
, arg2
);
798 sim_core_detach (sd
, NULL
, 0, arg2
, result
);
801 case TARGET_LINUX_SYS_truncate
:
802 result
= truncate ((char *) t2h_addr (cb
, &s
, arg1
), arg2
);
806 case TARGET_LINUX_SYS_ftruncate
:
807 result
= ftruncate (arg1
, arg2
);
811 case TARGET_LINUX_SYS_fchmod
:
812 result
= fchmod (arg1
, arg2
);
816 case TARGET_LINUX_SYS_fchown32
:
817 case TARGET_LINUX_SYS_fchown
:
818 result
= fchown (arg1
, arg2
, arg3
);
822 case TARGET_LINUX_SYS_statfs
:
824 struct statfs statbuf
;
826 result
= statfs ((char *) t2h_addr (cb
, &s
, arg1
), &statbuf
);
832 translate_endian_h2t (&statbuf
, sizeof(statbuf
));
833 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &statbuf
, sizeof(statbuf
))
842 case TARGET_LINUX_SYS_fstatfs
:
844 struct statfs statbuf
;
846 result
= fstatfs (arg1
, &statbuf
);
852 translate_endian_h2t (&statbuf
, sizeof(statbuf
));
853 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &statbuf
, sizeof(statbuf
))
862 case TARGET_LINUX_SYS_syslog
:
863 syslog (arg1
, "%s", (char *) t2h_addr (cb
, &s
, arg2
));
868 case TARGET_LINUX_SYS_setitimer
:
870 struct itimerval value
, ovalue
;
872 value
= *((struct itimerval
*) t2h_addr (cb
, &s
, arg2
));
873 translate_endian_t2h (&value
, sizeof(value
));
877 result
= setitimer (arg1
, &value
, NULL
);
882 result
= setitimer (arg1
, &value
, &ovalue
);
888 translate_endian_h2t (&ovalue
, sizeof(ovalue
));
889 if ((s
.write_mem
) (cb
, &s
, arg3
, (char *) &ovalue
, sizeof(ovalue
))
899 case TARGET_LINUX_SYS_getitimer
:
901 struct itimerval value
;
903 result
= getitimer (arg1
, &value
);
909 translate_endian_h2t (&value
, sizeof(value
));
910 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &value
, sizeof(value
))
919 case TARGET_LINUX_SYS_stat
:
925 result
= stat ((char *) t2h_addr (cb
, &s
, arg1
), &statbuf
);
930 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
931 buf
= xmalloc (buflen
);
932 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
934 /* The translation failed. This is due to an internal
935 host program error, not the target's fault. */
941 if ((s
.write_mem
) (cb
, &s
, arg2
, buf
, buflen
) != buflen
)
952 case TARGET_LINUX_SYS_lstat
:
958 result
= lstat ((char *) t2h_addr (cb
, &s
, arg1
), &statbuf
);
963 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
964 buf
= xmalloc (buflen
);
965 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
967 /* The translation failed. This is due to an internal
968 host program error, not the target's fault. */
974 if ((s
.write_mem
) (cb
, &s
, arg2
, buf
, buflen
) != buflen
)
985 case TARGET_LINUX_SYS_fstat
:
991 result
= fstat (arg1
, &statbuf
);
996 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
997 buf
= xmalloc (buflen
);
998 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
1000 /* The translation failed. This is due to an internal
1001 host program error, not the target's fault. */
1007 if ((s
.write_mem
) (cb
, &s
, arg2
, buf
, buflen
) != buflen
)
1018 case TARGET_LINUX_SYS_sysinfo
:
1020 struct sysinfo info
;
1022 result
= sysinfo (&info
);
1028 info
.uptime
= H2T_4 (info
.uptime
);
1029 info
.loads
[0] = H2T_4 (info
.loads
[0]);
1030 info
.loads
[1] = H2T_4 (info
.loads
[1]);
1031 info
.loads
[2] = H2T_4 (info
.loads
[2]);
1032 info
.totalram
= H2T_4 (info
.totalram
);
1033 info
.freeram
= H2T_4 (info
.freeram
);
1034 info
.sharedram
= H2T_4 (info
.sharedram
);
1035 info
.bufferram
= H2T_4 (info
.bufferram
);
1036 info
.totalswap
= H2T_4 (info
.totalswap
);
1037 info
.freeswap
= H2T_4 (info
.freeswap
);
1038 info
.procs
= H2T_2 (info
.procs
);
1039 #if LINUX_VERSION_CODE >= 0x20400
1040 info
.totalhigh
= H2T_4 (info
.totalhigh
);
1041 info
.freehigh
= H2T_4 (info
.freehigh
);
1042 info
.mem_unit
= H2T_4 (info
.mem_unit
);
1044 if ((s
.write_mem
) (cb
, &s
, arg1
, (char *) &info
, sizeof(info
))
1054 case TARGET_LINUX_SYS_ipc
:
1056 result
= ipc (arg1
, arg2
, arg3
, arg4
,
1057 (void *) t2h_addr (cb
, &s
, arg5
), arg6
);
1063 case TARGET_LINUX_SYS_fsync
:
1064 result
= fsync (arg1
);
1068 case TARGET_LINUX_SYS_uname
:
1069 /* utsname contains only arrays of char, so it is not necessary
1070 to translate endian. */
1071 result
= uname ((struct utsname
*) t2h_addr (cb
, &s
, arg1
));
1075 case TARGET_LINUX_SYS_adjtimex
:
1079 result
= adjtimex (&buf
);
1085 translate_endian_h2t (&buf
, sizeof(buf
));
1086 if ((s
.write_mem
) (cb
, &s
, arg1
, (char *) &buf
, sizeof(buf
))
1095 case TARGET_LINUX_SYS_mprotect
:
1096 result
= mprotect ((void *) (uintptr_t) arg1
, arg2
, arg3
);
1100 case TARGET_LINUX_SYS_fchdir
:
1101 result
= fchdir (arg1
);
1105 case TARGET_LINUX_SYS_setfsuid32
:
1106 case TARGET_LINUX_SYS_setfsuid
:
1107 result
= setfsuid (arg1
);
1111 case TARGET_LINUX_SYS_setfsgid32
:
1112 case TARGET_LINUX_SYS_setfsgid
:
1113 result
= setfsgid (arg1
);
1118 case TARGET_LINUX_SYS__llseek
:
1122 result
= _llseek (arg1
, arg2
, arg3
, &buf
, arg5
);
1128 translate_endian_h2t (&buf
, sizeof(buf
));
1129 if ((s
.write_mem
) (cb
, &s
, t2h_addr (cb
, &s
, arg4
),
1130 (char *) &buf
, sizeof(buf
)) != sizeof(buf
))
1138 case TARGET_LINUX_SYS_getdents
:
1142 result
= getdents (arg1
, &dir
, arg3
);
1148 dir
.d_ino
= H2T_4 (dir
.d_ino
);
1149 dir
.d_off
= H2T_4 (dir
.d_off
);
1150 dir
.d_reclen
= H2T_2 (dir
.d_reclen
);
1151 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &dir
, sizeof(dir
))
1161 case TARGET_LINUX_SYS_flock
:
1162 result
= flock (arg1
, arg2
);
1166 case TARGET_LINUX_SYS_msync
:
1167 result
= msync ((void *) (uintptr_t) arg1
, arg2
, arg3
);
1171 case TARGET_LINUX_SYS_readv
:
1173 struct iovec vector
;
1175 vector
= *((struct iovec
*) t2h_addr (cb
, &s
, arg2
));
1176 translate_endian_t2h (&vector
, sizeof(vector
));
1178 result
= readv (arg1
, &vector
, arg3
);
1183 case TARGET_LINUX_SYS_writev
:
1185 struct iovec vector
;
1187 vector
= *((struct iovec
*) t2h_addr (cb
, &s
, arg2
));
1188 translate_endian_t2h (&vector
, sizeof(vector
));
1190 result
= writev (arg1
, &vector
, arg3
);
1195 case TARGET_LINUX_SYS_fdatasync
:
1196 result
= fdatasync (arg1
);
1200 case TARGET_LINUX_SYS_mlock
:
1201 result
= mlock ((void *) t2h_addr (cb
, &s
, arg1
), arg2
);
1205 case TARGET_LINUX_SYS_munlock
:
1206 result
= munlock ((void *) t2h_addr (cb
, &s
, arg1
), arg2
);
1210 case TARGET_LINUX_SYS_nanosleep
:
1212 struct timespec req
, rem
;
1214 req
= *((struct timespec
*) t2h_addr (cb
, &s
, arg2
));
1215 translate_endian_t2h (&req
, sizeof(req
));
1217 result
= nanosleep (&req
, &rem
);
1223 translate_endian_h2t (&rem
, sizeof(rem
));
1224 if ((s
.write_mem
) (cb
, &s
, arg2
, (char *) &rem
, sizeof(rem
))
1233 case TARGET_LINUX_SYS_mremap
: /* FIXME */
1234 #if SIZEOF_VOID_P == 4 /* Code assumes m32r pointer size matches host. */
1235 result
= (int) mremap ((void *) t2h_addr (cb
, &s
, arg1
), arg2
, arg3
, arg4
);
1243 case TARGET_LINUX_SYS_getresuid32
:
1244 case TARGET_LINUX_SYS_getresuid
:
1246 uid_t ruid
, euid
, suid
;
1248 result
= getresuid (&ruid
, &euid
, &suid
);
1254 *((uid_t
*) t2h_addr (cb
, &s
, arg1
)) = H2T_4 (ruid
);
1255 *((uid_t
*) t2h_addr (cb
, &s
, arg2
)) = H2T_4 (euid
);
1256 *((uid_t
*) t2h_addr (cb
, &s
, arg3
)) = H2T_4 (suid
);
1260 case TARGET_LINUX_SYS_poll
:
1264 ufds
= *((struct pollfd
*) t2h_addr (cb
, &s
, arg1
));
1265 ufds
.fd
= T2H_4 (ufds
.fd
);
1266 ufds
.events
= T2H_2 (ufds
.events
);
1267 ufds
.revents
= T2H_2 (ufds
.revents
);
1269 result
= poll (&ufds
, arg2
, arg3
);
1274 case TARGET_LINUX_SYS_getresgid32
:
1275 case TARGET_LINUX_SYS_getresgid
:
1277 uid_t rgid
, egid
, sgid
;
1279 result
= getresgid (&rgid
, &egid
, &sgid
);
1285 *((uid_t
*) t2h_addr (cb
, &s
, arg1
)) = H2T_4 (rgid
);
1286 *((uid_t
*) t2h_addr (cb
, &s
, arg2
)) = H2T_4 (egid
);
1287 *((uid_t
*) t2h_addr (cb
, &s
, arg3
)) = H2T_4 (sgid
);
1291 case TARGET_LINUX_SYS_pread
:
1292 result
= pread (arg1
, (void *) t2h_addr (cb
, &s
, arg2
), arg3
, arg4
);
1296 case TARGET_LINUX_SYS_pwrite
:
1297 result
= pwrite (arg1
, (void *) t2h_addr (cb
, &s
, arg2
), arg3
, arg4
);
1301 case TARGET_LINUX_SYS_chown32
:
1302 case TARGET_LINUX_SYS_chown
:
1303 result
= chown ((char *) t2h_addr (cb
, &s
, arg1
), arg2
, arg3
);
1307 case TARGET_LINUX_SYS_getcwd
:
1311 ret
= getcwd ((char *) t2h_addr (cb
, &s
, arg1
), arg2
);
1312 result
= ret
== NULL
? 0 : arg1
;
1317 case TARGET_LINUX_SYS_sendfile
:
1321 offset
= *((off_t
*) t2h_addr (cb
, &s
, arg3
));
1322 offset
= T2H_4 (offset
);
1324 result
= sendfile (arg1
, arg2
, &offset
, arg3
);
1330 *((off_t
*) t2h_addr (cb
, &s
, arg3
)) = H2T_4 (offset
);
1341 m32rbf_h_gr_set (current_cpu
, 0, -errcode
);
1343 m32rbf_h_gr_set (current_cpu
, 0, result
);
1348 case TRAP_BREAKPOINT
:
1349 sim_engine_halt (sd
, current_cpu
, NULL
, pc
,
1350 sim_stopped
, SIM_SIGTRAP
);
1353 case TRAP_FLUSH_CACHE
:
1360 /* The new pc is the trap vector entry.
1361 We assume there's a branch there to some handler.
1362 Use cr5 as EVB (EIT Vector Base) register. */
1363 /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
1364 USI new_pc
= m32rbf_h_cr_get (current_cpu
, 5) + 0x40 + num
* 4;
1369 /* Fake an "rte" insn. */
1370 /* FIXME: Should duplicate all of rte processing. */
1371 return (pc
& -4) + 4;