summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/net/getaddrinfo.313
-rw-r--r--usr.bin/truss/main.c1
-rw-r--r--usr.bin/truss/setup.c59
-rw-r--r--usr.bin/truss/syscall.h4
-rw-r--r--usr.bin/truss/syscalls.c46
5 files changed, 69 insertions, 54 deletions
diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3
index e13c667..1d6cb56 100644
--- a/lib/libc/net/getaddrinfo.3
+++ b/lib/libc/net/getaddrinfo.3
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 20, 2015
+.Dd October 5, 2015
.Dt GETADDRINFO 3
.Os
.Sh NAME
@@ -243,15 +243,14 @@ The list can be traversed by following the
pointer in each
.Li addrinfo
structure until a null pointer is encountered.
-The three members
+Each returned
+.Li addrinfo
+structure contains three members that are suitable for a call to
+.Xr socket 2 :
.Fa ai_family ,
.Fa ai_socktype ,
and
-.Fa ai_protocol
-in each returned
-.Li addrinfo
-structure are suitable for a call to
-.Xr socket 2 .
+.Fa ai_protocol .
For each
.Li addrinfo
structure in the list, the
diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c
index 55fdeda..d46d01e 100644
--- a/usr.bin/truss/main.c
+++ b/usr.bin/truss/main.c
@@ -94,6 +94,7 @@ main(int ac, char **av)
trussinfo->strsize = 32;
trussinfo->curthread = NULL;
LIST_INIT(&trussinfo->proclist);
+ init_syscalls();
while ((c = getopt(ac, av, "p:o:facedDs:S")) != -1) {
switch (c) {
case 'p': /* specified pid */
diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c
index 4452f9f..74008e4 100644
--- a/usr.bin/truss/setup.c
+++ b/usr.bin/truss/setup.c
@@ -341,17 +341,9 @@ enter_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl)
fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n",
t->proc->abi->type, t->cs.number);
- sc = get_syscall(t->cs.name);
- if (sc) {
- t->cs.nargs = sc->nargs;
- assert(sc->nargs <= nitems(t->cs.s_args));
- } else {
-#if DEBUG
- fprintf(stderr, "unknown syscall %s -- setting "
- "args to %d\n", t->cs.name, t->cs.nargs);
-#endif
- t->cs.nargs = narg;
- }
+ sc = get_syscall(t->cs.name, narg);
+ t->cs.nargs = sc->nargs;
+ assert(sc->nargs <= nitems(t->cs.s_args));
t->cs.sc = sc;
@@ -372,7 +364,7 @@ enter_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl)
t->cs.args[sc->args[i].offset] : t->cs.args[i],
i < (t->cs.nargs - 1) ? "," : "");
#endif
- if (sc && !(sc->args[i].type & OUT)) {
+ if (!(sc->args[i].type & OUT)) {
t->cs.s_args[i] = print_arg(&sc->args[i],
t->cs.args, 0, info);
}
@@ -407,31 +399,26 @@ exit_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl)
}
sc = t->cs.sc;
- if (sc == NULL) {
- for (i = 0; i < t->cs.nargs; i++)
- asprintf(&t->cs.s_args[i], "0x%lx", t->cs.args[i]);
- } else {
- /*
- * Here, we only look for arguments that have OUT masked in --
- * otherwise, they were handled in enter_syscall().
- */
- for (i = 0; i < sc->nargs; i++) {
- char *temp;
-
- if (sc->args[i].type & OUT) {
- /*
- * If an error occurred, then don't bother
- * getting the data; it may not be valid.
- */
- if (errorp) {
- 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.s_args[i] = temp;
+ /*
+ * Here, we only look for arguments that have OUT masked in --
+ * otherwise, they were handled in enter_syscall().
+ */
+ for (i = 0; i < sc->nargs; i++) {
+ char *temp;
+
+ if (sc->args[i].type & OUT) {
+ /*
+ * If an error occurred, then don't bother
+ * getting the data; it may not be valid.
+ */
+ if (errorp) {
+ 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.s_args[i] = temp;
}
}
diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h
index 18dd33f..3e3a1b9 100644
--- a/usr.bin/truss/syscall.h
+++ b/usr.bin/truss/syscall.h
@@ -55,6 +55,7 @@ struct syscall_args {
};
struct syscall {
+ STAILQ_ENTRY(syscall) entries;
const char *name;
u_int ret_type; /* 0, 1, or 2 return values */
u_int nargs; /* actual number of meaningful arguments */
@@ -65,7 +66,7 @@ struct syscall {
int nerror; /* Number of calls that returned with error */
};
-struct syscall *get_syscall(const char*);
+struct syscall *get_syscall(const char *, int nargs);
char *print_arg(struct syscall_args *, unsigned long*, long *, struct trussinfo *);
/*
@@ -108,6 +109,7 @@ struct linux_socketcall_args {
char args_l_[PADL_(l_ulong)]; l_ulong args; char args_r_[PADR_(l_ulong)];
};
+void init_syscalls(void);
void print_syscall(struct trussinfo *, const char *, int, char **);
void print_syscall_ret(struct trussinfo *, const char *, int, char **, int,
long *, struct syscall *);
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index 6211bae..ddb1891 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
/*
* This should probably be in its own file, sorted alphabetically.
*/
-static struct syscall syscalls[] = {
+static struct syscall decoded_syscalls[] = {
{ .name = "fcntl", .ret_type = 1, .nargs = 3,
.args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } },
{ .name = "rfork", .ret_type = 1, .nargs = 1,
@@ -253,6 +253,8 @@ static struct syscall syscalls[] = {
.args = { { Int, 0 }, { Ptr, 1 } } },
{ .name = "kldfirstmod", .ret_type = 1, .nargs = 1,
.args = { { Int, 0 } } },
+ { .name = "modfind", .ret_type = 1, .nargs = 1,
+ .args = { { Name | IN, 0 } } },
{ .name = "nanosleep", .ret_type = 1, .nargs = 1,
.args = { { Timespec, 0 } } },
{ .name = "select", .ret_type = 1, .nargs = 5,
@@ -370,6 +372,7 @@ static struct syscall syscalls[] = {
.args = { { Ptr, 0 } } },
{ .name = 0 },
};
+static STAILQ_HEAD(, syscall) syscalls;
/* Xlat idea taken from strace */
struct xlat {
@@ -659,24 +662,49 @@ xlookup_bits(struct xlat *xlat, int val)
return (str);
}
+void
+init_syscalls(void)
+{
+ struct syscall *sc;
+
+ STAILQ_INIT(&syscalls);
+ for (sc = decoded_syscalls; sc->name != NULL; sc++)
+ STAILQ_INSERT_HEAD(&syscalls, sc, entries);
+}
/*
* If/when the list gets big, it might be desirable to do it
* as a hash table or binary search.
*/
struct syscall *
-get_syscall(const char *name)
+get_syscall(const char *name, int nargs)
{
struct syscall *sc;
+ int i;
- sc = syscalls;
if (name == NULL)
return (NULL);
- while (sc->name) {
+ STAILQ_FOREACH(sc, &syscalls, entries)
if (strcmp(name, sc->name) == 0)
return (sc);
- sc++;
+
+ /* It is unknown. Add it into the list. */
+#if DEBUG
+ fprintf(stderr, "unknown syscall %s -- setting args to %d\n", name,
+ nargs);
+#endif
+
+ sc = calloc(1, sizeof(struct syscall));
+ sc->name = strdup(name);
+ sc->ret_type = 1;
+ sc->nargs = nargs;
+ for (i = 0; i < nargs; i++) {
+ sc->args[i].offset = i;
+ /* Treat all unknown arguments as LongHex. */
+ sc->args[i].type = LongHex;
}
- return (NULL);
+ STAILQ_INSERT_HEAD(&syscalls, sc, entries);
+
+ return (sc);
}
/*
@@ -1632,8 +1660,6 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs,
struct timespec timediff;
if (trussinfo->flags & COUNTONLY) {
- if (!sc)
- return;
clock_gettime(CLOCK_REALTIME, &trussinfo->curthread->after);
timespecsubt(&trussinfo->curthread->after,
&trussinfo->curthread->before, &timediff);
@@ -1650,7 +1676,7 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs,
fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval[0],
strerror(retval[0]));
#ifndef __LP64__
- else if (sc != NULL && sc->ret_type == 2) {
+ else if (sc->ret_type == 2) {
off_t off;
#if _BYTE_ORDER == _LITTLE_ENDIAN
@@ -1677,7 +1703,7 @@ print_summary(struct trussinfo *trussinfo)
fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n",
"syscall", "seconds", "calls", "errors");
ncall = nerror = 0;
- for (sc = syscalls; sc->name != NULL; sc++)
+ STAILQ_FOREACH(sc, &syscalls, entries)
if (sc->ncalls) {
fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n",
sc->name, (intmax_t)sc->time.tv_sec,
OpenPOWER on IntegriCloud