|
|
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.