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