Annotation of qemu/linux-user/strace.c, revision 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.