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