Annotation of qemu/bsd-user/strace.c, revision 1.1

1.1     ! root        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