From owner-svn-src-head@freebsd.org Thu Aug 6 19:08:35 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 454939B52DF; Thu, 6 Aug 2015 19:08:35 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 293E5C57; Thu, 6 Aug 2015 19:08:35 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t76J8ZGn080759; Thu, 6 Aug 2015 19:08:35 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t76J8YG9080757; Thu, 6 Aug 2015 19:08:34 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201508061908.t76J8YG9080757@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Thu, 6 Aug 2015 19:08:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r286381 - head/usr.bin/truss X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Aug 2015 19:08:35 -0000 Author: jhb Date: Thu Aug 6 19:08:33 2015 New Revision: 286381 URL: https://svnweb.freebsd.org/changeset/base/286381 Log: Decode the arguments passed to the *at() family of system calls. This is especially useful now that libc's open() always calls openat(). While here, fix a few other things: - Decode the mode argument passed to access(), eaccess(), and faccessat(). - Decode the atfd paramete to pretty-print AT_FDCWD. - Decode the special AT_* flags used with some of the *at() system calls. - Decode arguments for fchmod(), lchmod(), fchown(), lchown(), eaccess(), and futimens(). - Decode both of the timeval structures passed to futimes() instead of just the first one. Modified: head/usr.bin/truss/syscall.h head/usr.bin/truss/syscalls.c Modified: head/usr.bin/truss/syscall.h ============================================================================== --- head/usr.bin/truss/syscall.h Thu Aug 6 18:32:32 2015 (r286380) +++ head/usr.bin/truss/syscall.h Thu Aug 6 19:08:33 2015 (r286381) @@ -41,7 +41,7 @@ enum Argtype { None = 1, Hex, Octal, Int Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl, - LinuxSockArgs, Umtxop }; + LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode }; #define ARG_MASK 0xff #define OUT 0x100 Modified: head/usr.bin/truss/syscalls.c ============================================================================== --- head/usr.bin/truss/syscalls.c Thu Aug 6 18:32:32 2015 (r286380) +++ head/usr.bin/truss/syscalls.c Thu Aug 6 19:08:33 2015 (r286381) @@ -115,6 +115,9 @@ static struct syscall syscalls[] = { { .name = "getuid", .ret_type = 1, .nargs = 0 }, { .name = "readlink", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Int, 2 } } }, + { .name = "readlinkat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 }, + { Int, 3 } } }, { .name = "lseek", .ret_type = 2, .nargs = 3, .args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, { .name = "linux_lseek", .ret_type = 2, .nargs = 3, @@ -127,28 +130,55 @@ static struct syscall syscalls[] = { .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } }, { .name = "open", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } }, + { .name = "openat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Open, 2 }, + { Octal, 3 } } }, { .name = "mkdir", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "mkdirat", .ret_type = 1, .nargs = 3, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } }, { .name = "linux_open", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, { .name = "close", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, { .name = "link", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Name, 1 } } }, + { .name = "linkat", .ret_type = 0, .nargs = 5, + .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 }, + { Atflags, 4 } } }, { .name = "unlink", .ret_type = 0, .nargs = 1, .args = { { Name, 0 } } }, + { .name = "unlinkat", .ret_type = 0, .nargs = 3, + .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } }, { .name = "chdir", .ret_type = 0, .nargs = 1, .args = { { Name, 0 } } }, { .name = "chroot", .ret_type = 0, .nargs = 1, .args = { { Name, 0 } } }, { .name = "mkfifo", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "mkfifoat", .ret_type = 0, .nargs = 3, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } }, { .name = "mknod", .ret_type = 0, .nargs = 3, .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } }, + { .name = "mknodat", .ret_type = 0, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } }, { .name = "chmod", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "fchmod", .ret_type = 0, .nargs = 2, + .args = { { Int, 0 }, { Octal, 1 } } }, + { .name = "lchmod", .ret_type = 0, .nargs = 2, + .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "fchmodat", .ret_type = 0, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Atflags, 3 } } }, { .name = "chown", .ret_type = 0, .nargs = 3, .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "fchown", .ret_type = 0, .nargs = 3, + .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "lchown", .ret_type = 0, .nargs = 3, + .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "fchownat", .ret_type = 0, .nargs = 5, + .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 }, + { Atflags, 4 } } }, { .name = "linux_stat64", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 }}}, { .name = "mount", .ret_type = 0, .nargs = 4, @@ -157,6 +187,9 @@ static struct syscall syscalls[] = { .args = { { Name, 0 }, { Int, 2 } } }, { .name = "fstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Stat | OUT, 1 } } }, + { .name = "fstatat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat | OUT, 2 }, + { Atflags, 3 } } }, { .name = "stat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, { .name = "lstat", .ret_type = 1, .nargs = 2, @@ -164,7 +197,7 @@ static struct syscall syscalls[] = { { .name = "linux_newstat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, { .name = "linux_access", .ret_type = 1, .nargs = 2, - .args = { { Name, 0 }, { Int, 1 }}}, + .args = { { Name, 0 }, { Accessmode, 1 }}}, { .name = "linux_newfstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Ptr | OUT, 1 } } }, { .name = "write", .ret_type = 1, .nargs = 3, @@ -176,15 +209,26 @@ static struct syscall syscalls[] = { { .name = "exit", .ret_type = 0, .nargs = 1, .args = { { Hex, 0 } } }, { .name = "access", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0 }, { Int, 1 } } }, + .args = { { Name | IN, 0 }, { Accessmode, 1 } } }, + { .name = "eaccess", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Accessmode, 1 } } }, + { .name = "faccessat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 }, + { Atflags, 3 } } }, { .name = "sigaction", .ret_type = 1, .nargs = 3, .args = { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } }, { .name = "accept", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, { .name = "bind", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, + { .name = "bindat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, + { Int, 3 } } }, { .name = "connect", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, + { .name = "connectat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, + { Int, 3 } } }, { .name = "getpeername", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, { .name = "getsockname", .ret_type = 1, .nargs = 3, @@ -248,7 +292,14 @@ static struct syscall syscalls[] = { { .name = "lutimes", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, { .name = "futimes", .ret_type = 1, .nargs = 2, - .args = { { Int, 0 }, { Timeval | IN, 1 } } }, + .args = { { Int, 0 }, { Timeval2 | IN, 1 } } }, + { .name = "futimesat", .ret_type = 1, .nargs = 3, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timeval2 | IN, 2 } } }, + { .name = "futimens", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Timespec2 | IN, 1 } } }, + { .name = "utimensat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 }, + { Atflags, 3 } } }, { .name = "chflags", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Hex, 1 } } }, { .name = "lchflags", .ret_type = 1, .nargs = 2, @@ -269,8 +320,12 @@ static struct syscall syscalls[] = { .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } }, { .name = "rename", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Name, 1 } } }, + { .name = "renameat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 } } }, { .name = "symlink", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Name, 1 } } }, + { .name = "symlinkat", .ret_type = 1, .nargs = 3, + .args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } }, { .name = "posix_openpt", .ret_type = 1, .nargs = 1, .args = { { Open, 0 } } }, { .name = "wait4", .ret_type = 1, .nargs = 4, @@ -438,6 +493,15 @@ static struct xlat umtx_ops[] = { XEND }; +static struct xlat at_flags[] = { + X(AT_EACCESS) X(AT_SYMLINK_NOFOLLOW) X(AT_SYMLINK_FOLLOW) + X(AT_REMOVEDIR) XEND +}; + +static struct xlat access_modes[] = { + X(R_OK) X(W_OK) X(X_OK) XEND +}; + #undef X #undef XEND @@ -780,6 +844,40 @@ print_arg(struct syscall_args *sc, unsig asprintf(&tmp, "0x%lx", args[sc->offset]); break; } + case Timespec2: { + struct timespec ts[2]; + FILE *fp; + size_t len; + const char *sep; + unsigned int i; + + if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) + != -1) { + fp = open_memstream(&tmp, &len); + fputc('{', fp); + sep = ""; + for (i = 0; i < nitems(ts); i++) { + fputs(sep, fp); + sep = ", "; + switch (ts[i].tv_nsec) { + case UTIME_NOW: + fprintf(fp, "UTIME_NOW"); + break; + case UTIME_OMIT: + fprintf(fp, "UTIME_OMIT"); + break; + default: + fprintf(fp, "%ld.%09ld", + (long)ts[i].tv_sec, ts[i].tv_nsec); + break; + } + } + fputc('}', fp); + fclose(fp); + } else + asprintf(&tmp, "0x%lx", args[sc->offset]); + break; + } case Timeval: { struct timeval tv; if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) @@ -1319,6 +1417,22 @@ print_arg(struct syscall_args *sc, unsig case Umtxop: tmp = strdup(xlookup(umtx_ops, args[sc->offset])); break; + case Atfd: + if ((int)args[sc->offset] == AT_FDCWD) + tmp = strdup("AT_FDCWD"); + else + asprintf(&tmp, "%d", (int)args[sc->offset]); + break; + case Atflags: + tmp = strdup(xlookup_bits(at_flags, args[sc->offset])); + break; + case Accessmode: + if (args[sc->offset] == F_OK) + tmp = strdup("F_OK"); + else + tmp = strdup(xlookup_bits(access_modes, + args[sc->offset])); + break; default: errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); }