|
|
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>
1.1.1.3 root 9: #include <sys/mount.h>
10: #include <sys/mman.h>
1.1 root 11: #include <unistd.h>
12: #include "qemu.h"
13:
14: int do_strace=0;
15:
16: struct syscallname {
17: int nr;
1.1.1.2 root 18: const char *name;
19: const char *format;
20: void (*call)(const struct syscallname *,
1.1 root 21: abi_long, abi_long, abi_long,
22: abi_long, abi_long, abi_long);
1.1.1.2 root 23: void (*result)(const struct syscallname *, abi_long);
1.1 root 24: };
25:
1.1.1.3 root 26: #ifdef __GNUC__
27: /*
28: * It is possible that target doesn't have syscall that uses
29: * following flags but we don't want the compiler to warn
30: * us about them being unused. Same applies to utility print
31: * functions. It is ok to keep them while not used.
32: */
33: #define UNUSED __attribute__ ((unused))
34: #else
35: #define UNUSED
36: #endif
37:
38: /*
39: * Structure used to translate flag values into strings. This is
40: * similar that is in the actual strace tool.
41: */
42: struct flags {
43: abi_long f_value; /* flag */
44: const char *f_string; /* stringified flag */
45: };
46:
47: /* common flags for all architectures */
48: #define FLAG_GENERIC(name) { name, #name }
49: /* target specific flags (syscall_defs.h has TARGET_<flag>) */
50: #define FLAG_TARGET(name) { TARGET_ ## name, #name }
51: /* end of flags array */
52: #define FLAG_END { 0, NULL }
53:
54: UNUSED static const char *get_comma(int);
55: UNUSED static void print_pointer(abi_long, int);
56: UNUSED static void print_flags(const struct flags *, abi_long, int);
57: UNUSED static void print_at_dirfd(abi_long, int);
58: UNUSED static void print_file_mode(abi_long, int);
59: UNUSED static void print_open_flags(abi_long, int);
60: UNUSED static void print_syscall_prologue(const struct syscallname *);
61: UNUSED static void print_syscall_epilogue(const struct syscallname *);
62: UNUSED static void print_string(abi_long, int);
63: UNUSED static void print_raw_param(const char *, abi_long, int);
64: UNUSED static void print_timeval(abi_ulong, int);
65: UNUSED static void print_number(abi_long, int);
66:
1.1 root 67: /*
68: * Utility functions
69: */
70: static void
71: print_ipc_cmd(int cmd)
72: {
73: #define output_cmd(val) \
74: if( cmd == val ) { \
75: gemu_log(#val); \
76: return; \
77: }
78:
79: cmd &= 0xff;
80:
81: /* General IPC commands */
82: output_cmd( IPC_RMID );
83: output_cmd( IPC_SET );
84: output_cmd( IPC_STAT );
85: output_cmd( IPC_INFO );
86: /* msgctl() commands */
87: #ifdef __USER_MISC
88: output_cmd( MSG_STAT );
89: output_cmd( MSG_INFO );
90: #endif
91: /* shmctl() commands */
92: output_cmd( SHM_LOCK );
93: output_cmd( SHM_UNLOCK );
94: output_cmd( SHM_STAT );
95: output_cmd( SHM_INFO );
96: /* semctl() commands */
97: output_cmd( GETPID );
98: output_cmd( GETVAL );
99: output_cmd( GETALL );
100: output_cmd( GETNCNT );
101: output_cmd( GETZCNT );
102: output_cmd( SETVAL );
103: output_cmd( SETALL );
104: output_cmd( SEM_STAT );
105: output_cmd( SEM_INFO );
106: output_cmd( IPC_RMID );
107: output_cmd( IPC_RMID );
108: output_cmd( IPC_RMID );
109: output_cmd( IPC_RMID );
110: output_cmd( IPC_RMID );
111: output_cmd( IPC_RMID );
112: output_cmd( IPC_RMID );
113: output_cmd( IPC_RMID );
114: output_cmd( IPC_RMID );
115:
116: /* Some value we don't recognize */
117: gemu_log("%d",cmd);
118: }
119:
120: #ifdef TARGET_NR__newselect
121: static void
122: print_fdset(int n, abi_ulong target_fds_addr)
123: {
124: int i;
125:
126: gemu_log("[");
127: if( target_fds_addr ) {
128: abi_long *target_fds;
129:
130: target_fds = lock_user(VERIFY_READ,
131: target_fds_addr,
132: sizeof(*target_fds)*(n / TARGET_ABI_BITS + 1),
133: 1);
134:
135: if (!target_fds)
136: return;
137:
138: for (i=n; i>=0; i--) {
139: if ((tswapl(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1)
140: gemu_log("%d,", i );
141: }
142: unlock_user(target_fds, target_fds_addr, 0);
143: }
144: gemu_log("]");
145: }
146: #endif
147:
148: /*
149: * Sysycall specific output functions
150: */
151:
152: /* select */
153: #ifdef TARGET_NR__newselect
154: static long newselect_arg1 = 0;
155: static long newselect_arg2 = 0;
156: static long newselect_arg3 = 0;
157: static long newselect_arg4 = 0;
158: static long newselect_arg5 = 0;
159:
160: static void
1.1.1.2 root 161: print_newselect(const struct syscallname *name,
1.1 root 162: abi_long arg1, abi_long arg2, abi_long arg3,
163: abi_long arg4, abi_long arg5, abi_long arg6)
164: {
165: gemu_log("%s(" TARGET_ABI_FMT_ld ",", name->name, arg1);
166: print_fdset(arg1, arg2);
167: gemu_log(",");
168: print_fdset(arg1, arg3);
169: gemu_log(",");
170: print_fdset(arg1, arg4);
171: gemu_log(",");
1.1.1.3 root 172: print_timeval(arg5, 1);
1.1 root 173: gemu_log(")");
174:
175: /* save for use in the return output function below */
176: newselect_arg1=arg1;
177: newselect_arg2=arg2;
178: newselect_arg3=arg3;
179: newselect_arg4=arg4;
180: newselect_arg5=arg5;
181: }
182: #endif
183:
1.1.1.2 root 184: #ifdef TARGET_NR_semctl
1.1 root 185: static void
1.1.1.2 root 186: print_semctl(const struct syscallname *name,
1.1 root 187: abi_long arg1, abi_long arg2, abi_long arg3,
188: abi_long arg4, abi_long arg5, abi_long arg6)
189: {
190: gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", name->name, arg1, arg2);
191: print_ipc_cmd(arg3);
192: gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
193: }
1.1.1.2 root 194: #endif
1.1 root 195:
196: static void
1.1.1.2 root 197: print_execve(const struct syscallname *name,
1.1 root 198: abi_long arg1, abi_long arg2, abi_long arg3,
199: abi_long arg4, abi_long arg5, abi_long arg6)
200: {
201: abi_ulong arg_ptr_addr;
202: char *s;
203:
204: if (!(s = lock_user_string(arg1)))
205: return;
206: gemu_log("%s(\"%s\",{", name->name, s);
207: unlock_user(s, arg1, 0);
208:
209: for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
1.1.1.2 root 210: abi_ulong *arg_ptr, arg_addr;
1.1 root 211:
212: arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
213: if (!arg_ptr)
214: return;
215: arg_addr = tswapl(*arg_ptr);
216: unlock_user(arg_ptr, arg_ptr_addr, 0);
217: if (!arg_addr)
218: break;
219: if ((s = lock_user_string(arg_addr))) {
220: gemu_log("\"%s\",", s);
1.1.1.2 root 221: unlock_user(s, arg_addr, 0);
1.1 root 222: }
223: }
224:
225: gemu_log("NULL})");
226: }
227:
228: #ifdef TARGET_NR_ipc
229: static void
1.1.1.2 root 230: print_ipc(const struct syscallname *name,
1.1 root 231: abi_long arg1, abi_long arg2, abi_long arg3,
232: abi_long arg4, abi_long arg5, abi_long arg6)
233: {
234: switch(arg1) {
235: case IPCOP_semctl:
1.1.1.2 root 236: gemu_log("semctl(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", arg1, arg2);
237: print_ipc_cmd(arg3);
238: gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
1.1 root 239: break;
240: default:
241: gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")",
242: name->name, arg1, arg2, arg3, arg4);
243: }
244: }
245: #endif
246:
247: /*
248: * Variants for the return value output function
249: */
250:
251: static void
1.1.1.2 root 252: print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
1.1 root 253: {
254: if( ret == -1 ) {
255: gemu_log(" = -1 errno=%d (%s)\n", errno, target_strerror(errno));
256: } else {
257: gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
258: }
259: }
260:
261: #if 0 /* currently unused */
262: static void
263: print_syscall_ret_raw(struct syscallname *name, abi_long ret)
264: {
265: gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
266: }
267: #endif
268:
269: #ifdef TARGET_NR__newselect
270: static void
1.1.1.2 root 271: print_syscall_ret_newselect(const struct syscallname *name, abi_long ret)
1.1 root 272: {
273: gemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
274: print_fdset(newselect_arg1,newselect_arg2);
275: gemu_log(",");
276: print_fdset(newselect_arg1,newselect_arg3);
277: gemu_log(",");
278: print_fdset(newselect_arg1,newselect_arg4);
279: gemu_log(",");
1.1.1.3 root 280: print_timeval(newselect_arg5, 1);
1.1 root 281: gemu_log(")\n");
282: }
283: #endif
284:
1.1.1.3 root 285: UNUSED static struct flags access_flags[] = {
286: FLAG_GENERIC(F_OK),
287: FLAG_GENERIC(R_OK),
288: FLAG_GENERIC(W_OK),
289: FLAG_GENERIC(X_OK),
290: FLAG_END,
291: };
292:
293: UNUSED static struct flags at_file_flags[] = {
294: #ifdef AT_EACCESS
295: FLAG_GENERIC(AT_EACCESS),
296: #endif
297: #ifdef AT_SYMLINK_NOFOLLOW
298: FLAG_GENERIC(AT_SYMLINK_NOFOLLOW),
299: #endif
300: FLAG_END,
301: };
302:
303: UNUSED static struct flags unlinkat_flags[] = {
304: #ifdef AT_REMOVEDIR
305: FLAG_GENERIC(AT_REMOVEDIR),
306: #endif
307: FLAG_END,
308: };
309:
310: UNUSED static struct flags mode_flags[] = {
311: FLAG_GENERIC(S_IFSOCK),
312: FLAG_GENERIC(S_IFLNK),
313: FLAG_GENERIC(S_IFREG),
314: FLAG_GENERIC(S_IFBLK),
315: FLAG_GENERIC(S_IFDIR),
316: FLAG_GENERIC(S_IFCHR),
317: FLAG_GENERIC(S_IFIFO),
318: FLAG_END,
319: };
320:
321: UNUSED static struct flags open_access_flags[] = {
322: FLAG_TARGET(O_RDONLY),
323: FLAG_TARGET(O_WRONLY),
324: FLAG_TARGET(O_RDWR),
325: FLAG_END,
326: };
327:
328: UNUSED static struct flags open_flags[] = {
329: FLAG_TARGET(O_APPEND),
330: FLAG_TARGET(O_CREAT),
331: FLAG_TARGET(O_DIRECTORY),
332: FLAG_TARGET(O_EXCL),
333: FLAG_TARGET(O_LARGEFILE),
334: FLAG_TARGET(O_NOCTTY),
335: FLAG_TARGET(O_NOFOLLOW),
336: FLAG_TARGET(O_NONBLOCK), /* also O_NDELAY */
337: FLAG_TARGET(O_SYNC),
338: FLAG_TARGET(O_TRUNC),
339: #ifdef O_DIRECT
340: FLAG_TARGET(O_DIRECT),
341: #endif
342: FLAG_END,
343: };
344:
345: UNUSED static struct flags mount_flags[] = {
346: #ifdef MS_BIND
347: FLAG_GENERIC(MS_BIND),
348: #endif
349: #ifdef MS_DIRSYNC
350: FLAG_GENERIC(MS_DIRSYNC),
351: #endif
352: FLAG_GENERIC(MS_MANDLOCK),
353: #ifdef MS_MOVE
354: FLAG_GENERIC(MS_MOVE),
355: #endif
356: FLAG_GENERIC(MS_NOATIME),
357: FLAG_GENERIC(MS_NODEV),
358: FLAG_GENERIC(MS_NODIRATIME),
359: FLAG_GENERIC(MS_NOEXEC),
360: FLAG_GENERIC(MS_NOSUID),
361: FLAG_GENERIC(MS_RDONLY),
362: #ifdef MS_RELATIME
363: FLAG_GENERIC(MS_RELATIME),
364: #endif
365: FLAG_GENERIC(MS_REMOUNT),
366: FLAG_GENERIC(MS_SYNCHRONOUS),
367: FLAG_END,
368: };
369:
370: UNUSED static struct flags umount2_flags[] = {
371: #ifdef MNT_FORCE
372: FLAG_GENERIC(MNT_FORCE),
373: #endif
374: #ifdef MNT_DETACH
375: FLAG_GENERIC(MNT_DETACH),
376: #endif
377: #ifdef MNT_EXPIRE
378: FLAG_GENERIC(MNT_EXPIRE),
379: #endif
380: FLAG_END,
381: };
382:
383: UNUSED static struct flags mmap_prot_flags[] = {
384: FLAG_GENERIC(PROT_NONE),
385: FLAG_GENERIC(PROT_EXEC),
386: FLAG_GENERIC(PROT_READ),
387: FLAG_GENERIC(PROT_WRITE),
1.1.1.4 ! root 388: FLAG_TARGET(PROT_SEM),
! 389: FLAG_GENERIC(PROT_GROWSDOWN),
! 390: FLAG_GENERIC(PROT_GROWSUP),
1.1.1.3 root 391: FLAG_END,
392: };
393:
394: UNUSED static struct flags mmap_flags[] = {
395: FLAG_TARGET(MAP_SHARED),
396: FLAG_TARGET(MAP_PRIVATE),
397: FLAG_TARGET(MAP_ANONYMOUS),
398: FLAG_TARGET(MAP_DENYWRITE),
399: FLAG_TARGET(MAP_FIXED),
400: FLAG_TARGET(MAP_GROWSDOWN),
401: #ifdef MAP_LOCKED
402: FLAG_TARGET(MAP_LOCKED),
403: #endif
404: #ifdef MAP_NONBLOCK
405: FLAG_TARGET(MAP_NONBLOCK),
406: #endif
407: FLAG_TARGET(MAP_NORESERVE),
408: #ifdef MAP_POPULATE
409: FLAG_TARGET(MAP_POPULATE),
410: #endif
411: FLAG_END,
412: };
413:
414: UNUSED static struct flags fcntl_flags[] = {
415: FLAG_TARGET(F_DUPFD),
416: FLAG_TARGET(F_GETFD),
417: FLAG_TARGET(F_SETFD),
418: FLAG_TARGET(F_GETFL),
419: FLAG_TARGET(F_SETFL),
420: FLAG_TARGET(F_GETLK),
421: FLAG_TARGET(F_SETLK),
422: FLAG_TARGET(F_SETLKW),
423: FLAG_END,
424: };
425:
426: /*
427: * print_xxx utility functions. These are used to print syscall
428: * parameters in certain format. All of these have parameter
429: * named 'last'. This parameter is used to add comma to output
430: * when last == 0.
431: */
432:
433: static const char *
434: get_comma(int last)
435: {
436: return ((last) ? "" : ",");
437: }
438:
439: static void
440: print_flags(const struct flags *f, abi_long tflags, int last)
441: {
442: const char *sep = "";
443: int flags;
444: int n;
445:
446: flags = (int)tswap32(tflags);
447:
448: if ((flags == 0) && (f->f_value == 0)) {
449: gemu_log("%s%s", f->f_string, get_comma(last));
450: return;
451: }
452: for (n = 0; f->f_string != NULL; f++) {
453: if ((f->f_value != 0) && ((flags & f->f_value) == f->f_value)) {
454: gemu_log("%s%s", sep, f->f_string);
455: flags &= ~f->f_value;
456: sep = "|";
457: n++;
458: }
459: }
460:
461: if (n > 0) {
462: /* print rest of the flags as numeric */
463: if (flags != 0) {
464: gemu_log("%s%#x%s", sep, flags, get_comma(last));
465: } else {
466: gemu_log("%s", get_comma(last));
467: }
468: } else {
469: /* no string version of flags found, print them in hex then */
470: gemu_log("%#x%s", flags, get_comma(last));
471: }
472: }
473:
474: static void
475: print_at_dirfd(abi_long tdirfd, int last)
476: {
477: int dirfd = tswap32(tdirfd);
478:
479: #ifdef AT_FDCWD
480: if (dirfd == AT_FDCWD) {
481: gemu_log("AT_FDCWD%s", get_comma(last));
482: return;
483: }
484: #endif
485: gemu_log("%d%s", dirfd, get_comma(last));
486: }
487:
488: static void
489: print_file_mode(abi_long tmode, int last)
490: {
491: const char *sep = "";
492: const struct flags *m;
493: mode_t mode = (mode_t)tswap32(tmode);
494:
495: for (m = &mode_flags[0]; m->f_string != NULL; m++) {
496: if ((m->f_value & mode) == m->f_value) {
497: gemu_log("%s%s", m->f_string, sep);
498: sep = "|";
499: mode &= ~m->f_value;
500: break;
501: }
502: }
503:
504: mode &= ~S_IFMT;
505: /* print rest of the mode as octal */
506: if (mode != 0)
507: gemu_log("%s%#o", sep, mode);
508:
509: gemu_log("%s", get_comma(last));
510: }
511:
512: static void
513: print_open_flags(abi_long tflags, int last)
514: {
515: int flags = tswap32(tflags);
516:
517: print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1);
518: flags &= ~TARGET_O_ACCMODE;
519: if (flags == 0) {
520: gemu_log("%s", get_comma(last));
521: return;
522: }
523: gemu_log("|");
524: print_flags(open_flags, flags, last);
525: }
526:
527: static void
528: print_syscall_prologue(const struct syscallname *sc)
529: {
530: gemu_log("%s(", sc->name);
531: }
532:
533: /*ARGSUSED*/
534: static void
535: print_syscall_epilogue(const struct syscallname *sc)
536: {
537: (void)sc;
538: gemu_log(")");
539: }
540:
541: static void
542: print_string(abi_long addr, int last)
543: {
544: char *s;
545:
546: if ((s = lock_user_string(addr)) != NULL) {
547: gemu_log("\"%s\"%s", s, get_comma(last));
548: unlock_user(s, addr, 0);
549: } else {
550: /* can't get string out of it, so print it as pointer */
551: print_pointer(addr, last);
552: }
553: }
554:
555: /*
556: * Prints out raw parameter using given format. Caller needs
557: * to do byte swapping if needed.
558: */
559: static void
560: print_raw_param(const char *fmt, abi_long param, int last)
561: {
562: char format[64];
563:
564: (void) snprintf(format, sizeof (format), "%s%s", fmt, get_comma(last));
565: gemu_log(format, param);
566: }
567:
568: static void
569: print_pointer(abi_long p, int last)
570: {
571: if (p == 0)
572: gemu_log("NULL%s", get_comma(last));
573: else
574: gemu_log("0x" TARGET_ABI_FMT_lx "%s", p, get_comma(last));
575: }
576:
577: /*
578: * Reads 32-bit (int) number from guest address space from
579: * address 'addr' and prints it.
580: */
581: static void
582: print_number(abi_long addr, int last)
583: {
584: if (addr == 0) {
585: gemu_log("NULL%s", get_comma(last));
586: } else {
587: int num;
588:
589: get_user_s32(num, addr);
590: gemu_log("[%d]%s", num, get_comma(last));
591: }
592: }
593:
594: static void
595: print_timeval(abi_ulong tv_addr, int last)
596: {
597: if( tv_addr ) {
598: struct target_timeval *tv;
599:
600: tv = lock_user(VERIFY_READ, tv_addr, sizeof(*tv), 1);
601: if (!tv)
602: return;
603: gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}%s",
604: tv->tv_sec, tv->tv_usec, get_comma(last));
605: unlock_user(tv, tv_addr, 0);
606: } else
607: gemu_log("NULL%s", get_comma(last));
608: }
609:
610: #undef UNUSED
611:
612: #ifdef TARGET_NR_accept
613: static void
614: print_accept(const struct syscallname *name,
615: abi_long arg0, abi_long arg1, abi_long arg2,
616: abi_long arg3, abi_long arg4, abi_long arg5)
617: {
618: print_syscall_prologue(name);
619: print_raw_param("%d", tswap32(arg0), 0);
620: print_pointer(arg1, 0);
621: print_number(arg2, 1);
622: print_syscall_epilogue(name);
623: }
624: #endif
625:
626: #ifdef TARGET_NR_access
627: static void
628: print_access(const struct syscallname *name,
629: abi_long arg0, abi_long arg1, abi_long arg2,
630: abi_long arg3, abi_long arg4, abi_long arg5)
631: {
632: print_syscall_prologue(name);
633: print_string(arg0, 0);
634: print_flags(access_flags, arg1, 1);
635: print_syscall_epilogue(name);
636: }
637: #endif
638:
639: #ifdef TARGET_NR_brk
640: static void
641: print_brk(const struct syscallname *name,
642: abi_long arg0, abi_long arg1, abi_long arg2,
643: abi_long arg3, abi_long arg4, abi_long arg5)
644: {
645: print_syscall_prologue(name);
646: print_pointer(arg0, 1);
647: print_syscall_epilogue(name);
648: }
649: #endif
650:
651: #ifdef TARGET_NR_chdir
652: static void
653: print_chdir(const struct syscallname *name,
654: abi_long arg0, abi_long arg1, abi_long arg2,
655: abi_long arg3, abi_long arg4, abi_long arg5)
656: {
657: print_syscall_prologue(name);
658: print_string(arg0, 1);
659: print_syscall_epilogue(name);
660: }
661: #endif
662:
663: #ifdef TARGET_NR_chmod
664: static void
665: print_chmod(const struct syscallname *name,
666: abi_long arg0, abi_long arg1, abi_long arg2,
667: abi_long arg3, abi_long arg4, abi_long arg5)
668: {
669: print_syscall_prologue(name);
670: print_string(arg0, 0);
671: print_file_mode(arg1, 1);
672: print_syscall_epilogue(name);
673: }
674: #endif
675:
676: #ifdef TARGET_NR_creat
677: static void
678: print_creat(const struct syscallname *name,
679: abi_long arg0, abi_long arg1, abi_long arg2,
680: abi_long arg3, abi_long arg4, abi_long arg5)
681: {
682: print_syscall_prologue(name);
683: print_string(arg0, 0);
684: print_file_mode(arg1, 1);
685: print_syscall_epilogue(name);
686: }
687: #endif
688:
689: #ifdef TARGET_NR_execv
690: static void
691: print_execv(const struct syscallname *name,
692: abi_long arg0, abi_long arg1, abi_long arg2,
693: abi_long arg3, abi_long arg4, abi_long arg5)
694: {
695: print_syscall_prologue(name);
696: print_string(arg0, 0);
697: print_raw_param("0x" TARGET_ABI_FMT_lx, tswapl(arg1), 1);
698: print_syscall_epilogue(name);
699: }
700: #endif
701:
702: #ifdef TARGET_NR_faccessat
703: static void
704: print_faccessat(const struct syscallname *name,
705: abi_long arg0, abi_long arg1, abi_long arg2,
706: abi_long arg3, abi_long arg4, abi_long arg5)
707: {
708: print_syscall_prologue(name);
709: print_at_dirfd(arg0, 0);
710: print_string(arg1, 0);
711: print_flags(access_flags, arg2, 0);
712: print_flags(at_file_flags, arg3, 1);
713: print_syscall_epilogue(name);
714: }
715: #endif
716:
717: #ifdef TARGET_NR_fchmodat
718: static void
719: print_fchmodat(const struct syscallname *name,
720: abi_long arg0, abi_long arg1, abi_long arg2,
721: abi_long arg3, abi_long arg4, abi_long arg5)
722: {
723: print_syscall_prologue(name);
724: print_at_dirfd(arg0, 0);
725: print_string(arg1, 0);
726: print_file_mode(arg2, 0);
727: print_flags(at_file_flags, arg3, 1);
728: print_syscall_epilogue(name);
729: }
730: #endif
731:
732: #ifdef TARGET_NR_fchownat
733: static void
734: print_fchownat(const struct syscallname *name,
735: abi_long arg0, abi_long arg1, abi_long arg2,
736: abi_long arg3, abi_long arg4, abi_long arg5)
737: {
738: print_syscall_prologue(name);
739: print_at_dirfd(arg0, 0);
740: print_string(arg1, 0);
741: #ifdef USE_UID16
742: print_raw_param("%d", tswap16(arg2), 0);
743: print_raw_param("%d", tswap16(arg3), 0);
744: #else
745: print_raw_param("%d", tswap32(arg2), 0);
746: print_raw_param("%d", tswap32(arg3), 0);
747: #endif
748: print_flags(at_file_flags, arg4, 1);
749: print_syscall_epilogue(name);
750: }
751: #endif
752:
753: #if defined(TARGET_NR_fcntl) || defined(TARGET_NR_fcntl64)
754: static void
755: print_fcntl(const struct syscallname *name,
756: abi_long arg0, abi_long arg1, abi_long arg2,
757: abi_long arg3, abi_long arg4, abi_long arg5)
758: {
759: print_syscall_prologue(name);
760: print_raw_param("%d", tswap32(arg0), 0);
761: print_flags(fcntl_flags, arg1, 0);
762: /*
763: * TODO: check flags and print following argument only
764: * when needed.
765: */
766: print_pointer(arg2, 1);
767: print_syscall_epilogue(name);
768: }
769: #define print_fcntl64 print_fcntl
770: #endif
771:
772:
773: #ifdef TARGET_NR_futimesat
774: static void
775: print_futimesat(const struct syscallname *name,
776: abi_long arg0, abi_long arg1, abi_long arg2,
777: abi_long arg3, abi_long arg4, abi_long arg5)
778: {
779: print_syscall_prologue(name);
780: print_at_dirfd(arg0, 0);
781: print_string(arg1, 0);
782: print_timeval(arg2, 0);
783: print_timeval(arg2 + sizeof (struct target_timeval), 1);
784: print_syscall_epilogue(name);
785: }
786: #endif
787:
788: #ifdef TARGET_NR_link
789: static void
790: print_link(const struct syscallname *name,
791: abi_long arg0, abi_long arg1, abi_long arg2,
792: abi_long arg3, abi_long arg4, abi_long arg5)
793: {
794: print_syscall_prologue(name);
795: print_string(arg0, 0);
796: print_string(arg1, 1);
797: print_syscall_epilogue(name);
798: }
799: #endif
800:
801: #ifdef TARGET_NR_linkat
802: static void
803: print_linkat(const struct syscallname *name,
804: abi_long arg0, abi_long arg1, abi_long arg2,
805: abi_long arg3, abi_long arg4, abi_long arg5)
806: {
807: print_syscall_prologue(name);
808: print_at_dirfd(arg0, 0);
809: print_string(arg1, 0);
810: print_at_dirfd(arg2, 0);
811: print_string(arg3, 0);
812: print_flags(at_file_flags, arg4, 1);
813: print_syscall_epilogue(name);
814: }
815: #endif
816:
817: #if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
818: defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64)
819: static void
820: print_stat(const struct syscallname *name,
821: abi_long arg0, abi_long arg1, abi_long arg2,
822: abi_long arg3, abi_long arg4, abi_long arg5)
823: {
824: print_syscall_prologue(name);
825: print_string(arg0, 0);
826: print_pointer(arg1, 1);
827: print_syscall_epilogue(name);
828: }
829: #define print_lstat print_stat
830: #define print_stat64 print_stat
831: #define print_lstat64 print_stat
832: #endif
833:
834: #if defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
835: static void
836: print_fstat(const struct syscallname *name,
837: abi_long arg0, abi_long arg1, abi_long arg2,
838: abi_long arg3, abi_long arg4, abi_long arg5)
839: {
840: print_syscall_prologue(name);
841: print_raw_param("%d", tswap32(arg0), 0);
842: print_pointer(arg1, 1);
843: print_syscall_epilogue(name);
844: }
845: #define print_fstat64 print_fstat
846: #endif
847:
848: #ifdef TARGET_NR_mkdir
849: static void
850: print_mkdir(const struct syscallname *name,
851: abi_long arg0, abi_long arg1, abi_long arg2,
852: abi_long arg3, abi_long arg4, abi_long arg5)
853: {
854: print_syscall_prologue(name);
855: print_string(arg0, 0);
856: print_file_mode(arg1, 1);
857: print_syscall_epilogue(name);
858: }
859: #endif
860:
861: #ifdef TARGET_NR_mkdirat
862: static void
863: print_mkdirat(const struct syscallname *name,
864: abi_long arg0, abi_long arg1, abi_long arg2,
865: abi_long arg3, abi_long arg4, abi_long arg5)
866: {
867: print_syscall_prologue(name);
868: print_at_dirfd(arg0, 0);
869: print_string(arg1, 0);
870: print_file_mode(arg2, 1);
871: print_syscall_epilogue(name);
872: }
873: #endif
874:
875: #ifdef TARGET_NR_mknod
876: static void
877: print_mknod(const struct syscallname *name,
878: abi_long arg0, abi_long arg1, abi_long arg2,
879: abi_long arg3, abi_long arg4, abi_long arg5)
880: {
881: int hasdev = (tswapl(arg1) & (S_IFCHR|S_IFBLK));
882:
883: print_syscall_prologue(name);
884: print_string(arg0, 0);
885: print_file_mode(arg1, (hasdev == 0));
886: if (hasdev) {
887: print_raw_param("makedev(%d", major(tswapl(arg2)), 0);
888: print_raw_param("%d)", minor(tswapl(arg2)), 1);
889: }
890: print_syscall_epilogue(name);
891: }
892: #endif
893:
894: #ifdef TARGET_NR_mknodat
895: static void
896: print_mknodat(const struct syscallname *name,
897: abi_long arg0, abi_long arg1, abi_long arg2,
898: abi_long arg3, abi_long arg4, abi_long arg5)
899: {
900: int hasdev = (tswapl(arg2) & (S_IFCHR|S_IFBLK));
901:
902: print_syscall_prologue(name);
903: print_at_dirfd(arg0, 0);
904: print_string(arg1, 0);
905: print_file_mode(arg2, (hasdev == 0));
906: if (hasdev) {
907: print_raw_param("makedev(%d", major(tswapl(arg3)), 0);
908: print_raw_param("%d)", minor(tswapl(arg3)), 1);
909: }
910: print_syscall_epilogue(name);
911: }
912: #endif
913:
914: #ifdef TARGET_NR_mq_open
915: static void
916: print_mq_open(const struct syscallname *name,
917: abi_long arg0, abi_long arg1, abi_long arg2,
918: abi_long arg3, abi_long arg4, abi_long arg5)
919: {
920: int is_creat = (tswapl(arg1) & TARGET_O_CREAT);
921:
922: print_syscall_prologue(name);
923: print_string(arg0, 0);
924: print_open_flags(arg1, (is_creat == 0));
925: if (is_creat) {
926: print_file_mode(arg2, 0);
927: print_pointer(arg3, 1);
928: }
929: print_syscall_epilogue(name);
930: }
931: #endif
932:
933: #ifdef TARGET_NR_open
934: static void
935: print_open(const struct syscallname *name,
936: abi_long arg0, abi_long arg1, abi_long arg2,
937: abi_long arg3, abi_long arg4, abi_long arg5)
938: {
939: int is_creat = (tswap32(arg1) & TARGET_O_CREAT);
940:
941: print_syscall_prologue(name);
942: print_string(arg0, 0);
943: print_open_flags(arg1, (is_creat == 0));
944: if (is_creat)
945: print_file_mode(arg2, 1);
946: print_syscall_epilogue(name);
947: }
948: #endif
949:
950: #ifdef TARGET_NR_openat
951: static void
952: print_openat(const struct syscallname *name,
953: abi_long arg0, abi_long arg1, abi_long arg2,
954: abi_long arg3, abi_long arg4, abi_long arg5)
955: {
956: int is_creat = (tswap32(arg2) & TARGET_O_CREAT);
957:
958: print_syscall_prologue(name);
959: print_at_dirfd(arg0, 0);
960: print_string(arg1, 0);
961: print_open_flags(arg2, (is_creat == 0));
962: if (is_creat)
963: print_file_mode(arg3, 1);
964: print_syscall_epilogue(name);
965: }
966: #endif
967:
968: #ifdef TARGET_NR_mq_unlink
969: static void
970: print_mq_unlink(const struct syscallname *name,
971: abi_long arg0, abi_long arg1, abi_long arg2,
972: abi_long arg3, abi_long arg4, abi_long arg5)
973: {
974: print_syscall_prologue(name);
975: print_string(arg0, 1);
976: print_syscall_epilogue(name);
977: }
978: #endif
979:
980: #if defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)
981: static void
982: print_fstatat64(const struct syscallname *name,
983: abi_long arg0, abi_long arg1, abi_long arg2,
984: abi_long arg3, abi_long arg4, abi_long arg5)
985: {
986: print_syscall_prologue(name);
987: print_at_dirfd(arg0, 0);
988: print_string(arg1, 0);
989: print_pointer(arg2, 0);
990: print_flags(at_file_flags, arg3, 1);
991: print_syscall_epilogue(name);
992: }
993: #define print_newfstatat print_fstatat64
994: #endif
995:
996: #ifdef TARGET_NR_readlink
997: static void
998: print_readlink(const struct syscallname *name,
999: abi_long arg0, abi_long arg1, abi_long arg2,
1000: abi_long arg3, abi_long arg4, abi_long arg5)
1001: {
1002: print_syscall_prologue(name);
1003: print_string(arg0, 0);
1004: print_pointer(arg1, 0);
1005: print_raw_param("%u", tswapl(arg2), 1);
1006: print_syscall_epilogue(name);
1007: }
1008: #endif
1009:
1010: #ifdef TARGET_NR_readlinkat
1011: static void
1012: print_readlinkat(const struct syscallname *name,
1013: abi_long arg0, abi_long arg1, abi_long arg2,
1014: abi_long arg3, abi_long arg4, abi_long arg5)
1015: {
1016: print_syscall_prologue(name);
1017: print_at_dirfd(arg0, 0);
1018: print_string(arg1, 0);
1019: print_pointer(arg2, 0);
1020: print_raw_param("%u", tswapl(arg3), 1);
1021: print_syscall_epilogue(name);
1022: }
1023: #endif
1024:
1025: #ifdef TARGET_NR_rename
1026: static void
1027: print_rename(const struct syscallname *name,
1028: abi_long arg0, abi_long arg1, abi_long arg2,
1029: abi_long arg3, abi_long arg4, abi_long arg5)
1030: {
1031: print_syscall_prologue(name);
1032: print_string(arg0, 0);
1033: print_string(arg1, 1);
1034: print_syscall_epilogue(name);
1035: }
1036: #endif
1037:
1038: #ifdef TARGET_NR_renameat
1039: static void
1040: print_renameat(const struct syscallname *name,
1041: abi_long arg0, abi_long arg1, abi_long arg2,
1042: abi_long arg3, abi_long arg4, abi_long arg5)
1043: {
1044: print_syscall_prologue(name);
1045: print_at_dirfd(arg0, 0);
1046: print_string(arg1, 0);
1047: print_at_dirfd(arg2, 0);
1048: print_string(arg3, 1);
1049: print_syscall_epilogue(name);
1050: }
1051: #endif
1052:
1053: #ifdef TARGET_NR_statfs
1054: static void
1055: print_statfs(const struct syscallname *name,
1056: abi_long arg0, abi_long arg1, abi_long arg2,
1057: abi_long arg3, abi_long arg4, abi_long arg5)
1058: {
1059: print_syscall_prologue(name);
1060: print_string(arg0, 0);
1061: print_pointer(arg1, 1);
1062: print_syscall_epilogue(name);
1063: }
1064: #define print_statfs64 print_statfs
1065: #endif
1066:
1067: #ifdef TARGET_NR_symlink
1068: static void
1069: print_symlink(const struct syscallname *name,
1070: abi_long arg0, abi_long arg1, abi_long arg2,
1071: abi_long arg3, abi_long arg4, abi_long arg5)
1072: {
1073: print_syscall_prologue(name);
1074: print_string(arg0, 0);
1075: print_string(arg1, 1);
1076: print_syscall_epilogue(name);
1077: }
1078: #endif
1079:
1080: #ifdef TARGET_NR_symlinkat
1081: static void
1082: print_symlinkat(const struct syscallname *name,
1083: abi_long arg0, abi_long arg1, abi_long arg2,
1084: abi_long arg3, abi_long arg4, abi_long arg5)
1085: {
1086: print_syscall_prologue(name);
1087: print_string(arg0, 0);
1088: print_at_dirfd(arg1, 0);
1089: print_string(arg2, 1);
1090: print_syscall_epilogue(name);
1091: }
1092: #endif
1093:
1094: #ifdef TARGET_NR_mount
1095: static void
1096: print_mount(const struct syscallname *name,
1097: abi_long arg0, abi_long arg1, abi_long arg2,
1098: abi_long arg3, abi_long arg4, abi_long arg5)
1099: {
1100: print_syscall_prologue(name);
1101: print_string(arg0, 0);
1102: print_string(arg1, 0);
1103: print_string(arg2, 0);
1104: print_flags(mount_flags, arg3, 0);
1105: print_pointer(arg4, 1);
1106: print_syscall_epilogue(name);
1107: }
1108: #endif
1109:
1110: #ifdef TARGET_NR_umount
1111: static void
1112: print_umount(const struct syscallname *name,
1113: abi_long arg0, abi_long arg1, abi_long arg2,
1114: abi_long arg3, abi_long arg4, abi_long arg5)
1115: {
1116: print_syscall_prologue(name);
1117: print_string(arg0, 1);
1118: print_syscall_epilogue(name);
1119: }
1120: #endif
1121:
1122: #ifdef TARGET_NR_umount2
1123: static void
1124: print_umount2(const struct syscallname *name,
1125: abi_long arg0, abi_long arg1, abi_long arg2,
1126: abi_long arg3, abi_long arg4, abi_long arg5)
1127: {
1128: print_syscall_prologue(name);
1129: print_string(arg0, 0);
1130: print_flags(umount2_flags, arg1, 1);
1131: print_syscall_epilogue(name);
1132: }
1133: #endif
1134:
1135: #ifdef TARGET_NR_unlink
1136: static void
1137: print_unlink(const struct syscallname *name,
1138: abi_long arg0, abi_long arg1, abi_long arg2,
1139: abi_long arg3, abi_long arg4, abi_long arg5)
1140: {
1141: print_syscall_prologue(name);
1142: print_string(arg0, 1);
1143: print_syscall_epilogue(name);
1144: }
1145: #endif
1146:
1147: #ifdef TARGET_NR_unlinkat
1148: static void
1149: print_unlinkat(const struct syscallname *name,
1150: abi_long arg0, abi_long arg1, abi_long arg2,
1151: abi_long arg3, abi_long arg4, abi_long arg5)
1152: {
1153: print_syscall_prologue(name);
1154: print_at_dirfd(arg0, 0);
1155: print_string(arg1, 0);
1156: print_flags(unlinkat_flags, arg2, 1);
1157: print_syscall_epilogue(name);
1158: }
1159: #endif
1160:
1161: #ifdef TARGET_NR_utime
1162: static void
1163: print_utime(const struct syscallname *name,
1164: abi_long arg0, abi_long arg1, abi_long arg2,
1165: abi_long arg3, abi_long arg4, abi_long arg5)
1166: {
1167: print_syscall_prologue(name);
1168: print_string(arg0, 0);
1169: print_pointer(arg1, 1);
1170: print_syscall_epilogue(name);
1171: }
1172: #endif
1173:
1174: #ifdef TARGET_NR_utimes
1175: static void
1176: print_utimes(const struct syscallname *name,
1177: abi_long arg0, abi_long arg1, abi_long arg2,
1178: abi_long arg3, abi_long arg4, abi_long arg5)
1179: {
1180: print_syscall_prologue(name);
1181: print_string(arg0, 0);
1182: print_pointer(arg1, 1);
1183: print_syscall_epilogue(name);
1184: }
1185: #endif
1186:
1187: #ifdef TARGET_NR_utimensat
1188: static void
1189: print_utimensat(const struct syscallname *name,
1190: abi_long arg0, abi_long arg1, abi_long arg2,
1191: abi_long arg3, abi_long arg4, abi_long arg5)
1192: {
1193: print_syscall_prologue(name);
1194: print_at_dirfd(arg0, 0);
1195: print_string(arg1, 0);
1196: print_pointer(arg2, 0);
1197: print_flags(at_file_flags, arg3, 1);
1198: print_syscall_epilogue(name);
1199: }
1200: #endif
1201:
1202: #ifdef TARGET_NR_mmap
1203: static void
1204: print_mmap(const struct syscallname *name,
1205: abi_long arg0, abi_long arg1, abi_long arg2,
1206: abi_long arg3, abi_long arg4, abi_long arg5)
1207: {
1208: print_syscall_prologue(name);
1209: print_pointer(arg0, 0);
1210: print_raw_param("%d", tswapl(arg1), 0);
1211: print_flags(mmap_prot_flags, arg2, 0);
1212: print_flags(mmap_flags, arg3, 0);
1213: print_raw_param("%d", tswapl(arg4), 0);
1214: print_raw_param("%#x", tswapl(arg5), 1);
1215: print_syscall_epilogue(name);
1216: }
1217: #define print_mmap2 print_mmap
1218: #endif
1219:
1220: #ifdef TARGET_NR_mprotect
1221: static void
1222: print_mprotect(const struct syscallname *name,
1223: abi_long arg0, abi_long arg1, abi_long arg2,
1224: abi_long arg3, abi_long arg4, abi_long arg5)
1225: {
1226: print_syscall_prologue(name);
1227: print_pointer(arg0, 0);
1228: print_raw_param("%d", tswapl(arg1), 0);
1229: print_flags(mmap_prot_flags, arg2, 1);
1230: print_syscall_epilogue(name);
1231: }
1232: #endif
1233:
1234: #ifdef TARGET_NR_munmap
1235: static void
1236: print_munmap(const struct syscallname *name,
1237: abi_long arg0, abi_long arg1, abi_long arg2,
1238: abi_long arg3, abi_long arg4, abi_long arg5)
1239: {
1240: print_syscall_prologue(name);
1241: print_pointer(arg0, 0);
1242: print_raw_param("%d", tswapl(arg1), 1);
1243: print_syscall_epilogue(name);
1244: }
1245: #endif
1246:
1247: #ifdef TARGET_NR_futex
1248: static void print_futex_op(abi_long tflag, int last)
1249: {
1250: #define print_op(val) \
1251: if( cmd == val ) { \
1252: gemu_log(#val); \
1253: return; \
1254: }
1255:
1256: int cmd = (int)tswap32(tflag);
1257: #ifdef FUTEX_PRIVATE_FLAG
1.1.1.4 ! root 1258: if (cmd & FUTEX_PRIVATE_FLAG) {
1.1.1.3 root 1259: gemu_log("FUTEX_PRIVATE_FLAG|");
1.1.1.4 ! root 1260: cmd &= ~FUTEX_PRIVATE_FLAG;
! 1261: }
1.1.1.3 root 1262: #endif
1263: print_op(FUTEX_WAIT)
1264: print_op(FUTEX_WAKE)
1265: print_op(FUTEX_FD)
1266: print_op(FUTEX_REQUEUE)
1267: print_op(FUTEX_CMP_REQUEUE)
1268: print_op(FUTEX_WAKE_OP)
1269: print_op(FUTEX_LOCK_PI)
1270: print_op(FUTEX_UNLOCK_PI)
1271: print_op(FUTEX_TRYLOCK_PI)
1272: #ifdef FUTEX_WAIT_BITSET
1273: print_op(FUTEX_WAIT_BITSET)
1274: #endif
1275: #ifdef FUTEX_WAKE_BITSET
1276: print_op(FUTEX_WAKE_BITSET)
1277: #endif
1278: /* unknown values */
1279: gemu_log("%d",cmd);
1280: }
1281:
1282: static void
1283: print_futex(const struct syscallname *name,
1284: abi_long arg0, abi_long arg1, abi_long arg2,
1285: abi_long arg3, abi_long arg4, abi_long arg5)
1286: {
1287: print_syscall_prologue(name);
1288: print_pointer(arg0, 0);
1289: print_futex_op(arg1, 0);
1290: print_raw_param(",%d", tswapl(arg2), 0);
1291: print_pointer(arg3, 0); /* struct timespec */
1292: print_pointer(arg4, 0);
1293: print_raw_param("%d", tswapl(arg4), 1);
1294: print_syscall_epilogue(name);
1295: }
1296: #endif
1297:
1.1 root 1298: /*
1299: * An array of all of the syscalls we know about
1300: */
1301:
1.1.1.2 root 1302: static const struct syscallname scnames[] = {
1.1 root 1303: #include "strace.list"
1304: };
1305:
1.1.1.2 root 1306: static int nsyscalls = ARRAY_SIZE(scnames);
1.1 root 1307:
1308: /*
1309: * The public interface to this module.
1310: */
1311: void
1312: print_syscall(int num,
1313: abi_long arg1, abi_long arg2, abi_long arg3,
1314: abi_long arg4, abi_long arg5, abi_long arg6)
1315: {
1316: int i;
1.1.1.2 root 1317: const 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 ")";
1.1 root 1318:
1319: gemu_log("%d ", getpid() );
1320:
1321: for(i=0;i<nsyscalls;i++)
1322: if( scnames[i].nr == num ) {
1323: if( scnames[i].call != NULL ) {
1324: scnames[i].call(&scnames[i],arg1,arg2,arg3,arg4,arg5,arg6);
1325: } else {
1326: /* XXX: this format system is broken because it uses
1327: host types and host pointers for strings */
1328: if( scnames[i].format != NULL )
1329: format = scnames[i].format;
1330: gemu_log(format,scnames[i].name, arg1,arg2,arg3,arg4,arg5,arg6);
1331: }
1.1.1.2 root 1332: return;
1.1 root 1333: }
1.1.1.2 root 1334: gemu_log("Unknown syscall %d\n", num);
1.1 root 1335: }
1336:
1337:
1338: void
1339: print_syscall_ret(int num, abi_long ret)
1340: {
1341: int i;
1342:
1343: for(i=0;i<nsyscalls;i++)
1344: if( scnames[i].nr == num ) {
1345: if( scnames[i].result != NULL ) {
1346: scnames[i].result(&scnames[i],ret);
1347: } else {
1348: if( ret < 0 ) {
1349: gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, target_strerror(-ret));
1350: } else {
1351: gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
1352: }
1353: }
1354: break;
1355: }
1356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.