1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <stdlib.h>
21: #include <stdio.h>
22: #include <stdarg.h>
23: #include <string.h>
24: #include <elf.h>
25: #include <endian.h>
26: #include <errno.h>
27: #include <unistd.h>
28: #include <fcntl.h>
29: #include <time.h>
30: #include <sys/types.h>
31: #include <sys/ipc.h>
32: #include <sys/msg.h>
33: #include <sys/wait.h>
34: #include <sys/time.h>
35: #include <sys/stat.h>
36: #include <sys/mount.h>
37: #include <sys/prctl.h>
38: #include <sys/resource.h>
39: #include <sys/mman.h>
40: #include <sys/swap.h>
41: #include <signal.h>
42: #include <sched.h>
43: #include <sys/socket.h>
44: #include <sys/uio.h>
45: #include <sys/poll.h>
46: #include <sys/times.h>
47: #include <sys/shm.h>
48: #include <sys/sem.h>
49: #include <sys/statfs.h>
50: #include <utime.h>
51: #include <sys/sysinfo.h>
52:
53: #include <netinet/ip.h>
54: #include <netinet/tcp.h>
55:
56: #define termios host_termios
57: #define winsize host_winsize
58: #define termio host_termio
59: #define sgttyb host_sgttyb
60: #define tchars host_tchars
61: #define ltchars host_ltchars
62:
63: #include <linux/termios.h>
64: #include <linux/unistd.h>
65: #include <linux/utsname.h>
66: #include <linux/cdrom.h>
67: #include <linux/hdreg.h>
68: #include <linux/soundcard.h>
69: #include <linux/dirent.h>
70: #include <linux/kd.h>
71:
72: #include "qemu.h"
73:
74:
75:
76: #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
77: || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
78:
79: #define USE_UID16
80: #endif
81:
82:
83: #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
84: #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
85:
86:
87: #undef _syscall0
88: #undef _syscall1
89: #undef _syscall2
90: #undef _syscall3
91: #undef _syscall4
92: #undef _syscall5
93: #undef _syscall6
94:
95: #define _syscall0(type,name) \
96: type name (void) \
97: { \
98: return syscall(__NR_##name); \
99: }
100:
101: #define _syscall1(type,name,type1,arg1) \
102: type name (type1 arg1) \
103: { \
104: return syscall(__NR_##name, arg1); \
105: }
106:
107: #define _syscall2(type,name,type1,arg1,type2,arg2) \
108: type name (type1 arg1,type2 arg2) \
109: { \
110: return syscall(__NR_##name, arg1, arg2); \
111: }
112:
113: #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
114: type name (type1 arg1,type2 arg2,type3 arg3) \
115: { \
116: return syscall(__NR_##name, arg1, arg2, arg3); \
117: }
118:
119: #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
120: type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
121: { \
122: return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
123: }
124:
125: #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
126: type5,arg5) \
127: type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
128: { \
129: return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
130: }
131:
132:
133: #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
134: type5,arg5,type6,arg6) \
135: type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
136: { \
137: return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
138: }
139:
140:
141: #define __NR_sys_uname __NR_uname
142: #define __NR_sys_faccessat __NR_faccessat
143: #define __NR_sys_fchmodat __NR_fchmodat
144: #define __NR_sys_fchownat __NR_fchownat
145: #define __NR_sys_getcwd1 __NR_getcwd
146: #define __NR_sys_getdents __NR_getdents
147: #define __NR_sys_getdents64 __NR_getdents64
148: #define __NR_sys_getpriority __NR_getpriority
149: #define __NR_sys_linkat __NR_linkat
150: #define __NR_sys_mkdirat __NR_mkdirat
151: #define __NR_sys_mknodat __NR_mknodat
152: #define __NR_sys_openat __NR_openat
153: #define __NR_sys_readlinkat __NR_readlinkat
154: #define __NR_sys_renameat __NR_renameat
155: #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
156: #define __NR_sys_symlinkat __NR_symlinkat
157: #define __NR_sys_syslog __NR_syslog
158: #define __NR_sys_tgkill __NR_tgkill
159: #define __NR_sys_tkill __NR_tkill
160: #define __NR_sys_unlinkat __NR_unlinkat
161: #define __NR_sys_utimensat __NR_utimensat
162:
163: #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
164: #define __NR__llseek __NR_lseek
165: #endif
166:
167: #ifdef __NR_gettid
168: _syscall0(int, gettid)
169: #else
170:
171:
172: static int gettid(void) {
173: return -ENOSYS;
174: }
175: #endif
176: _syscall1(int,sys_uname,struct new_utsname *,buf)
177: #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
178: _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
179: #endif
180: #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
181: _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
182: mode_t,mode,int,flags)
183: #endif
184: #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
185: _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
186: uid_t,owner,gid_t,group,int,flags)
187: #endif
188: _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
189: _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
190: #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
191: _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
192: #endif
193: _syscall2(int, sys_getpriority, int, which, int, who);
194: _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
195: loff_t *, res, uint, wh);
196: #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
197: _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
198: int,newdirfd,const char *,newpath,int,flags)
199: #endif
200: #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
201: _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
202: #endif
203: #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
204: _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
205: mode_t,mode,dev_t,dev)
206: #endif
207: #if defined(TARGET_NR_openat) && defined(__NR_openat)
208: _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
209: #endif
210: #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
211: _syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
212: char *,buf,size_t,bufsize)
213: #endif
214: #if defined(TARGET_NR_renameat) && defined(__NR_renameat)
215: _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
216: int,newdirfd,const char *,newpath)
217: #endif
218: _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
219: #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
220: _syscall3(int,sys_symlinkat,const char *,oldpath,
221: int,newdirfd,const char *,newpath)
222: #endif
223: _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
224: #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
225: _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
226: #endif
227: #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
228: _syscall2(int,sys_tkill,int,tid,int,sig)
229: #endif
230: #ifdef __NR_exit_group
231: _syscall1(int,exit_group,int,error_code)
232: #endif
233: #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
234: _syscall1(int,set_tid_address,int *,tidptr)
235: #endif
236: #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
237: _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
238: #endif
239: #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
240: _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
241: const struct timespec *,tsp,int,flags)
242: #endif
243:
244: extern int personality(int);
245: extern int flock(int, int);
246: extern int setfsuid(int);
247: extern int setfsgid(int);
248: extern int setresuid(uid_t, uid_t, uid_t);
249: extern int getresuid(uid_t *, uid_t *, uid_t *);
250: extern int setresgid(gid_t, gid_t, gid_t);
251: extern int getresgid(gid_t *, gid_t *, gid_t *);
252: extern int setgroups(int, gid_t *);
253:
254: #define ERRNO_TABLE_SIZE 1200
255:
256:
257:
258: static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
259: };
260:
261:
262:
263:
264:
265: static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
266: [EIDRM] = TARGET_EIDRM,
267: [ECHRNG] = TARGET_ECHRNG,
268: [EL2NSYNC] = TARGET_EL2NSYNC,
269: [EL3HLT] = TARGET_EL3HLT,
270: [EL3RST] = TARGET_EL3RST,
271: [ELNRNG] = TARGET_ELNRNG,
272: [EUNATCH] = TARGET_EUNATCH,
273: [ENOCSI] = TARGET_ENOCSI,
274: [EL2HLT] = TARGET_EL2HLT,
275: [EDEADLK] = TARGET_EDEADLK,
276: [ENOLCK] = TARGET_ENOLCK,
277: [EBADE] = TARGET_EBADE,
278: [EBADR] = TARGET_EBADR,
279: [EXFULL] = TARGET_EXFULL,
280: [ENOANO] = TARGET_ENOANO,
281: [EBADRQC] = TARGET_EBADRQC,
282: [EBADSLT] = TARGET_EBADSLT,
283: [EBFONT] = TARGET_EBFONT,
284: [ENOSTR] = TARGET_ENOSTR,
285: [ENODATA] = TARGET_ENODATA,
286: [ETIME] = TARGET_ETIME,
287: [ENOSR] = TARGET_ENOSR,
288: [ENONET] = TARGET_ENONET,
289: [ENOPKG] = TARGET_ENOPKG,
290: [EREMOTE] = TARGET_EREMOTE,
291: [ENOLINK] = TARGET_ENOLINK,
292: [EADV] = TARGET_EADV,
293: [ESRMNT] = TARGET_ESRMNT,
294: [ECOMM] = TARGET_ECOMM,
295: [EPROTO] = TARGET_EPROTO,
296: [EDOTDOT] = TARGET_EDOTDOT,
297: [EMULTIHOP] = TARGET_EMULTIHOP,
298: [EBADMSG] = TARGET_EBADMSG,
299: [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
300: [EOVERFLOW] = TARGET_EOVERFLOW,
301: [ENOTUNIQ] = TARGET_ENOTUNIQ,
302: [EBADFD] = TARGET_EBADFD,
303: [EREMCHG] = TARGET_EREMCHG,
304: [ELIBACC] = TARGET_ELIBACC,
305: [ELIBBAD] = TARGET_ELIBBAD,
306: [ELIBSCN] = TARGET_ELIBSCN,
307: [ELIBMAX] = TARGET_ELIBMAX,
308: [ELIBEXEC] = TARGET_ELIBEXEC,
309: [EILSEQ] = TARGET_EILSEQ,
310: [ENOSYS] = TARGET_ENOSYS,
311: [ELOOP] = TARGET_ELOOP,
312: [ERESTART] = TARGET_ERESTART,
313: [ESTRPIPE] = TARGET_ESTRPIPE,
314: [ENOTEMPTY] = TARGET_ENOTEMPTY,
315: [EUSERS] = TARGET_EUSERS,
316: [ENOTSOCK] = TARGET_ENOTSOCK,
317: [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
318: [EMSGSIZE] = TARGET_EMSGSIZE,
319: [EPROTOTYPE] = TARGET_EPROTOTYPE,
320: [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
321: [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
322: [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
323: [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
324: [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
325: [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
326: [EADDRINUSE] = TARGET_EADDRINUSE,
327: [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
328: [ENETDOWN] = TARGET_ENETDOWN,
329: [ENETUNREACH] = TARGET_ENETUNREACH,
330: [ENETRESET] = TARGET_ENETRESET,
331: [ECONNABORTED] = TARGET_ECONNABORTED,
332: [ECONNRESET] = TARGET_ECONNRESET,
333: [ENOBUFS] = TARGET_ENOBUFS,
334: [EISCONN] = TARGET_EISCONN,
335: [ENOTCONN] = TARGET_ENOTCONN,
336: [EUCLEAN] = TARGET_EUCLEAN,
337: [ENOTNAM] = TARGET_ENOTNAM,
338: [ENAVAIL] = TARGET_ENAVAIL,
339: [EISNAM] = TARGET_EISNAM,
340: [EREMOTEIO] = TARGET_EREMOTEIO,
341: [ESHUTDOWN] = TARGET_ESHUTDOWN,
342: [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
343: [ETIMEDOUT] = TARGET_ETIMEDOUT,
344: [ECONNREFUSED] = TARGET_ECONNREFUSED,
345: [EHOSTDOWN] = TARGET_EHOSTDOWN,
346: [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
347: [EALREADY] = TARGET_EALREADY,
348: [EINPROGRESS] = TARGET_EINPROGRESS,
349: [ESTALE] = TARGET_ESTALE,
350: [ECANCELED] = TARGET_ECANCELED,
351: [ENOMEDIUM] = TARGET_ENOMEDIUM,
352: [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
353: #ifdef ENOKEY
354: [ENOKEY] = TARGET_ENOKEY,
355: #endif
356: #ifdef EKEYEXPIRED
357: [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
358: #endif
359: #ifdef EKEYREVOKED
360: [EKEYREVOKED] = TARGET_EKEYREVOKED,
361: #endif
362: #ifdef EKEYREJECTED
363: [EKEYREJECTED] = TARGET_EKEYREJECTED,
364: #endif
365: #ifdef EOWNERDEAD
366: [EOWNERDEAD] = TARGET_EOWNERDEAD,
367: #endif
368: #ifdef ENOTRECOVERABLE
369: [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
370: #endif
371: };
372:
373: static inline int host_to_target_errno(int err)
374: {
375: if(host_to_target_errno_table[err])
376: return host_to_target_errno_table[err];
377: return err;
378: }
379:
380: static inline int target_to_host_errno(int err)
381: {
382: if (target_to_host_errno_table[err])
383: return target_to_host_errno_table[err];
384: return err;
385: }
386:
387: static inline abi_long get_errno(abi_long ret)
388: {
389: if (ret == -1)
390: return -host_to_target_errno(errno);
391: else
392: return ret;
393: }
394:
395: static inline int is_error(abi_long ret)
396: {
397: return (abi_ulong)ret >= (abi_ulong)(-4096);
398: }
399:
400: char *target_strerror(int err)
401: {
402: return strerror(target_to_host_errno(err));
403: }
404:
405: static abi_ulong target_brk;
406: static abi_ulong target_original_brk;
407:
408: void target_set_brk(abi_ulong new_brk)
409: {
410: target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
411: }
412:
413:
414: abi_long do_brk(abi_ulong new_brk)
415: {
416: abi_ulong brk_page;
417: abi_long mapped_addr;
418: int new_alloc_size;
419:
420: if (!new_brk)
421: return target_brk;
422: if (new_brk < target_original_brk)
423: return -TARGET_ENOMEM;
424:
425: brk_page = HOST_PAGE_ALIGN(target_brk);
426:
427:
428: if (new_brk < brk_page) {
429: target_brk = new_brk;
430: return target_brk;
431: }
432:
433:
434: new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
435: mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
436: PROT_READ|PROT_WRITE,
437: MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
438: if (is_error(mapped_addr)) {
439: return mapped_addr;
440: } else {
441: target_brk = new_brk;
442: return target_brk;
443: }
444: }
445:
446: static inline abi_long copy_from_user_fdset(fd_set *fds,
447: abi_ulong target_fds_addr,
448: int n)
449: {
450: int i, nw, j, k;
451: abi_ulong b, *target_fds;
452:
453: nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
454: if (!(target_fds = lock_user(VERIFY_READ,
455: target_fds_addr,
456: sizeof(abi_ulong) * nw,
457: 1)))
458: return -TARGET_EFAULT;
459:
460: FD_ZERO(fds);
461: k = 0;
462: for (i = 0; i < nw; i++) {
463:
464: __get_user(b, &target_fds[i]);
465: for (j = 0; j < TARGET_ABI_BITS; j++) {
466:
467: if ((b >> j) & 1)
468: FD_SET(k, fds);
469: k++;
470: }
471: }
472:
473: unlock_user(target_fds, target_fds_addr, 0);
474:
475: return 0;
476: }
477:
478: static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
479: const fd_set *fds,
480: int n)
481: {
482: int i, nw, j, k;
483: abi_long v;
484: abi_ulong *target_fds;
485: