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