xref: /netbsd-src/external/gpl3/gdb/dist/sim/m32r/traps.c (revision 05fa08567a80471fd0eb3843a238392874f2577c)
14e98e3e1Schristos /* m32r exception, interrupt, and trap (EIT) support
2*05fa0856Schristos    Copyright (C) 1998-2024 Free Software Foundation, Inc.
34b169a6bSchristos    Contributed by Cygnus Solutions & Renesas.
44e98e3e1Schristos 
54e98e3e1Schristos    This file is part of GDB, the GNU debugger.
64e98e3e1Schristos 
74e98e3e1Schristos    This program is free software; you can redistribute it and/or modify
84e98e3e1Schristos    it under the terms of the GNU General Public License as published by
94e98e3e1Schristos    the Free Software Foundation; either version 3 of the License, or
104e98e3e1Schristos    (at your option) any later version.
114e98e3e1Schristos 
124e98e3e1Schristos    This program is distributed in the hope that it will be useful,
134e98e3e1Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
144e98e3e1Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
154e98e3e1Schristos    GNU General Public License for more details.
164e98e3e1Schristos 
174e98e3e1Schristos    You should have received a copy of the GNU General Public License
184e98e3e1Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
194e98e3e1Schristos 
204b169a6bSchristos /* This must come before any other includes.  */
214b169a6bSchristos #include "defs.h"
224e98e3e1Schristos 
234b169a6bSchristos #include "portability.h"
244b169a6bSchristos #include "sim-main.h"
254b169a6bSchristos #include "sim-signal.h"
264b169a6bSchristos #include "sim-syscall.h"
274b169a6bSchristos #include "sim/callback.h"
284b169a6bSchristos #include "syscall.h"
294b169a6bSchristos #include <dirent.h>
304b169a6bSchristos #include <errno.h>
314b169a6bSchristos #include <fcntl.h>
324b169a6bSchristos #include <stdlib.h>
334b169a6bSchristos #include <time.h>
344b169a6bSchristos #include <unistd.h>
354b169a6bSchristos #include <utime.h>
364b169a6bSchristos /* TODO: The Linux syscall emulation needs work to support non-Linux hosts.
374b169a6bSchristos    Use an OS hack for now so the CPU emulation is available everywhere.
384b169a6bSchristos    NB: The emulation is also missing argument conversion (endian & bitsize)
394b169a6bSchristos    even on Linux hosts.  */
404b169a6bSchristos #ifdef __linux__
41*05fa0856Schristos #include <syslog.h>
42*05fa0856Schristos #include <sys/file.h>
43*05fa0856Schristos #include <sys/fsuid.h>
44*05fa0856Schristos #include <sys/ioctl.h>
454b169a6bSchristos #include <sys/mman.h>
464b169a6bSchristos #include <sys/poll.h>
474b169a6bSchristos #include <sys/resource.h>
48*05fa0856Schristos #include <sys/sendfile.h>
494b169a6bSchristos #include <sys/sysinfo.h>
504b169a6bSchristos #include <sys/stat.h>
514b169a6bSchristos #include <sys/time.h>
524b169a6bSchristos #include <sys/timeb.h>
534b169a6bSchristos #include <sys/timex.h>
544b169a6bSchristos #include <sys/types.h>
554b169a6bSchristos #include <sys/uio.h>
564b169a6bSchristos #include <sys/utsname.h>
574b169a6bSchristos #include <sys/vfs.h>
584b169a6bSchristos #include <linux/sysctl.h>
594b169a6bSchristos #include <linux/types.h>
604b169a6bSchristos #include <linux/unistd.h>
614b169a6bSchristos #endif
624b169a6bSchristos 
63*05fa0856Schristos #include "m32r-sim.h"
64*05fa0856Schristos 
654b169a6bSchristos #define TRAP_LINUX_SYSCALL 2
664e98e3e1Schristos #define TRAP_FLUSH_CACHE 12
674e98e3e1Schristos /* The semantic code invokes this for invalid (unrecognized) instructions.  */
684e98e3e1Schristos 
694e98e3e1Schristos SEM_PC
704e98e3e1Schristos sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC pc)
714e98e3e1Schristos {
724e98e3e1Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
734e98e3e1Schristos 
744e98e3e1Schristos #if 0
754e98e3e1Schristos   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
764e98e3e1Schristos     {
774e98e3e1Schristos       h_bsm_set (current_cpu, h_sm_get (current_cpu));
784e98e3e1Schristos       h_bie_set (current_cpu, h_ie_get (current_cpu));
794e98e3e1Schristos       h_bcond_set (current_cpu, h_cond_get (current_cpu));
804e98e3e1Schristos       /* sm not changed */
814e98e3e1Schristos       h_ie_set (current_cpu, 0);
824e98e3e1Schristos       h_cond_set (current_cpu, 0);
834e98e3e1Schristos 
844e98e3e1Schristos       h_bpc_set (current_cpu, cia);
854e98e3e1Schristos 
864e98e3e1Schristos       sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
874e98e3e1Schristos 			  EIT_RSVD_INSN_ADDR);
884e98e3e1Schristos     }
894e98e3e1Schristos   else
904e98e3e1Schristos #endif
914e98e3e1Schristos     sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
924e98e3e1Schristos 
934e98e3e1Schristos   return pc;
944e98e3e1Schristos }
954e98e3e1Schristos 
964e98e3e1Schristos /* Process an address exception.  */
974e98e3e1Schristos 
984e98e3e1Schristos void
994e98e3e1Schristos m32r_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
1004e98e3e1Schristos 		  unsigned int map, int nr_bytes, address_word addr,
1014e98e3e1Schristos 		  transfer_type transfer, sim_core_signals sig)
1024e98e3e1Schristos {
1034e98e3e1Schristos   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
1044e98e3e1Schristos     {
1054e98e3e1Schristos       m32rbf_h_cr_set (current_cpu, H_CR_BBPC,
1064e98e3e1Schristos 		       m32rbf_h_cr_get (current_cpu, H_CR_BPC));
1074e98e3e1Schristos       switch (MACH_NUM (CPU_MACH (current_cpu)))
1084e98e3e1Schristos 	{
1094e98e3e1Schristos 	case MACH_M32R:
1104e98e3e1Schristos 	  m32rbf_h_bpsw_set (current_cpu, m32rbf_h_psw_get (current_cpu));
1114e98e3e1Schristos 	  /* sm not changed.  */
1124e98e3e1Schristos 	  m32rbf_h_psw_set (current_cpu, m32rbf_h_psw_get (current_cpu) & 0x80);
1134e98e3e1Schristos 	  break;
1144e98e3e1Schristos 	case MACH_M32RX:
1154e98e3e1Schristos   	  m32rxf_h_bpsw_set (current_cpu, m32rxf_h_psw_get (current_cpu));
1164e98e3e1Schristos   	  /* sm not changed.  */
1174e98e3e1Schristos   	  m32rxf_h_psw_set (current_cpu, m32rxf_h_psw_get (current_cpu) & 0x80);
1184e98e3e1Schristos 	  break;
1194e98e3e1Schristos 	case MACH_M32R2:
1204e98e3e1Schristos 	  m32r2f_h_bpsw_set (current_cpu, m32r2f_h_psw_get (current_cpu));
1214e98e3e1Schristos 	  /* sm not changed.  */
1224e98e3e1Schristos 	  m32r2f_h_psw_set (current_cpu, m32r2f_h_psw_get (current_cpu) & 0x80);
1234e98e3e1Schristos 	  break;
1244e98e3e1Schristos 	default:
1254e98e3e1Schristos 	  abort ();
1264e98e3e1Schristos 	}
1274e98e3e1Schristos 
1284e98e3e1Schristos       m32rbf_h_cr_set (current_cpu, H_CR_BPC, cia);
1294e98e3e1Schristos 
1304e98e3e1Schristos       sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
1314e98e3e1Schristos 			  EIT_ADDR_EXCP_ADDR);
1324e98e3e1Schristos     }
1334e98e3e1Schristos   else
1344e98e3e1Schristos     sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr,
1354e98e3e1Schristos 		     transfer, sig);
1364e98e3e1Schristos }
1374e98e3e1Schristos 
1384b169a6bSchristos /* Translate target's address to host's address.  */
1394b169a6bSchristos 
1404b169a6bSchristos static void *
1414b169a6bSchristos t2h_addr (host_callback *cb, struct cb_syscall *sc,
1424b169a6bSchristos 	  unsigned long taddr)
1434b169a6bSchristos {
1444b169a6bSchristos   SIM_DESC sd = (SIM_DESC) sc->p1;
1454b169a6bSchristos   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
1464b169a6bSchristos 
1474b169a6bSchristos   if (taddr == 0)
1484b169a6bSchristos     return NULL;
1494b169a6bSchristos 
1504b169a6bSchristos   return sim_core_trans_addr (sd, cpu, read_map, taddr);
1514b169a6bSchristos }
1524b169a6bSchristos 
1534b169a6bSchristos /* TODO: These functions are a big hack and assume that the host runtime has
1544b169a6bSchristos    type sizes and struct layouts that match the target.  So the Linux emulation
1554b169a6bSchristos    probaly only really works in 32-bit runtimes.  */
1564b169a6bSchristos 
1574b169a6bSchristos static void
1584b169a6bSchristos translate_endian_h2t (void *addr, size_t size)
1594b169a6bSchristos {
1604b169a6bSchristos   unsigned int *p = (unsigned int *) addr;
1614b169a6bSchristos   int i;
1624b169a6bSchristos 
1634b169a6bSchristos   for (i = 0; i <= size - 4; i += 4,p++)
1644b169a6bSchristos     *p = H2T_4 (*p);
1654b169a6bSchristos 
1664b169a6bSchristos   if (i <= size - 2)
1674b169a6bSchristos     *((unsigned short *) p) = H2T_2 (*((unsigned short *) p));
1684b169a6bSchristos }
1694b169a6bSchristos 
1704b169a6bSchristos static void
1714b169a6bSchristos translate_endian_t2h (void *addr, size_t size)
1724b169a6bSchristos {
1734b169a6bSchristos   unsigned int *p = (unsigned int *) addr;
1744b169a6bSchristos   int i;
1754b169a6bSchristos 
1764b169a6bSchristos   for (i = 0; i <= size - 4; i += 4,p++)
1774b169a6bSchristos     *p = T2H_4 (*p);
1784b169a6bSchristos 
1794b169a6bSchristos   if (i <= size - 2)
1804b169a6bSchristos     *((unsigned short *) p) = T2H_2 (*((unsigned short *) p));
1814b169a6bSchristos }
1824b169a6bSchristos 
1834e98e3e1Schristos /* Trap support.
1844e98e3e1Schristos    The result is the pc address to continue at.
1854e98e3e1Schristos    Preprocessing like saving the various registers has already been done.  */
1864e98e3e1Schristos 
1874e98e3e1Schristos USI
1884e98e3e1Schristos m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num)
1894e98e3e1Schristos {
1904e98e3e1Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
1914e98e3e1Schristos   host_callback *cb = STATE_CALLBACK (sd);
1924e98e3e1Schristos 
1934e98e3e1Schristos   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
1944b169a6bSchristos     goto case_default;
1954e98e3e1Schristos 
1964e98e3e1Schristos   switch (num)
1974e98e3e1Schristos     {
1984e98e3e1Schristos     case TRAP_SYSCALL:
1994e98e3e1Schristos       {
200212397c6Schristos 	long result, result2;
201212397c6Schristos 	int errcode;
2024e98e3e1Schristos 
203212397c6Schristos 	sim_syscall_multi (current_cpu,
204212397c6Schristos 			   m32rbf_h_gr_get (current_cpu, 0),
205212397c6Schristos 			   m32rbf_h_gr_get (current_cpu, 1),
206212397c6Schristos 			   m32rbf_h_gr_get (current_cpu, 2),
207212397c6Schristos 			   m32rbf_h_gr_get (current_cpu, 3),
208212397c6Schristos 			   m32rbf_h_gr_get (current_cpu, 4),
209212397c6Schristos 			   &result, &result2, &errcode);
2104e98e3e1Schristos 
211212397c6Schristos 	m32rbf_h_gr_set (current_cpu, 2, errcode);
212212397c6Schristos 	m32rbf_h_gr_set (current_cpu, 0, result);
213212397c6Schristos 	m32rbf_h_gr_set (current_cpu, 1, result2);
2144e98e3e1Schristos 	break;
2154e98e3e1Schristos       }
2164e98e3e1Schristos 
2174b169a6bSchristos #ifdef __linux__
2184b169a6bSchristos     case TRAP_LINUX_SYSCALL:
2194b169a6bSchristos       {
2204b169a6bSchristos 	CB_SYSCALL s;
2214b169a6bSchristos 	unsigned int func, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
222*05fa0856Schristos 	int result, errcode;
2234b169a6bSchristos 
2244b169a6bSchristos 	if (STATE_ENVIRONMENT (sd) != USER_ENVIRONMENT)
2254b169a6bSchristos 	  goto case_default;
2264b169a6bSchristos 
2274b169a6bSchristos 	func = m32rbf_h_gr_get (current_cpu, 7);
2284b169a6bSchristos 	arg1 = m32rbf_h_gr_get (current_cpu, 0);
2294b169a6bSchristos 	arg2 = m32rbf_h_gr_get (current_cpu, 1);
2304b169a6bSchristos 	arg3 = m32rbf_h_gr_get (current_cpu, 2);
2314b169a6bSchristos 	arg4 = m32rbf_h_gr_get (current_cpu, 3);
2324b169a6bSchristos 	arg5 = m32rbf_h_gr_get (current_cpu, 4);
2334b169a6bSchristos 	arg6 = m32rbf_h_gr_get (current_cpu, 5);
2344b169a6bSchristos 	arg7 = m32rbf_h_gr_get (current_cpu, 6);
2354b169a6bSchristos 
2364b169a6bSchristos 	CB_SYSCALL_INIT (&s);
2374b169a6bSchristos 	s.func = func;
2384b169a6bSchristos 	s.arg1 = arg1;
2394b169a6bSchristos 	s.arg2 = arg2;
2404b169a6bSchristos 	s.arg3 = arg3;
2414b169a6bSchristos 	s.arg4 = arg4;
2424b169a6bSchristos 	s.arg5 = arg5;
2434b169a6bSchristos 	s.arg6 = arg6;
2444b169a6bSchristos 	s.arg7 = arg7;
2454b169a6bSchristos 
2464b169a6bSchristos 	s.p1 = sd;
2474b169a6bSchristos 	s.p2 = current_cpu;
2484b169a6bSchristos 	s.read_mem = sim_syscall_read_mem;
2494b169a6bSchristos 	s.write_mem = sim_syscall_write_mem;
2504b169a6bSchristos 
2514b169a6bSchristos 	result = 0;
2524b169a6bSchristos 	errcode = 0;
2534b169a6bSchristos 
2544b169a6bSchristos 	switch (func)
2554b169a6bSchristos 	  {
2564b169a6bSchristos 	  case TARGET_LINUX_SYS_exit:
2574b169a6bSchristos 	    sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, arg1);
2584b169a6bSchristos 	    break;
2594b169a6bSchristos 
2604b169a6bSchristos 	  case TARGET_LINUX_SYS_read:
2614b169a6bSchristos 	    result = read (arg1, t2h_addr (cb, &s, arg2), arg3);
2624b169a6bSchristos 	    errcode = errno;
2634b169a6bSchristos 	    break;
2644b169a6bSchristos 
2654b169a6bSchristos 	  case TARGET_LINUX_SYS_write:
2664b169a6bSchristos 	    result = write (arg1, t2h_addr (cb, &s, arg2), arg3);
2674b169a6bSchristos 	    errcode = errno;
2684b169a6bSchristos 	    break;
2694b169a6bSchristos 
2704b169a6bSchristos 	  case TARGET_LINUX_SYS_open:
2714b169a6bSchristos 	    result = open ((char *) t2h_addr (cb, &s, arg1), arg2, arg3);
2724b169a6bSchristos 	    errcode = errno;
2734b169a6bSchristos 	    break;
2744b169a6bSchristos 
2754b169a6bSchristos 	  case TARGET_LINUX_SYS_close:
2764b169a6bSchristos 	    result = close (arg1);
2774b169a6bSchristos 	    errcode = errno;
2784b169a6bSchristos 	    break;
2794b169a6bSchristos 
2804b169a6bSchristos 	  case TARGET_LINUX_SYS_creat:
2814b169a6bSchristos 	    result = creat ((char *) t2h_addr (cb, &s, arg1), arg2);
2824b169a6bSchristos 	    errcode = errno;
2834b169a6bSchristos 	    break;
2844b169a6bSchristos 
2854b169a6bSchristos 	  case TARGET_LINUX_SYS_link:
2864b169a6bSchristos 	    result = link ((char *) t2h_addr (cb, &s, arg1),
2874b169a6bSchristos 			   (char *) t2h_addr (cb, &s, arg2));
2884b169a6bSchristos 	    errcode = errno;
2894b169a6bSchristos 	    break;
2904b169a6bSchristos 
2914b169a6bSchristos 	  case TARGET_LINUX_SYS_unlink:
2924b169a6bSchristos 	    result = unlink ((char *) t2h_addr (cb, &s, arg1));
2934b169a6bSchristos 	    errcode = errno;
2944b169a6bSchristos 	    break;
2954b169a6bSchristos 
2964b169a6bSchristos 	  case TARGET_LINUX_SYS_chdir:
2974b169a6bSchristos 	    result = chdir ((char *) t2h_addr (cb, &s, arg1));
2984b169a6bSchristos 	    errcode = errno;
2994b169a6bSchristos 	    break;
3004b169a6bSchristos 
3014b169a6bSchristos 	  case TARGET_LINUX_SYS_time:
3024b169a6bSchristos 	    {
3034b169a6bSchristos 	      time_t t;
3044b169a6bSchristos 
3054b169a6bSchristos 	      if (arg1 == 0)
3064b169a6bSchristos 		{
3074b169a6bSchristos 		  result = (int) time (NULL);
3084b169a6bSchristos 		  errcode = errno;
3094b169a6bSchristos 		}
3104b169a6bSchristos 	      else
3114b169a6bSchristos 		{
3124b169a6bSchristos 		  result = (int) time (&t);
3134b169a6bSchristos 		  errcode = errno;
3144b169a6bSchristos 
3154b169a6bSchristos 		  if (result != 0)
3164b169a6bSchristos 		    break;
3174b169a6bSchristos 
3184b169a6bSchristos 		  t = H2T_4 (t);
3194b169a6bSchristos 		  if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t)) != sizeof(t))
3204b169a6bSchristos 		    {
3214b169a6bSchristos 		      result = -1;
3224b169a6bSchristos 		      errcode = EINVAL;
3234b169a6bSchristos 		    }
3244b169a6bSchristos 		}
3254b169a6bSchristos 	    }
3264b169a6bSchristos 	    break;
3274b169a6bSchristos 
3284b169a6bSchristos 	  case TARGET_LINUX_SYS_mknod:
3294b169a6bSchristos 	    result = mknod ((char *) t2h_addr (cb, &s, arg1),
3304b169a6bSchristos 			    (mode_t) arg2, (dev_t) arg3);
3314b169a6bSchristos 	    errcode = errno;
3324b169a6bSchristos 	    break;
3334b169a6bSchristos 
3344b169a6bSchristos 	  case TARGET_LINUX_SYS_chmod:
3354b169a6bSchristos 	    result = chmod ((char *) t2h_addr (cb, &s, arg1), (mode_t) arg2);
3364b169a6bSchristos 	    errcode = errno;
3374b169a6bSchristos 	    break;
3384b169a6bSchristos 
3394b169a6bSchristos 	  case TARGET_LINUX_SYS_lchown32:
3404b169a6bSchristos 	  case TARGET_LINUX_SYS_lchown:
3414b169a6bSchristos 	    result = lchown ((char *) t2h_addr (cb, &s, arg1),
3424b169a6bSchristos 			     (uid_t) arg2, (gid_t) arg3);
3434b169a6bSchristos 	    errcode = errno;
3444b169a6bSchristos 	    break;
3454b169a6bSchristos 
3464b169a6bSchristos 	  case TARGET_LINUX_SYS_lseek:
3474b169a6bSchristos 	    result = (int) lseek (arg1, (off_t) arg2, arg3);
3484b169a6bSchristos 	    errcode = errno;
3494b169a6bSchristos 	    break;
3504b169a6bSchristos 
3514b169a6bSchristos 	  case TARGET_LINUX_SYS_getpid:
3524b169a6bSchristos 	    result = getpid ();
3534b169a6bSchristos 	    errcode = errno;
3544b169a6bSchristos 	    break;
3554b169a6bSchristos 
3564b169a6bSchristos 	  case TARGET_LINUX_SYS_getuid32:
3574b169a6bSchristos 	  case TARGET_LINUX_SYS_getuid:
3584b169a6bSchristos 	    result = getuid ();
3594b169a6bSchristos 	    errcode = errno;
3604b169a6bSchristos 	    break;
3614b169a6bSchristos 
3624b169a6bSchristos 	  case TARGET_LINUX_SYS_utime:
3634b169a6bSchristos 	    {
3644b169a6bSchristos 	      struct utimbuf buf;
3654b169a6bSchristos 
3664b169a6bSchristos 	      if (arg2 == 0)
3674b169a6bSchristos 		{
3684b169a6bSchristos 		  result = utime ((char *) t2h_addr (cb, &s, arg1), NULL);
3694b169a6bSchristos 		  errcode = errno;
3704b169a6bSchristos 		}
3714b169a6bSchristos 	      else
3724b169a6bSchristos 		{
3734b169a6bSchristos 		  buf = *((struct utimbuf *) t2h_addr (cb, &s, arg2));
3744b169a6bSchristos 		  translate_endian_t2h (&buf, sizeof(buf));
3754b169a6bSchristos 		  result = utime ((char *) t2h_addr (cb, &s, arg1), &buf);
3764b169a6bSchristos 		  errcode = errno;
3774b169a6bSchristos 		}
3784b169a6bSchristos 	    }
3794b169a6bSchristos 	    break;
3804b169a6bSchristos 
3814b169a6bSchristos 	  case TARGET_LINUX_SYS_access:
3824b169a6bSchristos 	    result = access ((char *) t2h_addr (cb, &s, arg1), arg2);
3834b169a6bSchristos 	    errcode = errno;
3844b169a6bSchristos 	    break;
3854b169a6bSchristos 
3864b169a6bSchristos 	  case TARGET_LINUX_SYS_ftime:
3874b169a6bSchristos 	    {
3884b169a6bSchristos 	      struct timeb t;
389*05fa0856Schristos 	      struct timespec ts;
3904b169a6bSchristos 
391*05fa0856Schristos 	      result = clock_gettime (CLOCK_REALTIME, &ts);
3924b169a6bSchristos 	      errcode = errno;
3934b169a6bSchristos 
3944b169a6bSchristos 	      if (result != 0)
3954b169a6bSchristos 		break;
3964b169a6bSchristos 
397*05fa0856Schristos 	      t.time = H2T_4 (ts.tv_sec);
398*05fa0856Schristos 	      t.millitm = H2T_2 (ts.tv_nsec / 1000000);
399*05fa0856Schristos 	      /* POSIX.1-2001 says the contents of the timezone and dstflag
400*05fa0856Schristos 		 members of tp after a call to ftime() are unspecified.  */
401*05fa0856Schristos 	      t.timezone = H2T_2 (0);
402*05fa0856Schristos 	      t.dstflag = H2T_2 (0);
4034b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg1, (char *) &t, sizeof(t))
4044b169a6bSchristos 		  != sizeof(t))
4054b169a6bSchristos 		{
4064b169a6bSchristos 		  result = -1;
4074b169a6bSchristos 		  errcode = EINVAL;
4084b169a6bSchristos 		}
4094b169a6bSchristos 	    }
410*05fa0856Schristos 	    break;
4114b169a6bSchristos 
4124b169a6bSchristos 	  case TARGET_LINUX_SYS_sync:
4134b169a6bSchristos 	    sync ();
4144b169a6bSchristos 	    result = 0;
4154b169a6bSchristos 	    break;
4164b169a6bSchristos 
4174b169a6bSchristos 	  case TARGET_LINUX_SYS_rename:
4184b169a6bSchristos 	    result = rename ((char *) t2h_addr (cb, &s, arg1),
4194b169a6bSchristos 			     (char *) t2h_addr (cb, &s, arg2));
4204b169a6bSchristos 	    errcode = errno;
4214b169a6bSchristos 	    break;
4224b169a6bSchristos 
4234b169a6bSchristos 	  case TARGET_LINUX_SYS_mkdir:
4244b169a6bSchristos 	    result = mkdir ((char *) t2h_addr (cb, &s, arg1), arg2);
4254b169a6bSchristos 	    errcode = errno;
4264b169a6bSchristos 	    break;
4274b169a6bSchristos 
4284b169a6bSchristos 	  case TARGET_LINUX_SYS_rmdir:
4294b169a6bSchristos 	    result = rmdir ((char *) t2h_addr (cb, &s, arg1));
4304b169a6bSchristos 	    errcode = errno;
4314b169a6bSchristos 	    break;
4324b169a6bSchristos 
4334b169a6bSchristos 	  case TARGET_LINUX_SYS_dup:
4344b169a6bSchristos 	    result = dup (arg1);
4354b169a6bSchristos 	    errcode = errno;
4364b169a6bSchristos 	    break;
4374b169a6bSchristos 
4384b169a6bSchristos 	  case TARGET_LINUX_SYS_brk:
439*05fa0856Schristos 	    result = brk ((void *) (uintptr_t) arg1);
4404b169a6bSchristos 	    errcode = errno;
4414b169a6bSchristos 	    //result = arg1;
4424b169a6bSchristos 	    break;
4434b169a6bSchristos 
4444b169a6bSchristos 	  case TARGET_LINUX_SYS_getgid32:
4454b169a6bSchristos 	  case TARGET_LINUX_SYS_getgid:
4464b169a6bSchristos 	    result = getgid ();
4474b169a6bSchristos 	    errcode = errno;
4484b169a6bSchristos 	    break;
4494b169a6bSchristos 
4504b169a6bSchristos 	  case TARGET_LINUX_SYS_geteuid32:
4514b169a6bSchristos 	  case TARGET_LINUX_SYS_geteuid:
4524b169a6bSchristos 	    result = geteuid ();
4534b169a6bSchristos 	    errcode = errno;
4544b169a6bSchristos 	    break;
4554b169a6bSchristos 
4564b169a6bSchristos 	  case TARGET_LINUX_SYS_getegid32:
4574b169a6bSchristos 	  case TARGET_LINUX_SYS_getegid:
4584b169a6bSchristos 	    result = getegid ();
4594b169a6bSchristos 	    errcode = errno;
4604b169a6bSchristos 	    break;
4614b169a6bSchristos 
4624b169a6bSchristos 	  case TARGET_LINUX_SYS_ioctl:
4634b169a6bSchristos 	    result = ioctl (arg1, arg2, arg3);
4644b169a6bSchristos 	    errcode = errno;
4654b169a6bSchristos 	    break;
4664b169a6bSchristos 
4674b169a6bSchristos 	  case TARGET_LINUX_SYS_fcntl:
4684b169a6bSchristos 	    result = fcntl (arg1, arg2, arg3);
4694b169a6bSchristos 	    errcode = errno;
4704b169a6bSchristos 	    break;
4714b169a6bSchristos 
4724b169a6bSchristos 	  case TARGET_LINUX_SYS_dup2:
4734b169a6bSchristos 	    result = dup2 (arg1, arg2);
4744b169a6bSchristos 	    errcode = errno;
4754b169a6bSchristos 	    break;
4764b169a6bSchristos 
4774b169a6bSchristos 	  case TARGET_LINUX_SYS_getppid:
4784b169a6bSchristos 	    result = getppid ();
4794b169a6bSchristos 	    errcode = errno;
4804b169a6bSchristos 	    break;
4814b169a6bSchristos 
4824b169a6bSchristos 	  case TARGET_LINUX_SYS_getpgrp:
4834b169a6bSchristos 	    result = getpgrp ();
4844b169a6bSchristos 	    errcode = errno;
4854b169a6bSchristos 	    break;
4864b169a6bSchristos 
4874b169a6bSchristos 	  case TARGET_LINUX_SYS_getrlimit:
4884b169a6bSchristos 	    {
4894b169a6bSchristos 	      struct rlimit rlim;
4904b169a6bSchristos 
4914b169a6bSchristos 	      result = getrlimit (arg1, &rlim);
4924b169a6bSchristos 	      errcode = errno;
4934b169a6bSchristos 
4944b169a6bSchristos 	      if (result != 0)
4954b169a6bSchristos 		break;
4964b169a6bSchristos 
4974b169a6bSchristos 	      translate_endian_h2t (&rlim, sizeof(rlim));
4984b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &rlim, sizeof(rlim))
4994b169a6bSchristos 		  != sizeof(rlim))
5004b169a6bSchristos 		{
5014b169a6bSchristos 		  result = -1;
5024b169a6bSchristos 		  errcode = EINVAL;
5034b169a6bSchristos 		}
5044b169a6bSchristos 	    }
5054b169a6bSchristos 	    break;
5064b169a6bSchristos 
5074b169a6bSchristos 	  case TARGET_LINUX_SYS_getrusage:
5084b169a6bSchristos 	    {
5094b169a6bSchristos 	      struct rusage usage;
5104b169a6bSchristos 
5114b169a6bSchristos 	      result = getrusage (arg1, &usage);
5124b169a6bSchristos 	      errcode = errno;
5134b169a6bSchristos 
5144b169a6bSchristos 	      if (result != 0)
5154b169a6bSchristos 		break;
5164b169a6bSchristos 
5174b169a6bSchristos 	      translate_endian_h2t (&usage, sizeof(usage));
5184b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &usage, sizeof(usage))
5194b169a6bSchristos 		  != sizeof(usage))
5204b169a6bSchristos 		{
5214b169a6bSchristos 		  result = -1;
5224b169a6bSchristos 		  errcode = EINVAL;
5234b169a6bSchristos 		}
5244b169a6bSchristos 	    }
5254b169a6bSchristos 	    break;
5264b169a6bSchristos 
5274b169a6bSchristos 	  case TARGET_LINUX_SYS_gettimeofday:
5284b169a6bSchristos 	    {
5294b169a6bSchristos 	      struct timeval tv;
5304b169a6bSchristos 	      struct timezone tz;
5314b169a6bSchristos 
5324b169a6bSchristos 	      result = gettimeofday (&tv, &tz);
5334b169a6bSchristos 	      errcode = errno;
5344b169a6bSchristos 
5354b169a6bSchristos 	      if (result != 0)
5364b169a6bSchristos 		break;
5374b169a6bSchristos 
5384b169a6bSchristos 	      translate_endian_h2t (&tv, sizeof(tv));
5394b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg1, (char *) &tv, sizeof(tv))
5404b169a6bSchristos 		  != sizeof(tv))
5414b169a6bSchristos 		{
5424b169a6bSchristos 		  result = -1;
5434b169a6bSchristos 		  errcode = EINVAL;
5444b169a6bSchristos 		}
5454b169a6bSchristos 
5464b169a6bSchristos 	      translate_endian_h2t (&tz, sizeof(tz));
5474b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &tz, sizeof(tz))
5484b169a6bSchristos 		  != sizeof(tz))
5494b169a6bSchristos 		{
5504b169a6bSchristos 		  result = -1;
5514b169a6bSchristos 		  errcode = EINVAL;
5524b169a6bSchristos 		}
5534b169a6bSchristos 	    }
5544b169a6bSchristos 	    break;
5554b169a6bSchristos 
5564b169a6bSchristos 	  case TARGET_LINUX_SYS_getgroups32:
5574b169a6bSchristos 	  case TARGET_LINUX_SYS_getgroups:
5584b169a6bSchristos 	    {
5594b169a6bSchristos 	      gid_t *list = NULL;
5604b169a6bSchristos 
5614b169a6bSchristos 	      if (arg1 > 0)
5624b169a6bSchristos 		list = (gid_t *) malloc (arg1 * sizeof(gid_t));
5634b169a6bSchristos 
5644b169a6bSchristos 	      result = getgroups (arg1, list);
5654b169a6bSchristos 	      errcode = errno;
5664b169a6bSchristos 
5674b169a6bSchristos 	      if (result != 0)
5684b169a6bSchristos 		break;
5694b169a6bSchristos 
5704b169a6bSchristos 	      translate_endian_h2t (list, arg1 * sizeof(gid_t));
5714b169a6bSchristos 	      if (arg1 > 0)
5724b169a6bSchristos 		if ((s.write_mem) (cb, &s, arg2, (char *) list, arg1 * sizeof(gid_t))
5734b169a6bSchristos 		    != arg1 * sizeof(gid_t))
5744b169a6bSchristos 		  {
5754b169a6bSchristos 		    result = -1;
5764b169a6bSchristos 		     errcode = EINVAL;
5774b169a6bSchristos 		  }
5784b169a6bSchristos 	    }
5794b169a6bSchristos 	    break;
5804b169a6bSchristos 
5814b169a6bSchristos 	  case TARGET_LINUX_SYS_select:
5824b169a6bSchristos 	    {
5834b169a6bSchristos 	      int n;
5844b169a6bSchristos 	      fd_set readfds;
585*05fa0856Schristos 	      unsigned int treadfdsp;
5864b169a6bSchristos 	      fd_set *hreadfdsp;
5874b169a6bSchristos 	      fd_set writefds;
588*05fa0856Schristos 	      unsigned int twritefdsp;
5894b169a6bSchristos 	      fd_set *hwritefdsp;
5904b169a6bSchristos 	      fd_set exceptfds;
591*05fa0856Schristos 	      unsigned int texceptfdsp;
5924b169a6bSchristos 	      fd_set *hexceptfdsp;
593*05fa0856Schristos 	      unsigned int ttimeoutp;
5944b169a6bSchristos 	      struct timeval timeout;
5954b169a6bSchristos 
5964b169a6bSchristos 	      n = arg1;
5974b169a6bSchristos 
598*05fa0856Schristos 	      treadfdsp = arg2;
599*05fa0856Schristos 	      if (treadfdsp !=0)
6004b169a6bSchristos 		{
601*05fa0856Schristos 		  readfds = *((fd_set *) t2h_addr (cb, &s, treadfdsp));
6024b169a6bSchristos 		  translate_endian_t2h (&readfds, sizeof(readfds));
6034b169a6bSchristos 		  hreadfdsp = &readfds;
6044b169a6bSchristos 		}
6054b169a6bSchristos 	      else
6064b169a6bSchristos 		hreadfdsp = NULL;
6074b169a6bSchristos 
608*05fa0856Schristos 	      twritefdsp = arg3;
609*05fa0856Schristos 	      if (twritefdsp != 0)
6104b169a6bSchristos 		{
611*05fa0856Schristos 		  writefds = *((fd_set *) t2h_addr (cb, &s, twritefdsp));
6124b169a6bSchristos 		  translate_endian_t2h (&writefds, sizeof(writefds));
6134b169a6bSchristos 		  hwritefdsp = &writefds;
6144b169a6bSchristos 		}
6154b169a6bSchristos 	      else
6164b169a6bSchristos 		hwritefdsp = NULL;
6174b169a6bSchristos 
618*05fa0856Schristos 	      texceptfdsp = arg4;
619*05fa0856Schristos 	      if (texceptfdsp != 0)
6204b169a6bSchristos 		{
621*05fa0856Schristos 		  exceptfds = *((fd_set *) t2h_addr (cb, &s, texceptfdsp));
6224b169a6bSchristos 		  translate_endian_t2h (&exceptfds, sizeof(exceptfds));
6234b169a6bSchristos 		  hexceptfdsp = &exceptfds;
6244b169a6bSchristos 		}
6254b169a6bSchristos 	      else
6264b169a6bSchristos 		hexceptfdsp = NULL;
6274b169a6bSchristos 
628*05fa0856Schristos 	      ttimeoutp = arg5;
629*05fa0856Schristos 	      timeout = *((struct timeval *) t2h_addr (cb, &s, ttimeoutp));
6304b169a6bSchristos 	      translate_endian_t2h (&timeout, sizeof(timeout));
6314b169a6bSchristos 
6324b169a6bSchristos 	      result = select (n, hreadfdsp, hwritefdsp, hexceptfdsp, &timeout);
6334b169a6bSchristos 	      errcode = errno;
6344b169a6bSchristos 
6354b169a6bSchristos 	      if (result != 0)
6364b169a6bSchristos 		break;
6374b169a6bSchristos 
638*05fa0856Schristos 	      if (treadfdsp != 0)
6394b169a6bSchristos 		{
6404b169a6bSchristos 		  translate_endian_h2t (&readfds, sizeof(readfds));
641*05fa0856Schristos 		  if ((s.write_mem) (cb, &s, treadfdsp,
6424b169a6bSchristos 		       (char *) &readfds, sizeof(readfds)) != sizeof(readfds))
6434b169a6bSchristos 		    {
6444b169a6bSchristos 		      result = -1;
6454b169a6bSchristos 		      errcode = EINVAL;
6464b169a6bSchristos 		    }
6474b169a6bSchristos 		}
6484b169a6bSchristos 
649*05fa0856Schristos 	      if (twritefdsp != 0)
6504b169a6bSchristos 		{
6514b169a6bSchristos 		  translate_endian_h2t (&writefds, sizeof(writefds));
652*05fa0856Schristos 		  if ((s.write_mem) (cb, &s, twritefdsp,
6534b169a6bSchristos 		       (char *) &writefds, sizeof(writefds)) != sizeof(writefds))
6544b169a6bSchristos 		    {
6554b169a6bSchristos 		      result = -1;
6564b169a6bSchristos 		      errcode = EINVAL;
6574b169a6bSchristos 		    }
6584b169a6bSchristos 		}
6594b169a6bSchristos 
660*05fa0856Schristos 	      if (texceptfdsp != 0)
6614b169a6bSchristos 		{
6624b169a6bSchristos 		  translate_endian_h2t (&exceptfds, sizeof(exceptfds));
663*05fa0856Schristos 		  if ((s.write_mem) (cb, &s, texceptfdsp,
6644b169a6bSchristos 		       (char *) &exceptfds, sizeof(exceptfds)) != sizeof(exceptfds))
6654b169a6bSchristos 		    {
6664b169a6bSchristos 		      result = -1;
6674b169a6bSchristos 		      errcode = EINVAL;
6684b169a6bSchristos 		    }
6694b169a6bSchristos 		}
6704b169a6bSchristos 
6714b169a6bSchristos 	      translate_endian_h2t (&timeout, sizeof(timeout));
672*05fa0856Schristos 	      if ((s.write_mem) (cb, &s, ttimeoutp,
6734b169a6bSchristos 		   (char *) &timeout, sizeof(timeout)) != sizeof(timeout))
6744b169a6bSchristos 		{
6754b169a6bSchristos 		  result = -1;
6764b169a6bSchristos 		  errcode = EINVAL;
6774b169a6bSchristos 		}
6784b169a6bSchristos 	    }
6794b169a6bSchristos 	    break;
6804b169a6bSchristos 
6814b169a6bSchristos 	  case TARGET_LINUX_SYS_symlink:
6824b169a6bSchristos 	    result = symlink ((char *) t2h_addr (cb, &s, arg1),
6834b169a6bSchristos 			      (char *) t2h_addr (cb, &s, arg2));
6844b169a6bSchristos 	    errcode = errno;
6854b169a6bSchristos 	    break;
6864b169a6bSchristos 
6874b169a6bSchristos 	  case TARGET_LINUX_SYS_readlink:
6884b169a6bSchristos 	    result = readlink ((char *) t2h_addr (cb, &s, arg1),
6894b169a6bSchristos 			       (char *) t2h_addr (cb, &s, arg2),
6904b169a6bSchristos 			       arg3);
6914b169a6bSchristos 	    errcode = errno;
6924b169a6bSchristos 	    break;
6934b169a6bSchristos 
6944b169a6bSchristos 	  case TARGET_LINUX_SYS_readdir:
695*05fa0856Schristos #if SIZEOF_VOID_P == 4
6964b169a6bSchristos 	    result = (int) readdir ((DIR *) t2h_addr (cb, &s, arg1));
6974b169a6bSchristos 	    errcode = errno;
698*05fa0856Schristos #else
699*05fa0856Schristos 	    result = 0;
700*05fa0856Schristos 	    errcode = ENOSYS;
701*05fa0856Schristos #endif
7024b169a6bSchristos 	    break;
7034b169a6bSchristos 
7044b169a6bSchristos #if 0
7054b169a6bSchristos 	  case TARGET_LINUX_SYS_mmap:
7064b169a6bSchristos 	    {
7074b169a6bSchristos 	      result = (int) mmap ((void *) t2h_addr (cb, &s, arg1),
7084b169a6bSchristos 				   arg2, arg3, arg4, arg5, arg6);
7094b169a6bSchristos 	      errcode = errno;
7104b169a6bSchristos 
7114b169a6bSchristos 	      if (errno == 0)
7124b169a6bSchristos 		{
7134b169a6bSchristos 		  sim_core_attach (sd, NULL,
7144b169a6bSchristos 				   0, access_read_write_exec, 0,
7154b169a6bSchristos 				   result, arg2, 0, NULL, NULL);
7164b169a6bSchristos 		}
7174b169a6bSchristos 	    }
7184b169a6bSchristos 	    break;
7194b169a6bSchristos #endif
7204b169a6bSchristos 	  case TARGET_LINUX_SYS_mmap2:
7214b169a6bSchristos 	    {
722*05fa0856Schristos #if SIZEOF_VOID_P == 4  /* Code assumes m32r pointer size matches host.  */
7234b169a6bSchristos 	      void *addr;
7244b169a6bSchristos 	      size_t len;
7254b169a6bSchristos 	      int prot, flags, fildes;
7264b169a6bSchristos 	      off_t off;
7274b169a6bSchristos 
7284b169a6bSchristos 	      addr   = (void *) t2h_addr (cb, &s, arg1);
7294b169a6bSchristos 	      len    = arg2;
7304b169a6bSchristos 	      prot   = arg3;
7314b169a6bSchristos 	      flags  = arg4;
7324b169a6bSchristos 	      fildes = arg5;
7334b169a6bSchristos 	      off    = arg6 << 12;
7344b169a6bSchristos 
7354b169a6bSchristos 	      result = (int) mmap (addr, len, prot, flags, fildes, off);
7364b169a6bSchristos 	      errcode = errno;
7374b169a6bSchristos 	      if (result != -1)
7384b169a6bSchristos 		{
7394b169a6bSchristos 		  char c;
7404b169a6bSchristos 		  if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
7414b169a6bSchristos 		    sim_core_attach (sd, NULL,
7424b169a6bSchristos 				     0, access_read_write_exec, 0,
7434b169a6bSchristos 				     result, len, 0, NULL, NULL);
7444b169a6bSchristos 		}
745*05fa0856Schristos #else
746*05fa0856Schristos 	      result = 0;
747*05fa0856Schristos 	      errcode = ENOSYS;
748*05fa0856Schristos #endif
7494b169a6bSchristos 	    }
7504b169a6bSchristos 	    break;
7514b169a6bSchristos 
7524b169a6bSchristos 	  case TARGET_LINUX_SYS_mmap:
7534b169a6bSchristos 	    {
754*05fa0856Schristos #if SIZEOF_VOID_P == 4  /* Code assumes m32r pointer size matches host.  */
7554b169a6bSchristos 	      void *addr;
7564b169a6bSchristos 	      size_t len;
7574b169a6bSchristos 	      int prot, flags, fildes;
7584b169a6bSchristos 	      off_t off;
7594b169a6bSchristos 
7604b169a6bSchristos 	      addr   = *((void **)  t2h_addr (cb, &s, arg1));
7614b169a6bSchristos 	      len    = *((size_t *) t2h_addr (cb, &s, arg1 + 4));
7624b169a6bSchristos 	      prot   = *((int *)    t2h_addr (cb, &s, arg1 + 8));
7634b169a6bSchristos 	      flags  = *((int *)    t2h_addr (cb, &s, arg1 + 12));
7644b169a6bSchristos 	      fildes = *((int *)    t2h_addr (cb, &s, arg1 + 16));
7654b169a6bSchristos 	      off    = *((off_t *)  t2h_addr (cb, &s, arg1 + 20));
7664b169a6bSchristos 
7674b169a6bSchristos 	      addr   = (void *) T2H_4 ((unsigned int) addr);
7684b169a6bSchristos 	      len    = T2H_4 (len);
7694b169a6bSchristos 	      prot   = T2H_4 (prot);
7704b169a6bSchristos 	      flags  = T2H_4 (flags);
7714b169a6bSchristos 	      fildes = T2H_4 (fildes);
7724b169a6bSchristos 	      off    = T2H_4 (off);
7734b169a6bSchristos 
7744b169a6bSchristos 	      //addr   = (void *) t2h_addr (cb, &s, (unsigned int) addr);
7754b169a6bSchristos 	      result = (int) mmap (addr, len, prot, flags, fildes, off);
7764b169a6bSchristos 	      errcode = errno;
7774b169a6bSchristos 
7784b169a6bSchristos 	      //if (errno == 0)
7794b169a6bSchristos 	      if (result != -1)
7804b169a6bSchristos 		{
7814b169a6bSchristos 		  char c;
7824b169a6bSchristos 		  if (sim_core_read_buffer (sd, NULL, read_map, &c, result, 1) == 0)
7834b169a6bSchristos 		    sim_core_attach (sd, NULL,
7844b169a6bSchristos 				     0, access_read_write_exec, 0,
7854b169a6bSchristos 				     result, len, 0, NULL, NULL);
7864b169a6bSchristos 		}
787*05fa0856Schristos #else
788*05fa0856Schristos 	      result = 0;
789*05fa0856Schristos 	      errcode = ENOSYS;
790*05fa0856Schristos #endif
7914b169a6bSchristos 	    }
7924b169a6bSchristos 	    break;
7934b169a6bSchristos 
7944b169a6bSchristos 	  case TARGET_LINUX_SYS_munmap:
795*05fa0856Schristos 	    result = munmap ((void *) (uintptr_t) arg1, arg2);
7964b169a6bSchristos 	    errcode = errno;
7974b169a6bSchristos 	    if (result != -1)
7984b169a6bSchristos 	      sim_core_detach (sd, NULL, 0, arg2, result);
7994b169a6bSchristos 	    break;
8004b169a6bSchristos 
8014b169a6bSchristos 	  case TARGET_LINUX_SYS_truncate:
8024b169a6bSchristos 	    result = truncate ((char *) t2h_addr (cb, &s, arg1), arg2);
8034b169a6bSchristos 	    errcode = errno;
8044b169a6bSchristos 	    break;
8054b169a6bSchristos 
8064b169a6bSchristos 	  case TARGET_LINUX_SYS_ftruncate:
8074b169a6bSchristos 	    result = ftruncate (arg1, arg2);
8084b169a6bSchristos 	    errcode = errno;
8094b169a6bSchristos 	    break;
8104b169a6bSchristos 
8114b169a6bSchristos 	  case TARGET_LINUX_SYS_fchmod:
8124b169a6bSchristos 	    result = fchmod (arg1, arg2);
8134b169a6bSchristos 	    errcode = errno;
8144b169a6bSchristos 	    break;
8154b169a6bSchristos 
8164b169a6bSchristos 	  case TARGET_LINUX_SYS_fchown32:
8174b169a6bSchristos 	  case TARGET_LINUX_SYS_fchown:
8184b169a6bSchristos 	    result = fchown (arg1, arg2, arg3);
8194b169a6bSchristos 	    errcode = errno;
8204b169a6bSchristos 	    break;
8214b169a6bSchristos 
8224b169a6bSchristos 	  case TARGET_LINUX_SYS_statfs:
8234b169a6bSchristos 	    {
8244b169a6bSchristos 	      struct statfs statbuf;
8254b169a6bSchristos 
8264b169a6bSchristos 	      result = statfs ((char *) t2h_addr (cb, &s, arg1), &statbuf);
8274b169a6bSchristos 	      errcode = errno;
8284b169a6bSchristos 
8294b169a6bSchristos 	      if (result != 0)
8304b169a6bSchristos 		break;
8314b169a6bSchristos 
8324b169a6bSchristos 	      translate_endian_h2t (&statbuf, sizeof(statbuf));
8334b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf))
8344b169a6bSchristos 		  != sizeof(statbuf))
8354b169a6bSchristos 		{
8364b169a6bSchristos 		  result = -1;
8374b169a6bSchristos 		  errcode = EINVAL;
8384b169a6bSchristos 		}
8394b169a6bSchristos 	    }
8404b169a6bSchristos 	    break;
8414b169a6bSchristos 
8424b169a6bSchristos 	  case TARGET_LINUX_SYS_fstatfs:
8434b169a6bSchristos 	    {
8444b169a6bSchristos 	      struct statfs statbuf;
8454b169a6bSchristos 
8464b169a6bSchristos 	      result = fstatfs (arg1, &statbuf);
8474b169a6bSchristos 	      errcode = errno;
8484b169a6bSchristos 
8494b169a6bSchristos 	      if (result != 0)
8504b169a6bSchristos 		break;
8514b169a6bSchristos 
8524b169a6bSchristos 	      translate_endian_h2t (&statbuf, sizeof(statbuf));
8534b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &statbuf, sizeof(statbuf))
8544b169a6bSchristos 		  != sizeof(statbuf))
8554b169a6bSchristos 		{
8564b169a6bSchristos 		  result = -1;
8574b169a6bSchristos 		  errcode = EINVAL;
8584b169a6bSchristos 		}
8594b169a6bSchristos 	    }
8604b169a6bSchristos 	    break;
8614b169a6bSchristos 
8624b169a6bSchristos 	  case TARGET_LINUX_SYS_syslog:
863*05fa0856Schristos 	    syslog (arg1, "%s", (char *) t2h_addr (cb, &s, arg2));
864*05fa0856Schristos 	    result = 0;
8654b169a6bSchristos 	    errcode = errno;
8664b169a6bSchristos 	    break;
8674b169a6bSchristos 
8684b169a6bSchristos 	  case TARGET_LINUX_SYS_setitimer:
8694b169a6bSchristos 	    {
8704b169a6bSchristos 	      struct itimerval value, ovalue;
8714b169a6bSchristos 
8724b169a6bSchristos 	      value = *((struct itimerval *) t2h_addr (cb, &s, arg2));
8734b169a6bSchristos 	      translate_endian_t2h (&value, sizeof(value));
8744b169a6bSchristos 
8754b169a6bSchristos 	      if (arg2 == 0)
8764b169a6bSchristos 		{
8774b169a6bSchristos 		  result = setitimer (arg1, &value, NULL);
8784b169a6bSchristos 		  errcode = errno;
8794b169a6bSchristos 		}
8804b169a6bSchristos 	      else
8814b169a6bSchristos 		{
8824b169a6bSchristos 		  result = setitimer (arg1, &value, &ovalue);
8834b169a6bSchristos 		  errcode = errno;
8844b169a6bSchristos 
8854b169a6bSchristos 		  if (result != 0)
8864b169a6bSchristos 		    break;
8874b169a6bSchristos 
8884b169a6bSchristos 		  translate_endian_h2t (&ovalue, sizeof(ovalue));
8894b169a6bSchristos 		  if ((s.write_mem) (cb, &s, arg3, (char *) &ovalue, sizeof(ovalue))
8904b169a6bSchristos 		      != sizeof(ovalue))
8914b169a6bSchristos 		    {
8924b169a6bSchristos 		      result = -1;
8934b169a6bSchristos 		      errcode = EINVAL;
8944b169a6bSchristos 		    }
8954b169a6bSchristos 		}
8964b169a6bSchristos 	    }
8974b169a6bSchristos 	    break;
8984b169a6bSchristos 
8994b169a6bSchristos 	  case TARGET_LINUX_SYS_getitimer:
9004b169a6bSchristos 	    {
9014b169a6bSchristos 	      struct itimerval value;
9024b169a6bSchristos 
9034b169a6bSchristos 	      result = getitimer (arg1, &value);
9044b169a6bSchristos 	      errcode = errno;
9054b169a6bSchristos 
9064b169a6bSchristos 	      if (result != 0)
9074b169a6bSchristos 		break;
9084b169a6bSchristos 
9094b169a6bSchristos 	      translate_endian_h2t (&value, sizeof(value));
9104b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &value, sizeof(value))
9114b169a6bSchristos 		  != sizeof(value))
9124b169a6bSchristos 		{
9134b169a6bSchristos 		  result = -1;
9144b169a6bSchristos 		  errcode = EINVAL;
9154b169a6bSchristos 		}
9164b169a6bSchristos 	    }
9174b169a6bSchristos 	    break;
9184b169a6bSchristos 
9194b169a6bSchristos 	  case TARGET_LINUX_SYS_stat:
9204b169a6bSchristos 	    {
9214b169a6bSchristos 	      char *buf;
9224b169a6bSchristos 	      int buflen;
9234b169a6bSchristos 	      struct stat statbuf;
9244b169a6bSchristos 
9254b169a6bSchristos 	      result = stat ((char *) t2h_addr (cb, &s, arg1), &statbuf);
9264b169a6bSchristos 	      errcode = errno;
9274b169a6bSchristos 	      if (result < 0)
9284b169a6bSchristos 		break;
9294b169a6bSchristos 
9304b169a6bSchristos 	      buflen = cb_host_to_target_stat (cb, NULL, NULL);
9314b169a6bSchristos 	      buf = xmalloc (buflen);
9324b169a6bSchristos 	      if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
9334b169a6bSchristos 		{
9344b169a6bSchristos 		  /* The translation failed.  This is due to an internal
9354b169a6bSchristos 		     host program error, not the target's fault.  */
9364b169a6bSchristos 		  free (buf);
9374b169a6bSchristos 		  result = -1;
9384b169a6bSchristos 		  errcode = ENOSYS;
9394b169a6bSchristos 		  break;
9404b169a6bSchristos 		}
9414b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
9424b169a6bSchristos 		{
9434b169a6bSchristos 		  free (buf);
9444b169a6bSchristos 		  result = -1;
9454b169a6bSchristos 		  errcode = EINVAL;
9464b169a6bSchristos 		  break;
9474b169a6bSchristos 		}
9484b169a6bSchristos 	      free (buf);
9494b169a6bSchristos 	    }
9504b169a6bSchristos 	    break;
9514b169a6bSchristos 
9524b169a6bSchristos 	  case TARGET_LINUX_SYS_lstat:
9534b169a6bSchristos 	    {
9544b169a6bSchristos 	      char *buf;
9554b169a6bSchristos 	      int buflen;
9564b169a6bSchristos 	      struct stat statbuf;
9574b169a6bSchristos 
9584b169a6bSchristos 	      result = lstat ((char *) t2h_addr (cb, &s, arg1), &statbuf);
9594b169a6bSchristos 	      errcode = errno;
9604b169a6bSchristos 	      if (result < 0)
9614b169a6bSchristos 		break;
9624b169a6bSchristos 
9634b169a6bSchristos 	      buflen = cb_host_to_target_stat (cb, NULL, NULL);
9644b169a6bSchristos 	      buf = xmalloc (buflen);
9654b169a6bSchristos 	      if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
9664b169a6bSchristos 		{
9674b169a6bSchristos 		  /* The translation failed.  This is due to an internal
9684b169a6bSchristos 		     host program error, not the target's fault.  */
9694b169a6bSchristos 		  free (buf);
9704b169a6bSchristos 		  result = -1;
9714b169a6bSchristos 		  errcode = ENOSYS;
9724b169a6bSchristos 		  break;
9734b169a6bSchristos 		}
9744b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
9754b169a6bSchristos 		{
9764b169a6bSchristos 		  free (buf);
9774b169a6bSchristos 		  result = -1;
9784b169a6bSchristos 		  errcode = EINVAL;
9794b169a6bSchristos 		  break;
9804b169a6bSchristos 		}
9814b169a6bSchristos 	      free (buf);
9824b169a6bSchristos 	    }
9834b169a6bSchristos 	    break;
9844b169a6bSchristos 
9854b169a6bSchristos 	  case TARGET_LINUX_SYS_fstat:
9864b169a6bSchristos 	    {
9874b169a6bSchristos 	      char *buf;
9884b169a6bSchristos 	      int buflen;
9894b169a6bSchristos 	      struct stat statbuf;
9904b169a6bSchristos 
9914b169a6bSchristos 	      result = fstat (arg1, &statbuf);
9924b169a6bSchristos 	      errcode = errno;
9934b169a6bSchristos 	      if (result < 0)
9944b169a6bSchristos 		break;
9954b169a6bSchristos 
9964b169a6bSchristos 	      buflen = cb_host_to_target_stat (cb, NULL, NULL);
9974b169a6bSchristos 	      buf = xmalloc (buflen);
9984b169a6bSchristos 	      if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
9994b169a6bSchristos 		{
10004b169a6bSchristos 		  /* The translation failed.  This is due to an internal
10014b169a6bSchristos 		     host program error, not the target's fault.  */
10024b169a6bSchristos 		  free (buf);
10034b169a6bSchristos 		  result = -1;
10044b169a6bSchristos 		  errcode = ENOSYS;
10054b169a6bSchristos 		  break;
10064b169a6bSchristos 		}
10074b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, buf, buflen) != buflen)
10084b169a6bSchristos 		{
10094b169a6bSchristos 		  free (buf);
10104b169a6bSchristos 		  result = -1;
10114b169a6bSchristos 		  errcode = EINVAL;
10124b169a6bSchristos 		  break;
10134b169a6bSchristos 		}
10144b169a6bSchristos 	      free (buf);
10154b169a6bSchristos 	    }
10164b169a6bSchristos 	    break;
10174b169a6bSchristos 
10184b169a6bSchristos 	  case TARGET_LINUX_SYS_sysinfo:
10194b169a6bSchristos 	    {
10204b169a6bSchristos 	      struct sysinfo info;
10214b169a6bSchristos 
10224b169a6bSchristos 	      result = sysinfo (&info);
10234b169a6bSchristos 	      errcode = errno;
10244b169a6bSchristos 
10254b169a6bSchristos 	      if (result != 0)
10264b169a6bSchristos 		break;
10274b169a6bSchristos 
10284b169a6bSchristos 	      info.uptime    = H2T_4 (info.uptime);
10294b169a6bSchristos 	      info.loads[0]  = H2T_4 (info.loads[0]);
10304b169a6bSchristos 	      info.loads[1]  = H2T_4 (info.loads[1]);
10314b169a6bSchristos 	      info.loads[2]  = H2T_4 (info.loads[2]);
10324b169a6bSchristos 	      info.totalram  = H2T_4 (info.totalram);
10334b169a6bSchristos 	      info.freeram   = H2T_4 (info.freeram);
10344b169a6bSchristos 	      info.sharedram = H2T_4 (info.sharedram);
10354b169a6bSchristos 	      info.bufferram = H2T_4 (info.bufferram);
10364b169a6bSchristos 	      info.totalswap = H2T_4 (info.totalswap);
10374b169a6bSchristos 	      info.freeswap  = H2T_4 (info.freeswap);
10384b169a6bSchristos 	      info.procs     = H2T_2 (info.procs);
10394b169a6bSchristos #if LINUX_VERSION_CODE >= 0x20400
10404b169a6bSchristos 	      info.totalhigh = H2T_4 (info.totalhigh);
10414b169a6bSchristos 	      info.freehigh  = H2T_4 (info.freehigh);
10424b169a6bSchristos 	      info.mem_unit  = H2T_4 (info.mem_unit);
10434b169a6bSchristos #endif
10444b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg1, (char *) &info, sizeof(info))
10454b169a6bSchristos 		  != sizeof(info))
10464b169a6bSchristos 		{
10474b169a6bSchristos 		  result = -1;
10484b169a6bSchristos 		  errcode = EINVAL;
10494b169a6bSchristos 		}
10504b169a6bSchristos 	    }
10514b169a6bSchristos 	    break;
10524b169a6bSchristos 
10534b169a6bSchristos #if 0
10544b169a6bSchristos 	  case TARGET_LINUX_SYS_ipc:
10554b169a6bSchristos 	    {
10564b169a6bSchristos 	      result = ipc (arg1, arg2, arg3, arg4,
10574b169a6bSchristos 			    (void *) t2h_addr (cb, &s, arg5), arg6);
10584b169a6bSchristos 	      errcode = errno;
10594b169a6bSchristos 	    }
10604b169a6bSchristos 	    break;
10614b169a6bSchristos #endif
10624b169a6bSchristos 
10634b169a6bSchristos 	  case TARGET_LINUX_SYS_fsync:
10644b169a6bSchristos 	    result = fsync (arg1);
10654b169a6bSchristos 	    errcode = errno;
10664b169a6bSchristos 	    break;
10674b169a6bSchristos 
10684b169a6bSchristos 	  case TARGET_LINUX_SYS_uname:
10694b169a6bSchristos 	    /* utsname contains only arrays of char, so it is not necessary
10704b169a6bSchristos 	       to translate endian. */
10714b169a6bSchristos 	    result = uname ((struct utsname *) t2h_addr (cb, &s, arg1));
10724b169a6bSchristos 	    errcode = errno;
10734b169a6bSchristos 	    break;
10744b169a6bSchristos 
10754b169a6bSchristos 	  case TARGET_LINUX_SYS_adjtimex:
10764b169a6bSchristos 	    {
10774b169a6bSchristos 	      struct timex buf;
10784b169a6bSchristos 
10794b169a6bSchristos 	      result = adjtimex (&buf);
10804b169a6bSchristos 	      errcode = errno;
10814b169a6bSchristos 
10824b169a6bSchristos 	      if (result != 0)
10834b169a6bSchristos 		break;
10844b169a6bSchristos 
10854b169a6bSchristos 	      translate_endian_h2t (&buf, sizeof(buf));
10864b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg1, (char *) &buf, sizeof(buf))
10874b169a6bSchristos 		  != sizeof(buf))
10884b169a6bSchristos 		{
10894b169a6bSchristos 		  result = -1;
10904b169a6bSchristos 		  errcode = EINVAL;
10914b169a6bSchristos 		}
10924b169a6bSchristos 	    }
10934b169a6bSchristos 	    break;
10944b169a6bSchristos 
10954b169a6bSchristos 	  case TARGET_LINUX_SYS_mprotect:
1096*05fa0856Schristos 	    result = mprotect ((void *) (uintptr_t) arg1, arg2, arg3);
10974b169a6bSchristos 	    errcode = errno;
10984b169a6bSchristos 	    break;
10994b169a6bSchristos 
11004b169a6bSchristos 	  case TARGET_LINUX_SYS_fchdir:
11014b169a6bSchristos 	    result = fchdir (arg1);
11024b169a6bSchristos 	    errcode = errno;
11034b169a6bSchristos 	    break;
11044b169a6bSchristos 
11054b169a6bSchristos 	  case TARGET_LINUX_SYS_setfsuid32:
11064b169a6bSchristos 	  case TARGET_LINUX_SYS_setfsuid:
11074b169a6bSchristos 	    result = setfsuid (arg1);
11084b169a6bSchristos 	    errcode = errno;
11094b169a6bSchristos 	    break;
11104b169a6bSchristos 
11114b169a6bSchristos 	  case TARGET_LINUX_SYS_setfsgid32:
11124b169a6bSchristos 	  case TARGET_LINUX_SYS_setfsgid:
11134b169a6bSchristos 	    result = setfsgid (arg1);
11144b169a6bSchristos 	    errcode = errno;
11154b169a6bSchristos 	    break;
11164b169a6bSchristos 
11174b169a6bSchristos #if 0
11184b169a6bSchristos 	  case TARGET_LINUX_SYS__llseek:
11194b169a6bSchristos 	    {
11204b169a6bSchristos 	      loff_t buf;
11214b169a6bSchristos 
11224b169a6bSchristos 	      result = _llseek (arg1, arg2, arg3, &buf, arg5);
11234b169a6bSchristos 	      errcode = errno;
11244b169a6bSchristos 
11254b169a6bSchristos 	      if (result != 0)
11264b169a6bSchristos 		break;
11274b169a6bSchristos 
11284b169a6bSchristos 	      translate_endian_h2t (&buf, sizeof(buf));
11294b169a6bSchristos 	      if ((s.write_mem) (cb, &s, t2h_addr (cb, &s, arg4),
11304b169a6bSchristos 				 (char *) &buf, sizeof(buf)) != sizeof(buf))
11314b169a6bSchristos 		{
11324b169a6bSchristos 		  result = -1;
11334b169a6bSchristos 		  errcode = EINVAL;
11344b169a6bSchristos 		}
11354b169a6bSchristos 	    }
11364b169a6bSchristos 	    break;
11374b169a6bSchristos 
11384b169a6bSchristos 	  case TARGET_LINUX_SYS_getdents:
11394b169a6bSchristos 	    {
11404b169a6bSchristos 	      struct dirent dir;
11414b169a6bSchristos 
11424b169a6bSchristos 	      result = getdents (arg1, &dir, arg3);
11434b169a6bSchristos 	      errcode = errno;
11444b169a6bSchristos 
11454b169a6bSchristos 	      if (result != 0)
11464b169a6bSchristos 		break;
11474b169a6bSchristos 
11484b169a6bSchristos 	      dir.d_ino = H2T_4 (dir.d_ino);
11494b169a6bSchristos 	      dir.d_off = H2T_4 (dir.d_off);
11504b169a6bSchristos 	      dir.d_reclen = H2T_2 (dir.d_reclen);
11514b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &dir, sizeof(dir))
11524b169a6bSchristos 		  != sizeof(dir))
11534b169a6bSchristos 		{
11544b169a6bSchristos 		  result = -1;
11554b169a6bSchristos 		  errcode = EINVAL;
11564b169a6bSchristos 		}
11574b169a6bSchristos 	    }
11584b169a6bSchristos 	    break;
11594b169a6bSchristos #endif
11604b169a6bSchristos 
11614b169a6bSchristos 	  case TARGET_LINUX_SYS_flock:
11624b169a6bSchristos 	    result = flock (arg1, arg2);
11634b169a6bSchristos 	    errcode = errno;
11644b169a6bSchristos 	    break;
11654b169a6bSchristos 
11664b169a6bSchristos 	  case TARGET_LINUX_SYS_msync:
1167*05fa0856Schristos 	    result = msync ((void *) (uintptr_t) arg1, arg2, arg3);
11684b169a6bSchristos 	    errcode = errno;
11694b169a6bSchristos 	    break;
11704b169a6bSchristos 
11714b169a6bSchristos 	  case TARGET_LINUX_SYS_readv:
11724b169a6bSchristos 	    {
11734b169a6bSchristos 	      struct iovec vector;
11744b169a6bSchristos 
11754b169a6bSchristos 	      vector = *((struct iovec *) t2h_addr (cb, &s, arg2));
11764b169a6bSchristos 	      translate_endian_t2h (&vector, sizeof(vector));
11774b169a6bSchristos 
11784b169a6bSchristos 	      result = readv (arg1, &vector, arg3);
11794b169a6bSchristos 	      errcode = errno;
11804b169a6bSchristos 	    }
11814b169a6bSchristos 	    break;
11824b169a6bSchristos 
11834b169a6bSchristos 	  case TARGET_LINUX_SYS_writev:
11844b169a6bSchristos 	    {
11854b169a6bSchristos 	      struct iovec vector;
11864b169a6bSchristos 
11874b169a6bSchristos 	      vector = *((struct iovec *) t2h_addr (cb, &s, arg2));
11884b169a6bSchristos 	      translate_endian_t2h (&vector, sizeof(vector));
11894b169a6bSchristos 
11904b169a6bSchristos 	      result = writev (arg1, &vector, arg3);
11914b169a6bSchristos 	      errcode = errno;
11924b169a6bSchristos 	    }
11934b169a6bSchristos 	    break;
11944b169a6bSchristos 
11954b169a6bSchristos 	  case TARGET_LINUX_SYS_fdatasync:
11964b169a6bSchristos 	    result = fdatasync (arg1);
11974b169a6bSchristos 	    errcode = errno;
11984b169a6bSchristos 	    break;
11994b169a6bSchristos 
12004b169a6bSchristos 	  case TARGET_LINUX_SYS_mlock:
12014b169a6bSchristos 	    result = mlock ((void *) t2h_addr (cb, &s, arg1), arg2);
12024b169a6bSchristos 	    errcode = errno;
12034b169a6bSchristos 	    break;
12044b169a6bSchristos 
12054b169a6bSchristos 	  case TARGET_LINUX_SYS_munlock:
12064b169a6bSchristos 	    result = munlock ((void *) t2h_addr (cb, &s, arg1), arg2);
12074b169a6bSchristos 	    errcode = errno;
12084b169a6bSchristos 	    break;
12094b169a6bSchristos 
12104b169a6bSchristos 	  case TARGET_LINUX_SYS_nanosleep:
12114b169a6bSchristos 	    {
12124b169a6bSchristos 	      struct timespec req, rem;
12134b169a6bSchristos 
12144b169a6bSchristos 	      req = *((struct timespec *) t2h_addr (cb, &s, arg2));
12154b169a6bSchristos 	      translate_endian_t2h (&req, sizeof(req));
12164b169a6bSchristos 
12174b169a6bSchristos 	      result = nanosleep (&req, &rem);
12184b169a6bSchristos 	      errcode = errno;
12194b169a6bSchristos 
12204b169a6bSchristos 	      if (result != 0)
12214b169a6bSchristos 		break;
12224b169a6bSchristos 
12234b169a6bSchristos 	      translate_endian_h2t (&rem, sizeof(rem));
12244b169a6bSchristos 	      if ((s.write_mem) (cb, &s, arg2, (char *) &rem, sizeof(rem))
12254b169a6bSchristos 		  != sizeof(rem))
12264b169a6bSchristos 		{
12274b169a6bSchristos 		  result = -1;
12284b169a6bSchristos 		  errcode = EINVAL;
12294b169a6bSchristos 		}
12304b169a6bSchristos 	    }
12314b169a6bSchristos 	    break;
12324b169a6bSchristos 
12334b169a6bSchristos 	  case TARGET_LINUX_SYS_mremap: /* FIXME */
1234*05fa0856Schristos #if SIZEOF_VOID_P == 4  /* Code assumes m32r pointer size matches host.  */
12354b169a6bSchristos 	    result = (int) mremap ((void *) t2h_addr (cb, &s, arg1), arg2, arg3, arg4);
12364b169a6bSchristos 	    errcode = errno;
1237*05fa0856Schristos #else
1238*05fa0856Schristos 	    result = -1;
1239*05fa0856Schristos 	    errcode = ENOSYS;
1240*05fa0856Schristos #endif
12414b169a6bSchristos 	    break;
12424b169a6bSchristos 
12434b169a6bSchristos 	  case TARGET_LINUX_SYS_getresuid32:
12444b169a6bSchristos 	  case TARGET_LINUX_SYS_getresuid:
12454b169a6bSchristos 	    {
12464b169a6bSchristos 	      uid_t ruid, euid, suid;
12474b169a6bSchristos 
12484b169a6bSchristos 	      result = getresuid (&ruid, &euid, &suid);
12494b169a6bSchristos 	      errcode = errno;
12504b169a6bSchristos 
12514b169a6bSchristos 	      if (result != 0)
12524b169a6bSchristos 		break;
12534b169a6bSchristos 
12544b169a6bSchristos 	      *((uid_t *) t2h_addr (cb, &s, arg1)) = H2T_4 (ruid);
12554b169a6bSchristos 	      *((uid_t *) t2h_addr (cb, &s, arg2)) = H2T_4 (euid);
12564b169a6bSchristos 	      *((uid_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (suid);
12574b169a6bSchristos 	    }
12584b169a6bSchristos 	    break;
12594b169a6bSchristos 
12604b169a6bSchristos 	  case TARGET_LINUX_SYS_poll:
12614b169a6bSchristos 	    {
12624b169a6bSchristos 	      struct pollfd ufds;
12634b169a6bSchristos 
12644b169a6bSchristos 	      ufds = *((struct pollfd *) t2h_addr (cb, &s, arg1));
12654b169a6bSchristos 	      ufds.fd = T2H_4 (ufds.fd);
12664b169a6bSchristos 	      ufds.events = T2H_2 (ufds.events);
12674b169a6bSchristos 	      ufds.revents = T2H_2 (ufds.revents);
12684b169a6bSchristos 
12694b169a6bSchristos 	      result = poll (&ufds, arg2, arg3);
12704b169a6bSchristos 	      errcode = errno;
12714b169a6bSchristos 	    }
12724b169a6bSchristos 	    break;
12734b169a6bSchristos 
12744b169a6bSchristos 	  case TARGET_LINUX_SYS_getresgid32:
12754b169a6bSchristos 	  case TARGET_LINUX_SYS_getresgid:
12764b169a6bSchristos 	    {
12774b169a6bSchristos 	      uid_t rgid, egid, sgid;
12784b169a6bSchristos 
12794b169a6bSchristos 	      result = getresgid (&rgid, &egid, &sgid);
12804b169a6bSchristos 	      errcode = errno;
12814b169a6bSchristos 
12824b169a6bSchristos 	      if (result != 0)
12834b169a6bSchristos 		break;
12844b169a6bSchristos 
12854b169a6bSchristos 	      *((uid_t *) t2h_addr (cb, &s, arg1)) = H2T_4 (rgid);
12864b169a6bSchristos 	      *((uid_t *) t2h_addr (cb, &s, arg2)) = H2T_4 (egid);
12874b169a6bSchristos 	      *((uid_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (sgid);
12884b169a6bSchristos 	    }
12894b169a6bSchristos 	    break;
12904b169a6bSchristos 
12914b169a6bSchristos 	  case TARGET_LINUX_SYS_pread:
12924b169a6bSchristos 	    result =  pread (arg1, (void *) t2h_addr (cb, &s, arg2), arg3, arg4);
12934b169a6bSchristos 	    errcode = errno;
12944b169a6bSchristos 	    break;
12954b169a6bSchristos 
12964b169a6bSchristos 	  case TARGET_LINUX_SYS_pwrite:
12974b169a6bSchristos 	    result =  pwrite (arg1, (void *) t2h_addr (cb, &s, arg2), arg3, arg4);
12984b169a6bSchristos 	    errcode = errno;
12994b169a6bSchristos 	    break;
13004b169a6bSchristos 
13014b169a6bSchristos 	  case TARGET_LINUX_SYS_chown32:
13024b169a6bSchristos 	  case TARGET_LINUX_SYS_chown:
13034b169a6bSchristos 	    result = chown ((char *) t2h_addr (cb, &s, arg1), arg2, arg3);
13044b169a6bSchristos 	    errcode = errno;
13054b169a6bSchristos 	    break;
13064b169a6bSchristos 
13074b169a6bSchristos 	  case TARGET_LINUX_SYS_getcwd:
1308*05fa0856Schristos 	    {
1309*05fa0856Schristos 	      void *ret;
1310*05fa0856Schristos 
1311*05fa0856Schristos 	      ret = getcwd ((char *) t2h_addr (cb, &s, arg1), arg2);
1312*05fa0856Schristos 	      result = ret == NULL ? 0 : arg1;
13134b169a6bSchristos 	      errcode = errno;
1314*05fa0856Schristos 	    }
13154b169a6bSchristos 	    break;
13164b169a6bSchristos 
13174b169a6bSchristos 	  case TARGET_LINUX_SYS_sendfile:
13184b169a6bSchristos 	    {
13194b169a6bSchristos 	      off_t offset;
13204b169a6bSchristos 
13214b169a6bSchristos 	      offset = *((off_t *) t2h_addr (cb, &s, arg3));
13224b169a6bSchristos 	      offset = T2H_4 (offset);
13234b169a6bSchristos 
13244b169a6bSchristos 	      result = sendfile (arg1, arg2, &offset, arg3);
13254b169a6bSchristos 	      errcode = errno;
13264b169a6bSchristos 
13274b169a6bSchristos 	      if (result != 0)
13284b169a6bSchristos 		break;
13294b169a6bSchristos 
13304b169a6bSchristos 	      *((off_t *) t2h_addr (cb, &s, arg3)) = H2T_4 (offset);
13314b169a6bSchristos 	    }
13324b169a6bSchristos 	    break;
13334b169a6bSchristos 
13344b169a6bSchristos 	  default:
13354b169a6bSchristos 	    result = -1;
13364b169a6bSchristos 	    errcode = ENOSYS;
13374b169a6bSchristos 	    break;
13384b169a6bSchristos 	  }
13394b169a6bSchristos 
13404b169a6bSchristos 	if (result == -1)
13414b169a6bSchristos 	  m32rbf_h_gr_set (current_cpu, 0, -errcode);
13424b169a6bSchristos 	else
13434b169a6bSchristos 	  m32rbf_h_gr_set (current_cpu, 0, result);
13444b169a6bSchristos 	break;
13454b169a6bSchristos       }
13464b169a6bSchristos #endif
13474b169a6bSchristos 
13484e98e3e1Schristos     case TRAP_BREAKPOINT:
13494e98e3e1Schristos       sim_engine_halt (sd, current_cpu, NULL, pc,
13504e98e3e1Schristos 		       sim_stopped, SIM_SIGTRAP);
13514e98e3e1Schristos       break;
13524e98e3e1Schristos 
13534e98e3e1Schristos     case TRAP_FLUSH_CACHE:
13544e98e3e1Schristos       /* Do nothing.  */
13554e98e3e1Schristos       break;
13564e98e3e1Schristos 
13574b169a6bSchristos     case_default:
13584e98e3e1Schristos     default:
13594e98e3e1Schristos       {
13604b169a6bSchristos 	/* The new pc is the trap vector entry.
13614b169a6bSchristos 	   We assume there's a branch there to some handler.
13624b169a6bSchristos 	   Use cr5 as EVB (EIT Vector Base) register.  */
13634e98e3e1Schristos 	/* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
13644e98e3e1Schristos 	USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
13654e98e3e1Schristos 	return new_pc;
13664e98e3e1Schristos       }
13674e98e3e1Schristos     }
13684e98e3e1Schristos 
13694e98e3e1Schristos   /* Fake an "rte" insn.  */
13704e98e3e1Schristos   /* FIXME: Should duplicate all of rte processing.  */
13714e98e3e1Schristos   return (pc & -4) + 4;
13724e98e3e1Schristos }
1373