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; 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, arg_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 } 192