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