Index: lib/libsysdecode/flags.c =================================================================== --- lib/libsysdecode/flags.c +++ lib/libsysdecode/flags.c @@ -64,12 +64,14 @@ #include #include #include -#include #include #include #include #include #include +#include + +#include "sysdecode.h" /* * This is taken from the xlat tables originally in truss which were @@ -259,6 +261,18 @@ return (print_mask_int(fp, atflags, flag, rem)); } +static struct name_table linux_atflags[] = { + X(LINUX_AT_SYMLINK_NOFOLLOW) X(LINUX_AT_EACCESS) + X(LINUX_AT_REMOVEDIR) X(LINUX_AT_SYMLINK_FOLLOW) XEND +}; + +bool +sysdecode_linux_atflags(FILE *fp, int flag, int *rem) +{ + + return (print_mask_int(fp, linux_atflags, flag, rem)); +} + static struct name_table semctlops[] = { X(GETNCNT) X(GETPID) X(GETVAL) X(GETALL) X(GETZCNT) X(SETVAL) X(SETALL) X(IPC_RMID) X(IPC_SET) X(IPC_STAT) XEND Index: lib/libsysdecode/sysdecode.h =================================================================== --- lib/libsysdecode/sysdecode.h +++ lib/libsysdecode/sysdecode.h @@ -129,4 +129,5 @@ bool sysdecode_wait6_options(FILE *_fp, int _options, int *_rem); const char *sysdecode_whence(int _whence); +bool sysdecode_linux_atflags(FILE *_fp, int _flags, int *_rem); #endif /* !__SYSDECODE_H__ */ Index: usr.bin/truss/Makefile =================================================================== --- usr.bin/truss/Makefile +++ usr.bin/truss/Makefile @@ -8,5 +8,6 @@ #CFLAGS+= -I${.CURDIR} -I. -I${SRCTOP}/sys CFLAGS+= -I${SRCTOP}/sys +CFLAGS+= -I${SRCTOP}/lib/libsysdecode .include Index: usr.bin/truss/linux.h =================================================================== --- /dev/null +++ usr.bin/truss/linux.h @@ -0,0 +1,129 @@ +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright 1997 Sean Eric Fagan + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Sean Eric Fagan + * 4. Neither the name of the author may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Linux Socket defines + */ +#define LINUX_SOCKET 1 +#define LINUX_BIND 2 +#define LINUX_CONNECT 3 +#define LINUX_LISTEN 4 +#define LINUX_ACCEPT 5 +#define LINUX_GETSOCKNAME 6 +#define LINUX_GETPEERNAME 7 +#define LINUX_SOCKETPAIR 8 +#define LINUX_SEND 9 +#define LINUX_RECV 10 +#define LINUX_SENDTO 11 +#define LINUX_RECVFROM 12 +#define LINUX_SHUTDOWN 13 +#define LINUX_SETSOCKOPT 14 +#define LINUX_GETSOCKOPT 15 +#define LINUX_SENDMSG 16 +#define LINUX_RECVMSG 17 + +#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \ + 0 : sizeof(register_t) - sizeof(t)) + +#if BYTE_ORDER == LITTLE_ENDIAN +#define PADL_(t) 0 +#define PADR_(t) PAD_(t) +#else +#define PADL_(t) PAD_(t) +#define PADR_(t) 0 +#endif + +typedef int l_int; +typedef uint32_t l_ulong; + +struct linux_socketcall_args { + char what_l_[PADL_(l_int)]; l_int what; char what_r_[PADR_(l_int)]; + char args_l_[PADL_(l_ulong)]; l_ulong args; char args_r_[PADR_(l_ulong)]; +}; + +/* Unroll stat structures for supported platforms */ +#if defined(__aarch64__) +struct l_timespec { int64_t tv_sec; int64_t tv_nsec; }; +typedef struct l_newstat { + uint64_t t_dev; uint64_t st_ino; uint32_t st_mode; uint32_t st_nlink; + uint32_t st_uid; uint32_t st_gid; uint64_t st_rdev; uint64_t __st_pad1; + int64_t st_size; int32_t st_blksize; int32_t __st_pad2; + int64_t st_blocks; struct l_timespec st_atim; struct l_timespec st_mtim; + struct l_timespec st_ctim; uint32_t __unused1; uint32_t __unused2; +} l_newstat_t; +typedef struct stat l_stat64_t; +#elif defined(__amd64__) +struct l_timespec { int64_t tv_sec; int64_t tv_nsec; }; +typedef struct l_newstat { + uint64_t st_dev; uint64_t st_ino; uint64_t st_nlink; uint32_t st_mode; + uint32_t st_uid; uint32_t st_gid; uint32_t __st_pad1; uint64_t st_rdev; + int64_t st_size; int64_t st_blksize; int64_t st_blocks; + struct l_timespec st_atim; struct l_timespec st_mtim; + struct l_timespec st_ctim; int64_t __unused1; int64_t __unused2; + int64_t __unused3; +} l_newstat_t; +struct l32_timespec { uint32_t tv_sec; uint32_t tv_nsec; } __packed; +typedef struct l_stat64 { + unsigned short st_dev; u_char __pad0[10]; uint32_t __st_ino; + unsigned int st_mode; unsigned int st_nlink; uint32_t st_uid; + uint32_t st_gid; unsigned short st_rdev; u_char __pad3[10]; + uint64_t st_size; uint32_t st_blksize; uint32_t st_blocks; + uint32_t __pad4; struct l32_timespec st_atim; + struct l32_timespec st_mtim; struct l32_timespec st_ctim; + uint64_t st_ino; +} __packed l_stat64_t; +#elif defined(__i386__) +struct l_timespec { int32_t tv_sec; int32_t tv_nsec; }; +typedef struct l_newstat { + unsigned short st_dev; unsigned short __pad1; uint32_t st_ino; + unsigned short st_mode; unsigned short st_nlink; unsigned short st_uid; + unsigned short st_gid; unsigned short st_rdev; unsigned short __pad2; + uint32_t st_size; uint32_t st_blksize; uint32_t st_blocks; + struct l_timespec st_atim; struct l_timespec st_mtim; + struct l_timespec st_ctim; uint32_t __unused4; uint32_t __unused5; +} l_newstat_t; +typedef struct l_stat64 { + unsigned short st_dev; u_char __pad0[10]; uint32_t __st_ino; + unsigned int st_mode; unsigned int st_nlink; uint32_t st_uid; + uint32_t st_gid; unsigned short st_rdev; u_char __pad3[10]; + int64_t st_size; uint32_t st_blksize; uint32_t st_blocks; + uint32_t __pad4; struct l_timespec st_atim; struct l_timespec st_mtim; + struct l_timespec st_ctim; uint64_t st_ino; +} l_stat64_t; +#else +/* Provide dummy defines for unsupported platforms */ +typedef struct stat l_newstat_t; +typedef struct stat l_stat64_t; +#endif Index: usr.bin/truss/syscall.h =================================================================== --- usr.bin/truss/syscall.h +++ usr.bin/truss/syscall.h @@ -159,7 +159,6 @@ Itimerval, Kevent, Kevent11, - LinuxSockArgs, Msghdr, Pollfd, Rlimit, @@ -199,6 +198,11 @@ CloudABIULFlags, CloudABIWhence, + LinuxAtflags, + LinuxNewstat, + LinuxSockArgs, + LinuxStat64, + MAX_ARG_TYPE, }; @@ -231,46 +235,6 @@ char *print_arg(struct syscall_args *, unsigned long*, register_t *, struct trussinfo *); -/* - * Linux Socket defines - */ -#define LINUX_SOCKET 1 -#define LINUX_BIND 2 -#define LINUX_CONNECT 3 -#define LINUX_LISTEN 4 -#define LINUX_ACCEPT 5 -#define LINUX_GETSOCKNAME 6 -#define LINUX_GETPEERNAME 7 -#define LINUX_SOCKETPAIR 8 -#define LINUX_SEND 9 -#define LINUX_RECV 10 -#define LINUX_SENDTO 11 -#define LINUX_RECVFROM 12 -#define LINUX_SHUTDOWN 13 -#define LINUX_SETSOCKOPT 14 -#define LINUX_GETSOCKOPT 15 -#define LINUX_SENDMSG 16 -#define LINUX_RECVMSG 17 - -#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \ - 0 : sizeof(register_t) - sizeof(t)) - -#if BYTE_ORDER == LITTLE_ENDIAN -#define PADL_(t) 0 -#define PADR_(t) PAD_(t) -#else -#define PADL_(t) PAD_(t) -#define PADR_(t) 0 -#endif - -typedef int l_int; -typedef uint32_t l_ulong; - -struct linux_socketcall_args { - char what_l_[PADL_(l_int)]; l_int what; char what_r_[PADR_(l_int)]; - char args_l_[PADL_(l_ulong)]; l_ulong args; char args_r_[PADR_(l_ulong)]; -}; - void init_syscalls(void); void print_syscall(struct trussinfo *); void print_syscall_ret(struct trussinfo *, int, register_t *); Index: usr.bin/truss/syscalls.c =================================================================== --- usr.bin/truss/syscalls.c +++ usr.bin/truss/syscalls.c @@ -80,6 +80,7 @@ #include "truss.h" #include "extern.h" +#include "linux.h" #include "syscall.h" /* @@ -559,14 +560,24 @@ { .name = "linux_execve", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { ExecArgs | IN, 1 }, { ExecEnv | IN, 2 } } }, + { .name = "linux_fstat64", .ret_type = 1, .nargs = 2, + .args = { { Atfd | IN, 0 }, { LinuxStat64 | OUT, 1 } } }, + { .name = "linux_fstatat64", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { LinuxStat64 | OUT, 2 }, + { LinuxAtflags, 3 } } }, { .name = "linux_lseek", .ret_type = 2, .nargs = 3, .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } }, { .name = "linux_mkdir", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Int, 1 } } }, { .name = "linux_newfstat", .ret_type = 1, .nargs = 2, - .args = { { Int, 0 }, { Ptr | OUT, 1 } } }, + .args = { { Int, 0 }, { LinuxNewstat | OUT, 1 } } }, + { .name = "linux_newfstatat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { LinuxNewstat | OUT, 2 }, + { LinuxAtflags, 3 } } }, + { .name = "linux_newlstat", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { LinuxNewstat | OUT, 1 } } }, { .name = "linux_newstat", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, + .args = { { Name | IN, 0 }, { LinuxNewstat | OUT, 1 } } }, { .name = "linux_open", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, { .name = "linux_readlink", .ret_type = 1, .nargs = 3, @@ -574,7 +585,7 @@ { .name = "linux_socketcall", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { LinuxSockArgs, 1 } } }, { .name = "linux_stat64", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, + .args = { { Name | IN, 0 }, { LinuxStat64 | OUT, 1 } } }, /* CloudABI system calls. */ { .name = "cloudabi_sys_clock_res_get", .ret_type = 1, .nargs = 1, @@ -2188,6 +2199,40 @@ } break; } + case LinuxNewstat: { + l_newstat_t st; + + if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) + != -1) { + char mode[12]; + + strmode(st.st_mode, mode); + fprintf(fp, + "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode, + (uintmax_t)st.st_ino, (intmax_t)st.st_size, + (long)st.st_blksize); + } else { + fprintf(fp, "0x%lx", args[sc->offset]); + } + break; + } + case LinuxStat64: { + l_stat64_t st; + + if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) + != -1) { + char mode[12]; + + strmode(st.st_mode, mode); + fprintf(fp, + "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode, + (uintmax_t)st.st_ino, (intmax_t)st.st_size, + (long)st.st_blksize); + } else { + fprintf(fp, "0x%lx", args[sc->offset]); + } + break; + } case StatFs: { unsigned int i; struct statfs buf; @@ -2278,6 +2323,9 @@ case Atflags: print_mask_arg(sysdecode_atflags, fp, args[sc->offset]); break; + case LinuxAtflags: + print_mask_arg(sysdecode_linux_atflags, fp, args[sc->offset]); + break; case Accessmode: print_mask_arg(sysdecode_access_mode, fp, args[sc->offset]); break;