]> git.proxmox.com Git - qemu.git/blob - linux-user/syscall.c
linux-user mknodat() syscall, by Thayne Harbaugh.
[qemu.git] / linux-user / syscall.c
1 /*
2 * Linux syscalls
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <elf.h>
25 #include <endian.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <time.h>
30 #include <sys/types.h>
31 #include <sys/ipc.h>
32 #include <sys/msg.h>
33 #include <sys/wait.h>
34 #include <sys/time.h>
35 #include <sys/stat.h>
36 #include <sys/mount.h>
37 #include <sys/prctl.h>
38 #include <sys/resource.h>
39 #include <sys/mman.h>
40 #include <sys/swap.h>
41 #include <signal.h>
42 #include <sched.h>
43 #include <sys/socket.h>
44 #include <sys/uio.h>
45 #include <sys/poll.h>
46 #include <sys/times.h>
47 #include <sys/shm.h>
48 #include <sys/sem.h>
49 #include <sys/statfs.h>
50 #include <utime.h>
51 #include <sys/sysinfo.h>
52 //#include <sys/user.h>
53 #include <netinet/ip.h>
54 #include <netinet/tcp.h>
55
56 #define termios host_termios
57 #define winsize host_winsize
58 #define termio host_termio
59 #define sgttyb host_sgttyb /* same as target */
60 #define tchars host_tchars /* same as target */
61 #define ltchars host_ltchars /* same as target */
62
63 #include <linux/termios.h>
64 #include <linux/unistd.h>
65 #include <linux/utsname.h>
66 #include <linux/cdrom.h>
67 #include <linux/hdreg.h>
68 #include <linux/soundcard.h>
69 #include <linux/dirent.h>
70 #include <linux/kd.h>
71
72 #include "qemu.h"
73
74 //#define DEBUG
75
76 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
77 || defined(TARGET_M68K) || defined(TARGET_SH4)
78 /* 16 bit uid wrappers emulation */
79 #define USE_UID16
80 #endif
81
82 //#include <linux/msdos_fs.h>
83 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
84 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
85
86
87 #undef _syscall0
88 #undef _syscall1
89 #undef _syscall2
90 #undef _syscall3
91 #undef _syscall4
92 #undef _syscall5
93 #undef _syscall6
94
95 #define _syscall0(type,name) \
96 type name (void) \
97 { \
98 return syscall(__NR_##name); \
99 }
100
101 #define _syscall1(type,name,type1,arg1) \
102 type name (type1 arg1) \
103 { \
104 return syscall(__NR_##name, arg1); \
105 }
106
107 #define _syscall2(type,name,type1,arg1,type2,arg2) \
108 type name (type1 arg1,type2 arg2) \
109 { \
110 return syscall(__NR_##name, arg1, arg2); \
111 }
112
113 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
114 type name (type1 arg1,type2 arg2,type3 arg3) \
115 { \
116 return syscall(__NR_##name, arg1, arg2, arg3); \
117 }
118
119 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
120 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
121 { \
122 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
123 }
124
125 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
126 type5,arg5) \
127 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
128 { \
129 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
130 }
131
132
133 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
134 type5,arg5,type6,arg6) \
135 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
136 { \
137 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
138 }
139
140
141 #define __NR_sys_uname __NR_uname
142 #define __NR_sys_getcwd1 __NR_getcwd
143 #define __NR_sys_getdents __NR_getdents
144 #define __NR_sys_getdents64 __NR_getdents64
145 #define __NR_sys_mkdirat __NR_mkdirat
146 #define __NR_sys_mknodat __NR_mknodat
147 #define __NR_sys_openat __NR_openat
148 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
149 #define __NR_sys_syslog __NR_syslog
150 #define __NR_sys_tgkill __NR_tgkill
151 #define __NR_sys_tkill __NR_tkill
152
153 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
154 #define __NR__llseek __NR_lseek
155 #endif
156
157 #ifdef __NR_gettid
158 _syscall0(int, gettid)
159 #else
160 static int gettid(void) {
161 return -ENOSYS;
162 }
163 #endif
164 _syscall1(int,sys_uname,struct new_utsname *,buf)
165 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
166 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
167 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
168 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
169 #endif
170 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
171 loff_t *, res, uint, wh);
172 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
173 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
174 #endif
175 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
176 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
177 mode_t,mode,dev_t,dev)
178 #endif
179 #if defined(TARGET_NR_openat) && defined(__NR_openat)
180 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
181 #endif
182 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
183 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
184 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
185 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
186 #endif
187 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
188 _syscall2(int,sys_tkill,int,tid,int,sig)
189 #endif
190 #ifdef __NR_exit_group
191 _syscall1(int,exit_group,int,error_code)
192 #endif
193 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
194 _syscall1(int,set_tid_address,int *,tidptr)
195 #endif
196
197 extern int personality(int);
198 extern int flock(int, int);
199 extern int setfsuid(int);
200 extern int setfsgid(int);
201 extern int setresuid(uid_t, uid_t, uid_t);
202 extern int getresuid(uid_t *, uid_t *, uid_t *);
203 extern int setresgid(gid_t, gid_t, gid_t);
204 extern int getresgid(gid_t *, gid_t *, gid_t *);
205 extern int setgroups(int, gid_t *);
206
207 /*
208 * This list is the union of errno values overridden in asm-<arch>/errno.h
209 * minus the errnos that are not actually generic to all archs.
210 */
211 static uint16_t host_to_target_errno_table[1200] = {
212 [EIDRM] = TARGET_EIDRM,
213 [ECHRNG] = TARGET_ECHRNG,
214 [EL2NSYNC] = TARGET_EL2NSYNC,
215 [EL3HLT] = TARGET_EL3HLT,
216 [EL3RST] = TARGET_EL3RST,
217 [ELNRNG] = TARGET_ELNRNG,
218 [EUNATCH] = TARGET_EUNATCH,
219 [ENOCSI] = TARGET_ENOCSI,
220 [EL2HLT] = TARGET_EL2HLT,
221 [EDEADLK] = TARGET_EDEADLK,
222 [ENOLCK] = TARGET_ENOLCK,
223 [EBADE] = TARGET_EBADE,
224 [EBADR] = TARGET_EBADR,
225 [EXFULL] = TARGET_EXFULL,
226 [ENOANO] = TARGET_ENOANO,
227 [EBADRQC] = TARGET_EBADRQC,
228 [EBADSLT] = TARGET_EBADSLT,
229 [EBFONT] = TARGET_EBFONT,
230 [ENOSTR] = TARGET_ENOSTR,
231 [ENODATA] = TARGET_ENODATA,
232 [ETIME] = TARGET_ETIME,
233 [ENOSR] = TARGET_ENOSR,
234 [ENONET] = TARGET_ENONET,
235 [ENOPKG] = TARGET_ENOPKG,
236 [EREMOTE] = TARGET_EREMOTE,
237 [ENOLINK] = TARGET_ENOLINK,
238 [EADV] = TARGET_EADV,
239 [ESRMNT] = TARGET_ESRMNT,
240 [ECOMM] = TARGET_ECOMM,
241 [EPROTO] = TARGET_EPROTO,
242 [EDOTDOT] = TARGET_EDOTDOT,
243 [EMULTIHOP] = TARGET_EMULTIHOP,
244 [EBADMSG] = TARGET_EBADMSG,
245 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
246 [EOVERFLOW] = TARGET_EOVERFLOW,
247 [ENOTUNIQ] = TARGET_ENOTUNIQ,
248 [EBADFD] = TARGET_EBADFD,
249 [EREMCHG] = TARGET_EREMCHG,
250 [ELIBACC] = TARGET_ELIBACC,
251 [ELIBBAD] = TARGET_ELIBBAD,
252 [ELIBSCN] = TARGET_ELIBSCN,
253 [ELIBMAX] = TARGET_ELIBMAX,
254 [ELIBEXEC] = TARGET_ELIBEXEC,
255 [EILSEQ] = TARGET_EILSEQ,
256 [ENOSYS] = TARGET_ENOSYS,
257 [ELOOP] = TARGET_ELOOP,
258 [ERESTART] = TARGET_ERESTART,
259 [ESTRPIPE] = TARGET_ESTRPIPE,
260 [ENOTEMPTY] = TARGET_ENOTEMPTY,
261 [EUSERS] = TARGET_EUSERS,
262 [ENOTSOCK] = TARGET_ENOTSOCK,
263 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
264 [EMSGSIZE] = TARGET_EMSGSIZE,
265 [EPROTOTYPE] = TARGET_EPROTOTYPE,
266 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
267 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
268 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
269 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
270 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
271 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
272 [EADDRINUSE] = TARGET_EADDRINUSE,
273 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
274 [ENETDOWN] = TARGET_ENETDOWN,
275 [ENETUNREACH] = TARGET_ENETUNREACH,
276 [ENETRESET] = TARGET_ENETRESET,
277 [ECONNABORTED] = TARGET_ECONNABORTED,
278 [ECONNRESET] = TARGET_ECONNRESET,
279 [ENOBUFS] = TARGET_ENOBUFS,
280 [EISCONN] = TARGET_EISCONN,
281 [ENOTCONN] = TARGET_ENOTCONN,
282 [EUCLEAN] = TARGET_EUCLEAN,
283 [ENOTNAM] = TARGET_ENOTNAM,
284 [ENAVAIL] = TARGET_ENAVAIL,
285 [EISNAM] = TARGET_EISNAM,
286 [EREMOTEIO] = TARGET_EREMOTEIO,
287 [ESHUTDOWN] = TARGET_ESHUTDOWN,
288 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
289 [ETIMEDOUT] = TARGET_ETIMEDOUT,
290 [ECONNREFUSED] = TARGET_ECONNREFUSED,
291 [EHOSTDOWN] = TARGET_EHOSTDOWN,
292 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
293 [EALREADY] = TARGET_EALREADY,
294 [EINPROGRESS] = TARGET_EINPROGRESS,
295 [ESTALE] = TARGET_ESTALE,
296 [ECANCELED] = TARGET_ECANCELED,
297 [ENOMEDIUM] = TARGET_ENOMEDIUM,
298 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
299 #ifdef ENOKEY
300 [ENOKEY] = TARGET_ENOKEY,
301 #endif
302 #ifdef EKEYEXPIRED
303 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
304 #endif
305 #ifdef EKEYREVOKED
306 [EKEYREVOKED] = TARGET_EKEYREVOKED,
307 #endif
308 #ifdef EKEYREJECTED
309 [EKEYREJECTED] = TARGET_EKEYREJECTED,
310 #endif
311 #ifdef EOWNERDEAD
312 [EOWNERDEAD] = TARGET_EOWNERDEAD,
313 #endif
314 #ifdef ENOTRECOVERABLE
315 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
316 #endif
317 };
318
319 static inline int host_to_target_errno(int err)
320 {
321 if(host_to_target_errno_table[err])
322 return host_to_target_errno_table[err];
323 return err;
324 }
325
326 static inline long get_errno(long ret)
327 {
328 if (ret == -1)
329 return -host_to_target_errno(errno);
330 else
331 return ret;
332 }
333
334 static inline int is_error(long ret)
335 {
336 return (unsigned long)ret >= (unsigned long)(-4096);
337 }
338
339 static target_ulong target_brk;
340 static target_ulong target_original_brk;
341
342 void target_set_brk(target_ulong new_brk)
343 {
344 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
345 }
346
347 long do_brk(target_ulong new_brk)
348 {
349 target_ulong brk_page;
350 long mapped_addr;
351 int new_alloc_size;
352
353 if (!new_brk)
354 return target_brk;
355 if (new_brk < target_original_brk)
356 return -ENOMEM;
357
358 brk_page = HOST_PAGE_ALIGN(target_brk);
359
360 /* If the new brk is less than this, set it and we're done... */
361 if (new_brk < brk_page) {
362 target_brk = new_brk;
363 return target_brk;
364 }
365
366 /* We need to allocate more memory after the brk... */
367 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
368 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
369 PROT_READ|PROT_WRITE,
370 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
371 if (is_error(mapped_addr)) {
372 return mapped_addr;
373 } else {
374 target_brk = new_brk;
375 return target_brk;
376 }
377 }
378
379 static inline fd_set *target_to_host_fds(fd_set *fds,
380 target_long *target_fds, int n)
381 {
382 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
383 return (fd_set *)target_fds;
384 #else
385 int i, b;
386 if (target_fds) {
387 FD_ZERO(fds);
388 for(i = 0;i < n; i++) {
389 b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
390 (i & (TARGET_LONG_BITS - 1))) & 1;
391 if (b)
392 FD_SET(i, fds);
393 }
394 return fds;
395 } else {
396 return NULL;
397 }
398 #endif
399 }
400
401 static inline void host_to_target_fds(target_long *target_fds,
402 fd_set *fds, int n)
403 {
404 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
405 /* nothing to do */
406 #else
407 int i, nw, j, k;
408 target_long v;
409
410 if (target_fds) {
411 nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS;
412 k = 0;
413 for(i = 0;i < nw; i++) {
414 v = 0;
415 for(j = 0; j < TARGET_LONG_BITS; j++) {
416 v |= ((FD_ISSET(k, fds) != 0) << j);
417 k++;
418 }
419 target_fds[i] = tswapl(v);
420 }
421 }
422 #endif
423 }
424
425 #if defined(__alpha__)
426 #define HOST_HZ 1024
427 #else
428 #define HOST_HZ 100
429 #endif
430
431 static inline long host_to_target_clock_t(long ticks)
432 {
433 #if HOST_HZ == TARGET_HZ
434 return ticks;
435 #else
436 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
437 #endif
438 }
439
440 static inline void host_to_target_rusage(target_ulong target_addr,
441 const struct rusage *rusage)
442 {
443 struct target_rusage *target_rusage;
444
445 lock_user_struct(target_rusage, target_addr, 0);
446 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
447 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
448 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
449 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
450 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
451 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
452 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
453 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
454 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
455 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
456 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
457 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
458 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
459 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
460 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
461 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
462 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
463 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
464 unlock_user_struct(target_rusage, target_addr, 1);
465 }
466
467 static inline void target_to_host_timeval(struct timeval *tv,
468 target_ulong target_addr)
469 {
470 struct target_timeval *target_tv;
471
472 lock_user_struct(target_tv, target_addr, 1);
473 tv->tv_sec = tswapl(target_tv->tv_sec);
474 tv->tv_usec = tswapl(target_tv->tv_usec);
475 unlock_user_struct(target_tv, target_addr, 0);
476 }
477
478 static inline void host_to_target_timeval(target_ulong target_addr,
479 const struct timeval *tv)
480 {
481 struct target_timeval *target_tv;
482
483 lock_user_struct(target_tv, target_addr, 0);
484 target_tv->tv_sec = tswapl(tv->tv_sec);
485 target_tv->tv_usec = tswapl(tv->tv_usec);
486 unlock_user_struct(target_tv, target_addr, 1);
487 }
488
489
490 static long do_select(long n,
491 target_ulong rfd_p, target_ulong wfd_p,
492 target_ulong efd_p, target_ulong target_tv)
493 {
494 fd_set rfds, wfds, efds;
495 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
496 target_long *target_rfds, *target_wfds, *target_efds;
497 struct timeval tv, *tv_ptr;
498 long ret;
499 int ok;
500
501 if (rfd_p) {
502 target_rfds = lock_user(rfd_p, sizeof(target_long) * n, 1);
503 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
504 } else {
505 target_rfds = NULL;
506 rfds_ptr = NULL;
507 }
508 if (wfd_p) {
509 target_wfds = lock_user(wfd_p, sizeof(target_long) * n, 1);
510 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
511 } else {
512 target_wfds = NULL;
513 wfds_ptr = NULL;
514 }
515 if (efd_p) {
516 target_efds = lock_user(efd_p, sizeof(target_long) * n, 1);
517 efds_ptr = target_to_host_fds(&efds, target_efds, n);
518 } else {
519 target_efds = NULL;
520 efds_ptr = NULL;
521 }
522
523 if (target_tv) {
524 target_to_host_timeval(&tv, target_tv);
525 tv_ptr = &tv;
526 } else {
527 tv_ptr = NULL;
528 }
529 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
530 ok = !is_error(ret);
531
532 if (ok) {
533 host_to_target_fds(target_rfds, rfds_ptr, n);
534 host_to_target_fds(target_wfds, wfds_ptr, n);
535 host_to_target_fds(target_efds, efds_ptr, n);
536
537 if (target_tv) {
538 host_to_target_timeval(target_tv, &tv);
539 }
540 }
541 if (target_rfds)
542 unlock_user(target_rfds, rfd_p, ok ? sizeof(target_long) * n : 0);
543 if (target_wfds)
544 unlock_user(target_wfds, wfd_p, ok ? sizeof(target_long) * n : 0);
545 if (target_efds)
546 unlock_user(target_efds, efd_p, ok ? sizeof(target_long) * n : 0);
547
548 return ret;
549 }
550
551 static inline void target_to_host_sockaddr(struct sockaddr *addr,
552 target_ulong target_addr,
553 socklen_t len)
554 {
555 struct target_sockaddr *target_saddr;
556
557 target_saddr = lock_user(target_addr, len, 1);
558 memcpy(addr, target_saddr, len);
559 addr->sa_family = tswap16(target_saddr->sa_family);
560 unlock_user(target_saddr, target_addr, 0);
561 }
562
563 static inline void host_to_target_sockaddr(target_ulong target_addr,
564 struct sockaddr *addr,
565 socklen_t len)
566 {
567 struct target_sockaddr *target_saddr;
568
569 target_saddr = lock_user(target_addr, len, 0);
570 memcpy(target_saddr, addr, len);
571 target_saddr->sa_family = tswap16(addr->sa_family);
572 unlock_user(target_saddr, target_addr, len);
573 }
574
575 /* ??? Should this also swap msgh->name? */
576 static inline void target_to_host_cmsg(struct msghdr *msgh,
577 struct target_msghdr *target_msgh)
578 {
579 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
580 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
581 socklen_t space = 0;
582
583 while (cmsg && target_cmsg) {
584 void *data = CMSG_DATA(cmsg);
585 void *target_data = TARGET_CMSG_DATA(target_cmsg);
586
587 int len = tswapl(target_cmsg->cmsg_len)
588 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
589
590 space += CMSG_SPACE(len);
591 if (space > msgh->msg_controllen) {
592 space -= CMSG_SPACE(len);
593 gemu_log("Host cmsg overflow\n");
594 break;
595 }
596
597 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
598 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
599 cmsg->cmsg_len = CMSG_LEN(len);
600
601 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
602 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
603 memcpy(data, target_data, len);
604 } else {
605 int *fd = (int *)data;
606 int *target_fd = (int *)target_data;
607 int i, numfds = len / sizeof(int);
608
609 for (i = 0; i < numfds; i++)
610 fd[i] = tswap32(target_fd[i]);
611 }
612
613 cmsg = CMSG_NXTHDR(msgh, cmsg);
614 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
615 }
616
617 msgh->msg_controllen = space;
618 }
619
620 /* ??? Should this also swap msgh->name? */
621 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
622 struct msghdr *msgh)
623 {
624 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
625 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
626 socklen_t space = 0;
627
628 while (cmsg && target_cmsg) {
629 void *data = CMSG_DATA(cmsg);
630 void *target_data = TARGET_CMSG_DATA(target_cmsg);
631
632 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
633
634 space += TARGET_CMSG_SPACE(len);
635 if (space > tswapl(target_msgh->msg_controllen)) {
636 space -= TARGET_CMSG_SPACE(len);
637 gemu_log("Target cmsg overflow\n");
638 break;
639 }
640
641 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
642 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
643 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
644
645 if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
646 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
647 memcpy(target_data, data, len);
648 } else {
649 int *fd = (int *)data;
650 int *target_fd = (int *)target_data;
651 int i, numfds = len / sizeof(int);
652
653 for (i = 0; i < numfds; i++)
654 target_fd[i] = tswap32(fd[i]);
655 }
656
657 cmsg = CMSG_NXTHDR(msgh, cmsg);
658 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
659 }
660
661 msgh->msg_controllen = tswapl(space);
662 }
663
664 static long do_setsockopt(int sockfd, int level, int optname,
665 target_ulong optval, socklen_t optlen)
666 {
667 int val, ret;
668
669 switch(level) {
670 case SOL_TCP:
671 /* TCP options all take an 'int' value. */
672 if (optlen < sizeof(uint32_t))
673 return -EINVAL;
674
675 val = tget32(optval);
676 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
677 break;
678 case SOL_IP:
679 switch(optname) {
680 case IP_TOS:
681 case IP_TTL:
682 case IP_HDRINCL:
683 case IP_ROUTER_ALERT:
684 case IP_RECVOPTS:
685 case IP_RETOPTS:
686 case IP_PKTINFO:
687 case IP_MTU_DISCOVER:
688 case IP_RECVERR:
689 case IP_RECVTOS:
690 #ifdef IP_FREEBIND
691 case IP_FREEBIND:
692 #endif
693 case IP_MULTICAST_TTL:
694 case IP_MULTICAST_LOOP:
695 val = 0;
696 if (optlen >= sizeof(uint32_t)) {
697 val = tget32(optval);
698 } else if (optlen >= 1) {
699 val = tget8(optval);
700 }
701 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
702 break;
703 default:
704 goto unimplemented;
705 }
706 break;
707 case TARGET_SOL_SOCKET:
708 switch (optname) {
709 /* Options with 'int' argument. */
710 case TARGET_SO_DEBUG:
711 optname = SO_DEBUG;
712 break;
713 case TARGET_SO_REUSEADDR:
714 optname = SO_REUSEADDR;
715 break;
716 case TARGET_SO_TYPE:
717 optname = SO_TYPE;
718 break;
719 case TARGET_SO_ERROR:
720 optname = SO_ERROR;
721 break;
722 case TARGET_SO_DONTROUTE:
723 optname = SO_DONTROUTE;
724 break;
725 case TARGET_SO_BROADCAST:
726 optname = SO_BROADCAST;
727 break;
728 case TARGET_SO_SNDBUF:
729 optname = SO_SNDBUF;
730 break;
731 case TARGET_SO_RCVBUF:
732 optname = SO_RCVBUF;
733 break;
734 case TARGET_SO_KEEPALIVE:
735 optname = SO_KEEPALIVE;
736 break;
737 case TARGET_SO_OOBINLINE:
738 optname = SO_OOBINLINE;
739 break;
740 case TARGET_SO_NO_CHECK:
741 optname = SO_NO_CHECK;
742 break;
743 case TARGET_SO_PRIORITY:
744 optname = SO_PRIORITY;
745 break;
746 #ifdef SO_BSDCOMPAT
747 case TARGET_SO_BSDCOMPAT:
748 optname = SO_BSDCOMPAT;
749 break;
750 #endif
751 case TARGET_SO_PASSCRED:
752 optname = SO_PASSCRED;
753 break;
754 case TARGET_SO_TIMESTAMP:
755 optname = SO_TIMESTAMP;
756 break;
757 case TARGET_SO_RCVLOWAT:
758 optname = SO_RCVLOWAT;
759 break;
760 case TARGET_SO_RCVTIMEO:
761 optname = SO_RCVTIMEO;
762 break;
763 case TARGET_SO_SNDTIMEO:
764 optname = SO_SNDTIMEO;
765 break;
766 break;
767 default:
768 goto unimplemented;
769 }
770 if (optlen < sizeof(uint32_t))
771 return -EINVAL;
772
773 val = tget32(optval);
774 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
775 break;
776 default:
777 unimplemented:
778 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
779 ret = -ENOSYS;
780 }
781 return ret;
782 }
783
784 static long do_getsockopt(int sockfd, int level, int optname,
785 target_ulong optval, target_ulong optlen)
786 {
787 int len, lv, val, ret;
788
789 switch(level) {
790 case TARGET_SOL_SOCKET:
791 level = SOL_SOCKET;
792 switch (optname) {
793 case TARGET_SO_LINGER:
794 case TARGET_SO_RCVTIMEO:
795 case TARGET_SO_SNDTIMEO:
796 case TARGET_SO_PEERCRED:
797 case TARGET_SO_PEERNAME:
798 /* These don't just return a single integer */
799 goto unimplemented;
800 default:
801 goto int_case;
802 }
803 break;
804 case SOL_TCP:
805 /* TCP options all take an 'int' value. */
806 int_case:
807 len = tget32(optlen);
808 if (len < 0)
809 return -EINVAL;
810 lv = sizeof(int);
811 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
812 if (ret < 0)
813 return ret;
814 val = tswap32(val);
815 if (len > lv)
816 len = lv;
817 if (len == 4)
818 tput32(optval, val);
819 else
820 tput8(optval, val);
821 tput32(optlen, len);
822 break;
823 case SOL_IP:
824 switch(optname) {
825 case IP_TOS:
826 case IP_TTL:
827 case IP_HDRINCL:
828 case IP_ROUTER_ALERT:
829 case IP_RECVOPTS:
830 case IP_RETOPTS:
831 case IP_PKTINFO:
832 case IP_MTU_DISCOVER:
833 case IP_RECVERR:
834 case IP_RECVTOS:
835 #ifdef IP_FREEBIND
836 case IP_FREEBIND:
837 #endif
838 case IP_MULTICAST_TTL:
839 case IP_MULTICAST_LOOP:
840 len = tget32(optlen);
841 if (len < 0)
842 return -EINVAL;
843 lv = sizeof(int);
844 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
845 if (ret < 0)
846 return ret;
847 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
848 len = 1;
849 tput32(optlen, len);
850 tput8(optval, val);
851 } else {
852 if (len > sizeof(int))
853 len = sizeof(int);
854 tput32(optlen, len);
855 tput32(optval, val);
856 }
857 break;
858 default:
859 goto unimplemented;
860 }
861 break;
862 default:
863 unimplemented:
864 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
865 level, optname);
866 ret = -ENOSYS;
867 break;
868 }
869 return ret;
870 }
871
872 static void lock_iovec(struct iovec *vec, target_ulong target_addr,
873 int count, int copy)
874 {
875 struct target_iovec *target_vec;
876 target_ulong base;
877 int i;
878
879 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
880 for(i = 0;i < count; i++) {
881 base = tswapl(target_vec[i].iov_base);
882 vec[i].iov_len = tswapl(target_vec[i].iov_len);
883 vec[i].iov_base = lock_user(base, vec[i].iov_len, copy);
884 }
885 unlock_user (target_vec, target_addr, 0);
886 }
887
888 static void unlock_iovec(struct iovec *vec, target_ulong target_addr,
889 int count, int copy)
890 {
891 struct target_iovec *target_vec;
892 target_ulong base;
893 int i;
894
895 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
896 for(i = 0;i < count; i++) {
897 base = tswapl(target_vec[i].iov_base);
898 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
899 }
900 unlock_user (target_vec, target_addr, 0);
901 }
902
903 static long do_socket(int domain, int type, int protocol)
904 {
905 #if defined(TARGET_MIPS)
906 switch(type) {
907 case TARGET_SOCK_DGRAM:
908 type = SOCK_DGRAM;
909 break;
910 case TARGET_SOCK_STREAM:
911 type = SOCK_STREAM;
912 break;
913 case TARGET_SOCK_RAW:
914 type = SOCK_RAW;
915 break;
916 case TARGET_SOCK_RDM:
917 type = SOCK_RDM;
918 break;
919 case TARGET_SOCK_SEQPACKET:
920 type = SOCK_SEQPACKET;
921 break;
922 case TARGET_SOCK_PACKET:
923 type = SOCK_PACKET;
924 break;
925 }
926 #endif
927 return get_errno(socket(domain, type, protocol));
928 }
929
930 static long do_bind(int sockfd, target_ulong target_addr,
931 socklen_t addrlen)
932 {
933 void *addr = alloca(addrlen);
934
935 target_to_host_sockaddr(addr, target_addr, addrlen);
936 return get_errno(bind(sockfd, addr, addrlen));
937 }
938
939 static long do_connect(int sockfd, target_ulong target_addr,
940 socklen_t addrlen)
941 {
942 void *addr = alloca(addrlen);
943
944 target_to_host_sockaddr(addr, target_addr, addrlen);
945 return get_errno(connect(sockfd, addr, addrlen));
946 }
947
948 static long do_sendrecvmsg(int fd, target_ulong target_msg,
949 int flags, int send)
950 {
951 long ret;
952 struct target_msghdr *msgp;
953 struct msghdr msg;
954 int count;
955 struct iovec *vec;
956 target_ulong target_vec;
957
958 lock_user_struct(msgp, target_msg, 1);
959 if (msgp->msg_name) {
960 msg.msg_namelen = tswap32(msgp->msg_namelen);
961 msg.msg_name = alloca(msg.msg_namelen);
962 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
963 msg.msg_namelen);
964 } else {
965 msg.msg_name = NULL;
966 msg.msg_namelen = 0;
967 }
968 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
969 msg.msg_control = alloca(msg.msg_controllen);
970 msg.msg_flags = tswap32(msgp->msg_flags);
971
972 count = tswapl(msgp->msg_iovlen);
973 vec = alloca(count * sizeof(struct iovec));
974 target_vec = tswapl(msgp->msg_iov);
975 lock_iovec(vec, target_vec, count, send);
976 msg.msg_iovlen = count;
977 msg.msg_iov = vec;
978
979 if (send) {
980 target_to_host_cmsg(&msg, msgp);
981 ret = get_errno(sendmsg(fd, &msg, flags));
982 } else {
983 ret = get_errno(recvmsg(fd, &msg, flags));
984 if (!is_error(ret))
985 host_to_target_cmsg(msgp, &msg);
986 }
987 unlock_iovec(vec, target_vec, count, !send);
988 return ret;
989 }
990
991 static long do_accept(int fd, target_ulong target_addr,
992 target_ulong target_addrlen)
993 {
994 socklen_t addrlen = tget32(target_addrlen);
995 void *addr = alloca(addrlen);
996 long ret;
997
998 ret = get_errno(accept(fd, addr, &addrlen));
999 if (!is_error(ret)) {
1000 host_to_target_sockaddr(target_addr, addr, addrlen);
1001 tput32(target_addrlen, addrlen);
1002 }
1003 return ret;
1004 }
1005
1006 static long do_getpeername(int fd, target_ulong target_addr,
1007 target_ulong target_addrlen)
1008 {
1009 socklen_t addrlen = tget32(target_addrlen);
1010 void *addr = alloca(addrlen);
1011 long ret;
1012
1013 ret = get_errno(getpeername(fd, addr, &addrlen));
1014 if (!is_error(ret)) {
1015 host_to_target_sockaddr(target_addr, addr, addrlen);
1016 tput32(target_addrlen, addrlen);
1017 }
1018 return ret;
1019 }
1020
1021 static long do_getsockname(int fd, target_ulong target_addr,
1022 target_ulong target_addrlen)
1023 {
1024 socklen_t addrlen = tget32(target_addrlen);
1025 void *addr = alloca(addrlen);
1026 long ret;
1027
1028 ret = get_errno(getsockname(fd, addr, &addrlen));
1029 if (!is_error(ret)) {
1030 host_to_target_sockaddr(target_addr, addr, addrlen);
1031 tput32(target_addrlen, addrlen);
1032 }
1033 return ret;
1034 }
1035
1036 static long do_socketpair(int domain, int type, int protocol,
1037 target_ulong target_tab)
1038 {
1039 int tab[2];
1040 long ret;
1041
1042 ret = get_errno(socketpair(domain, type, protocol, tab));
1043 if (!is_error(ret)) {
1044 tput32(target_tab, tab[0]);
1045 tput32(target_tab + 4, tab[1]);
1046 }
1047 return ret;
1048 }
1049
1050 static long do_sendto(int fd, target_ulong msg, size_t len, int flags,
1051 target_ulong target_addr, socklen_t addrlen)
1052 {
1053 void *addr;
1054 void *host_msg;
1055 long ret;
1056
1057 host_msg = lock_user(msg, len, 1);
1058 if (target_addr) {
1059 addr = alloca(addrlen);
1060 target_to_host_sockaddr(addr, target_addr, addrlen);
1061 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1062 } else {
1063 ret = get_errno(send(fd, host_msg, len, flags));
1064 }
1065 unlock_user(host_msg, msg, 0);
1066 return ret;
1067 }
1068
1069 static long do_recvfrom(int fd, target_ulong msg, size_t len, int flags,
1070 target_ulong target_addr, target_ulong target_addrlen)
1071 {
1072 socklen_t addrlen;
1073 void *addr;
1074 void *host_msg;
1075 long ret;
1076
1077 host_msg = lock_user(msg, len, 0);
1078 if (target_addr) {
1079 addrlen = tget32(target_addrlen);
1080 addr = alloca(addrlen);
1081 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1082 } else {
1083 addr = NULL; /* To keep compiler quiet. */
1084 ret = get_errno(recv(fd, host_msg, len, flags));
1085 }
1086 if (!is_error(ret)) {
1087 if (target_addr) {
1088 host_to_target_sockaddr(target_addr, addr, addrlen);
1089 tput32(target_addrlen, addrlen);
1090 }
1091 unlock_user(host_msg, msg, len);
1092 } else {
1093 unlock_user(host_msg, msg, 0);
1094 }
1095 return ret;
1096 }
1097
1098 static long do_socketcall(int num, target_ulong vptr)
1099 {
1100 long ret;
1101 const int n = sizeof(target_ulong);
1102
1103 switch(num) {
1104 case SOCKOP_socket:
1105 {
1106 int domain = tgetl(vptr);
1107 int type = tgetl(vptr + n);
1108 int protocol = tgetl(vptr + 2 * n);
1109 ret = do_socket(domain, type, protocol);
1110 }
1111 break;
1112 case SOCKOP_bind:
1113 {
1114 int sockfd = tgetl(vptr);
1115 target_ulong target_addr = tgetl(vptr + n);
1116 socklen_t addrlen = tgetl(vptr + 2 * n);
1117 ret = do_bind(sockfd, target_addr, addrlen);
1118 }
1119 break;
1120 case SOCKOP_connect:
1121 {
1122 int sockfd = tgetl(vptr);
1123 target_ulong target_addr = tgetl(vptr + n);
1124 socklen_t addrlen = tgetl(vptr + 2 * n);
1125 ret = do_connect(sockfd, target_addr, addrlen);
1126 }
1127 break;
1128 case SOCKOP_listen:
1129 {
1130 int sockfd = tgetl(vptr);
1131 int backlog = tgetl(vptr + n);
1132 ret = get_errno(listen(sockfd, backlog));
1133 }
1134 break;
1135 case SOCKOP_accept:
1136 {
1137 int sockfd = tgetl(vptr);
1138 target_ulong target_addr = tgetl(vptr + n);
1139 target_ulong target_addrlen = tgetl(vptr + 2 * n);
1140 ret = do_accept(sockfd, target_addr, target_addrlen);
1141 }
1142 break;
1143 case SOCKOP_getsockname:
1144 {
1145 int sockfd = tgetl(vptr);
1146 target_ulong target_addr = tgetl(vptr + n);
1147 target_ulong target_addrlen = tgetl(vptr + 2 * n);
1148 ret = do_getsockname(sockfd, target_addr, target_addrlen);
1149 }
1150 break;
1151 case SOCKOP_getpeername:
1152 {
1153 int sockfd = tgetl(vptr);
1154 target_ulong target_addr = tgetl(vptr + n);
1155 target_ulong target_addrlen = tgetl(vptr + 2 * n);
1156 ret = do_getpeername(sockfd, target_addr, target_addrlen);
1157 }
1158 break;
1159 case SOCKOP_socketpair:
1160 {
1161 int domain = tgetl(vptr);
1162 int type = tgetl(vptr + n);
1163 int protocol = tgetl(vptr + 2 * n);
1164 target_ulong tab = tgetl(vptr + 3 * n);
1165 ret = do_socketpair(domain, type, protocol, tab);
1166 }
1167 break;
1168 case SOCKOP_send:
1169 {
1170 int sockfd = tgetl(vptr);
1171 target_ulong msg = tgetl(vptr + n);
1172 size_t len = tgetl(vptr + 2 * n);
1173 int flags = tgetl(vptr + 3 * n);
1174 ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1175 }
1176 break;
1177 case SOCKOP_recv:
1178 {
1179 int sockfd = tgetl(vptr);
1180 target_ulong msg = tgetl(vptr + n);
1181 size_t len = tgetl(vptr + 2 * n);
1182 int flags = tgetl(vptr + 3 * n);
1183 ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1184 }
1185 break;
1186 case SOCKOP_sendto:
1187 {
1188 int sockfd = tgetl(vptr);
1189 target_ulong msg = tgetl(vptr + n);
1190 size_t len = tgetl(vptr + 2 * n);
1191 int flags = tgetl(vptr + 3 * n);
1192 target_ulong addr = tgetl(vptr + 4 * n);
1193 socklen_t addrlen = tgetl(vptr + 5 * n);
1194 ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1195 }
1196 break;
1197 case SOCKOP_recvfrom:
1198 {
1199 int sockfd = tgetl(vptr);
1200 target_ulong msg = tgetl(vptr + n);
1201 size_t len = tgetl(vptr + 2 * n);
1202 int flags = tgetl(vptr + 3 * n);
1203 target_ulong addr = tgetl(vptr + 4 * n);
1204 target_ulong addrlen = tgetl(vptr + 5 * n);
1205 ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1206 }
1207 break;
1208 case SOCKOP_shutdown:
1209 {
1210 int sockfd = tgetl(vptr);
1211 int how = tgetl(vptr + n);
1212
1213 ret = get_errno(shutdown(sockfd, how));
1214 }
1215 break;
1216 case SOCKOP_sendmsg:
1217 case SOCKOP_recvmsg:
1218 {
1219 int fd;
1220 target_ulong target_msg;
1221 int flags;
1222
1223 fd = tgetl(vptr);
1224 target_msg = tgetl(vptr + n);
1225 flags = tgetl(vptr + 2 * n);
1226
1227 ret = do_sendrecvmsg(fd, target_msg, flags,
1228 (num == SOCKOP_sendmsg));
1229 }
1230 break;
1231 case SOCKOP_setsockopt:
1232 {
1233 int sockfd = tgetl(vptr);
1234 int level = tgetl(vptr + n);
1235 int optname = tgetl(vptr + 2 * n);
1236 target_ulong optval = tgetl(vptr + 3 * n);
1237 socklen_t optlen = tgetl(vptr + 4 * n);
1238
1239 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1240 }
1241 break;
1242 case SOCKOP_getsockopt:
1243 {
1244 int sockfd = tgetl(vptr);
1245 int level = tgetl(vptr + n);
1246 int optname = tgetl(vptr + 2 * n);
1247 target_ulong optval = tgetl(vptr + 3 * n);
1248 target_ulong poptlen = tgetl(vptr + 4 * n);
1249
1250 ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
1251 }
1252 break;
1253 default:
1254 gemu_log("Unsupported socketcall: %d\n", num);
1255 ret = -ENOSYS;
1256 break;
1257 }
1258 return ret;
1259 }
1260
1261 #define N_SHM_REGIONS 32
1262
1263 static struct shm_region {
1264 uint32_t start;
1265 uint32_t size;
1266 } shm_regions[N_SHM_REGIONS];
1267
1268 struct target_ipc_perm
1269 {
1270 target_long __key;
1271 target_ulong uid;
1272 target_ulong gid;
1273 target_ulong cuid;
1274 target_ulong cgid;
1275 unsigned short int mode;
1276 unsigned short int __pad1;
1277 unsigned short int __seq;
1278 unsigned short int __pad2;
1279 target_ulong __unused1;
1280 target_ulong __unused2;
1281 };
1282
1283 struct target_semid_ds
1284 {
1285 struct target_ipc_perm sem_perm;
1286 target_ulong sem_otime;
1287 target_ulong __unused1;
1288 target_ulong sem_ctime;
1289 target_ulong __unused2;
1290 target_ulong sem_nsems;
1291 target_ulong __unused3;
1292 target_ulong __unused4;
1293 };
1294
1295 static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
1296 target_ulong target_addr)
1297 {
1298 struct target_ipc_perm *target_ip;
1299 struct target_semid_ds *target_sd;
1300
1301 lock_user_struct(target_sd, target_addr, 1);
1302 target_ip=&(target_sd->sem_perm);
1303 host_ip->__key = tswapl(target_ip->__key);
1304 host_ip->uid = tswapl(target_ip->uid);
1305 host_ip->gid = tswapl(target_ip->gid);
1306 host_ip->cuid = tswapl(target_ip->cuid);
1307 host_ip->cgid = tswapl(target_ip->cgid);
1308 host_ip->mode = tswapl(target_ip->mode);
1309 unlock_user_struct(target_sd, target_addr, 0);
1310 }
1311
1312 static inline void host_to_target_ipc_perm(target_ulong target_addr,
1313 struct ipc_perm *host_ip)
1314 {
1315 struct target_ipc_perm *target_ip;
1316 struct target_semid_ds *target_sd;
1317
1318 lock_user_struct(target_sd, target_addr, 0);
1319 target_ip = &(target_sd->sem_perm);
1320 target_ip->__key = tswapl(host_ip->__key);
1321 target_ip->uid = tswapl(host_ip->uid);
1322 target_ip->gid = tswapl(host_ip->gid);
1323 target_ip->cuid = tswapl(host_ip->cuid);
1324 target_ip->cgid = tswapl(host_ip->cgid);
1325 target_ip->mode = tswapl(host_ip->mode);
1326 unlock_user_struct(target_sd, target_addr, 1);
1327 }
1328
1329 static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
1330 target_ulong target_addr)
1331 {
1332 struct target_semid_ds *target_sd;
1333
1334 lock_user_struct(target_sd, target_addr, 1);
1335 target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1336 host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1337 host_sd->sem_otime = tswapl(target_sd->sem_otime);
1338 host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1339 unlock_user_struct(target_sd, target_addr, 0);
1340 }
1341
1342 static inline void host_to_target_semid_ds(target_ulong target_addr,
1343 struct semid_ds *host_sd)
1344 {
1345 struct target_semid_ds *target_sd;
1346
1347 lock_user_struct(target_sd, target_addr, 0);
1348 host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1349 target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1350 target_sd->sem_otime = tswapl(host_sd->sem_otime);
1351 target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1352 unlock_user_struct(target_sd, target_addr, 1);
1353 }
1354
1355 union semun {
1356 int val;
1357 struct semid_ds *buf;
1358 unsigned short *array;
1359 };
1360
1361 union target_semun {
1362 int val;
1363 target_long buf;
1364 unsigned short int *array;
1365 };
1366
1367 static inline void target_to_host_semun(unsigned long cmd,
1368 union semun *host_su,
1369 target_ulong target_addr,
1370 struct semid_ds *ds)
1371 {
1372 union target_semun *target_su;
1373
1374 switch( cmd ) {
1375 case IPC_STAT:
1376 case IPC_SET:
1377 lock_user_struct(target_su, target_addr, 1);
1378 target_to_host_semid_ds(ds,target_su->buf);
1379 host_su->buf = ds;
1380 unlock_user_struct(target_su, target_addr, 0);
1381 break;
1382 case GETVAL:
1383 case SETVAL:
1384 lock_user_struct(target_su, target_addr, 1);
1385 host_su->val = tswapl(target_su->val);
1386 unlock_user_struct(target_su, target_addr, 0);
1387 break;
1388 case GETALL:
1389 case SETALL:
1390 lock_user_struct(target_su, target_addr, 1);
1391 *host_su->array = tswap16(*target_su->array);
1392 unlock_user_struct(target_su, target_addr, 0);
1393 break;
1394 default:
1395 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1396 }
1397 }
1398
1399 static inline void host_to_target_semun(unsigned long cmd,
1400 target_ulong target_addr,
1401 union semun *host_su,
1402 struct semid_ds *ds)
1403 {
1404 union target_semun *target_su;
1405
1406 switch( cmd ) {
1407 case IPC_STAT:
1408 case IPC_SET:
1409 lock_user_struct(target_su, target_addr, 0);
1410 host_to_target_semid_ds(target_su->buf,ds);
1411 unlock_user_struct(target_su, target_addr, 1);
1412 break;
1413 case GETVAL:
1414 case SETVAL:
1415 lock_user_struct(target_su, target_addr, 0);
1416 target_su->val = tswapl(host_su->val);
1417 unlock_user_struct(target_su, target_addr, 1);
1418 break;
1419 case GETALL:
1420 case SETALL:
1421 lock_user_struct(target_su, target_addr, 0);
1422 *target_su->array = tswap16(*host_su->array);
1423 unlock_user_struct(target_su, target_addr, 1);
1424 break;
1425 default:
1426 gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1427 }
1428 }
1429
1430 static inline long do_semctl(long first, long second, long third, long ptr)
1431 {
1432 union semun arg;
1433 struct semid_ds dsarg;
1434 int cmd = third&0xff;
1435 long ret = 0;
1436
1437 switch( cmd ) {
1438 case GETVAL:
1439 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1440 ret = get_errno(semctl(first, second, cmd, arg));
1441 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1442 break;
1443 case SETVAL:
1444 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1445 ret = get_errno(semctl(first, second, cmd, arg));
1446 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1447 break;
1448 case GETALL:
1449 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1450 ret = get_errno(semctl(first, second, cmd, arg));
1451 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1452 break;
1453 case SETALL:
1454 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1455 ret = get_errno(semctl(first, second, cmd, arg));
1456 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1457 break;
1458 case IPC_STAT:
1459 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1460 ret = get_errno(semctl(first, second, cmd, arg));
1461 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1462 break;
1463 case IPC_SET:
1464 target_to_host_semun(cmd,&arg,ptr,&dsarg);
1465 ret = get_errno(semctl(first, second, cmd, arg));
1466 host_to_target_semun(cmd,ptr,&arg,&dsarg);
1467 break;
1468 default:
1469 ret = get_errno(semctl(first, second, cmd, arg));
1470 }
1471
1472 return ret;
1473 }
1474
1475 struct target_msqid_ds
1476 {
1477 struct target_ipc_perm msg_perm;
1478 target_ulong msg_stime;
1479 target_ulong __unused1;
1480 target_ulong msg_rtime;
1481 target_ulong __unused2;
1482 target_ulong msg_ctime;
1483 target_ulong __unused3;
1484 target_ulong __msg_cbytes;
1485 target_ulong msg_qnum;
1486 target_ulong msg_qbytes;
1487 target_ulong msg_lspid;
1488 target_ulong msg_lrpid;
1489 target_ulong __unused4;
1490 target_ulong __unused5;
1491 };
1492
1493 static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
1494 target_ulong target_addr)
1495 {
1496 struct target_msqid_ds *target_md;
1497
1498 lock_user_struct(target_md, target_addr, 1);
1499 target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1500 host_md->msg_stime = tswapl(target_md->msg_stime);
1501 host_md->msg_rtime = tswapl(target_md->msg_rtime);
1502 host_md->msg_ctime = tswapl(target_md->msg_ctime);
1503 host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1504 host_md->msg_qnum = tswapl(target_md->msg_qnum);
1505 host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1506 host_md->msg_lspid = tswapl(target_md->msg_lspid);
1507 host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1508 unlock_user_struct(target_md, target_addr, 0);
1509 }
1510
1511 static inline void host_to_target_msqid_ds(target_ulong target_addr,
1512 struct msqid_ds *host_md)
1513 {
1514 struct target_msqid_ds *target_md;
1515
1516 lock_user_struct(target_md, target_addr, 0);
1517 host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1518 target_md->msg_stime = tswapl(host_md->msg_stime);
1519 target_md->msg_rtime = tswapl(host_md->msg_rtime);
1520 target_md->msg_ctime = tswapl(host_md->msg_ctime);
1521 target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1522 target_md->msg_qnum = tswapl(host_md->msg_qnum);
1523 target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1524 target_md->msg_lspid = tswapl(host_md->msg_lspid);
1525 target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1526 unlock_user_struct(target_md, target_addr, 1);
1527 }
1528
1529 static inline long do_msgctl(long first, long second, long ptr)
1530 {
1531 struct msqid_ds dsarg;
1532 int cmd = second&0xff;
1533 long ret = 0;
1534 switch( cmd ) {
1535 case IPC_STAT:
1536 case IPC_SET:
1537 target_to_host_msqid_ds(&dsarg,ptr);
1538 ret = get_errno(msgctl(first, cmd, &dsarg));
1539 host_to_target_msqid_ds(ptr,&dsarg);
1540 default:
1541 ret = get_errno(msgctl(first, cmd, &dsarg));
1542 }
1543 return ret;
1544 }
1545
1546 struct target_msgbuf {
1547 target_ulong mtype;
1548 char mtext[1];
1549 };
1550
1551 static inline long do_msgsnd(long msqid, long msgp, long msgsz, long msgflg)
1552 {
1553 struct target_msgbuf *target_mb;
1554 struct msgbuf *host_mb;
1555 long ret = 0;
1556
1557 lock_user_struct(target_mb,msgp,0);
1558 host_mb = malloc(msgsz+sizeof(long));
1559 host_mb->mtype = tswapl(target_mb->mtype);
1560 memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1561 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1562 free(host_mb);
1563 unlock_user_struct(target_mb, msgp, 0);
1564
1565 return ret;
1566 }
1567
1568 static inline long do_msgrcv(long msqid, long msgp, long msgsz, long msgtype, long msgflg)
1569 {
1570 struct target_msgbuf *target_mb;
1571 struct msgbuf *host_mb;
1572 long ret = 0;
1573
1574 lock_user_struct(target_mb, msgp, 0);
1575 host_mb = malloc(msgsz+sizeof(long));
1576 ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1577 if (ret > 0)
1578 memcpy(target_mb->mtext, host_mb->mtext, ret);
1579 target_mb->mtype = tswapl(host_mb->mtype);
1580 free(host_mb);
1581 unlock_user_struct(target_mb, msgp, 0);
1582
1583 return ret;
1584 }
1585
1586 /* ??? This only works with linear mappings. */
1587 static long do_ipc(long call, long first, long second, long third,
1588 long ptr, long fifth)
1589 {
1590 int version;
1591 long ret = 0;
1592 unsigned long raddr;
1593 struct shmid_ds shm_info;
1594 int i;
1595
1596 version = call >> 16;
1597 call &= 0xffff;
1598
1599 switch (call) {
1600 case IPCOP_semop:
1601 ret = get_errno(semop(first,(struct sembuf *) ptr, second));
1602 break;
1603
1604 case IPCOP_semget:
1605 ret = get_errno(semget(first, second, third));
1606 break;
1607
1608 case IPCOP_semctl:
1609 ret = do_semctl(first, second, third, ptr);
1610 break;
1611
1612 case IPCOP_semtimedop:
1613 gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
1614 ret = -ENOSYS;
1615 break;
1616
1617 case IPCOP_msgget:
1618 ret = get_errno(msgget(first, second));
1619 break;
1620
1621 case IPCOP_msgsnd:
1622 ret = do_msgsnd(first, ptr, second, third);
1623 break;
1624
1625 case IPCOP_msgctl:
1626 ret = do_msgctl(first, second, ptr);
1627 break;
1628
1629 case IPCOP_msgrcv:
1630 {
1631 struct ipc_kludge
1632 {
1633 void *__unbounded msgp;
1634 long int msgtyp;
1635 };
1636
1637 struct ipc_kludge *foo = (struct ipc_kludge *) ptr;
1638 struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
1639
1640 ret = do_msgrcv(first, (long)msgp, second, 0, third);
1641
1642 }
1643 break;
1644
1645 case IPCOP_shmat:
1646 /* SHM_* flags are the same on all linux platforms */
1647 ret = get_errno((long) shmat(first, (void *) ptr, second));
1648 if (is_error(ret))
1649 break;
1650 raddr = ret;
1651 /* find out the length of the shared memory segment */
1652
1653 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
1654 if (is_error(ret)) {
1655 /* can't get length, bail out */
1656 shmdt((void *) raddr);
1657 break;
1658 }
1659 page_set_flags(raddr, raddr + shm_info.shm_segsz,
1660 PAGE_VALID | PAGE_READ |
1661 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
1662 for (i = 0; i < N_SHM_REGIONS; ++i) {
1663 if (shm_regions[i].start == 0) {
1664 shm_regions[i].start = raddr;
1665 shm_regions[i].size = shm_info.shm_segsz;
1666 break;
1667 }
1668 }
1669 if (put_user(raddr, (uint32_t *)third))
1670 return -EFAULT;
1671 ret = 0;
1672 break;
1673 case IPCOP_shmdt:
1674 for (i = 0; i < N_SHM_REGIONS; ++i) {
1675 if (shm_regions[i].start == ptr) {
1676 shm_regions[i].start = 0;
1677 page_set_flags(ptr, shm_regions[i].size, 0);
1678 break;
1679 }
1680 }
1681 ret = get_errno(shmdt((void *) ptr));
1682 break;
1683
1684 case IPCOP_shmget:
1685 /* IPC_* flag values are the same on all linux platforms */
1686 ret = get_errno(shmget(first, second, third));
1687 break;
1688
1689 /* IPC_* and SHM_* command values are the same on all linux platforms */
1690 case IPCOP_shmctl:
1691 switch(second) {
1692 case IPC_RMID:
1693 case SHM_LOCK:
1694 case SHM_UNLOCK:
1695 ret = get_errno(shmctl(first, second, NULL));
1696 break;
1697 default:
1698 goto unimplemented;
1699 }
1700 break;
1701 default:
1702 unimplemented:
1703 gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
1704 ret = -ENOSYS;
1705 break;
1706 }
1707 return ret;
1708 }
1709
1710 /* kernel structure types definitions */
1711 #define IFNAMSIZ 16
1712
1713 #define STRUCT(name, list...) STRUCT_ ## name,
1714 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
1715 enum {
1716 #include "syscall_types.h"
1717 };
1718 #undef STRUCT
1719 #undef STRUCT_SPECIAL
1720
1721 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
1722 #define STRUCT_SPECIAL(name)
1723 #include "syscall_types.h"
1724 #undef STRUCT
1725 #undef STRUCT_SPECIAL
1726
1727 typedef struct IOCTLEntry {
1728 unsigned int target_cmd;
1729 unsigned int host_cmd;
1730 const char *name;
1731 int access;
1732 const argtype arg_type[5];
1733 } IOCTLEntry;
1734
1735 #define IOC_R 0x0001
1736 #define IOC_W 0x0002
1737 #define IOC_RW (IOC_R | IOC_W)
1738
1739 #define MAX_STRUCT_SIZE 4096
1740
1741 IOCTLEntry ioctl_entries[] = {
1742 #define IOCTL(cmd, access, types...) \
1743 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
1744 #include "ioctls.h"
1745 { 0, 0, },
1746 };
1747
1748 /* ??? Implement proper locking for ioctls. */
1749 static long do_ioctl(long fd, long cmd, long arg)
1750 {
1751 const IOCTLEntry *ie;
1752 const argtype *arg_type;
1753 long ret;
1754 uint8_t buf_temp[MAX_STRUCT_SIZE];
1755 int target_size;
1756 void *argptr;
1757
1758 ie = ioctl_entries;
1759 for(;;) {
1760 if (ie->target_cmd == 0) {
1761 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
1762 return -ENOSYS;
1763 }
1764 if (ie->target_cmd == cmd)
1765 break;
1766 ie++;
1767 }
1768 arg_type = ie->arg_type;
1769 #if defined(DEBUG)
1770 gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
1771 #endif
1772 switch(arg_type[0]) {
1773 case TYPE_NULL:
1774 /* no argument */
1775 ret = get_errno(ioctl(fd, ie->host_cmd));
1776 break;
1777 case TYPE_PTRVOID:
1778 case TYPE_INT:
1779 /* int argment */
1780 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
1781 break;
1782 case TYPE_PTR:
1783 arg_type++;
1784 target_size = thunk_type_size(arg_type, 0);
1785 switch(ie->access) {
1786 case IOC_R:
1787 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1788 if (!is_error(ret)) {
1789 argptr = lock_user(arg, target_size, 0);
1790 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1791 unlock_user(argptr, arg, target_size);
1792 }
1793 break;
1794 case IOC_W:
1795 argptr = lock_user(arg, target_size, 1);
1796 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1797 unlock_user(argptr, arg, 0);
1798 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1799 break;
1800 default:
1801 case IOC_RW:
1802 argptr = lock_user(arg, target_size, 1);
1803 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1804 unlock_user(argptr, arg, 0);
1805 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1806 if (!is_error(ret)) {
1807 argptr = lock_user(arg, target_size, 0);
1808 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1809 unlock_user(argptr, arg, target_size);
1810 }
1811 break;
1812 }
1813 break;
1814 default:
1815 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
1816 ret = -ENOSYS;
1817 break;
1818 }
1819 return ret;
1820 }
1821
1822 bitmask_transtbl iflag_tbl[] = {
1823 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
1824 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
1825 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
1826 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
1827 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
1828 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
1829 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
1830 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
1831 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
1832 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
1833 { TARGET_IXON, TARGET_IXON, IXON, IXON },
1834 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
1835 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
1836 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
1837 { 0, 0, 0, 0 }
1838 };
1839
1840 bitmask_transtbl oflag_tbl[] = {
1841 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
1842 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
1843 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
1844 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
1845 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
1846 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
1847 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
1848 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
1849 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
1850 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
1851 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
1852 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
1853 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
1854 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
1855 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
1856 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
1857 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
1858 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
1859 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
1860 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
1861 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
1862 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
1863 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
1864 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
1865 { 0, 0, 0, 0 }
1866 };
1867
1868 bitmask_transtbl cflag_tbl[] = {
1869 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
1870 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
1871 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
1872 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
1873 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
1874 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
1875 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
1876 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
1877 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
1878 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
1879 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
1880 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
1881 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
1882 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
1883 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
1884 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
1885 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
1886 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
1887 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
1888 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
1889 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
1890 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
1891 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
1892 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
1893 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
1894 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
1895 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
1896 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
1897 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
1898 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
1899 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
1900 { 0, 0, 0, 0 }
1901 };
1902
1903 bitmask_transtbl lflag_tbl[] = {
1904 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
1905 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
1906 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
1907 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
1908 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
1909 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
1910 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
1911 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
1912 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
1913 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
1914 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
1915 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
1916 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
1917 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
1918 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
1919 { 0, 0, 0, 0 }
1920 };
1921
1922 static void target_to_host_termios (void *dst, const void *src)
1923 {
1924 struct host_termios *host = dst;
1925 const struct target_termios *target = src;
1926
1927 host->c_iflag =
1928 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
1929 host->c_oflag =
1930 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
1931 host->c_cflag =
1932 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
1933 host->c_lflag =
1934 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
1935 host->c_line = target->c_line;
1936
1937 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
1938 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
1939 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
1940 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
1941 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
1942 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
1943 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
1944 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
1945 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
1946 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
1947 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
1948 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
1949 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
1950 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
1951 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
1952 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
1953 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
1954 }
1955
1956 static void host_to_target_termios (void *dst, const void *src)
1957 {
1958 struct target_termios *target = dst;
1959 const struct host_termios *host = src;
1960
1961 target->c_iflag =
1962 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
1963 target->c_oflag =
1964 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
1965 target->c_cflag =
1966 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
1967 target->c_lflag =
1968 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
1969 target->c_line = host->c_line;
1970
1971 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
1972 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
1973 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
1974 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
1975 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
1976 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
1977 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
1978 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
1979 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
1980 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
1981 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
1982 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
1983 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
1984 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
1985 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
1986 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
1987 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
1988 }
1989
1990 StructEntry struct_termios_def = {
1991 .convert = { host_to_target_termios, target_to_host_termios },
1992 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
1993 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
1994 };
1995
1996 static bitmask_transtbl mmap_flags_tbl[] = {
1997 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
1998 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
1999 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2000 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2001 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2002 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2003 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2004 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2005 { 0, 0, 0, 0 }
2006 };
2007
2008 static bitmask_transtbl fcntl_flags_tbl[] = {
2009 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
2010 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
2011 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
2012 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
2013 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
2014 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
2015 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
2016 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
2017 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
2018 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
2019 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2020 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
2021 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2022 #if defined(O_DIRECT)
2023 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
2024 #endif
2025 { 0, 0, 0, 0 }
2026 };
2027
2028 #if defined(TARGET_I386)
2029
2030 /* NOTE: there is really one LDT for all the threads */
2031 uint8_t *ldt_table;
2032
2033 static int read_ldt(target_ulong ptr, unsigned long bytecount)
2034 {
2035 int size;
2036 void *p;
2037
2038 if (!ldt_table)
2039 return 0;
2040 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2041 if (size > bytecount)
2042 size = bytecount;
2043 p = lock_user(ptr, size, 0);
2044 /* ??? Shoudl this by byteswapped? */
2045 memcpy(p, ldt_table, size);
2046 unlock_user(p, ptr, size);
2047 return size;
2048 }
2049
2050 /* XXX: add locking support */
2051 static int write_ldt(CPUX86State *env,
2052 target_ulong ptr, unsigned long bytecount, int oldmode)
2053 {
2054 struct target_modify_ldt_ldt_s ldt_info;
2055 struct target_modify_ldt_ldt_s *target_ldt_info;
2056 int seg_32bit, contents, read_exec_only, limit_in_pages;
2057 int seg_not_present, useable;
2058 uint32_t *lp, entry_1, entry_2;
2059
2060 if (bytecount != sizeof(ldt_info))
2061 return -EINVAL;
2062 lock_user_struct(target_ldt_info, ptr, 1);
2063 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2064 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2065 ldt_info.limit = tswap32(target_ldt_info->limit);
2066 ldt_info.flags = tswap32(target_ldt_info->flags);
2067 unlock_user_struct(target_ldt_info, ptr, 0);
2068
2069 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2070 return -EINVAL;
2071 seg_32bit = ldt_info.flags & 1;
2072 contents = (ldt_info.flags >> 1) & 3;
2073 read_exec_only = (ldt_info.flags >> 3) & 1;
2074 limit_in_pages = (ldt_info.flags >> 4) & 1;
2075 seg_not_present = (ldt_info.flags >> 5) & 1;
2076 useable = (ldt_info.flags >> 6) & 1;
2077
2078 if (contents == 3) {
2079 if (oldmode)
2080 return -EINVAL;
2081 if (seg_not_present == 0)
2082 return -EINVAL;
2083 }
2084 /* allocate the LDT */
2085 if (!ldt_table) {
2086 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2087 if (!ldt_table)
2088 return -ENOMEM;
2089 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2090 env->ldt.base = h2g(ldt_table);
2091 env->ldt.limit = 0xffff;
2092 }
2093
2094 /* NOTE: same code as Linux kernel */
2095 /* Allow LDTs to be cleared by the user. */
2096 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2097 if (oldmode ||
2098 (contents == 0 &&
2099 read_exec_only == 1 &&
2100 seg_32bit == 0 &&
2101 limit_in_pages == 0 &&
2102 seg_not_present == 1 &&
2103 useable == 0 )) {
2104 entry_1 = 0;
2105 entry_2 = 0;
2106 goto install;
2107 }
2108 }
2109
2110 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2111 (ldt_info.limit & 0x0ffff);
2112 entry_2 = (ldt_info.base_addr & 0xff000000) |
2113 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2114 (ldt_info.limit & 0xf0000) |
2115 ((read_exec_only ^ 1) << 9) |
2116 (contents << 10) |
2117 ((seg_not_present ^ 1) << 15) |
2118 (seg_32bit << 22) |
2119 (limit_in_pages << 23) |
2120 0x7000;
2121 if (!oldmode)
2122 entry_2 |= (useable << 20);
2123
2124 /* Install the new entry ... */
2125 install:
2126 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2127 lp[0] = tswap32(entry_1);
2128 lp[1] = tswap32(entry_2);
2129 return 0;
2130 }
2131
2132 /* specific and weird i386 syscalls */
2133 int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount)
2134 {
2135 int ret = -ENOSYS;
2136
2137 switch (func) {
2138 case 0:
2139 ret = read_ldt(ptr, bytecount);
2140 break;
2141 case 1:
2142 ret = write_ldt(env, ptr, bytecount, 1);
2143 break;
2144 case 0x11:
2145 ret = write_ldt(env, ptr, bytecount, 0);
2146 break;
2147 }
2148 return ret;
2149 }
2150
2151 #endif /* defined(TARGET_I386) */
2152
2153 /* this stack is the equivalent of the kernel stack associated with a
2154 thread/process */
2155 #define NEW_STACK_SIZE 8192
2156
2157 static int clone_func(void *arg)
2158 {
2159 CPUState *env = arg;
2160 cpu_loop(env);
2161 /* never exits */
2162 return 0;
2163 }
2164
2165 int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
2166 {
2167 int ret;
2168 TaskState *ts;
2169 uint8_t *new_stack;
2170 CPUState *new_env;
2171
2172 if (flags & CLONE_VM) {
2173 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
2174 memset(ts, 0, sizeof(TaskState));
2175 new_stack = ts->stack;
2176 ts->used = 1;
2177 /* add in task state list */
2178 ts->next = first_task_state;
2179 first_task_state = ts;
2180 /* we create a new CPU instance. */
2181 new_env = cpu_copy(env);
2182 #if defined(TARGET_I386)
2183 if (!newsp)
2184 newsp = env->regs[R_ESP];
2185 new_env->regs[R_ESP] = newsp;
2186 new_env->regs[R_EAX] = 0;
2187 #elif defined(TARGET_ARM)
2188 if (!newsp)
2189 newsp = env->regs[13];
2190 new_env->regs[13] = newsp;
2191 new_env->regs[0] = 0;
2192 #elif defined(TARGET_SPARC)
2193 if (!newsp)
2194 newsp = env->regwptr[22];
2195 new_env->regwptr[22] = newsp;
2196 new_env->regwptr[0] = 0;
2197 /* XXXXX */
2198 printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
2199 #elif defined(TARGET_M68K)
2200 if (!newsp)
2201 newsp = env->aregs[7];
2202 new_env->aregs[7] = newsp;
2203 new_env->dregs[0] = 0;
2204 /* ??? is this sufficient? */
2205 #elif defined(TARGET_MIPS)
2206 if (!newsp)
2207 newsp = env->gpr[29][env->current_tc];
2208 new_env->gpr[29][env->current_tc] = newsp;
2209 #elif defined(TARGET_PPC)
2210 if (!newsp)
2211 newsp = env->gpr[1];
2212 new_env->gpr[1] = newsp;
2213 {
2214 int i;
2215 for (i = 7; i < 32; i++)
2216 new_env->gpr[i] = 0;
2217 }
2218 #elif defined(TARGET_SH4)
2219 if (!newsp)
2220 newsp = env->gregs[15];
2221 new_env->gregs[15] = newsp;
2222 /* XXXXX */
2223 #elif defined(TARGET_ALPHA)
2224 if (!newsp)
2225 newsp = env->ir[30];
2226 new_env->ir[30] = newsp;
2227 /* ? */
2228 {
2229 int i;
2230 for (i = 7; i < 30; i++)
2231 new_env->ir[i] = 0;
2232 }
2233 #else
2234 #error unsupported target CPU
2235 #endif
2236 new_env->opaque = ts;
2237 #ifdef __ia64__
2238 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2239 #else
2240 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2241 #endif
2242 } else {
2243 /* if no CLONE_VM, we consider it is a fork */
2244 if ((flags & ~CSIGNAL) != 0)
2245 return -EINVAL;
2246 ret = fork();
2247 }
2248 return ret;
2249 }
2250
2251 static long do_fcntl(int fd, int cmd, target_ulong arg)
2252 {
2253 struct flock fl;
2254 struct target_flock *target_fl;
2255 struct flock64 fl64;
2256 struct target_flock64 *target_fl64;
2257 long ret;
2258
2259 switch(cmd) {
2260 case TARGET_F_GETLK:
2261 lock_user_struct(target_fl, arg, 1);
2262 fl.l_type = tswap16(target_fl->l_type);
2263 fl.l_whence = tswap16(target_fl->l_whence);
2264 fl.l_start = tswapl(target_fl->l_start);
2265 fl.l_len = tswapl(target_fl->l_len);
2266 fl.l_pid = tswapl(target_fl->l_pid);
2267 unlock_user_struct(target_fl, arg, 0);
2268 ret = fcntl(fd, cmd, &fl);
2269 if (ret == 0) {
2270 lock_user_struct(target_fl, arg, 0);
2271 target_fl->l_type = tswap16(fl.l_type);
2272 target_fl->l_whence = tswap16(fl.l_whence);
2273 target_fl->l_start = tswapl(fl.l_start);
2274 target_fl->l_len = tswapl(fl.l_len);
2275 target_fl->l_pid = tswapl(fl.l_pid);
2276 unlock_user_struct(target_fl, arg, 1);
2277 }
2278 break;
2279
2280 case TARGET_F_SETLK:
2281 case TARGET_F_SETLKW:
2282 lock_user_struct(target_fl, arg, 1);
2283 fl.l_type = tswap16(target_fl->l_type);
2284 fl.l_whence = tswap16(target_fl->l_whence);
2285 fl.l_start = tswapl(target_fl->l_start);
2286 fl.l_len = tswapl(target_fl->l_len);
2287 fl.l_pid = tswapl(target_fl->l_pid);
2288 unlock_user_struct(target_fl, arg, 0);
2289 ret = fcntl(fd, cmd, &fl);
2290 break;
2291
2292 case TARGET_F_GETLK64:
2293 lock_user_struct(target_fl64, arg, 1);
2294 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2295 fl64.l_whence = tswap16(target_fl64->l_whence);
2296 fl64.l_start = tswapl(target_fl64->l_start);
2297 fl64.l_len = tswapl(target_fl64->l_len);
2298 fl64.l_pid = tswap16(target_fl64->l_pid);
2299 unlock_user_struct(target_fl64, arg, 0);
2300 ret = fcntl(fd, cmd >> 1, &fl64);
2301 if (ret == 0) {
2302 lock_user_struct(target_fl64, arg, 0);
2303 target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2304 target_fl64->l_whence = tswap16(fl64.l_whence);
2305 target_fl64->l_start = tswapl(fl64.l_start);
2306 target_fl64->l_len = tswapl(fl64.l_len);
2307 target_fl64->l_pid = tswapl(fl64.l_pid);
2308 unlock_user_struct(target_fl64, arg, 1);
2309 }
2310 break;
2311 case TARGET_F_SETLK64:
2312 case TARGET_F_SETLKW64:
2313 lock_user_struct(target_fl64, arg, 1);
2314 fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2315 fl64.l_whence = tswap16(target_fl64->l_whence);
2316 fl64.l_start = tswapl(target_fl64->l_start);
2317 fl64.l_len = tswapl(target_fl64->l_len);
2318 fl64.l_pid = tswap16(target_fl64->l_pid);
2319 unlock_user_struct(target_fl64, arg, 0);
2320 ret = fcntl(fd, cmd >> 1, &fl64);
2321 break;
2322
2323 case F_GETFL:
2324 ret = fcntl(fd, cmd, arg);
2325 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2326 break;
2327
2328 case F_SETFL:
2329 ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl));
2330 break;
2331
2332 default:
2333 ret = fcntl(fd, cmd, arg);
2334 break;
2335 }
2336 return ret;
2337 }
2338
2339 #ifdef USE_UID16
2340
2341 static inline int high2lowuid(int uid)
2342 {
2343 if (uid > 65535)
2344 return 65534;
2345 else
2346 return uid;
2347 }
2348
2349 static inline int high2lowgid(int gid)
2350 {
2351 if (gid > 65535)
2352 return 65534;
2353 else
2354 return gid;
2355 }
2356
2357 static inline int low2highuid(int uid)
2358 {
2359 if ((int16_t)uid == -1)
2360 return -1;
2361 else
2362 return uid;
2363 }
2364
2365 static inline int low2highgid(int gid)
2366 {
2367 if ((int16_t)gid == -1)
2368 return -1;
2369 else
2370 return gid;
2371 }
2372
2373 #endif /* USE_UID16 */
2374
2375 void syscall_init(void)
2376 {
2377 IOCTLEntry *ie;
2378 const argtype *arg_type;
2379 int size;
2380
2381 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
2382 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
2383 #include "syscall_types.h"
2384 #undef STRUCT
2385 #undef STRUCT_SPECIAL
2386
2387 /* we patch the ioctl size if necessary. We rely on the fact that
2388 no ioctl has all the bits at '1' in the size field */
2389 ie = ioctl_entries;
2390 while (ie->target_cmd != 0) {
2391 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
2392 TARGET_IOC_SIZEMASK) {
2393 arg_type = ie->arg_type;
2394 if (arg_type[0] != TYPE_PTR) {
2395 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
2396 ie->target_cmd);
2397 exit(1);
2398 }
2399 arg_type++;
2400 size = thunk_type_size(arg_type, 0);
2401 ie->target_cmd = (ie->target_cmd &
2402 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
2403 (size << TARGET_IOC_SIZESHIFT);
2404 }
2405 /* automatic consistency check if same arch */
2406 #if defined(__i386__) && defined(TARGET_I386)
2407 if (ie->target_cmd != ie->host_cmd) {
2408 fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
2409 ie->target_cmd, ie->host_cmd);
2410 }
2411 #endif
2412 ie++;
2413 }
2414 }
2415
2416 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
2417 {
2418 #ifdef TARGET_WORDS_BIG_ENDIAN
2419 return ((uint64_t)word0 << 32) | word1;
2420 #else
2421 return ((uint64_t)word1 << 32) | word0;
2422 #endif
2423 }
2424
2425 #ifdef TARGET_NR_truncate64
2426 static inline long target_truncate64(void *cpu_env, const char *arg1,
2427 long arg2, long arg3, long arg4)
2428 {
2429 #ifdef TARGET_ARM
2430 if (((CPUARMState *)cpu_env)->eabi)
2431 {
2432 arg2 = arg3;
2433 arg3 = arg4;
2434 }
2435 #endif
2436 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
2437 }
2438 #endif
2439
2440 #ifdef TARGET_NR_ftruncate64
2441 static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2,
2442 long arg3, long arg4)
2443 {
2444 #ifdef TARGET_ARM
2445 if (((CPUARMState *)cpu_env)->eabi)
2446 {
2447 arg2 = arg3;
2448 arg3 = arg4;
2449 }
2450 #endif
2451 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
2452 }
2453 #endif
2454
2455 static inline void target_to_host_timespec(struct timespec *host_ts,
2456 target_ulong target_addr)
2457 {
2458 struct target_timespec *target_ts;
2459
2460 lock_user_struct(target_ts, target_addr, 1);
2461 host_ts->tv_sec = tswapl(target_ts->tv_sec);
2462 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
2463 unlock_user_struct(target_ts, target_addr, 0);
2464 }
2465
2466 static inline void host_to_target_timespec(target_ulong target_addr,
2467 struct timespec *host_ts)
2468 {
2469 struct target_timespec *target_ts;
2470
2471 lock_user_struct(target_ts, target_addr, 0);
2472 target_ts->tv_sec = tswapl(host_ts->tv_sec);
2473 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
2474 unlock_user_struct(target_ts, target_addr, 1);
2475 }
2476
2477 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2478 long arg4, long arg5, long arg6)
2479 {
2480 long ret;
2481 struct stat st;
2482 struct statfs stfs;
2483 void *p;
2484
2485 #ifdef DEBUG
2486 gemu_log("syscall %d", num);
2487 #endif
2488 switch(num) {
2489 case TARGET_NR_exit:
2490 #ifdef HAVE_GPROF
2491 _mcleanup();
2492 #endif
2493 gdb_exit(cpu_env, arg1);
2494 /* XXX: should free thread stack and CPU env */
2495 _exit(arg1);
2496 ret = 0; /* avoid warning */
2497 break;
2498 case TARGET_NR_read:
2499 page_unprotect_range(arg2, arg3);
2500 p = lock_user(arg2, arg3, 0);
2501 ret = get_errno(read(arg1, p, arg3));
2502 unlock_user(p, arg2, ret);
2503 break;
2504 case TARGET_NR_write:
2505 p = lock_user(arg2, arg3, 1);
2506 ret = get_errno(write(arg1, p, arg3));
2507 unlock_user(p, arg2, 0);
2508 break;
2509 case TARGET_NR_open:
2510 p = lock_user_string(arg1);
2511 ret = get_errno(open(path(p),
2512 target_to_host_bitmask(arg2, fcntl_flags_tbl),
2513 arg3));
2514 unlock_user(p, arg1, 0);
2515 break;
2516 #if defined(TARGET_NR_openat) && defined(__NR_openat)
2517 case TARGET_NR_openat:
2518 if (!arg2) {
2519 ret = -EFAULT;
2520 goto fail;
2521 }
2522 p = lock_user_string(arg2);
2523 if (!access_ok(VERIFY_READ, p, 1))
2524 ret = -EFAULT;
2525 else
2526 ret = get_errno(sys_openat(arg1,
2527 path(p),
2528 target_to_host_bitmask(arg3, fcntl_flags_tbl),
2529 arg4));
2530 if (p)
2531 unlock_user(p, arg2, 0);
2532 break;
2533 #endif
2534 case TARGET_NR_close:
2535 ret = get_errno(close(arg1));
2536 break;
2537 case TARGET_NR_brk:
2538 ret = do_brk(arg1);
2539 break;
2540 case TARGET_NR_fork:
2541 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
2542 break;
2543 #ifdef TARGET_NR_waitpid
2544 case TARGET_NR_waitpid:
2545 {
2546 int status;
2547 ret = get_errno(waitpid(arg1, &status, arg3));
2548 if (!is_error(ret) && arg2)
2549 tput32(arg2, status);
2550 }
2551 break;
2552 #endif
2553 #ifdef TARGET_NR_creat /* not on alpha */
2554 case TARGET_NR_creat:
2555 p = lock_user_string(arg1);
2556 ret = get_errno(creat(p, arg2));
2557 unlock_user(p, arg1, 0);
2558 break;
2559 #endif
2560 case TARGET_NR_link:
2561 {
2562 void * p2;
2563 p = lock_user_string(arg1);
2564 p2 = lock_user_string(arg2);
2565 ret = get_errno(link(p, p2));
2566 unlock_user(p2, arg2, 0);
2567 unlock_user(p, arg1, 0);
2568 }
2569 break;
2570 case TARGET_NR_unlink:
2571 p = lock_user_string(arg1);
2572 ret = get_errno(unlink(p));
2573 unlock_user(p, arg1, 0);
2574 break;
2575 case TARGET_NR_execve:
2576 {
2577 char **argp, **envp;
2578 int argc, envc;
2579 target_ulong gp;
2580 target_ulong guest_argp;
2581 target_ulong guest_envp;
2582 target_ulong addr;
2583 char **q;
2584
2585 argc = 0;
2586 guest_argp = arg2;
2587 for (gp = guest_argp; tgetl(gp); gp++)
2588 argc++;
2589 envc = 0;
2590 guest_envp = arg3;
2591 for (gp = guest_envp; tgetl(gp); gp++)
2592 envc++;
2593
2594 argp = alloca((argc + 1) * sizeof(void *));
2595 envp = alloca((envc + 1) * sizeof(void *));
2596
2597 for (gp = guest_argp, q = argp; ;
2598 gp += sizeof(target_ulong), q++) {
2599 addr = tgetl(gp);
2600 if (!addr)
2601 break;
2602 *q = lock_user_string(addr);
2603 }
2604 *q = NULL;
2605
2606 for (gp = guest_envp, q = envp; ;
2607 gp += sizeof(target_ulong), q++) {
2608 addr = tgetl(gp);
2609 if (!addr)
2610 break;
2611 *q = lock_user_string(addr);
2612 }
2613 *q = NULL;
2614
2615 p = lock_user_string(arg1);
2616 ret = get_errno(execve(p, argp, envp));
2617 unlock_user(p, arg1, 0);
2618
2619 for (gp = guest_argp, q = argp; *q;
2620 gp += sizeof(target_ulong), q++) {
2621 addr = tgetl(gp);
2622 unlock_user(*q, addr, 0);
2623 }
2624 for (gp = guest_envp, q = envp; *q;
2625 gp += sizeof(target_ulong), q++) {
2626 addr = tgetl(gp);
2627 unlock_user(*q, addr, 0);
2628 }
2629 }
2630 break;
2631 case TARGET_NR_chdir:
2632 p = lock_user_string(arg1);
2633 ret = get_errno(chdir(p));
2634 unlock_user(p, arg1, 0);
2635 break;
2636 #ifdef TARGET_NR_time
2637 case TARGET_NR_time:
2638 {
2639 time_t host_time;
2640 ret = get_errno(time(&host_time));
2641 if (!is_error(ret) && arg1)
2642 tputl(arg1, host_time);
2643 }
2644 break;
2645 #endif
2646 case TARGET_NR_mknod:
2647 p = lock_user_string(arg1);
2648 ret = get_errno(mknod(p, arg2, arg3));
2649 unlock_user(p, arg1, 0);
2650 break;
2651 #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
2652 case TARGET_NR_mknodat:
2653 if (!arg2) {
2654 ret = -EFAULT;
2655 goto fail;
2656 }
2657 p = lock_user_string(arg2);
2658 if (!access_ok(VERIFY_READ, p, 1))
2659 ret = -EFAULT;
2660 else
2661 ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
2662 if (p)
2663 unlock_user(p, arg2, 0);
2664 break;
2665 #endif
2666 case TARGET_NR_chmod:
2667 p = lock_user_string(arg1);
2668 ret = get_errno(chmod(p, arg2));
2669 unlock_user(p, arg1, 0);
2670 break;
2671 #ifdef TARGET_NR_break
2672 case TARGET_NR_break:
2673 goto unimplemented;
2674 #endif
2675 #ifdef TARGET_NR_oldstat
2676 case TARGET_NR_oldstat:
2677 goto unimplemented;
2678 #endif
2679 case TARGET_NR_lseek:
2680 ret = get_errno(lseek(arg1, arg2, arg3));
2681 break;
2682 #ifdef TARGET_NR_getxpid
2683 case TARGET_NR_getxpid:
2684 #else
2685 case TARGET_NR_getpid:
2686 #endif
2687 ret = get_errno(getpid());
2688 break;
2689 case TARGET_NR_mount:
2690 {
2691 /* need to look at the data field */
2692 void *p2, *p3;
2693 p = lock_user_string(arg1);
2694 p2 = lock_user_string(arg2);
2695 p3 = lock_user_string(arg3);
2696 ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, (const void *)arg5));
2697 unlock_user(p, arg1, 0);
2698 unlock_user(p2, arg2, 0);
2699 unlock_user(p3, arg3, 0);
2700 break;
2701 }
2702 #ifdef TARGET_NR_umount
2703 case TARGET_NR_umount:
2704 p = lock_user_string(arg1);
2705 ret = get_errno(umount(p));
2706 unlock_user(p, arg1, 0);
2707 break;
2708 #endif
2709 #ifdef TARGET_NR_stime /* not on alpha */
2710 case TARGET_NR_stime:
2711 {
2712 time_t host_time;
2713 host_time = tgetl(arg1);
2714 ret = get_errno(stime(&host_time));
2715 }
2716 break;
2717 #endif
2718 case TARGET_NR_ptrace:
2719 goto unimplemented;
2720 #ifdef TARGET_NR_alarm /* not on alpha */
2721 case TARGET_NR_alarm:
2722 ret = alarm(arg1);
2723 break;
2724 #endif
2725 #ifdef TARGET_NR_oldfstat
2726 case TARGET_NR_oldfstat:
2727 goto unimplemented;
2728 #endif
2729 #ifdef TARGET_NR_pause /* not on alpha */
2730 case TARGET_NR_pause:
2731 ret = get_errno(pause());
2732 break;
2733 #endif
2734 #ifdef TARGET_NR_utime
2735 case TARGET_NR_utime:
2736 {
2737 struct utimbuf tbuf, *host_tbuf;
2738 struct target_utimbuf *target_tbuf;
2739 if (arg2) {
2740 lock_user_struct(target_tbuf, arg2, 1);
2741 tbuf.actime = tswapl(target_tbuf->actime);
2742 tbuf.modtime = tswapl(target_tbuf->modtime);
2743 unlock_user_struct(target_tbuf, arg2, 0);
2744 host_tbuf = &tbuf;
2745 } else {
2746 host_tbuf = NULL;
2747 }
2748 p = lock_user_string(arg1);
2749 ret = get_errno(utime(p, host_tbuf));
2750 unlock_user(p, arg1, 0);
2751 }
2752 break;
2753 #endif
2754 case TARGET_NR_utimes:
2755 {
2756 struct timeval *tvp, tv[2];
2757 if (arg2) {
2758 target_to_host_timeval(&tv[0], arg2);
2759 target_to_host_timeval(&tv[1],
2760 arg2 + sizeof (struct target_timeval));
2761 tvp = tv;
2762 } else {
2763 tvp = NULL;
2764 }
2765 p = lock_user_string(arg1);
2766 ret = get_errno(utimes(p, tvp));
2767 unlock_user(p, arg1, 0);
2768 }
2769 break;
2770 #ifdef TARGET_NR_stty
2771 case TARGET_NR_stty:
2772 goto unimplemented;
2773 #endif
2774 #ifdef TARGET_NR_gtty
2775 case TARGET_NR_gtty:
2776 goto unimplemented;
2777 #endif
2778 case TARGET_NR_access:
2779 p = lock_user_string(arg1);
2780 ret = get_errno(access(p, arg2));
2781 unlock_user(p, arg1, 0);
2782 break;
2783 #ifdef TARGET_NR_nice /* not on alpha */
2784 case TARGET_NR_nice:
2785 ret = get_errno(nice(arg1));
2786 break;
2787 #endif
2788 #ifdef TARGET_NR_ftime
2789 case TARGET_NR_ftime:
2790 goto unimplemented;
2791 #endif
2792 case TARGET_NR_sync:
2793 sync();
2794 ret = 0;
2795 break;
2796 case TARGET_NR_kill:
2797 ret = get_errno(kill(arg1, arg2));
2798 break;
2799 case TARGET_NR_rename:
2800 {
2801 void *p2;
2802 p = lock_user_string(arg1);
2803 p2 = lock_user_string(arg2);
2804 ret = get_errno(rename(p, p2));
2805 unlock_user(p2, arg2, 0);
2806 unlock_user(p, arg1, 0);
2807 }
2808 break;
2809 case TARGET_NR_mkdir:
2810 p = lock_user_string(arg1);
2811 ret = get_errno(mkdir(p, arg2));
2812 unlock_user(p, arg1, 0);
2813 break;
2814 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
2815 case TARGET_NR_mkdirat:
2816 if (!arg2) {
2817 ret = -EFAULT;
2818 goto fail;
2819 }
2820 p = lock_user_string(arg2);
2821 if (!access_ok(VERIFY_READ, p, 1))
2822 ret = -EFAULT;
2823 else
2824 ret = get_errno(sys_mkdirat(arg1, p, arg3));
2825 if (p)
2826 unlock_user(p, arg2, 0);
2827 break;
2828 #endif
2829 case TARGET_NR_rmdir:
2830 p = lock_user_string(arg1);
2831 ret = get_errno(rmdir(p));
2832 unlock_user(p, arg1, 0);
2833 break;
2834 case TARGET_NR_dup:
2835 ret = get_errno(dup(arg1));
2836 break;
2837 case TARGET_NR_pipe:
2838 {
2839 int host_pipe[2];
2840 ret = get_errno(pipe(host_pipe));
2841 if (!is_error(ret)) {
2842 #if defined(TARGET_MIPS)
2843 CPUMIPSState *env = (CPUMIPSState*)cpu_env;
2844 env->gpr[3][env->current_tc] = host_pipe[1];
2845 ret = host_pipe[0];
2846 #else
2847 tput32(arg1, host_pipe[0]);
2848 tput32(arg1 + 4, host_pipe[1]);
2849 #endif
2850 }
2851 }
2852 break;
2853 case TARGET_NR_times:
2854 {
2855 struct target_tms *tmsp;
2856 struct tms tms;
2857 ret = get_errno(times(&tms));
2858 if (arg1) {
2859 tmsp = lock_user(arg1, sizeof(struct target_tms), 0);
2860 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
2861 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
2862 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
2863 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
2864 }
2865 if (!is_error(ret))
2866 ret = host_to_target_clock_t(ret);
2867 }
2868 break;
2869 #ifdef TARGET_NR_prof
2870 case TARGET_NR_prof:
2871 goto unimplemented;
2872 #endif
2873 #ifdef TARGET_NR_signal
2874 case TARGET_NR_signal:
2875 goto unimplemented;
2876 #endif
2877 case TARGET_NR_acct:
2878 p = lock_user_string(arg1);
2879 ret = get_errno(acct(path(p)));
2880 unlock_user(p, arg1, 0);
2881 break;
2882 #ifdef TARGET_NR_umount2 /* not on alpha */
2883 case TARGET_NR_umount2:
2884 p = lock_user_string(arg1);
2885 ret = get_errno(umount2(p, arg2));
2886 unlock_user(p, arg1, 0);
2887 break;
2888 #endif
2889 #ifdef TARGET_NR_lock
2890 case TARGET_NR_lock:
2891 goto unimplemented;
2892 #endif
2893 case TARGET_NR_ioctl:
2894 ret = do_ioctl(arg1, arg2, arg3);
2895 break;
2896 case TARGET_NR_fcntl:
2897 ret = get_errno(do_fcntl(arg1, arg2, arg3));
2898 break;
2899 #ifdef TARGET_NR_mpx
2900 case TARGET_NR_mpx:
2901 goto unimplemented;
2902 #endif
2903 case TARGET_NR_setpgid:
2904 ret = get_errno(setpgid(arg1, arg2));
2905 break;
2906 #ifdef TARGET_NR_ulimit
2907 case TARGET_NR_ulimit:
2908 goto unimplemented;
2909 #endif
2910 #ifdef TARGET_NR_oldolduname
2911 case TARGET_NR_oldolduname:
2912 goto unimplemented;
2913 #endif
2914 case TARGET_NR_umask:
2915 ret = get_errno(umask(arg1));
2916 break;
2917 case TARGET_NR_chroot:
2918 p = lock_user_string(arg1);
2919 ret = get_errno(chroot(p));
2920 unlock_user(p, arg1, 0);
2921 break;
2922 case TARGET_NR_ustat:
2923 goto unimplemented;
2924 case TARGET_NR_dup2:
2925 ret = get_errno(dup2(arg1, arg2));
2926 break;
2927 #ifdef TARGET_NR_getppid /* not on alpha */
2928 case TARGET_NR_getppid:
2929 ret = get_errno(getppid());
2930 break;
2931 #endif
2932 case TARGET_NR_getpgrp:
2933 ret = get_errno(getpgrp());
2934 break;
2935 case TARGET_NR_setsid:
2936 ret = get_errno(setsid());
2937 break;
2938 #ifdef TARGET_NR_sigaction
2939 case TARGET_NR_sigaction:
2940 {
2941 #if !defined(TARGET_MIPS)
2942 struct target_old_sigaction *old_act;
2943 struct target_sigaction act, oact, *pact;
2944 if (arg2) {
2945 lock_user_struct(old_act, arg2, 1);
2946 act._sa_handler = old_act->_sa_handler;
2947 target_siginitset(&act.sa_mask, old_act->sa_mask);
2948 act.sa_flags = old_act->sa_flags;
2949 act.sa_restorer = old_act->sa_restorer;
2950 unlock_user_struct(old_act, arg2, 0);
2951 pact = &act;
2952 } else {
2953 pact = NULL;
2954 }
2955 ret = get_errno(do_sigaction(arg1, pact, &oact));
2956 if (!is_error(ret) && arg3) {
2957 lock_user_struct(old_act, arg3, 0);
2958 old_act->_sa_handler = oact._sa_handler;
2959 old_act->sa_mask = oact.sa_mask.sig[0];
2960 old_act->sa_flags = oact.sa_flags;
2961 old_act->sa_restorer = oact.sa_restorer;
2962 unlock_user_struct(old_act, arg3, 1);
2963 }
2964 #else
2965 struct target_sigaction act, oact, *pact, *old_act;
2966
2967 if (arg2) {
2968 lock_user_struct(old_act, arg2, 1);
2969 act._sa_handler = old_act->_sa_handler;
2970 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
2971 act.sa_flags = old_act->sa_flags;
2972 unlock_user_struct(old_act, arg2, 0);
2973 pact = &act;
2974 } else {
2975 pact = NULL;
2976 }
2977
2978 ret = get_errno(do_sigaction(arg1, pact, &oact));
2979
2980 if (!is_error(ret) && arg3) {
2981 lock_user_struct(old_act, arg3, 0);
2982 old_act->_sa_handler = oact._sa_handler;
2983 old_act->sa_flags = oact.sa_flags;
2984 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
2985 old_act->sa_mask.sig[1] = 0;
2986 old_act->sa_mask.sig[2] = 0;
2987 old_act->sa_mask.sig[3] = 0;
2988 unlock_user_struct(old_act, arg3, 1);
2989 }
2990 #endif
2991 }
2992 break;
2993 #endif
2994 case TARGET_NR_rt_sigaction:
2995 {
2996 struct target_sigaction *act;
2997 struct target_sigaction *oact;
2998
2999 if (arg2)
3000 lock_user_struct(act, arg2, 1);
3001 else
3002 act = NULL;
3003 if (arg3)
3004 lock_user_struct(oact, arg3, 0);
3005 else
3006 oact = NULL;
3007 ret = get_errno(do_sigaction(arg1, act, oact));
3008 if (arg2)
3009 unlock_user_struct(act, arg2, 0);
3010 if (arg3)
3011 unlock_user_struct(oact, arg3, 1);
3012 }
3013 break;
3014 #ifdef TARGET_NR_sgetmask /* not on alpha */
3015 case TARGET_NR_sgetmask:
3016 {
3017 sigset_t cur_set;
3018 target_ulong target_set;
3019 sigprocmask(0, NULL, &cur_set);
3020 host_to_target_old_sigset(&target_set, &cur_set);
3021 ret = target_set;
3022 }
3023 break;
3024 #endif
3025 #ifdef TARGET_NR_ssetmask /* not on alpha */
3026 case TARGET_NR_ssetmask:
3027 {
3028 sigset_t set, oset, cur_set;
3029 target_ulong target_set = arg1;
3030 sigprocmask(0, NULL, &cur_set);
3031 target_to_host_old_sigset(&set, &target_set);
3032 sigorset(&set, &set, &cur_set);
3033 sigprocmask(SIG_SETMASK, &set, &oset);
3034 host_to_target_old_sigset(&target_set, &oset);
3035 ret = target_set;
3036 }
3037 break;
3038 #endif
3039 #ifdef TARGET_NR_sigprocmask
3040 case TARGET_NR_sigprocmask:
3041 {
3042 int how = arg1;
3043 sigset_t set, oldset, *set_ptr;
3044
3045 if (arg2) {
3046 switch(how) {
3047 case TARGET_SIG_BLOCK:
3048 how = SIG_BLOCK;
3049 break;
3050 case TARGET_SIG_UNBLOCK:
3051 how = SIG_UNBLOCK;
3052 break;
3053 case TARGET_SIG_SETMASK:
3054 how = SIG_SETMASK;
3055 break;
3056 default:
3057 ret = -EINVAL;
3058 goto fail;
3059 }
3060 p = lock_user(arg2, sizeof(target_sigset_t), 1);
3061 target_to_host_old_sigset(&set, p);
3062 unlock_user(p, arg2, 0);
3063 set_ptr = &set;
3064 } else {
3065 how = 0;
3066 set_ptr = NULL;
3067 }
3068 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3069 if (!is_error(ret) && arg3) {
3070 p = lock_user(arg3, sizeof(target_sigset_t), 0);
3071 host_to_target_old_sigset(p, &oldset);
3072 unlock_user(p, arg3, sizeof(target_sigset_t));
3073 }
3074 }
3075 break;
3076 #endif
3077 case TARGET_NR_rt_sigprocmask:
3078 {
3079 int how = arg1;
3080 sigset_t set, oldset, *set_ptr;
3081
3082 if (arg2) {
3083 switch(how) {
3084 case TARGET_SIG_BLOCK:
3085 how = SIG_BLOCK;
3086 break;
3087 case TARGET_SIG_UNBLOCK:
3088 how = SIG_UNBLOCK;
3089 break;
3090 case TARGET_SIG_SETMASK:
3091 how = SIG_SETMASK;
3092 break;
3093 default:
3094 ret = -EINVAL;
3095 goto fail;
3096 }
3097 p = lock_user(arg2, sizeof(target_sigset_t), 1);
3098 target_to_host_sigset(&set, p);
3099 unlock_user(p, arg2, 0);
3100 set_ptr = &set;
3101 } else {
3102 how = 0;
3103 set_ptr = NULL;
3104 }
3105 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3106 if (!is_error(ret) && arg3) {
3107 p = lock_user(arg3, sizeof(target_sigset_t), 0);
3108 host_to_target_sigset(p, &oldset);
3109 unlock_user(p, arg3, sizeof(target_sigset_t));
3110 }
3111 }
3112 break;
3113 #ifdef TARGET_NR_sigpending
3114 case TARGET_NR_sigpending:
3115 {
3116 sigset_t set;
3117 ret = get_errno(sigpending(&set));
3118 if (!is_error(ret)) {
3119 p = lock_user(arg1, sizeof(target_sigset_t), 0);
3120 host_to_target_old_sigset(p, &set);
3121 unlock_user(p, arg1, sizeof(target_sigset_t));
3122 }
3123 }
3124 break;
3125 #endif
3126 case TARGET_NR_rt_sigpending:
3127 {
3128 sigset_t set;
3129 ret = get_errno(sigpending(&set));
3130 if (!is_error(ret)) {
3131 p = lock_user(arg1, sizeof(target_sigset_t), 0);
3132 host_to_target_sigset(p, &set);
3133 unlock_user(p, arg1, sizeof(target_sigset_t));
3134 }
3135 }
3136 break;
3137 #ifdef TARGET_NR_sigsuspend
3138 case TARGET_NR_sigsuspend:
3139 {
3140 sigset_t set;
3141 p = lock_user(arg1, sizeof(target_sigset_t), 1);
3142 target_to_host_old_sigset(&set, p);
3143 unlock_user(p, arg1, 0);
3144 ret = get_errno(sigsuspend(&set));
3145 }
3146 break;
3147 #endif
3148 case TARGET_NR_rt_sigsuspend:
3149 {
3150 sigset_t set;
3151 p = lock_user(arg1, sizeof(target_sigset_t), 1);
3152 target_to_host_sigset(&set, p);
3153 unlock_user(p, arg1, 0);
3154 ret = get_errno(sigsuspend(&set));
3155 }
3156 break;
3157 case TARGET_NR_rt_sigtimedwait:
3158 {
3159 sigset_t set;
3160 struct timespec uts, *puts;
3161 siginfo_t uinfo;
3162
3163 p = lock_user(arg1, sizeof(target_sigset_t), 1);
3164 target_to_host_sigset(&set, p);
3165 unlock_user(p, arg1, 0);
3166 if (arg3) {
3167 puts = &uts;
3168 target_to_host_timespec(puts, arg3);
3169 } else {
3170 puts = NULL;
3171 }
3172 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
3173 if (!is_error(ret) && arg2) {
3174 p = lock_user(arg2, sizeof(target_sigset_t), 0);
3175 host_to_target_siginfo(p, &uinfo);
3176 unlock_user(p, arg2, sizeof(target_sigset_t));
3177 }
3178 }
3179 break;
3180 case TARGET_NR_rt_sigqueueinfo:
3181 {
3182 siginfo_t uinfo;
3183 p = lock_user(arg3, sizeof(target_sigset_t), 1);
3184 target_to_host_siginfo(&uinfo, p);
3185 unlock_user(p, arg1, 0);
3186 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
3187 }
3188 break;
3189 #ifdef TARGET_NR_sigreturn
3190 case TARGET_NR_sigreturn:
3191 /* NOTE: ret is eax, so not transcoding must be done */
3192 ret = do_sigreturn(cpu_env);
3193 break;
3194 #endif
3195 case TARGET_NR_rt_sigreturn:
3196 /* NOTE: ret is eax, so not transcoding must be done */
3197 ret = do_rt_sigreturn(cpu_env);
3198 break;
3199 case TARGET_NR_sethostname:
3200 p = lock_user_string(arg1);
3201 ret = get_errno(sethostname(p, arg2));
3202 unlock_user(p, arg1, 0);
3203 break;
3204 case TARGET_NR_setrlimit:
3205 {
3206 /* XXX: convert resource ? */
3207 int resource = arg1;
3208 struct target_rlimit *target_rlim;
3209 struct rlimit rlim;
3210 lock_user_struct(target_rlim, arg2, 1);
3211 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3212 rlim.rlim_max = tswapl(target_rlim->rlim_max);
3213 unlock_user_struct(target_rlim, arg2, 0);
3214 ret = get_errno(setrlimit(resource, &rlim));
3215 }
3216 break;
3217 case TARGET_NR_getrlimit:
3218 {
3219 /* XXX: convert resource ? */
3220 int resource = arg1;
3221 struct target_rlimit *target_rlim;
3222 struct rlimit rlim;
3223
3224 ret = get_errno(getrlimit(resource, &rlim));
3225 if (!is_error(ret)) {
3226 lock_user_struct(target_rlim, arg2, 0);
3227 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3228 rlim.rlim_max = tswapl(target_rlim->rlim_max);
3229 unlock_user_struct(target_rlim, arg2, 1);
3230 }
3231 }
3232 break;
3233 case TARGET_NR_getrusage:
3234 {
3235 struct rusage rusage;
3236 ret = get_errno(getrusage(arg1, &rusage));
3237 if (!is_error(ret)) {
3238 host_to_target_rusage(arg2, &rusage);
3239 }
3240 }
3241 break;
3242 case TARGET_NR_gettimeofday:
3243 {
3244 struct timeval tv;
3245 ret = get_errno(gettimeofday(&tv, NULL));
3246 if (!is_error(ret)) {
3247 host_to_target_timeval(arg1, &tv);
3248 }
3249 }
3250 break;
3251 case TARGET_NR_settimeofday:
3252 {
3253 struct timeval tv;
3254 target_to_host_timeval(&tv, arg1);
3255 ret = get_errno(settimeofday(&tv, NULL));
3256 }
3257 break;
3258 #ifdef TARGET_NR_select
3259 case TARGET_NR_select:
3260 {
3261 struct target_sel_arg_struct *sel;
3262 target_ulong inp, outp, exp, tvp;
3263 long nsel;
3264
3265 lock_user_struct(sel, arg1, 1);
3266 nsel = tswapl(sel->n);
3267 inp = tswapl(sel->inp);
3268 outp = tswapl(sel->outp);
3269 exp = tswapl(sel->exp);
3270 tvp = tswapl(sel->tvp);
3271 unlock_user_struct(sel, arg1, 0);
3272 ret = do_select(nsel, inp, outp, exp, tvp);
3273 }
3274 break;
3275 #endif
3276 case TARGET_NR_symlink:
3277 {
3278 void *p2;
3279 p = lock_user_string(arg1);
3280 p2 = lock_user_string(arg2);
3281 ret = get_errno(symlink(p, p2));
3282 unlock_user(p2, arg2, 0);
3283 unlock_user(p, arg1, 0);
3284 }
3285 break;
3286 #ifdef TARGET_NR_oldlstat
3287 case TARGET_NR_oldlstat:
3288 goto unimplemented;
3289 #endif
3290 case TARGET_NR_readlink:
3291 {
3292 void *p2;
3293 p = lock_user_string(arg1);
3294 p2 = lock_user(arg2, arg3, 0);
3295 ret = get_errno(readlink(path(p), p2, arg3));
3296 unlock_user(p2, arg2, ret);
3297 unlock_user(p, arg1, 0);
3298 }
3299 break;
3300 #ifdef TARGET_NR_uselib
3301 case TARGET_NR_uselib:
3302 goto unimplemented;
3303 #endif
3304 #ifdef TARGET_NR_swapon
3305 case TARGET_NR_swapon:
3306 p = lock_user_string(arg1);
3307 ret = get_errno(swapon(p, arg2));
3308 unlock_user(p, arg1, 0);
3309 break;
3310 #endif
3311 case TARGET_NR_reboot:
3312 goto unimplemented;
3313 #ifdef TARGET_NR_readdir
3314 case TARGET_NR_readdir:
3315 goto unimplemented;
3316 #endif
3317 #ifdef TARGET_NR_mmap
3318 case TARGET_NR_mmap:
3319 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K)
3320 {
3321 target_ulong *v;
3322 target_ulong v1, v2, v3, v4, v5, v6;
3323 v = lock_user(arg1, 6 * sizeof(target_ulong), 1);
3324 v1 = tswapl(v[0]);
3325 v2 = tswapl(v[1]);
3326 v3 = tswapl(v[2]);
3327 v4 = tswapl(v[3]);
3328 v5 = tswapl(v[4]);
3329 v6 = tswapl(v[5]);
3330 unlock_user(v, arg1, 0);
3331 ret = get_errno(target_mmap(v1, v2, v3,
3332 target_to_host_bitmask(v4, mmap_flags_tbl),
3333 v5, v6));
3334 }
3335 #else
3336 ret = get_errno(target_mmap(arg1, arg2, arg3,
3337 target_to_host_bitmask(arg4, mmap_flags_tbl),
3338 arg5,
3339 arg6));
3340 #endif
3341 break;
3342 #endif
3343 #ifdef TARGET_NR_mmap2
3344 case TARGET_NR_mmap2:
3345 #if defined(TARGET_SPARC) || defined(TARGET_MIPS)
3346 #define MMAP_SHIFT 12
3347 #else
3348 #define MMAP_SHIFT TARGET_PAGE_BITS
3349 #endif
3350 ret = get_errno(target_mmap(arg1, arg2, arg3,
3351 target_to_host_bitmask(arg4, mmap_flags_tbl),
3352 arg5,
3353 arg6 << MMAP_SHIFT));
3354 break;
3355 #endif
3356 case TARGET_NR_munmap:
3357 ret = get_errno(target_munmap(arg1, arg2));
3358 break;
3359 case TARGET_NR_mprotect:
3360 ret = get_errno(target_mprotect(arg1, arg2, arg3));
3361 break;
3362 #ifdef TARGET_NR_mremap
3363 case TARGET_NR_mremap:
3364 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
3365 break;
3366 #endif
3367 /* ??? msync/mlock/munlock are broken for softmmu. */
3368 #ifdef TARGET_NR_msync
3369 case TARGET_NR_msync:
3370 ret = get_errno(msync(g2h(arg1), arg2, arg3));
3371 break;
3372 #endif
3373 #ifdef TARGET_NR_mlock
3374 case TARGET_NR_mlock:
3375 ret = get_errno(mlock(g2h(arg1), arg2));
3376 break;
3377 #endif
3378 #ifdef TARGET_NR_munlock
3379 case TARGET_NR_munlock:
3380 ret = get_errno(munlock(g2h(arg1), arg2));
3381 break;
3382 #endif
3383 #ifdef TARGET_NR_mlockall
3384 case TARGET_NR_mlockall:
3385 ret = get_errno(mlockall(arg1));
3386 break;
3387 #endif
3388 #ifdef TARGET_NR_munlockall
3389 case TARGET_NR_munlockall:
3390 ret = get_errno(munlockall());
3391 break;
3392 #endif
3393 case TARGET_NR_truncate:
3394 p = lock_user_string(arg1);
3395 ret = get_errno(truncate(p, arg2));
3396 unlock_user(p, arg1, 0);
3397 break;
3398 case TARGET_NR_ftruncate:
3399 ret = get_errno(ftruncate(arg1, arg2));
3400 break;
3401 case TARGET_NR_fchmod:
3402 ret = get_errno(fchmod(arg1, arg2));
3403 break;
3404 case TARGET_NR_getpriority:
3405 ret = get_errno(getpriority(arg1, arg2));
3406 break;
3407 case TARGET_NR_setpriority:
3408 ret = get_errno(setpriority(arg1, arg2, arg3));
3409 break;
3410 #ifdef TARGET_NR_profil
3411 case TARGET_NR_profil:
3412 goto unimplemented;
3413 #endif
3414 case TARGET_NR_statfs:
3415 p = lock_user_string(arg1);
3416 ret = get_errno(statfs(path(p), &stfs));
3417 unlock_user(p, arg1, 0);
3418 convert_statfs:
3419 if (!is_error(ret)) {
3420 struct target_statfs *target_stfs;
3421
3422 lock_user_struct(target_stfs, arg2, 0);
3423 /* ??? put_user is probably wrong. */
3424 put_user(stfs.f_type, &target_stfs->f_type);
3425 put_user(stfs.f_bsize, &target_stfs->f_bsize);
3426 put_user(stfs.f_blocks, &target_stfs->f_blocks);
3427 put_user(stfs.f_bfree, &target_stfs->f_bfree);
3428 put_user(stfs.f_bavail, &target_stfs->f_bavail);
3429 put_user(stfs.f_files, &target_stfs->f_files);
3430 put_user(stfs.f_ffree, &target_stfs->f_ffree);
3431 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
3432 put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
3433 put_user(stfs.f_namelen, &target_stfs->f_namelen);
3434 unlock_user_struct(target_stfs, arg2, 1);
3435 }
3436 break;
3437 case TARGET_NR_fstatfs:
3438 ret = get_errno(fstatfs(arg1, &stfs));
3439 goto convert_statfs;
3440 #ifdef TARGET_NR_statfs64
3441 case TARGET_NR_statfs64:
3442 p = lock_user_string(arg1);
3443 ret = get_errno(statfs(path(p), &stfs));
3444 unlock_user(p, arg1, 0);
3445 convert_statfs64:
3446 if (!is_error(ret)) {
3447 struct target_statfs64 *target_stfs;
3448
3449 lock_user_struct(target_stfs, arg3, 0);
3450 /* ??? put_user is probably wrong. */
3451 put_user(stfs.f_type, &target_stfs->f_type);
3452 put_user(stfs.f_bsize, &target_stfs->f_bsize);
3453 put_user(stfs.f_blocks, &target_stfs->f_blocks);
3454 put_user(stfs.f_bfree, &target_stfs->f_bfree);
3455 put_user(stfs.f_bavail, &target_stfs->f_bavail);
3456 put_user(stfs.f_files, &target_stfs->f_files);
3457 put_user(stfs.f_ffree, &target_stfs->f_ffree);
3458 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
3459 put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
3460 put_user(stfs.f_namelen, &target_stfs->f_namelen);
3461 unlock_user_struct(target_stfs, arg3, 0);
3462 }
3463 break;
3464 case TARGET_NR_fstatfs64:
3465 ret = get_errno(fstatfs(arg1, &stfs));
3466 goto convert_statfs64;
3467 #endif
3468 #ifdef TARGET_NR_ioperm
3469 case TARGET_NR_ioperm:
3470 goto unimplemented;
3471 #endif
3472 #ifdef TARGET_NR_socketcall
3473 case TARGET_NR_socketcall:
3474 ret = do_socketcall(arg1, arg2);
3475 break;
3476 #endif
3477 #ifdef TARGET_NR_accept
3478 case TARGET_NR_accept:
3479 ret = do_accept(arg1, arg2, arg3);
3480 break;
3481 #endif
3482 #ifdef TARGET_NR_bind
3483 case TARGET_NR_bind:
3484 ret = do_bind(arg1, arg2, arg3);
3485 break;
3486 #endif
3487 #ifdef TARGET_NR_connect
3488 case TARGET_NR_connect:
3489 ret = do_connect(arg1, arg2, arg3);
3490 break;
3491 #endif
3492 #ifdef TARGET_NR_getpeername
3493 case TARGET_NR_getpeername:
3494 ret = do_getpeername(arg1, arg2, arg3);
3495 break;
3496 #endif
3497 #ifdef TARGET_NR_getsockname
3498 case TARGET_NR_getsockname:
3499 ret = do_getsockname(arg1, arg2, arg3);
3500 break;
3501 #endif
3502 #ifdef TARGET_NR_getsockopt
3503 case TARGET_NR_getsockopt:
3504 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
3505 break;
3506 #endif
3507 #ifdef TARGET_NR_listen
3508 case TARGET_NR_listen:
3509 ret = get_errno(listen(arg1, arg2));
3510 break;
3511 #endif
3512 #ifdef TARGET_NR_recv
3513 case TARGET_NR_recv:
3514 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
3515 break;
3516 #endif
3517 #ifdef TARGET_NR_recvfrom
3518 case TARGET_NR_recvfrom:
3519 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
3520 break;
3521 #endif
3522 #ifdef TARGET_NR_recvmsg
3523 case TARGET_NR_recvmsg:
3524 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
3525 break;
3526 #endif
3527 #ifdef TARGET_NR_send
3528 case TARGET_NR_send:
3529 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
3530 break;
3531 #endif
3532 #ifdef TARGET_NR_sendmsg
3533 case TARGET_NR_sendmsg:
3534 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
3535 break;
3536 #endif
3537 #ifdef TARGET_NR_sendto
3538 case TARGET_NR_sendto:
3539 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
3540 break;
3541 #endif
3542 #ifdef TARGET_NR_shutdown
3543 case TARGET_NR_shutdown:
3544 ret = get_errno(shutdown(arg1, arg2));
3545 break;
3546 #endif
3547 #ifdef TARGET_NR_socket
3548 case TARGET_NR_socket:
3549 ret = do_socket(arg1, arg2, arg3);
3550 break;
3551 #endif
3552 #ifdef TARGET_NR_socketpair
3553 case TARGET_NR_socketpair:
3554 ret = do_socketpair(arg1, arg2, arg3, arg4);
3555 break;
3556 #endif
3557 #ifdef TARGET_NR_setsockopt
3558 case TARGET_NR_setsockopt:
3559 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
3560 break;
3561 #endif
3562
3563 case TARGET_NR_syslog:
3564 p = lock_user_string(arg2);
3565 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
3566 unlock_user(p, arg2, 0);
3567 break;
3568
3569 case TARGET_NR_setitimer:
3570 {
3571 struct itimerval value, ovalue, *pvalue;
3572
3573 if (arg2) {
3574 pvalue = &value;
3575 target_to_host_timeval(&pvalue->it_interval,
3576 arg2);
3577 target_to_host_timeval(&pvalue->it_value,
3578 arg2 + sizeof(struct target_timeval));
3579 } else {
3580 pvalue = NULL;
3581 }
3582 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
3583 if (!is_error(ret) && arg3) {
3584 host_to_target_timeval(arg3,
3585 &ovalue.it_interval);
3586 host_to_target_timeval(arg3 + sizeof(struct target_timeval),
3587 &ovalue.it_value);
3588 }
3589 }
3590 break;
3591 case TARGET_NR_getitimer:
3592 {
3593 struct itimerval value;
3594
3595 ret = get_errno(getitimer(arg1, &value));
3596 if (!is_error(ret) && arg2) {
3597 host_to_target_timeval(arg2,
3598 &value.it_interval);
3599 host_to_target_timeval(arg2 + sizeof(struct target_timeval),
3600 &value.it_value);
3601 }
3602 }
3603 break;
3604 case TARGET_NR_stat:
3605 p = lock_user_string(arg1);
3606 ret = get_errno(stat(path(p), &st));
3607 unlock_user(p, arg1, 0);
3608 goto do_stat;
3609 case TARGET_NR_lstat:
3610 p = lock_user_string(arg1);
3611 ret = get_errno(lstat(path(p), &st));
3612 unlock_user(p, arg1, 0);
3613 goto do_stat;
3614 case TARGET_NR_fstat:
3615 {
3616 ret = get_errno(fstat(arg1, &st));
3617 do_stat:
3618 if (!is_error(ret)) {
3619 struct target_stat *target_st;
3620
3621 lock_user_struct(target_st, arg2, 0);
3622 #if defined(TARGET_MIPS) || defined(TARGET_SPARC64)
3623 target_st->st_dev = tswap32(st.st_dev);
3624 #else
3625 target_st->st_dev = tswap16(st.st_dev);
3626 #endif
3627 target_st->st_ino = tswapl(st.st_ino);
3628 #if defined(TARGET_PPC) || defined(TARGET_MIPS)
3629 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
3630 target_st->st_uid = tswap32(st.st_uid);
3631 target_st->st_gid = tswap32(st.st_gid);
3632 #elif defined(TARGET_SPARC64)
3633 target_st->st_mode = tswap32(st.st_mode);
3634 target_st->st_uid = tswap32(st.st_uid);
3635 target_st->st_gid = tswap32(st.st_gid);
3636 #else
3637 target_st->st_mode = tswap16(st.st_mode);
3638 target_st->st_uid = tswap16(st.st_uid);
3639 target_st->st_gid = tswap16(st.st_gid);
3640 #endif
3641 #if defined(TARGET_MIPS)
3642 /* If this is the same on PPC, then just merge w/ the above ifdef */
3643 target_st->st_nlink = tswapl(st.st_nlink);
3644 target_st->st_rdev = tswapl(st.st_rdev);
3645 #elif defined(TARGET_SPARC64)
3646 target_st->st_nlink = tswap32(st.st_nlink);
3647 target_st->st_rdev = tswap32(st.st_rdev);
3648 #else
3649 target_st->st_nlink = tswap16(st.st_nlink);
3650 target_st->st_rdev = tswap16(st.st_rdev);
3651 #endif
3652 target_st->st_size = tswapl(st.st_size);
3653 target_st->st_blksize = tswapl(st.st_blksize);
3654 target_st->st_blocks = tswapl(st.st_blocks);
3655 target_st->target_st_atime = tswapl(st.st_atime);
3656 target_st->target_st_mtime = tswapl(st.st_mtime);
3657 target_st->target_st_ctime = tswapl(st.st_ctime);
3658 unlock_user_struct(target_st, arg2, 1);
3659 }
3660 }
3661 break;
3662 #ifdef TARGET_NR_olduname
3663 case TARGET_NR_olduname:
3664 goto unimplemented;
3665 #endif
3666 #ifdef TARGET_NR_iopl
3667 case TARGET_NR_iopl:
3668 goto unimplemented;
3669 #endif
3670 case TARGET_NR_vhangup:
3671 ret = get_errno(vhangup());
3672 break;
3673 #ifdef TARGET_NR_idle
3674 case TARGET_NR_idle:
3675 goto unimplemented;
3676 #endif
3677 #ifdef TARGET_NR_syscall
3678 case TARGET_NR_syscall:
3679 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
3680 break;
3681 #endif
3682 case TARGET_NR_wait4:
3683 {
3684 int status;
3685 target_long status_ptr = arg2;
3686 struct rusage rusage, *rusage_ptr;
3687 target_ulong target_rusage = arg4;
3688 if (target_rusage)
3689 rusage_ptr = &rusage;
3690 else
3691 rusage_ptr = NULL;
3692 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
3693 if (!is_error(ret)) {
3694 if (status_ptr)
3695 tputl(status_ptr, status);
3696 if (target_rusage) {
3697 host_to_target_rusage(target_rusage, &rusage);
3698 }
3699 }
3700 }
3701 break;
3702 #ifdef TARGET_NR_swapoff
3703 case TARGET_NR_swapoff:
3704 p = lock_user_string(arg1);
3705 ret = get_errno(swapoff(p));
3706 unlock_user(p, arg1, 0);
3707 break;
3708 #endif
3709 case TARGET_NR_sysinfo:
3710 {
3711 struct target_sysinfo *target_value;
3712 struct sysinfo value;
3713 ret = get_errno(sysinfo(&value));
3714 if (!is_error(ret) && arg1)
3715 {
3716 /* ??? __put_user is probably wrong. */
3717 lock_user_struct(target_value, arg1, 0);
3718 __put_user(value.uptime, &target_value->uptime);
3719 __put_user(value.loads[0], &target_value->loads[0]);
3720 __put_user(value.loads[1], &target_value->loads[1]);
3721 __put_user(value.loads[2], &target_value->loads[2]);
3722 __put_user(value.totalram, &target_value->totalram);
3723 __put_user(value.freeram, &target_value->freeram);
3724 __put_user(value.sharedram, &target_value->sharedram);
3725 __put_user(value.bufferram, &target_value->bufferram);
3726 __put_user(value.totalswap, &target_value->totalswap);
3727 __put_user(value.freeswap, &target_value->freeswap);
3728 __put_user(value.procs, &target_value->procs);
3729 __put_user(value.totalhigh, &target_value->totalhigh);
3730 __put_user(value.freehigh, &target_value->freehigh);
3731 __put_user(value.mem_unit, &target_value->mem_unit);
3732 unlock_user_struct(target_value, arg1, 1);
3733 }
3734 }
3735 break;
3736 #ifdef TARGET_NR_ipc
3737 case TARGET_NR_ipc:
3738 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
3739 break;
3740 #endif
3741 case TARGET_NR_fsync:
3742 ret = get_errno(fsync(arg1));
3743 break;
3744 case TARGET_NR_clone:
3745 ret = get_errno(do_fork(cpu_env, arg1, arg2));
3746 break;
3747 #ifdef __NR_exit_group
3748 /* new thread calls */
3749 case TARGET_NR_exit_group:
3750 gdb_exit(cpu_env, arg1);
3751 ret = get_errno(exit_group(arg1));
3752 break;
3753 #endif
3754 case TARGET_NR_setdomainname:
3755 p = lock_user_string(arg1);
3756 ret = get_errno(setdomainname(p, arg2));
3757 unlock_user(p, arg1, 0);
3758 break;
3759 case TARGET_NR_uname:
3760 /* no need to transcode because we use the linux syscall */
3761 {
3762 struct new_utsname * buf;
3763
3764 lock_user_struct(buf, arg1, 0);
3765 ret = get_errno(sys_uname(buf));
3766 if (!is_error(ret)) {
3767 /* Overrite the native machine name with whatever is being
3768 emulated. */
3769 strcpy (buf->machine, UNAME_MACHINE);
3770 /* Allow the user to override the reported release. */
3771 if (qemu_uname_release && *qemu_uname_release)
3772 strcpy (buf->release, qemu_uname_release);
3773 }
3774 unlock_user_struct(buf, arg1, 1);
3775 }
3776 break;
3777 #ifdef TARGET_I386
3778 case TARGET_NR_modify_ldt:
3779 ret = get_errno(do_modify_ldt(cpu_env, arg1, arg2, arg3));
3780 break;
3781 #if !defined(TARGET_X86_64)
3782 case TARGET_NR_vm86old:
3783 goto unimplemented;
3784 case TARGET_NR_vm86:
3785 ret = do_vm86(cpu_env, arg1, arg2);
3786 break;
3787 #endif
3788 #endif
3789 case TARGET_NR_adjtimex:
3790 goto unimplemented;
3791 #ifdef TARGET_NR_create_module
3792 case TARGET_NR_create_module:
3793 #endif
3794 case TARGET_NR_init_module:
3795 case TARGET_NR_delete_module:
3796 #ifdef TARGET_NR_get_kernel_syms
3797 case TARGET_NR_get_kernel_syms:
3798 #endif
3799 goto unimplemented;
3800 case TARGET_NR_quotactl:
3801 goto unimplemented;
3802 case TARGET_NR_getpgid:
3803 ret = get_errno(getpgid(arg1));
3804 break;
3805 case TARGET_NR_fchdir:
3806 ret = get_errno(fchdir(arg1));
3807 break;
3808 #ifdef TARGET_NR_bdflush /* not on x86_64 */
3809 case TARGET_NR_bdflush:
3810 goto unimplemented;
3811 #endif
3812 #ifdef TARGET_NR_sysfs
3813 case TARGET_NR_sysfs:
3814 goto unimplemented;
3815 #endif
3816 case TARGET_NR_personality:
3817 ret = get_errno(personality(arg1));
3818 break;
3819 #ifdef TARGET_NR_afs_syscall
3820 case TARGET_NR_afs_syscall:
3821 goto unimplemented;
3822 #endif
3823 #ifdef TARGET_NR__llseek /* Not on alpha */
3824 case TARGET_NR__llseek:
3825 {
3826 #if defined (__x86_64__)
3827 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
3828 tput64(arg4, ret);
3829 #else
3830 int64_t res;
3831 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
3832 tput64(arg4, res);
3833 #endif
3834 }
3835 break;
3836 #endif
3837 case TARGET_NR_getdents:
3838 #if TARGET_LONG_SIZE != 4
3839 goto unimplemented;
3840 #warning not supported
3841 #elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
3842 {
3843 struct target_dirent *target_dirp;
3844 struct dirent *dirp;
3845 long count = arg3;
3846
3847 dirp = malloc(count);
3848 if (!dirp)
3849 return -ENOMEM;
3850
3851 ret = get_errno(sys_getdents(arg1, dirp, count));
3852 if (!is_error(ret)) {
3853 struct dirent *de;
3854 struct target_dirent *tde;
3855 int len = ret;
3856 int reclen, treclen;
3857 int count1, tnamelen;
3858
3859 count1 = 0;
3860 de = dirp;
3861 target_dirp = lock_user(arg2, count, 0);
3862 tde = target_dirp;
3863 while (len > 0) {
3864 reclen = de->d_reclen;
3865 treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
3866 tde->d_reclen = tswap16(treclen);
3867 tde->d_ino = tswapl(de->d_ino);
3868 tde->d_off = tswapl(de->d_off);
3869 tnamelen = treclen - (2 * sizeof(target_long) + 2);
3870 if (tnamelen > 256)
3871 tnamelen = 256;
3872 /* XXX: may not be correct */
3873 strncpy(tde->d_name, de->d_name, tnamelen);
3874 de = (struct dirent *)((char *)de + reclen);
3875 len -= reclen;
3876 tde = (struct target_dirent *)((char *)tde + treclen);
3877 count1 += treclen;
3878 }
3879 ret = count1;
3880 }
3881 unlock_user(target_dirp, arg2, ret);
3882 free(dirp);
3883 }
3884 #else
3885 {
3886 struct dirent *dirp;
3887 long count = arg3;
3888
3889 dirp = lock_user(arg2, count, 0);
3890 ret = get_errno(sys_getdents(arg1, dirp, count));
3891 if (!is_error(ret)) {
3892 struct dirent *de;
3893 int len = ret;
3894 int reclen;
3895 de = dirp;
3896 while (len > 0) {
3897 reclen = de->d_reclen;
3898 if (reclen > len)
3899 break;
3900 de->d_reclen = tswap16(reclen);
3901 tswapls(&de->d_ino);
3902 tswapls(&de->d_off);
3903 de = (struct dirent *)((char *)de + reclen);
3904 len -= reclen;
3905 }
3906 }
3907 unlock_user(dirp, arg2, ret);
3908 }
3909 #endif
3910 break;
3911 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
3912 case TARGET_NR_getdents64:
3913 {
3914 struct dirent64 *dirp;
3915 long count = arg3;
3916 dirp = lock_user(arg2, count, 0);
3917 ret = get_errno(sys_getdents64(arg1, dirp, count));
3918 if (!is_error(ret)) {
3919 struct dirent64 *de;
3920 int len = ret;
3921 int reclen;
3922 de = dirp;
3923 while (len > 0) {
3924 reclen = de->d_reclen;
3925 if (reclen > len)
3926 break;
3927 de->d_reclen = tswap16(reclen);
3928 tswap64s(&de->d_ino);
3929 tswap64s(&de->d_off);
3930 de = (struct dirent64 *)((char *)de + reclen);
3931 len -= reclen;
3932 }
3933 }
3934 unlock_user(dirp, arg2, ret);
3935 }
3936 break;
3937 #endif /* TARGET_NR_getdents64 */
3938 #ifdef TARGET_NR__newselect
3939 case TARGET_NR__newselect:
3940 ret = do_select(arg1, arg2, arg3, arg4, arg5);
3941 break;
3942 #endif
3943 #ifdef TARGET_NR_poll
3944 case TARGET_NR_poll:
3945 {
3946 struct target_pollfd *target_pfd;
3947 unsigned int nfds = arg2;
3948 int timeout = arg3;
3949 struct pollfd *pfd;
3950 unsigned int i;
3951
3952 target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1);
3953 pfd = alloca(sizeof(struct pollfd) * nfds);
3954 for(i = 0; i < nfds; i++) {
3955 pfd[i].fd = tswap32(target_pfd[i].fd);
3956 pfd[i].events = tswap16(target_pfd[i].events);
3957 }
3958 ret = get_errno(poll(pfd, nfds, timeout));
3959 if (!is_error(ret)) {
3960 for(i = 0; i < nfds; i++) {
3961 target_pfd[i].revents = tswap16(pfd[i].revents);
3962 }
3963 ret += nfds * (sizeof(struct target_pollfd)
3964 - sizeof(struct pollfd));
3965 }
3966 unlock_user(target_pfd, arg1, ret);
3967 }
3968 break;
3969 #endif
3970 case TARGET_NR_flock:
3971 /* NOTE: the flock constant seems to be the same for every
3972 Linux platform */
3973 ret = get_errno(flock(arg1, arg2));
3974 break;
3975 case TARGET_NR_readv:
3976 {
3977 int count = arg3;
3978 struct iovec *vec;
3979
3980 vec = alloca(count * sizeof(struct iovec));
3981 lock_iovec(vec, arg2, count, 0);
3982 ret = get_errno(readv(arg1, vec, count));
3983 unlock_iovec(vec, arg2, count, 1);
3984 }
3985 break;
3986 case TARGET_NR_writev:
3987 {
3988 int count = arg3;
3989 struct iovec *vec;
3990
3991 vec = alloca(count * sizeof(struct iovec));
3992 lock_iovec(vec, arg2, count, 1);
3993 ret = get_errno(writev(arg1, vec, count));
3994 unlock_iovec(vec, arg2, count, 0);
3995 }
3996 break;
3997 case TARGET_NR_getsid:
3998 ret = get_errno(getsid(arg1));
3999 break;
4000 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
4001 case TARGET_NR_fdatasync:
4002 ret = get_errno(fdatasync(arg1));
4003 break;
4004 #endif
4005 case TARGET_NR__sysctl:
4006 /* We don't implement this, but ENODIR is always a safe
4007 return value. */
4008 return -ENOTDIR;
4009 case TARGET_NR_sched_setparam:
4010 {
4011 struct sched_param *target_schp;
4012 struct sched_param schp;
4013
4014 lock_user_struct(target_schp, arg2, 1);
4015 schp.sched_priority = tswap32(target_schp->sched_priority);
4016 unlock_user_struct(target_schp, arg2, 0);
4017 ret = get_errno(sched_setparam(arg1, &schp));
4018 }
4019 break;
4020 case TARGET_NR_sched_getparam:
4021 {
4022 struct sched_param *target_schp;
4023 struct sched_param schp;
4024 ret = get_errno(sched_getparam(arg1, &schp));
4025 if (!is_error(ret)) {
4026 lock_user_struct(target_schp, arg2, 0);
4027 target_schp->sched_priority = tswap32(schp.sched_priority);
4028 unlock_user_struct(target_schp, arg2, 1);
4029 }
4030 }
4031 break;
4032 case TARGET_NR_sched_setscheduler:
4033 {
4034 struct sched_param *target_schp;
4035 struct sched_param schp;
4036 lock_user_struct(target_schp, arg3, 1);
4037 schp.sched_priority = tswap32(target_schp->sched_priority);
4038 unlock_user_struct(target_schp, arg3, 0);
4039 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
4040 }
4041 break;
4042 case TARGET_NR_sched_getscheduler:
4043 ret = get_errno(sched_getscheduler(arg1));
4044 break;
4045 case TARGET_NR_sched_yield:
4046 ret = get_errno(sched_yield());
4047 break;
4048 case TARGET_NR_sched_get_priority_max:
4049 ret = get_errno(sched_get_priority_max(arg1));
4050 break;
4051 case TARGET_NR_sched_get_priority_min:
4052 ret = get_errno(sched_get_priority_min(arg1));
4053 break;
4054 case TARGET_NR_sched_rr_get_interval:
4055 {
4056 struct timespec ts;
4057 ret = get_errno(sched_rr_get_interval(arg1, &ts));
4058 if (!is_error(ret)) {
4059 host_to_target_timespec(arg2, &ts);
4060 }
4061 }
4062 break;
4063 case TARGET_NR_nanosleep:
4064 {
4065 struct timespec req, rem;
4066 target_to_host_timespec(&req, arg1);
4067 ret = get_errno(nanosleep(&req, &rem));
4068 if (is_error(ret) && arg2) {
4069 host_to_target_timespec(arg2, &rem);
4070 }
4071 }
4072 break;
4073 #ifdef TARGET_NR_query_module
4074 case TARGET_NR_query_module:
4075 goto unimplemented;
4076 #endif
4077 #ifdef TARGET_NR_nfsservctl
4078 case TARGET_NR_nfsservctl:
4079 goto unimplemented;
4080 #endif
4081 case TARGET_NR_prctl:
4082 switch (arg1)
4083 {
4084 case PR_GET_PDEATHSIG:
4085 {
4086 int deathsig;
4087 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
4088 if (!is_error(ret) && arg2)
4089 tput32(arg2, deathsig);
4090 }
4091 break;
4092 default:
4093 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
4094 break;
4095 }
4096 break;
4097 #ifdef TARGET_NR_pread
4098 case TARGET_NR_pread:
4099 page_unprotect_range(arg2, arg3);
4100 p = lock_user(arg2, arg3, 0);
4101 ret = get_errno(pread(arg1, p, arg3, arg4));
4102 unlock_user(p, arg2, ret);
4103 break;
4104 case TARGET_NR_pwrite:
4105 p = lock_user(arg2, arg3, 1);
4106 ret = get_errno(pwrite(arg1, p, arg3, arg4));
4107 unlock_user(p, arg2, 0);
4108 break;
4109 #endif
4110 case TARGET_NR_getcwd:
4111 p = lock_user(arg1, arg2, 0);
4112 ret = get_errno(sys_getcwd1(p, arg2));
4113 unlock_user(p, arg1, ret);
4114 break;
4115 case TARGET_NR_capget:
4116 goto unimplemented;
4117 case TARGET_NR_capset:
4118 goto unimplemented;
4119 case TARGET_NR_sigaltstack:
4120 goto unimplemented;
4121 case TARGET_NR_sendfile:
4122 goto unimplemented;
4123 #ifdef TARGET_NR_getpmsg
4124 case TARGET_NR_getpmsg:
4125 goto unimplemented;
4126 #endif
4127 #ifdef TARGET_NR_putpmsg
4128 case TARGET_NR_putpmsg:
4129 goto unimplemented;
4130 #endif
4131 #ifdef TARGET_NR_vfork
4132 case TARGET_NR_vfork:
4133 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
4134 break;
4135 #endif
4136 #ifdef TARGET_NR_ugetrlimit
4137 case TARGET_NR_ugetrlimit:
4138 {
4139 struct rlimit rlim;
4140 ret = get_errno(getrlimit(arg1, &rlim));
4141 if (!is_error(ret)) {
4142 struct target_rlimit *target_rlim;
4143 lock_user_struct(target_rlim, arg2, 0);
4144 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
4145 target_rlim->rlim_max = tswapl(rlim.rlim_max);
4146 unlock_user_struct(target_rlim, arg2, 1);
4147 }
4148 break;
4149 }
4150 #endif
4151 #ifdef TARGET_NR_truncate64
4152 case TARGET_NR_truncate64:
4153 p = lock_user_string(arg1);
4154 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
4155 unlock_user(p, arg1, 0);
4156 break;
4157 #endif
4158 #ifdef TARGET_NR_ftruncate64
4159 case TARGET_NR_ftruncate64:
4160 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
4161 break;
4162 #endif
4163 #ifdef TARGET_NR_stat64
4164 case TARGET_NR_stat64:
4165 p = lock_user_string(arg1);
4166 ret = get_errno(stat(path(p), &st));
4167 unlock_user(p, arg1, 0);
4168 goto do_stat64;
4169 #endif
4170 #ifdef TARGET_NR_lstat64
4171 case TARGET_NR_lstat64:
4172 p = lock_user_string(arg1);
4173 ret = get_errno(lstat(path(p), &st));
4174 unlock_user(p, arg1, 0);
4175 goto do_stat64;
4176 #endif
4177 #ifdef TARGET_NR_fstat64
4178 case TARGET_NR_fstat64:
4179 {
4180 ret = get_errno(fstat(arg1, &st));
4181 do_stat64:
4182 if (!is_error(ret)) {
4183 #ifdef TARGET_ARM
4184 if (((CPUARMState *)cpu_env)->eabi) {
4185 struct target_eabi_stat64 *target_st;
4186 lock_user_struct(target_st, arg2, 1);
4187 memset(target_st, 0, sizeof(struct target_eabi_stat64));
4188 /* put_user is probably wrong. */
4189 put_user(st.st_dev, &target_st->st_dev);
4190 put_user(st.st_ino, &target_st->st_ino);
4191 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4192 put_user(st.st_ino, &target_st->__st_ino);
4193 #endif
4194 put_user(st.st_mode, &target_st->st_mode);
4195 put_user(st.st_nlink, &target_st->st_nlink);
4196 put_user(st.st_uid, &target_st->st_uid);
4197 put_user(st.st_gid, &target_st->st_gid);
4198 put_user(st.st_rdev, &target_st->st_rdev);
4199 /* XXX: better use of kernel struct */
4200 put_user(st.st_size, &target_st->st_size);
4201 put_user(st.st_blksize, &target_st->st_blksize);
4202 put_user(st.st_blocks, &target_st->st_blocks);
4203 put_user(st.st_atime, &target_st->target_st_atime);
4204 put_user(st.st_mtime, &target_st->target_st_mtime);
4205 put_user(st.st_ctime, &target_st->target_st_ctime);
4206 unlock_user_struct(target_st, arg2, 0);
4207 } else
4208 #endif
4209 {
4210 struct target_stat64 *target_st;
4211 lock_user_struct(target_st, arg2, 1);
4212 memset(target_st, 0, sizeof(struct target_stat64));
4213 /* ??? put_user is probably wrong. */
4214 put_user(st.st_dev, &target_st->st_dev);
4215 put_user(st.st_ino, &target_st->st_ino);
4216 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4217 put_user(st.st_ino, &target_st->__st_ino);
4218 #endif
4219 put_user(st.st_mode, &target_st->st_mode);
4220 put_user(st.st_nlink, &target_st->st_nlink);
4221 put_user(st.st_uid, &target_st->st_uid);
4222 put_user(st.st_gid, &target_st->st_gid);
4223 put_user(st.st_rdev, &target_st->st_rdev);
4224 /* XXX: better use of kernel struct */
4225 put_user(st.st_size, &target_st->st_size);
4226 put_user(st.st_blksize, &target_st->st_blksize);
4227 put_user(st.st_blocks, &target_st->st_blocks);
4228 put_user(st.st_atime, &target_st->target_st_atime);
4229 put_user(st.st_mtime, &target_st->target_st_mtime);
4230 put_user(st.st_ctime, &target_st->target_st_ctime);
4231 unlock_user_struct(target_st, arg2, 0);
4232 }
4233 }
4234 }
4235 break;
4236 #endif
4237 #ifdef USE_UID16
4238 case TARGET_NR_lchown:
4239 p = lock_user_string(arg1);
4240 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
4241 unlock_user(p, arg1, 0);
4242 break;
4243 case TARGET_NR_getuid:
4244 ret = get_errno(high2lowuid(getuid()));
4245 break;
4246 case TARGET_NR_getgid:
4247 ret = get_errno(high2lowgid(getgid()));
4248 break;
4249 case TARGET_NR_geteuid:
4250 ret = get_errno(high2lowuid(geteuid()));
4251 break;
4252 case TARGET_NR_getegid:
4253 ret = get_errno(high2lowgid(getegid()));
4254 break;
4255 case TARGET_NR_setreuid:
4256 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
4257 break;
4258 case TARGET_NR_setregid:
4259 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
4260 break;
4261 case TARGET_NR_getgroups:
4262 {
4263 int gidsetsize = arg1;
4264 uint16_t *target_grouplist;
4265 gid_t *grouplist;
4266 int i;
4267
4268 grouplist = alloca(gidsetsize * sizeof(gid_t));
4269 ret = get_errno(getgroups(gidsetsize, grouplist));
4270 if (!is_error(ret)) {
4271 target_grouplist = lock_user(arg2, gidsetsize * 2, 0);
4272 for(i = 0;i < gidsetsize; i++)
4273 target_grouplist[i] = tswap16(grouplist[i]);
4274 unlock_user(target_grouplist, arg2, gidsetsize * 2);
4275 }
4276 }
4277 break;
4278 case TARGET_NR_setgroups:
4279 {
4280 int gidsetsize = arg1;
4281 uint16_t *target_grouplist;
4282 gid_t *grouplist;
4283 int i;
4284
4285 grouplist = alloca(gidsetsize * sizeof(gid_t));
4286 target_grouplist = lock_user(arg2, gidsetsize * 2, 1);
4287 for(i = 0;i < gidsetsize; i++)
4288 grouplist[i] = tswap16(target_grouplist[i]);
4289 unlock_user(target_grouplist, arg2, 0);
4290 ret = get_errno(setgroups(gidsetsize, grouplist));
4291 }
4292 break;
4293 case TARGET_NR_fchown:
4294 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
4295 break;
4296 #ifdef TARGET_NR_setresuid
4297 case TARGET_NR_setresuid:
4298 ret = get_errno(setresuid(low2highuid(arg1),
4299 low2highuid(arg2),
4300 low2highuid(arg3)));
4301 break;
4302 #endif
4303 #ifdef TARGET_NR_getresuid
4304 case TARGET_NR_getresuid:
4305 {
4306 uid_t ruid, euid, suid;
4307 ret = get_errno(getresuid(&ruid, &euid, &suid));
4308 if (!is_error(ret)) {
4309 tput16(arg1, tswap16(high2lowuid(ruid)));
4310 tput16(arg2, tswap16(high2lowuid(euid)));
4311 tput16(arg3, tswap16(high2lowuid(suid)));
4312 }
4313 }
4314 break;
4315 #endif
4316 #ifdef TARGET_NR_getresgid
4317 case TARGET_NR_setresgid:
4318 ret = get_errno(setresgid(low2highgid(arg1),
4319 low2highgid(arg2),
4320 low2highgid(arg3)));
4321 break;
4322 #endif
4323 #ifdef TARGET_NR_getresgid
4324 case TARGET_NR_getresgid:
4325 {
4326 gid_t rgid, egid, sgid;
4327 ret = get_errno(getresgid(&rgid, &egid, &sgid));
4328 if (!is_error(ret)) {
4329 tput16(arg1, tswap16(high2lowgid(rgid)));
4330 tput16(arg2, tswap16(high2lowgid(egid)));
4331 tput16(arg3, tswap16(high2lowgid(sgid)));
4332 }
4333 }
4334 break;
4335 #endif
4336 case TARGET_NR_chown:
4337 p = lock_user_string(arg1);
4338 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
4339 unlock_user(p, arg1, 0);
4340 break;
4341 case TARGET_NR_setuid:
4342 ret = get_errno(setuid(low2highuid(arg1)));
4343 break;
4344 case TARGET_NR_setgid:
4345 ret = get_errno(setgid(low2highgid(arg1)));
4346 break;
4347 case TARGET_NR_setfsuid:
4348 ret = get_errno(setfsuid(arg1));
4349 break;
4350 case TARGET_NR_setfsgid:
4351 ret = get_errno(setfsgid(arg1));
4352 break;
4353 #endif /* USE_UID16 */
4354
4355 #ifdef TARGET_NR_lchown32
4356 case TARGET_NR_lchown32:
4357 p = lock_user_string(arg1);
4358 ret = get_errno(lchown(p, arg2, arg3));
4359 unlock_user(p, arg1, 0);
4360 break;
4361 #endif
4362 #ifdef TARGET_NR_getuid32
4363 case TARGET_NR_getuid32:
4364 ret = get_errno(getuid());
4365 break;
4366 #endif
4367 #ifdef TARGET_NR_getgid32
4368 case TARGET_NR_getgid32:
4369 ret = get_errno(getgid());
4370 break;
4371 #endif
4372 #ifdef TARGET_NR_geteuid32
4373 case TARGET_NR_geteuid32:
4374 ret = get_errno(geteuid());
4375 break;
4376 #endif
4377 #ifdef TARGET_NR_getegid32
4378 case TARGET_NR_getegid32:
4379 ret = get_errno(getegid());
4380 break;
4381 #endif
4382 #ifdef TARGET_NR_setreuid32
4383 case TARGET_NR_setreuid32:
4384 ret = get_errno(setreuid(arg1, arg2));
4385 break;
4386 #endif
4387 #ifdef TARGET_NR_setregid32
4388 case TARGET_NR_setregid32:
4389 ret = get_errno(setregid(arg1, arg2));
4390 break;
4391 #endif
4392 #ifdef TARGET_NR_getgroups32
4393 case TARGET_NR_getgroups32:
4394 {
4395 int gidsetsize = arg1;
4396 uint32_t *target_grouplist;
4397 gid_t *grouplist;
4398 int i;
4399
4400 grouplist = alloca(gidsetsize * sizeof(gid_t));
4401 ret = get_errno(getgroups(gidsetsize, grouplist));
4402 if (!is_error(ret)) {
4403 target_grouplist = lock_user(arg2, gidsetsize * 4, 0);
4404 for(i = 0;i < gidsetsize; i++)
4405 target_grouplist[i] = tswap32(grouplist[i]);
4406 unlock_user(target_grouplist, arg2, gidsetsize * 4);
4407 }
4408 }
4409 break;
4410 #endif
4411 #ifdef TARGET_NR_setgroups32
4412 case TARGET_NR_setgroups32:
4413 {
4414 int gidsetsize = arg1;
4415 uint32_t *target_grouplist;
4416 gid_t *grouplist;
4417 int i;
4418
4419 grouplist = alloca(gidsetsize * sizeof(gid_t));
4420 target_grouplist = lock_user(arg2, gidsetsize * 4, 1);
4421 for(i = 0;i < gidsetsize; i++)
4422 grouplist[i] = tswap32(target_grouplist[i]);
4423 unlock_user(target_grouplist, arg2, 0);
4424 ret = get_errno(setgroups(gidsetsize, grouplist));
4425 }
4426 break;
4427 #endif
4428 #ifdef TARGET_NR_fchown32
4429 case TARGET_NR_fchown32:
4430 ret = get_errno(fchown(arg1, arg2, arg3));
4431 break;
4432 #endif
4433 #ifdef TARGET_NR_setresuid32
4434 case TARGET_NR_setresuid32:
4435 ret = get_errno(setresuid(arg1, arg2, arg3));
4436 break;
4437 #endif
4438 #ifdef TARGET_NR_getresuid32
4439 case TARGET_NR_getresuid32:
4440 {
4441 uid_t ruid, euid, suid;
4442 ret = get_errno(getresuid(&ruid, &euid, &suid));
4443 if (!is_error(ret)) {
4444 tput32(arg1, tswap32(ruid));
4445 tput32(arg2, tswap32(euid));
4446 tput32(arg3, tswap32(suid));
4447 }
4448 }
4449 break;
4450 #endif
4451 #ifdef TARGET_NR_setresgid32
4452 case TARGET_NR_setresgid32:
4453 ret = get_errno(setresgid(arg1, arg2, arg3));
4454 break;
4455 #endif
4456 #ifdef TARGET_NR_getresgid32
4457 case TARGET_NR_getresgid32:
4458 {
4459 gid_t rgid, egid, sgid;
4460 ret = get_errno(getresgid(&rgid, &egid, &sgid));
4461 if (!is_error(ret)) {
4462 tput32(arg1, tswap32(rgid));
4463 tput32(arg2, tswap32(egid));
4464 tput32(arg3, tswap32(sgid));
4465 }
4466 }
4467 break;
4468 #endif
4469 #ifdef TARGET_NR_chown32
4470 case TARGET_NR_chown32:
4471 p = lock_user_string(arg1);
4472 ret = get_errno(chown(p, arg2, arg3));
4473 unlock_user(p, arg1, 0);
4474 break;
4475 #endif
4476 #ifdef TARGET_NR_setuid32
4477 case TARGET_NR_setuid32:
4478 ret = get_errno(setuid(arg1));
4479 break;
4480 #endif
4481 #ifdef TARGET_NR_setgid32
4482 case TARGET_NR_setgid32:
4483 ret = get_errno(setgid(arg1));
4484 break;
4485 #endif
4486 #ifdef TARGET_NR_setfsuid32
4487 case TARGET_NR_setfsuid32:
4488 ret = get_errno(setfsuid(arg1));
4489 break;
4490 #endif
4491 #ifdef TARGET_NR_setfsgid32
4492 case TARGET_NR_setfsgid32:
4493 ret = get_errno(setfsgid(arg1));
4494 break;
4495 #endif
4496
4497 case TARGET_NR_pivot_root:
4498 goto unimplemented;
4499 #ifdef TARGET_NR_mincore
4500 case TARGET_NR_mincore:
4501 goto unimplemented;
4502 #endif
4503 #ifdef TARGET_NR_madvise
4504 case TARGET_NR_madvise:
4505 /* A straight passthrough may not be safe because qemu sometimes
4506 turns private flie-backed mappings into anonymous mappings.
4507 This will break MADV_DONTNEED.
4508 This is a hint, so ignoring and returning success is ok. */
4509 ret = get_errno(0);
4510 break;
4511 #endif
4512 #if TARGET_LONG_BITS == 32
4513 case TARGET_NR_fcntl64:
4514 {
4515 int cmd;
4516 struct flock64 fl;
4517 struct target_flock64 *target_fl;
4518 #ifdef TARGET_ARM
4519 struct target_eabi_flock64 *target_efl;
4520 #endif
4521
4522 switch(arg2){
4523 case TARGET_F_GETLK64:
4524 cmd = F_GETLK64;
4525 break;
4526 case TARGET_F_SETLK64:
4527 cmd = F_SETLK64;
4528 break;
4529 case TARGET_F_SETLKW64:
4530 cmd = F_SETLK64;
4531 break;
4532 default:
4533 cmd = arg2;
4534 break;
4535 }
4536
4537 switch(arg2) {
4538 case TARGET_F_GETLK64:
4539 #ifdef TARGET_ARM
4540 if (((CPUARMState *)cpu_env)->eabi) {
4541 lock_user_struct(target_efl, arg3, 1);
4542 fl.l_type = tswap16(target_efl->l_type);
4543 fl.l_whence = tswap16(target_efl->l_whence);
4544 fl.l_start = tswap64(target_efl->l_start);
4545 fl.l_len = tswap64(target_efl->l_len);
4546 fl.l_pid = tswapl(target_efl->l_pid);
4547 unlock_user_struct(target_efl, arg3, 0);
4548 } else
4549 #endif
4550 {
4551 lock_user_struct(target_fl, arg3, 1);
4552 fl.l_type = tswap16(target_fl->l_type);
4553 fl.l_whence = tswap16(target_fl->l_whence);
4554 fl.l_start = tswap64(target_fl->l_start);
4555 fl.l_len = tswap64(target_fl->l_len);
4556 fl.l_pid = tswapl(target_fl->l_pid);
4557 unlock_user_struct(target_fl, arg3, 0);
4558 }
4559 ret = get_errno(fcntl(arg1, cmd, &fl));
4560 if (ret == 0) {
4561 #ifdef TARGET_ARM
4562 if (((CPUARMState *)cpu_env)->eabi) {
4563 lock_user_struct(target_efl, arg3, 0);
4564 target_efl->l_type = tswap16(fl.l_type);
4565 target_efl->l_whence = tswap16(fl.l_whence);
4566 target_efl->l_start = tswap64(fl.l_start);
4567 target_efl->l_len = tswap64(fl.l_len);
4568 target_efl->l_pid = tswapl(fl.l_pid);
4569 unlock_user_struct(target_efl, arg3, 1);
4570 } else
4571 #endif
4572 {
4573 lock_user_struct(target_fl, arg3, 0);
4574 target_fl->l_type = tswap16(fl.l_type);
4575 target_fl->l_whence = tswap16(fl.l_whence);
4576 target_fl->l_start = tswap64(fl.l_start);
4577 target_fl->l_len = tswap64(fl.l_len);
4578 target_fl->l_pid = tswapl(fl.l_pid);
4579 unlock_user_struct(target_fl, arg3, 1);
4580 }
4581 }
4582 break;
4583
4584 case TARGET_F_SETLK64:
4585 case TARGET_F_SETLKW64:
4586 #ifdef TARGET_ARM
4587 if (((CPUARMState *)cpu_env)->eabi) {
4588 lock_user_struct(target_efl, arg3, 1);
4589 fl.l_type = tswap16(target_efl->l_type);
4590 fl.l_whence = tswap16(target_efl->l_whence);
4591 fl.l_start = tswap64(target_efl->l_start);
4592 fl.l_len = tswap64(target_efl->l_len);
4593 fl.l_pid = tswapl(target_efl->l_pid);
4594 unlock_user_struct(target_efl, arg3, 0);
4595 } else
4596 #endif
4597 {
4598 lock_user_struct(target_fl, arg3, 1);
4599 fl.l_type = tswap16(target_fl->l_type);
4600 fl.l_whence = tswap16(target_fl->l_whence);
4601 fl.l_start = tswap64(target_fl->l_start);
4602 fl.l_len = tswap64(target_fl->l_len);
4603 fl.l_pid = tswapl(target_fl->l_pid);
4604 unlock_user_struct(target_fl, arg3, 0);
4605 }
4606 ret = get_errno(fcntl(arg1, cmd, &fl));
4607 break;
4608 default:
4609 ret = get_errno(do_fcntl(arg1, cmd, arg3));
4610 break;
4611 }
4612 break;
4613 }
4614 #endif
4615 #ifdef TARGET_NR_cacheflush
4616 case TARGET_NR_cacheflush:
4617 /* self-modifying code is handled automatically, so nothing needed */
4618 ret = 0;
4619 break;
4620 #endif
4621 #ifdef TARGET_NR_security
4622 case TARGET_NR_security:
4623 goto unimplemented;
4624 #endif
4625 #ifdef TARGET_NR_getpagesize
4626 case TARGET_NR_getpagesize:
4627 ret = TARGET_PAGE_SIZE;
4628 break;
4629 #endif
4630 case TARGET_NR_gettid:
4631 ret = get_errno(gettid());
4632 break;
4633 #ifdef TARGET_NR_readahead
4634 case TARGET_NR_readahead:
4635 goto unimplemented;
4636 #endif
4637 #ifdef TARGET_NR_setxattr
4638 case TARGET_NR_setxattr:
4639 case TARGET_NR_lsetxattr:
4640 case TARGET_NR_fsetxattr:
4641 case TARGET_NR_getxattr:
4642 case TARGET_NR_lgetxattr:
4643 case TARGET_NR_fgetxattr:
4644 case TARGET_NR_listxattr:
4645 case TARGET_NR_llistxattr:
4646 case TARGET_NR_flistxattr:
4647 case TARGET_NR_removexattr:
4648 case TARGET_NR_lremovexattr:
4649 case TARGET_NR_fremovexattr:
4650 goto unimplemented_nowarn;
4651 #endif
4652 #ifdef TARGET_NR_set_thread_area
4653 case TARGET_NR_set_thread_area:
4654 #ifdef TARGET_MIPS
4655 ((CPUMIPSState *) cpu_env)->tls_value = arg1;
4656 ret = 0;
4657 break;
4658 #else
4659 goto unimplemented_nowarn;
4660 #endif
4661 #endif
4662 #ifdef TARGET_NR_get_thread_area
4663 case TARGET_NR_get_thread_area:
4664 goto unimplemented_nowarn;
4665 #endif
4666 #ifdef TARGET_NR_getdomainname
4667 case TARGET_NR_getdomainname:
4668 goto unimplemented_nowarn;
4669 #endif
4670
4671 #ifdef TARGET_NR_clock_gettime
4672 case TARGET_NR_clock_gettime:
4673 {
4674 struct timespec ts;
4675 ret = get_errno(clock_gettime(arg1, &ts));
4676 if (!is_error(ret)) {
4677 host_to_target_timespec(arg2, &ts);
4678 }
4679 break;
4680 }
4681 #endif
4682 #ifdef TARGET_NR_clock_getres
4683 case TARGET_NR_clock_getres:
4684 {
4685 struct timespec ts;
4686 ret = get_errno(clock_getres(arg1, &ts));
4687 if (!is_error(ret)) {
4688 host_to_target_timespec(arg2, &ts);
4689 }
4690 break;
4691 }
4692 #endif
4693
4694 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
4695 case TARGET_NR_set_tid_address:
4696 ret = get_errno(set_tid_address((int *) arg1));
4697 break;
4698 #endif
4699
4700 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
4701 case TARGET_NR_tkill:
4702 ret = get_errno(sys_tkill((int)arg1, (int)arg2));
4703 break;
4704 #endif
4705
4706 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
4707 case TARGET_NR_tgkill:
4708 ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3));
4709 break;
4710 #endif
4711
4712 #ifdef TARGET_NR_set_robust_list
4713 case TARGET_NR_set_robust_list:
4714 goto unimplemented_nowarn;
4715 #endif
4716
4717 default:
4718 unimplemented:
4719 gemu_log("qemu: Unsupported syscall: %d\n", num);
4720 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
4721 unimplemented_nowarn:
4722 #endif
4723 ret = -ENOSYS;
4724 break;
4725 }
4726 fail:
4727 #ifdef DEBUG
4728 gemu_log(" = %ld\n", ret);
4729 #endif
4730 return ret;
4731 }
4732