From b328cce0e3c98aeb1847de0d9ff290b2c5632d44 Mon Sep 17 00:00:00 2001 From: zont Date: Sun, 2 Sep 2012 11:03:18 +0000 Subject: - Style(9) cleanup. Approved by: kib (mentor) --- usr.bin/truss/amd64-fbsd.c | 400 +++++++++++++++++++------------------- usr.bin/truss/amd64-fbsd32.c | 403 +++++++++++++++++++------------------- usr.bin/truss/amd64-linux32.c | 377 +++++++++++++++++------------------ usr.bin/truss/i386-fbsd.c | 389 ++++++++++++++++++------------------- usr.bin/truss/i386-linux.c | 374 +++++++++++++++++------------------ usr.bin/truss/ia64-fbsd.c | 348 +++++++++++++++++---------------- usr.bin/truss/main.c | 51 +++-- usr.bin/truss/mips-fbsd.c | 431 +++++++++++++++++++++-------------------- usr.bin/truss/powerpc-fbsd.c | 419 +++++++++++++++++++-------------------- usr.bin/truss/powerpc64-fbsd.c | 387 ++++++++++++++++++------------------ usr.bin/truss/setup.c | 47 +++-- usr.bin/truss/sparc64-fbsd.c | 425 ++++++++++++++++++++-------------------- usr.bin/truss/syscall.h | 6 +- usr.bin/truss/syscalls.c | 245 +++++++++++++---------- usr.bin/truss/truss.h | 32 +-- 15 files changed, 2202 insertions(+), 2132 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/truss/amd64-fbsd.c b/usr.bin/truss/amd64-fbsd.c index 6ed3812..4ded727 100644 --- a/usr.bin/truss/amd64-fbsd.c +++ b/usr.bin/truss/amd64-fbsd.c @@ -88,18 +88,19 @@ static struct freebsd_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -110,147 +111,145 @@ clear_fsc(void) { */ void -amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i, reg; - struct syscall *sc; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - /* - * FreeBSD has two special kinds of system call redirctions -- - * SYS_syscall, and SYS___syscall. The former is the old syscall() - * routine, basically; the latter is for quad-aligned arguments. - */ - reg = 0; - syscall_num = regs.r_rax; - switch (syscall_num) { - case SYS_syscall: - case SYS___syscall: - syscall_num = regs.r_rdi; - reg++; - break; - } - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - for (i = 0; i < nargs && reg < 6; i++, reg++) { - switch (reg) { - case 0: fsc.args[i] = regs.r_rdi; break; - case 1: fsc.args[i] = regs.r_rsi; break; - case 2: fsc.args[i] = regs.r_rdx; break; - case 3: fsc.args[i] = regs.r_rcx; break; - case 4: fsc.args[i] = regs.r_r8; break; - case 5: fsc.args[i] = regs.r_r9; break; - } - } - if (nargs > i) { - struct ptrace_io_desc iorequest; - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)(regs.r_rsp + sizeof(register_t)); - iorequest.piod_addr = &fsc.args[i]; - iorequest.piod_len = (nargs - i) * sizeof(register_t); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; - } - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct ptrace_io_desc iorequest; + struct reg regs; + struct syscall *sc; + int i, reg, syscall_num; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + + /* + * FreeBSD has two special kinds of system call redirctions -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + */ + reg = 0; + syscall_num = regs.r_rax; + switch (syscall_num) { + case SYS_syscall: + case SYS___syscall: + syscall_num = regs.r_rdi; + reg++; + break; + } + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0|| + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); + for (i = 0; i < nargs && reg < 6; i++, reg++) { + switch (reg) { + case 0: fsc.args[i] = regs.r_rdi; break; + case 1: fsc.args[i] = regs.r_rsi; break; + case 2: fsc.args[i] = regs.r_rdx; break; + case 3: fsc.args[i] = regs.r_rcx; break; + case 4: fsc.args[i] = regs.r_r8; break; + case 5: fsc.args[i] = regs.r_r9; break; + } + } + if (nargs > i) { + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.r_rsp + sizeof(register_t)); + iorequest.piod_addr = &fsc.args[i]; + iorequest.piod_len = (nargs - i) * sizeof(register_t); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; + } + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } + fsc.nargs = nargs; + } - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%lx%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%lx%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -263,68 +262,69 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { long amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return (-1); - } - retval = regs.r_rax; - errorp = !!(regs.r_rflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval = regs.r_rax; + errorp = !!(regs.r_rflags & PSL_C); + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c index c3dd183..5cf9f84 100644 --- a/usr.bin/truss/amd64-fbsd32.c +++ b/usr.bin/truss/amd64-fbsd32.c @@ -43,8 +43,8 @@ static const char rcsid[] = */ #include -#include #include +#include #include #include @@ -90,21 +90,21 @@ static struct freebsd32_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.args32) { - free(fsc.args32); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.args32) + free(fsc.args32); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -115,145 +115,143 @@ clear_fsc(void) { */ void -amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i; - unsigned long parm_offset; - struct syscall *sc = NULL; - struct ptrace_io_desc iorequest; - cpid = trussinfo->curthread->tid; - - clear_fsc(); - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - parm_offset = regs.r_rsp + sizeof(int); - - /* - * FreeBSD has two special kinds of system call redirctions -- - * SYS_syscall, and SYS___syscall. The former is the old syscall() - * routine, basically; the latter is for quad-aligned arguments. - */ - syscall_num = regs.r_rax; - switch (syscall_num) { - case SYS_syscall: - syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); - parm_offset += sizeof(int); - break; - case SYS___syscall: - syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); - parm_offset += sizeof(quad_t); - break; - } - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : - freebsd32_syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args32 = malloc((1+nargs) * sizeof(unsigned int)); - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)parm_offset; - iorequest.piod_addr = fsc.args32; - iorequest.piod_len = (1+nargs) * sizeof(unsigned int); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - for (i = 0; i < nargs + 1; i++) - fsc.args[i] = fsc.args32[i]; - - if (fsc.name) - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct ptrace_io_desc iorequest; + struct reg regs; + struct syscall *sc; + unsigned long parm_offset; + int i, syscall_num; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + parm_offset = regs.r_rsp + sizeof(int); + + /* + * FreeBSD has two special kinds of system call redirctions -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + */ + syscall_num = regs.r_rax; + switch (syscall_num) { + case SYS_syscall: + syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); + parm_offset += sizeof(int); + break; + case SYS___syscall: + syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); + parm_offset += sizeof(quad_t); + break; + } + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : freebsd32_syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0|| + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args32 = malloc((1 + nargs) * sizeof(unsigned int)); + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)parm_offset; + iorequest.piod_addr = fsc.args32; + iorequest.piod_len = (1 + nargs) * sizeof(unsigned int); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); + for (i = 0; i < nargs + 1; i++) + fsc.args[i] = fsc.args32[i]; + + sc = NULL; + if (fsc.name) + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } - - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.nargs = nargs; + } - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "freebsd32_execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "freebsd32_execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "freebsd32_execve") == 0|| + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "freebsd32_execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -266,68 +264,69 @@ amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs) { long amd64_fbsd32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return (-1); - } - - retval = regs.r_rax; - errorp = !!(regs.r_rflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval = regs.r_rax; + errorp = !!(regs.r_rflags & PSL_C); + /* - * If an error occurred, then don't bother getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "freebsd32_execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "freebsd32_execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c index 3de40da..e041b60 100644 --- a/usr.bin/truss/amd64-linux32.c +++ b/usr.bin/truss/amd64-linux32.c @@ -86,15 +86,17 @@ static struct linux_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -105,211 +107,214 @@ clear_fsc(void) { */ void -amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i; - struct syscall *sc; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - syscall_num = regs.r_rax; - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : linux32_syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "linux_fork") - || !strcmp(fsc.name, "linux_vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - /* - * Linux passes syscall arguments in registers, not - * on the stack. Fortunately, we've got access to the - * register set. Note that we don't bother checking the - * number of arguments. And what does linux do for syscalls - * that have more than five arguments? - */ - - fsc.args[0] = regs.r_rbx; - fsc.args[1] = regs.r_rcx; - fsc.args[2] = regs.r_rdx; - fsc.args[3] = regs.r_rsi; - fsc.args[4] = regs.r_rdi; - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct reg regs; + struct syscall *sc; + int i, syscall_num; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + + syscall_num = regs.r_rax; + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : linux32_syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "linux_fork") == 0|| + strcmp(fsc.name, "linux_vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + /* + * Linux passes syscall arguments in registers, not + * on the stack. Fortunately, we've got access to the + * register set. Note that we don't bother checking the + * number of arguments. And what does linux do for syscalls + * that have more than five arguments? + */ + + fsc.args[0] = regs.r_rbx; + fsc.args[1] = regs.r_rcx; + fsc.args[2] = regs.r_rdx; + fsc.args[3] = regs.r_rsi; + fsc.args[4] = regs.r_rdi; + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } - - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.nargs = nargs; + } - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "linux_execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "linux_execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "linux_execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* * Linux syscalls return negative errno's, we do positive and map them */ static const int bsd_to_linux_errno[] = { - -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, - -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, - -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, - -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, - -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, + -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, + -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, + -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, + -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, + -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, - -6, + -6, }; long -amd64_linux32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +amd64_linux32_syscall_exit(struct trussinfo *trussinfo, + int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - - cpid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return (-1); - } - - retval = regs.r_rax; - errorp = !!(regs.r_rflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval = regs.r_rax; + errorp = !!(regs.r_rflags & PSL_C); + + /* + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. + */ + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - if (errorp) { - for (i = 0; (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) - if (retval == bsd_to_linux_errno[i]) - break; - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - errorp ? i : retval, fsc.sc); - clear_fsc(); - - return (retval); + if (errorp) { + for (i = 0; + (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) { + if (retval == bsd_to_linux_errno[i]) + break; + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "linux_execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + errorp ? i : retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c index 82f1db0..cbf2d1e 100644 --- a/usr.bin/truss/i386-fbsd.c +++ b/usr.bin/truss/i386-fbsd.c @@ -43,8 +43,8 @@ static const char rcsid[] = */ #include -#include #include +#include #include #include @@ -88,18 +88,19 @@ static struct freebsd_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -110,140 +111,139 @@ clear_fsc(void) { */ void -i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i; - unsigned int parm_offset; - struct syscall *sc = NULL; - struct ptrace_io_desc iorequest; - cpid = trussinfo->curthread->tid; - - clear_fsc(); - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - parm_offset = regs.r_esp + sizeof(int); - - /* - * FreeBSD has two special kinds of system call redirctions -- - * SYS_syscall, and SYS___syscall. The former is the old syscall() - * routine, basically; the latter is for quad-aligned arguments. - */ - syscall_num = regs.r_eax; - switch (syscall_num) { - case SYS_syscall: - syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); - parm_offset += sizeof(int); - break; - case SYS___syscall: - syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); - parm_offset += sizeof(quad_t); - break; - } - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)parm_offset; - iorequest.piod_addr = fsc.args; - iorequest.piod_len = (1+nargs) * sizeof(unsigned long); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; - - if (fsc.name) - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +i386_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct ptrace_io_desc iorequest; + struct reg regs; + struct syscall *sc; + unsigned int parm_offset; + int i, syscall_num; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + parm_offset = regs.r_esp + sizeof(int); + + /* + * FreeBSD has two special kinds of system call redirctions -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + */ + syscall_num = regs.r_eax; + switch (syscall_num) { + case SYS_syscall: + syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); + parm_offset += sizeof(int); + break; + case SYS___syscall: + syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); + parm_offset += sizeof(quad_t); + break; + } + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0 || + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)parm_offset; + iorequest.piod_addr = fsc.args; + iorequest.piod_len = (1 + nargs) * sizeof(unsigned long); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; + + sc = NULL; + if (fsc.name) + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } - - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.nargs = nargs; + } - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -256,68 +256,69 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { long i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return (-1); - } - - retval = regs.r_eax; - errorp = !!(regs.r_eflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval = regs.r_eax; + errorp = !!(regs.r_eflags & PSL_C); + /* - * If an error occurred, then don't bother getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c index 66bccf9..6a0c261 100644 --- a/usr.bin/truss/i386-linux.c +++ b/usr.bin/truss/i386-linux.c @@ -86,15 +86,17 @@ static struct linux_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -105,211 +107,213 @@ clear_fsc(void) { */ void -i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i; - struct syscall *sc; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - syscall_num = regs.r_eax; - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : linux_syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "linux_fork") - || !strcmp(fsc.name, "linux_vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - /* - * Linux passes syscall arguments in registers, not - * on the stack. Fortunately, we've got access to the - * register set. Note that we don't bother checking the - * number of arguments. And what does linux do for syscalls - * that have more than five arguments? - */ - - fsc.args[0] = regs.r_ebx; - fsc.args[1] = regs.r_ecx; - fsc.args[2] = regs.r_edx; - fsc.args[3] = regs.r_esi; - fsc.args[4] = regs.r_edi; - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct reg regs; + struct syscall *sc; + int i, syscall_num; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + + syscall_num = regs.r_eax; + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : linux_syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "linux_fork") == 0 || + strcmp(fsc.name, "linux_vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + /* + * Linux passes syscall arguments in registers, not + * on the stack. Fortunately, we've got access to the + * register set. Note that we don't bother checking the + * number of arguments. And what does linux do for syscalls + * that have more than five arguments? + */ + + fsc.args[0] = regs.r_ebx; + fsc.args[1] = regs.r_ecx; + fsc.args[2] = regs.r_edx; + fsc.args[3] = regs.r_esi; + fsc.args[4] = regs.r_edi; + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } - - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.nargs = nargs; + } - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "linux_execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "linux_execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "linux_execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* * Linux syscalls return negative errno's, we do positive and map them */ static const int bsd_to_linux_errno[] = { - -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, - -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, - -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, - -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, - -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, + -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, + -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, + -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, + -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, + -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, - -6, + -6, }; long i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - - cpid = trussinfo->curthread->tid; - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) - { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return (-1); - } - - retval = regs.r_eax; - errorp = !!(regs.r_eflags & PSL_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval = regs.r_eax; + errorp = !!(regs.r_eflags & PSL_C); + + /* + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. + */ + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - if (errorp) { - for (i = 0; (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) - if (retval == bsd_to_linux_errno[i]) - break; - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - errorp ? i : retval, fsc.sc); - clear_fsc(); - - return (retval); + if (errorp) { + for (i = 0; + (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) { + if (retval == bsd_to_linux_errno[i]) + break; + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "linux_execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + errorp ? i : retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/ia64-fbsd.c b/usr.bin/truss/ia64-fbsd.c index 84515aa..951917f 100644 --- a/usr.bin/truss/ia64-fbsd.c +++ b/usr.bin/truss/ia64-fbsd.c @@ -87,18 +87,19 @@ static struct freebsd_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -109,122 +110,122 @@ clear_fsc(void) { */ void -ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i; - unsigned long *parm_offset; - struct syscall *sc; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - parm_offset = ®s.r_scratch.gr16; - - /* - * FreeBSD has two special kinds of system call redirctions -- - * SYS_syscall, and SYS___syscall. The former is the old syscall() - * routine, basically; the latter is for quad-aligned arguments. - */ - syscall_num = regs.r_scratch.gr15; /* XXX double-check. */ - if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) - syscall_num = (int)*parm_offset++; - - fsc.number = syscall_num; - fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) - ? NULL : syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - memcpy(fsc.args, parm_offset, nargs * sizeof(long)); - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct reg regs; + struct syscall *sc; + unsigned long *parm_offset; + int i, syscall_num; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + parm_offset = ®s.r_scratch.gr16; + + /* + * FreeBSD has two special kinds of system call redirctions -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + */ + syscall_num = regs.r_scratch.gr15; /* XXX double-check. */ + if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) + syscall_num = (int)*parm_offset++; + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0 || + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); + memcpy(fsc.args, parm_offset, nargs * sizeof(long)); + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } + fsc.nargs = nargs; + } - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -237,65 +238,68 @@ ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) { long ia64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return (-1); - } - retval = regs.r_scratch.gr8; - errorp = (regs.r_scratch.gr10 != 0) ? 1 : 0; - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return (-1); + } + + retval = regs.r_scratch.gr8; + errorp = (regs.r_scratch.gr10 != 0) ? 1 : 0; + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index e04e810..d6a1edc 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$"); #include "extern.h" #include "syscall.h" -#define MAXARGS 6 +#define MAXARGS 6 static void usage(void) @@ -113,19 +113,19 @@ static struct ex_types { /* * Set the execution type. This is called after every exec, and when - * a process is first monitored. + * a process is first monitored. */ static struct ex_types * set_etype(struct trussinfo *trussinfo) { struct ex_types *funcs; - char progt[32]; - - size_t len = sizeof(progt); - int mib[4]; + size_t len; int error; + int mib[4]; + char progt[32]; + len = sizeof(progt); mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_SV_NAME; @@ -135,7 +135,7 @@ set_etype(struct trussinfo *trussinfo) err(2, "can not get etype"); for (funcs = ex_types; funcs->type; funcs++) - if (!strcmp(funcs->type, progt)) + if (strcmp(funcs->type, progt) == 0) break; if (funcs->type == NULL) { @@ -163,16 +163,13 @@ strsig(int sig) int main(int ac, char **av) { - int c; - int i; - pid_t childpid; - int status; - char **command; struct ex_types *funcs; - int initial_open; - char *fname; struct trussinfo *trussinfo; + char *fname; char *signame; + char **command; + pid_t childpid; + int c, i, initial_open, status; fname = NULL; initial_open = 1; @@ -192,7 +189,7 @@ main(int ac, char **av) case 'p': /* specified pid */ trussinfo->pid = atoi(optarg); /* make sure i don't trace me */ - if(trussinfo->pid == getpid()) { + if (trussinfo->pid == getpid()) { fprintf(stderr, "attempt to grab self.\n"); exit(2); } @@ -221,7 +218,7 @@ main(int ac, char **av) case 's': /* Specified string size */ trussinfo->strsize = atoi(optarg); break; - case 'S': /* Don't trace signals */ + case 'S': /* Don't trace signals */ trussinfo->flags |= NOSIGS; break; default: @@ -288,7 +285,7 @@ START_TRACE: struct timespec timediff; waitevent(trussinfo); - switch(i = trussinfo->pr_why) { + switch (i = trussinfo->pr_why) { case S_SCE: funcs->enter_syscall(trussinfo, MAXARGS); clock_gettime(CLOCK_REALTIME, @@ -301,9 +298,8 @@ START_TRACE: if (trussinfo->curthread->in_fork && (trussinfo->flags & FOLLOWFORKS)) { trussinfo->curthread->in_fork = 0; - childpid = - funcs->exit_syscall(trussinfo, - trussinfo->pr_data); + childpid = funcs->exit_syscall(trussinfo, + trussinfo->pr_data); /* * Fork a new copy of ourself to trace @@ -359,10 +355,10 @@ START_TRACE: timediff.tv_nsec); } if (trussinfo->flags & RELATIVETIMESTAMPS) { - timespecsubt(&trussinfo->after, - &trussinfo->before, &timediff); - fprintf(trussinfo->outfile, "%ld.%09ld ", - (long)timediff.tv_sec, timediff.tv_nsec); + timespecsubt(&trussinfo->after, + &trussinfo->before, &timediff); + fprintf(trussinfo->outfile, "%ld.%09ld ", + (long)timediff.tv_sec, timediff.tv_nsec); } fprintf(trussinfo->outfile, "process exit, rval = %u\n", trussinfo->pr_data); @@ -372,13 +368,14 @@ START_TRACE: } } while (trussinfo->pr_why != S_EXIT); - if (trussinfo->flags & FOLLOWFORKS) + if (trussinfo->flags & FOLLOWFORKS) { do { childpid = wait(&status); } while (childpid != -1); + } - if (trussinfo->flags & COUNTONLY) - print_summary(trussinfo); + if (trussinfo->flags & COUNTONLY) + print_summary(trussinfo); fflush(trussinfo->outfile); diff --git a/usr.bin/truss/mips-fbsd.c b/usr.bin/truss/mips-fbsd.c index 5d295c7..b141f80 100644 --- a/usr.bin/truss/mips-fbsd.c +++ b/usr.bin/truss/mips-fbsd.c @@ -92,18 +92,19 @@ static struct freebsd_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -114,162 +115,169 @@ clear_fsc(void) { */ void -mips_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i; - struct syscall *sc; - int indir = 0; /* indirect system call */ - struct ptrace_io_desc iorequest; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - syscall_num = regs.r_regs[V0]; - if (syscall_num == SYS_syscall) { - indir = 1; - syscall_num = regs.r_regs[A0]; - } - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); +mips_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct ptrace_io_desc iorequest; + struct reg regs; + struct syscall *sc; + int i, syscall_num; + int indir; /* indirect system call */ + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + + indir = 0; + syscall_num = regs.r_regs[V0]; + if (syscall_num == SYS_syscall) { + indir = 1; + syscall_num = regs.r_regs[A0]; + } + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0 || + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); #if 0 // XXX - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)parm_offset; - iorequest.piod_addr = fsc.args; - iorequest.piod_len = (1+nargs) * sizeof(unsigned long); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)parm_offset; + iorequest.piod_addr = fsc.args; + iorequest.piod_len = (1 + nargs) * sizeof(unsigned long); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; #else - iorequest.piod_op = PIOD_READ_D; + iorequest.piod_op = PIOD_READ_D; #endif - switch (nargs) { - default: - /* - * The OS doesn't seem to allow more than 10 words of - * parameters (yay!). So we shouldn't be here. - */ - warn("More than 10 words (%d) of arguments!\n", nargs); - break; - case 10: case 9: case 8: case 7: case 6: case 5: - /* - * If there are 7-10 words of arguments, they are placed - * on the stack, as is normal for other processors. - * The fall-through for all of these is deliberate!!! - */ - // XXX BAD constant used here - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)(regs.r_regs[SP] + 4 * sizeof(uint32_t)); - iorequest.piod_addr = &fsc.args[4]; - iorequest.piod_len = (nargs - 4) * sizeof(fsc.args[0]); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) return; - case 4: fsc.args[3] = regs.r_regs[A3]; - case 3: fsc.args[2] = regs.r_regs[A2]; - case 2: fsc.args[1] = regs.r_regs[A1]; - case 1: fsc.args[0] = regs.r_regs[A0]; - case 0: - break; - } - if (indir) { - memmove(&fsc.args[0], &fsc.args[1], (nargs-1) * sizeof(fsc.args[0])); - } - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { + switch (nargs) { + default: + /* + * The OS doesn't seem to allow more than 10 words of + * parameters (yay!). So we shouldn't be here. + */ + warn("More than 10 words (%d) of arguments!\n", nargs); + break; + case 10: + case 9: + case 8: + case 7: + case 6: + case 5: + /* + * If there are 7-10 words of arguments, they are placed + * on the stack, as is normal for other processors. + * The fall-through for all of these is deliberate!!! + */ + // XXX BAD constant used here + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.r_regs[SP] + + 4 * sizeof(uint32_t)); + iorequest.piod_addr = &fsc.args[4]; + iorequest.piod_len = (nargs - 4) * sizeof(fsc.args[0]); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; + case 4: fsc.args[3] = regs.r_regs[A3]; + case 3: fsc.args[2] = regs.r_regs[A2]; + case 2: fsc.args[1] = regs.r_regs[A1]; + case 1: fsc.args[0] = regs.r_regs[A0]; + case 0: break; + } + if (indir) { + memmove(&fsc.args[0], &fsc.args[1], + (nargs - 1) * sizeof(fsc.args[0])); + } + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } + fsc.nargs = nargs; + } - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -280,66 +288,71 @@ mips_syscall_entry(struct trussinfo *trussinfo, int nargs) { */ long -mips_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); - return (-1); - } - retval = regs.r_regs[V0]; - errorp = !!regs.r_regs[A3]; - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { +mips_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +{ + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "\n"); + return (-1); + } + + retval = regs.r_regs[V0]; + errorp = !!regs.r_regs[A3]; + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/powerpc-fbsd.c b/usr.bin/truss/powerpc-fbsd.c index 506d122..e98b7ed 100644 --- a/usr.bin/truss/powerpc-fbsd.c +++ b/usr.bin/truss/powerpc-fbsd.c @@ -65,7 +65,7 @@ static int cpid = -1; #ifdef __powerpc64__ /* 32-bit compatibility */ #include "freebsd32_syscalls.h" -#define syscallnames freebsd32_syscallnames +#define syscallnames freebsd32_syscallnames #else /* native 32-bit */ #include "syscalls.h" #endif @@ -92,18 +92,19 @@ static struct freebsd_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -114,147 +115,146 @@ clear_fsc(void) { */ void -powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - void *args; - int syscall_num; - int i; - int regargs; - struct syscall *sc; - - /* Account for a 64-bit argument with corresponding alignment. */ - nargs += 2; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - /* - * FreeBSD has two special kinds of system call redirctions -- - * SYS_syscall, and SYS___syscall. The former is the old syscall() - * routine, basically; the latter is for quad-aligned arguments. - */ - regargs = NARGREG; - syscall_num = regs.fixreg[0]; - args = ®s.fixreg[3]; - if (syscall_num == SYS_syscall) { - args = ®s.fixreg[4]; - regargs -= 1; - syscall_num = regs.fixreg[3]; - } else if (syscall_num == SYS___syscall) { - args = ®s.fixreg[5]; - regargs -= 2; - syscall_num = regs.fixreg[4]; - } - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - - if (nargs > regargs) { - struct ptrace_io_desc iorequest; - memmove(&fsc.args[0], args, regargs * sizeof(fsc.args[0])); - - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)(regs.fixreg[1] + 8); - iorequest.piod_addr = &fsc.args[regargs]; - iorequest.piod_len = (nargs - regargs) * sizeof(fsc.args[0]); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; - } else { - memmove(&fsc.args[0], args, nargs * sizeof(fsc.args[0])); - } - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct ptrace_io_desc iorequest; + struct reg regs; + struct syscall *sc; + void *args; + int i, regargs, syscall_num; + + /* Account for a 64-bit argument with corresponding alignment. */ + nargs += 2; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + + /* + * FreeBSD has two special kinds of system call redirctions -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + */ + regargs = NARGREG; + syscall_num = regs.fixreg[0]; + args = ®s.fixreg[3]; + if (syscall_num == SYS_syscall) { + args = ®s.fixreg[4]; + regargs -= 1; + syscall_num = regs.fixreg[3]; + } else if (syscall_num == SYS___syscall) { + args = ®s.fixreg[5]; + regargs -= 2; + syscall_num = regs.fixreg[4]; + } + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0 || + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); + + if (nargs > regargs) { + memmove(&fsc.args[0], args, regargs * sizeof(fsc.args[0])); + + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.fixreg[1] + 8); + iorequest.piod_addr = &fsc.args[regargs]; + iorequest.piod_len = (nargs - regargs) * sizeof(fsc.args[0]); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; + } else + memmove(&fsc.args[0], args, nargs * sizeof(fsc.args[0])); + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } + fsc.nargs = nargs; + } - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - } - - return; + if (fsc.name && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -267,76 +267,77 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { long powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); - return (-1); - } - retval = regs.fixreg[3]; - errorp = !!(regs.cr & 0x10000000); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * On 32-bit big-endian, the low word of a 64-bit return is - * in the greater address. Switch to this. XXX note that - * print_syscall_ret can't handle 64-bit return values (llseek) - */ - if (sc->ret_type == 2) - retval = regs.fixreg[4]; - - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "\n"); + return (-1); + } + + retval = regs.fixreg[3]; + errorp = !!(regs.cr & 0x10000000); + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * On 32-bit big-endian, the low word of a 64-bit return is + * in the greater address. Switch to this. XXX note that + * print_syscall_ret can't handle 64-bit return values (llseek) + */ + if (sc->ret_type == 2) + retval = regs.fixreg[4]; + + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/powerpc64-fbsd.c b/usr.bin/truss/powerpc64-fbsd.c index bad9ed8..0eae03f 100644 --- a/usr.bin/truss/powerpc64-fbsd.c +++ b/usr.bin/truss/powerpc64-fbsd.c @@ -87,18 +87,19 @@ static struct freebsd_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -109,140 +110,139 @@ clear_fsc(void) { */ void -powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - void *args; - int syscall_num; - int i; - int regargs; - struct syscall *sc; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - /* - * FreeBSD has two special kinds of system call redirctions -- - * SYS_syscall, and SYS___syscall. The former is the old syscall() - * routine, basically; the latter is for quad-aligned arguments. - */ - regargs = NARGREG; - syscall_num = regs.fixreg[0]; - args = ®s.fixreg[3]; - if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { - args = ®s.fixreg[4]; - regargs -= 1; - syscall_num = regs.fixreg[3]; - } - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - - if (nargs > regargs) { - struct ptrace_io_desc iorequest; - memmove(&fsc.args[0], args, regargs * sizeof(fsc.args[0])); - - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)(regs.fixreg[1] + 48); - iorequest.piod_addr = &fsc.args[regargs]; - iorequest.piod_len = (nargs - regargs) * sizeof(fsc.args[0]); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) - return; - } else { - memmove(&fsc.args[0], args, nargs * sizeof(fsc.args[0])); - } - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { +powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct ptrace_io_desc iorequest; + struct reg regs; + struct syscall *sc; + void *args; + int i, regargs, syscall_num; + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + + /* + * FreeBSD has two special kinds of system call redirctions -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. + */ + regargs = NARGREG; + syscall_num = regs.fixreg[0]; + args = ®s.fixreg[3]; + if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { + args = ®s.fixreg[4]; + regargs -= 1; + syscall_num = regs.fixreg[3]; + } + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0 || + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); + + if (nargs > regargs) { + memmove(&fsc.args[0], args, regargs * sizeof(fsc.args[0])); + + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.fixreg[1] + 48); + iorequest.piod_addr = &fsc.args[regargs]; + iorequest.piod_len = (nargs - regargs) * sizeof(fsc.args[0]); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; + } else + memmove(&fsc.args[0], args, nargs * sizeof(fsc.args[0])); + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } + fsc.nargs = nargs; + } - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ - - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - } - - return; + if (fsc.name && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -255,68 +255,69 @@ powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { long powerpc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); - return (-1); - } - retval = regs.fixreg[3]; - errorp = !!(regs.cr & 0x10000000); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "\n"); + return (-1); + } + + retval = regs.fixreg[3]; + errorp = !!(regs.cr & 0x10000000); + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - - - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c index 66ad8de..b4c61e1 100644 --- a/usr.bin/truss/setup.c +++ b/usr.bin/truss/setup.c @@ -73,15 +73,14 @@ setup_and_wait(char *command[]) int waitval; pid = vfork(); - if (pid == -1) { + if (pid == -1) err(1, "fork failed"); - } if (pid == 0) { /* Child */ ptrace(PT_TRACE_ME, 0, 0, 0); execvp(command[0], command); err(1, "execvp %s", command[0]); } - + /* Only in the parent here */ if (waitpid(pid, &waitval, 0) < 0) { err(1, "unexpect stop in waitpid"); @@ -89,7 +88,7 @@ setup_and_wait(char *command[]) } child_pid = pid; - + return (pid); } @@ -102,19 +101,18 @@ setup_and_wait(char *command[]) int start_tracing(pid_t pid) { - int waitval; - int ret; - int retry = 10; + int ret, retry, waitval; + retry = 10; do { ret = ptrace(PT_ATTACH, pid, NULL, 0); usleep(200); - } while(ret && retry-- > 0); + } while (ret && retry-- > 0); if (ret) err(1, "can not attach to target process"); - child_pid = pid; - if (waitpid(pid, &waitval, 0) < 0) + child_pid = pid; + if (waitpid(pid, &waitval, 0) < 0) err(1, "Unexpect stop in waitpid"); return (0); @@ -131,14 +129,14 @@ restore_proc(int signo __unused) { int waitval; - /* stop the child so that we can detach */ + /* stop the child so that we can detach */ kill(child_pid, SIGSTOP); if (waitpid(child_pid, &waitval, 0) < 0) err(1, "Unexpected stop in waitpid"); if (ptrace(PT_DETACH, child_pid, (caddr_t)1, 0) < 0) err(1, "Can not detach the process"); - + kill(child_pid, SIGCONT); exit(0); } @@ -150,12 +148,13 @@ restore_proc(int signo __unused) static void find_thread(struct trussinfo *info, lwpid_t lwpid) { - info->curthread = NULL; struct threadinfo *np; + + info->curthread = NULL; SLIST_FOREACH(np, &info->threadlist, entries) { - if (np->tid == lwpid) { - info->curthread = np; - return; + if (np->tid == lwpid) { + info->curthread = np; + return; } } @@ -177,16 +176,16 @@ find_thread(struct trussinfo *info, lwpid_t lwpid) void waitevent(struct trussinfo *info) { - int waitval; + struct ptrace_lwpinfo lwpinfo; static int pending_signal = 0; - + int waitval; + ptrace(PT_SYSCALL, info->pid, (caddr_t)1, pending_signal); pending_signal = 0; - if (waitpid(info->pid, &waitval, 0) < 0) { + if (waitpid(info->pid, &waitval, 0) < 0) err(1, "Unexpected stop in waitpid"); - } - + if (WIFCONTINUED(waitval)) { info->pr_why = S_NONE; return; @@ -197,10 +196,10 @@ waitevent(struct trussinfo *info) return; } if (WIFSTOPPED(waitval)) { - struct ptrace_lwpinfo lwpinfo; - ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo, sizeof(lwpinfo)); + ptrace(PT_LWPINFO, info->pid, (caddr_t)&lwpinfo, + sizeof(lwpinfo)); find_thread(info, lwpinfo.pl_lwpid); - switch(WSTOPSIG(waitval)) { + switch (WSTOPSIG(waitval)) { case SIGTRAP: if (lwpinfo.pl_flags & PL_FLAG_SCE) { info->pr_why = S_SCE; diff --git a/usr.bin/truss/sparc64-fbsd.c b/usr.bin/truss/sparc64-fbsd.c index 47302cc..4aa512d 100644 --- a/usr.bin/truss/sparc64-fbsd.c +++ b/usr.bin/truss/sparc64-fbsd.c @@ -93,18 +93,19 @@ static struct freebsd_syscall { /* Clear up and free parts of the fsc structure. */ static __inline void -clear_fsc(void) { - if (fsc.args) { - free(fsc.args); - } - if (fsc.s_args) { - int i; - for (i = 0; i < fsc.nargs; i++) - if (fsc.s_args[i]) - free(fsc.s_args[i]); - free(fsc.s_args); - } - memset(&fsc, 0, sizeof(fsc)); +clear_fsc(void) +{ + int i; + + if (fsc.args) + free(fsc.args); + if (fsc.s_args) { + for (i = 0; i < fsc.nargs; i++) + if (fsc.s_args[i]) + free(fsc.s_args[i]); + free(fsc.s_args); + } + memset(&fsc, 0, sizeof(fsc)); } /* @@ -115,159 +116,162 @@ clear_fsc(void) { */ void -sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { - struct reg regs; - int syscall_num; - int i; - struct syscall *sc; - int indir = 0; /* indirect system call */ - struct ptrace_io_desc iorequest; - - cpid = trussinfo->curthread->tid; - - clear_fsc(); - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); - return; - } - - /* - * FreeBSD has two special kinds of system call redirctions -- - * SYS_syscall, and SYS___syscall. The former is the old syscall() - * routine, basically; the latter is for quad-aligned arguments. - */ - syscall_num = regs.r_global[1]; - if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { - indir = 1; - syscall_num = regs.r_out[0]; - } - - fsc.number = syscall_num; - fsc.name = - (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; - if (!fsc.name) { - fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); - } - - if (fsc.name && (trussinfo->flags & FOLLOWFORKS) - && ((!strcmp(fsc.name, "fork") - || !strcmp(fsc.name, "rfork") - || !strcmp(fsc.name, "vfork")))) - { - trussinfo->curthread->in_fork = 1; - } - - if (nargs == 0) - return; - - fsc.args = malloc((1+nargs) * sizeof(unsigned long)); - switch (nargs) { - default: - /* - * The OS doesn't seem to allow more than 10 words of - * parameters (yay!). So we shouldn't be here. - */ - warn("More than 10 words (%d) of arguments!\n", nargs); - break; - case 10: case 9: case 8: case 7: +sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) +{ + struct ptrace_io_desc iorequest; + struct reg regs; + struct syscall *sc; + int i, syscall_num; + int indir; /* indirect system call */ + + clear_fsc(); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); + return; + } + /* - * If there are 7-10 words of arguments, they are placed - * on the stack, as is normal for other processors. - * The fall-through for all of these is deliberate!!! + * FreeBSD has two special kinds of system call redirctions -- + * SYS_syscall, and SYS___syscall. The former is the old syscall() + * routine, basically; the latter is for quad-aligned arguments. */ - iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (void *)(regs.r_out[6] + SPOFF + - offsetof(struct frame, fr_pad[6])); - iorequest.piod_addr = &fsc.args[6]; - iorequest.piod_len = (nargs - 6) * sizeof(fsc.args[0]); - ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); - if (iorequest.piod_len == 0) return; - - case 6: fsc.args[5] = regs.r_out[5]; - case 5: fsc.args[4] = regs.r_out[4]; - case 4: fsc.args[3] = regs.r_out[3]; - case 3: fsc.args[2] = regs.r_out[2]; - case 2: fsc.args[1] = regs.r_out[1]; - case 1: fsc.args[0] = regs.r_out[0]; - case 0: - break; - } - - if (indir) { - memmove(&fsc.args[0], &fsc.args[1], (nargs-1) * sizeof(fsc.args[0])); - } - - sc = get_syscall(fsc.name); - if (sc) { - fsc.nargs = sc->nargs; - } else { + indir = 0; + syscall_num = regs.r_global[1]; + if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { + indir = 1; + syscall_num = regs.r_out[0]; + } + + fsc.number = syscall_num; + fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? + NULL : syscallnames[syscall_num]; + if (!fsc.name) { + fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", + syscall_num); + } + + if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && + (strcmp(fsc.name, "fork") == 0 || + strcmp(fsc.name, "rfork") == 0 || + strcmp(fsc.name, "vfork") == 0)) + trussinfo->curthread->in_fork = 1; + + if (nargs == 0) + return; + + fsc.args = malloc((1 + nargs) * sizeof(unsigned long)); + switch (nargs) { + default: + /* + * The OS doesn't seem to allow more than 10 words of + * parameters (yay!). So we shouldn't be here. + */ + warn("More than 10 words (%d) of arguments!\n", nargs); + break; + case 10: + case 9: + case 8: + case 7: + /* + * If there are 7-10 words of arguments, they are placed + * on the stack, as is normal for other processors. + * The fall-through for all of these is deliberate!!! + */ + iorequest.piod_op = PIOD_READ_D; + iorequest.piod_offs = (void *)(regs.r_out[6] + SPOFF + + offsetof(struct frame, fr_pad[6])); + iorequest.piod_addr = &fsc.args[6]; + iorequest.piod_len = (nargs - 6) * sizeof(fsc.args[0]); + ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); + if (iorequest.piod_len == 0) + return; + case 6: fsc.args[5] = regs.r_out[5]; + case 5: fsc.args[4] = regs.r_out[4]; + case 4: fsc.args[3] = regs.r_out[3]; + case 3: fsc.args[2] = regs.r_out[2]; + case 2: fsc.args[1] = regs.r_out[1]; + case 1: fsc.args[0] = regs.r_out[0]; + case 0: + break; + } + + if (indir) + memmove(&fsc.args[0], &fsc.args[1], (nargs - 1) * + sizeof(fsc.args[0])); + + sc = get_syscall(fsc.name); + if (sc) + fsc.nargs = sc->nargs; + else { #if DEBUG - fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", - fsc.name, nargs); + fprintf(trussinfo->outfile, "unknown syscall %s -- setting " + "args to %d\n", fsc.name, nargs); #endif - fsc.nargs = nargs; - } - - fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); - fsc.sc = sc; + fsc.nargs = nargs; + } - /* - * At this point, we set up the system call arguments. - * We ignore any OUT ones, however -- those are arguments that - * are set by the system call, and so are probably meaningless - * now. This doesn't currently support arguments that are - * passed in *and* out, however. - */ + fsc.s_args = calloc(1, (1 + fsc.nargs) * sizeof(char *)); + fsc.sc = sc; - if (fsc.name) { + /* + * At this point, we set up the system call arguments. + * We ignore any OUT ones, however -- those are arguments that + * are set by the system call, and so are probably meaningless + * now. This doesn't currently support arguments that are + * passed in *and* out, however. + */ + if (fsc.name) { #if DEBUG - fprintf(stderr, "syscall %s(", fsc.name); + fprintf(stderr, "syscall %s(", fsc.name); #endif - for (i = 0; i < fsc.nargs; i++) { + for (i = 0; i < fsc.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%x%s", - sc - ? fsc.args[sc->args[i].offset] - : fsc.args[i], - i < (fsc.nargs - 1) ? "," : ""); + fprintf(stderr, "0x%x%s", sc ? + fsc.args[sc->args[i].offset] : fsc.args[i], + i < (fsc.nargs - 1) ? "," : ""); #endif - if (sc && !(sc->args[i].type & OUT)) { - fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); - } - } + if (sc && !(sc->args[i].type & OUT)) { + fsc.s_args[i] = print_arg(&sc->args[i], + fsc.args, 0, trussinfo); + } + } #if DEBUG - fprintf(stderr, ")\n"); + fprintf(stderr, ")\n"); #endif - } + } #if DEBUG - fprintf(trussinfo->outfile, "\n"); + fprintf(trussinfo->outfile, "\n"); #endif - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - - /* XXX - * This could be done in a more general - * manner but it still wouldn't be very pretty. - */ - if (!strcmp(fsc.name, "execve")) { - if ((trussinfo->flags & EXECVEARGS) == 0) - if (fsc.s_args[1]) { - free(fsc.s_args[1]); - fsc.s_args[1] = NULL; - } - if ((trussinfo->flags & EXECVEENVS) == 0) - if (fsc.s_args[2]) { - free(fsc.s_args[2]); - fsc.s_args[2] = NULL; - } - } - } - - return; + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) { + /* + * XXX + * This could be done in a more general + * manner but it still wouldn't be very pretty. + */ + if (strcmp(fsc.name, "execve") == 0) { + if ((trussinfo->flags & EXECVEARGS) == 0) { + if (fsc.s_args[1]) { + free(fsc.s_args[1]); + fsc.s_args[1] = NULL; + } + } + if ((trussinfo->flags & EXECVEENVS) == 0) { + if (fsc.s_args[2]) { + free(fsc.s_args[2]); + fsc.s_args[2] = NULL; + } + } + } + } + + return; } /* @@ -278,66 +282,71 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { */ long -sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { - struct reg regs; - long retval; - int i; - int errorp; - struct syscall *sc; - - if (fsc.name == NULL) - return (-1); - cpid = trussinfo->curthread->tid; - - if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { - fprintf(trussinfo->outfile, "\n"); - return (-1); - } - retval = regs.r_out[0]; - errorp = !!(regs.r_tstate & TSTATE_XCC_C); - - /* - * This code, while simpler than the initial versions I used, could - * stand some significant cleaning. - */ - - sc = fsc.sc; - if (!sc) { - for (i = 0; i < fsc.nargs; i++) - asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); - } else { - /* - * Here, we only look for arguments that have OUT masked in -- - * otherwise, they were handled in the syscall_entry function. - */ - for (i = 0; i < sc->nargs; i++) { - char *temp; - if (sc->args[i].type & OUT) { +sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) +{ + struct reg regs; + struct syscall *sc; + long retval; + int errorp, i; + + if (fsc.name == NULL) + return (-1); + + cpid = trussinfo->curthread->tid; + + if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { + fprintf(trussinfo->outfile, "\n"); + return (-1); + } + + retval = regs.r_out[0]; + errorp = !!(regs.r_tstate & TSTATE_XCC_C); + /* - * If an error occurred, than don't bothe getting the data; - * it may not be valid. + * This code, while simpler than the initial versions I used, could + * stand some significant cleaning. */ - if (errorp) - asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); - else - temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); - fsc.s_args[i] = temp; - } - } - } - - if (fsc.name != NULL && - (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { - trussinfo->curthread->in_syscall = 1; - } - /* - * It would probably be a good idea to merge the error handling, - * but that complicates things considerably. - */ - - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - retval, fsc.sc); - clear_fsc(); - - return (retval); + + sc = fsc.sc; + if (!sc) { + for (i = 0; i < fsc.nargs; i++) + asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); + } else { + /* + * Here, we only look for arguments that have OUT masked in -- + * otherwise, they were handled in the syscall_entry function. + */ + 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", + fsc.args[sc->args[i].offset]); + } else { + temp = print_arg(&sc->args[i], + fsc.args, retval, trussinfo); + } + fsc.s_args[i] = temp; + } + } + } + + if (fsc.name != NULL && (strcmp(fsc.name, "execve") == 0 || + strcmp(fsc.name, "exit") == 0)) + trussinfo->curthread->in_syscall = 1; + + /* + * It would probably be a good idea to merge the error handling, + * but that complicates things considerably. + */ + + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); + clear_fsc(); + + return (retval); } diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index 484bb5d..49ff9a4 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -42,9 +42,9 @@ enum Argtype { None = 1, Hex, Octal, Int, Name, Ptr, Stat, Ioctl, Quad, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, Pathconf }; -#define ARG_MASK 0xff -#define OUT 0x100 -#define IN /*0x20*/0 +#define ARG_MASK 0xff +#define OUT 0x100 +#define IN /*0x20*/0 struct syscall_args { enum Argtype type; diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 25e012e..4fba0cc 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -269,8 +269,8 @@ struct xlat { const char *str; }; -#define X(a) { a, #a }, -#define XEND { 0, NULL } +#define X(a) { a, #a }, +#define XEND { 0, NULL } static struct xlat kevent_filters[] = { X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE) @@ -414,10 +414,11 @@ xlookup(struct xlat *xlat, int val) static char * xlookup_bits(struct xlat *xlat, int val) { + int len, rem; static char str[512]; - int len = 0; - int rem = val; + len = 0; + rem = val; for (; xlat->str != NULL; xlat++) { if ((xlat->val & rem) == xlat->val) { /* don't print the "all-bits-zero" string unless all @@ -445,12 +446,13 @@ xlookup_bits(struct xlat *xlat, int val) struct syscall * get_syscall(const char *name) { - struct syscall *sc = syscalls; + struct syscall *sc; + sc = syscalls; if (name == NULL) return (NULL); while (sc->name) { - if (!strcmp(name, sc->name)) + if (strcmp(name, sc->name) == 0) return (sc); sc++; } @@ -477,8 +479,8 @@ get_struct(pid_t pid, void *offset, void *buf, int len) return (0); } -#define MAXSIZE 4096 -#define BLOCKSIZE 1024 +#define MAXSIZE 4096 +#define BLOCKSIZE 1024 /* * get_string * Copy a string from the process. Note that it is @@ -489,12 +491,11 @@ get_struct(pid_t pid, void *offset, void *buf, int len) static char * get_string(pid_t pid, void *offset, int max) { - char *buf; struct ptrace_io_desc iorequest; - int totalsize, size; - int diff = 0; - int i; + char *buf; + int diff, i, size, totalsize; + diff = 0; totalsize = size = max ? (max + 1) : BLOCKSIZE; buf = malloc(totalsize); if (buf == NULL) @@ -536,11 +537,14 @@ get_string(pid_t pid, void *offset, int max) */ char * -print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trussinfo *trussinfo) +print_arg(struct syscall_args *sc, unsigned long *args, long retval, + struct trussinfo *trussinfo) { - char *tmp = NULL; - pid_t pid = trussinfo->pid; + char *tmp; + pid_t pid; + tmp = NULL; + pid = trussinfo->pid; switch (sc->type & ARG_MASK) { case Hex: asprintf(&tmp, "0x%x", (int)args[sc->offset]); @@ -581,15 +585,18 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus len = max_string; truncated = 1; } - if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) != -1) { + if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) + != -1) { tmp3 = malloc(len * 4 + 1); while (len) { - if (strvisx(tmp3, tmp2, len, VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string) + if (strvisx(tmp3, tmp2, len, + VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string) break; len--; truncated = 1; }; - asprintf(&tmp, "\"%s\"%s", tmp3, truncated?"...":""); + asprintf(&tmp, "\"%s\"%s", tmp3, truncated ? + "..." : ""); free(tmp3); } else { asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -602,10 +609,9 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus char *string; char *strarray[100]; /* XXX This is ugly. */ - if (get_struct(pid, (void *)args[sc->offset], (void *)&strarray, - sizeof(strarray)) == -1) { + if (get_struct(pid, (void *)args[sc->offset], + (void *)&strarray, sizeof(strarray)) == -1) err(1, "get_struct %p", (void *)args[sc->offset]); - } num = 0; size = 0; @@ -623,7 +629,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus tmp2 += sprintf(tmp2, " ["); for (i = 0; i < num; i++) { string = get_string(pid, (void*)strarray[i], 0); - tmp2 += sprintf(tmp2, " \"%s\"%c", string, (i+1 == num) ? ' ' : ','); + tmp2 += sprintf(tmp2, " \"%s\"%c", string, + (i + 1 == num) ? ' ' : ','); free(string); } tmp2 += sprintf(tmp2, "]"); @@ -657,20 +664,22 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Ioctl: { const char *temp = ioctlname(args[sc->offset]); - if (temp) { + if (temp) tmp = strdup(temp); - } else { + else { unsigned long arg = args[sc->offset]; - asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", arg, - arg&IOC_OUT?"R":"", arg&IOC_IN?"W":"", - IOCGROUP(arg), isprint(IOCGROUP(arg))?(char)IOCGROUP(arg):'?', + asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", + arg, arg & IOC_OUT ? "R" : "", + arg & IOC_IN ? "W" : "", IOCGROUP(arg), + isprint(IOCGROUP(arg)) ? (char)IOCGROUP(arg) : '?', arg & 0xFF, IOCPARM_LEN(arg)); } break; } case Umtx: { struct umtx umtx; - if (get_struct(pid, (void *)args[sc->offset], &umtx, sizeof(umtx)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &umtx, + sizeof(umtx)) != -1) asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner); else asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -678,23 +687,28 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Timespec: { struct timespec ts; - if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1) - asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec, ts.tv_nsec); + if (get_struct(pid, (void *)args[sc->offset], &ts, + sizeof(ts)) != -1) + asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec, + ts.tv_nsec); else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Timeval: { struct timeval tv; - if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) - asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec, tv.tv_usec); + if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) + != -1) + asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec, + tv.tv_usec); else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Timeval2: { struct timeval tv[2]; - if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) + != -1) asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }", (long)tv[0].tv_sec, tv[0].tv_usec, (long)tv[1].tv_sec, tv[1].tv_usec); @@ -704,7 +718,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Itimerval: { struct itimerval itv; - if (get_struct(pid, (void *)args[sc->offset], &itv, sizeof(itv)) != -1) + if (get_struct(pid, (void *)args[sc->offset], &itv, + sizeof(itv)) != -1) asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }", (long)itv.it_interval.tv_sec, itv.it_interval.tv_usec, @@ -716,8 +731,9 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Pollfd: { /* - * XXX: A Pollfd argument expects the /next/ syscall argument to be - * the number of fds in the array. This matches the poll syscall. + * XXX: A Pollfd argument expects the /next/ syscall argument + * to be the number of fds in the array. This matches the poll + * syscall. */ struct pollfd *pfd; int numfds = args[sc->offset+1]; @@ -726,22 +742,22 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus const int per_fd = 100; if ((pfd = malloc(bytes)) == NULL) - err(1, "Cannot malloc %d bytes for pollfd array", bytes); - if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) != -1) { - + err(1, "Cannot malloc %d bytes for pollfd array", + bytes); + if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) + != -1) { used = 0; tmpsize = 1 + per_fd * numfds + 2; if ((tmp = malloc(tmpsize)) == NULL) - err(1, "Cannot alloc %d bytes for poll output", tmpsize); + err(1, "Cannot alloc %d bytes for poll output", + tmpsize); tmp[used++] = '{'; for (i = 0; i < numfds; i++) { - u = snprintf(tmp + used, per_fd, - "%s%d/%s", - i > 0 ? " " : "", - pfd[i].fd, - xlookup_bits(poll_flags, pfd[i].events) ); + u = snprintf(tmp + used, per_fd, "%s%d/%s", + i > 0 ? " " : "", pfd[i].fd, + xlookup_bits(poll_flags, pfd[i].events)); if (u > 0) used += u < per_fd ? u : per_fd; } @@ -755,8 +771,9 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Fd_set: { /* - * XXX: A Fd_set argument expects the /first/ syscall argument to be - * the number of fds in the array. This matches the select syscall. + * XXX: A Fd_set argument expects the /first/ syscall argument + * to be the number of fds in the array. This matches the + * select syscall. */ fd_set *fds; int numfds = args[0]; @@ -765,17 +782,21 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus const int per_fd = 20; if ((fds = malloc(bytes)) == NULL) - err(1, "Cannot malloc %d bytes for fd_set array", bytes); - if (get_struct(pid, (void *)args[sc->offset], fds, bytes) != -1) { + err(1, "Cannot malloc %d bytes for fd_set array", + bytes); + if (get_struct(pid, (void *)args[sc->offset], fds, bytes) + != -1) { used = 0; tmpsize = 1 + numfds * per_fd + 2; if ((tmp = malloc(tmpsize)) == NULL) - err(1, "Cannot alloc %d bytes for fd_set output", tmpsize); + err(1, "Cannot alloc %d bytes for fd_set " + "output", tmpsize); tmp[used++] = '{'; for (i = 0; i < numfds; i++) { if (FD_ISSET(i, fds)) { - u = snprintf(tmp + used, per_fd, "%d ", i); + u = snprintf(tmp + used, per_fd, "%d ", + i); if (u > 0) used += u < per_fd ? u : per_fd; } @@ -784,9 +805,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus used--; tmp[used++] = '}'; tmp[used++] = '\0'; - } else { + } else asprintf(&tmp, "0x%lx", args[sc->offset]); - } free(fds); break; } @@ -805,16 +825,16 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus int i, used; sig = args[sc->offset]; - if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, sizeof(ss)) == -1) { + if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, + sizeof(ss)) == -1) { asprintf(&tmp, "0x%lx", args[sc->offset]); break; } tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */ used = 0; for (i = 1; i < sys_nsig; i++) { - if (sigismember(&ss, i)) { + if (sigismember(&ss, i)) used += sprintf(tmp + used, "%s|", strsig(i)); - } } if (used) tmp[used-1] = 0; @@ -824,7 +844,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Sigprocmask: { switch (args[sc->offset]) { -#define S(a) case a: tmp = strdup(#a); break; +#define S(a) case a: tmp = strdup(#a); break; S(SIG_BLOCK); S(SIG_UNBLOCK); S(SIG_SETMASK); @@ -838,10 +858,12 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus /* XXX output depends on the value of the previous argument */ switch (args[sc->offset-1]) { case F_SETFD: - tmp = strdup(xlookup_bits(fcntlfd_arg, args[sc->offset])); + tmp = strdup(xlookup_bits(fcntlfd_arg, + args[sc->offset])); break; case F_SETFL: - tmp = strdup(xlookup_bits(fcntlfl_arg, args[sc->offset])); + tmp = strdup(xlookup_bits(fcntlfl_arg, + args[sc->offset])); break; case F_GETFD: case F_GETFL: @@ -902,7 +924,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus /* yuck: get ss_len */ if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, - sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1) + sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1) err(1, "get_struct %p", (void *)args[sc->offset]); /* * If ss_len is 0, then try to guess from the sockaddr type. @@ -922,8 +944,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus break; } } - if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, ss.ss_len) - == -1) { + if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, + ss.ss_len) == -1) { err(2, "get_struct %p", (void *)args[sc->offset]); } @@ -931,12 +953,15 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus case AF_INET: lsin = (struct sockaddr_in *)&ss; inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof addr); - asprintf(&tmp, "{ AF_INET %s:%d }", addr, htons(lsin->sin_port)); + asprintf(&tmp, "{ AF_INET %s:%d }", addr, + htons(lsin->sin_port)); break; case AF_INET6: lsin6 = (struct sockaddr_in6 *)&ss; - inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, sizeof addr); - asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr, htons(lsin6->sin6_port)); + inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, + sizeof addr); + asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr, + htons(lsin6->sin6_port)); break; case AF_UNIX: sun = (struct sockaddr_un *)&ss; @@ -944,12 +969,14 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus break; default: sa = (struct sockaddr *)&ss; - asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data = {%n%*s } }", - (int)sa->sa_len, (int)sa->sa_family, &i, - 6 * (int)(sa->sa_len - ((char *)&sa->sa_data - (char *)sa)), ""); + asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data " + "= {%n%*s } }", (int)sa->sa_len, (int)sa->sa_family, + &i, 6 * (int)(sa->sa_len - ((char *)&sa->sa_data - + (char *)sa)), ""); if (tmp != NULL) { p = tmp + i; - for (q = (u_char *)&sa->sa_data; q < (u_char *)sa + sa->sa_len; q++) + for (q = (u_char *)&sa->sa_data; + q < (u_char *)sa + sa->sa_len; q++) p += sprintf(p, " %#02x,", *q); } } @@ -960,8 +987,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus char *hand; const char *h; - if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) != -1) { - + if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) + != -1) { asprintf(&hand, "%p", sa.sa_handler); if (sa.sa_handler == SIG_DFL) h = "SIG_DFL"; @@ -970,13 +997,11 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus else h = hand; - asprintf(&tmp, "{ %s %s ss_t }", - h, + asprintf(&tmp, "{ %s %s ss_t }", h, xlookup_bits(sigaction_flags, sa.sa_flags)); free(hand); - } else { + } else asprintf(&tmp, "0x%lx", args[sc->offset]); - } break; } case Kevent: { @@ -1001,12 +1026,15 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus if (numevents >= 0) bytes = sizeof(struct kevent) * numevents; if ((ke = malloc(bytes)) == NULL) - err(1, "Cannot malloc %d bytes for kevent array", bytes); - if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], ke, bytes) != -1) { + err(1, "Cannot malloc %d bytes for kevent array", + bytes); + if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], + ke, bytes) != -1) { used = 0; tmpsize = 1 + per_ke * numevents + 2; if ((tmp = malloc(tmpsize)) == NULL) - err(1, "Cannot alloc %d bytes for kevent output", tmpsize); + err(1, "Cannot alloc %d bytes for kevent " + "output", tmpsize); tmp[used++] = '{'; for (i = 0; i < numevents; i++) { @@ -1032,12 +1060,14 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Stat: { struct stat st; - if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) != -1) { + if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) + != -1) { char mode[12]; strmode(st.st_mode, mode); - asprintf(&tmp, "{ mode=%s,inode=%jd,size=%jd,blksize=%ld }", - mode, - (intmax_t)st.st_ino,(intmax_t)st.st_size,(long)st.st_blksize); + asprintf(&tmp, + "{ mode=%s,inode=%jd,size=%jd,blksize=%ld }", mode, + (intmax_t)st.st_ino, (intmax_t)st.st_size, + (long)st.st_blksize); } else { asprintf(&tmp, "0x%lx", args[sc->offset]); } @@ -1045,24 +1075,25 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus } case Rusage: { struct rusage ru; - if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) != -1) { - asprintf(&tmp, "{ u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld }", + if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) + != -1) { + asprintf(&tmp, + "{ u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld }", (long)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec, (long)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec, ru.ru_inblock, ru.ru_oublock); - } else { + } else asprintf(&tmp, "0x%lx", args[sc->offset]); - } break; } case Rlimit: { struct rlimit rl; - if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) != -1) { + if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) + != -1) { asprintf(&tmp, "{ cur=%ju,max=%ju }", rl.rlim_cur, rl.rlim_max); - } else { + } else asprintf(&tmp, "0x%lx", args[sc->offset]); - } break; } default: @@ -1079,21 +1110,24 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trus */ void -print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s_args) +print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, + char **s_args) { - int i; - int len = 0; struct timespec timediff; + int i, len; + len = 0; if (trussinfo->flags & FOLLOWFORKS) len += fprintf(trussinfo->outfile, "%5d: ", trussinfo->pid); - if (name != NULL && (!strcmp(name, "execve") || !strcmp(name, "exit"))) { + if (name != NULL && (strcmp(name, "execve") == 0|| + strcmp(name, "exit") == 0)) { clock_gettime(CLOCK_REALTIME, &trussinfo->after); } if (trussinfo->flags & ABSOLUTETIMESTAMPS) { - timespecsubt(&trussinfo->after, &trussinfo->start_time, &timediff); + timespecsubt(&trussinfo->after, &trussinfo->start_time, + &timediff); len += fprintf(trussinfo->outfile, "%ld.%09ld ", (long)timediff.tv_sec, timediff.tv_nsec); } @@ -1110,8 +1144,10 @@ print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s if (s_args[i]) len += fprintf(trussinfo->outfile, "%s", s_args[i]); else - len += fprintf(trussinfo->outfile, ""); - len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ? "," : ""); + len += fprintf(trussinfo->outfile, + ""); + len += fprintf(trussinfo->outfile, "%s", i < (nargs - 1) ? + "," : ""); } len += fprintf(trussinfo->outfile, ")"); for (i = 0; i < 6 - (len / 8); i++) @@ -1138,14 +1174,15 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, print_syscall(trussinfo, name, nargs, s_args); fflush(trussinfo->outfile); - if (errorp) { - fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval, strerror(retval)); - } else { + if (errorp) + fprintf(trussinfo->outfile, " ERR#%ld '%s'\n", retval, + strerror(retval)); + else { /* * Because pipe(2) has a special assembly glue to provide the * libc API, we have to adjust retval. */ - if (name != NULL && !strcmp(name, "pipe")) + if (name != NULL && strcmp(name, "pipe") == 0) retval = 0; fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval, retval); } @@ -1154,12 +1191,12 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, void print_summary(struct trussinfo *trussinfo) { - struct syscall *sc; struct timespec total = {0, 0}; + struct syscall *sc; int ncall, nerror; fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n", - "syscall", "seconds", "calls", "errors"); + "syscall", "seconds", "calls", "errors"); ncall = nerror = 0; for (sc = syscalls; sc->name != NULL; sc++) if (sc->ncalls) { @@ -1171,7 +1208,7 @@ print_summary(struct trussinfo *trussinfo) nerror += sc->nerror; } fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n", - "", "-------------", "-------", "-------"); + "", "-------------", "-------", "-------"); fprintf(trussinfo->outfile, "%-20s%5jd.%09ld%8d%8d\n", - "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror); + "", (intmax_t)total.tv_sec, total.tv_nsec, ncall, nerror); } diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h index e708530..d09886e 100644 --- a/usr.bin/truss/truss.h +++ b/usr.bin/truss/truss.h @@ -27,13 +27,13 @@ #include -#define FOLLOWFORKS 0x00000001 -#define RELATIVETIMESTAMPS 0x00000002 -#define ABSOLUTETIMESTAMPS 0x00000004 -#define NOSIGS 0x00000008 -#define EXECVEARGS 0x00000010 -#define EXECVEENVS 0x00000020 -#define COUNTONLY 0x00000040 +#define FOLLOWFORKS 0x00000001 +#define RELATIVETIMESTAMPS 0x00000002 +#define ABSOLUTETIMESTAMPS 0x00000004 +#define NOSIGS 0x00000008 +#define EXECVEARGS 0x00000010 +#define EXECVEENVS 0x00000020 +#define COUNTONLY 0x00000040 struct threadinfo { @@ -57,11 +57,11 @@ struct trussinfo struct timespec after; struct threadinfo *curthread; - + SLIST_HEAD(, threadinfo) threadlist; }; -#define timespecsubt(tvp, uvp, vvp) \ +#define timespecsubt(tvp, uvp, vvp) \ do { \ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ (vvp)->tv_nsec = (tvp)->tv_nsec - (uvp)->tv_nsec; \ @@ -71,7 +71,7 @@ struct trussinfo } \ } while (0) -#define timespecadd(tvp, uvp, vvp) \ +#define timespecadd(tvp, uvp, vvp) \ do { \ (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ (vvp)->tv_nsec = (tvp)->tv_nsec + (uvp)->tv_nsec; \ @@ -81,9 +81,9 @@ struct trussinfo } \ } while (0) -#define S_NONE 0 -#define S_SCE 1 -#define S_SCX 2 -#define S_EXIT 3 -#define S_SIG 4 -#define S_EXEC 5 +#define S_NONE 0 +#define S_SCE 1 +#define S_SCX 2 +#define S_EXIT 3 +#define S_SIG 4 +#define S_EXEC 5 -- cgit v1.1