home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)syscall.c 2.4 92/01/10
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include <signal.h>
- #include <time.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, res;
- int pid = tcp->pid;
-
- #if 1
- int scno;
- if (upeek(pid, (unsigned)uoff(u_arg[7]), &scno) < 0)
- return -1;
-
- if (!(tcp->flags & TCB_INSYSCALL) && scno == 0) {
- tcp->flags |= TCB_INSYSCALL;
- (void)fprintf(stderr, " **syscall: RESYNC\n");
- }
- #endif
- if (tcp->flags & TCB_INSYSCALL) {
- u_int u_error;
-
- /* get error code from user struct */
- if (upeek(pid, (unsigned)uoff(u_error), (int *)&u_error) < 0)
- return -1;
- u_error >>= 24; /* u_error is a char */
- tcp->u_error = u_error;
-
- /* get system call return value */
- if (upeek(pid, (unsigned)uoff(u_rval1), &tcp->u_rval) < 0)
- return -1;
-
- if (tcp->scno < nsyscall)
- res = (*sysent[tcp->scno].sys_func)(tcp);
- else
- res = RVAL_HEX;
-
- if (u_error) {
- tprintf(") = -1 (%s)\n",
- (u_error<sys_nerr)?sys_errlist[u_error]:"???");
- } else {
- char *format;
- switch (res & RVAL_FMASK) {
- case RVAL_HEX:
- format = ") = %#x";
- break;
- case RVAL_OCT:
- format = ") = %o";
- break;
- case RVAL_UDEC:
- format = ") = %u";
- break;
- case RVAL_DEC:
- default:
- format = ") = %d";
- break;
- }
- tprintf(format, tcp->u_rval);
- tprintf(res&RVAL_STR?" (%s)\n":"\n", tcp->auxstr);
- }
- if (fflush(tcp->outf) == EOF)
- return -1;
- tcp->flags &= ~TCB_INSYSCALL;
- return 0;
- }
-
- /* Entering system call */
- #if 1
- tcp->scno = scno;
- #else
- if (upeek(pid, (unsigned)uoff(u_arg[7]), &tcp->scno) < 0)
- return -1;
- #endif
-
- if (Nproc > 1)
- tprintf(" [pid %u]: ", pid);
- if (tflag) {
- extern time_t time();
- time_t t = time((time_t *)0);
- char str[16];
-
- if (strftime(str, sizeof(str), "%T", localtime(&t)) > 0)
- tprintf("%s ", str);
- }
- if (cflag) {
- (void)printcall(tcp->pid);
- }
- if (tcp->scno >= nsyscall) {
- tprintf("syscall_%u(", tcp->scno);
- tcp->flags |= TCB_INSYSCALL;
- return 0;
- }
- tprintf("%s(", sysent[tcp->scno].sys_name);
- for (i=0; i<sysent[tcp->scno].nargs; i++) {
- struct user *u;
- if (upeek(pid, (u_int)uoff(u_arg[0]) + (i*sizeof(u->u_arg[0])),
- &tcp->u_args[i]) < 0)
- return -1;
- }
- res = (*sysent[tcp->scno].sys_func)(tcp);
- if (fflush(tcp->outf) == EOF)
- return -1;
- tcp->flags |= TCB_INSYSCALL;
- return 0;
- }
-
- 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++)
- tprintf(i>0?", %#x":"%#x", tcp->u_args[i]);
- return 0;
- }
-
- int
- getrval2(pid)
- {
- int val;
-
- if (upeek(pid, (unsigned)uoff(u_rval2), &val) < 0)
- 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) {
- (void)fprintf(stderr, "Bogus syscall: %u\n", scno);
- return 0;
- }
- nargs = sysent[scno].nargs;
- tprintf("%s", sysent[scno].sys_name);
- for (i = 0; i < nargs; i++)
- tprintf(", %#x", tcp->u_args[i+1]);
- }
- return 0;
- }
-