|
|
1.1 root 1: /*
2: * BSD syscalls
3: *
4: * Copyright (c) 2003 - 2008 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., 51 Franklin Street - Fifth Floor, Boston,
19: * MA 02110-1301, USA.
20: */
21: #include <stdlib.h>
22: #include <stdio.h>
23: #include <stdint.h>
24: #include <stdarg.h>
25: #include <string.h>
26: #include <errno.h>
27: #include <unistd.h>
28: #include <fcntl.h>
29: #include <time.h>
30: #include <limits.h>
31: #include <sys/types.h>
32: #include <sys/mman.h>
33: #include <sys/syscall.h>
34: #include <signal.h>
35: #include <utime.h>
36:
37: #include "qemu.h"
38: #include "qemu-common.h"
39:
40: //#define DEBUG
41:
42: static abi_ulong target_brk;
43: static abi_ulong target_original_brk;
44:
45: #define get_errno(x) (x)
46: #define target_to_host_bitmask(x, tbl) (x)
47:
48: void target_set_brk(abi_ulong new_brk)
49: {
50: target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
51: }
52:
53: /* do_syscall() should always have a single exit point at the end so
54: that actions, such as logging of syscall results, can be performed.
55: All errnos that do_syscall() returns must be -TARGET_<errcode>. */
56: abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
57: abi_long arg2, abi_long arg3, abi_long arg4,
58: abi_long arg5, abi_long arg6)
59: {
60: abi_long ret;
61: void *p;
62:
63: #ifdef DEBUG
64: gemu_log("freebsd syscall %d\n", num);
65: #endif
66: if(do_strace)
67: print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
68:
69: switch(num) {
70: case TARGET_FREEBSD_NR_exit:
71: #ifdef HAVE_GPROF
72: _mcleanup();
73: #endif
74: gdb_exit(cpu_env, arg1);
75: /* XXX: should free thread stack and CPU env */
76: _exit(arg1);
77: ret = 0; /* avoid warning */
78: break;
79: case TARGET_FREEBSD_NR_read:
80: if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
81: goto efault;
82: ret = get_errno(read(arg1, p, arg3));
83: unlock_user(p, arg2, ret);
84: break;
85: case TARGET_FREEBSD_NR_write:
86: if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
87: goto efault;
88: ret = get_errno(write(arg1, p, arg3));
89: unlock_user(p, arg2, 0);
90: break;
91: case TARGET_FREEBSD_NR_open:
92: if (!(p = lock_user_string(arg1)))
93: goto efault;
94: ret = get_errno(open(path(p),
95: target_to_host_bitmask(arg2, fcntl_flags_tbl),
96: arg3));
97: unlock_user(p, arg1, 0);
98: break;
99: case TARGET_FREEBSD_NR_mmap:
100: ret = get_errno(target_mmap(arg1, arg2, arg3,
101: target_to_host_bitmask(arg4, mmap_flags_tbl),
102: arg5,
103: arg6));
104: break;
105: case TARGET_FREEBSD_NR_mprotect:
106: ret = get_errno(target_mprotect(arg1, arg2, arg3));
107: break;
108: case TARGET_FREEBSD_NR_syscall:
109: case TARGET_FREEBSD_NR___syscall:
110: ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
111: break;
112: default:
113: ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
114: break;
115: }
116: fail:
117: #ifdef DEBUG
118: gemu_log(" = %ld\n", ret);
119: #endif
120: if (do_strace)
121: print_freebsd_syscall_ret(num, ret);
122: return ret;
123: efault:
124: ret = -TARGET_EFAULT;
125: goto fail;
126: }
127:
128: abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
129: abi_long arg2, abi_long arg3, abi_long arg4,
130: abi_long arg5, abi_long arg6)
131: {
132: abi_long ret;
133: void *p;
134:
135: #ifdef DEBUG
136: gemu_log("netbsd syscall %d\n", num);
137: #endif
138: if(do_strace)
139: print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
140:
141: switch(num) {
142: case TARGET_NETBSD_NR_exit:
143: #ifdef HAVE_GPROF
144: _mcleanup();
145: #endif
146: gdb_exit(cpu_env, arg1);
147: /* XXX: should free thread stack and CPU env */
148: _exit(arg1);
149: ret = 0; /* avoid warning */
150: break;
151: case TARGET_NETBSD_NR_read:
152: if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
153: goto efault;
154: ret = get_errno(read(arg1, p, arg3));
155: unlock_user(p, arg2, ret);
156: break;
157: case TARGET_NETBSD_NR_write:
158: if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
159: goto efault;
160: ret = get_errno(write(arg1, p, arg3));
161: unlock_user(p, arg2, 0);
162: break;
163: case TARGET_NETBSD_NR_open:
164: if (!(p = lock_user_string(arg1)))
165: goto efault;
166: ret = get_errno(open(path(p),
167: target_to_host_bitmask(arg2, fcntl_flags_tbl),
168: arg3));
169: unlock_user(p, arg1, 0);
170: break;
171: case TARGET_NETBSD_NR_mmap:
172: ret = get_errno(target_mmap(arg1, arg2, arg3,
173: target_to_host_bitmask(arg4, mmap_flags_tbl),
174: arg5,
175: arg6));
176: break;
177: case TARGET_NETBSD_NR_mprotect:
178: ret = get_errno(target_mprotect(arg1, arg2, arg3));
179: break;
180: case TARGET_NETBSD_NR_syscall:
181: case TARGET_NETBSD_NR___syscall:
182: ret = do_netbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
183: break;
184: default:
185: ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
186: break;
187: }
188: fail:
189: #ifdef DEBUG
190: gemu_log(" = %ld\n", ret);
191: #endif
192: if (do_strace)
193: print_netbsd_syscall_ret(num, ret);
194: return ret;
195: efault:
196: ret = -TARGET_EFAULT;
197: goto fail;
198: }
199:
200: abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
201: abi_long arg2, abi_long arg3, abi_long arg4,
202: abi_long arg5, abi_long arg6)
203: {
204: abi_long ret;
205: void *p;
206:
207: #ifdef DEBUG
208: gemu_log("openbsd syscall %d\n", num);
209: #endif
210: if(do_strace)
211: print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
212:
213: switch(num) {
214: case TARGET_OPENBSD_NR_exit:
215: #ifdef HAVE_GPROF
216: _mcleanup();
217: #endif
218: gdb_exit(cpu_env, arg1);
219: /* XXX: should free thread stack and CPU env */
220: _exit(arg1);
221: ret = 0; /* avoid warning */
222: break;
223: case TARGET_OPENBSD_NR_read:
224: if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
225: goto efault;
226: ret = get_errno(read(arg1, p, arg3));
227: unlock_user(p, arg2, ret);
228: break;
229: case TARGET_OPENBSD_NR_write:
230: if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
231: goto efault;
232: ret = get_errno(write(arg1, p, arg3));
233: unlock_user(p, arg2, 0);
234: break;
235: case TARGET_OPENBSD_NR_open:
236: if (!(p = lock_user_string(arg1)))
237: goto efault;
238: ret = get_errno(open(path(p),
239: target_to_host_bitmask(arg2, fcntl_flags_tbl),
240: arg3));
241: unlock_user(p, arg1, 0);
242: break;
243: case TARGET_OPENBSD_NR_mmap:
244: ret = get_errno(target_mmap(arg1, arg2, arg3,
245: target_to_host_bitmask(arg4, mmap_flags_tbl),
246: arg5,
247: arg6));
248: break;
249: case TARGET_OPENBSD_NR_mprotect:
250: ret = get_errno(target_mprotect(arg1, arg2, arg3));
251: break;
252: case TARGET_OPENBSD_NR_syscall:
253: case TARGET_OPENBSD_NR___syscall:
254: ret = do_openbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
255: break;
256: default:
257: ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
258: break;
259: }
260: fail:
261: #ifdef DEBUG
262: gemu_log(" = %ld\n", ret);
263: #endif
264: if (do_strace)
265: print_openbsd_syscall_ret(num, ret);
266: return ret;
267: efault:
268: ret = -TARGET_EFAULT;
269: goto fail;
270: }
271:
272: void syscall_init(void)
273: {
274: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.