aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/truss/setup.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-07-16 22:59:15 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2019-07-16 22:59:15 +0000
commitcaa449b63565ac48cc2f859c03afe40a5ff4f27c (patch)
tree7726a79675e6e690c1ae05c525742f80cafc7358 /usr.bin/truss/setup.c
parentdc9df3a59d67eefe904db06ab236db99c6d894e2 (diff)
downloadsrc-caa449b63565ac48cc2f859c03afe40a5ff4f27c.tar.gz
src-caa449b63565ac48cc2f859c03afe40a5ff4f27c.zip
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
Notes
Notes: svn path=/head/; revision=350069
Diffstat (limited to 'usr.bin/truss/setup.c')
-rw-r--r--usr.bin/truss/setup.c102
1 files changed, 89 insertions, 13 deletions
diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c
index cc28dda61e86..172d7d5d366c 100644
--- a/usr.bin/truss/setup.c
+++ b/usr.bin/truss/setup.c
@@ -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 threadinfo *,
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 threadinfo *t,
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 threadinfo *t,
#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_lwpinfo *pl)
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_lwpinfo *pl)
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_lwpinfo *pl)
* 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);
/*