long powerpc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { struct reg regs; struct freebsd_syscall *fsc; struct syscall *sc; lwpid_t tid; long retval; int errorp, i; if (trussinfo->curthread->fsc == NULL) return (-1); tid = trussinfo->curthread->tid; if (ptrace(PT_GETREGS, tid, (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. */ fsc = trussinfo->curthread->fsc; 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); free_fsc(fsc); return (retval); }
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) { /* * If an error occurred, than don't bothe 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") || !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); }
long 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) { /* * If an error occurred, than don't bothe 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; } } } /* * 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); }
void print_openbsd_syscall_ret(int num, abi_long ret) { print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames)); }
void print_netbsd_syscall_ret(int num, abi_long ret) { print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames)); }
void print_freebsd_syscall_ret(int num, abi_long ret) { print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames)); }