]> git.proxmox.com Git - qemu.git/blob - linux-user/syscall.c
sparc user fixes (Blue Swirl)
[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/wait.h>
32 #include <sys/time.h>
33 #include <sys/stat.h>
34 #include <sys/mount.h>
35 #include <sys/resource.h>
36 #include <sys/mman.h>
37 #include <sys/swap.h>
38 #include <signal.h>
39 #include <sched.h>
40 #include <sys/socket.h>
41 #include <sys/uio.h>
42 #include <sys/poll.h>
43 #include <sys/times.h>
44 #include <sys/shm.h>
45 #include <sys/statfs.h>
46 #include <utime.h>
47 #include <sys/sysinfo.h>
48 //#include <sys/user.h>
49 #include <netinet/ip.h>
50 #include <netinet/tcp.h>
51
52 #define termios host_termios
53 #define winsize host_winsize
54 #define termio host_termio
55 #define sgttyb host_sgttyb /* same as target */
56 #define tchars host_tchars /* same as target */
57 #define ltchars host_ltchars /* same as target */
58
59 #include <linux/termios.h>
60 #include <linux/unistd.h>
61 #include <linux/utsname.h>
62 #include <linux/cdrom.h>
63 #include <linux/hdreg.h>
64 #include <linux/soundcard.h>
65 #include <linux/dirent.h>
66 #include <linux/kd.h>
67
68 #include "qemu.h"
69
70 //#define DEBUG
71
72 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
73 /* 16 bit uid wrappers emulation */
74 #define USE_UID16
75 #endif
76
77 //#include <linux/msdos_fs.h>
78 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
79 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
80
81
82 #undef _syscall0
83 #undef _syscall1
84 #undef _syscall2
85 #undef _syscall3
86 #undef _syscall4
87 #undef _syscall5
88 #undef _syscall6
89
90 #define _syscall0(type,name) \
91 type name (void) \
92 { \
93 return syscall(__NR_##name); \
94 }
95
96 #define _syscall1(type,name,type1,arg1) \
97 type name (type1 arg1) \
98 { \
99 return syscall(__NR_##name, arg1); \
100 }
101
102 #define _syscall2(type,name,type1,arg1,type2,arg2) \
103 type name (type1 arg1,type2 arg2) \
104 { \
105 return syscall(__NR_##name, arg1, arg2); \
106 }
107
108 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
109 type name (type1 arg1,type2 arg2,type3 arg3) \
110 { \
111 return syscall(__NR_##name, arg1, arg2, arg3); \
112 }
113
114 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
115 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
116 { \
117 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
118 }
119
120 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
121 type5,arg5) \
122 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
123 { \
124 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
125 }
126
127
128 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
129 type5,arg5,type6,arg6) \
130 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
131 { \
132 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
133 }
134
135
136 #define __NR_sys_uname __NR_uname
137 #define __NR_sys_getcwd1 __NR_getcwd
138 #define __NR_sys_getdents __NR_getdents
139 #define __NR_sys_getdents64 __NR_getdents64
140 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
141
142 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
143 #define __NR__llseek __NR_lseek
144 #endif
145
146 #ifdef __NR_gettid
147 _syscall0(int, gettid)
148 #else
149 static int gettid(void) {
150 return -ENOSYS;
151 }
152 #endif
153 _syscall1(int,sys_uname,struct new_utsname *,buf)
154 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
155 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
156 _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
157 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
158 loff_t *, res, uint, wh);
159 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
160 #ifdef __NR_exit_group
161 _syscall1(int,exit_group,int,error_code)
162 #endif
163
164 extern int personality(int);
165 extern int flock(int, int);
166 extern int setfsuid(int);
167 extern int setfsgid(int);
168 extern int setresuid(uid_t, uid_t, uid_t);
169 extern int getresuid(uid_t *, uid_t *, uid_t *);
170 extern int setresgid(gid_t, gid_t, gid_t);
171 extern int getresgid(gid_t *, gid_t *, gid_t *);
172 extern int setgroups(int, gid_t *);
173
174 static inline long get_errno(long ret)
175 {
176 if (ret == -1)
177 return -errno;
178 else
179 return ret;
180 }
181
182 static inline int is_error(long ret)
183 {
184 return (unsigned long)ret >= (unsigned long)(-4096);
185 }
186
187 static target_ulong target_brk;
188 static target_ulong target_original_brk;
189
190 void target_set_brk(target_ulong new_brk)
191 {
192 target_original_brk = target_brk = new_brk;
193 }
194
195 long do_brk(target_ulong new_brk)
196 {
197 target_ulong brk_page;
198 long mapped_addr;
199 int new_alloc_size;
200
201 if (!new_brk)
202 return target_brk;
203 if (new_brk < target_original_brk)
204 return -ENOMEM;
205
206 brk_page = HOST_PAGE_ALIGN(target_brk);
207
208 /* If the new brk is less than this, set it and we're done... */
209 if (new_brk < brk_page) {
210 target_brk = new_brk;
211 return target_brk;
212 }
213
214 /* We need to allocate more memory after the brk... */
215 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
216 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
217 PROT_READ|PROT_WRITE,
218 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
219 if (is_error(mapped_addr)) {
220 return mapped_addr;
221 } else {
222 target_brk = new_brk;
223 return target_brk;
224 }
225 }
226
227 static inline fd_set *target_to_host_fds(fd_set *fds,
228 target_long *target_fds, int n)
229 {
230 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
231 return (fd_set *)target_fds;
232 #else
233 int i, b;
234 if (target_fds) {
235 FD_ZERO(fds);
236 for(i = 0;i < n; i++) {
237 b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
238 (i & (TARGET_LONG_BITS - 1))) & 1;
239 if (b)
240 FD_SET(i, fds);
241 }
242 return fds;
243 } else {
244 return NULL;
245 }
246 #endif
247 }
248
249 static inline void host_to_target_fds(target_long *target_fds,
250 fd_set *fds, int n)
251 {
252 #if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)
253 /* nothing to do */
254 #else
255 int i, nw, j, k;
256 target_long v;
257
258 if (target_fds) {
259 nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS;
260 k = 0;
261 for(i = 0;i < nw; i++) {
262 v = 0;
263 for(j = 0; j < TARGET_LONG_BITS; j++) {
264 v |= ((FD_ISSET(k, fds) != 0) << j);
265 k++;
266 }
267 target_fds[i] = tswapl(v);
268 }
269 }
270 #endif
271 }
272
273 #if defined(__alpha__)
274 #define HOST_HZ 1024
275 #else
276 #define HOST_HZ 100
277 #endif
278
279 static inline long host_to_target_clock_t(long ticks)
280 {
281 #if HOST_HZ == TARGET_HZ
282 return ticks;
283 #else
284 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
285 #endif
286 }
287
288 static inline void host_to_target_rusage(target_ulong target_addr,
289 const struct rusage *rusage)
290 {
291 struct target_rusage *target_rusage;
292
293 lock_user_struct(target_rusage, target_addr, 0);
294 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
295 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
296 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
297 target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
298 target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
299 target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
300 target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
301 target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
302 target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
303 target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
304 target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
305 target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
306 target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
307 target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
308 target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
309 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
310 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
311 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
312 unlock_user_struct(target_rusage, target_addr, 1);
313 }
314
315 static inline void target_to_host_timeval(struct timeval *tv,
316 target_ulong target_addr)
317 {
318 struct target_timeval *target_tv;
319
320 lock_user_struct(target_tv, target_addr, 1);
321 tv->tv_sec = tswapl(target_tv->tv_sec);
322 tv->tv_usec = tswapl(target_tv->tv_usec);
323 unlock_user_struct(target_tv, target_addr, 0);
324 }
325
326 static inline void host_to_target_timeval(target_ulong target_addr,
327 const struct timeval *tv)
328 {
329 struct target_timeval *target_tv;
330
331 lock_user_struct(target_tv, target_addr, 0);
332 target_tv->tv_sec = tswapl(tv->tv_sec);
333 target_tv->tv_usec = tswapl(tv->tv_usec);
334 unlock_user_struct(target_tv, target_addr, 1);
335 }
336
337
338 static long do_select(long n,
339 target_ulong rfd_p, target_ulong wfd_p,
340 target_ulong efd_p, target_ulong target_tv)
341 {
342 fd_set rfds, wfds, efds;
343 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
344 target_long *target_rfds, *target_wfds, *target_efds;
345 struct timeval tv, *tv_ptr;
346 long ret;
347 int ok;
348
349 if (rfd_p) {
350 target_rfds = lock_user(rfd_p, sizeof(target_long) * n, 1);
351 rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
352 } else {
353 target_rfds = NULL;
354 rfds_ptr = NULL;
355 }
356 if (wfd_p) {
357 target_wfds = lock_user(wfd_p, sizeof(target_long) * n, 1);
358 wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
359 } else {
360 target_wfds = NULL;
361 wfds_ptr = NULL;
362 }
363 if (efd_p) {
364 target_efds = lock_user(efd_p, sizeof(target_long) * n, 1);
365 efds_ptr = target_to_host_fds(&efds, target_efds, n);
366 } else {
367 target_efds = NULL;
368 efds_ptr = NULL;
369 }
370
371 if (target_tv) {
372 target_to_host_timeval(&tv, target_tv);
373 tv_ptr = &tv;
374 } else {
375 tv_ptr = NULL;
376 }
377 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
378 ok = !is_error(ret);
379
380 if (ok) {
381 host_to_target_fds(target_rfds, rfds_ptr, n);
382 host_to_target_fds(target_wfds, wfds_ptr, n);
383 host_to_target_fds(target_efds, efds_ptr, n);
384
385 if (target_tv) {
386 host_to_target_timeval(target_tv, &tv);
387 }
388 }
389 if (target_rfds)
390 unlock_user(target_rfds, rfd_p, ok ? sizeof(target_long) * n : 0);
391 if (target_wfds)
392 unlock_user(target_wfds, wfd_p, ok ? sizeof(target_long) * n : 0);
393 if (target_efds)
394 unlock_user(target_efds, efd_p, ok ? sizeof(target_long) * n : 0);
395
396 return ret;
397 }
398
399 static inline void target_to_host_sockaddr(struct sockaddr *addr,
400 target_ulong target_addr,
401 socklen_t len)
402 {
403 struct target_sockaddr *target_saddr;
404
405 target_saddr = lock_user(target_addr, len, 1);
406 memcpy(addr, target_saddr, len);
407 addr->sa_family = tswap16(target_saddr->sa_family);
408 unlock_user(target_saddr, target_addr, 0);
409 }
410
411 static inline void host_to_target_sockaddr(target_ulong target_addr,
412 struct sockaddr *addr,
413 socklen_t len)
414 {
415 struct target_sockaddr *target_saddr;
416
417 target_saddr = lock_user(target_addr, len, 0);
418 memcpy(target_saddr, addr, len);
419 target_saddr->sa_family = tswap16(addr->sa_family);
420 unlock_user(target_saddr, target_addr, len);
421 }
422
423 /* ??? Should this also swap msgh->name? */
424 static inline void target_to_host_cmsg(struct msghdr *msgh,
425 struct target_msghdr *target_msgh)
426 {
427 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
428 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
429 socklen_t space = 0;
430
431 while (cmsg && target_cmsg) {
432 void *data = CMSG_DATA(cmsg);
433 void *target_data = TARGET_CMSG_DATA(target_cmsg);
434
435 int len = tswapl(target_cmsg->cmsg_len)
436 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
437
438 space += CMSG_SPACE(len);
439 if (space > msgh->msg_controllen) {
440 space -= CMSG_SPACE(len);
441 gemu_log("Host cmsg overflow\n");
442 break;
443 }
444
445 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
446 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
447 cmsg->cmsg_len = CMSG_LEN(len);
448
449 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
450 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
451 memcpy(data, target_data, len);
452 } else {
453 int *fd = (int *)data;
454 int *target_fd = (int *)target_data;
455 int i, numfds = len / sizeof(int);
456
457 for (i = 0; i < numfds; i++)
458 fd[i] = tswap32(target_fd[i]);
459 }
460
461 cmsg = CMSG_NXTHDR(msgh, cmsg);
462 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
463 }
464
465 msgh->msg_controllen = space;
466 }
467
468 /* ??? Should this also swap msgh->name? */
469 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
470 struct msghdr *msgh)
471 {
472 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
473 struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh);
474 socklen_t space = 0;
475
476 while (cmsg && target_cmsg) {
477 void *data = CMSG_DATA(cmsg);
478 void *target_data = TARGET_CMSG_DATA(target_cmsg);
479
480 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
481
482 space += TARGET_CMSG_SPACE(len);
483 if (space > tswapl(target_msgh->msg_controllen)) {
484 space -= TARGET_CMSG_SPACE(len);
485 gemu_log("Target cmsg overflow\n");
486 break;
487 }
488
489 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
490 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
491 target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
492
493 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
494 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
495 memcpy(target_data, data, len);
496 } else {
497 int *fd = (int *)data;
498 int *target_fd = (int *)target_data;
499 int i, numfds = len / sizeof(int);
500
501 for (i = 0; i < numfds; i++)
502 target_fd[i] = tswap32(fd[i]);
503 }
504
505 cmsg = CMSG_NXTHDR(msgh, cmsg);
506 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
507 }
508
509 msgh->msg_controllen = tswapl(space);
510 }
511
512 static long do_setsockopt(int sockfd, int level, int optname,
513 target_ulong optval, socklen_t optlen)
514 {
515 int val, ret;
516
517 switch(level) {
518 case SOL_TCP:
519 /* TCP options all take an 'int' value. */
520 if (optlen < sizeof(uint32_t))
521 return -EINVAL;
522
523 val = tget32(optval);
524 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
525 break;
526 case SOL_IP:
527 switch(optname) {
528 case IP_TOS:
529 case IP_TTL:
530 case IP_HDRINCL:
531 case IP_ROUTER_ALERT:
532 case IP_RECVOPTS:
533 case IP_RETOPTS:
534 case IP_PKTINFO:
535 case IP_MTU_DISCOVER:
536 case IP_RECVERR:
537 case IP_RECVTOS:
538 #ifdef IP_FREEBIND
539 case IP_FREEBIND:
540 #endif
541 case IP_MULTICAST_TTL:
542 case IP_MULTICAST_LOOP:
543 val = 0;
544 if (optlen >= sizeof(uint32_t)) {
545 val = tget32(optval);
546 } else if (optlen >= 1) {
547 val = tget8(optval);
548 }
549 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
550 break;
551 default:
552 goto unimplemented;
553 }
554 break;
555 case SOL_SOCKET:
556 switch (optname) {
557 /* Options with 'int' argument. */
558 case SO_DEBUG:
559 case SO_REUSEADDR:
560 case SO_TYPE:
561 case SO_ERROR:
562 case SO_DONTROUTE:
563 case SO_BROADCAST:
564 case SO_SNDBUF:
565 case SO_RCVBUF:
566 case SO_KEEPALIVE:
567 case SO_OOBINLINE:
568 case SO_NO_CHECK:
569 case SO_PRIORITY:
570 #ifdef SO_BSDCOMPAT
571 case SO_BSDCOMPAT:
572 #endif
573 case SO_PASSCRED:
574 case SO_TIMESTAMP:
575 case SO_RCVLOWAT:
576 case SO_RCVTIMEO:
577 case SO_SNDTIMEO:
578 if (optlen < sizeof(uint32_t))
579 return -EINVAL;
580
581 val = tget32(optval);
582 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
583 break;
584 default:
585 goto unimplemented;
586 }
587 break;
588 default:
589 unimplemented:
590 gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
591 ret = -ENOSYS;
592 }
593 return ret;
594 }
595
596 static long do_getsockopt(int sockfd, int level, int optname,
597 target_ulong optval, target_ulong optlen)
598 {
599 int len, lv, val, ret;
600
601 switch(level) {
602 case SOL_SOCKET:
603 switch (optname) {
604 case SO_LINGER:
605 case SO_RCVTIMEO:
606 case SO_SNDTIMEO:
607 case SO_PEERCRED:
608 case SO_PEERNAME:
609 /* These don't just return a single integer */
610 goto unimplemented;
611 default:
612 goto int_case;
613 }
614 break;
615 case SOL_TCP:
616 /* TCP options all take an 'int' value. */
617 int_case:
618 len = tget32(optlen);
619 if (len < 0)
620 return -EINVAL;
621 lv = sizeof(int);
622 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
623 if (ret < 0)
624 return ret;
625 val = tswap32(val);
626 if (len > lv)
627 len = lv;
628 if (len == 4)
629 tput32(optval, val);
630 else
631 tput8(optval, val);
632 tput32(optlen, len);
633 break;
634 case SOL_IP:
635 switch(optname) {
636 case IP_TOS:
637 case IP_TTL:
638 case IP_HDRINCL:
639 case IP_ROUTER_ALERT:
640 case IP_RECVOPTS:
641 case IP_RETOPTS:
642 case IP_PKTINFO:
643 case IP_MTU_DISCOVER:
644 case IP_RECVERR:
645 case IP_RECVTOS:
646 #ifdef IP_FREEBIND
647 case IP_FREEBIND:
648 #endif
649 case IP_MULTICAST_TTL:
650 case IP_MULTICAST_LOOP:
651 len = tget32(optlen);
652 if (len < 0)
653 return -EINVAL;
654 lv = sizeof(int);
655 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
656 if (ret < 0)
657 return ret;
658 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
659 len = 1;
660 tput32(optlen, len);
661 tput8(optval, val);
662 } else {
663 if (len > sizeof(int))
664 len = sizeof(int);
665 tput32(optlen, len);
666 tput32(optval, val);
667 }
668 break;
669 default:
670 goto unimplemented;
671 }
672 break;
673 default:
674 unimplemented:
675 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
676 level, optname);
677 ret = -ENOSYS;
678 break;
679 }
680 return ret;
681 }
682
683 static void lock_iovec(struct iovec *vec, target_ulong target_addr,
684 int count, int copy)
685 {
686 struct target_iovec *target_vec;
687 target_ulong base;
688 int i;
689
690 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
691 for(i = 0;i < count; i++) {
692 base = tswapl(target_vec[i].iov_base);
693 vec[i].iov_len = tswapl(target_vec[i].iov_len);
694 vec[i].iov_base = lock_user(base, vec[i].iov_len, copy);
695 }
696 unlock_user (target_vec, target_addr, 0);
697 }
698
699 static void unlock_iovec(struct iovec *vec, target_ulong target_addr,
700 int count, int copy)
701 {
702 struct target_iovec *target_vec;
703 target_ulong base;
704 int i;
705
706 target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
707 for(i = 0;i < count; i++) {
708 base = tswapl(target_vec[i].iov_base);
709 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
710 }
711 unlock_user (target_vec, target_addr, 0);
712 }
713
714 static long do_socketcall(int num, target_ulong vptr)
715 {
716 long ret;
717 const int n = sizeof(target_ulong);
718
719 switch(num) {
720 case SOCKOP_socket:
721 {
722 int domain = tgetl(vptr);
723 int type = tgetl(vptr + n);
724 int protocol = tgetl(vptr + 2 * n);
725
726 ret = get_errno(socket(domain, type, protocol));
727 }
728 break;
729 case SOCKOP_bind:
730 {
731 int sockfd = tgetl(vptr);
732 target_ulong target_addr = tgetl(vptr + n);
733 socklen_t addrlen = tgetl(vptr + 2 * n);
734 void *addr = alloca(addrlen);
735
736 target_to_host_sockaddr(addr, target_addr, addrlen);
737 ret = get_errno(bind(sockfd, addr, addrlen));
738 }
739 break;
740 case SOCKOP_connect:
741 {
742 int sockfd = tgetl(vptr);
743 target_ulong target_addr = tgetl(vptr + n);
744 socklen_t addrlen = tgetl(vptr + 2 * n);
745 void *addr = alloca(addrlen);
746
747 target_to_host_sockaddr(addr, target_addr, addrlen);
748 ret = get_errno(connect(sockfd, addr, addrlen));
749 }
750 break;
751 case SOCKOP_listen:
752 {
753 int sockfd = tgetl(vptr);
754 int backlog = tgetl(vptr + n);
755
756 ret = get_errno(listen(sockfd, backlog));
757 }
758 break;
759 case SOCKOP_accept:
760 {
761 int sockfd = tgetl(vptr);
762 target_ulong target_addr = tgetl(vptr + n);
763 target_ulong target_addrlen = tgetl(vptr + 2 * n);
764 socklen_t addrlen = tget32(target_addrlen);
765 void *addr = alloca(addrlen);
766
767 ret = get_errno(accept(sockfd, addr, &addrlen));
768 if (!is_error(ret)) {
769 host_to_target_sockaddr(target_addr, addr, addrlen);
770 tput32(target_addrlen, addrlen);
771 }
772 }
773 break;
774 case SOCKOP_getsockname:
775 {
776 int sockfd = tgetl(vptr);
777 target_ulong target_addr = tgetl(vptr + n);
778 target_ulong target_addrlen = tgetl(vptr + 2 * n);
779 socklen_t addrlen = tget32(target_addrlen);
780 void *addr = alloca(addrlen);
781
782 ret = get_errno(getsockname(sockfd, addr, &addrlen));
783 if (!is_error(ret)) {
784 host_to_target_sockaddr(target_addr, addr, addrlen);
785 tput32(target_addrlen, addrlen);
786 }
787 }
788 break;
789 case SOCKOP_getpeername:
790 {
791 int sockfd = tgetl(vptr);
792 target_ulong target_addr = tgetl(vptr + n);
793 target_ulong target_addrlen = tgetl(vptr + 2 * n);
794 socklen_t addrlen = tget32(target_addrlen);
795 void *addr = alloca(addrlen);
796
797 ret = get_errno(getpeername(sockfd, addr, &addrlen));
798 if (!is_error(ret)) {
799 host_to_target_sockaddr(target_addr, addr, addrlen);
800 tput32(target_addrlen, addrlen);
801 }
802 }
803 break;
804 case SOCKOP_socketpair:
805 {
806 int domain = tgetl(vptr);
807 int type = tgetl(vptr + n);
808 int protocol = tgetl(vptr + 2 * n);
809 target_ulong target_tab = tgetl(vptr + 3 * n);
810 int tab[2];
811
812 ret = get_errno(socketpair(domain, type, protocol, tab));
813 if (!is_error(ret)) {
814 tput32(target_tab, tab[0]);
815 tput32(target_tab + 4, tab[1]);
816 }
817 }
818 break;
819 case SOCKOP_send:
820 {
821 int sockfd = tgetl(vptr);
822 target_ulong msg = tgetl(vptr + n);
823 size_t len = tgetl(vptr + 2 * n);
824 int flags = tgetl(vptr + 3 * n);
825 void *host_msg;
826
827 host_msg = lock_user(msg, len, 1);
828 ret = get_errno(send(sockfd, host_msg, len, flags));
829 unlock_user(host_msg, msg, 0);
830 }
831 break;
832 case SOCKOP_recv:
833 {
834 int sockfd = tgetl(vptr);
835 target_ulong msg = tgetl(vptr + n);
836 size_t len = tgetl(vptr + 2 * n);
837 int flags = tgetl(vptr + 3 * n);
838 void *host_msg;
839
840 host_msg = lock_user(msg, len, 0);
841 ret = get_errno(recv(sockfd, host_msg, len, flags));
842 unlock_user(host_msg, msg, ret);
843 }
844 break;
845 case SOCKOP_sendto:
846 {
847 int sockfd = tgetl(vptr);
848 target_ulong msg = tgetl(vptr + n);
849 size_t len = tgetl(vptr + 2 * n);
850 int flags = tgetl(vptr + 3 * n);
851 target_ulong target_addr = tgetl(vptr + 4 * n);
852 socklen_t addrlen = tgetl(vptr + 5 * n);
853 void *addr = alloca(addrlen);
854 void *host_msg;
855
856 host_msg = lock_user(msg, len, 1);
857 target_to_host_sockaddr(addr, target_addr, addrlen);
858 ret = get_errno(sendto(sockfd, host_msg, len, flags, addr, addrlen));
859 unlock_user(host_msg, msg, 0);
860 }
861 break;
862 case SOCKOP_recvfrom:
863 {
864 int sockfd = tgetl(vptr);
865 target_ulong msg = tgetl(vptr + n);
866 size_t len = tgetl(vptr + 2 * n);
867 int flags = tgetl(vptr + 3 * n);
868 target_ulong target_addr = tgetl(vptr + 4 * n);
869 target_ulong target_addrlen = tgetl(vptr + 5 * n);
870 socklen_t addrlen = tget32(target_addrlen);
871 void *addr = alloca(addrlen);
872 void *host_msg;
873
874 host_msg = lock_user(msg, len, 0);
875 ret = get_errno(recvfrom(sockfd, host_msg, len, flags, addr, &addrlen));
876 if (!is_error(ret)) {
877 host_to_target_sockaddr(target_addr, addr, addrlen);
878 tput32(target_addrlen, addrlen);
879 unlock_user(host_msg, msg, len);
880 } else {
881 unlock_user(host_msg, msg, 0);
882 }
883 }
884 break;
885 case SOCKOP_shutdown:
886 {
887 int sockfd = tgetl(vptr);
888 int how = tgetl(vptr + n);
889
890 ret = get_errno(shutdown(sockfd, how));
891 }
892 break;
893 case SOCKOP_sendmsg:
894 case SOCKOP_recvmsg:
895 {
896 int fd;
897 target_ulong target_msg;
898 struct target_msghdr *msgp;
899 struct msghdr msg;
900 int flags, count;
901 struct iovec *vec;
902 target_ulong target_vec;
903 int send = (num == SOCKOP_sendmsg);
904
905 target_msg = tgetl(vptr + n);
906 lock_user_struct(msgp, target_msg, 1);
907 if (msgp->msg_name) {
908 msg.msg_namelen = tswap32(msgp->msg_namelen);
909 msg.msg_name = alloca(msg.msg_namelen);
910 target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
911 msg.msg_namelen);
912 } else {
913 msg.msg_name = NULL;
914 msg.msg_namelen = 0;
915 }
916 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
917 msg.msg_control = alloca(msg.msg_controllen);
918 msg.msg_flags = tswap32(msgp->msg_flags);
919
920 count = tswapl(msgp->msg_iovlen);
921 vec = alloca(count * sizeof(struct iovec));
922 target_vec = tswapl(msgp->msg_iov);
923 lock_iovec(vec, target_vec, count, send);
924 msg.msg_iovlen = count;
925 msg.msg_iov = vec;
926
927 fd = tgetl(vptr);
928 flags = tgetl(vptr + 2 * n);
929 if (send) {
930 target_to_host_cmsg(&msg, msgp);
931 ret = get_errno(sendmsg(fd, &msg, flags));
932 } else {
933 ret = get_errno(recvmsg(fd, &msg, flags));
934 if (!is_error(ret))
935 host_to_target_cmsg(msgp, &msg);
936 }
937 unlock_iovec(vec, target_vec, count, !send);
938 }
939 break;
940 case SOCKOP_setsockopt:
941 {
942 int sockfd = tgetl(vptr);
943 int level = tgetl(vptr + n);
944 int optname = tgetl(vptr + 2 * n);
945 target_ulong optval = tgetl(vptr + 3 * n);
946 socklen_t optlen = tgetl(vptr + 4 * n);
947
948 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
949 }
950 break;
951 case SOCKOP_getsockopt:
952 {
953 int sockfd = tgetl(vptr);
954 int level = tgetl(vptr + n);
955 int optname = tgetl(vptr + 2 * n);
956 target_ulong optval = tgetl(vptr + 3 * n);
957 target_ulong poptlen = tgetl(vptr + 4 * n);
958
959 ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
960 }
961 break;
962 default:
963 gemu_log("Unsupported socketcall: %d\n", num);
964 ret = -ENOSYS;
965 break;
966 }
967 return ret;
968 }
969
970
971 #define N_SHM_REGIONS 32
972
973 static struct shm_region {
974 uint32_t start;
975 uint32_t size;
976 } shm_regions[N_SHM_REGIONS];
977
978 /* ??? This only works with linear mappings. */
979 static long do_ipc(long call, long first, long second, long third,
980 long ptr, long fifth)
981 {
982 int version;
983 long ret = 0;
984 unsigned long raddr;
985 struct shmid_ds shm_info;
986 int i;
987
988 version = call >> 16;
989 call &= 0xffff;
990
991 switch (call) {
992 case IPCOP_shmat:
993 /* SHM_* flags are the same on all linux platforms */
994 ret = get_errno((long) shmat(first, (void *) ptr, second));
995 if (is_error(ret))
996 break;
997 raddr = ret;
998 /* find out the length of the shared memory segment */
999
1000 ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
1001 if (is_error(ret)) {
1002 /* can't get length, bail out */
1003 shmdt((void *) raddr);
1004 break;
1005 }
1006 page_set_flags(raddr, raddr + shm_info.shm_segsz,
1007 PAGE_VALID | PAGE_READ |
1008 ((second & SHM_RDONLY)? 0: PAGE_WRITE));
1009 for (i = 0; i < N_SHM_REGIONS; ++i) {
1010 if (shm_regions[i].start == 0) {
1011 shm_regions[i].start = raddr;
1012 shm_regions[i].size = shm_info.shm_segsz;
1013 break;
1014 }
1015 }
1016 if (put_user(raddr, (uint32_t *)third))
1017 return -EFAULT;
1018 ret = 0;
1019 break;
1020 case IPCOP_shmdt:
1021 for (i = 0; i < N_SHM_REGIONS; ++i) {
1022 if (shm_regions[i].start == ptr) {
1023 shm_regions[i].start = 0;
1024 page_set_flags(ptr, shm_regions[i].size, 0);
1025 break;
1026 }
1027 }
1028 ret = get_errno(shmdt((void *) ptr));
1029 break;
1030
1031 case IPCOP_shmget:
1032 /* IPC_* flag values are the same on all linux platforms */
1033 ret = get_errno(shmget(first, second, third));
1034 break;
1035
1036 /* IPC_* and SHM_* command values are the same on all linux platforms */
1037 case IPCOP_shmctl:
1038 switch(second) {
1039 case IPC_RMID:
1040 case SHM_LOCK:
1041 case SHM_UNLOCK:
1042 ret = get_errno(shmctl(first, second, NULL));
1043 break;
1044 default:
1045 goto unimplemented;
1046 }
1047 break;
1048 default:
1049 unimplemented:
1050 gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version);
1051 ret = -ENOSYS;
1052 break;
1053 }
1054 return ret;
1055 }
1056
1057 /* kernel structure types definitions */
1058 #define IFNAMSIZ 16
1059
1060 #define STRUCT(name, list...) STRUCT_ ## name,
1061 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
1062 enum {
1063 #include "syscall_types.h"
1064 };
1065 #undef STRUCT
1066 #undef STRUCT_SPECIAL
1067
1068 #define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
1069 #define STRUCT_SPECIAL(name)
1070 #include "syscall_types.h"
1071 #undef STRUCT
1072 #undef STRUCT_SPECIAL
1073
1074 typedef struct IOCTLEntry {
1075 unsigned int target_cmd;
1076 unsigned int host_cmd;
1077 const char *name;
1078 int access;
1079 const argtype arg_type[5];
1080 } IOCTLEntry;
1081
1082 #define IOC_R 0x0001
1083 #define IOC_W 0x0002
1084 #define IOC_RW (IOC_R | IOC_W)
1085
1086 #define MAX_STRUCT_SIZE 4096
1087
1088 IOCTLEntry ioctl_entries[] = {
1089 #define IOCTL(cmd, access, types...) \
1090 { TARGET_ ## cmd, cmd, #cmd, access, { types } },
1091 #include "ioctls.h"
1092 { 0, 0, },
1093 };
1094
1095 /* ??? Implement proper locking for ioctls. */
1096 static long do_ioctl(long fd, long cmd, long arg)
1097 {
1098 const IOCTLEntry *ie;
1099 const argtype *arg_type;
1100 long ret;
1101 uint8_t buf_temp[MAX_STRUCT_SIZE];
1102 int target_size;
1103 void *argptr;
1104
1105 ie = ioctl_entries;
1106 for(;;) {
1107 if (ie->target_cmd == 0) {
1108 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
1109 return -ENOSYS;
1110 }
1111 if (ie->target_cmd == cmd)
1112 break;
1113 ie++;
1114 }
1115 arg_type = ie->arg_type;
1116 #if defined(DEBUG)
1117 gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
1118 #endif
1119 switch(arg_type[0]) {
1120 case TYPE_NULL:
1121 /* no argument */
1122 ret = get_errno(ioctl(fd, ie->host_cmd));
1123 break;
1124 case TYPE_PTRVOID:
1125 case TYPE_INT:
1126 /* int argment */
1127 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
1128 break;
1129 case TYPE_PTR:
1130 arg_type++;
1131 target_size = thunk_type_size(arg_type, 0);
1132 switch(ie->access) {
1133 case IOC_R:
1134 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1135 if (!is_error(ret)) {
1136 argptr = lock_user(arg, target_size, 0);
1137 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1138 unlock_user(argptr, arg, target_size);
1139 }
1140 break;
1141 case IOC_W:
1142 argptr = lock_user(arg, target_size, 1);
1143 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1144 unlock_user(argptr, arg, 0);
1145 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1146 break;
1147 default:
1148 case IOC_RW:
1149 argptr = lock_user(arg, target_size, 1);
1150 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
1151 unlock_user(argptr, arg, 0);
1152 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1153 if (!is_error(ret)) {
1154 argptr = lock_user(arg, target_size, 0);
1155 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
1156 unlock_user(argptr, arg, target_size);
1157 }
1158 break;
1159 }
1160 break;
1161 default:
1162 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
1163 ret = -ENOSYS;
1164 break;
1165 }
1166 return ret;
1167 }
1168
1169 bitmask_transtbl iflag_tbl[] = {
1170 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
1171 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
1172 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
1173 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
1174 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
1175 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
1176 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
1177 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
1178 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
1179 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
1180 { TARGET_IXON, TARGET_IXON, IXON, IXON },
1181 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
1182 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
1183 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
1184 { 0, 0, 0, 0 }
1185 };
1186
1187 bitmask_transtbl oflag_tbl[] = {
1188 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
1189 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
1190 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
1191 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
1192 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
1193 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
1194 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
1195 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
1196 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
1197 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
1198 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
1199 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
1200 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
1201 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
1202 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
1203 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
1204 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
1205 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
1206 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
1207 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
1208 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
1209 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
1210 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
1211 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
1212 { 0, 0, 0, 0 }
1213 };
1214
1215 bitmask_transtbl cflag_tbl[] = {
1216 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
1217 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
1218 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
1219 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
1220 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
1221 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
1222 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
1223 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
1224 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
1225 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
1226 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
1227 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
1228 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
1229 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
1230 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
1231 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
1232 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
1233 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
1234 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
1235 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
1236 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
1237 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
1238 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
1239 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
1240 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
1241 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
1242 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
1243 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
1244 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
1245 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
1246 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
1247 { 0, 0, 0, 0 }
1248 };
1249
1250 bitmask_transtbl lflag_tbl[] = {
1251 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
1252 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
1253 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
1254 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
1255 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
1256 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
1257 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
1258 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
1259 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
1260 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
1261 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
1262 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
1263 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
1264 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
1265 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
1266 { 0, 0, 0, 0 }
1267 };
1268
1269 static void target_to_host_termios (void *dst, const void *src)
1270 {
1271 struct host_termios *host = dst;
1272 const struct target_termios *target = src;
1273
1274 host->c_iflag =
1275 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
1276 host->c_oflag =
1277 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
1278 host->c_cflag =
1279 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
1280 host->c_lflag =
1281 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
1282 host->c_line = target->c_line;
1283
1284 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
1285 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
1286 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
1287 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
1288 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
1289 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
1290 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
1291 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
1292 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
1293 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
1294 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
1295 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
1296 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
1297 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
1298 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
1299 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
1300 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
1301 }
1302
1303 static void host_to_target_termios (void *dst, const void *src)
1304 {
1305 struct target_termios *target = dst;
1306 const struct host_termios *host = src;
1307
1308 target->c_iflag =
1309 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
1310 target->c_oflag =
1311 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
1312 target->c_cflag =
1313 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
1314 target->c_lflag =
1315 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
1316 target->c_line = host->c_line;
1317
1318 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
1319 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
1320 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
1321 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
1322 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
1323 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
1324 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
1325 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
1326 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
1327 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
1328 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
1329 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
1330 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
1331 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
1332 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
1333 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
1334 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
1335 }
1336
1337 StructEntry struct_termios_def = {
1338 .convert = { host_to_target_termios, target_to_host_termios },
1339 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
1340 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
1341 };
1342
1343 static bitmask_transtbl mmap_flags_tbl[] = {
1344 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
1345 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
1346 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
1347 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
1348 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
1349 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
1350 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
1351 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
1352 { 0, 0, 0, 0 }
1353 };
1354
1355 static bitmask_transtbl fcntl_flags_tbl[] = {
1356 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
1357 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
1358 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
1359 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
1360 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
1361 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
1362 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
1363 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
1364 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
1365 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
1366 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
1367 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
1368 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
1369 #if defined(O_DIRECT)
1370 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
1371 #endif
1372 { 0, 0, 0, 0 }
1373 };
1374
1375 #if defined(TARGET_I386)
1376
1377 /* NOTE: there is really one LDT for all the threads */
1378 uint8_t *ldt_table;
1379
1380 static int read_ldt(target_ulong ptr, unsigned long bytecount)
1381 {
1382 int size;
1383 void *p;
1384
1385 if (!ldt_table)
1386 return 0;
1387 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
1388 if (size > bytecount)
1389 size = bytecount;
1390 p = lock_user(ptr, size, 0);
1391 /* ??? Shoudl this by byteswapped? */
1392 memcpy(p, ldt_table, size);
1393 unlock_user(p, ptr, size);
1394 return size;
1395 }
1396
1397 /* XXX: add locking support */
1398 static int write_ldt(CPUX86State *env,
1399 target_ulong ptr, unsigned long bytecount, int oldmode)
1400 {
1401 struct target_modify_ldt_ldt_s ldt_info;
1402 struct target_modify_ldt_ldt_s *target_ldt_info;
1403 int seg_32bit, contents, read_exec_only, limit_in_pages;
1404 int seg_not_present, useable;
1405 uint32_t *lp, entry_1, entry_2;
1406
1407 if (bytecount != sizeof(ldt_info))
1408 return -EINVAL;
1409 lock_user_struct(target_ldt_info, ptr, 1);
1410 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
1411 ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
1412 ldt_info.limit = tswap32(target_ldt_info->limit);
1413 ldt_info.flags = tswap32(target_ldt_info->flags);
1414 unlock_user_struct(target_ldt_info, ptr, 0);
1415
1416 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1417 return -EINVAL;
1418 seg_32bit = ldt_info.flags & 1;
1419 contents = (ldt_info.flags >> 1) & 3;
1420 read_exec_only = (ldt_info.flags >> 3) & 1;
1421 limit_in_pages = (ldt_info.flags >> 4) & 1;
1422 seg_not_present = (ldt_info.flags >> 5) & 1;
1423 useable = (ldt_info.flags >> 6) & 1;
1424
1425 if (contents == 3) {
1426 if (oldmode)
1427 return -EINVAL;
1428 if (seg_not_present == 0)
1429 return -EINVAL;
1430 }
1431 /* allocate the LDT */
1432 if (!ldt_table) {
1433 ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1434 if (!ldt_table)
1435 return -ENOMEM;
1436 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1437 env->ldt.base = h2g(ldt_table);
1438 env->ldt.limit = 0xffff;
1439 }
1440
1441 /* NOTE: same code as Linux kernel */
1442 /* Allow LDTs to be cleared by the user. */
1443 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
1444 if (oldmode ||
1445 (contents == 0 &&
1446 read_exec_only == 1 &&
1447 seg_32bit == 0 &&
1448 limit_in_pages == 0 &&
1449 seg_not_present == 1 &&
1450 useable == 0 )) {
1451 entry_1 = 0;
1452 entry_2 = 0;
1453 goto install;
1454 }
1455 }
1456
1457 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
1458 (ldt_info.limit & 0x0ffff);
1459 entry_2 = (ldt_info.base_addr & 0xff000000) |
1460 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
1461 (ldt_info.limit & 0xf0000) |
1462 ((read_exec_only ^ 1) << 9) |
1463 (contents << 10) |
1464 ((seg_not_present ^ 1) << 15) |
1465 (seg_32bit << 22) |
1466 (limit_in_pages << 23) |
1467 0x7000;
1468 if (!oldmode)
1469 entry_2 |= (useable << 20);
1470
1471 /* Install the new entry ... */
1472 install:
1473 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
1474 lp[0] = tswap32(entry_1);
1475 lp[1] = tswap32(entry_2);
1476 return 0;
1477 }
1478
1479 /* specific and weird i386 syscalls */
1480 int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount)
1481 {
1482 int ret = -ENOSYS;
1483
1484 switch (func) {
1485 case 0:
1486 ret = read_ldt(ptr, bytecount);
1487 break;
1488 case 1:
1489 ret = write_ldt(env, ptr, bytecount, 1);
1490 break;
1491 case 0x11:
1492 ret = write_ldt(env, ptr, bytecount, 0);
1493 break;
1494 }
1495 return ret;
1496 }
1497
1498 #endif /* defined(TARGET_I386) */
1499
1500 /* this stack is the equivalent of the kernel stack associated with a
1501 thread/process */
1502 #define NEW_STACK_SIZE 8192
1503
1504 static int clone_func(void *arg)
1505 {
1506 CPUState *env = arg;
1507 cpu_loop(env);
1508 /* never exits */
1509 return 0;
1510 }
1511
1512 int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
1513 {
1514 int ret;
1515 TaskState *ts;
1516 uint8_t *new_stack;
1517 CPUState *new_env;
1518
1519 if (flags & CLONE_VM) {
1520 ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
1521 memset(ts, 0, sizeof(TaskState));
1522 new_stack = ts->stack;
1523 ts->used = 1;
1524 /* add in task state list */
1525 ts->next = first_task_state;
1526 first_task_state = ts;
1527 /* we create a new CPU instance. */
1528 new_env = cpu_init();
1529 memcpy(new_env, env, sizeof(CPUState));
1530 #if defined(TARGET_I386)
1531 if (!newsp)
1532 newsp = env->regs[R_ESP];
1533 new_env->regs[R_ESP] = newsp;
1534 new_env->regs[R_EAX] = 0;
1535 #elif defined(TARGET_ARM)
1536 if (!newsp)
1537 newsp = env->regs[13];
1538 new_env->regs[13] = newsp;
1539 new_env->regs[0] = 0;
1540 #elif defined(TARGET_SPARC)
1541 if (!newsp)
1542 newsp = env->regwptr[22];
1543 new_env->regwptr[22] = newsp;
1544 new_env->regwptr[0] = 0;
1545 /* XXXXX */
1546 printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1547 #elif defined(TARGET_MIPS)
1548 printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1549 #elif defined(TARGET_PPC)
1550 if (!newsp)
1551 newsp = env->gpr[1];
1552 new_env->gpr[1] = newsp;
1553 {
1554 int i;
1555 for (i = 7; i < 32; i++)
1556 new_env->gpr[i] = 0;
1557 }
1558 #elif defined(TARGET_SH4)
1559 if (!newsp)
1560 newsp = env->gregs[15];
1561 new_env->gregs[15] = newsp;
1562 /* XXXXX */
1563 #else
1564 #error unsupported target CPU
1565 #endif
1566 new_env->opaque = ts;
1567 #ifdef __ia64__
1568 ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1569 #else
1570 ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
1571 #endif
1572 } else {
1573 /* if no CLONE_VM, we consider it is a fork */
1574 if ((flags & ~CSIGNAL) != 0)
1575 return -EINVAL;
1576 ret = fork();
1577 }
1578 return ret;
1579 }
1580
1581 static long do_fcntl(int fd, int cmd, target_ulong arg)
1582 {
1583 struct flock fl;
1584 struct target_flock *target_fl;
1585 long ret;
1586
1587 switch(cmd) {
1588 case TARGET_F_GETLK:
1589 ret = fcntl(fd, cmd, &fl);
1590 if (ret == 0) {
1591 lock_user_struct(target_fl, arg, 0);
1592 target_fl->l_type = tswap16(fl.l_type);
1593 target_fl->l_whence = tswap16(fl.l_whence);
1594 target_fl->l_start = tswapl(fl.l_start);
1595 target_fl->l_len = tswapl(fl.l_len);
1596 target_fl->l_pid = tswapl(fl.l_pid);
1597 unlock_user_struct(target_fl, arg, 1);
1598 }
1599 break;
1600
1601 case TARGET_F_SETLK:
1602 case TARGET_F_SETLKW:
1603 lock_user_struct(target_fl, arg, 1);
1604 fl.l_type = tswap16(target_fl->l_type);
1605 fl.l_whence = tswap16(target_fl->l_whence);
1606 fl.l_start = tswapl(target_fl->l_start);
1607 fl.l_len = tswapl(target_fl->l_len);
1608 fl.l_pid = tswapl(target_fl->l_pid);
1609 unlock_user_struct(target_fl, arg, 0);
1610 ret = fcntl(fd, cmd, &fl);
1611 break;
1612
1613 case TARGET_F_GETLK64:
1614 case TARGET_F_SETLK64:
1615 case TARGET_F_SETLKW64:
1616 ret = -1;
1617 errno = EINVAL;
1618 break;
1619
1620 case F_GETFL:
1621 ret = fcntl(fd, cmd, arg);
1622 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
1623 break;
1624
1625 case F_SETFL:
1626 ret = fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl));
1627 break;
1628
1629 default:
1630 ret = fcntl(fd, cmd, arg);
1631 break;
1632 }
1633 return ret;
1634 }
1635
1636 #ifdef USE_UID16
1637
1638 static inline int high2lowuid(int uid)
1639 {
1640 if (uid > 65535)
1641 return 65534;
1642 else
1643 return uid;
1644 }
1645
1646 static inline int high2lowgid(int gid)
1647 {
1648 if (gid > 65535)
1649 return 65534;
1650 else
1651 return gid;
1652 }
1653
1654 static inline int low2highuid(int uid)
1655 {
1656 if ((int16_t)uid == -1)
1657 return -1;
1658 else
1659 return uid;
1660 }
1661
1662 static inline int low2highgid(int gid)
1663 {
1664 if ((int16_t)gid == -1)
1665 return -1;
1666 else
1667 return gid;
1668 }
1669
1670 #endif /* USE_UID16 */
1671
1672 void syscall_init(void)
1673 {
1674 IOCTLEntry *ie;
1675 const argtype *arg_type;
1676 int size;
1677
1678 #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
1679 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
1680 #include "syscall_types.h"
1681 #undef STRUCT
1682 #undef STRUCT_SPECIAL
1683
1684 /* we patch the ioctl size if necessary. We rely on the fact that
1685 no ioctl has all the bits at '1' in the size field */
1686 ie = ioctl_entries;
1687 while (ie->target_cmd != 0) {
1688 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
1689 TARGET_IOC_SIZEMASK) {
1690 arg_type = ie->arg_type;
1691 if (arg_type[0] != TYPE_PTR) {
1692 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
1693 ie->target_cmd);
1694 exit(1);
1695 }
1696 arg_type++;
1697 size = thunk_type_size(arg_type, 0);
1698 ie->target_cmd = (ie->target_cmd &
1699 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
1700 (size << TARGET_IOC_SIZESHIFT);
1701 }
1702 /* automatic consistency check if same arch */
1703 #if defined(__i386__) && defined(TARGET_I386)
1704 if (ie->target_cmd != ie->host_cmd) {
1705 fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
1706 ie->target_cmd, ie->host_cmd);
1707 }
1708 #endif
1709 ie++;
1710 }
1711 }
1712
1713 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
1714 {
1715 #ifdef TARGET_WORDS_BIG_ENDIAN
1716 return ((uint64_t)word0 << 32) | word1;
1717 #else
1718 return ((uint64_t)word1 << 32) | word0;
1719 #endif
1720 }
1721
1722 #ifdef TARGET_NR_truncate64
1723 static inline long target_truncate64(void *cpu_env, const char *arg1,
1724 long arg2, long arg3, long arg4)
1725 {
1726 #ifdef TARGET_ARM
1727 if (((CPUARMState *)cpu_env)->eabi)
1728 {
1729 arg2 = arg3;
1730 arg3 = arg4;
1731 }
1732 #endif
1733 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
1734 }
1735 #endif
1736
1737 #ifdef TARGET_NR_ftruncate64
1738 static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2,
1739 long arg3, long arg4)
1740 {
1741 #ifdef TARGET_ARM
1742 if (((CPUARMState *)cpu_env)->eabi)
1743 {
1744 arg2 = arg3;
1745 arg3 = arg4;
1746 }
1747 #endif
1748 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
1749 }
1750 #endif
1751
1752 static inline void target_to_host_timespec(struct timespec *host_ts,
1753 target_ulong target_addr)
1754 {
1755 struct target_timespec *target_ts;
1756
1757 lock_user_struct(target_ts, target_addr, 1);
1758 host_ts->tv_sec = tswapl(target_ts->tv_sec);
1759 host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
1760 unlock_user_struct(target_ts, target_addr, 0);
1761 }
1762
1763 static inline void host_to_target_timespec(target_ulong target_addr,
1764 struct timespec *host_ts)
1765 {
1766 struct target_timespec *target_ts;
1767
1768 lock_user_struct(target_ts, target_addr, 0);
1769 target_ts->tv_sec = tswapl(host_ts->tv_sec);
1770 target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
1771 unlock_user_struct(target_ts, target_addr, 1);
1772 }
1773
1774 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1775 long arg4, long arg5, long arg6)
1776 {
1777 long ret;
1778 struct stat st;
1779 struct statfs stfs;
1780 void *p;
1781
1782 #ifdef DEBUG
1783 gemu_log("syscall %d", num);
1784 #endif
1785 switch(num) {
1786 case TARGET_NR_exit:
1787 #ifdef HAVE_GPROF
1788 _mcleanup();
1789 #endif
1790 gdb_exit(cpu_env, arg1);
1791 /* XXX: should free thread stack and CPU env */
1792 _exit(arg1);
1793 ret = 0; /* avoid warning */
1794 break;
1795 case TARGET_NR_read:
1796 page_unprotect_range(arg2, arg3);
1797 p = lock_user(arg2, arg3, 0);
1798 ret = get_errno(read(arg1, p, arg3));
1799 unlock_user(p, arg2, ret);
1800 break;
1801 case TARGET_NR_write:
1802 p = lock_user(arg2, arg3, 1);
1803 ret = get_errno(write(arg1, p, arg3));
1804 unlock_user(p, arg2, 0);
1805 break;
1806 case TARGET_NR_open:
1807 p = lock_user_string(arg1);
1808 ret = get_errno(open(path(p),
1809 target_to_host_bitmask(arg2, fcntl_flags_tbl),
1810 arg3));
1811 unlock_user(p, arg1, 0);
1812 break;
1813 case TARGET_NR_close:
1814 ret = get_errno(close(arg1));
1815 break;
1816 case TARGET_NR_brk:
1817 ret = do_brk(arg1);
1818 break;
1819 case TARGET_NR_fork:
1820 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
1821 break;
1822 case TARGET_NR_waitpid:
1823 {
1824 int status;
1825 ret = get_errno(waitpid(arg1, &status, arg3));
1826 if (!is_error(ret) && arg2)
1827 tput32(arg2, status);
1828 }
1829 break;
1830 case TARGET_NR_creat:
1831 p = lock_user_string(arg1);
1832 ret = get_errno(creat(p, arg2));
1833 unlock_user(p, arg1, 0);
1834 break;
1835 case TARGET_NR_link:
1836 {
1837 void * p2;
1838 p = lock_user_string(arg1);
1839 p2 = lock_user_string(arg2);
1840 ret = get_errno(link(p, p2));
1841 unlock_user(p2, arg2, 0);
1842 unlock_user(p, arg1, 0);
1843 }
1844 break;
1845 case TARGET_NR_unlink:
1846 p = lock_user_string(arg1);
1847 ret = get_errno(unlink(p));
1848 unlock_user(p, arg1, 0);
1849 break;
1850 case TARGET_NR_execve:
1851 {
1852 char **argp, **envp;
1853 int argc, envc;
1854 target_ulong gp;
1855 target_ulong guest_argp;
1856 target_ulong guest_envp;
1857 target_ulong addr;
1858 char **q;
1859
1860 argc = 0;
1861 guest_argp = arg2;
1862 for (gp = guest_argp; tgetl(gp); gp++)
1863 argc++;
1864 envc = 0;
1865 guest_envp = arg3;
1866 for (gp = guest_envp; tgetl(gp); gp++)
1867 envc++;
1868
1869 argp = alloca((argc + 1) * sizeof(void *));
1870 envp = alloca((envc + 1) * sizeof(void *));
1871
1872 for (gp = guest_argp, q = argp; ;
1873 gp += sizeof(target_ulong), q++) {
1874 addr = tgetl(gp);
1875 if (!addr)
1876 break;
1877 *q = lock_user_string(addr);
1878 }
1879 *q = NULL;
1880
1881 for (gp = guest_envp, q = envp; ;
1882 gp += sizeof(target_ulong), q++) {
1883 addr = tgetl(gp);
1884 if (!addr)
1885 break;
1886 *q = lock_user_string(addr);
1887 }
1888 *q = NULL;
1889
1890 p = lock_user_string(arg1);
1891 ret = get_errno(execve(p, argp, envp));
1892 unlock_user(p, arg1, 0);
1893
1894 for (gp = guest_argp, q = argp; *q;
1895 gp += sizeof(target_ulong), q++) {
1896 addr = tgetl(gp);
1897 unlock_user(*q, addr, 0);
1898 }
1899 for (gp = guest_envp, q = envp; *q;
1900 gp += sizeof(target_ulong), q++) {
1901 addr = tgetl(gp);
1902 unlock_user(*q, addr, 0);
1903 }
1904 }
1905 break;
1906 case TARGET_NR_chdir:
1907 p = lock_user_string(arg1);
1908 ret = get_errno(chdir(p));
1909 unlock_user(p, arg1, 0);
1910 break;
1911 #ifdef TARGET_NR_time
1912 case TARGET_NR_time:
1913 {
1914 time_t host_time;
1915 ret = get_errno(time(&host_time));
1916 if (!is_error(ret) && arg1)
1917 tputl(arg1, host_time);
1918 }
1919 break;
1920 #endif
1921 case TARGET_NR_mknod:
1922 p = lock_user_string(arg1);
1923 ret = get_errno(mknod(p, arg2, arg3));
1924 unlock_user(p, arg1, 0);
1925 break;
1926 case TARGET_NR_chmod:
1927 p = lock_user_string(arg1);
1928 ret = get_errno(chmod(p, arg2));
1929 unlock_user(p, arg1, 0);
1930 break;
1931 #ifdef TARGET_NR_break
1932 case TARGET_NR_break:
1933 goto unimplemented;
1934 #endif
1935 #ifdef TARGET_NR_oldstat
1936 case TARGET_NR_oldstat:
1937 goto unimplemented;
1938 #endif
1939 case TARGET_NR_lseek:
1940 ret = get_errno(lseek(arg1, arg2, arg3));
1941 break;
1942 case TARGET_NR_getpid:
1943 ret = get_errno(getpid());
1944 break;
1945 case TARGET_NR_mount:
1946 /* need to look at the data field */
1947 goto unimplemented;
1948 case TARGET_NR_umount:
1949 p = lock_user_string(arg1);
1950 ret = get_errno(umount(p));
1951 unlock_user(p, arg1, 0);
1952 break;
1953 case TARGET_NR_stime:
1954 {
1955 time_t host_time;
1956 host_time = tgetl(arg1);
1957 ret = get_errno(stime(&host_time));
1958 }
1959 break;
1960 case TARGET_NR_ptrace:
1961 goto unimplemented;
1962 case TARGET_NR_alarm:
1963 ret = alarm(arg1);
1964 break;
1965 #ifdef TARGET_NR_oldfstat
1966 case TARGET_NR_oldfstat:
1967 goto unimplemented;
1968 #endif
1969 case TARGET_NR_pause:
1970 ret = get_errno(pause());
1971 break;
1972 case TARGET_NR_utime:
1973 {
1974 struct utimbuf tbuf, *host_tbuf;
1975 struct target_utimbuf *target_tbuf;
1976 if (arg2) {
1977 lock_user_struct(target_tbuf, arg2, 1);
1978 tbuf.actime = tswapl(target_tbuf->actime);
1979 tbuf.modtime = tswapl(target_tbuf->modtime);
1980 unlock_user_struct(target_tbuf, arg2, 0);
1981 host_tbuf = &tbuf;
1982 } else {
1983 host_tbuf = NULL;
1984 }
1985 p = lock_user_string(arg1);
1986 ret = get_errno(utime(p, host_tbuf));
1987 unlock_user(p, arg1, 0);
1988 }
1989 break;
1990 case TARGET_NR_utimes:
1991 {
1992 struct timeval *tvp, tv[2];
1993 if (arg2) {
1994 target_to_host_timeval(&tv[0], arg2);
1995 target_to_host_timeval(&tv[1],
1996 arg2 + sizeof (struct target_timeval));
1997 tvp = tv;
1998 } else {
1999 tvp = NULL;
2000 }
2001 p = lock_user_string(arg1);
2002 ret = get_errno(utimes(p, tvp));
2003 unlock_user(p, arg1, 0);
2004 }
2005 break;
2006 #ifdef TARGET_NR_stty
2007 case TARGET_NR_stty:
2008 goto unimplemented;
2009 #endif
2010 #ifdef TARGET_NR_gtty
2011 case TARGET_NR_gtty:
2012 goto unimplemented;
2013 #endif
2014 case TARGET_NR_access:
2015 p = lock_user_string(arg1);
2016 ret = get_errno(access(p, arg2));
2017 unlock_user(p, arg1, 0);
2018 break;
2019 case TARGET_NR_nice:
2020 ret = get_errno(nice(arg1));
2021 break;
2022 #ifdef TARGET_NR_ftime
2023 case TARGET_NR_ftime:
2024 goto unimplemented;
2025 #endif
2026 case TARGET_NR_sync:
2027 sync();
2028 ret = 0;
2029 break;
2030 case TARGET_NR_kill:
2031 ret = get_errno(kill(arg1, arg2));
2032 break;
2033 case TARGET_NR_rename:
2034 {
2035 void *p2;
2036 p = lock_user_string(arg1);
2037 p2 = lock_user_string(arg2);
2038 ret = get_errno(rename(p, p2));
2039 unlock_user(p2, arg2, 0);
2040 unlock_user(p, arg1, 0);
2041 }
2042 break;
2043 case TARGET_NR_mkdir:
2044 p = lock_user_string(arg1);
2045 ret = get_errno(mkdir(p, arg2));
2046 unlock_user(p, arg1, 0);
2047 break;
2048 case TARGET_NR_rmdir:
2049 p = lock_user_string(arg1);
2050 ret = get_errno(rmdir(p));
2051 unlock_user(p, arg1, 0);
2052 break;
2053 case TARGET_NR_dup:
2054 ret = get_errno(dup(arg1));
2055 break;
2056 case TARGET_NR_pipe:
2057 {
2058 int host_pipe[2];
2059 ret = get_errno(pipe(host_pipe));
2060 if (!is_error(ret)) {
2061 tput32(arg1, host_pipe[0]);
2062 tput32(arg1 + 4, host_pipe[1]);
2063 }
2064 }
2065 break;
2066 case TARGET_NR_times:
2067 {
2068 struct target_tms *tmsp;
2069 struct tms tms;
2070 ret = get_errno(times(&tms));
2071 if (arg1) {
2072 tmsp = lock_user(arg1, sizeof(struct target_tms), 0);
2073 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
2074 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
2075 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
2076 tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
2077 }
2078 if (!is_error(ret))
2079 ret = host_to_target_clock_t(ret);
2080 }
2081 break;
2082 #ifdef TARGET_NR_prof
2083 case TARGET_NR_prof:
2084 goto unimplemented;
2085 #endif
2086 case TARGET_NR_signal:
2087 goto unimplemented;
2088
2089 case TARGET_NR_acct:
2090 p = lock_user_string(arg1);
2091 ret = get_errno(acct(path(p)));
2092 unlock_user(p, arg1, 0);
2093 break;
2094 case TARGET_NR_umount2:
2095 p = lock_user_string(arg1);
2096 ret = get_errno(umount2(p, arg2));
2097 unlock_user(p, arg1, 0);
2098 break;
2099 #ifdef TARGET_NR_lock
2100 case TARGET_NR_lock:
2101 goto unimplemented;
2102 #endif
2103 case TARGET_NR_ioctl:
2104 ret = do_ioctl(arg1, arg2, arg3);
2105 break;
2106 case TARGET_NR_fcntl:
2107 ret = get_errno(do_fcntl(arg1, arg2, arg3));
2108 break;
2109 #ifdef TARGET_NR_mpx
2110 case TARGET_NR_mpx:
2111 goto unimplemented;
2112 #endif
2113 case TARGET_NR_setpgid:
2114 ret = get_errno(setpgid(arg1, arg2));
2115 break;
2116 #ifdef TARGET_NR_ulimit
2117 case TARGET_NR_ulimit:
2118 goto unimplemented;
2119 #endif
2120 #ifdef TARGET_NR_oldolduname
2121 case TARGET_NR_oldolduname:
2122 goto unimplemented;
2123 #endif
2124 case TARGET_NR_umask:
2125 ret = get_errno(umask(arg1));
2126 break;
2127 case TARGET_NR_chroot:
2128 p = lock_user_string(arg1);
2129 ret = get_errno(chroot(p));
2130 unlock_user(p, arg1, 0);
2131 break;
2132 case TARGET_NR_ustat:
2133 goto unimplemented;
2134 case TARGET_NR_dup2:
2135 ret = get_errno(dup2(arg1, arg2));
2136 break;
2137 case TARGET_NR_getppid:
2138 ret = get_errno(getppid());
2139 break;
2140 case TARGET_NR_getpgrp:
2141 ret = get_errno(getpgrp());
2142 break;
2143 case TARGET_NR_setsid:
2144 ret = get_errno(setsid());
2145 break;
2146 case TARGET_NR_sigaction:
2147 {
2148 struct target_old_sigaction *old_act;
2149 struct target_sigaction act, oact, *pact;
2150 if (arg2) {
2151 lock_user_struct(old_act, arg2, 1);
2152 act._sa_handler = old_act->_sa_handler;
2153 target_siginitset(&act.sa_mask, old_act->sa_mask);
2154 act.sa_flags = old_act->sa_flags;
2155 act.sa_restorer = old_act->sa_restorer;
2156 unlock_user_struct(old_act, arg2, 0);
2157 pact = &act;
2158 } else {
2159 pact = NULL;
2160 }
2161 ret = get_errno(do_sigaction(arg1, pact, &oact));
2162 if (!is_error(ret) && arg3) {
2163 lock_user_struct(old_act, arg3, 0);
2164 old_act->_sa_handler = oact._sa_handler;
2165 old_act->sa_mask = oact.sa_mask.sig[0];
2166 old_act->sa_flags = oact.sa_flags;
2167 old_act->sa_restorer = oact.sa_restorer;
2168 unlock_user_struct(old_act, arg3, 1);
2169 }
2170 }
2171 break;
2172 case TARGET_NR_rt_sigaction:
2173 {
2174 struct target_sigaction *act;
2175 struct target_sigaction *oact;
2176
2177 if (arg2)
2178 lock_user_struct(act, arg2, 1);
2179 else
2180 act = NULL;
2181 if (arg3)
2182 lock_user_struct(oact, arg3, 0);
2183 else
2184 oact = NULL;
2185 ret = get_errno(do_sigaction(arg1, act, oact));
2186 if (arg2)
2187 unlock_user_struct(act, arg2, 0);
2188 if (arg3)
2189 unlock_user_struct(oact, arg3, 1);
2190 }
2191 break;
2192 case TARGET_NR_sgetmask:
2193 {
2194 sigset_t cur_set;
2195 target_ulong target_set;
2196 sigprocmask(0, NULL, &cur_set);
2197 host_to_target_old_sigset(&target_set, &cur_set);
2198 ret = target_set;
2199 }
2200 break;
2201 case TARGET_NR_ssetmask:
2202 {
2203 sigset_t set, oset, cur_set;
2204 target_ulong target_set = arg1;
2205 sigprocmask(0, NULL, &cur_set);
2206 target_to_host_old_sigset(&set, &target_set);
2207 sigorset(&set, &set, &cur_set);
2208 sigprocmask(SIG_SETMASK, &set, &oset);
2209 host_to_target_old_sigset(&target_set, &oset);
2210 ret = target_set;
2211 }
2212 break;
2213 case TARGET_NR_sigprocmask:
2214 {
2215 int how = arg1;
2216 sigset_t set, oldset, *set_ptr;
2217
2218 if (arg2) {
2219 switch(how) {
2220 case TARGET_SIG_BLOCK:
2221 how = SIG_BLOCK;
2222 break;
2223 case TARGET_SIG_UNBLOCK:
2224 how = SIG_UNBLOCK;
2225 break;
2226 case TARGET_SIG_SETMASK:
2227 how = SIG_SETMASK;
2228 break;
2229 default:
2230 ret = -EINVAL;
2231 goto fail;
2232 }
2233 p = lock_user(arg2, sizeof(target_sigset_t), 1);
2234 target_to_host_old_sigset(&set, p);
2235 unlock_user(p, arg2, 0);
2236 set_ptr = &set;
2237 } else {
2238 how = 0;
2239 set_ptr = NULL;
2240 }
2241 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
2242 if (!is_error(ret) && arg3) {
2243 p = lock_user(arg3, sizeof(target_sigset_t), 0);
2244 host_to_target_old_sigset(p, &oldset);
2245 unlock_user(p, arg3, sizeof(target_sigset_t));
2246 }
2247 }
2248 break;
2249 case TARGET_NR_rt_sigprocmask:
2250 {
2251 int how = arg1;
2252 sigset_t set, oldset, *set_ptr;
2253
2254 if (arg2) {
2255 switch(how) {
2256 case TARGET_SIG_BLOCK:
2257 how = SIG_BLOCK;
2258 break;
2259 case TARGET_SIG_UNBLOCK:
2260 how = SIG_UNBLOCK;
2261 break;
2262 case TARGET_SIG_SETMASK:
2263 how = SIG_SETMASK;
2264 break;
2265 default:
2266 ret = -EINVAL;
2267 goto fail;
2268 }
2269 p = lock_user(arg2, sizeof(target_sigset_t), 1);
2270 target_to_host_sigset(&set, p);
2271 unlock_user(p, arg2, 0);
2272 set_ptr = &set;
2273 } else {
2274 how = 0;
2275 set_ptr = NULL;
2276 }
2277 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
2278 if (!is_error(ret) && arg3) {
2279 p = lock_user(arg3, sizeof(target_sigset_t), 0);
2280 host_to_target_sigset(p, &oldset);
2281 unlock_user(p, arg3, sizeof(target_sigset_t));
2282 }
2283 }
2284 break;
2285 case TARGET_NR_sigpending:
2286 {
2287 sigset_t set;
2288 ret = get_errno(sigpending(&set));
2289 if (!is_error(ret)) {
2290 p = lock_user(arg1, sizeof(target_sigset_t), 0);
2291 host_to_target_old_sigset(p, &set);
2292 unlock_user(p, arg1, sizeof(target_sigset_t));
2293 }
2294 }
2295 break;
2296 case TARGET_NR_rt_sigpending:
2297 {
2298 sigset_t set;
2299 ret = get_errno(sigpending(&set));
2300 if (!is_error(ret)) {
2301 p = lock_user(arg1, sizeof(target_sigset_t), 0);
2302 host_to_target_sigset(p, &set);
2303 unlock_user(p, arg1, sizeof(target_sigset_t));
2304 }
2305 }
2306 break;
2307 case TARGET_NR_sigsuspend:
2308 {
2309 sigset_t set;
2310 p = lock_user(arg1, sizeof(target_sigset_t), 1);
2311 target_to_host_old_sigset(&set, p);
2312 unlock_user(p, arg1, 0);
2313 ret = get_errno(sigsuspend(&set));
2314 }
2315 break;
2316 case TARGET_NR_rt_sigsuspend:
2317 {
2318 sigset_t set;
2319 p = lock_user(arg1, sizeof(target_sigset_t), 1);
2320 target_to_host_sigset(&set, p);
2321 unlock_user(p, arg1, 0);
2322 ret = get_errno(sigsuspend(&set));
2323 }
2324 break;
2325 case TARGET_NR_rt_sigtimedwait:
2326 {
2327 sigset_t set;
2328 struct timespec uts, *puts;
2329 siginfo_t uinfo;
2330
2331 p = lock_user(arg1, sizeof(target_sigset_t), 1);
2332 target_to_host_sigset(&set, p);
2333 unlock_user(p, arg1, 0);
2334 if (arg3) {
2335 puts = &uts;
2336 target_to_host_timespec(puts, arg3);
2337 } else {
2338 puts = NULL;
2339 }
2340 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
2341 if (!is_error(ret) && arg2) {
2342 p = lock_user(arg2, sizeof(target_sigset_t), 0);
2343 host_to_target_siginfo(p, &uinfo);
2344 unlock_user(p, arg2, sizeof(target_sigset_t));
2345 }
2346 }
2347 break;
2348 case TARGET_NR_rt_sigqueueinfo:
2349 {
2350 siginfo_t uinfo;
2351 p = lock_user(arg3, sizeof(target_sigset_t), 1);
2352 target_to_host_siginfo(&uinfo, p);
2353 unlock_user(p, arg1, 0);
2354 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
2355 }
2356 break;
2357 case TARGET_NR_sigreturn:
2358 /* NOTE: ret is eax, so not transcoding must be done */
2359 ret = do_sigreturn(cpu_env);
2360 break;
2361 case TARGET_NR_rt_sigreturn:
2362 /* NOTE: ret is eax, so not transcoding must be done */
2363 ret = do_rt_sigreturn(cpu_env);
2364 break;
2365 case TARGET_NR_sethostname:
2366 p = lock_user_string(arg1);
2367 ret = get_errno(sethostname(p, arg2));
2368 unlock_user(p, arg1, 0);
2369 break;
2370 case TARGET_NR_setrlimit:
2371 {
2372 /* XXX: convert resource ? */
2373 int resource = arg1;
2374 struct target_rlimit *target_rlim;
2375 struct rlimit rlim;
2376 lock_user_struct(target_rlim, arg2, 1);
2377 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
2378 rlim.rlim_max = tswapl(target_rlim->rlim_max);
2379 unlock_user_struct(target_rlim, arg2, 0);
2380 ret = get_errno(setrlimit(resource, &rlim));
2381 }
2382 break;
2383 case TARGET_NR_getrlimit:
2384 {
2385 /* XXX: convert resource ? */
2386 int resource = arg1;
2387 struct target_rlimit *target_rlim;
2388 struct rlimit rlim;
2389
2390 ret = get_errno(getrlimit(resource, &rlim));
2391 if (!is_error(ret)) {
2392 lock_user_struct(target_rlim, arg2, 0);
2393 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
2394 rlim.rlim_max = tswapl(target_rlim->rlim_max);
2395 unlock_user_struct(target_rlim, arg2, 1);
2396 }
2397 }
2398 break;
2399 case TARGET_NR_getrusage:
2400 {
2401 struct rusage rusage;
2402 ret = get_errno(getrusage(arg1, &rusage));
2403 if (!is_error(ret)) {
2404 host_to_target_rusage(arg2, &rusage);
2405 }
2406 }
2407 break;
2408 case TARGET_NR_gettimeofday:
2409 {
2410 struct timeval tv;
2411 ret = get_errno(gettimeofday(&tv, NULL));
2412 if (!is_error(ret)) {
2413 host_to_target_timeval(arg1, &tv);
2414 }
2415 }
2416 break;
2417 case TARGET_NR_settimeofday:
2418 {
2419 struct timeval tv;
2420 target_to_host_timeval(&tv, arg1);
2421 ret = get_errno(settimeofday(&tv, NULL));
2422 }
2423 break;
2424 #ifdef TARGET_NR_select
2425 case TARGET_NR_select:
2426 {
2427 struct target_sel_arg_struct *sel;
2428 target_ulong inp, outp, exp, tvp;
2429 long nsel;
2430
2431 lock_user_struct(sel, arg1, 1);
2432 nsel = tswapl(sel->n);
2433 inp = tswapl(sel->inp);
2434 outp = tswapl(sel->outp);
2435 exp = tswapl(sel->exp);
2436 tvp = tswapl(sel->tvp);
2437 unlock_user_struct(sel, arg1, 0);
2438 ret = do_select(nsel, inp, outp, exp, tvp);
2439 }
2440 break;
2441 #endif
2442 case TARGET_NR_symlink:
2443 {
2444 void *p2;
2445 p = lock_user_string(arg1);
2446 p2 = lock_user_string(arg2);
2447 ret = get_errno(symlink(p, p2));
2448 unlock_user(p2, arg2, 0);
2449 unlock_user(p, arg1, 0);
2450 }
2451 break;
2452 #ifdef TARGET_NR_oldlstat
2453 case TARGET_NR_oldlstat:
2454 goto unimplemented;
2455 #endif
2456 case TARGET_NR_readlink:
2457 {
2458 void *p2;
2459 p = lock_user_string(arg1);
2460 p2 = lock_user(arg2, arg3, 0);
2461 ret = get_errno(readlink(path(p), p2, arg3));
2462 unlock_user(p2, arg2, ret);
2463 unlock_user(p, arg1, 0);
2464 }
2465 break;
2466 case TARGET_NR_uselib:
2467 goto unimplemented;
2468 case TARGET_NR_swapon:
2469 p = lock_user_string(arg1);
2470 ret = get_errno(swapon(p, arg2));
2471 unlock_user(p, arg1, 0);
2472 break;
2473 case TARGET_NR_reboot:
2474 goto unimplemented;
2475 case TARGET_NR_readdir:
2476 goto unimplemented;
2477 case TARGET_NR_mmap:
2478 #if defined(TARGET_I386) || defined(TARGET_ARM)
2479 {
2480 target_ulong *v;
2481 target_ulong v1, v2, v3, v4, v5, v6;
2482 v = lock_user(arg1, 6 * sizeof(target_ulong), 1);
2483 v1 = tswapl(v[0]);
2484 v2 = tswapl(v[1]);
2485 v3 = tswapl(v[2]);
2486 v4 = tswapl(v[3]);
2487 v5 = tswapl(v[4]);
2488 v6 = tswapl(v[5]);
2489 unlock_user(v, arg1, 0);
2490 ret = get_errno(target_mmap(v1, v2, v3,
2491 target_to_host_bitmask(v4, mmap_flags_tbl),
2492 v5, v6));
2493 }
2494 #else
2495 ret = get_errno(target_mmap(arg1, arg2, arg3,
2496 target_to_host_bitmask(arg4, mmap_flags_tbl),
2497 arg5,
2498 arg6));
2499 #endif
2500 break;
2501 #ifdef TARGET_NR_mmap2
2502 case TARGET_NR_mmap2:
2503 #if defined(TARGET_SPARC)
2504 #define MMAP_SHIFT 12
2505 #else
2506 #define MMAP_SHIFT TARGET_PAGE_BITS
2507 #endif
2508 ret = get_errno(target_mmap(arg1, arg2, arg3,
2509 target_to_host_bitmask(arg4, mmap_flags_tbl),
2510 arg5,
2511 arg6 << MMAP_SHIFT));
2512 break;
2513 #endif
2514 case TARGET_NR_munmap:
2515 ret = get_errno(target_munmap(arg1, arg2));
2516 break;
2517 case TARGET_NR_mprotect:
2518 ret = get_errno(target_mprotect(arg1, arg2, arg3));
2519 break;
2520 case TARGET_NR_mremap:
2521 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
2522 break;
2523 /* ??? msync/mlock/munlock are broken for softmmu. */
2524 case TARGET_NR_msync:
2525 ret = get_errno(msync(g2h(arg1), arg2, arg3));
2526 break;
2527 case TARGET_NR_mlock:
2528 ret = get_errno(mlock(g2h(arg1), arg2));
2529 break;
2530 case TARGET_NR_munlock:
2531 ret = get_errno(munlock(g2h(arg1), arg2));
2532 break;
2533 case TARGET_NR_mlockall:
2534 ret = get_errno(mlockall(arg1));
2535 break;
2536 case TARGET_NR_munlockall:
2537 ret = get_errno(munlockall());
2538 break;
2539 case TARGET_NR_truncate:
2540 p = lock_user_string(arg1);
2541 ret = get_errno(truncate(p, arg2));
2542 unlock_user(p, arg1, 0);
2543 break;
2544 case TARGET_NR_ftruncate:
2545 ret = get_errno(ftruncate(arg1, arg2));
2546 break;
2547 case TARGET_NR_fchmod:
2548 ret = get_errno(fchmod(arg1, arg2));
2549 break;
2550 case TARGET_NR_getpriority:
2551 ret = get_errno(getpriority(arg1, arg2));
2552 break;
2553 case TARGET_NR_setpriority:
2554 ret = get_errno(setpriority(arg1, arg2, arg3));
2555 break;
2556 #ifdef TARGET_NR_profil
2557 case TARGET_NR_profil:
2558 goto unimplemented;
2559 #endif
2560 case TARGET_NR_statfs:
2561 p = lock_user_string(arg1);
2562 ret = get_errno(statfs(path(p), &stfs));
2563 unlock_user(p, arg1, 0);
2564 convert_statfs:
2565 if (!is_error(ret)) {
2566 struct target_statfs *target_stfs;
2567
2568 lock_user_struct(target_stfs, arg2, 0);
2569 /* ??? put_user is probably wrong. */
2570 put_user(stfs.f_type, &target_stfs->f_type);
2571 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2572 put_user(stfs.f_blocks, &target_stfs->f_blocks);
2573 put_user(stfs.f_bfree, &target_stfs->f_bfree);
2574 put_user(stfs.f_bavail, &target_stfs->f_bavail);
2575 put_user(stfs.f_files, &target_stfs->f_files);
2576 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2577 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2578 put_user(stfs.f_namelen, &target_stfs->f_namelen);
2579 unlock_user_struct(target_stfs, arg2, 1);
2580 }
2581 break;
2582 case TARGET_NR_fstatfs:
2583 ret = get_errno(fstatfs(arg1, &stfs));
2584 goto convert_statfs;
2585 #ifdef TARGET_NR_statfs64
2586 case TARGET_NR_statfs64:
2587 p = lock_user_string(arg1);
2588 ret = get_errno(statfs(path(p), &stfs));
2589 unlock_user(p, arg1, 0);
2590 convert_statfs64:
2591 if (!is_error(ret)) {
2592 struct target_statfs64 *target_stfs;
2593
2594 lock_user_struct(target_stfs, arg3, 0);
2595 /* ??? put_user is probably wrong. */
2596 put_user(stfs.f_type, &target_stfs->f_type);
2597 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2598 put_user(stfs.f_blocks, &target_stfs->f_blocks);
2599 put_user(stfs.f_bfree, &target_stfs->f_bfree);
2600 put_user(stfs.f_bavail, &target_stfs->f_bavail);
2601 put_user(stfs.f_files, &target_stfs->f_files);
2602 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2603 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2604 put_user(stfs.f_namelen, &target_stfs->f_namelen);
2605 unlock_user_struct(target_stfs, arg3, 0);
2606 }
2607 break;
2608 case TARGET_NR_fstatfs64:
2609 ret = get_errno(fstatfs(arg1, &stfs));
2610 goto convert_statfs64;
2611 #endif
2612 #ifdef TARGET_NR_ioperm
2613 case TARGET_NR_ioperm:
2614 goto unimplemented;
2615 #endif
2616 case TARGET_NR_socketcall:
2617 ret = do_socketcall(arg1, arg2);
2618 break;
2619 case TARGET_NR_syslog:
2620 goto unimplemented;
2621 case TARGET_NR_setitimer:
2622 {
2623 struct itimerval value, ovalue, *pvalue;
2624
2625 if (arg2) {
2626 pvalue = &value;
2627 target_to_host_timeval(&pvalue->it_interval,
2628 arg2);
2629 target_to_host_timeval(&pvalue->it_value,
2630 arg2 + sizeof(struct target_timeval));
2631 } else {
2632 pvalue = NULL;
2633 }
2634 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
2635 if (!is_error(ret) && arg3) {
2636 host_to_target_timeval(arg3,
2637 &ovalue.it_interval);
2638 host_to_target_timeval(arg3 + sizeof(struct target_timeval),
2639 &ovalue.it_value);
2640 }
2641 }
2642 break;
2643 case TARGET_NR_getitimer:
2644 {
2645 struct itimerval value;
2646
2647 ret = get_errno(getitimer(arg1, &value));
2648 if (!is_error(ret) && arg2) {
2649 host_to_target_timeval(arg2,
2650 &value.it_interval);
2651 host_to_target_timeval(arg2 + sizeof(struct target_timeval),
2652 &value.it_value);
2653 }
2654 }
2655 break;
2656 case TARGET_NR_stat:
2657 p = lock_user_string(arg1);
2658 ret = get_errno(stat(path(p), &st));
2659 unlock_user(p, arg1, 0);
2660 goto do_stat;
2661 case TARGET_NR_lstat:
2662 p = lock_user_string(arg1);
2663 ret = get_errno(lstat(path(p), &st));
2664 unlock_user(p, arg1, 0);
2665 goto do_stat;
2666 case TARGET_NR_fstat:
2667 {
2668 ret = get_errno(fstat(arg1, &st));
2669 do_stat:
2670 if (!is_error(ret)) {
2671 struct target_stat *target_st;
2672
2673 lock_user_struct(target_st, arg2, 0);
2674 target_st->st_dev = tswap16(st.st_dev);
2675 target_st->st_ino = tswapl(st.st_ino);
2676 #if defined(TARGET_PPC)
2677 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
2678 target_st->st_uid = tswap32(st.st_uid);
2679 target_st->st_gid = tswap32(st.st_gid);
2680 #else
2681 target_st->st_mode = tswap16(st.st_mode);
2682 target_st->st_uid = tswap16(st.st_uid);
2683 target_st->st_gid = tswap16(st.st_gid);
2684 #endif
2685 target_st->st_nlink = tswap16(st.st_nlink);
2686 target_st->st_rdev = tswap16(st.st_rdev);
2687 target_st->st_size = tswapl(st.st_size);
2688 target_st->st_blksize = tswapl(st.st_blksize);
2689 target_st->st_blocks = tswapl(st.st_blocks);
2690 target_st->target_st_atime = tswapl(st.st_atime);
2691 target_st->target_st_mtime = tswapl(st.st_mtime);
2692 target_st->target_st_ctime = tswapl(st.st_ctime);
2693 unlock_user_struct(target_st, arg2, 1);
2694 }
2695 }
2696 break;
2697 #ifdef TARGET_NR_olduname
2698 case TARGET_NR_olduname:
2699 goto unimplemented;
2700 #endif
2701 #ifdef TARGET_NR_iopl
2702 case TARGET_NR_iopl:
2703 goto unimplemented;
2704 #endif
2705 case TARGET_NR_vhangup:
2706 ret = get_errno(vhangup());
2707 break;
2708 #ifdef TARGET_NR_idle
2709 case TARGET_NR_idle:
2710 goto unimplemented;
2711 #endif
2712 #ifdef TARGET_NR_syscall
2713 case TARGET_NR_syscall:
2714 ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
2715 break;
2716 #endif
2717 case TARGET_NR_wait4:
2718 {
2719 int status;
2720 target_long status_ptr = arg2;
2721 struct rusage rusage, *rusage_ptr;
2722 target_ulong target_rusage = arg4;
2723 if (target_rusage)
2724 rusage_ptr = &rusage;
2725 else
2726 rusage_ptr = NULL;
2727 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
2728 if (!is_error(ret)) {
2729 if (status_ptr)
2730 tputl(status_ptr, status);
2731 if (target_rusage) {
2732 host_to_target_rusage(target_rusage, &rusage);
2733 }
2734 }
2735 }
2736 break;
2737 case TARGET_NR_swapoff:
2738 p = lock_user_string(arg1);
2739 ret = get_errno(swapoff(p));
2740 unlock_user(p, arg1, 0);
2741 break;
2742 case TARGET_NR_sysinfo:
2743 {
2744 struct target_sysinfo *target_value;
2745 struct sysinfo value;
2746 ret = get_errno(sysinfo(&value));
2747 if (!is_error(ret) && arg1)
2748 {
2749 /* ??? __put_user is probably wrong. */
2750 lock_user_struct(target_value, arg1, 0);
2751 __put_user(value.uptime, &target_value->uptime);
2752 __put_user(value.loads[0], &target_value->loads[0]);
2753 __put_user(value.loads[1], &target_value->loads[1]);
2754 __put_user(value.loads[2], &target_value->loads[2]);
2755 __put_user(value.totalram, &target_value->totalram);
2756 __put_user(value.freeram, &target_value->freeram);
2757 __put_user(value.sharedram, &target_value->sharedram);
2758 __put_user(value.bufferram, &target_value->bufferram);
2759 __put_user(value.totalswap, &target_value->totalswap);
2760 __put_user(value.freeswap, &target_value->freeswap);
2761 __put_user(value.procs, &target_value->procs);
2762 __put_user(value.totalhigh, &target_value->totalhigh);
2763 __put_user(value.freehigh, &target_value->freehigh);
2764 __put_user(value.mem_unit, &target_value->mem_unit);
2765 unlock_user_struct(target_value, arg1, 1);
2766 }
2767 }
2768 break;
2769 case TARGET_NR_ipc:
2770 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
2771 break;
2772 case TARGET_NR_fsync:
2773 ret = get_errno(fsync(arg1));
2774 break;
2775 case TARGET_NR_clone:
2776 ret = get_errno(do_fork(cpu_env, arg1, arg2));
2777 break;
2778 #ifdef __NR_exit_group
2779 /* new thread calls */
2780 case TARGET_NR_exit_group:
2781 gdb_exit(cpu_env, arg1);
2782 ret = get_errno(exit_group(arg1));
2783 break;
2784 #endif
2785 case TARGET_NR_setdomainname:
2786 p = lock_user_string(arg1);
2787 ret = get_errno(setdomainname(p, arg2));
2788 unlock_user(p, arg1, 0);
2789 break;
2790 case TARGET_NR_uname:
2791 /* no need to transcode because we use the linux syscall */
2792 {
2793 struct new_utsname * buf;
2794
2795 lock_user_struct(buf, arg1, 0);
2796 ret = get_errno(sys_uname(buf));
2797 if (!is_error(ret)) {
2798 /* Overrite the native machine name with whatever is being
2799 emulated. */
2800 strcpy (buf->machine, UNAME_MACHINE);
2801 /* Allow the user to override the reported release. */
2802 if (qemu_uname_release && *qemu_uname_release)
2803 strcpy (buf->release, qemu_uname_release);
2804 }
2805 unlock_user_struct(buf, arg1, 1);
2806 }
2807 break;
2808 #ifdef TARGET_I386
2809 case TARGET_NR_modify_ldt:
2810 ret = get_errno(do_modify_ldt(cpu_env, arg1, arg2, arg3));
2811 break;
2812 case TARGET_NR_vm86old:
2813 goto unimplemented;
2814 case TARGET_NR_vm86:
2815 ret = do_vm86(cpu_env, arg1, arg2);
2816 break;
2817 #endif
2818 case TARGET_NR_adjtimex:
2819 goto unimplemented;
2820 case TARGET_NR_create_module:
2821 case TARGET_NR_init_module:
2822 case TARGET_NR_delete_module:
2823 case TARGET_NR_get_kernel_syms:
2824 goto unimplemented;
2825 case TARGET_NR_quotactl:
2826 goto unimplemented;
2827 case TARGET_NR_getpgid:
2828 ret = get_errno(getpgid(arg1));
2829 break;
2830 case TARGET_NR_fchdir:
2831 ret = get_errno(fchdir(arg1));
2832 break;
2833 case TARGET_NR_bdflush:
2834 goto unimplemented;
2835 case TARGET_NR_sysfs:
2836 goto unimplemented;
2837 case TARGET_NR_personality:
2838 ret = get_errno(personality(arg1));
2839 break;
2840 case TARGET_NR_afs_syscall:
2841 goto unimplemented;
2842 case TARGET_NR__llseek:
2843 {
2844 #if defined (__x86_64__)
2845 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
2846 tput64(arg4, ret);
2847 #else
2848 int64_t res;
2849 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
2850 tput64(arg4, res);
2851 #endif
2852 }
2853 break;
2854 case TARGET_NR_getdents:
2855 #if TARGET_LONG_SIZE != 4
2856 goto unimplemented;
2857 #warning not supported
2858 #elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
2859 {
2860 struct target_dirent *target_dirp;
2861 struct dirent *dirp;
2862 long count = arg3;
2863
2864 dirp = malloc(count);
2865 if (!dirp)
2866 return -ENOMEM;
2867
2868 ret = get_errno(sys_getdents(arg1, dirp, count));
2869 if (!is_error(ret)) {
2870 struct dirent *de;
2871 struct target_dirent *tde;
2872 int len = ret;
2873 int reclen, treclen;
2874 int count1, tnamelen;
2875
2876 count1 = 0;
2877 de = dirp;
2878 target_dirp = lock_user(arg2, count, 0);
2879 tde = target_dirp;
2880 while (len > 0) {
2881 reclen = de->d_reclen;
2882 treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
2883 tde->d_reclen = tswap16(treclen);
2884 tde->d_ino = tswapl(de->d_ino);
2885 tde->d_off = tswapl(de->d_off);
2886 tnamelen = treclen - (2 * sizeof(target_long) + 2);
2887 if (tnamelen > 256)
2888 tnamelen = 256;
2889 /* XXX: may not be correct */
2890 strncpy(tde->d_name, de->d_name, tnamelen);
2891 de = (struct dirent *)((char *)de + reclen);
2892 len -= reclen;
2893 tde = (struct dirent *)((char *)tde + treclen);
2894 count1 += treclen;
2895 }
2896 ret = count1;
2897 }
2898 unlock_user(target_dirp, arg2, ret);
2899 free(dirp);
2900 }
2901 #else
2902 {
2903 struct dirent *dirp;
2904 long count = arg3;
2905
2906 dirp = lock_user(arg2, count, 0);
2907 ret = get_errno(sys_getdents(arg1, dirp, count));
2908 if (!is_error(ret)) {
2909 struct dirent *de;
2910 int len = ret;
2911 int reclen;
2912 de = dirp;
2913 while (len > 0) {
2914 reclen = de->d_reclen;
2915 if (reclen > len)
2916 break;
2917 de->d_reclen = tswap16(reclen);
2918 tswapls(&de->d_ino);
2919 tswapls(&de->d_off);
2920 de = (struct dirent *)((char *)de + reclen);
2921 len -= reclen;
2922 }
2923 }
2924 unlock_user(dirp, arg2, ret);
2925 }
2926 #endif
2927 break;
2928 #ifdef TARGET_NR_getdents64
2929 case TARGET_NR_getdents64:
2930 {
2931 struct dirent64 *dirp;
2932 long count = arg3;
2933 dirp = lock_user(arg2, count, 0);
2934 ret = get_errno(sys_getdents64(arg1, dirp, count));
2935 if (!is_error(ret)) {
2936 struct dirent64 *de;
2937 int len = ret;
2938 int reclen;
2939 de = dirp;
2940 while (len > 0) {
2941 reclen = de->d_reclen;
2942 if (reclen > len)
2943 break;
2944 de->d_reclen = tswap16(reclen);
2945 tswap64s(&de->d_ino);
2946 tswap64s(&de->d_off);
2947 de = (struct dirent64 *)((char *)de + reclen);
2948 len -= reclen;
2949 }
2950 }
2951 unlock_user(dirp, arg2, ret);
2952 }
2953 break;
2954 #endif /* TARGET_NR_getdents64 */
2955 case TARGET_NR__newselect:
2956 ret = do_select(arg1, arg2, arg3, arg4, arg5);
2957 break;
2958 case TARGET_NR_poll:
2959 {
2960 struct target_pollfd *target_pfd;
2961 unsigned int nfds = arg2;
2962 int timeout = arg3;
2963 struct pollfd *pfd;
2964 unsigned int i;
2965
2966 target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1);
2967 pfd = alloca(sizeof(struct pollfd) * nfds);
2968 for(i = 0; i < nfds; i++) {
2969 pfd[i].fd = tswap32(target_pfd[i].fd);
2970 pfd[i].events = tswap16(target_pfd[i].events);
2971 }
2972 ret = get_errno(poll(pfd, nfds, timeout));
2973 if (!is_error(ret)) {
2974 for(i = 0; i < nfds; i++) {
2975 target_pfd[i].revents = tswap16(pfd[i].revents);
2976 }
2977 ret += nfds * (sizeof(struct target_pollfd)
2978 - sizeof(struct pollfd));
2979 }
2980 unlock_user(target_pfd, arg1, ret);
2981 }
2982 break;
2983 case TARGET_NR_flock:
2984 /* NOTE: the flock constant seems to be the same for every
2985 Linux platform */
2986 ret = get_errno(flock(arg1, arg2));
2987 break;
2988 case TARGET_NR_readv:
2989 {
2990 int count = arg3;
2991 struct iovec *vec;
2992
2993 vec = alloca(count * sizeof(struct iovec));
2994 lock_iovec(vec, arg2, count, 0);
2995 ret = get_errno(readv(arg1, vec, count));
2996 unlock_iovec(vec, arg2, count, 1);
2997 }
2998 break;
2999 case TARGET_NR_writev:
3000 {
3001 int count = arg3;
3002 struct iovec *vec;
3003
3004 vec = alloca(count * sizeof(struct iovec));
3005 lock_iovec(vec, arg2, count, 1);
3006 ret = get_errno(writev(arg1, vec, count));
3007 unlock_iovec(vec, arg2, count, 0);
3008 }
3009 break;
3010 case TARGET_NR_getsid:
3011 ret = get_errno(getsid(arg1));
3012 break;
3013 case TARGET_NR_fdatasync:
3014 ret = get_errno(fdatasync(arg1));
3015 break;
3016 case TARGET_NR__sysctl:
3017 /* We don't implement this, but ENODIR is always a safe
3018 return value. */
3019 return -ENOTDIR;
3020 case TARGET_NR_sched_setparam:
3021 {
3022 struct sched_param *target_schp;
3023 struct sched_param schp;
3024
3025 lock_user_struct(target_schp, arg2, 1);
3026 schp.sched_priority = tswap32(target_schp->sched_priority);
3027 unlock_user_struct(target_schp, arg2, 0);
3028 ret = get_errno(sched_setparam(arg1, &schp));
3029 }
3030 break;
3031 case TARGET_NR_sched_getparam:
3032 {
3033 struct sched_param *target_schp;
3034 struct sched_param schp;
3035 ret = get_errno(sched_getparam(arg1, &schp));
3036 if (!is_error(ret)) {
3037 lock_user_struct(target_schp, arg2, 0);
3038 target_schp->sched_priority = tswap32(schp.sched_priority);
3039 unlock_user_struct(target_schp, arg2, 1);
3040 }
3041 }
3042 break;
3043 case TARGET_NR_sched_setscheduler:
3044 {
3045 struct sched_param *target_schp;
3046 struct sched_param schp;
3047 lock_user_struct(target_schp, arg3, 1);
3048 schp.sched_priority = tswap32(target_schp->sched_priority);
3049 unlock_user_struct(target_schp, arg3, 0);
3050 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
3051 }
3052 break;
3053 case TARGET_NR_sched_getscheduler:
3054 ret = get_errno(sched_getscheduler(arg1));
3055 break;
3056 case TARGET_NR_sched_yield:
3057 ret = get_errno(sched_yield());
3058 break;
3059 case TARGET_NR_sched_get_priority_max:
3060 ret = get_errno(sched_get_priority_max(arg1));
3061 break;
3062 case TARGET_NR_sched_get_priority_min:
3063 ret = get_errno(sched_get_priority_min(arg1));
3064 break;
3065 case TARGET_NR_sched_rr_get_interval:
3066 {
3067 struct timespec ts;
3068 ret = get_errno(sched_rr_get_interval(arg1, &ts));
3069 if (!is_error(ret)) {
3070 host_to_target_timespec(arg2, &ts);
3071 }
3072 }
3073 break;
3074 case TARGET_NR_nanosleep:
3075 {
3076 struct timespec req, rem;
3077 target_to_host_timespec(&req, arg1);
3078 ret = get_errno(nanosleep(&req, &rem));
3079 if (is_error(ret) && arg2) {
3080 host_to_target_timespec(arg2, &rem);
3081 }
3082 }
3083 break;
3084 case TARGET_NR_query_module:
3085 goto unimplemented;
3086 case TARGET_NR_nfsservctl:
3087 goto unimplemented;
3088 case TARGET_NR_prctl:
3089 goto unimplemented;
3090 #ifdef TARGET_NR_pread
3091 case TARGET_NR_pread:
3092 page_unprotect_range(arg2, arg3);
3093 p = lock_user(arg2, arg3, 0);
3094 ret = get_errno(pread(arg1, p, arg3, arg4));
3095 unlock_user(p, arg2, ret);
3096 break;
3097 case TARGET_NR_pwrite:
3098 p = lock_user(arg2, arg3, 1);
3099 ret = get_errno(pwrite(arg1, p, arg3, arg4));
3100 unlock_user(p, arg2, 0);
3101 break;
3102 #endif
3103 case TARGET_NR_getcwd:
3104 p = lock_user(arg1, arg2, 0);
3105 ret = get_errno(sys_getcwd1(p, arg2));
3106 unlock_user(p, arg1, ret);
3107 break;
3108 case TARGET_NR_capget:
3109 goto unimplemented;
3110 case TARGET_NR_capset:
3111 goto unimplemented;
3112 case TARGET_NR_sigaltstack:
3113 goto unimplemented;
3114 case TARGET_NR_sendfile:
3115 goto unimplemented;
3116 #ifdef TARGET_NR_getpmsg
3117 case TARGET_NR_getpmsg:
3118 goto unimplemented;
3119 #endif
3120 #ifdef TARGET_NR_putpmsg
3121 case TARGET_NR_putpmsg:
3122 goto unimplemented;
3123 #endif
3124 #ifdef TARGET_NR_vfork
3125 case TARGET_NR_vfork:
3126 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
3127 break;
3128 #endif
3129 #ifdef TARGET_NR_ugetrlimit
3130 case TARGET_NR_ugetrlimit:
3131 {
3132 struct rlimit rlim;
3133 ret = get_errno(getrlimit(arg1, &rlim));
3134 if (!is_error(ret)) {
3135 struct target_rlimit *target_rlim;
3136 lock_user_struct(target_rlim, arg2, 0);
3137 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
3138 target_rlim->rlim_max = tswapl(rlim.rlim_max);
3139 unlock_user_struct(target_rlim, arg2, 1);
3140 }
3141 break;
3142 }
3143 #endif
3144 #ifdef TARGET_NR_truncate64
3145 case TARGET_NR_truncate64:
3146 p = lock_user_string(arg1);
3147 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
3148 unlock_user(p, arg1, 0);
3149 break;
3150 #endif
3151 #ifdef TARGET_NR_ftruncate64
3152 case TARGET_NR_ftruncate64:
3153 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
3154 break;
3155 #endif
3156 #ifdef TARGET_NR_stat64
3157 case TARGET_NR_stat64:
3158 p = lock_user_string(arg1);
3159 ret = get_errno(stat(path(p), &st));
3160 unlock_user(p, arg1, 0);
3161 goto do_stat64;
3162 #endif
3163 #ifdef TARGET_NR_lstat64
3164 case TARGET_NR_lstat64:
3165 p = lock_user_string(arg1);
3166 ret = get_errno(lstat(path(p), &st));
3167 unlock_user(p, arg1, 0);
3168 goto do_stat64;
3169 #endif
3170 #ifdef TARGET_NR_fstat64
3171 case TARGET_NR_fstat64:
3172 {
3173 ret = get_errno(fstat(arg1, &st));
3174 do_stat64:
3175 if (!is_error(ret)) {
3176 #ifdef TARGET_ARM
3177 if (((CPUARMState *)cpu_env)->eabi) {
3178 struct target_eabi_stat64 *target_st;
3179 lock_user_struct(target_st, arg2, 1);
3180 memset(target_st, 0, sizeof(struct target_eabi_stat64));
3181 /* put_user is probably wrong. */
3182 put_user(st.st_dev, &target_st->st_dev);
3183 put_user(st.st_ino, &target_st->st_ino);
3184 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3185 put_user(st.st_ino, &target_st->__st_ino);
3186 #endif
3187 put_user(st.st_mode, &target_st->st_mode);
3188 put_user(st.st_nlink, &target_st->st_nlink);
3189 put_user(st.st_uid, &target_st->st_uid);
3190 put_user(st.st_gid, &target_st->st_gid);
3191 put_user(st.st_rdev, &target_st->st_rdev);
3192 /* XXX: better use of kernel struct */
3193 put_user(st.st_size, &target_st->st_size);
3194 put_user(st.st_blksize, &target_st->st_blksize);
3195 put_user(st.st_blocks, &target_st->st_blocks);
3196 put_user(st.st_atime, &target_st->target_st_atime);
3197 put_user(st.st_mtime, &target_st->target_st_mtime);
3198 put_user(st.st_ctime, &target_st->target_st_ctime);
3199 unlock_user_struct(target_st, arg2, 0);
3200 } else
3201 #endif
3202 {
3203 struct target_stat64 *target_st;
3204 lock_user_struct(target_st, arg2, 1);
3205 memset(target_st, 0, sizeof(struct target_stat64));
3206 /* ??? put_user is probably wrong. */
3207 put_user(st.st_dev, &target_st->st_dev);
3208 put_user(st.st_ino, &target_st->st_ino);
3209 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3210 put_user(st.st_ino, &target_st->__st_ino);
3211 #endif
3212 put_user(st.st_mode, &target_st->st_mode);
3213 put_user(st.st_nlink, &target_st->st_nlink);
3214 put_user(st.st_uid, &target_st->st_uid);
3215 put_user(st.st_gid, &target_st->st_gid);
3216 put_user(st.st_rdev, &target_st->st_rdev);
3217 /* XXX: better use of kernel struct */
3218 put_user(st.st_size, &target_st->st_size);
3219 put_user(st.st_blksize, &target_st->st_blksize);
3220 put_user(st.st_blocks, &target_st->st_blocks);
3221 put_user(st.st_atime, &target_st->target_st_atime);
3222 put_user(st.st_mtime, &target_st->target_st_mtime);
3223 put_user(st.st_ctime, &target_st->target_st_ctime);
3224 unlock_user_struct(target_st, arg2, 0);
3225 }
3226 }
3227 }
3228 break;
3229 #endif
3230 #ifdef USE_UID16
3231 case TARGET_NR_lchown:
3232 p = lock_user_string(arg1);
3233 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
3234 unlock_user(p, arg1, 0);
3235 break;
3236 case TARGET_NR_getuid:
3237 ret = get_errno(high2lowuid(getuid()));
3238 break;
3239 case TARGET_NR_getgid:
3240 ret = get_errno(high2lowgid(getgid()));
3241 break;
3242 case TARGET_NR_geteuid:
3243 ret = get_errno(high2lowuid(geteuid()));
3244 break;
3245 case TARGET_NR_getegid:
3246 ret = get_errno(high2lowgid(getegid()));
3247 break;
3248 case TARGET_NR_setreuid:
3249 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
3250 break;
3251 case TARGET_NR_setregid:
3252 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
3253 break;
3254 case TARGET_NR_getgroups:
3255 {
3256 int gidsetsize = arg1;
3257 uint16_t *target_grouplist;
3258 gid_t *grouplist;
3259 int i;
3260
3261 grouplist = alloca(gidsetsize * sizeof(gid_t));
3262 ret = get_errno(getgroups(gidsetsize, grouplist));
3263 if (!is_error(ret)) {
3264 target_grouplist = lock_user(arg2, gidsetsize * 2, 0);
3265 for(i = 0;i < gidsetsize; i++)
3266 target_grouplist[i] = tswap16(grouplist[i]);
3267 unlock_user(target_grouplist, arg2, gidsetsize * 2);
3268 }
3269 }
3270 break;
3271 case TARGET_NR_setgroups:
3272 {
3273 int gidsetsize = arg1;
3274 uint16_t *target_grouplist;
3275 gid_t *grouplist;
3276 int i;
3277
3278 grouplist = alloca(gidsetsize * sizeof(gid_t));
3279 target_grouplist = lock_user(arg2, gidsetsize * 2, 1);
3280 for(i = 0;i < gidsetsize; i++)
3281 grouplist[i] = tswap16(target_grouplist[i]);
3282 unlock_user(target_grouplist, arg2, 0);
3283 ret = get_errno(setgroups(gidsetsize, grouplist));
3284 }
3285 break;
3286 case TARGET_NR_fchown:
3287 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
3288 break;
3289 #ifdef TARGET_NR_setresuid
3290 case TARGET_NR_setresuid:
3291 ret = get_errno(setresuid(low2highuid(arg1),
3292 low2highuid(arg2),
3293 low2highuid(arg3)));
3294 break;
3295 #endif
3296 #ifdef TARGET_NR_getresuid
3297 case TARGET_NR_getresuid:
3298 {
3299 uid_t ruid, euid, suid;
3300 ret = get_errno(getresuid(&ruid, &euid, &suid));
3301 if (!is_error(ret)) {
3302 tput16(arg1, tswap16(high2lowuid(ruid)));
3303 tput16(arg2, tswap16(high2lowuid(euid)));
3304 tput16(arg3, tswap16(high2lowuid(suid)));
3305 }
3306 }
3307 break;
3308 #endif
3309 #ifdef TARGET_NR_getresgid
3310 case TARGET_NR_setresgid:
3311 ret = get_errno(setresgid(low2highgid(arg1),
3312 low2highgid(arg2),
3313 low2highgid(arg3)));
3314 break;
3315 #endif
3316 #ifdef TARGET_NR_getresgid
3317 case TARGET_NR_getresgid:
3318 {
3319 gid_t rgid, egid, sgid;
3320 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3321 if (!is_error(ret)) {
3322 tput16(arg1, tswap16(high2lowgid(rgid)));
3323 tput16(arg2, tswap16(high2lowgid(egid)));
3324 tput16(arg3, tswap16(high2lowgid(sgid)));
3325 }
3326 }
3327 break;
3328 #endif
3329 case TARGET_NR_chown:
3330 p = lock_user_string(arg1);
3331 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
3332 unlock_user(p, arg1, 0);
3333 break;
3334 case TARGET_NR_setuid:
3335 ret = get_errno(setuid(low2highuid(arg1)));
3336 break;
3337 case TARGET_NR_setgid:
3338 ret = get_errno(setgid(low2highgid(arg1)));
3339 break;
3340 case TARGET_NR_setfsuid:
3341 ret = get_errno(setfsuid(arg1));
3342 break;
3343 case TARGET_NR_setfsgid:
3344 ret = get_errno(setfsgid(arg1));
3345 break;
3346 #endif /* USE_UID16 */
3347
3348 #ifdef TARGET_NR_lchown32
3349 case TARGET_NR_lchown32:
3350 p = lock_user_string(arg1);
3351 ret = get_errno(lchown(p, arg2, arg3));
3352 unlock_user(p, arg1, 0);
3353 break;
3354 #endif
3355 #ifdef TARGET_NR_getuid32
3356 case TARGET_NR_getuid32:
3357 ret = get_errno(getuid());
3358 break;
3359 #endif
3360 #ifdef TARGET_NR_getgid32
3361 case TARGET_NR_getgid32:
3362 ret = get_errno(getgid());
3363 break;
3364 #endif
3365 #ifdef TARGET_NR_geteuid32
3366 case TARGET_NR_geteuid32:
3367 ret = get_errno(geteuid());
3368 break;
3369 #endif
3370 #ifdef TARGET_NR_getegid32
3371 case TARGET_NR_getegid32:
3372 ret = get_errno(getegid());
3373 break;
3374 #endif
3375 #ifdef TARGET_NR_setreuid32
3376 case TARGET_NR_setreuid32:
3377 ret = get_errno(setreuid(arg1, arg2));
3378 break;
3379 #endif
3380 #ifdef TARGET_NR_setregid32
3381 case TARGET_NR_setregid32:
3382 ret = get_errno(setregid(arg1, arg2));
3383 break;
3384 #endif
3385 #ifdef TARGET_NR_getgroups32
3386 case TARGET_NR_getgroups32:
3387 {
3388 int gidsetsize = arg1;
3389 uint32_t *target_grouplist;
3390 gid_t *grouplist;
3391 int i;
3392
3393 grouplist = alloca(gidsetsize * sizeof(gid_t));
3394 ret = get_errno(getgroups(gidsetsize, grouplist));
3395 if (!is_error(ret)) {
3396 target_grouplist = lock_user(arg2, gidsetsize * 4, 0);
3397 for(i = 0;i < gidsetsize; i++)
3398 target_grouplist[i] = tswap32(grouplist[i]);
3399 unlock_user(target_grouplist, arg2, gidsetsize * 4);
3400 }
3401 }
3402 break;
3403 #endif
3404 #ifdef TARGET_NR_setgroups32
3405 case TARGET_NR_setgroups32:
3406 {
3407 int gidsetsize = arg1;
3408 uint32_t *target_grouplist;
3409 gid_t *grouplist;
3410 int i;
3411
3412 grouplist = alloca(gidsetsize * sizeof(gid_t));
3413 target_grouplist = lock_user(arg2, gidsetsize * 4, 1);
3414 for(i = 0;i < gidsetsize; i++)
3415 grouplist[i] = tswap32(target_grouplist[i]);
3416 unlock_user(target_grouplist, arg2, 0);
3417 ret = get_errno(setgroups(gidsetsize, grouplist));
3418 }
3419 break;
3420 #endif
3421 #ifdef TARGET_NR_fchown32
3422 case TARGET_NR_fchown32:
3423 ret = get_errno(fchown(arg1, arg2, arg3));
3424 break;
3425 #endif
3426 #ifdef TARGET_NR_setresuid32
3427 case TARGET_NR_setresuid32:
3428 ret = get_errno(setresuid(arg1, arg2, arg3));
3429 break;
3430 #endif
3431 #ifdef TARGET_NR_getresuid32
3432 case TARGET_NR_getresuid32:
3433 {
3434 uid_t ruid, euid, suid;
3435 ret = get_errno(getresuid(&ruid, &euid, &suid));
3436 if (!is_error(ret)) {
3437 tput32(arg1, tswap32(ruid));
3438 tput32(arg2, tswap32(euid));
3439 tput32(arg3, tswap32(suid));
3440 }
3441 }
3442 break;
3443 #endif
3444 #ifdef TARGET_NR_setresgid32
3445 case TARGET_NR_setresgid32:
3446 ret = get_errno(setresgid(arg1, arg2, arg3));
3447 break;
3448 #endif
3449 #ifdef TARGET_NR_getresgid32
3450 case TARGET_NR_getresgid32:
3451 {
3452 gid_t rgid, egid, sgid;
3453 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3454 if (!is_error(ret)) {
3455 tput32(arg1, tswap32(rgid));
3456 tput32(arg2, tswap32(egid));
3457 tput32(arg3, tswap32(sgid));
3458 }
3459 }
3460 break;
3461 #endif
3462 #ifdef TARGET_NR_chown32
3463 case TARGET_NR_chown32:
3464 p = lock_user_string(arg1);
3465 ret = get_errno(chown(p, arg2, arg3));
3466 unlock_user(p, arg1, 0);
3467 break;
3468 #endif
3469 #ifdef TARGET_NR_setuid32
3470 case TARGET_NR_setuid32:
3471 ret = get_errno(setuid(arg1));
3472 break;
3473 #endif
3474 #ifdef TARGET_NR_setgid32
3475 case TARGET_NR_setgid32:
3476 ret = get_errno(setgid(arg1));
3477 break;
3478 #endif
3479 #ifdef TARGET_NR_setfsuid32
3480 case TARGET_NR_setfsuid32:
3481 ret = get_errno(setfsuid(arg1));
3482 break;
3483 #endif
3484 #ifdef TARGET_NR_setfsgid32
3485 case TARGET_NR_setfsgid32:
3486 ret = get_errno(setfsgid(arg1));
3487 break;
3488 #endif
3489
3490 case TARGET_NR_pivot_root:
3491 goto unimplemented;
3492 #ifdef TARGET_NR_mincore
3493 case TARGET_NR_mincore:
3494 goto unimplemented;
3495 #endif
3496 #ifdef TARGET_NR_madvise
3497 case TARGET_NR_madvise:
3498 /* A straight passthrough may not be safe because qemu sometimes
3499 turns private flie-backed mappings into anonymous mappings.
3500 This will break MADV_DONTNEED.
3501 This is a hint, so ignoring and returning success is ok. */
3502 ret = get_errno(0);
3503 break;
3504 #endif
3505 #if TARGET_LONG_BITS == 32
3506 case TARGET_NR_fcntl64:
3507 {
3508 struct flock64 fl;
3509 struct target_flock64 *target_fl;
3510 #ifdef TARGET_ARM
3511 struct target_eabi_flock64 *target_efl;
3512 #endif
3513
3514 switch(arg2) {
3515 case F_GETLK64:
3516 ret = get_errno(fcntl(arg1, arg2, &fl));
3517 if (ret == 0) {
3518 #ifdef TARGET_ARM
3519 if (((CPUARMState *)cpu_env)->eabi) {
3520 lock_user_struct(target_efl, arg3, 0);
3521 target_efl->l_type = tswap16(fl.l_type);
3522 target_efl->l_whence = tswap16(fl.l_whence);
3523 target_efl->l_start = tswap64(fl.l_start);
3524 target_efl->l_len = tswap64(fl.l_len);
3525 target_efl->l_pid = tswapl(fl.l_pid);
3526 unlock_user_struct(target_efl, arg3, 1);
3527 } else
3528 #endif
3529 {
3530 lock_user_struct(target_fl, arg3, 0);
3531 target_fl->l_type = tswap16(fl.l_type);
3532 target_fl->l_whence = tswap16(fl.l_whence);
3533 target_fl->l_start = tswap64(fl.l_start);
3534 target_fl->l_len = tswap64(fl.l_len);
3535 target_fl->l_pid = tswapl(fl.l_pid);
3536 unlock_user_struct(target_fl, arg3, 1);
3537 }
3538 }
3539 break;
3540
3541 case F_SETLK64:
3542 case F_SETLKW64:
3543 #ifdef TARGET_ARM
3544 if (((CPUARMState *)cpu_env)->eabi) {
3545 lock_user_struct(target_efl, arg3, 1);
3546 fl.l_type = tswap16(target_efl->l_type);
3547 fl.l_whence = tswap16(target_efl->l_whence);
3548 fl.l_start = tswap64(target_efl->l_start);
3549 fl.l_len = tswap64(target_efl->l_len);
3550 fl.l_pid = tswapl(target_efl->l_pid);
3551 unlock_user_struct(target_efl, arg3, 0);
3552 } else
3553 #endif
3554 {
3555 lock_user_struct(target_fl, arg3, 1);
3556 fl.l_type = tswap16(target_fl->l_type);
3557 fl.l_whence = tswap16(target_fl->l_whence);
3558 fl.l_start = tswap64(target_fl->l_start);
3559 fl.l_len = tswap64(target_fl->l_len);
3560 fl.l_pid = tswapl(target_fl->l_pid);
3561 unlock_user_struct(target_fl, arg3, 0);
3562 }
3563 ret = get_errno(fcntl(arg1, arg2, &fl));
3564 break;
3565 default:
3566 ret = get_errno(do_fcntl(arg1, arg2, arg3));
3567 break;
3568 }
3569 break;
3570 }
3571 #endif
3572 #ifdef TARGET_NR_security
3573 case TARGET_NR_security:
3574 goto unimplemented;
3575 #endif
3576 #ifdef TARGET_NR_getpagesize
3577 case TARGET_NR_getpagesize:
3578 ret = TARGET_PAGE_SIZE;
3579 break;
3580 #endif
3581 case TARGET_NR_gettid:
3582 ret = get_errno(gettid());
3583 break;
3584 case TARGET_NR_readahead:
3585 goto unimplemented;
3586 #ifdef TARGET_NR_setxattr
3587 case TARGET_NR_setxattr:
3588 case TARGET_NR_lsetxattr:
3589 case TARGET_NR_fsetxattr:
3590 case TARGET_NR_getxattr:
3591 case TARGET_NR_lgetxattr:
3592 case TARGET_NR_fgetxattr:
3593 case TARGET_NR_listxattr:
3594 case TARGET_NR_llistxattr:
3595 case TARGET_NR_flistxattr:
3596 case TARGET_NR_removexattr:
3597 case TARGET_NR_lremovexattr:
3598 case TARGET_NR_fremovexattr:
3599 goto unimplemented_nowarn;
3600 #endif
3601 #ifdef TARGET_NR_set_thread_area
3602 case TARGET_NR_set_thread_area:
3603 case TARGET_NR_get_thread_area:
3604 goto unimplemented_nowarn;
3605 #endif
3606 #ifdef TARGET_NR_getdomainname
3607 case TARGET_NR_getdomainname:
3608 goto unimplemented_nowarn;
3609 #endif
3610 default:
3611 unimplemented:
3612 gemu_log("qemu: Unsupported syscall: %d\n", num);
3613 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_getdomainname)
3614 unimplemented_nowarn:
3615 #endif
3616 ret = -ENOSYS;
3617 break;
3618 }
3619 fail:
3620 #ifdef DEBUG
3621 gemu_log(" = %ld\n", ret);
3622 #endif
3623 return ret;
3624 }
3625