Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Jul 2019 22:59:15 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r350069 - head/usr.bin/truss
Message-ID:  <201907162259.x6GMxFrJ069696@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Tue Jul 16 22:59:15 2019
New Revision: 350069
URL: https://svnweb.freebsd.org/changeset/base/350069

Log:
  Use PT_GET_SC_ARGS and PT_GET_SC_RET in truss.
  
  This removes all of the architecture-specific functions from truss.
  
  A per-ABI structure is still needed to map syscall numbers to names
  and FreeBSD errno values to ABI error values as well as hold syscall
  counters.  However, the linker set of ABI structures is now replaced
  with a simple table mapping ABI names to structures.  This approach
  permits sharing the same ABI structure among separate names such as
  i386 a.out and ELF binaries as well as ELF v1 vs ELF v2 for powerpc64.
  
  A few differences are visible due to using PT_GET_SC_RET to fetch the
  error value of a system call.  Note that ktrace/kdump have had the
  "new" behaviors for a long time already:
  - System calls that return with EJUSTRETURN or ERESTART will now be
    noticed and logged as such.  Previously sigreturn (which uses
    EJUSTRETURN) would report whatever random value was in the register
    holding errno from the previous system call for example.  Now it
    reports EJUSTRETURN.
  - System calls that return errno as their error value such as
    posix_fallocate() and posix_fadvise() now report non-zero return
    values as errors instead of success with a non-zero return value.
  
  Reviewed by:	kib
  MFC after:	1 month
  Sponsored by:	DARPA
  Differential Revision:	https://reviews.freebsd.org/D20963

Deleted:
  head/usr.bin/truss/aarch64-cloudabi32.c
  head/usr.bin/truss/aarch64-cloudabi64.c
  head/usr.bin/truss/aarch64-freebsd.c
  head/usr.bin/truss/amd64-cloudabi32.c
  head/usr.bin/truss/amd64-cloudabi64.c
  head/usr.bin/truss/amd64-freebsd.c
  head/usr.bin/truss/amd64-freebsd32.c
  head/usr.bin/truss/amd64-linux.c
  head/usr.bin/truss/amd64-linux32.c
  head/usr.bin/truss/arm-freebsd.c
  head/usr.bin/truss/i386-cloudabi32.c
  head/usr.bin/truss/i386-freebsd.c
  head/usr.bin/truss/i386-linux.c
  head/usr.bin/truss/mips-freebsd.c
  head/usr.bin/truss/powerpc-freebsd.c
  head/usr.bin/truss/powerpc64-freebsd.c
  head/usr.bin/truss/powerpc64-freebsd32.c
  head/usr.bin/truss/riscv-freebsd.c
  head/usr.bin/truss/sparc64-freebsd.c
Modified:
  head/usr.bin/truss/Makefile
  head/usr.bin/truss/setup.c
  head/usr.bin/truss/syscall.h
  head/usr.bin/truss/syscalls.c
  head/usr.bin/truss/truss.h

Modified: head/usr.bin/truss/Makefile
==============================================================================
--- head/usr.bin/truss/Makefile	Tue Jul 16 22:55:30 2019	(r350068)
+++ head/usr.bin/truss/Makefile	Tue Jul 16 22:59:15 2019	(r350069)
@@ -9,38 +9,4 @@ LIBADD=	sysdecode
 #CFLAGS+= -I${.CURDIR} -I. -I${SRCTOP}/sys
 CFLAGS+= -I${SRCTOP}/sys
 
-ABIS+=		freebsd
-# Each ABI is expected to have an ABI.c, MACHINE_ARCH-ABI.c or
-# MACHINE_CPUARCH-ABI.c file that will be used to map the syscall arguments.
-.if ${MACHINE_ARCH} == "aarch64"
-ABIS+=		cloudabi32
-ABIS+=		cloudabi64
-.endif
-.if ${MACHINE_CPUARCH} == "i386"
-ABIS+=		i386-linux
-ABIS+=		cloudabi32
-.endif
-.if ${MACHINE_CPUARCH} == "amd64"
-ABIS+=		amd64-linux
-ABIS+=		amd64-linux32
-ABIS+=		freebsd32
-ABIS+=		cloudabi32
-ABIS+=		cloudabi64
-.endif
-.if ${MACHINE_ARCH} == "powerpc64"
-ABIS+=		freebsd32
-.endif
-
-.for abi in ${ABIS}
-# Find the right file to handle this ABI.
-abi_src=
-ABI_SRCS=	${abi}.c ${MACHINE_ARCH}-${abi}.c ${MACHINE_CPUARCH}-${abi}.c
-.for f in ${ABI_SRCS}
-.if exists(${.CURDIR}/${f}) && empty(abi_src)
-abi_src=	${f}
-.endif
-.endfor
-SRCS:=		${SRCS} ${abi_src}
-.endfor
-
 .include <bsd.prog.mk>

Modified: head/usr.bin/truss/setup.c
==============================================================================
--- head/usr.bin/truss/setup.c	Tue Jul 16 22:55:30 2019	(r350068)
+++ head/usr.bin/truss/setup.c	Tue Jul 16 22:59:15 2019	(r350069)
@@ -61,7 +61,10 @@ __FBSDID("$FreeBSD$");
 #include "syscall.h"
 #include "extern.h"
 
-SET_DECLARE(procabi, struct procabi);
+struct procabi_table {
+	const char *name;
+	struct procabi *abi;
+};
 
 static sig_atomic_t detaching;
 
@@ -69,6 +72,79 @@ static void	enter_syscall(struct trussinfo *, struct t
 		    struct ptrace_lwpinfo *);
 static void	new_proc(struct trussinfo *, pid_t, lwpid_t);
 
+
+static struct procabi cloudabi32 = {
+	"CloudABI32",
+	SYSDECODE_ABI_CLOUDABI32,
+	STAILQ_HEAD_INITIALIZER(cloudabi32.extra_syscalls),
+	{ NULL }
+};
+
+static struct procabi cloudabi64 = {
+	"CloudABI64",
+	SYSDECODE_ABI_CLOUDABI64,
+	STAILQ_HEAD_INITIALIZER(cloudabi64.extra_syscalls),
+	{ NULL }
+};
+
+static struct procabi freebsd = {
+	"FreeBSD",
+	SYSDECODE_ABI_FREEBSD,
+	STAILQ_HEAD_INITIALIZER(freebsd.extra_syscalls),
+	{ NULL }
+};
+
+#ifdef __LP64__
+static struct procabi freebsd32 = {
+	"FreeBSD32",
+	SYSDECODE_ABI_FREEBSD32,
+	STAILQ_HEAD_INITIALIZER(freebsd32.extra_syscalls),
+	{ NULL }
+};
+#endif
+
+static struct procabi linux = {
+	"Linux",
+	SYSDECODE_ABI_LINUX,
+	STAILQ_HEAD_INITIALIZER(linux.extra_syscalls),
+	{ NULL }
+};
+
+#ifdef __LP64__
+static struct procabi linux32 = {
+	"Linux32",
+	SYSDECODE_ABI_LINUX32,
+	STAILQ_HEAD_INITIALIZER(linux32.extra_syscalls),
+	{ NULL }
+};
+#endif
+
+static struct procabi_table abis[] = {
+	{ "CloudABI ELF32", &cloudabi32 },
+	{ "CloudABI ELF64", &cloudabi64 },
+#ifdef __LP64__
+	{ "FreeBSD ELF64", &freebsd },
+	{ "FreeBSD ELF32", &freebsd32 },
+#else
+	{ "FreeBSD ELF32", &freebsd },
+#endif
+#if defined(__powerpc64__)
+	{ "FreeBSD ELF64 V2", &freebsd },
+#endif
+#if defined(__amd64__)
+	{ "FreeBSD a.out", &freebsd32 },
+#endif
+#if defined(__i386__)
+	{ "FreeBSD a.out", &freebsd },
+#endif
+#ifdef __LP64__
+	{ "Linux ELF64", &linux },
+	{ "Linux ELF32", &linux32 },
+#else
+	{ "Linux ELF", &linux },
+#endif
+};
+
 /*
  * setup_and_wait() is called to start a process.  All it really does
  * is fork(), enable tracing in the child, and then exec the given
@@ -153,8 +229,8 @@ detach_proc(pid_t pid)
 static struct procabi *
 find_abi(pid_t pid)
 {
-	struct procabi **pabi;
 	size_t len;
+	unsigned int i;
 	int error;
 	int mib[4];
 	char progt[32];
@@ -168,9 +244,9 @@ find_abi(pid_t pid)
 	if (error != 0)
 		err(2, "can not get sysvec name");
 
-	SET_FOREACH(pabi, procabi) {
-		if (strcmp((*pabi)->type, progt) == 0)
-			return (*pabi);
+	for (i = 0; i < nitems(abis); i++) {
+		if (strcmp(abis[i].name, progt) == 0)
+			return (abis[i].abi);
 	}
 	warnx("ABI %s for pid %ld is not supported", progt, (long)pid);
 	return (NULL);
@@ -376,7 +452,8 @@ enter_syscall(struct trussinfo *info, struct threadinf
 
 	alloc_syscall(t, pl);
 	narg = MIN(pl->pl_syscall_narg, nitems(t->cs.args));
-	if (narg != 0 && t->proc->abi->fetch_args(info, narg) != 0) {
+	if (narg != 0 && ptrace(PT_GET_SC_ARGS, t->tid, (caddr_t)t->cs.args,
+	    sizeof(t->cs.args)) != 0) {
 		free_syscall(t);
 		return;
 	}
@@ -408,7 +485,7 @@ enter_syscall(struct trussinfo *info, struct threadinf
 #endif
 		if (!(sc->args[i].type & OUT)) {
 			t->cs.s_args[i] = print_arg(&sc->args[i],
-			    t->cs.args, 0, info);
+			    t->cs.args, NULL, info);
 		}
 	}
 #if DEBUG
@@ -446,9 +523,8 @@ exit_syscall(struct trussinfo *info, struct ptrace_lwp
 	struct threadinfo *t;
 	struct procinfo *p;
 	struct syscall *sc;
-	long retval[2];
+	struct ptrace_sc_ret psr;
 	u_int i;
-	int errorp;
 
 	t = info->curthread;
 	if (!t->in_syscall)
@@ -456,7 +532,7 @@ exit_syscall(struct trussinfo *info, struct ptrace_lwp
 
 	clock_gettime(CLOCK_REALTIME, &t->after);
 	p = t->proc;
-	if (p->abi->fetch_retval(info, retval, &errorp) < 0) {
+	if (ptrace(PT_GET_SC_RET, t->tid, (caddr_t)&psr, sizeof(psr)) != 0) {
 		free_syscall(t);
 		return;
 	}
@@ -474,18 +550,18 @@ exit_syscall(struct trussinfo *info, struct ptrace_lwp
 			 * If an error occurred, then don't bother
 			 * getting the data; it may not be valid.
 			 */
-			if (errorp) {
+			if (psr.sr_error != 0) {
 				asprintf(&temp, "0x%lx",
 				    t->cs.args[sc->args[i].offset]);
 			} else {
 				temp = print_arg(&sc->args[i],
-				    t->cs.args, retval, info);
+				    t->cs.args, psr.sr_retval, info);
 			}
 			t->cs.s_args[i] = temp;
 		}
 	}
 
-	print_syscall_ret(info, errorp, retval);
+	print_syscall_ret(info, psr.sr_error, psr.sr_retval);
 	free_syscall(t);
 
 	/*

Modified: head/usr.bin/truss/syscall.h
==============================================================================
--- head/usr.bin/truss/syscall.h	Tue Jul 16 22:55:30 2019	(r350068)
+++ head/usr.bin/truss/syscall.h	Tue Jul 16 22:59:15 2019	(r350069)
@@ -227,7 +227,8 @@ struct syscall {
 };
 
 struct syscall *get_syscall(struct threadinfo *, u_int, u_int);
-char *print_arg(struct syscall_args *, unsigned long*, long *, struct trussinfo *);
+char *print_arg(struct syscall_args *, unsigned long*, register_t *,
+    struct trussinfo *);
 
 /*
  * Linux Socket defines
@@ -271,5 +272,5 @@ struct linux_socketcall_args {
 
 void init_syscalls(void);
 void print_syscall(struct trussinfo *);
-void print_syscall_ret(struct trussinfo *, int, long *);
+void print_syscall_ret(struct trussinfo *, int, register_t *);
 void print_summary(struct trussinfo *trussinfo);

Modified: head/usr.bin/truss/syscalls.c
==============================================================================
--- head/usr.bin/truss/syscalls.c	Tue Jul 16 22:55:30 2019	(r350068)
+++ head/usr.bin/truss/syscalls.c	Tue Jul 16 22:59:15 2019	(r350069)
@@ -61,6 +61,8 @@ __FBSDID("$FreeBSD$");
 #include <assert.h>
 #include <ctype.h>
 #include <err.h>
+#define _WANT_KERNEL_ERRNO
+#include <errno.h>
 #include <fcntl.h>
 #include <poll.h>
 #include <sched.h>
@@ -1556,7 +1558,7 @@ print_cmsgs(FILE *fp, pid_t pid, bool receive, struct 
  * an array of all of the system call arguments.
  */
 char *
-print_arg(struct syscall_args *sc, unsigned long *args, long *retval,
+print_arg(struct syscall_args *sc, unsigned long *args, register_t *retval,
     struct trussinfo *trussinfo)
 {
 	FILE *fp;
@@ -2277,7 +2279,7 @@ print_arg(struct syscall_args *sc, unsigned long *args
 		 * Overwrite the first retval to signal a successful
 		 * return as well.
 		 */
-		fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]);
+		fprintf(fp, "{ %d, %d }", (int)retval[0], (int)retval[1]);
 		retval[0] = 0;
 		break;
 	case Utrace: {
@@ -2646,12 +2648,11 @@ print_syscall(struct trussinfo *trussinfo)
 }
 
 void
-print_syscall_ret(struct trussinfo *trussinfo, int errorp, long *retval)
+print_syscall_ret(struct trussinfo *trussinfo, int error, register_t *retval)
 {
 	struct timespec timediff;
 	struct threadinfo *t;
 	struct syscall *sc;
-	int error;
 
 	t = trussinfo->curthread;
 	sc = t->cs.sc;
@@ -2659,7 +2660,7 @@ print_syscall_ret(struct trussinfo *trussinfo, int err
 		timespecsub(&t->after, &t->before, &timediff);
 		timespecadd(&sc->time, &timediff, &sc->time);
 		sc->ncalls++;
-		if (errorp)
+		if (error != 0)
 			sc->nerror++;
 		return;
 	}
@@ -2676,11 +2677,14 @@ print_syscall_ret(struct trussinfo *trussinfo, int err
 		return;
 	}
 
-	if (errorp) {
-		error = sysdecode_abi_to_freebsd_errno(t->proc->abi->abi,
-		    retval[0]);
-		fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0],
-		    error == INT_MAX ? "Unknown error" : strerror(error));
+	if (error == ERESTART)
+		fprintf(trussinfo->outfile, " ERESTART\n");
+	else if (error == EJUSTRETURN)
+		fprintf(trussinfo->outfile, " EJUSTRETURN\n");
+	else if (error != 0) {
+		fprintf(trussinfo->outfile, " ERR#%d '%s'\n",
+		    sysdecode_freebsd_to_abi_errno(t->proc->abi->abi, error),
+		    strerror(error));
 	}
 #ifndef __LP64__
 	else if (sc->ret_type == 2) {
@@ -2696,8 +2700,8 @@ print_syscall_ret(struct trussinfo *trussinfo, int err
 	}
 #endif
 	else
-		fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval[0],
-		    retval[0]);
+		fprintf(trussinfo->outfile, " = %jd (0x%jx)\n",
+		    (intmax_t)retval[0], (intmax_t)retval[0]);
 }
 
 void

Modified: head/usr.bin/truss/truss.h
==============================================================================
--- head/usr.bin/truss/truss.h	Tue Jul 16 22:55:30 2019	(r350068)
+++ head/usr.bin/truss/truss.h	Tue Jul 16 22:59:15 2019	(r350069)
@@ -27,7 +27,6 @@
  * $FreeBSD$
  */
 
-#include <sys/linker_set.h>
 #include <sys/queue.h>
 
 #define	FOLLOWFORKS		0x00000001
@@ -59,13 +58,9 @@ struct extra_syscall {
 struct procabi {
 	const char *type;
 	enum sysdecode_abi abi;
-	int (*fetch_args)(struct trussinfo *, u_int);
-	int (*fetch_retval)(struct trussinfo *, long *, int *);
 	STAILQ_HEAD(, extra_syscall) extra_syscalls;
 	struct syscall *syscalls[SYSCALL_NORMAL_COUNT];
 };
-
-#define	PROCABI(abi)	DATA_SET(procabi, abi)
 
 /*
  * This is confusingly named.  It holds per-thread state about the



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201907162259.x6GMxFrJ069696>