File:  [Qemu by Fabrice Bellard] / qemu / bsd-user / strace.c
Revision 1.1: download - view: text, annotated - select for diffs
Tue Apr 24 16:55:56 2018 UTC (3 years, 7 months ago) by root
CVS tags: MAIN, HEAD
Initial revision

    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: }

unix.superglobalmegacorp.com