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