Annotation of qemu/linux-user/strace.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <errno.h>
                      3: #include <sys/ipc.h>
                      4: #include <sys/msg.h>
                      5: #include <sys/sem.h>
                      6: #include <sys/shm.h>
                      7: #include <sys/select.h>
                      8: #include <sys/types.h>
                      9: #include <unistd.h>
                     10: #include "qemu.h"
                     11: 
                     12: int do_strace=0;
                     13: 
                     14: struct syscallname {
                     15:     int nr;
                     16:     char *name;
                     17:     char *format;
                     18:     void (*call)(struct syscallname *,
                     19:                  abi_long, abi_long, abi_long,
                     20:                  abi_long, abi_long, abi_long);
                     21:     void (*result)(struct syscallname *, abi_long);
                     22: };
                     23: 
                     24: /*
                     25:  * Utility functions
                     26:  */
                     27: static void
                     28: print_ipc_cmd(int cmd)
                     29: {
                     30: #define output_cmd(val) \
                     31: if( cmd == val ) { \
                     32:     gemu_log(#val); \
                     33:     return; \
                     34: }
                     35: 
                     36:     cmd &= 0xff;
                     37: 
                     38:     /* General IPC commands */
                     39:     output_cmd( IPC_RMID );
                     40:     output_cmd( IPC_SET );
                     41:     output_cmd( IPC_STAT );
                     42:     output_cmd( IPC_INFO );
                     43:     /* msgctl() commands */
                     44:     #ifdef __USER_MISC
                     45:     output_cmd( MSG_STAT );
                     46:     output_cmd( MSG_INFO );
                     47:     #endif
                     48:     /* shmctl() commands */
                     49:     output_cmd( SHM_LOCK );
                     50:     output_cmd( SHM_UNLOCK );
                     51:     output_cmd( SHM_STAT );
                     52:     output_cmd( SHM_INFO );
                     53:     /* semctl() commands */
                     54:     output_cmd( GETPID );
                     55:     output_cmd( GETVAL );
                     56:     output_cmd( GETALL );
                     57:     output_cmd( GETNCNT );
                     58:     output_cmd( GETZCNT );
                     59:     output_cmd( SETVAL );
                     60:     output_cmd( SETALL );
                     61:     output_cmd( SEM_STAT );
                     62:     output_cmd( SEM_INFO );
                     63:     output_cmd( IPC_RMID );
                     64:     output_cmd( IPC_RMID );
                     65:     output_cmd( IPC_RMID );
                     66:     output_cmd( IPC_RMID );
                     67:     output_cmd( IPC_RMID );
                     68:     output_cmd( IPC_RMID );
                     69:     output_cmd( IPC_RMID );
                     70:     output_cmd( IPC_RMID );
                     71:     output_cmd( IPC_RMID );
                     72: 
                     73:     /* Some value we don't recognize */
                     74:     gemu_log("%d",cmd);
                     75: }
                     76: 
                     77: #ifdef TARGET_NR__newselect
                     78: static void
                     79: print_fdset(int n, abi_ulong target_fds_addr)
                     80: {
                     81:     int i;
                     82: 
                     83:     gemu_log("[");
                     84:     if( target_fds_addr ) {
                     85:         abi_long *target_fds;
                     86: 
                     87:         target_fds = lock_user(VERIFY_READ,
                     88:                                target_fds_addr,
                     89:                                sizeof(*target_fds)*(n / TARGET_ABI_BITS + 1),
                     90:                                1);
                     91: 
                     92:         if (!target_fds)
                     93:             return;
                     94: 
                     95:         for (i=n; i>=0; i--) {
                     96:             if ((tswapl(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1)
                     97:                 gemu_log("%d,", i );
                     98:             }
                     99:         unlock_user(target_fds, target_fds_addr, 0);
                    100:     }
                    101:     gemu_log("]");
                    102: }
                    103: 
                    104: static void
                    105: print_timeval(abi_ulong tv_addr)
                    106: {
                    107:     if( tv_addr ) {
                    108:         struct target_timeval *tv;
                    109: 
                    110:         tv = lock_user(VERIFY_READ, tv_addr, sizeof(*tv), 1);
                    111:         if (!tv)
                    112:             return;
                    113:         gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}",
                    114:                 tv->tv_sec, tv->tv_usec);
                    115:         unlock_user(tv, tv_addr, 0);
                    116:     } else
                    117:         gemu_log("NULL");
                    118: }
                    119: #endif
                    120: 
                    121: /*
                    122:  * Sysycall specific output functions
                    123:  */
                    124: 
                    125: /* select */
                    126: #ifdef TARGET_NR__newselect
                    127: static long newselect_arg1 = 0;
                    128: static long newselect_arg2 = 0;
                    129: static long newselect_arg3 = 0;
                    130: static long newselect_arg4 = 0;
                    131: static long newselect_arg5 = 0;
                    132: 
                    133: static void
                    134: print_newselect(struct syscallname *name,
                    135:                 abi_long arg1, abi_long arg2, abi_long arg3,
                    136:                 abi_long arg4, abi_long arg5, abi_long arg6)
                    137: {
                    138:     gemu_log("%s(" TARGET_ABI_FMT_ld ",", name->name, arg1);
                    139:     print_fdset(arg1, arg2);
                    140:     gemu_log(",");
                    141:     print_fdset(arg1, arg3);
                    142:     gemu_log(",");
                    143:     print_fdset(arg1, arg4);
                    144:     gemu_log(",");
                    145:     print_timeval(arg5);
                    146:     gemu_log(")");
                    147: 
                    148:     /* save for use in the return output function below */
                    149:     newselect_arg1=arg1;
                    150:     newselect_arg2=arg2;
                    151:     newselect_arg3=arg3;
                    152:     newselect_arg4=arg4;
                    153:     newselect_arg5=arg5;
                    154: }
                    155: #endif
                    156: 
                    157: static void
                    158: print_semctl(struct syscallname *name,
                    159:              abi_long arg1, abi_long arg2, abi_long arg3,
                    160:              abi_long arg4, abi_long arg5, abi_long arg6)
                    161: {
                    162:     gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", name->name, arg1, arg2);
                    163:     print_ipc_cmd(arg3);
                    164:     gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
                    165: }
                    166: 
                    167: static void
                    168: print_execve(struct syscallname *name,
                    169:              abi_long arg1, abi_long arg2, abi_long arg3,
                    170:              abi_long arg4, abi_long arg5, abi_long arg6)
                    171: {
                    172:     abi_ulong arg_ptr_addr;
                    173:     char *s;
                    174: 
                    175:     if (!(s = lock_user_string(arg1)))
                    176:         return;
                    177:     gemu_log("%s(\"%s\",{", name->name, s);
                    178:     unlock_user(s, arg1, 0);
                    179: 
                    180:     for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
                    181:         abi_ulong *arg_ptr, arg_addr, s_addr;
                    182: 
                    183:        arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
                    184:         if (!arg_ptr)
                    185:             return;
                    186:        arg_addr = tswapl(*arg_ptr);
                    187:        unlock_user(arg_ptr, arg_ptr_addr, 0);
                    188:         if (!arg_addr)
                    189:             break;
                    190:         if ((s = lock_user_string(arg_addr))) {
                    191:             gemu_log("\"%s\",", s);
                    192:             unlock_user(s, s_addr, 0);
                    193:         }
                    194:     }
                    195: 
                    196:     gemu_log("NULL})");
                    197: }
                    198: 
                    199: #ifdef TARGET_NR_ipc
                    200: static void
                    201: print_ipc(struct syscallname *name,
                    202:           abi_long arg1, abi_long arg2, abi_long arg3,
                    203:           abi_long arg4, abi_long arg5, abi_long arg6)
                    204: {
                    205:     switch(arg1) {
                    206:     case IPCOP_semctl:
                    207:         name->name = "semctl";
                    208:         print_semctl(name,arg2,arg3,arg4,arg5,arg6,0);
                    209:         break;
                    210:     default:
                    211:         gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")",
                    212:                  name->name, arg1, arg2, arg3, arg4);
                    213:     }
                    214: }
                    215: #endif
                    216: 
                    217: /*
                    218:  * Variants for the return value output function
                    219:  */
                    220: 
                    221: static void
                    222: print_syscall_ret_addr(struct syscallname *name, abi_long ret)
                    223: {
                    224: if( ret == -1 ) {
                    225:         gemu_log(" = -1 errno=%d (%s)\n", errno, target_strerror(errno));
                    226:     } else {
                    227:         gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
                    228:     }
                    229: }
                    230: 
                    231: #if 0 /* currently unused */
                    232: static void
                    233: print_syscall_ret_raw(struct syscallname *name, abi_long ret)
                    234: {
                    235:         gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
                    236: }
                    237: #endif
                    238: 
                    239: #ifdef TARGET_NR__newselect
                    240: static void
                    241: print_syscall_ret_newselect(struct syscallname *name, abi_long ret)
                    242: {
                    243:     gemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
                    244:     print_fdset(newselect_arg1,newselect_arg2);
                    245:     gemu_log(",");
                    246:     print_fdset(newselect_arg1,newselect_arg3);
                    247:     gemu_log(",");
                    248:     print_fdset(newselect_arg1,newselect_arg4);
                    249:     gemu_log(",");
                    250:     print_timeval(newselect_arg5);
                    251:     gemu_log(")\n");
                    252: }
                    253: #endif
                    254: 
                    255: /*
                    256:  * An array of all of the syscalls we know about
                    257:  */
                    258: 
                    259: static struct syscallname scnames[] = {
                    260: #include "strace.list"
                    261: };
                    262: 
                    263: static int nsyscalls = sizeof(scnames)/sizeof(struct syscallname);
                    264: 
                    265: /*
                    266:  * The public interface to this module.
                    267:  */
                    268: void
                    269: print_syscall(int num,
                    270:               abi_long arg1, abi_long arg2, abi_long arg3,
                    271:               abi_long arg4, abi_long arg5, abi_long arg6)
                    272: {
                    273:     int i;
                    274:     char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")";
                    275: 
                    276:     gemu_log("%d ", getpid() );
                    277: 
                    278:     for(i=0;i<nsyscalls;i++)
                    279:         if( scnames[i].nr == num ) {
                    280:             if( scnames[i].call != NULL ) {
                    281:                 scnames[i].call(&scnames[i],arg1,arg2,arg3,arg4,arg5,arg6);
                    282:             } else {
                    283:                 /* XXX: this format system is broken because it uses
                    284:                    host types and host pointers for strings */
                    285:                 if( scnames[i].format != NULL )
                    286:                     format = scnames[i].format;
                    287:                 gemu_log(format,scnames[i].name, arg1,arg2,arg3,arg4,arg5,arg6);
                    288:             }
                    289:             break;
                    290:         }
                    291: }
                    292: 
                    293: 
                    294: void
                    295: print_syscall_ret(int num, abi_long ret)
                    296: {
                    297:     int i;
                    298: 
                    299:     for(i=0;i<nsyscalls;i++)
                    300:         if( scnames[i].nr == num ) {
                    301:             if( scnames[i].result != NULL ) {
                    302:                 scnames[i].result(&scnames[i],ret);
                    303:             } else {
                    304:                 if( ret < 0 ) {
                    305:                     gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, target_strerror(-ret));
                    306:                 } else {
                    307:                     gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
                    308:                 }
                    309:             }
                    310:             break;
                    311:         }
                    312: }
                    313: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.