home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)syscall.c 1.5 91/09/05
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include <signal.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/ptrace.h>
- #include <sys/user.h>
-
- #include "defs.h"
-
- extern char *sys_errlist[];
- extern int sys_nerr;
-
- #include "syscall.h"
- struct sysent {
- int nargs;
- int (*sys_func)();
- char *sys_name;
- } sysent[] = {
- #include "syscallent.h"
- };
- int nsyscall = sizeof sysent / sizeof sysent[0];
-
- int
- syscall(tcp)
- struct tcb *tcp;
- {
- int i, sys_res;
- int pid = tcp->pid;
- struct user *u;
-
- #if 0
- errno = 0;
- if ((scno = ptrace(PTRACE_PEEKUSER, pid, uoff(u_arg[7]), 0)) == -1) {
- if (errno) {
- perror("trace: ptrace(PTRACE_PEEKUSER)");
- return -1;
- }
- }
- #endif
- if (tcp->flags & TCB_INSYSCALL) {
- u_int u_error;
-
- /* get error code from user struct */
- errno = 0;
- u_error = ptrace(PTRACE_PEEKUSER, pid, uoff(u_error), 0);
- if (errno) {
- perror("ptrace(PTRACE_PEEKUSER,..,u_error)");
- return -1;
- }
- u_error >>= 24; /* u_error is a char */
- tcp->u_error = u_error;
-
- /* get system call return value */
- errno = 0;
- tcp->u_rval = ptrace(PTRACE_PEEKUSER, pid,
- uoff(u_rval1), 0);
- if (errno) {
- perror("ptrace(PTRACE_PEEKUSER,..,u_rval1)");
- return -1;
- }
- sys_res = (*sysent[tcp->scno].sys_func)(tcp);
- if (u_error) {
- fprintf(outf, ") = -1 (%s)\n",
- (u_error<sys_nerr)?sys_errlist[u_error]:"???");
- } else {
- fprintf(outf, sys_res&RVAL_HEX?") = %#x":") = %d",
- tcp->u_rval);
- fprintf(outf, sys_res&RVAL_STR?" (%s)\n":"\n",
- tcp->auxstr);
- }
- fflush(outf);
- tcp->flags &= ~TCB_INSYSCALL;
- return 0;
- }
- errno = 0;
- if ((tcp->scno = ptrace(PTRACE_PEEKUSER, pid, uoff(u_arg[7]), 0)) == -1) {
- if (errno) {
- perror("trace: ptrace(PTRACE_PEEKUSER)");
- return -1;
- }
- }
- if (Nproc > 1)
- fprintf(outf, " [pid %u]: ", pid);
- if (tflag) {
- time_t t = time(0);
- char str[sizeof("HH:MM:SS")];
-
- strftime(str, sizeof(str), "%T", localtime(&t));
- fprintf(outf, "%s ", str);
- }
- fprintf(outf, "%s(", sysent[tcp->scno].sys_name);
- for (i=0; i<sysent[tcp->scno].nargs; i++) {
- errno = 0;
- tcp->u_args[i] = ptrace(PTRACE_PEEKUSER, pid,
- uoff(u_arg[0]) + (i*sizeof(u->u_arg[0])), 0);
- if (errno) {
- perror("ptrace(PTRACE_PEEKUSER)");
- return -1;
- }
- }
- sys_res = (*sysent[tcp->scno].sys_func)(tcp);
- fflush(outf);
- tcp->flags |= TCB_INSYSCALL;
- return sys_res;
- }
-
- int
- printargs(tcp)
- struct tcb *tcp;
- {
- int i, nargs = sysent[tcp->scno].nargs;
-
- if (tcp->flags & TCB_INSYSCALL)
- return 0;
-
- for (i = 0; i < nargs; i++)
- fprintf(outf, i>0?", %#x":"%#x", tcp->u_args[i]);
- return 0;
- }
-
- int
- getrval2(pid)
- {
- int val;
-
- errno = 0;
- val = ptrace(PTRACE_PEEKUSER, pid, uoff(u_rval2), 0);
- if (errno) {
- perror(" [ptrace(PTRACE_PEEKUSER,..,u_rval2)]");
- return -1;
- }
- return val;
- }
-
- /*
- * Apparently, indirect system calls have already be converted by ptrace(2),
- * so if you see "indir" this program has gone astray.
- */
- int
- sys_indir(tcp)
- struct tcb *tcp;
- {
- u_int i, scno, nargs;
-
- if (entering(tcp)) {
- if ((scno = tcp->u_args[0]) > nsyscall) {
- fprintf(stderr, "Bogus syscall: %u\n", scno);
- return 0;
- }
- nargs = sysent[scno].nargs;
- fprintf(outf, "%s", sysent[scno].sys_name);
- for (i = 0; i < nargs; i++)
- fprintf(outf, ", %#x", tcp->u_args[i+1]);
- }
- return 0;
- }
-