symbian-qemu-0.9.1-12/qemu-symbian-svp/bsd-user/strace.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #include <stdio.h>
       
     2 #include <errno.h>
       
     3 #include <sys/select.h>
       
     4 #include <sys/types.h>
       
     5 #include <unistd.h>
       
     6 #include <sys/syscall.h>
       
     7 #include "qemu.h"
       
     8 
       
     9 int do_strace=0;
       
    10 
       
    11 struct syscallname {
       
    12     int nr;
       
    13     const char *name;
       
    14     const char *format;
       
    15     void (*call)(const struct syscallname *,
       
    16                  abi_long, abi_long, abi_long,
       
    17                  abi_long, abi_long, abi_long);
       
    18     void (*result)(const struct syscallname *, abi_long);
       
    19 };
       
    20 
       
    21 /*
       
    22  * Utility functions
       
    23  */
       
    24 
       
    25 static void
       
    26 print_execve(const struct syscallname *name,
       
    27              abi_long arg1, abi_long arg2, abi_long arg3,
       
    28              abi_long arg4, abi_long arg5, abi_long arg6)
       
    29 {
       
    30     abi_ulong arg_ptr_addr;
       
    31     char *s;
       
    32 
       
    33     if (!(s = lock_user_string(arg1)))
       
    34         return;
       
    35     gemu_log("%s(\"%s\",{", name->name, s);
       
    36     unlock_user(s, arg1, 0);
       
    37 
       
    38     for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
       
    39         abi_ulong *arg_ptr, arg_addr, s_addr;
       
    40 
       
    41         arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
       
    42         if (!arg_ptr)
       
    43             return;
       
    44         arg_addr = tswapl(*arg_ptr);
       
    45         unlock_user(arg_ptr, arg_ptr_addr, 0);
       
    46         if (!arg_addr)
       
    47             break;
       
    48         if ((s = lock_user_string(arg_addr))) {
       
    49             gemu_log("\"%s\",", s);
       
    50             unlock_user(s, s_addr, 0);
       
    51         }
       
    52     }
       
    53 
       
    54     gemu_log("NULL})");
       
    55 }
       
    56 
       
    57 /*
       
    58  * Variants for the return value output function
       
    59  */
       
    60 
       
    61 static void
       
    62 print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
       
    63 {
       
    64 if( ret == -1 ) {
       
    65         gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno));
       
    66     } else {
       
    67         gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
       
    68     }
       
    69 }
       
    70 
       
    71 #if 0 /* currently unused */
       
    72 static void
       
    73 print_syscall_ret_raw(struct syscallname *name, abi_long ret)
       
    74 {
       
    75         gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
       
    76 }
       
    77 #endif
       
    78 
       
    79 /*
       
    80  * An array of all of the syscalls we know about
       
    81  */
       
    82 
       
    83 static const struct syscallname freebsd_scnames[] = {
       
    84 #include "freebsd/strace.list"
       
    85 };
       
    86 static const struct syscallname netbsd_scnames[] = {
       
    87 #include "netbsd/strace.list"
       
    88 };
       
    89 static const struct syscallname openbsd_scnames[] = {
       
    90 #include "openbsd/strace.list"
       
    91 };
       
    92 
       
    93 static void
       
    94 print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
       
    95               abi_long arg1, abi_long arg2, abi_long arg3,
       
    96               abi_long arg4, abi_long arg5, abi_long arg6)
       
    97 {
       
    98     unsigned int i;
       
    99     const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
       
   100         TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
       
   101         TARGET_ABI_FMT_ld ")";
       
   102 
       
   103     gemu_log("%d ", getpid() );
       
   104 
       
   105     for (i = 0; i < nscnames; i++)
       
   106         if (scnames[i].nr == num) {
       
   107             if (scnames[i].call != NULL) {
       
   108                 scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5,
       
   109                                 arg6);
       
   110             } else {
       
   111                 /* XXX: this format system is broken because it uses
       
   112                    host types and host pointers for strings */
       
   113                 if (scnames[i].format != NULL)
       
   114                     format = scnames[i].format;
       
   115                 gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4,
       
   116                          arg5, arg6);
       
   117             }
       
   118             return;
       
   119         }
       
   120     gemu_log("Unknown syscall %d\n", num);
       
   121 }
       
   122 
       
   123 static void
       
   124 print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
       
   125                   unsigned int nscnames)
       
   126 {
       
   127     unsigned int i;
       
   128 
       
   129     for (i = 0; i < nscnames; i++)
       
   130         if (scnames[i].nr == num) {
       
   131             if (scnames[i].result != NULL) {
       
   132                 scnames[i].result(&scnames[i], ret);
       
   133             } else {
       
   134                 if( ret < 0 ) {
       
   135                     gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
       
   136                              strerror(-ret));
       
   137                 } else {
       
   138                     gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
       
   139                 }
       
   140             }
       
   141             break;
       
   142         }
       
   143 }
       
   144 
       
   145 /*
       
   146  * The public interface to this module.
       
   147  */
       
   148 void
       
   149 print_freebsd_syscall(int num,
       
   150                       abi_long arg1, abi_long arg2, abi_long arg3,
       
   151                       abi_long arg4, abi_long arg5, abi_long arg6)
       
   152 {
       
   153     print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames),
       
   154                   arg1, arg2, arg3, arg4, arg5, arg6);
       
   155 }
       
   156 
       
   157 void
       
   158 print_freebsd_syscall_ret(int num, abi_long ret)
       
   159 {
       
   160     print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
       
   161 }
       
   162 
       
   163 void
       
   164 print_netbsd_syscall(int num,
       
   165                       abi_long arg1, abi_long arg2, abi_long arg3,
       
   166                       abi_long arg4, abi_long arg5, abi_long arg6)
       
   167 {
       
   168     print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames),
       
   169                   arg1, arg2, arg3, arg4, arg5, arg6);
       
   170 }
       
   171 
       
   172 void
       
   173 print_netbsd_syscall_ret(int num, abi_long ret)
       
   174 {
       
   175     print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
       
   176 }
       
   177 
       
   178 void
       
   179 print_openbsd_syscall(int num,
       
   180                       abi_long arg1, abi_long arg2, abi_long arg3,
       
   181                       abi_long arg4, abi_long arg5, abi_long arg6)
       
   182 {
       
   183     print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames),
       
   184                   arg1, arg2, arg3, arg4, arg5, arg6);
       
   185 }
       
   186 
       
   187 void
       
   188 print_openbsd_syscall_ret(int num, abi_long ret)
       
   189 {
       
   190     print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
       
   191 }