Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/truss/syscalls.c
Show First 20 Lines • Show All 1,045 Lines • ▼ Show 20 Lines | #endif | ||||
return (sc); | return (sc); | ||||
} | } | ||||
/* | /* | ||||
* Copy a fixed amount of bytes from the process. | * Copy a fixed amount of bytes from the process. | ||||
*/ | */ | ||||
static int | static int | ||||
get_struct(pid_t pid, void *offset, void *buf, int len) | get_struct(pid_t pid, uintptr_t offset, void *buf, int len) | ||||
{ | { | ||||
struct ptrace_io_desc iorequest; | struct ptrace_io_desc iorequest; | ||||
iorequest.piod_op = PIOD_READ_D; | iorequest.piod_op = PIOD_READ_D; | ||||
iorequest.piod_offs = offset; | iorequest.piod_offs = (void *)offset; | ||||
iorequest.piod_addr = buf; | iorequest.piod_addr = buf; | ||||
iorequest.piod_len = len; | iorequest.piod_len = len; | ||||
if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) | if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) | ||||
return (-1); | return (-1); | ||||
return (0); | return (0); | ||||
} | } | ||||
#define MAXSIZE 4096 | #define MAXSIZE 4096 | ||||
/* | /* | ||||
* Copy a string from the process. Note that it is | * Copy a string from the process. Note that it is | ||||
* expected to be a C string, but if max is set, it will | * expected to be a C string, but if max is set, it will | ||||
* only get that much. | * only get that much. | ||||
*/ | */ | ||||
static char * | static char * | ||||
get_string(pid_t pid, void *addr, int max) | get_string(pid_t pid, uintptr_t addr, int max) | ||||
{ | { | ||||
struct ptrace_io_desc iorequest; | struct ptrace_io_desc iorequest; | ||||
char *buf, *nbuf; | char *buf, *nbuf; | ||||
size_t offset, size, totalsize; | size_t offset, size, totalsize; | ||||
offset = 0; | offset = 0; | ||||
if (max) | if (max) | ||||
size = max + 1; | size = max + 1; | ||||
else { | else { | ||||
/* Read up to the end of the current page. */ | /* Read up to the end of the current page. */ | ||||
size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE); | size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE); | ||||
if (size > MAXSIZE) | if (size > MAXSIZE) | ||||
size = MAXSIZE; | size = MAXSIZE; | ||||
} | } | ||||
totalsize = size; | totalsize = size; | ||||
buf = malloc(totalsize); | buf = malloc(totalsize); | ||||
if (buf == NULL) | if (buf == NULL) | ||||
return (NULL); | return (NULL); | ||||
for (;;) { | for (;;) { | ||||
iorequest.piod_op = PIOD_READ_D; | iorequest.piod_op = PIOD_READ_D; | ||||
iorequest.piod_offs = (char *)addr + offset; | iorequest.piod_offs = (void *)(addr + offset); | ||||
iorequest.piod_addr = buf + offset; | iorequest.piod_addr = buf + offset; | ||||
iorequest.piod_len = size; | iorequest.piod_len = size; | ||||
if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) { | if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) { | ||||
free(buf); | free(buf); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (memchr(buf + offset, '\0', size) != NULL) | if (memchr(buf + offset, '\0', size) != NULL) | ||||
return (buf); | return (buf); | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | print_utrace(FILE *fp, void *utrace_addr, size_t len) | ||||
utrace_buffer = utrace_addr; | utrace_buffer = utrace_addr; | ||||
fprintf(fp, "%zu:", len); | fprintf(fp, "%zu:", len); | ||||
while (len--) | while (len--) | ||||
fprintf(fp, " %02x", *utrace_buffer++); | fprintf(fp, " %02x", *utrace_buffer++); | ||||
fprintf(fp, " }"); | fprintf(fp, " }"); | ||||
} | } | ||||
static void | static void | ||||
print_sockaddr(FILE *fp, struct trussinfo *trussinfo, void *arg, socklen_t len) | print_pointer(FILE *fp, uintptr_t arg) | ||||
{ | { | ||||
fprintf(fp, "%p", (void *)arg); | |||||
cem: This regresses the NULL case for a number of callers that explicitly prefixed `0x` before (and… | |||||
jhbUnsubmitted Not Done Inline ActionsEh, %p on FreeBSD includes a 0x prefix. FreeBSD is not Linux: case 'p': /*- * ``The argument shall be a pointer to void. The * value of the pointer is converted to a sequence * of printable characters, in an implementation- * defined manner.'' * -- ANSI X3J11 */ ujval = (uintmax_t)(uintptr_t)GETARG(void *); base = 16; xdigs = xdigs_lower; flags = flags | INTMAXT; ox[1] = 'x'; goto nosign; .... if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; PRINT(ox, 2); } The other reason for print_pointer is that it gives us a place to pretty-print NULL (as I said earlier) which I had wanted to do in truss back when doing the initial sysdecode work just hadn't gotten around to. jhb: Eh, %p on FreeBSD includes a 0x prefix. FreeBSD is not Linux:
```
case 'p':
/*-
*… | |||||
cemUnsubmitted Not Done Inline ActionsAh, I didn't realize the userspace version of printf did that. The kernel version does not: 796 case 'p': 797 base = 16; 798 sharpflag = (width == 0); 799 sign = 0; 800 num = (uintptr_t)va_arg(ap, void *); 801 goto number; ... 914 if (sharpflag && num != 0) { <<<<<< 915 if (base == 8) { 916 PCHAR('0'); 917 } else if (base == 16) { 918 PCHAR('0'); 919 PCHAR('x'); cem: Ah, I didn't realize the userspace version of printf did that. The kernel version does not… | |||||
} | |||||
static void | |||||
print_sockaddr(FILE *fp, struct trussinfo *trussinfo, uintptr_t arg, | |||||
socklen_t len) | |||||
{ | |||||
char addr[64]; | char addr[64]; | ||||
struct sockaddr_in *lsin; | struct sockaddr_in *lsin; | ||||
struct sockaddr_in6 *lsin6; | struct sockaddr_in6 *lsin6; | ||||
struct sockaddr_un *sun; | struct sockaddr_un *sun; | ||||
struct sockaddr *sa; | struct sockaddr *sa; | ||||
u_char *q; | u_char *q; | ||||
pid_t pid = trussinfo->curthread->proc->pid; | pid_t pid = trussinfo->curthread->proc->pid; | ||||
if (arg == NULL) { | if (arg == 0) { | ||||
fputs("NULL", fp); | fputs("NULL", fp); | ||||
return; | return; | ||||
} | } | ||||
/* If the length is too small, just bail. */ | /* If the length is too small, just bail. */ | ||||
if (len < sizeof(*sa)) { | if (len < sizeof(*sa)) { | ||||
fprintf(fp, "%p", arg); | print_pointer(fp, arg); | ||||
return; | return; | ||||
} | } | ||||
sa = calloc(1, len); | sa = calloc(1, len); | ||||
if (get_struct(pid, arg, sa, len) == -1) { | if (get_struct(pid, arg, sa, len) == -1) { | ||||
free(sa); | free(sa); | ||||
fprintf(fp, "%p", arg); | print_pointer(fp, arg); | ||||
return; | return; | ||||
} | } | ||||
switch (sa->sa_family) { | switch (sa->sa_family) { | ||||
case AF_INET: | case AF_INET: | ||||
if (len < sizeof(*lsin)) | if (len < sizeof(*lsin)) | ||||
goto sockaddr_short; | goto sockaddr_short; | ||||
lsin = (struct sockaddr_in *)(void *)sa; | lsin = (struct sockaddr_in *)(void *)sa; | ||||
Show All 29 Lines | sockaddr_short: | ||||
fputs(" } }", fp); | fputs(" } }", fp); | ||||
} | } | ||||
free(sa); | free(sa); | ||||
} | } | ||||
#define IOV_LIMIT 16 | #define IOV_LIMIT 16 | ||||
static void | static void | ||||
print_iovec(FILE *fp, struct trussinfo *trussinfo, void *arg, int iovcnt) | print_iovec(FILE *fp, struct trussinfo *trussinfo, uintptr_t arg, int iovcnt) | ||||
{ | { | ||||
struct iovec iov[IOV_LIMIT]; | struct iovec iov[IOV_LIMIT]; | ||||
size_t max_string = trussinfo->strsize; | size_t max_string = trussinfo->strsize; | ||||
char tmp2[max_string + 1], *tmp3; | char tmp2[max_string + 1], *tmp3; | ||||
size_t len; | size_t len; | ||||
pid_t pid = trussinfo->curthread->proc->pid; | pid_t pid = trussinfo->curthread->proc->pid; | ||||
int i; | int i; | ||||
bool buf_truncated, iov_truncated; | bool buf_truncated, iov_truncated; | ||||
if (iovcnt <= 0) { | if (iovcnt <= 0) { | ||||
fprintf(fp, "%p", arg); | print_pointer(fp, arg); | ||||
return; | return; | ||||
} | } | ||||
if (iovcnt > IOV_LIMIT) { | if (iovcnt > IOV_LIMIT) { | ||||
iovcnt = IOV_LIMIT; | iovcnt = IOV_LIMIT; | ||||
iov_truncated = true; | iov_truncated = true; | ||||
} else { | } else { | ||||
iov_truncated = false; | iov_truncated = false; | ||||
} | } | ||||
if (get_struct(pid, arg, &iov, iovcnt * sizeof(struct iovec)) == -1) { | if (get_struct(pid, arg, &iov, iovcnt * sizeof(struct iovec)) == -1) { | ||||
fprintf(fp, "%p", arg); | print_pointer(fp, arg); | ||||
return; | return; | ||||
} | } | ||||
fputs("[", fp); | fputs("[", fp); | ||||
for (i = 0; i < iovcnt; i++) { | for (i = 0; i < iovcnt; i++) { | ||||
len = iov[i].iov_len; | len = iov[i].iov_len; | ||||
if (len > max_string) { | if (len > max_string) { | ||||
len = max_string; | len = max_string; | ||||
buf_truncated = true; | buf_truncated = true; | ||||
} else { | } else { | ||||
buf_truncated = false; | buf_truncated = false; | ||||
} | } | ||||
fprintf(fp, "%s{", (i > 0) ? "," : ""); | fprintf(fp, "%s{", (i > 0) ? "," : ""); | ||||
if (len && get_struct(pid, iov[i].iov_base, &tmp2, len) != -1) { | if (len && get_struct(pid, (uintptr_t)iov[i].iov_base, &tmp2, len) != -1) { | ||||
tmp3 = malloc(len * 4 + 1); | tmp3 = malloc(len * 4 + 1); | ||||
while (len) { | while (len) { | ||||
if (strvisx(tmp3, tmp2, len, | if (strvisx(tmp3, tmp2, len, | ||||
VIS_CSTYLE|VIS_TAB|VIS_NL) <= | VIS_CSTYLE|VIS_TAB|VIS_NL) <= | ||||
(int)max_string) | (int)max_string) | ||||
break; | break; | ||||
len--; | len--; | ||||
buf_truncated = true; | buf_truncated = true; | ||||
} | } | ||||
fprintf(fp, "\"%s\"%s", tmp3, | fprintf(fp, "\"%s\"%s", tmp3, | ||||
buf_truncated ? "..." : ""); | buf_truncated ? "..." : ""); | ||||
free(tmp3); | free(tmp3); | ||||
} else { | } else { | ||||
fprintf(fp, "%p", iov[i].iov_base); | print_pointer(fp, (uintptr_t)iov[i].iov_base); | ||||
} | } | ||||
fprintf(fp, ",%zu}", iov[i].iov_len); | fprintf(fp, ",%zu}", iov[i].iov_len); | ||||
} | } | ||||
fprintf(fp, "%s%s", iov_truncated ? ",..." : "", "]"); | fprintf(fp, "%s%s", iov_truncated ? ",..." : "", "]"); | ||||
} | } | ||||
static void | static void | ||||
print_gen_cmsg(FILE *fp, struct cmsghdr *cmsghdr) | print_gen_cmsg(FILE *fp, struct cmsghdr *cmsghdr) | ||||
▲ Show 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | print_cmsgs(FILE *fp, pid_t pid, bool receive, struct msghdr *msghdr) | ||||
bool first; | bool first; | ||||
len = msghdr->msg_controllen; | len = msghdr->msg_controllen; | ||||
if (len == 0) { | if (len == 0) { | ||||
fputs("{}", fp); | fputs("{}", fp); | ||||
return; | return; | ||||
} | } | ||||
cmsgbuf = calloc(1, len); | cmsgbuf = calloc(1, len); | ||||
if (get_struct(pid, msghdr->msg_control, cmsgbuf, len) == -1) { | if (get_struct(pid, (uintptr_t)msghdr->msg_control, cmsgbuf, len) == -1) { | ||||
fprintf(fp, "%p", msghdr->msg_control); | print_pointer(fp, (uintptr_t)msghdr->msg_control); | ||||
free(cmsgbuf); | free(cmsgbuf); | ||||
return; | return; | ||||
} | } | ||||
msghdr->msg_control = cmsgbuf; | msghdr->msg_control = cmsgbuf; | ||||
first = true; | first = true; | ||||
fputs("{", fp); | fputs("{", fp); | ||||
for (cmsghdr = CMSG_FIRSTHDR(msghdr); | for (cmsghdr = CMSG_FIRSTHDR(msghdr); | ||||
cmsghdr != NULL; | cmsghdr != NULL; | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | case Int: | ||||
fprintf(fp, "%d", (int)args[sc->offset]); | fprintf(fp, "%d", (int)args[sc->offset]); | ||||
break; | break; | ||||
case UInt: | case UInt: | ||||
fprintf(fp, "%u", (unsigned int)args[sc->offset]); | fprintf(fp, "%u", (unsigned int)args[sc->offset]); | ||||
break; | break; | ||||
case PUInt: { | case PUInt: { | ||||
unsigned int val; | unsigned int val; | ||||
if (get_struct(pid, (void *)args[sc->offset], &val, | if (get_struct(pid, args[sc->offset], &val, | ||||
sizeof(val)) == 0) | sizeof(val)) == 0) | ||||
fprintf(fp, "{ %u }", val); | fprintf(fp, "{ %u }", val); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case LongHex: | case LongHex: | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | fprintf(fp, "0x%lx", args[sc->offset]); | ||||
break; | break; | ||||
case Long: | case Long: | ||||
fprintf(fp, "%ld", args[sc->offset]); | fprintf(fp, "%ld", args[sc->offset]); | ||||
break; | break; | ||||
case Sizet: | case Sizet: | ||||
fprintf(fp, "%zu", (size_t)args[sc->offset]); | fprintf(fp, "%zu", (size_t)args[sc->offset]); | ||||
break; | break; | ||||
case ShmName: | case ShmName: | ||||
/* Handle special SHM_ANON value. */ | /* Handle special SHM_ANON value. */ | ||||
if ((char *)args[sc->offset] == SHM_ANON) { | if ((char *)args[sc->offset] == SHM_ANON) { | ||||
fprintf(fp, "SHM_ANON"); | fprintf(fp, "SHM_ANON"); | ||||
break; | break; | ||||
} | } | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case Name: { | case Name: { | ||||
/* NULL-terminated string. */ | /* NULL-terminated string. */ | ||||
char *tmp2; | char *tmp2; | ||||
tmp2 = get_string(pid, (void*)args[sc->offset], 0); | tmp2 = get_string(pid, args[sc->offset], 0); | ||||
fprintf(fp, "\"%s\"", tmp2); | fprintf(fp, "\"%s\"", tmp2); | ||||
free(tmp2); | free(tmp2); | ||||
break; | break; | ||||
} | } | ||||
case BinString: { | case BinString: { | ||||
/* | /* | ||||
* Binary block of data that might have printable characters. | * Binary block of data that might have printable characters. | ||||
* XXX If type|OUT, assume that the length is the syscall's | * XXX If type|OUT, assume that the length is the syscall's | ||||
Show All 13 Lines | case BinString: { | ||||
/* | /* | ||||
* Don't print more than max_string characters, to avoid word | * Don't print more than max_string characters, to avoid word | ||||
* wrap. If we have to truncate put some ... after the string. | * wrap. If we have to truncate put some ... after the string. | ||||
*/ | */ | ||||
if (len > max_string) { | if (len > max_string) { | ||||
len = max_string; | len = max_string; | ||||
truncated = 1; | truncated = 1; | ||||
} | } | ||||
if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) | if (len && get_struct(pid, args[sc->offset], &tmp2, len) | ||||
!= -1) { | != -1) { | ||||
tmp3 = malloc(len * 4 + 1); | tmp3 = malloc(len * 4 + 1); | ||||
while (len) { | while (len) { | ||||
if (strvisx(tmp3, tmp2, len, | if (strvisx(tmp3, tmp2, len, | ||||
VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string) | VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string) | ||||
break; | break; | ||||
len--; | len--; | ||||
truncated = 1; | truncated = 1; | ||||
} | } | ||||
fprintf(fp, "\"%s\"%s", tmp3, truncated ? | fprintf(fp, "\"%s\"%s", tmp3, truncated ? | ||||
"..." : ""); | "..." : ""); | ||||
free(tmp3); | free(tmp3); | ||||
} else { | } else { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
case ExecArgs: | case ExecArgs: | ||||
case ExecEnv: | case ExecEnv: | ||||
case StringArray: { | case StringArray: { | ||||
uintptr_t addr; | uintptr_t addr; | ||||
union { | union { | ||||
char *strarray[0]; | char *strarray[0]; | ||||
char buf[PAGE_SIZE]; | char buf[PAGE_SIZE]; | ||||
} u; | } u; | ||||
char *string; | char *string; | ||||
size_t len; | size_t len; | ||||
u_int first, i; | u_int first, i; | ||||
/* | /* | ||||
* Only parse argv[] and environment arrays from exec calls | * Only parse argv[] and environment arrays from exec calls | ||||
* if requested. | * if requested. | ||||
*/ | */ | ||||
if (((sc->type & ARG_MASK) == ExecArgs && | if (((sc->type & ARG_MASK) == ExecArgs && | ||||
(trussinfo->flags & EXECVEARGS) == 0) || | (trussinfo->flags & EXECVEARGS) == 0) || | ||||
((sc->type & ARG_MASK) == ExecEnv && | ((sc->type & ARG_MASK) == ExecEnv && | ||||
(trussinfo->flags & EXECVEENVS) == 0)) { | (trussinfo->flags & EXECVEENVS) == 0)) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* Read a page of pointers at a time. Punt if the top-level | * Read a page of pointers at a time. Punt if the top-level | ||||
* pointer is not aligned. Note that the first read is of | * pointer is not aligned. Note that the first read is of | ||||
* a partial page. | * a partial page. | ||||
*/ | */ | ||||
addr = args[sc->offset]; | addr = args[sc->offset]; | ||||
if (addr % sizeof(char *) != 0) { | if (addr % sizeof(char *) != 0) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
len = PAGE_SIZE - (addr & PAGE_MASK); | len = PAGE_SIZE - (addr & PAGE_MASK); | ||||
if (get_struct(pid, (void *)addr, u.buf, len) == -1) { | if (get_struct(pid, addr, u.buf, len) == -1) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
fputc('[', fp); | fputc('[', fp); | ||||
first = 1; | first = 1; | ||||
i = 0; | i = 0; | ||||
while (u.strarray[i] != NULL) { | while (u.strarray[i] != NULL) { | ||||
string = get_string(pid, u.strarray[i], 0); | string = get_string(pid, (uintptr_t)u.strarray[i], 0); | ||||
fprintf(fp, "%s \"%s\"", first ? "" : ",", string); | fprintf(fp, "%s \"%s\"", first ? "" : ",", string); | ||||
free(string); | free(string); | ||||
first = 0; | first = 0; | ||||
i++; | i++; | ||||
if (i == len / sizeof(char *)) { | if (i == len / sizeof(char *)) { | ||||
addr += len; | addr += len; | ||||
len = PAGE_SIZE; | len = PAGE_SIZE; | ||||
if (get_struct(pid, (void *)addr, u.buf, len) == | if (get_struct(pid, addr, u.buf, len) == | ||||
-1) { | -1) { | ||||
fprintf(fp, ", <inval>"); | fprintf(fp, ", <inval>"); | ||||
break; | break; | ||||
} | } | ||||
i = 0; | i = 0; | ||||
} | } | ||||
} | } | ||||
fputs(" ]", fp); | fputs(" ]", fp); | ||||
Show All 23 Lines | #endif | ||||
else | else | ||||
fprintf(fp, "0x%llx", ll); | fprintf(fp, "0x%llx", ll); | ||||
break; | break; | ||||
} | } | ||||
#endif | #endif | ||||
case PQuadHex: { | case PQuadHex: { | ||||
uint64_t val; | uint64_t val; | ||||
if (get_struct(pid, (void *)args[sc->offset], &val, | if (get_struct(pid, args[sc->offset], &val, | ||||
sizeof(val)) == 0) | sizeof(val)) == 0) | ||||
fprintf(fp, "{ 0x%jx }", (uintmax_t)val); | fprintf(fp, "{ 0x%jx }", (uintmax_t)val); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Ptr: | case Ptr: | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
case Readlinkres: { | case Readlinkres: { | ||||
char *tmp2; | char *tmp2; | ||||
if (retval[0] == -1) | if (retval[0] == -1) | ||||
break; | break; | ||||
tmp2 = get_string(pid, (void*)args[sc->offset], retval[0]); | tmp2 = get_string(pid, args[sc->offset], retval[0]); | ||||
fprintf(fp, "\"%s\"", tmp2); | fprintf(fp, "\"%s\"", tmp2); | ||||
free(tmp2); | free(tmp2); | ||||
break; | break; | ||||
} | } | ||||
case Ioctl: { | case Ioctl: { | ||||
const char *temp; | const char *temp; | ||||
unsigned long cmd; | unsigned long cmd; | ||||
cmd = args[sc->offset]; | cmd = args[sc->offset]; | ||||
temp = sysdecode_ioctlname(cmd); | temp = sysdecode_ioctlname(cmd); | ||||
if (temp) | if (temp) | ||||
fputs(temp, fp); | fputs(temp, fp); | ||||
else { | else { | ||||
fprintf(fp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", | fprintf(fp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", | ||||
cmd, cmd & IOC_OUT ? "R" : "", | cmd, cmd & IOC_OUT ? "R" : "", | ||||
cmd & IOC_IN ? "W" : "", IOCGROUP(cmd), | cmd & IOC_IN ? "W" : "", IOCGROUP(cmd), | ||||
isprint(IOCGROUP(cmd)) ? (char)IOCGROUP(cmd) : '?', | isprint(IOCGROUP(cmd)) ? (char)IOCGROUP(cmd) : '?', | ||||
cmd & 0xFF, IOCPARM_LEN(cmd)); | cmd & 0xFF, IOCPARM_LEN(cmd)); | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
case Timespec: { | case Timespec: { | ||||
struct timespec ts; | struct timespec ts; | ||||
if (get_struct(pid, (void *)args[sc->offset], &ts, | if (get_struct(pid, args[sc->offset], &ts, sizeof(ts)) != -1) | ||||
sizeof(ts)) != -1) | |||||
fprintf(fp, "{ %jd.%09ld }", (intmax_t)ts.tv_sec, | fprintf(fp, "{ %jd.%09ld }", (intmax_t)ts.tv_sec, | ||||
ts.tv_nsec); | ts.tv_nsec); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Timespec2: { | case Timespec2: { | ||||
struct timespec ts[2]; | struct timespec ts[2]; | ||||
const char *sep; | const char *sep; | ||||
unsigned int i; | unsigned int i; | ||||
if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) | if (get_struct(pid, args[sc->offset], &ts, sizeof(ts)) != -1) { | ||||
!= -1) { | |||||
fputs("{ ", fp); | fputs("{ ", fp); | ||||
sep = ""; | sep = ""; | ||||
for (i = 0; i < nitems(ts); i++) { | for (i = 0; i < nitems(ts); i++) { | ||||
fputs(sep, fp); | fputs(sep, fp); | ||||
sep = ", "; | sep = ", "; | ||||
switch (ts[i].tv_nsec) { | switch (ts[i].tv_nsec) { | ||||
case UTIME_NOW: | case UTIME_NOW: | ||||
fprintf(fp, "UTIME_NOW"); | fprintf(fp, "UTIME_NOW"); | ||||
break; | break; | ||||
case UTIME_OMIT: | case UTIME_OMIT: | ||||
fprintf(fp, "UTIME_OMIT"); | fprintf(fp, "UTIME_OMIT"); | ||||
break; | break; | ||||
default: | default: | ||||
fprintf(fp, "%jd.%09ld", | fprintf(fp, "%jd.%09ld", | ||||
(intmax_t)ts[i].tv_sec, | (intmax_t)ts[i].tv_sec, | ||||
ts[i].tv_nsec); | ts[i].tv_nsec); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Timeval: { | case Timeval: { | ||||
struct timeval tv; | struct timeval tv; | ||||
if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) | if (get_struct(pid, args[sc->offset], &tv, sizeof(tv)) != -1) | ||||
!= -1) | |||||
fprintf(fp, "{ %jd.%06ld }", (intmax_t)tv.tv_sec, | fprintf(fp, "{ %jd.%06ld }", (intmax_t)tv.tv_sec, | ||||
tv.tv_usec); | tv.tv_usec); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Timeval2: { | case Timeval2: { | ||||
struct timeval tv[2]; | struct timeval tv[2]; | ||||
if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) | if (get_struct(pid, args[sc->offset], &tv, sizeof(tv)) != -1) | ||||
!= -1) | |||||
fprintf(fp, "{ %jd.%06ld, %jd.%06ld }", | fprintf(fp, "{ %jd.%06ld, %jd.%06ld }", | ||||
(intmax_t)tv[0].tv_sec, tv[0].tv_usec, | (intmax_t)tv[0].tv_sec, tv[0].tv_usec, | ||||
(intmax_t)tv[1].tv_sec, tv[1].tv_usec); | (intmax_t)tv[1].tv_sec, tv[1].tv_usec); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Itimerval: { | case Itimerval: { | ||||
struct itimerval itv; | struct itimerval itv; | ||||
if (get_struct(pid, (void *)args[sc->offset], &itv, | if (get_struct(pid, args[sc->offset], &itv, sizeof(itv)) != -1) | ||||
sizeof(itv)) != -1) | |||||
fprintf(fp, "{ %jd.%06ld, %jd.%06ld }", | fprintf(fp, "{ %jd.%06ld, %jd.%06ld }", | ||||
(intmax_t)itv.it_interval.tv_sec, | (intmax_t)itv.it_interval.tv_sec, | ||||
itv.it_interval.tv_usec, | itv.it_interval.tv_usec, | ||||
(intmax_t)itv.it_value.tv_sec, | (intmax_t)itv.it_value.tv_sec, | ||||
itv.it_value.tv_usec); | itv.it_value.tv_usec); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case LinuxSockArgs: | case LinuxSockArgs: | ||||
{ | { | ||||
struct linux_socketcall_args largs; | struct linux_socketcall_args largs; | ||||
if (get_struct(pid, (void *)args[sc->offset], (void *)&largs, | if (get_struct(pid, args[sc->offset], (void *)&largs, | ||||
sizeof(largs)) != -1) | sizeof(largs)) != -1) | ||||
fprintf(fp, "{ %s, 0x%lx }", | fprintf(fp, "{ %s, 0x%lx }", | ||||
lookup(linux_socketcall_ops, largs.what, 10), | lookup(linux_socketcall_ops, largs.what, 10), | ||||
(long unsigned int)largs.args); | (long unsigned int)largs.args); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Pollfd: { | case Pollfd: { | ||||
/* | /* | ||||
* XXX: A Pollfd argument expects the /next/ syscall argument | * XXX: A Pollfd argument expects the /next/ syscall argument | ||||
* to be the number of fds in the array. This matches the poll | * to be the number of fds in the array. This matches the poll | ||||
* syscall. | * syscall. | ||||
*/ | */ | ||||
struct pollfd *pfd; | struct pollfd *pfd; | ||||
int numfds = args[sc->offset + 1]; | int numfds = args[sc->offset + 1]; | ||||
size_t bytes = sizeof(struct pollfd) * numfds; | size_t bytes = sizeof(struct pollfd) * numfds; | ||||
int i; | int i; | ||||
if ((pfd = malloc(bytes)) == NULL) | if ((pfd = malloc(bytes)) == NULL) | ||||
err(1, "Cannot malloc %zu bytes for pollfd array", | err(1, "Cannot malloc %zu bytes for pollfd array", | ||||
bytes); | bytes); | ||||
if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) | if (get_struct(pid, args[sc->offset], pfd, bytes) != -1) { | ||||
!= -1) { | |||||
fputs("{", fp); | fputs("{", fp); | ||||
for (i = 0; i < numfds; i++) { | for (i = 0; i < numfds; i++) { | ||||
fprintf(fp, " %d/%s", pfd[i].fd, | fprintf(fp, " %d/%s", pfd[i].fd, | ||||
xlookup_bits(poll_flags, pfd[i].events)); | xlookup_bits(poll_flags, pfd[i].events)); | ||||
} | } | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else { | } else { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
} | } | ||||
free(pfd); | free(pfd); | ||||
break; | break; | ||||
} | } | ||||
case Fd_set: { | case Fd_set: { | ||||
/* | /* | ||||
* XXX: A Fd_set argument expects the /first/ syscall argument | * XXX: A Fd_set argument expects the /first/ syscall argument | ||||
* to be the number of fds in the array. This matches the | * to be the number of fds in the array. This matches the | ||||
* select syscall. | * select syscall. | ||||
*/ | */ | ||||
fd_set *fds; | fd_set *fds; | ||||
int numfds = args[0]; | int numfds = args[0]; | ||||
size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS; | size_t bytes = _howmany(numfds, _NFDBITS) * _NFDBITS; | ||||
int i; | int i; | ||||
if ((fds = malloc(bytes)) == NULL) | if ((fds = malloc(bytes)) == NULL) | ||||
err(1, "Cannot malloc %zu bytes for fd_set array", | err(1, "Cannot malloc %zu bytes for fd_set array", | ||||
bytes); | bytes); | ||||
if (get_struct(pid, (void *)args[sc->offset], fds, bytes) | if (get_struct(pid, args[sc->offset], fds, bytes) != -1) { | ||||
!= -1) { | |||||
fputs("{", fp); | fputs("{", fp); | ||||
for (i = 0; i < numfds; i++) { | for (i = 0; i < numfds; i++) { | ||||
if (FD_ISSET(i, fds)) | if (FD_ISSET(i, fds)) | ||||
fprintf(fp, " %d", i); | fprintf(fp, " %d", i); | ||||
} | } | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
free(fds); | free(fds); | ||||
break; | break; | ||||
} | } | ||||
case Signal: | case Signal: | ||||
fputs(strsig2(args[sc->offset]), fp); | fputs(strsig2(args[sc->offset]), fp); | ||||
break; | break; | ||||
case Sigset: { | case Sigset: { | ||||
long sig; | long sig; | ||||
sigset_t ss; | sigset_t ss; | ||||
int i, first; | int i, first; | ||||
sig = args[sc->offset]; | sig = args[sc->offset]; | ||||
if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, | if (get_struct(pid, args[sc->offset], (void *)&ss, | ||||
sizeof(ss)) == -1) { | sizeof(ss)) == -1) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
fputs("{ ", fp); | fputs("{ ", fp); | ||||
first = 1; | first = 1; | ||||
for (i = 1; i < sys_nsig; i++) { | for (i = 1; i < sys_nsig; i++) { | ||||
if (sigismember(&ss, i)) { | if (sigismember(&ss, i)) { | ||||
fprintf(fp, "%s%s", !first ? "|" : "", | fprintf(fp, "%s%s", !first ? "|" : "", | ||||
strsig2(i)); | strsig2(i)); | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | case Sockaddr: { | ||||
/* | /* | ||||
* Extract the address length from the next argument. If | * Extract the address length from the next argument. If | ||||
* this is an output sockaddr (OUT is set), then the | * this is an output sockaddr (OUT is set), then the | ||||
* next argument is a pointer to a socklen_t. Otherwise | * next argument is a pointer to a socklen_t. Otherwise | ||||
* the next argument contains a socklen_t by value. | * the next argument contains a socklen_t by value. | ||||
*/ | */ | ||||
if (sc->type & OUT) { | if (sc->type & OUT) { | ||||
if (get_struct(pid, (void *)args[sc->offset + 1], | if (get_struct(pid, args[sc->offset + 1], &len, | ||||
&len, sizeof(len)) == -1) { | sizeof(len)) == -1) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
} else | } else | ||||
len = args[sc->offset + 1]; | len = args[sc->offset + 1]; | ||||
print_sockaddr(fp, trussinfo, (void *)args[sc->offset], len); | print_sockaddr(fp, trussinfo, args[sc->offset], len); | ||||
break; | break; | ||||
} | } | ||||
case Sigaction: { | case Sigaction: { | ||||
struct sigaction sa; | struct sigaction sa; | ||||
if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) | if (get_struct(pid, args[sc->offset], &sa, sizeof(sa)) != -1) { | ||||
!= -1) { | |||||
fputs("{ ", fp); | fputs("{ ", fp); | ||||
if (sa.sa_handler == SIG_DFL) | if (sa.sa_handler == SIG_DFL) | ||||
fputs("SIG_DFL", fp); | fputs("SIG_DFL", fp); | ||||
else if (sa.sa_handler == SIG_IGN) | else if (sa.sa_handler == SIG_IGN) | ||||
fputs("SIG_IGN", fp); | fputs("SIG_IGN", fp); | ||||
else | else | ||||
fprintf(fp, "%p", sa.sa_handler); | fprintf(fp, "%p", sa.sa_handler); | ||||
fprintf(fp, " %s ss_t }", | fprintf(fp, " %s ss_t }", | ||||
xlookup_bits(sigaction_flags, sa.sa_flags)); | xlookup_bits(sigaction_flags, sa.sa_flags)); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Kevent: { | case Kevent: { | ||||
/* | /* | ||||
* XXX XXX: The size of the array is determined by either the | * XXX XXX: The size of the array is determined by either the | ||||
* next syscall argument, or by the syscall return value, | * next syscall argument, or by the syscall return value, | ||||
* depending on which argument number we are. This matches the | * depending on which argument number we are. This matches the | ||||
* kevent syscall, but luckily that's the only syscall that uses | * kevent syscall, but luckily that's the only syscall that uses | ||||
Show All 12 Lines | case Kevent: { | ||||
if (numevents >= 0) { | if (numevents >= 0) { | ||||
bytes = sizeof(struct kevent) * numevents; | bytes = sizeof(struct kevent) * numevents; | ||||
if ((ke = malloc(bytes)) == NULL) | if ((ke = malloc(bytes)) == NULL) | ||||
err(1, | err(1, | ||||
"Cannot malloc %zu bytes for kevent array", | "Cannot malloc %zu bytes for kevent array", | ||||
bytes); | bytes); | ||||
} else | } else | ||||
ke = NULL; | ke = NULL; | ||||
if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], | if (numevents >= 0 && get_struct(pid, 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]); | print_kevent(fp, &ke[i]); | ||||
} | } | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else { | } else { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
} | } | ||||
free(ke); | free(ke); | ||||
break; | break; | ||||
} | } | ||||
case Kevent11: { | case Kevent11: { | ||||
struct kevent_freebsd11 *ke11; | struct kevent_freebsd11 *ke11; | ||||
struct kevent ke; | struct kevent ke; | ||||
int numevents = -1; | int numevents = -1; | ||||
Show All 9 Lines | if (numevents >= 0) { | ||||
bytes = sizeof(struct kevent_freebsd11) * numevents; | bytes = sizeof(struct kevent_freebsd11) * numevents; | ||||
if ((ke11 = malloc(bytes)) == NULL) | if ((ke11 = malloc(bytes)) == NULL) | ||||
err(1, | err(1, | ||||
"Cannot malloc %zu bytes for kevent array", | "Cannot malloc %zu bytes for kevent array", | ||||
bytes); | bytes); | ||||
} else | } else | ||||
ke11 = NULL; | ke11 = NULL; | ||||
memset(&ke, 0, sizeof(ke)); | memset(&ke, 0, sizeof(ke)); | ||||
if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], | if (numevents >= 0 && get_struct(pid, args[sc->offset], | ||||
ke11, bytes) != -1) { | ke11, bytes) != -1) { | ||||
fputc('{', fp); | fputc('{', fp); | ||||
for (i = 0; i < numevents; i++) { | for (i = 0; i < numevents; i++) { | ||||
fputc(' ', fp); | fputc(' ', fp); | ||||
ke.ident = ke11[i].ident; | ke.ident = ke11[i].ident; | ||||
ke.filter = ke11[i].filter; | ke.filter = ke11[i].filter; | ||||
ke.flags = ke11[i].flags; | ke.flags = ke11[i].flags; | ||||
ke.fflags = ke11[i].fflags; | ke.fflags = ke11[i].fflags; | ||||
ke.data = ke11[i].data; | ke.data = ke11[i].data; | ||||
ke.udata = ke11[i].udata; | ke.udata = ke11[i].udata; | ||||
print_kevent(fp, &ke); | print_kevent(fp, &ke); | ||||
} | } | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else { | } else { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
} | } | ||||
free(ke11); | 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, args[sc->offset], &st, sizeof(st)) | ||||
!= -1) { | != -1) { | ||||
char mode[12]; | char mode[12]; | ||||
strmode(st.st_mode, mode); | strmode(st.st_mode, mode); | ||||
fprintf(fp, | fprintf(fp, | ||||
"{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode, | "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode, | ||||
(uintmax_t)st.st_ino, (intmax_t)st.st_size, | (uintmax_t)st.st_ino, (intmax_t)st.st_size, | ||||
(long)st.st_blksize); | (long)st.st_blksize); | ||||
} else { | } else { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
case Stat11: { | case Stat11: { | ||||
struct freebsd11_stat st; | struct freebsd11_stat st; | ||||
if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) | if (get_struct(pid, args[sc->offset], &st, sizeof(st)) | ||||
!= -1) { | != -1) { | ||||
char mode[12]; | char mode[12]; | ||||
strmode(st.st_mode, mode); | strmode(st.st_mode, mode); | ||||
fprintf(fp, | fprintf(fp, | ||||
"{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode, | "{ mode=%s,inode=%ju,size=%jd,blksize=%ld }", mode, | ||||
(uintmax_t)st.st_ino, (intmax_t)st.st_size, | (uintmax_t)st.st_ino, (intmax_t)st.st_size, | ||||
(long)st.st_blksize); | (long)st.st_blksize); | ||||
} else { | } else { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
case StatFs: { | case StatFs: { | ||||
unsigned int i; | unsigned int i; | ||||
struct statfs buf; | struct statfs buf; | ||||
if (get_struct(pid, (void *)args[sc->offset], &buf, | if (get_struct(pid, args[sc->offset], &buf, | ||||
sizeof(buf)) != -1) { | sizeof(buf)) != -1) { | ||||
char fsid[17]; | char fsid[17]; | ||||
bzero(fsid, sizeof(fsid)); | bzero(fsid, sizeof(fsid)); | ||||
if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) { | if (buf.f_fsid.val[0] != 0 || buf.f_fsid.val[1] != 0) { | ||||
for (i = 0; i < sizeof(buf.f_fsid); i++) | for (i = 0; i < sizeof(buf.f_fsid); i++) | ||||
snprintf(&fsid[i*2], | snprintf(&fsid[i*2], | ||||
sizeof(fsid) - (i*2), "%02x", | sizeof(fsid) - (i*2), "%02x", | ||||
((u_char *)&buf.f_fsid)[i]); | ((u_char *)&buf.f_fsid)[i]); | ||||
} | } | ||||
fprintf(fp, | fprintf(fp, | ||||
"{ fstypename=%s,mntonname=%s,mntfromname=%s," | "{ fstypename=%s,mntonname=%s,mntfromname=%s," | ||||
"fsid=%s }", buf.f_fstypename, buf.f_mntonname, | "fsid=%s }", buf.f_fstypename, buf.f_mntonname, | ||||
buf.f_mntfromname, fsid); | buf.f_mntfromname, fsid); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Rusage: { | case Rusage: { | ||||
struct rusage ru; | struct rusage ru; | ||||
if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) | if (get_struct(pid, args[sc->offset], &ru, sizeof(ru)) | ||||
!= -1) { | != -1) { | ||||
fprintf(fp, | fprintf(fp, | ||||
"{ u=%jd.%06ld,s=%jd.%06ld,in=%ld,out=%ld }", | "{ u=%jd.%06ld,s=%jd.%06ld,in=%ld,out=%ld }", | ||||
(intmax_t)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec, | (intmax_t)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec, | ||||
(intmax_t)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec, | (intmax_t)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec, | ||||
ru.ru_inblock, ru.ru_oublock); | ru.ru_inblock, ru.ru_oublock); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Rlimit: { | case Rlimit: { | ||||
struct rlimit rl; | struct rlimit rl; | ||||
if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) | if (get_struct(pid, args[sc->offset], &rl, sizeof(rl)) | ||||
!= -1) { | != -1) { | ||||
fprintf(fp, "{ cur=%ju,max=%ju }", | fprintf(fp, "{ cur=%ju,max=%ju }", | ||||
rl.rlim_cur, rl.rlim_max); | rl.rlim_cur, rl.rlim_max); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case ExitStatus: { | case ExitStatus: { | ||||
int status; | int status; | ||||
if (get_struct(pid, (void *)args[sc->offset], &status, | if (get_struct(pid, args[sc->offset], &status, | ||||
sizeof(status)) != -1) { | sizeof(status)) != -1) { | ||||
fputs("{ ", fp); | fputs("{ ", fp); | ||||
if (WIFCONTINUED(status)) | if (WIFCONTINUED(status)) | ||||
fputs("CONTINUED", fp); | fputs("CONTINUED", fp); | ||||
else if (WIFEXITED(status)) | else if (WIFEXITED(status)) | ||||
fprintf(fp, "EXITED,val=%d", | fprintf(fp, "EXITED,val=%d", | ||||
WEXITSTATUS(status)); | WEXITSTATUS(status)); | ||||
else if (WIFSIGNALED(status)) | else if (WIFSIGNALED(status)) | ||||
fprintf(fp, "SIGNALED,sig=%s%s", | fprintf(fp, "SIGNALED,sig=%s%s", | ||||
strsig2(WTERMSIG(status)), | strsig2(WTERMSIG(status)), | ||||
WCOREDUMP(status) ? ",cored" : ""); | WCOREDUMP(status) ? ",cored" : ""); | ||||
else | else | ||||
fprintf(fp, "STOPPED,sig=%s", | fprintf(fp, "STOPPED,sig=%s", | ||||
strsig2(WTERMSIG(status))); | strsig2(WTERMSIG(status))); | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Waitoptions: | case Waitoptions: | ||||
print_mask_arg(sysdecode_wait6_options, fp, args[sc->offset]); | print_mask_arg(sysdecode_wait6_options, fp, args[sc->offset]); | ||||
break; | break; | ||||
case Idtype: | case Idtype: | ||||
print_integer_arg(sysdecode_idtype, fp, args[sc->offset]); | print_integer_arg(sysdecode_idtype, fp, args[sc->offset]); | ||||
break; | break; | ||||
Show All 19 Lines | #endif | ||||
case Sysctl: { | case Sysctl: { | ||||
char name[BUFSIZ]; | char name[BUFSIZ]; | ||||
int oid[CTL_MAXNAME + 2], qoid[CTL_MAXNAME + 2]; | int oid[CTL_MAXNAME + 2], qoid[CTL_MAXNAME + 2]; | ||||
size_t i; | size_t i; | ||||
int len; | int len; | ||||
memset(name, 0, sizeof(name)); | memset(name, 0, sizeof(name)); | ||||
len = args[sc->offset + 1]; | len = args[sc->offset + 1]; | ||||
if (get_struct(pid, (void *)args[sc->offset], oid, | if (get_struct(pid, args[sc->offset], oid, | ||||
len * sizeof(oid[0])) != -1) { | len * sizeof(oid[0])) != -1) { | ||||
fprintf(fp, "\""); | fprintf(fp, "\""); | ||||
if (oid[0] == CTL_SYSCTL) { | if (oid[0] == CTL_SYSCTL) { | ||||
fprintf(fp, "sysctl."); | fprintf(fp, "sysctl."); | ||||
switch (oid[1]) { | switch (oid[1]) { | ||||
case CTL_SYSCTL_DEBUG: | case CTL_SYSCTL_DEBUG: | ||||
fprintf(fp, "debug"); | fprintf(fp, "debug"); | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | case PipeFds: | ||||
retval[0] = 0; | retval[0] = 0; | ||||
break; | break; | ||||
case Utrace: { | case Utrace: { | ||||
size_t len; | size_t len; | ||||
void *utrace_addr; | void *utrace_addr; | ||||
len = args[sc->offset + 1]; | len = args[sc->offset + 1]; | ||||
utrace_addr = calloc(1, len); | utrace_addr = calloc(1, len); | ||||
if (get_struct(pid, (void *)args[sc->offset], | if (get_struct(pid, args[sc->offset], | ||||
(void *)utrace_addr, len) != -1) | (void *)utrace_addr, len) != -1) | ||||
print_utrace(fp, utrace_addr, len); | print_utrace(fp, utrace_addr, len); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
free(utrace_addr); | free(utrace_addr); | ||||
break; | break; | ||||
} | } | ||||
case IntArray: { | case IntArray: { | ||||
int descriptors[16]; | int descriptors[16]; | ||||
unsigned long i, ndescriptors; | unsigned long i, ndescriptors; | ||||
bool truncated; | bool truncated; | ||||
ndescriptors = args[sc->offset + 1]; | ndescriptors = args[sc->offset + 1]; | ||||
truncated = false; | truncated = false; | ||||
if (ndescriptors > nitems(descriptors)) { | if (ndescriptors > nitems(descriptors)) { | ||||
ndescriptors = nitems(descriptors); | ndescriptors = nitems(descriptors); | ||||
truncated = true; | truncated = true; | ||||
} | } | ||||
if (get_struct(pid, (void *)args[sc->offset], | if (get_struct(pid, args[sc->offset], | ||||
descriptors, ndescriptors * sizeof(descriptors[0])) != -1) { | descriptors, ndescriptors * sizeof(descriptors[0])) != -1) { | ||||
fprintf(fp, "{"); | fprintf(fp, "{"); | ||||
for (i = 0; i < ndescriptors; i++) | for (i = 0; i < ndescriptors; i++) | ||||
fprintf(fp, i == 0 ? " %d" : ", %d", | fprintf(fp, i == 0 ? " %d" : ", %d", | ||||
descriptors[i]); | descriptors[i]); | ||||
fprintf(fp, truncated ? ", ... }" : " }"); | fprintf(fp, truncated ? ", ... }" : " }"); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Pipe2: | case Pipe2: | ||||
print_mask_arg(sysdecode_pipe2_flags, fp, args[sc->offset]); | print_mask_arg(sysdecode_pipe2_flags, fp, args[sc->offset]); | ||||
break; | break; | ||||
case CapFcntlRights: { | case CapFcntlRights: { | ||||
uint32_t rights; | uint32_t rights; | ||||
if (sc->type & OUT) { | if (sc->type & OUT) { | ||||
if (get_struct(pid, (void *)args[sc->offset], &rights, | if (get_struct(pid, args[sc->offset], &rights, | ||||
sizeof(rights)) == -1) { | sizeof(rights)) == -1) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
} else | } else | ||||
rights = args[sc->offset]; | rights = args[sc->offset]; | ||||
print_mask_arg32(sysdecode_cap_fcntlrights, fp, rights); | print_mask_arg32(sysdecode_cap_fcntlrights, fp, rights); | ||||
break; | break; | ||||
} | } | ||||
case Fadvice: | case Fadvice: | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | case Sockoptname: { | ||||
break; | break; | ||||
} | } | ||||
case Msgflags: | case Msgflags: | ||||
print_mask_arg(sysdecode_msg_flags, fp, args[sc->offset]); | print_mask_arg(sysdecode_msg_flags, fp, args[sc->offset]); | ||||
break; | break; | ||||
case CapRights: { | case CapRights: { | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
if (get_struct(pid, (void *)args[sc->offset], &rights, | if (get_struct(pid, args[sc->offset], &rights, | ||||
sizeof(rights)) != -1) { | sizeof(rights)) != -1) { | ||||
fputs("{ ", fp); | fputs("{ ", fp); | ||||
sysdecode_cap_rights(fp, &rights); | sysdecode_cap_rights(fp, &rights); | ||||
fputs(" }", fp); | fputs(" }", fp); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Acltype: | case Acltype: | ||||
print_integer_arg(sysdecode_acltype, fp, args[sc->offset]); | print_integer_arg(sysdecode_acltype, fp, args[sc->offset]); | ||||
break; | break; | ||||
case Extattrnamespace: | case Extattrnamespace: | ||||
print_integer_arg(sysdecode_extattrnamespace, fp, | print_integer_arg(sysdecode_extattrnamespace, fp, | ||||
args[sc->offset]); | args[sc->offset]); | ||||
Show All 31 Lines | case Rtpriofunc: | ||||
break; | break; | ||||
case Schedpolicy: | case Schedpolicy: | ||||
print_integer_arg(sysdecode_scheduler_policy, fp, | print_integer_arg(sysdecode_scheduler_policy, fp, | ||||
args[sc->offset]); | args[sc->offset]); | ||||
break; | break; | ||||
case Schedparam: { | case Schedparam: { | ||||
struct sched_param sp; | struct sched_param sp; | ||||
if (get_struct(pid, (void *)args[sc->offset], &sp, | if (get_struct(pid, args[sc->offset], &sp, sizeof(sp)) != -1) | ||||
sizeof(sp)) != -1) | |||||
fprintf(fp, "{ %d }", sp.sched_priority); | fprintf(fp, "{ %d }", sp.sched_priority); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case PSig: { | case PSig: { | ||||
int sig; | int sig; | ||||
if (get_struct(pid, (void *)args[sc->offset], &sig, | if (get_struct(pid, args[sc->offset], &sig, sizeof(sig)) == 0) | ||||
sizeof(sig)) == 0) | |||||
fprintf(fp, "{ %s }", strsig2(sig)); | fprintf(fp, "{ %s }", strsig2(sig)); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Siginfo: { | case Siginfo: { | ||||
siginfo_t si; | siginfo_t si; | ||||
if (get_struct(pid, (void *)args[sc->offset], &si, | if (get_struct(pid, args[sc->offset], &si, sizeof(si)) != -1) { | ||||
sizeof(si)) != -1) { | |||||
fprintf(fp, "{ signo=%s", strsig2(si.si_signo)); | fprintf(fp, "{ signo=%s", strsig2(si.si_signo)); | ||||
decode_siginfo(fp, &si); | decode_siginfo(fp, &si); | ||||
fprintf(fp, " }"); | fprintf(fp, " }"); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case Iovec: | case Iovec: | ||||
/* | /* | ||||
* Print argument as an array of struct iovec, where the next | * Print argument as an array of struct iovec, where the next | ||||
* syscall argument is the number of elements of the array. | * syscall argument is the number of elements of the array. | ||||
*/ | */ | ||||
print_iovec(fp, trussinfo, (void *)args[sc->offset], | print_iovec(fp, trussinfo, args[sc->offset], | ||||
(int)args[sc->offset + 1]); | (int)args[sc->offset + 1]); | ||||
break; | break; | ||||
case Sctpsndrcvinfo: { | case Sctpsndrcvinfo: { | ||||
struct sctp_sndrcvinfo info; | struct sctp_sndrcvinfo info; | ||||
if (get_struct(pid, (void *)args[sc->offset], | if (get_struct(pid, args[sc->offset], | ||||
&info, sizeof(struct sctp_sndrcvinfo)) == -1) { | &info, sizeof(struct sctp_sndrcvinfo)) == -1) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
print_sctp_sndrcvinfo(fp, sc->type & OUT, &info); | print_sctp_sndrcvinfo(fp, sc->type & OUT, &info); | ||||
break; | break; | ||||
} | } | ||||
case Msghdr: { | case Msghdr: { | ||||
struct msghdr msghdr; | struct msghdr msghdr; | ||||
if (get_struct(pid, (void *)args[sc->offset], | if (get_struct(pid, args[sc->offset], | ||||
&msghdr, sizeof(struct msghdr)) == -1) { | &msghdr, sizeof(struct msghdr)) == -1) { | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
fputs("{", fp); | fputs("{", fp); | ||||
print_sockaddr(fp, trussinfo, msghdr.msg_name, msghdr.msg_namelen); | print_sockaddr(fp, trussinfo, (uintptr_t)msghdr.msg_name, msghdr.msg_namelen); | ||||
fprintf(fp, ",%d,", msghdr.msg_namelen); | fprintf(fp, ",%d,", msghdr.msg_namelen); | ||||
print_iovec(fp, trussinfo, msghdr.msg_iov, msghdr.msg_iovlen); | print_iovec(fp, trussinfo, (uintptr_t)msghdr.msg_iov, msghdr.msg_iovlen); | ||||
fprintf(fp, ",%d,", msghdr.msg_iovlen); | fprintf(fp, ",%d,", msghdr.msg_iovlen); | ||||
print_cmsgs(fp, pid, sc->type & OUT, &msghdr); | print_cmsgs(fp, pid, sc->type & OUT, &msghdr); | ||||
fprintf(fp, ",%u,", msghdr.msg_controllen); | fprintf(fp, ",%u,", msghdr.msg_controllen); | ||||
print_mask_arg(sysdecode_msg_flags, fp, msghdr.msg_flags); | print_mask_arg(sysdecode_msg_flags, fp, msghdr.msg_flags); | ||||
fputs("}", fp); | fputs("}", fp); | ||||
break; | break; | ||||
} | } | ||||
case CloudABIAdvice: | case CloudABIAdvice: | ||||
fputs(xlookup(cloudabi_advice, args[sc->offset]), fp); | fputs(xlookup(cloudabi_advice, args[sc->offset]), fp); | ||||
break; | break; | ||||
case CloudABIClockID: | case CloudABIClockID: | ||||
fputs(xlookup(cloudabi_clockid, args[sc->offset]), fp); | fputs(xlookup(cloudabi_clockid, args[sc->offset]), fp); | ||||
break; | break; | ||||
case CloudABIFDSFlags: | case CloudABIFDSFlags: | ||||
fputs(xlookup_bits(cloudabi_fdsflags, args[sc->offset]), fp); | fputs(xlookup_bits(cloudabi_fdsflags, args[sc->offset]), fp); | ||||
break; | break; | ||||
case CloudABIFDStat: { | case CloudABIFDStat: { | ||||
cloudabi_fdstat_t fds; | cloudabi_fdstat_t fds; | ||||
if (get_struct(pid, (void *)args[sc->offset], &fds, sizeof(fds)) | if (get_struct(pid, args[sc->offset], &fds, sizeof(fds)) | ||||
!= -1) { | != -1) { | ||||
fprintf(fp, "{ %s, ", | fprintf(fp, "{ %s, ", | ||||
xlookup(cloudabi_filetype, fds.fs_filetype)); | xlookup(cloudabi_filetype, fds.fs_filetype)); | ||||
fprintf(fp, "%s, ... }", | fprintf(fp, "%s, ... }", | ||||
xlookup_bits(cloudabi_fdflags, fds.fs_flags)); | xlookup_bits(cloudabi_fdflags, fds.fs_flags)); | ||||
} else | } else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case CloudABIFileStat: { | case CloudABIFileStat: { | ||||
cloudabi_filestat_t fsb; | cloudabi_filestat_t fsb; | ||||
if (get_struct(pid, (void *)args[sc->offset], &fsb, sizeof(fsb)) | if (get_struct(pid, args[sc->offset], &fsb, sizeof(fsb)) | ||||
!= -1) | != -1) | ||||
fprintf(fp, "{ %s, %ju }", | fprintf(fp, "{ %s, %ju }", | ||||
xlookup(cloudabi_filetype, fsb.st_filetype), | xlookup(cloudabi_filetype, fsb.st_filetype), | ||||
(uintmax_t)fsb.st_size); | (uintmax_t)fsb.st_size); | ||||
else | else | ||||
fprintf(fp, "0x%lx", args[sc->offset]); | print_pointer(fp, args[sc->offset]); | ||||
break; | break; | ||||
} | } | ||||
case CloudABIFileType: | case CloudABIFileType: | ||||
fputs(xlookup(cloudabi_filetype, args[sc->offset]), fp); | fputs(xlookup(cloudabi_filetype, args[sc->offset]), fp); | ||||
break; | break; | ||||
case CloudABIFSFlags: | case CloudABIFSFlags: | ||||
fputs(xlookup_bits(cloudabi_fsflags, args[sc->offset]), fp); | fputs(xlookup_bits(cloudabi_fsflags, args[sc->offset]), fp); | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 158 Lines • Show Last 20 Lines |
This regresses the NULL case for a number of callers that explicitly prefixed 0x before (and the rest probably should have).
I am guessing you do it this way because uintmax_t is still broken on CHERIBSD, so you can't just do fprintf(fp, "0x%jx", (uintmax_t)arg);.