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

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)) {
1.1.1.2 ! root       39:         abi_ulong *arg_ptr, arg_addr;
1.1       root       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);
1.1.1.2 ! root       50:             unlock_user(s, arg_addr, 0);
1.1       root       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