qemu/linux-user/strace.c
<<
>>
Prefs
   1#include "qemu/osdep.h"
   2#include <sys/ipc.h>
   3#include <sys/msg.h>
   4#include <sys/sem.h>
   5#include <sys/shm.h>
   6#include <sys/select.h>
   7#include <sys/mount.h>
   8#include <sys/mman.h>
   9#include <sched.h>
  10#include "qemu.h"
  11
  12int do_strace=0;
  13
  14struct syscallname {
  15    int nr;
  16    const char *name;
  17    const char *format;
  18    void (*call)(const struct syscallname *,
  19                 abi_long, abi_long, abi_long,
  20                 abi_long, abi_long, abi_long);
  21    void (*result)(const struct syscallname *, abi_long);
  22};
  23
  24#ifdef __GNUC__
  25/*
  26 * It is possible that target doesn't have syscall that uses
  27 * following flags but we don't want the compiler to warn
  28 * us about them being unused.  Same applies to utility print
  29 * functions.  It is ok to keep them while not used.
  30 */
  31#define UNUSED __attribute__ ((unused))
  32#else
  33#define UNUSED
  34#endif
  35
  36/*
  37 * Structure used to translate flag values into strings.  This is
  38 * similar that is in the actual strace tool.
  39 */
  40struct flags {
  41    abi_long    f_value;  /* flag */
  42    const char  *f_string; /* stringified flag */
  43};
  44
  45/* common flags for all architectures */
  46#define FLAG_GENERIC(name) { name, #name }
  47/* target specific flags (syscall_defs.h has TARGET_<flag>) */
  48#define FLAG_TARGET(name)  { TARGET_ ## name, #name }
  49/* end of flags array */
  50#define FLAG_END           { 0, NULL }
  51
  52UNUSED static const char *get_comma(int);
  53UNUSED static void print_pointer(abi_long, int);
  54UNUSED static void print_flags(const struct flags *, abi_long, int);
  55UNUSED static void print_at_dirfd(abi_long, int);
  56UNUSED static void print_file_mode(abi_long, int);
  57UNUSED static void print_open_flags(abi_long, int);
  58UNUSED static void print_syscall_prologue(const struct syscallname *);
  59UNUSED static void print_syscall_epilogue(const struct syscallname *);
  60UNUSED static void print_string(abi_long, int);
  61UNUSED static void print_raw_param(const char *, abi_long, int);
  62UNUSED static void print_timeval(abi_ulong, int);
  63UNUSED static void print_number(abi_long, int);
  64UNUSED static void print_signal(abi_ulong, int);
  65
  66/*
  67 * Utility functions
  68 */
  69static void
  70print_ipc_cmd(int cmd)
  71{
  72#define output_cmd(val) \
  73if( cmd == val ) { \
  74    gemu_log(#val); \
  75    return; \
  76}
  77
  78    cmd &= 0xff;
  79
  80    /* General IPC commands */
  81    output_cmd( IPC_RMID );
  82    output_cmd( IPC_SET );
  83    output_cmd( IPC_STAT );
  84    output_cmd( IPC_INFO );
  85    /* msgctl() commands */
  86    #ifdef __USER_MISC
  87    output_cmd( MSG_STAT );
  88    output_cmd( MSG_INFO );
  89    #endif
  90    /* shmctl() commands */
  91    output_cmd( SHM_LOCK );
  92    output_cmd( SHM_UNLOCK );
  93    output_cmd( SHM_STAT );
  94    output_cmd( SHM_INFO );
  95    /* semctl() commands */
  96    output_cmd( GETPID );
  97    output_cmd( GETVAL );
  98    output_cmd( GETALL );
  99    output_cmd( GETNCNT );
 100    output_cmd( GETZCNT );
 101    output_cmd( SETVAL );
 102    output_cmd( SETALL );
 103    output_cmd( SEM_STAT );
 104    output_cmd( SEM_INFO );
 105    output_cmd( IPC_RMID );
 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
 115    /* Some value we don't recognize */
 116    gemu_log("%d",cmd);
 117}
 118
 119static void
 120print_signal(abi_ulong arg, int last)
 121{
 122    const char *signal_name = NULL;
 123    switch(arg) {
 124    case TARGET_SIGHUP: signal_name = "SIGHUP"; break;
 125    case TARGET_SIGINT: signal_name = "SIGINT"; break;
 126    case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break;
 127    case TARGET_SIGILL: signal_name = "SIGILL"; break;
 128    case TARGET_SIGABRT: signal_name = "SIGABRT"; break;
 129    case TARGET_SIGFPE: signal_name = "SIGFPE"; break;
 130    case TARGET_SIGKILL: signal_name = "SIGKILL"; break;
 131    case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break;
 132    case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break;
 133    case TARGET_SIGALRM: signal_name = "SIGALRM"; break;
 134    case TARGET_SIGTERM: signal_name = "SIGTERM"; break;
 135    case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break;
 136    case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break;
 137    case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break;
 138    case TARGET_SIGCONT: signal_name = "SIGCONT"; break;
 139    case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break;
 140    case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break;
 141    case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break;
 142    }
 143    if (signal_name == NULL) {
 144        print_raw_param("%ld", arg, last);
 145        return;
 146    }
 147    gemu_log("%s%s", signal_name, get_comma(last));
 148}
 149
 150#ifdef TARGET_NR__newselect
 151static void
 152print_fdset(int n, abi_ulong target_fds_addr)
 153{
 154    int i;
 155
 156    gemu_log("[");
 157    if( target_fds_addr ) {
 158        abi_long *target_fds;
 159
 160        target_fds = lock_user(VERIFY_READ,
 161                               target_fds_addr,
 162                               sizeof(*target_fds)*(n / TARGET_ABI_BITS + 1),
 163                               1);
 164
 165        if (!target_fds)
 166            return;
 167
 168        for (i=n; i>=0; i--) {
 169            if ((tswapal(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1)
 170                gemu_log("%d,", i );
 171            }
 172        unlock_user(target_fds, target_fds_addr, 0);
 173    }
 174    gemu_log("]");
 175}
 176#endif
 177
 178/*
 179 * Sysycall specific output functions
 180 */
 181
 182/* select */
 183#ifdef TARGET_NR__newselect
 184static long newselect_arg1 = 0;
 185static long newselect_arg2 = 0;
 186static long newselect_arg3 = 0;
 187static long newselect_arg4 = 0;
 188static long newselect_arg5 = 0;
 189
 190static void
 191print_newselect(const struct syscallname *name,
 192                abi_long arg1, abi_long arg2, abi_long arg3,
 193                abi_long arg4, abi_long arg5, abi_long arg6)
 194{
 195    gemu_log("%s(" TARGET_ABI_FMT_ld ",", name->name, arg1);
 196    print_fdset(arg1, arg2);
 197    gemu_log(",");
 198    print_fdset(arg1, arg3);
 199    gemu_log(",");
 200    print_fdset(arg1, arg4);
 201    gemu_log(",");
 202    print_timeval(arg5, 1);
 203    gemu_log(")");
 204
 205    /* save for use in the return output function below */
 206    newselect_arg1=arg1;
 207    newselect_arg2=arg2;
 208    newselect_arg3=arg3;
 209    newselect_arg4=arg4;
 210    newselect_arg5=arg5;
 211}
 212#endif
 213
 214#ifdef TARGET_NR_semctl
 215static void
 216print_semctl(const struct syscallname *name,
 217             abi_long arg1, abi_long arg2, abi_long arg3,
 218             abi_long arg4, abi_long arg5, abi_long arg6)
 219{
 220    gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", name->name, arg1, arg2);
 221    print_ipc_cmd(arg3);
 222    gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
 223}
 224#endif
 225
 226static void
 227print_execve(const struct syscallname *name,
 228             abi_long arg1, abi_long arg2, abi_long arg3,
 229             abi_long arg4, abi_long arg5, abi_long arg6)
 230{
 231    abi_ulong arg_ptr_addr;
 232    char *s;
 233
 234    if (!(s = lock_user_string(arg1)))
 235        return;
 236    gemu_log("%s(\"%s\",{", name->name, s);
 237    unlock_user(s, arg1, 0);
 238
 239    for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
 240        abi_ulong *arg_ptr, arg_addr;
 241
 242        arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
 243        if (!arg_ptr)
 244            return;
 245    arg_addr = tswapal(*arg_ptr);
 246        unlock_user(arg_ptr, arg_ptr_addr, 0);
 247        if (!arg_addr)
 248            break;
 249        if ((s = lock_user_string(arg_addr))) {
 250            gemu_log("\"%s\",", s);
 251            unlock_user(s, arg_addr, 0);
 252        }
 253    }
 254
 255    gemu_log("NULL})");
 256}
 257
 258#ifdef TARGET_NR_ipc
 259static void
 260print_ipc(const struct syscallname *name,
 261          abi_long arg1, abi_long arg2, abi_long arg3,
 262          abi_long arg4, abi_long arg5, abi_long arg6)
 263{
 264    switch(arg1) {
 265    case IPCOP_semctl:
 266        gemu_log("semctl(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", arg1, arg2);
 267        print_ipc_cmd(arg3);
 268        gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
 269        break;
 270    default:
 271        gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")",
 272                 name->name, arg1, arg2, arg3, arg4);
 273    }
 274}
 275#endif
 276
 277/*
 278 * Variants for the return value output function
 279 */
 280
 281static void
 282print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
 283{
 284    char *errstr = NULL;
 285
 286    if (ret < 0) {
 287        errstr = target_strerror(-ret);
 288    }
 289    if (errstr) {
 290        gemu_log(" = -1 errno=%d (%s)\n", (int)-ret, errstr);
 291    } else {
 292        gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
 293    }
 294}
 295
 296#if 0 /* currently unused */
 297static void
 298print_syscall_ret_raw(struct syscallname *name, abi_long ret)
 299{
 300        gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
 301}
 302#endif
 303
 304#ifdef TARGET_NR__newselect
 305static void
 306print_syscall_ret_newselect(const struct syscallname *name, abi_long ret)
 307{
 308    gemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
 309    print_fdset(newselect_arg1,newselect_arg2);
 310    gemu_log(",");
 311    print_fdset(newselect_arg1,newselect_arg3);
 312    gemu_log(",");
 313    print_fdset(newselect_arg1,newselect_arg4);
 314    gemu_log(",");
 315    print_timeval(newselect_arg5, 1);
 316    gemu_log(")\n");
 317}
 318#endif
 319
 320UNUSED static struct flags access_flags[] = {
 321    FLAG_GENERIC(F_OK),
 322    FLAG_GENERIC(R_OK),
 323    FLAG_GENERIC(W_OK),
 324    FLAG_GENERIC(X_OK),
 325    FLAG_END,
 326};
 327
 328UNUSED static struct flags at_file_flags[] = {
 329#ifdef AT_EACCESS
 330    FLAG_GENERIC(AT_EACCESS),
 331#endif
 332#ifdef AT_SYMLINK_NOFOLLOW
 333    FLAG_GENERIC(AT_SYMLINK_NOFOLLOW),
 334#endif
 335    FLAG_END,
 336};
 337
 338UNUSED static struct flags unlinkat_flags[] = {
 339#ifdef AT_REMOVEDIR
 340    FLAG_GENERIC(AT_REMOVEDIR),
 341#endif
 342    FLAG_END,
 343};
 344
 345UNUSED static struct flags mode_flags[] = {
 346    FLAG_GENERIC(S_IFSOCK),
 347    FLAG_GENERIC(S_IFLNK),
 348    FLAG_GENERIC(S_IFREG),
 349    FLAG_GENERIC(S_IFBLK),
 350    FLAG_GENERIC(S_IFDIR),
 351    FLAG_GENERIC(S_IFCHR),
 352    FLAG_GENERIC(S_IFIFO),
 353    FLAG_END,
 354};
 355
 356UNUSED static struct flags open_access_flags[] = {
 357    FLAG_TARGET(O_RDONLY),
 358    FLAG_TARGET(O_WRONLY),
 359    FLAG_TARGET(O_RDWR),
 360    FLAG_END,
 361};
 362
 363UNUSED static struct flags open_flags[] = {
 364    FLAG_TARGET(O_APPEND),
 365    FLAG_TARGET(O_CREAT),
 366    FLAG_TARGET(O_DIRECTORY),
 367    FLAG_TARGET(O_EXCL),
 368    FLAG_TARGET(O_LARGEFILE),
 369    FLAG_TARGET(O_NOCTTY),
 370    FLAG_TARGET(O_NOFOLLOW),
 371    FLAG_TARGET(O_NONBLOCK),      /* also O_NDELAY */
 372    FLAG_TARGET(O_DSYNC),
 373    FLAG_TARGET(__O_SYNC),
 374    FLAG_TARGET(O_TRUNC),
 375#ifdef O_DIRECT
 376    FLAG_TARGET(O_DIRECT),
 377#endif
 378#ifdef O_NOATIME
 379    FLAG_TARGET(O_NOATIME),
 380#endif
 381#ifdef O_CLOEXEC
 382    FLAG_TARGET(O_CLOEXEC),
 383#endif
 384#ifdef O_PATH
 385    FLAG_TARGET(O_PATH),
 386#endif
 387    FLAG_END,
 388};
 389
 390UNUSED static struct flags mount_flags[] = {
 391#ifdef MS_BIND
 392    FLAG_GENERIC(MS_BIND),
 393#endif
 394#ifdef MS_DIRSYNC
 395    FLAG_GENERIC(MS_DIRSYNC),
 396#endif
 397    FLAG_GENERIC(MS_MANDLOCK),
 398#ifdef MS_MOVE
 399    FLAG_GENERIC(MS_MOVE),
 400#endif
 401    FLAG_GENERIC(MS_NOATIME),
 402    FLAG_GENERIC(MS_NODEV),
 403    FLAG_GENERIC(MS_NODIRATIME),
 404    FLAG_GENERIC(MS_NOEXEC),
 405    FLAG_GENERIC(MS_NOSUID),
 406    FLAG_GENERIC(MS_RDONLY),
 407#ifdef MS_RELATIME
 408    FLAG_GENERIC(MS_RELATIME),
 409#endif
 410    FLAG_GENERIC(MS_REMOUNT),
 411    FLAG_GENERIC(MS_SYNCHRONOUS),
 412    FLAG_END,
 413};
 414
 415UNUSED static struct flags umount2_flags[] = {
 416#ifdef MNT_FORCE
 417    FLAG_GENERIC(MNT_FORCE),
 418#endif
 419#ifdef MNT_DETACH
 420    FLAG_GENERIC(MNT_DETACH),
 421#endif
 422#ifdef MNT_EXPIRE
 423    FLAG_GENERIC(MNT_EXPIRE),
 424#endif
 425    FLAG_END,
 426};
 427
 428UNUSED static struct flags mmap_prot_flags[] = {
 429    FLAG_GENERIC(PROT_NONE),
 430    FLAG_GENERIC(PROT_EXEC),
 431    FLAG_GENERIC(PROT_READ),
 432    FLAG_GENERIC(PROT_WRITE),
 433    FLAG_TARGET(PROT_SEM),
 434    FLAG_GENERIC(PROT_GROWSDOWN),
 435    FLAG_GENERIC(PROT_GROWSUP),
 436    FLAG_END,
 437};
 438
 439UNUSED static struct flags mmap_flags[] = {
 440    FLAG_TARGET(MAP_SHARED),
 441    FLAG_TARGET(MAP_PRIVATE),
 442    FLAG_TARGET(MAP_ANONYMOUS),
 443    FLAG_TARGET(MAP_DENYWRITE),
 444    FLAG_TARGET(MAP_FIXED),
 445    FLAG_TARGET(MAP_GROWSDOWN),
 446    FLAG_TARGET(MAP_EXECUTABLE),
 447#ifdef MAP_LOCKED
 448    FLAG_TARGET(MAP_LOCKED),
 449#endif
 450#ifdef MAP_NONBLOCK
 451    FLAG_TARGET(MAP_NONBLOCK),
 452#endif
 453    FLAG_TARGET(MAP_NORESERVE),
 454#ifdef MAP_POPULATE
 455    FLAG_TARGET(MAP_POPULATE),
 456#endif
 457#ifdef TARGET_MAP_UNINITIALIZED
 458    FLAG_TARGET(MAP_UNINITIALIZED),
 459#endif
 460    FLAG_END,
 461};
 462
 463UNUSED static struct flags clone_flags[] = {
 464    FLAG_GENERIC(CLONE_VM),
 465    FLAG_GENERIC(CLONE_FS),
 466    FLAG_GENERIC(CLONE_FILES),
 467    FLAG_GENERIC(CLONE_SIGHAND),
 468    FLAG_GENERIC(CLONE_PTRACE),
 469    FLAG_GENERIC(CLONE_VFORK),
 470    FLAG_GENERIC(CLONE_PARENT),
 471    FLAG_GENERIC(CLONE_THREAD),
 472    FLAG_GENERIC(CLONE_NEWNS),
 473    FLAG_GENERIC(CLONE_SYSVSEM),
 474    FLAG_GENERIC(CLONE_SETTLS),
 475    FLAG_GENERIC(CLONE_PARENT_SETTID),
 476    FLAG_GENERIC(CLONE_CHILD_CLEARTID),
 477    FLAG_GENERIC(CLONE_DETACHED),
 478    FLAG_GENERIC(CLONE_UNTRACED),
 479    FLAG_GENERIC(CLONE_CHILD_SETTID),
 480#if defined(CLONE_NEWUTS)
 481    FLAG_GENERIC(CLONE_NEWUTS),
 482#endif
 483#if defined(CLONE_NEWIPC)
 484    FLAG_GENERIC(CLONE_NEWIPC),
 485#endif
 486#if defined(CLONE_NEWUSER)
 487    FLAG_GENERIC(CLONE_NEWUSER),
 488#endif
 489#if defined(CLONE_NEWPID)
 490    FLAG_GENERIC(CLONE_NEWPID),
 491#endif
 492#if defined(CLONE_NEWNET)
 493    FLAG_GENERIC(CLONE_NEWNET),
 494#endif
 495#if defined(CLONE_IO)
 496    FLAG_GENERIC(CLONE_IO),
 497#endif
 498    FLAG_END,
 499};
 500
 501/*
 502 * print_xxx utility functions.  These are used to print syscall
 503 * parameters in certain format.  All of these have parameter
 504 * named 'last'.  This parameter is used to add comma to output
 505 * when last == 0.
 506 */
 507
 508static const char *
 509get_comma(int last)
 510{
 511    return ((last) ? "" : ",");
 512}
 513
 514static void
 515print_flags(const struct flags *f, abi_long flags, int last)
 516{
 517    const char *sep = "";
 518    int n;
 519
 520    if ((flags == 0) && (f->f_value == 0)) {
 521        gemu_log("%s%s", f->f_string, get_comma(last));
 522        return;
 523    }
 524    for (n = 0; f->f_string != NULL; f++) {
 525        if ((f->f_value != 0) && ((flags & f->f_value) == f->f_value)) {
 526            gemu_log("%s%s", sep, f->f_string);
 527            flags &= ~f->f_value;
 528            sep = "|";
 529            n++;
 530        }
 531    }
 532
 533    if (n > 0) {
 534        /* print rest of the flags as numeric */
 535        if (flags != 0) {
 536            gemu_log("%s%#x%s", sep, (unsigned int)flags, get_comma(last));
 537        } else {
 538            gemu_log("%s", get_comma(last));
 539        }
 540    } else {
 541        /* no string version of flags found, print them in hex then */
 542        gemu_log("%#x%s", (unsigned int)flags, get_comma(last));
 543    }
 544}
 545
 546static void
 547print_at_dirfd(abi_long dirfd, int last)
 548{
 549#ifdef AT_FDCWD
 550    if (dirfd == AT_FDCWD) {
 551        gemu_log("AT_FDCWD%s", get_comma(last));
 552        return;
 553    }
 554#endif
 555    gemu_log("%d%s", (int)dirfd, get_comma(last));
 556}
 557
 558static void
 559print_file_mode(abi_long mode, int last)
 560{
 561    const char *sep = "";
 562    const struct flags *m;
 563
 564    for (m = &mode_flags[0]; m->f_string != NULL; m++) {
 565        if ((m->f_value & mode) == m->f_value) {
 566            gemu_log("%s%s", m->f_string, sep);
 567            sep = "|";
 568            mode &= ~m->f_value;
 569            break;
 570        }
 571    }
 572
 573    mode &= ~S_IFMT;
 574    /* print rest of the mode as octal */
 575    if (mode != 0)
 576        gemu_log("%s%#o", sep, (unsigned int)mode);
 577
 578    gemu_log("%s", get_comma(last));
 579}
 580
 581static void
 582print_open_flags(abi_long flags, int last)
 583{
 584    print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1);
 585    flags &= ~TARGET_O_ACCMODE;
 586    if (flags == 0) {
 587        gemu_log("%s", get_comma(last));
 588        return;
 589    }
 590    gemu_log("|");
 591    print_flags(open_flags, flags, last);
 592}
 593
 594static void
 595print_syscall_prologue(const struct syscallname *sc)
 596{
 597    gemu_log("%s(", sc->name);
 598}
 599
 600/*ARGSUSED*/
 601static void
 602print_syscall_epilogue(const struct syscallname *sc)
 603{
 604    (void)sc;
 605    gemu_log(")");
 606}
 607
 608static void
 609print_string(abi_long addr, int last)
 610{
 611    char *s;
 612
 613    if ((s = lock_user_string(addr)) != NULL) {
 614        gemu_log("\"%s\"%s", s, get_comma(last));
 615        unlock_user(s, addr, 0);
 616    } else {
 617        /* can't get string out of it, so print it as pointer */
 618        print_pointer(addr, last);
 619    }
 620}
 621
 622/*
 623 * Prints out raw parameter using given format.  Caller needs
 624 * to do byte swapping if needed.
 625 */
 626static void
 627print_raw_param(const char *fmt, abi_long param, int last)
 628{
 629    char format[64];
 630
 631    (void) snprintf(format, sizeof (format), "%s%s", fmt, get_comma(last));
 632    gemu_log(format, param);
 633}
 634
 635static void
 636print_pointer(abi_long p, int last)
 637{
 638    if (p == 0)
 639        gemu_log("NULL%s", get_comma(last));
 640    else
 641        gemu_log("0x" TARGET_ABI_FMT_lx "%s", p, get_comma(last));
 642}
 643
 644/*
 645 * Reads 32-bit (int) number from guest address space from
 646 * address 'addr' and prints it.
 647 */
 648static void
 649print_number(abi_long addr, int last)
 650{
 651    if (addr == 0) {
 652        gemu_log("NULL%s", get_comma(last));
 653    } else {
 654        int num;
 655
 656        get_user_s32(num, addr);
 657        gemu_log("[%d]%s", num, get_comma(last));
 658    }
 659}
 660
 661static void
 662print_timeval(abi_ulong tv_addr, int last)
 663{
 664    if( tv_addr ) {
 665        struct target_timeval *tv;
 666
 667        tv = lock_user(VERIFY_READ, tv_addr, sizeof(*tv), 1);
 668        if (!tv)
 669            return;
 670        gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}%s",
 671            tswapal(tv->tv_sec), tswapal(tv->tv_usec), get_comma(last));
 672        unlock_user(tv, tv_addr, 0);
 673    } else
 674        gemu_log("NULL%s", get_comma(last));
 675}
 676
 677#undef UNUSED
 678
 679#ifdef TARGET_NR_accept
 680static void
 681print_accept(const struct syscallname *name,
 682    abi_long arg0, abi_long arg1, abi_long arg2,
 683    abi_long arg3, abi_long arg4, abi_long arg5)
 684{
 685    print_syscall_prologue(name);
 686    print_raw_param("%d", arg0, 0);
 687    print_pointer(arg1, 0);
 688    print_number(arg2, 1);
 689    print_syscall_epilogue(name);
 690}
 691#endif
 692
 693#ifdef TARGET_NR_access
 694static void
 695print_access(const struct syscallname *name,
 696    abi_long arg0, abi_long arg1, abi_long arg2,
 697    abi_long arg3, abi_long arg4, abi_long arg5)
 698{
 699    print_syscall_prologue(name);
 700    print_string(arg0, 0);
 701    print_flags(access_flags, arg1, 1);
 702    print_syscall_epilogue(name);
 703}
 704#endif
 705
 706#ifdef TARGET_NR_brk
 707static void
 708print_brk(const struct syscallname *name,
 709    abi_long arg0, abi_long arg1, abi_long arg2,
 710    abi_long arg3, abi_long arg4, abi_long arg5)
 711{
 712    print_syscall_prologue(name);
 713    print_pointer(arg0, 1);
 714    print_syscall_epilogue(name);
 715}
 716#endif
 717
 718#ifdef TARGET_NR_chdir
 719static void
 720print_chdir(const struct syscallname *name,
 721    abi_long arg0, abi_long arg1, abi_long arg2,
 722    abi_long arg3, abi_long arg4, abi_long arg5)
 723{
 724    print_syscall_prologue(name);
 725    print_string(arg0, 1);
 726    print_syscall_epilogue(name);
 727}
 728#endif
 729
 730#ifdef TARGET_NR_chmod
 731static void
 732print_chmod(const struct syscallname *name,
 733    abi_long arg0, abi_long arg1, abi_long arg2,
 734    abi_long arg3, abi_long arg4, abi_long arg5)
 735{
 736    print_syscall_prologue(name);
 737    print_string(arg0, 0);
 738    print_file_mode(arg1, 1);
 739    print_syscall_epilogue(name);
 740}
 741#endif
 742
 743#ifdef TARGET_NR_clone
 744static void
 745print_clone(const struct syscallname *name,
 746    abi_long arg0, abi_long arg1, abi_long arg2,
 747    abi_long arg3, abi_long arg4, abi_long arg5)
 748{
 749    print_syscall_prologue(name);
 750#if defined(TARGET_M68K)
 751    print_flags(clone_flags, arg0, 0);
 752    print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1);
 753#elif defined(TARGET_SH4) || defined(TARGET_ALPHA)
 754    print_flags(clone_flags, arg0, 0);
 755    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
 756    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
 757    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0);
 758    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1);
 759#elif defined(TARGET_CRIS)
 760    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0);
 761    print_flags(clone_flags, arg1, 0);
 762    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
 763    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
 764    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
 765#else
 766    print_flags(clone_flags, arg0, 0);
 767    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
 768    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
 769    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
 770    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
 771#endif
 772    print_syscall_epilogue(name);
 773}
 774#endif
 775
 776#ifdef TARGET_NR_creat
 777static void
 778print_creat(const struct syscallname *name,
 779    abi_long arg0, abi_long arg1, abi_long arg2,
 780    abi_long arg3, abi_long arg4, abi_long arg5)
 781{
 782    print_syscall_prologue(name);
 783    print_string(arg0, 0);
 784    print_file_mode(arg1, 1);
 785    print_syscall_epilogue(name);
 786}
 787#endif
 788
 789#ifdef TARGET_NR_execv
 790static void
 791print_execv(const struct syscallname *name,
 792    abi_long arg0, abi_long arg1, abi_long arg2,
 793    abi_long arg3, abi_long arg4, abi_long arg5)
 794{
 795    print_syscall_prologue(name);
 796    print_string(arg0, 0);
 797    print_raw_param("0x" TARGET_ABI_FMT_lx, arg1, 1);
 798    print_syscall_epilogue(name);
 799}
 800#endif
 801
 802#ifdef TARGET_NR_faccessat
 803static void
 804print_faccessat(const struct syscallname *name,
 805    abi_long arg0, abi_long arg1, abi_long arg2,
 806    abi_long arg3, abi_long arg4, abi_long arg5)
 807{
 808    print_syscall_prologue(name);
 809    print_at_dirfd(arg0, 0);
 810    print_string(arg1, 0);
 811    print_flags(access_flags, arg2, 0);
 812    print_flags(at_file_flags, arg3, 1);
 813    print_syscall_epilogue(name);
 814}
 815#endif
 816
 817#ifdef TARGET_NR_fchmodat
 818static void
 819print_fchmodat(const struct syscallname *name,
 820    abi_long arg0, abi_long arg1, abi_long arg2,
 821    abi_long arg3, abi_long arg4, abi_long arg5)
 822{
 823    print_syscall_prologue(name);
 824    print_at_dirfd(arg0, 0);
 825    print_string(arg1, 0);
 826    print_file_mode(arg2, 0);
 827    print_flags(at_file_flags, arg3, 1);
 828    print_syscall_epilogue(name);
 829}
 830#endif
 831
 832#ifdef TARGET_NR_fchownat
 833static void
 834print_fchownat(const struct syscallname *name,
 835    abi_long arg0, abi_long arg1, abi_long arg2,
 836    abi_long arg3, abi_long arg4, abi_long arg5)
 837{
 838    print_syscall_prologue(name);
 839    print_at_dirfd(arg0, 0);
 840    print_string(arg1, 0);
 841    print_raw_param("%d", arg2, 0);
 842    print_raw_param("%d", arg3, 0);
 843    print_flags(at_file_flags, arg4, 1);
 844    print_syscall_epilogue(name);
 845}
 846#endif
 847
 848#if defined(TARGET_NR_fcntl) || defined(TARGET_NR_fcntl64)
 849static void
 850print_fcntl(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_raw_param("%d", arg0, 0);
 856    switch(arg1) {
 857    case TARGET_F_DUPFD:
 858        gemu_log("F_DUPFD,");
 859        print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
 860        break;
 861    case TARGET_F_GETFD:
 862        gemu_log("F_GETFD");
 863        break;
 864    case TARGET_F_SETFD:
 865        gemu_log("F_SETFD,");
 866        print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
 867        break;
 868    case TARGET_F_GETFL:
 869        gemu_log("F_GETFL");
 870        break;
 871    case TARGET_F_SETFL:
 872        gemu_log("F_SETFL,");
 873        print_open_flags(arg2, 1);
 874        break;
 875    case TARGET_F_GETLK:
 876        gemu_log("F_GETLK,");
 877        print_pointer(arg2, 1);
 878        break;
 879    case TARGET_F_SETLK:
 880        gemu_log("F_SETLK,");
 881        print_pointer(arg2, 1);
 882        break;
 883    case TARGET_F_SETLKW:
 884        gemu_log("F_SETLKW,");
 885        print_pointer(arg2, 1);
 886        break;
 887    case TARGET_F_GETOWN:
 888        gemu_log("F_GETOWN");
 889        break;
 890    case TARGET_F_SETOWN:
 891        gemu_log("F_SETOWN,");
 892        print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
 893        break;
 894    case TARGET_F_GETSIG:
 895        gemu_log("F_GETSIG");
 896        break;
 897    case TARGET_F_SETSIG:
 898        gemu_log("F_SETSIG,");
 899        print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
 900        break;
 901#if TARGET_ABI_BITS == 32
 902    case TARGET_F_GETLK64:
 903        gemu_log("F_GETLK64,");
 904        print_pointer(arg2, 1);
 905        break;
 906    case TARGET_F_SETLK64:
 907        gemu_log("F_SETLK64,");
 908        print_pointer(arg2, 1);
 909        break;
 910    case TARGET_F_SETLKW64:
 911        gemu_log("F_SETLKW64,");
 912        print_pointer(arg2, 1);
 913        break;
 914#endif
 915    case TARGET_F_SETLEASE:
 916        gemu_log("F_SETLEASE,");
 917        print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
 918        break;
 919    case TARGET_F_GETLEASE:
 920        gemu_log("F_GETLEASE");
 921        break;
 922    case TARGET_F_DUPFD_CLOEXEC:
 923        gemu_log("F_DUPFD_CLOEXEC,");
 924        print_raw_param(TARGET_ABI_FMT_ld, arg2, 1);
 925        break;
 926    case TARGET_F_NOTIFY:
 927        gemu_log("F_NOTIFY,");
 928        print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
 929        break;
 930    default:
 931        print_raw_param(TARGET_ABI_FMT_ld, arg1, 0);
 932        print_pointer(arg2, 1);
 933        break;
 934    }
 935    print_syscall_epilogue(name);
 936}
 937#define print_fcntl64   print_fcntl
 938#endif
 939
 940
 941#ifdef TARGET_NR_futimesat
 942static void
 943print_futimesat(const struct syscallname *name,
 944    abi_long arg0, abi_long arg1, abi_long arg2,
 945    abi_long arg3, abi_long arg4, abi_long arg5)
 946{
 947    print_syscall_prologue(name);
 948    print_at_dirfd(arg0, 0);
 949    print_string(arg1, 0);
 950    print_timeval(arg2, 0);
 951    print_timeval(arg2 + sizeof (struct target_timeval), 1);
 952    print_syscall_epilogue(name);
 953}
 954#endif
 955
 956#ifdef TARGET_NR_link
 957static void
 958print_link(const struct syscallname *name,
 959    abi_long arg0, abi_long arg1, abi_long arg2,
 960    abi_long arg3, abi_long arg4, abi_long arg5)
 961{
 962    print_syscall_prologue(name);
 963    print_string(arg0, 0);
 964    print_string(arg1, 1);
 965    print_syscall_epilogue(name);
 966}
 967#endif
 968
 969#ifdef TARGET_NR_linkat
 970static void
 971print_linkat(const struct syscallname *name,
 972    abi_long arg0, abi_long arg1, abi_long arg2,
 973    abi_long arg3, abi_long arg4, abi_long arg5)
 974{
 975    print_syscall_prologue(name);
 976    print_at_dirfd(arg0, 0);
 977    print_string(arg1, 0);
 978    print_at_dirfd(arg2, 0);
 979    print_string(arg3, 0);
 980    print_flags(at_file_flags, arg4, 1);
 981    print_syscall_epilogue(name);
 982}
 983#endif
 984
 985#ifdef TARGET_NR__llseek
 986static void
 987print__llseek(const struct syscallname *name,
 988    abi_long arg0, abi_long arg1, abi_long arg2,
 989    abi_long arg3, abi_long arg4, abi_long arg5)
 990{
 991    const char *whence = "UNKNOWN";
 992    print_syscall_prologue(name);
 993    print_raw_param("%d", arg0, 0);
 994    print_raw_param("%ld", arg1, 0);
 995    print_raw_param("%ld", arg2, 0);
 996    print_pointer(arg3, 0);
 997    switch(arg4) {
 998    case SEEK_SET: whence = "SEEK_SET"; break;
 999    case SEEK_CUR: whence = "SEEK_CUR"; break;
1000    case SEEK_END: whence = "SEEK_END"; break;
1001    }
1002    gemu_log("%s",whence);
1003    print_syscall_epilogue(name);
1004}
1005#endif
1006
1007#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
1008    defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64)
1009static void
1010print_stat(const struct syscallname *name,
1011    abi_long arg0, abi_long arg1, abi_long arg2,
1012    abi_long arg3, abi_long arg4, abi_long arg5)
1013{
1014    print_syscall_prologue(name);
1015    print_string(arg0, 0);
1016    print_pointer(arg1, 1);
1017    print_syscall_epilogue(name);
1018}
1019#define print_lstat     print_stat
1020#define print_stat64    print_stat
1021#define print_lstat64   print_stat
1022#endif
1023
1024#if defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
1025static void
1026print_fstat(const struct syscallname *name,
1027    abi_long arg0, abi_long arg1, abi_long arg2,
1028    abi_long arg3, abi_long arg4, abi_long arg5)
1029{
1030    print_syscall_prologue(name);
1031    print_raw_param("%d", arg0, 0);
1032    print_pointer(arg1, 1);
1033    print_syscall_epilogue(name);
1034}
1035#define print_fstat64     print_fstat
1036#endif
1037
1038#ifdef TARGET_NR_mkdir
1039static void
1040print_mkdir(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_string(arg0, 0);
1046    print_file_mode(arg1, 1);
1047    print_syscall_epilogue(name);
1048}
1049#endif
1050
1051#ifdef TARGET_NR_mkdirat
1052static void
1053print_mkdirat(const struct syscallname *name,
1054    abi_long arg0, abi_long arg1, abi_long arg2,
1055    abi_long arg3, abi_long arg4, abi_long arg5)
1056{
1057    print_syscall_prologue(name);
1058    print_at_dirfd(arg0, 0);
1059    print_string(arg1, 0);
1060    print_file_mode(arg2, 1);
1061    print_syscall_epilogue(name);
1062}
1063#endif
1064
1065#ifdef TARGET_NR_rmdir
1066static void
1067print_rmdir(const struct syscallname *name,
1068    abi_long arg0, abi_long arg1, abi_long arg2,
1069    abi_long arg3, abi_long arg4, abi_long arg5)
1070{
1071    print_syscall_prologue(name);
1072    print_string(arg0, 0);
1073    print_syscall_epilogue(name);
1074}
1075#endif
1076
1077#ifdef TARGET_NR_rt_sigaction
1078static void
1079print_rt_sigaction(const struct syscallname *name,
1080    abi_long arg0, abi_long arg1, abi_long arg2,
1081    abi_long arg3, abi_long arg4, abi_long arg5)
1082{
1083    print_syscall_prologue(name);
1084    print_signal(arg0, 0);
1085    print_pointer(arg1, 0);
1086    print_pointer(arg2, 1);
1087    print_syscall_epilogue(name);
1088}
1089#endif
1090
1091#ifdef TARGET_NR_rt_sigprocmask
1092static void
1093print_rt_sigprocmask(const struct syscallname *name,
1094    abi_long arg0, abi_long arg1, abi_long arg2,
1095    abi_long arg3, abi_long arg4, abi_long arg5)
1096{
1097    const char *how = "UNKNOWN";
1098    print_syscall_prologue(name);
1099    switch(arg0) {
1100    case TARGET_SIG_BLOCK: how = "SIG_BLOCK"; break;
1101    case TARGET_SIG_UNBLOCK: how = "SIG_UNBLOCK"; break;
1102    case TARGET_SIG_SETMASK: how = "SIG_SETMASK"; break;
1103    }
1104    gemu_log("%s,",how);
1105    print_pointer(arg1, 0);
1106    print_pointer(arg2, 1);
1107    print_syscall_epilogue(name);
1108}
1109#endif
1110
1111#ifdef TARGET_NR_mknod
1112static void
1113print_mknod(const struct syscallname *name,
1114    abi_long arg0, abi_long arg1, abi_long arg2,
1115    abi_long arg3, abi_long arg4, abi_long arg5)
1116{
1117    int hasdev = (arg1 & (S_IFCHR|S_IFBLK));
1118
1119    print_syscall_prologue(name);
1120    print_string(arg0, 0);
1121    print_file_mode(arg1, (hasdev == 0));
1122    if (hasdev) {
1123        print_raw_param("makedev(%d", major(arg2), 0);
1124        print_raw_param("%d)", minor(arg2), 1);
1125    }
1126    print_syscall_epilogue(name);
1127}
1128#endif
1129
1130#ifdef TARGET_NR_mknodat
1131static void
1132print_mknodat(const struct syscallname *name,
1133    abi_long arg0, abi_long arg1, abi_long arg2,
1134    abi_long arg3, abi_long arg4, abi_long arg5)
1135{
1136    int hasdev = (arg2 & (S_IFCHR|S_IFBLK));
1137
1138    print_syscall_prologue(name);
1139    print_at_dirfd(arg0, 0);
1140    print_string(arg1, 0);
1141    print_file_mode(arg2, (hasdev == 0));
1142    if (hasdev) {
1143        print_raw_param("makedev(%d", major(arg3), 0);
1144        print_raw_param("%d)", minor(arg3), 1);
1145    }
1146    print_syscall_epilogue(name);
1147}
1148#endif
1149
1150#ifdef TARGET_NR_mq_open
1151static void
1152print_mq_open(const struct syscallname *name,
1153    abi_long arg0, abi_long arg1, abi_long arg2,
1154    abi_long arg3, abi_long arg4, abi_long arg5)
1155{
1156    int is_creat = (arg1 & TARGET_O_CREAT);
1157
1158    print_syscall_prologue(name);
1159    print_string(arg0, 0);
1160    print_open_flags(arg1, (is_creat == 0));
1161    if (is_creat) {
1162        print_file_mode(arg2, 0);
1163        print_pointer(arg3, 1);
1164    }
1165    print_syscall_epilogue(name);
1166}
1167#endif
1168
1169#ifdef TARGET_NR_open
1170static void
1171print_open(const struct syscallname *name,
1172    abi_long arg0, abi_long arg1, abi_long arg2,
1173    abi_long arg3, abi_long arg4, abi_long arg5)
1174{
1175    int is_creat = (arg1 & TARGET_O_CREAT);
1176
1177    print_syscall_prologue(name);
1178    print_string(arg0, 0);
1179    print_open_flags(arg1, (is_creat == 0));
1180    if (is_creat)
1181        print_file_mode(arg2, 1);
1182    print_syscall_epilogue(name);
1183}
1184#endif
1185
1186#ifdef TARGET_NR_openat
1187static void
1188print_openat(const struct syscallname *name,
1189    abi_long arg0, abi_long arg1, abi_long arg2,
1190    abi_long arg3, abi_long arg4, abi_long arg5)
1191{
1192    int is_creat = (arg2 & TARGET_O_CREAT);
1193
1194    print_syscall_prologue(name);
1195    print_at_dirfd(arg0, 0);
1196    print_string(arg1, 0);
1197    print_open_flags(arg2, (is_creat == 0));
1198    if (is_creat)
1199        print_file_mode(arg3, 1);
1200    print_syscall_epilogue(name);
1201}
1202#endif
1203
1204#ifdef TARGET_NR_mq_unlink
1205static void
1206print_mq_unlink(const struct syscallname *name,
1207    abi_long arg0, abi_long arg1, abi_long arg2,
1208    abi_long arg3, abi_long arg4, abi_long arg5)
1209{
1210    print_syscall_prologue(name);
1211    print_string(arg0, 1);
1212    print_syscall_epilogue(name);
1213}
1214#endif
1215
1216#if defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)
1217static void
1218print_fstatat64(const struct syscallname *name,
1219    abi_long arg0, abi_long arg1, abi_long arg2,
1220    abi_long arg3, abi_long arg4, abi_long arg5)
1221{
1222    print_syscall_prologue(name);
1223    print_at_dirfd(arg0, 0);
1224    print_string(arg1, 0);
1225    print_pointer(arg2, 0);
1226    print_flags(at_file_flags, arg3, 1);
1227    print_syscall_epilogue(name);
1228}
1229#define print_newfstatat    print_fstatat64
1230#endif
1231
1232#ifdef TARGET_NR_readlink
1233static void
1234print_readlink(const struct syscallname *name,
1235    abi_long arg0, abi_long arg1, abi_long arg2,
1236    abi_long arg3, abi_long arg4, abi_long arg5)
1237{
1238    print_syscall_prologue(name);
1239    print_string(arg0, 0);
1240    print_pointer(arg1, 0);
1241    print_raw_param("%u", arg2, 1);
1242    print_syscall_epilogue(name);
1243}
1244#endif
1245
1246#ifdef TARGET_NR_readlinkat
1247static void
1248print_readlinkat(const struct syscallname *name,
1249    abi_long arg0, abi_long arg1, abi_long arg2,
1250    abi_long arg3, abi_long arg4, abi_long arg5)
1251{
1252    print_syscall_prologue(name);
1253    print_at_dirfd(arg0, 0);
1254    print_string(arg1, 0);
1255    print_pointer(arg2, 0);
1256    print_raw_param("%u", arg3, 1);
1257    print_syscall_epilogue(name);
1258}
1259#endif
1260
1261#ifdef TARGET_NR_rename
1262static void
1263print_rename(const struct syscallname *name,
1264    abi_long arg0, abi_long arg1, abi_long arg2,
1265    abi_long arg3, abi_long arg4, abi_long arg5)
1266{
1267    print_syscall_prologue(name);
1268    print_string(arg0, 0);
1269    print_string(arg1, 1);
1270    print_syscall_epilogue(name);
1271}
1272#endif
1273
1274#ifdef TARGET_NR_renameat
1275static void
1276print_renameat(const struct syscallname *name,
1277    abi_long arg0, abi_long arg1, abi_long arg2,
1278    abi_long arg3, abi_long arg4, abi_long arg5)
1279{
1280    print_syscall_prologue(name);
1281    print_at_dirfd(arg0, 0);
1282    print_string(arg1, 0);
1283    print_at_dirfd(arg2, 0);
1284    print_string(arg3, 1);
1285    print_syscall_epilogue(name);
1286}
1287#endif
1288
1289#ifdef TARGET_NR_statfs
1290static void
1291print_statfs(const struct syscallname *name,
1292    abi_long arg0, abi_long arg1, abi_long arg2,
1293    abi_long arg3, abi_long arg4, abi_long arg5)
1294{
1295    print_syscall_prologue(name);
1296    print_string(arg0, 0);
1297    print_pointer(arg1, 1);
1298    print_syscall_epilogue(name);
1299}
1300#define print_statfs64  print_statfs
1301#endif
1302
1303#ifdef TARGET_NR_symlink
1304static void
1305print_symlink(const struct syscallname *name,
1306    abi_long arg0, abi_long arg1, abi_long arg2,
1307    abi_long arg3, abi_long arg4, abi_long arg5)
1308{
1309    print_syscall_prologue(name);
1310    print_string(arg0, 0);
1311    print_string(arg1, 1);
1312    print_syscall_epilogue(name);
1313}
1314#endif
1315
1316#ifdef TARGET_NR_symlinkat
1317static void
1318print_symlinkat(const struct syscallname *name,
1319    abi_long arg0, abi_long arg1, abi_long arg2,
1320    abi_long arg3, abi_long arg4, abi_long arg5)
1321{
1322    print_syscall_prologue(name);
1323    print_string(arg0, 0);
1324    print_at_dirfd(arg1, 0);
1325    print_string(arg2, 1);
1326    print_syscall_epilogue(name);
1327}
1328#endif
1329
1330#ifdef TARGET_NR_mount
1331static void
1332print_mount(const struct syscallname *name,
1333    abi_long arg0, abi_long arg1, abi_long arg2,
1334    abi_long arg3, abi_long arg4, abi_long arg5)
1335{
1336    print_syscall_prologue(name);
1337    print_string(arg0, 0);
1338    print_string(arg1, 0);
1339    print_string(arg2, 0);
1340    print_flags(mount_flags, arg3, 0);
1341    print_pointer(arg4, 1);
1342    print_syscall_epilogue(name);
1343}
1344#endif
1345
1346#ifdef TARGET_NR_umount
1347static void
1348print_umount(const struct syscallname *name,
1349    abi_long arg0, abi_long arg1, abi_long arg2,
1350    abi_long arg3, abi_long arg4, abi_long arg5)
1351{
1352    print_syscall_prologue(name);
1353    print_string(arg0, 1);
1354    print_syscall_epilogue(name);
1355}
1356#endif
1357
1358#ifdef TARGET_NR_umount2
1359static void
1360print_umount2(const struct syscallname *name,
1361    abi_long arg0, abi_long arg1, abi_long arg2,
1362    abi_long arg3, abi_long arg4, abi_long arg5)
1363{
1364    print_syscall_prologue(name);
1365    print_string(arg0, 0);
1366    print_flags(umount2_flags, arg1, 1);
1367    print_syscall_epilogue(name);
1368}
1369#endif
1370
1371#ifdef TARGET_NR_unlink
1372static void
1373print_unlink(const struct syscallname *name,
1374    abi_long arg0, abi_long arg1, abi_long arg2,
1375    abi_long arg3, abi_long arg4, abi_long arg5)
1376{
1377    print_syscall_prologue(name);
1378    print_string(arg0, 1);
1379    print_syscall_epilogue(name);
1380}
1381#endif
1382
1383#ifdef TARGET_NR_unlinkat
1384static void
1385print_unlinkat(const struct syscallname *name,
1386    abi_long arg0, abi_long arg1, abi_long arg2,
1387    abi_long arg3, abi_long arg4, abi_long arg5)
1388{
1389    print_syscall_prologue(name);
1390    print_at_dirfd(arg0, 0);
1391    print_string(arg1, 0);
1392    print_flags(unlinkat_flags, arg2, 1);
1393    print_syscall_epilogue(name);
1394}
1395#endif
1396
1397#ifdef TARGET_NR_utime
1398static void
1399print_utime(const struct syscallname *name,
1400    abi_long arg0, abi_long arg1, abi_long arg2,
1401    abi_long arg3, abi_long arg4, abi_long arg5)
1402{
1403    print_syscall_prologue(name);
1404    print_string(arg0, 0);
1405    print_pointer(arg1, 1);
1406    print_syscall_epilogue(name);
1407}
1408#endif
1409
1410#ifdef TARGET_NR_utimes
1411static void
1412print_utimes(const struct syscallname *name,
1413    abi_long arg0, abi_long arg1, abi_long arg2,
1414    abi_long arg3, abi_long arg4, abi_long arg5)
1415{
1416    print_syscall_prologue(name);
1417    print_string(arg0, 0);
1418    print_pointer(arg1, 1);
1419    print_syscall_epilogue(name);
1420}
1421#endif
1422
1423#ifdef TARGET_NR_utimensat
1424static void
1425print_utimensat(const struct syscallname *name,
1426    abi_long arg0, abi_long arg1, abi_long arg2,
1427    abi_long arg3, abi_long arg4, abi_long arg5)
1428{
1429    print_syscall_prologue(name);
1430    print_at_dirfd(arg0, 0);
1431    print_string(arg1, 0);
1432    print_pointer(arg2, 0);
1433    print_flags(at_file_flags, arg3, 1);
1434    print_syscall_epilogue(name);
1435}
1436#endif
1437
1438#if defined(TARGET_NR_mmap) || defined(TARGET_NR_mmap2)
1439static void
1440print_mmap(const struct syscallname *name,
1441    abi_long arg0, abi_long arg1, abi_long arg2,
1442    abi_long arg3, abi_long arg4, abi_long arg5)
1443{
1444    print_syscall_prologue(name);
1445    print_pointer(arg0, 0);
1446    print_raw_param("%d", arg1, 0);
1447    print_flags(mmap_prot_flags, arg2, 0);
1448    print_flags(mmap_flags, arg3, 0);
1449    print_raw_param("%d", arg4, 0);
1450    print_raw_param("%#x", arg5, 1);
1451    print_syscall_epilogue(name);
1452}
1453#define print_mmap2     print_mmap
1454#endif
1455
1456#ifdef TARGET_NR_mprotect
1457static void
1458print_mprotect(const struct syscallname *name,
1459    abi_long arg0, abi_long arg1, abi_long arg2,
1460    abi_long arg3, abi_long arg4, abi_long arg5)
1461{
1462    print_syscall_prologue(name);
1463    print_pointer(arg0, 0);
1464    print_raw_param("%d", arg1, 0);
1465    print_flags(mmap_prot_flags, arg2, 1);
1466    print_syscall_epilogue(name);
1467}
1468#endif
1469
1470#ifdef TARGET_NR_munmap
1471static void
1472print_munmap(const struct syscallname *name,
1473    abi_long arg0, abi_long arg1, abi_long arg2,
1474    abi_long arg3, abi_long arg4, abi_long arg5)
1475{
1476    print_syscall_prologue(name);
1477    print_pointer(arg0, 0);
1478    print_raw_param("%d", arg1, 1);
1479    print_syscall_epilogue(name);
1480}
1481#endif
1482
1483#ifdef TARGET_NR_futex
1484static void print_futex_op(abi_long tflag, int last)
1485{
1486#define print_op(val) \
1487if( cmd == val ) { \
1488    gemu_log(#val); \
1489    return; \
1490}
1491
1492    int cmd = (int)tflag;
1493#ifdef FUTEX_PRIVATE_FLAG
1494    if (cmd & FUTEX_PRIVATE_FLAG) {
1495        gemu_log("FUTEX_PRIVATE_FLAG|");
1496        cmd &= ~FUTEX_PRIVATE_FLAG;
1497    }
1498#endif
1499#ifdef FUTEX_CLOCK_REALTIME
1500    if (cmd & FUTEX_CLOCK_REALTIME) {
1501        gemu_log("FUTEX_CLOCK_REALTIME|");
1502        cmd &= ~FUTEX_CLOCK_REALTIME;
1503    }
1504#endif
1505    print_op(FUTEX_WAIT)
1506    print_op(FUTEX_WAKE)
1507    print_op(FUTEX_FD)
1508    print_op(FUTEX_REQUEUE)
1509    print_op(FUTEX_CMP_REQUEUE)
1510    print_op(FUTEX_WAKE_OP)
1511    print_op(FUTEX_LOCK_PI)
1512    print_op(FUTEX_UNLOCK_PI)
1513    print_op(FUTEX_TRYLOCK_PI)
1514#ifdef FUTEX_WAIT_BITSET
1515    print_op(FUTEX_WAIT_BITSET)
1516#endif
1517#ifdef FUTEX_WAKE_BITSET
1518    print_op(FUTEX_WAKE_BITSET)
1519#endif
1520    /* unknown values */
1521    gemu_log("%d",cmd);
1522}
1523
1524static void
1525print_futex(const struct syscallname *name,
1526    abi_long arg0, abi_long arg1, abi_long arg2,
1527    abi_long arg3, abi_long arg4, abi_long arg5)
1528{
1529    print_syscall_prologue(name);
1530    print_pointer(arg0, 0);
1531    print_futex_op(arg1, 0);
1532    print_raw_param(",%d", arg2, 0);
1533    print_pointer(arg3, 0); /* struct timespec */
1534    print_pointer(arg4, 0);
1535    print_raw_param("%d", arg4, 1);
1536    print_syscall_epilogue(name);
1537}
1538#endif
1539
1540#ifdef TARGET_NR_kill
1541static void
1542print_kill(const struct syscallname *name,
1543    abi_long arg0, abi_long arg1, abi_long arg2,
1544    abi_long arg3, abi_long arg4, abi_long arg5)
1545{
1546    print_syscall_prologue(name);
1547    print_raw_param("%d", arg0, 0);
1548    print_signal(arg1, 1);
1549    print_syscall_epilogue(name);
1550}
1551#endif
1552
1553/*
1554 * An array of all of the syscalls we know about
1555 */
1556
1557static const struct syscallname scnames[] = {
1558#include "strace.list"
1559};
1560
1561static int nsyscalls = ARRAY_SIZE(scnames);
1562
1563/*
1564 * The public interface to this module.
1565 */
1566void
1567print_syscall(int num,
1568              abi_long arg1, abi_long arg2, abi_long arg3,
1569              abi_long arg4, abi_long arg5, abi_long arg6)
1570{
1571    int i;
1572    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 ")";
1573
1574    gemu_log("%d ", getpid() );
1575
1576    for(i=0;i<nsyscalls;i++)
1577        if( scnames[i].nr == num ) {
1578            if( scnames[i].call != NULL ) {
1579                scnames[i].call(&scnames[i],arg1,arg2,arg3,arg4,arg5,arg6);
1580            } else {
1581                /* XXX: this format system is broken because it uses
1582                   host types and host pointers for strings */
1583                if( scnames[i].format != NULL )
1584                    format = scnames[i].format;
1585                gemu_log(format,scnames[i].name, arg1,arg2,arg3,arg4,arg5,arg6);
1586            }
1587            return;
1588        }
1589    gemu_log("Unknown syscall %d\n", num);
1590}
1591
1592
1593void
1594print_syscall_ret(int num, abi_long ret)
1595{
1596    int i;
1597    char *errstr = NULL;
1598
1599    for(i=0;i<nsyscalls;i++)
1600        if( scnames[i].nr == num ) {
1601            if( scnames[i].result != NULL ) {
1602                scnames[i].result(&scnames[i],ret);
1603            } else {
1604                if (ret < 0) {
1605                    errstr = target_strerror(-ret);
1606                }
1607                if (errstr) {
1608                    gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
1609                             -ret, errstr);
1610                } else {
1611                    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
1612                }
1613            }
1614            break;
1615        }
1616}
1617