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.
This commit is contained in:
parent
e82ce59c37
commit
7d89732757
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286381
@ -41,7 +41,7 @@ enum Argtype { None = 1, Hex, Octal, Int, LongHex, Name, Ptr, Stat, Ioctl, Quad,
|
|||||||
Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open,
|
Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open,
|
||||||
Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2,
|
Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2,
|
||||||
Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl,
|
Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl,
|
||||||
LinuxSockArgs, Umtxop };
|
LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode };
|
||||||
|
|
||||||
#define ARG_MASK 0xff
|
#define ARG_MASK 0xff
|
||||||
#define OUT 0x100
|
#define OUT 0x100
|
||||||
|
@ -115,6 +115,9 @@ static struct syscall syscalls[] = {
|
|||||||
{ .name = "getuid", .ret_type = 1, .nargs = 0 },
|
{ .name = "getuid", .ret_type = 1, .nargs = 0 },
|
||||||
{ .name = "readlink", .ret_type = 1, .nargs = 3,
|
{ .name = "readlink", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Int, 2 } } },
|
.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,
|
{ .name = "lseek", .ret_type = 2, .nargs = 3,
|
||||||
.args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } },
|
.args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } },
|
||||||
{ .name = "linux_lseek", .ret_type = 2, .nargs = 3,
|
{ .name = "linux_lseek", .ret_type = 2, .nargs = 3,
|
||||||
@ -127,28 +130,55 @@ static struct syscall syscalls[] = {
|
|||||||
.args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } },
|
.args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } },
|
||||||
{ .name = "open", .ret_type = 1, .nargs = 3,
|
{ .name = "open", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } },
|
.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,
|
{ .name = "mkdir", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name, 0 }, { Octal, 1 } } },
|
.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,
|
{ .name = "linux_open", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } },
|
.args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } },
|
||||||
{ .name = "close", .ret_type = 1, .nargs = 1,
|
{ .name = "close", .ret_type = 1, .nargs = 1,
|
||||||
.args = { { Int, 0 } } },
|
.args = { { Int, 0 } } },
|
||||||
{ .name = "link", .ret_type = 0, .nargs = 2,
|
{ .name = "link", .ret_type = 0, .nargs = 2,
|
||||||
.args = { { Name, 0 }, { Name, 1 } } },
|
.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,
|
{ .name = "unlink", .ret_type = 0, .nargs = 1,
|
||||||
.args = { { Name, 0 } } },
|
.args = { { Name, 0 } } },
|
||||||
|
{ .name = "unlinkat", .ret_type = 0, .nargs = 3,
|
||||||
|
.args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } },
|
||||||
{ .name = "chdir", .ret_type = 0, .nargs = 1,
|
{ .name = "chdir", .ret_type = 0, .nargs = 1,
|
||||||
.args = { { Name, 0 } } },
|
.args = { { Name, 0 } } },
|
||||||
{ .name = "chroot", .ret_type = 0, .nargs = 1,
|
{ .name = "chroot", .ret_type = 0, .nargs = 1,
|
||||||
.args = { { Name, 0 } } },
|
.args = { { Name, 0 } } },
|
||||||
{ .name = "mkfifo", .ret_type = 0, .nargs = 2,
|
{ .name = "mkfifo", .ret_type = 0, .nargs = 2,
|
||||||
.args = { { Name, 0 }, { Octal, 1 } } },
|
.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,
|
{ .name = "mknod", .ret_type = 0, .nargs = 3,
|
||||||
.args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } },
|
.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,
|
{ .name = "chmod", .ret_type = 0, .nargs = 2,
|
||||||
.args = { { Name, 0 }, { Octal, 1 } } },
|
.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,
|
{ .name = "chown", .ret_type = 0, .nargs = 3,
|
||||||
.args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } },
|
.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,
|
{ .name = "linux_stat64", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 }}},
|
.args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 }}},
|
||||||
{ .name = "mount", .ret_type = 0, .nargs = 4,
|
{ .name = "mount", .ret_type = 0, .nargs = 4,
|
||||||
@ -157,6 +187,9 @@ static struct syscall syscalls[] = {
|
|||||||
.args = { { Name, 0 }, { Int, 2 } } },
|
.args = { { Name, 0 }, { Int, 2 } } },
|
||||||
{ .name = "fstat", .ret_type = 1, .nargs = 2,
|
{ .name = "fstat", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Int, 0 }, { Stat | OUT, 1 } } },
|
.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,
|
{ .name = "stat", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
|
.args = { { Name | IN, 0 }, { Stat | OUT, 1 } } },
|
||||||
{ .name = "lstat", .ret_type = 1, .nargs = 2,
|
{ .name = "lstat", .ret_type = 1, .nargs = 2,
|
||||||
@ -164,7 +197,7 @@ static struct syscall syscalls[] = {
|
|||||||
{ .name = "linux_newstat", .ret_type = 1, .nargs = 2,
|
{ .name = "linux_newstat", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
|
.args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } },
|
||||||
{ .name = "linux_access", .ret_type = 1, .nargs = 2,
|
{ .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,
|
{ .name = "linux_newfstat", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Int, 0 }, { Ptr | OUT, 1 } } },
|
.args = { { Int, 0 }, { Ptr | OUT, 1 } } },
|
||||||
{ .name = "write", .ret_type = 1, .nargs = 3,
|
{ .name = "write", .ret_type = 1, .nargs = 3,
|
||||||
@ -176,15 +209,26 @@ static struct syscall syscalls[] = {
|
|||||||
{ .name = "exit", .ret_type = 0, .nargs = 1,
|
{ .name = "exit", .ret_type = 0, .nargs = 1,
|
||||||
.args = { { Hex, 0 } } },
|
.args = { { Hex, 0 } } },
|
||||||
{ .name = "access", .ret_type = 1, .nargs = 2,
|
{ .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,
|
{ .name = "sigaction", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } },
|
.args = { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } },
|
||||||
{ .name = "accept", .ret_type = 1, .nargs = 3,
|
{ .name = "accept", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
|
.args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
|
||||||
{ .name = "bind", .ret_type = 1, .nargs = 3,
|
{ .name = "bind", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } },
|
.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,
|
{ .name = "connect", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } },
|
.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,
|
{ .name = "getpeername", .ret_type = 1, .nargs = 3,
|
||||||
.args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
|
.args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } },
|
||||||
{ .name = "getsockname", .ret_type = 1, .nargs = 3,
|
{ .name = "getsockname", .ret_type = 1, .nargs = 3,
|
||||||
@ -248,7 +292,14 @@ static struct syscall syscalls[] = {
|
|||||||
{ .name = "lutimes", .ret_type = 1, .nargs = 2,
|
{ .name = "lutimes", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
|
.args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } },
|
||||||
{ .name = "futimes", .ret_type = 1, .nargs = 2,
|
{ .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,
|
{ .name = "chflags", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name | IN, 0 }, { Hex, 1 } } },
|
.args = { { Name | IN, 0 }, { Hex, 1 } } },
|
||||||
{ .name = "lchflags", .ret_type = 1, .nargs = 2,
|
{ .name = "lchflags", .ret_type = 1, .nargs = 2,
|
||||||
@ -269,8 +320,12 @@ static struct syscall syscalls[] = {
|
|||||||
.args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } },
|
.args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } },
|
||||||
{ .name = "rename", .ret_type = 1, .nargs = 2,
|
{ .name = "rename", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name, 0 }, { Name, 1 } } },
|
.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,
|
{ .name = "symlink", .ret_type = 1, .nargs = 2,
|
||||||
.args = { { Name, 0 }, { Name, 1 } } },
|
.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,
|
{ .name = "posix_openpt", .ret_type = 1, .nargs = 1,
|
||||||
.args = { { Open, 0 } } },
|
.args = { { Open, 0 } } },
|
||||||
{ .name = "wait4", .ret_type = 1, .nargs = 4,
|
{ .name = "wait4", .ret_type = 1, .nargs = 4,
|
||||||
@ -438,6 +493,15 @@ static struct xlat umtx_ops[] = {
|
|||||||
XEND
|
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 X
|
||||||
#undef XEND
|
#undef XEND
|
||||||
|
|
||||||
@ -780,6 +844,40 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
|
|||||||
asprintf(&tmp, "0x%lx", args[sc->offset]);
|
asprintf(&tmp, "0x%lx", args[sc->offset]);
|
||||||
break;
|
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: {
|
case Timeval: {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
|
if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
|
||||||
@ -1319,6 +1417,22 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
|
|||||||
case Umtxop:
|
case Umtxop:
|
||||||
tmp = strdup(xlookup(umtx_ops, args[sc->offset]));
|
tmp = strdup(xlookup(umtx_ops, args[sc->offset]));
|
||||||
break;
|
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:
|
default:
|
||||||
errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
|
errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user