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