Merge ^/head r288831 through r288835.

This commit is contained in:
Dimitry Andric 2015-10-05 20:08:11 +00:00
commit 926b24f309
5 changed files with 68 additions and 53 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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;
/*
* 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;
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;
}
}

View File

@ -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 *);

View File

@ -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,