Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/truss/syscalls.c
Show All 35 Lines | |||||
/* | /* | ||||
* This file has routines used to print out system calls and their | * This file has routines used to print out system calls and their | ||||
* arguments. | * arguments. | ||||
*/ | */ | ||||
#include <sys/capsicum.h> | #include <sys/capsicum.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#define _WANT_FREEBSD11_KEVENT | |||||
#include <sys/event.h> | #include <sys/event.h> | ||||
#include <sys/ioccom.h> | #include <sys/ioccom.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/ptrace.h> | #include <sys/ptrace.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#define _WANT_FREEBSD11_STAT | #define _WANT_FREEBSD11_STAT | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | /* Native ABI */ | ||||
.args = { { Int, 0 }, { Timespec | OUT, 1 } } }, | .args = { { Int, 0 }, { Timespec | OUT, 1 } } }, | ||||
{ .name = "close", .ret_type = 1, .nargs = 1, | { .name = "close", .ret_type = 1, .nargs = 1, | ||||
.args = { { Int, 0 } } }, | .args = { { Int, 0 } } }, | ||||
{ .name = "compat11.fstat", .ret_type = 1, .nargs = 2, | { .name = "compat11.fstat", .ret_type = 1, .nargs = 2, | ||||
.args = { { Int, 0 }, { Stat11 | OUT, 1 } } }, | .args = { { Int, 0 }, { Stat11 | OUT, 1 } } }, | ||||
{ .name = "compat11.fstatat", .ret_type = 1, .nargs = 4, | { .name = "compat11.fstatat", .ret_type = 1, .nargs = 4, | ||||
.args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat11 | OUT, 2 }, | .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat11 | OUT, 2 }, | ||||
{ Atflags, 3 } } }, | { Atflags, 3 } } }, | ||||
{ .name = "compat11.kevent", .ret_type = 1, .nargs = 6, | |||||
.args = { { Int, 0 }, { Kevent11, 1 }, { Int, 2 }, | |||||
{ Kevent11 | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } }, | |||||
{ .name = "compat11.lstat", .ret_type = 1, .nargs = 2, | { .name = "compat11.lstat", .ret_type = 1, .nargs = 2, | ||||
.args = { { Name | IN, 0 }, { Stat11 | OUT, 1 } } }, | .args = { { Name | IN, 0 }, { Stat11 | OUT, 1 } } }, | ||||
{ .name = "compat11.stat", .ret_type = 1, .nargs = 2, | { .name = "compat11.stat", .ret_type = 1, .nargs = 2, | ||||
.args = { { Name | IN, 0 }, { Stat11 | OUT, 1 } } }, | .args = { { Name | IN, 0 }, { Stat11 | OUT, 1 } } }, | ||||
{ .name = "connect", .ret_type = 1, .nargs = 3, | { .name = "connect", .ret_type = 1, .nargs = 3, | ||||
.args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Socklent, 2 } } }, | .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Socklent, 2 } } }, | ||||
{ .name = "connectat", .ret_type = 1, .nargs = 4, | { .name = "connectat", .ret_type = 1, .nargs = 4, | ||||
.args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, | .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, | ||||
▲ Show 20 Lines • Show All 482 Lines • ▼ Show 20 Lines | |||||
struct xlat { | struct xlat { | ||||
int val; | int val; | ||||
const char *str; | const char *str; | ||||
}; | }; | ||||
#define X(a) { a, #a }, | #define X(a) { a, #a }, | ||||
#define XEND { 0, NULL } | #define XEND { 0, NULL } | ||||
static struct xlat kevent_filters[] = { | |||||
X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE) | |||||
X(EVFILT_PROC) X(EVFILT_SIGNAL) X(EVFILT_TIMER) | |||||
X(EVFILT_PROCDESC) X(EVFILT_FS) X(EVFILT_LIO) X(EVFILT_USER) | |||||
X(EVFILT_SENDFILE) XEND | |||||
}; | |||||
static struct xlat kevent_flags[] = { | |||||
X(EV_ADD) X(EV_DELETE) X(EV_ENABLE) X(EV_DISABLE) X(EV_ONESHOT) | |||||
X(EV_CLEAR) X(EV_RECEIPT) X(EV_DISPATCH) X(EV_FORCEONESHOT) | |||||
X(EV_DROP) X(EV_FLAG1) X(EV_ERROR) X(EV_EOF) XEND | |||||
}; | |||||
static struct xlat kevent_user_ffctrl[] = { | |||||
X(NOTE_FFNOP) X(NOTE_FFAND) X(NOTE_FFOR) X(NOTE_FFCOPY) | |||||
XEND | |||||
}; | |||||
static struct xlat kevent_rdwr_fflags[] = { | |||||
X(NOTE_LOWAT) X(NOTE_FILE_POLL) XEND | |||||
}; | |||||
static struct xlat kevent_vnode_fflags[] = { | |||||
X(NOTE_DELETE) X(NOTE_WRITE) X(NOTE_EXTEND) X(NOTE_ATTRIB) | |||||
X(NOTE_LINK) X(NOTE_RENAME) X(NOTE_REVOKE) XEND | |||||
}; | |||||
static struct xlat kevent_proc_fflags[] = { | |||||
X(NOTE_EXIT) X(NOTE_FORK) X(NOTE_EXEC) X(NOTE_TRACK) X(NOTE_TRACKERR) | |||||
X(NOTE_CHILD) XEND | |||||
}; | |||||
static struct xlat kevent_timer_fflags[] = { | |||||
X(NOTE_SECONDS) X(NOTE_MSECONDS) X(NOTE_USECONDS) X(NOTE_NSECONDS) | |||||
XEND | |||||
}; | |||||
static struct xlat poll_flags[] = { | static struct xlat poll_flags[] = { | ||||
X(POLLSTANDARD) X(POLLIN) X(POLLPRI) X(POLLOUT) X(POLLERR) | X(POLLSTANDARD) X(POLLIN) X(POLLPRI) X(POLLOUT) X(POLLERR) | ||||
X(POLLHUP) X(POLLNVAL) X(POLLRDNORM) X(POLLRDBAND) | X(POLLHUP) X(POLLNVAL) X(POLLRDNORM) X(POLLRDBAND) | ||||
X(POLLWRBAND) X(POLLINIGNEOF) XEND | X(POLLWRBAND) X(POLLINIGNEOF) XEND | ||||
}; | }; | ||||
static struct xlat sigaction_flags[] = { | static struct xlat sigaction_flags[] = { | ||||
X(SA_ONSTACK) X(SA_RESTART) X(SA_RESETHAND) X(SA_NOCLDSTOP) | X(SA_ONSTACK) X(SA_RESTART) X(SA_RESETHAND) X(SA_NOCLDSTOP) | ||||
▲ Show 20 Lines • Show All 434 Lines • ▼ Show 20 Lines | strsig2(int sig) | ||||
if (signame == NULL) { | if (signame == NULL) { | ||||
snprintf(tmp, sizeof(tmp), "%d", sig); | snprintf(tmp, sizeof(tmp), "%d", sig); | ||||
signame = tmp; | signame = tmp; | ||||
} | } | ||||
return (signame); | return (signame); | ||||
} | } | ||||
static void | static void | ||||
print_kevent(FILE *fp, struct kevent *ke, int input) | print_kevent(FILE *fp, struct kevent *ke) | ||||
{ | { | ||||
switch (ke->filter) { | switch (ke->filter) { | ||||
case EVFILT_READ: | case EVFILT_READ: | ||||
case EVFILT_WRITE: | case EVFILT_WRITE: | ||||
case EVFILT_VNODE: | case EVFILT_VNODE: | ||||
case EVFILT_PROC: | case EVFILT_PROC: | ||||
case EVFILT_TIMER: | case EVFILT_TIMER: | ||||
case EVFILT_PROCDESC: | case EVFILT_PROCDESC: | ||||
case EVFILT_EMPTY: | |||||
fprintf(fp, "%ju", (uintmax_t)ke->ident); | fprintf(fp, "%ju", (uintmax_t)ke->ident); | ||||
break; | break; | ||||
case EVFILT_SIGNAL: | case EVFILT_SIGNAL: | ||||
fputs(strsig2(ke->ident), fp); | fputs(strsig2(ke->ident), fp); | ||||
break; | break; | ||||
default: | default: | ||||
fprintf(fp, "%p", (void *)ke->ident); | fprintf(fp, "%p", (void *)ke->ident); | ||||
} | } | ||||
fprintf(fp, ",%s,%s,", xlookup(kevent_filters, ke->filter), | fprintf(fp, ","); | ||||
xlookup_bits(kevent_flags, ke->flags)); | print_integer_arg(sysdecode_kevent_filter, fp, ke->filter); | ||||
switch (ke->filter) { | fprintf(fp, ","); | ||||
case EVFILT_READ: | print_mask_arg(sysdecode_kevent_flags, fp, ke->flags); | ||||
case EVFILT_WRITE: | fprintf(fp, ","); | ||||
fputs(xlookup_bits(kevent_rdwr_fflags, ke->fflags), fp); | sysdecode_kevent_fflags(fp, ke->filter, ke->fflags, 16); | ||||
break; | |||||
case EVFILT_VNODE: | |||||
fputs(xlookup_bits(kevent_vnode_fflags, ke->fflags), fp); | |||||
break; | |||||
case EVFILT_PROC: | |||||
case EVFILT_PROCDESC: | |||||
fputs(xlookup_bits(kevent_proc_fflags, ke->fflags), fp); | |||||
break; | |||||
case EVFILT_TIMER: | |||||
fputs(xlookup_bits(kevent_timer_fflags, ke->fflags), fp); | |||||
break; | |||||
case EVFILT_USER: { | |||||
int ctrl, data; | |||||
ctrl = ke->fflags & NOTE_FFCTRLMASK; | |||||
data = ke->fflags & NOTE_FFLAGSMASK; | |||||
if (input) { | |||||
fputs(xlookup(kevent_user_ffctrl, ctrl), fp); | |||||
if (ke->fflags & NOTE_TRIGGER) | |||||
fputs("|NOTE_TRIGGER", fp); | |||||
if (data != 0) | |||||
fprintf(fp, "|%#x", data); | |||||
} else { | |||||
fprintf(fp, "%#x", data); | |||||
} | |||||
break; | |||||
} | |||||
default: | |||||
fprintf(fp, "%#x", ke->fflags); | |||||
} | |||||
fprintf(fp, ",%#jx,%p", (uintmax_t)ke->data, ke->udata); | fprintf(fp, ",%#jx,%p", (uintmax_t)ke->data, ke->udata); | ||||
} | } | ||||
static void | static void | ||||
print_utrace(FILE *fp, void *utrace_addr, size_t len) | print_utrace(FILE *fp, void *utrace_addr, size_t len) | ||||
{ | { | ||||
unsigned char *utrace_buffer; | unsigned char *utrace_buffer; | ||||
▲ Show 20 Lines • Show All 588 Lines • ▼ Show 20 Lines | if (numevents >= 0) { | ||||
bytes); | bytes); | ||||
} else | } else | ||||
ke = NULL; | ke = NULL; | ||||
if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], | if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], | ||||
ke, bytes) != -1) { | ke, bytes) != -1) { | ||||
fputc('{', fp); | fputc('{', fp); | ||||
for (i = 0; i < numevents; i++) { | for (i = 0; i < numevents; i++) { | ||||
fputc(' ', fp); | fputc(' ', fp); | ||||
print_kevent(fp, &ke[i], sc->offset == 1); | print_kevent(fp, &ke[i]); | ||||
} | } | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else { | } else { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | fprintf(fp, "0x%lx", args[sc->offset]); | ||||
} | } | ||||
free(ke); | free(ke); | ||||
break; | |||||
} | |||||
case Kevent11: { | |||||
struct kevent_freebsd11 *ke11; | |||||
struct kevent ke; | |||||
int numevents = -1; | |||||
size_t bytes; | |||||
int i; | |||||
if (sc->offset == 1) | |||||
numevents = args[sc->offset+1]; | |||||
else if (sc->offset == 3 && retval[0] != -1) | |||||
numevents = retval[0]; | |||||
if (numevents >= 0) { | |||||
bytes = sizeof(struct kevent_freebsd11) * numevents; | |||||
if ((ke11 = malloc(bytes)) == NULL) | |||||
err(1, | |||||
"Cannot malloc %zu bytes for kevent array", | |||||
bytes); | |||||
} else | |||||
ke11 = NULL; | |||||
memset(&ke, 0, sizeof(ke)); | |||||
if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], | |||||
ke11, bytes) != -1) { | |||||
fputc('{', fp); | |||||
for (i = 0; i < numevents; i++) { | |||||
fputc(' ', fp); | |||||
ke.ident = ke11[i].ident; | |||||
ke.filter = ke11[i].filter; | |||||
ke.flags = ke11[i].flags; | |||||
ke.fflags = ke11[i].fflags; | |||||
ke.data = ke11[i].data; | |||||
ke.udata = ke11[i].udata; | |||||
print_kevent(fp, &ke); | |||||
} | |||||
fputs(" }", fp); | |||||
} else { | |||||
fprintf(fp, "0x%lx", args[sc->offset]); | |||||
} | |||||
free(ke11); | |||||
break; | break; | ||||
} | } | ||||
case Stat: { | case Stat: { | ||||
struct stat st; | struct stat st; | ||||
if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) | if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) | ||||
!= -1) { | != -1) { | ||||
char mode[12]; | char mode[12]; | ||||
▲ Show 20 Lines • Show All 545 Lines • Show Last 20 Lines |