home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume3 / strace / part01 / syscall.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-02  |  3.4 KB  |  180 lines

  1. /*
  2.  * @(#)syscall.c    2.4 92/01/10
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <strings.h>
  7. #include <signal.h>
  8. #include <time.h>
  9. #include <errno.h>
  10. #include <sys/types.h>
  11. #include <sys/param.h>
  12. #include <sys/ptrace.h>
  13. #include <sys/user.h>
  14.  
  15. #include "defs.h"
  16.  
  17. extern char *sys_errlist[];
  18. extern int sys_nerr;
  19.  
  20. #include "syscall.h"
  21. struct sysent {
  22.     int    nargs;
  23.     int    (*sys_func)();
  24.     char    *sys_name;
  25. } sysent[] = {
  26. #include "syscallent.h"
  27. };
  28. int nsyscall = sizeof sysent / sizeof sysent[0];
  29.  
  30. int
  31. syscall(tcp)
  32. struct tcb *tcp;
  33. {
  34.     int    i, res;
  35.     int    pid = tcp->pid;
  36.  
  37. #if 1
  38.     int scno;
  39.     if (upeek(pid, (unsigned)uoff(u_arg[7]), &scno) < 0)
  40.         return -1;
  41.  
  42.     if (!(tcp->flags & TCB_INSYSCALL) && scno == 0) {
  43.         tcp->flags |= TCB_INSYSCALL;
  44.         (void)fprintf(stderr, "  **syscall: RESYNC\n");
  45.     }
  46. #endif
  47.     if (tcp->flags & TCB_INSYSCALL) {
  48.         u_int u_error;
  49.  
  50.         /* get error code from user struct */
  51.         if (upeek(pid, (unsigned)uoff(u_error), (int *)&u_error) < 0)
  52.             return -1;
  53.         u_error >>= 24; /* u_error is a char */
  54.         tcp->u_error = u_error;
  55.  
  56.         /* get system call return value */
  57.         if (upeek(pid, (unsigned)uoff(u_rval1), &tcp->u_rval) < 0)
  58.             return -1;
  59.  
  60.         if (tcp->scno < nsyscall)
  61.             res = (*sysent[tcp->scno].sys_func)(tcp);
  62.         else
  63.             res = RVAL_HEX;
  64.  
  65.         if (u_error) {
  66.             tprintf(") = -1 (%s)\n",
  67.             (u_error<sys_nerr)?sys_errlist[u_error]:"???");
  68.         } else {
  69.             char *format;
  70.             switch (res & RVAL_FMASK) {
  71.             case RVAL_HEX:
  72.                 format = ") = %#x";
  73.                 break;
  74.             case RVAL_OCT:
  75.                 format = ") = %o";
  76.                 break;
  77.             case RVAL_UDEC:
  78.                 format = ") = %u";
  79.                 break;
  80.             case RVAL_DEC:
  81.             default:
  82.                 format = ") = %d";
  83.                 break;
  84.             }
  85.             tprintf(format, tcp->u_rval);
  86.             tprintf(res&RVAL_STR?" (%s)\n":"\n", tcp->auxstr);
  87.         }
  88.         if (fflush(tcp->outf) == EOF)
  89.             return -1;
  90.         tcp->flags &= ~TCB_INSYSCALL;
  91.         return 0;
  92.     }
  93.  
  94.     /* Entering system call */
  95. #if 1
  96.     tcp->scno = scno;
  97. #else
  98.     if (upeek(pid, (unsigned)uoff(u_arg[7]), &tcp->scno) < 0)
  99.         return -1;
  100. #endif
  101.  
  102.     if (Nproc > 1)
  103.         tprintf(" [pid %u]: ", pid);
  104.     if (tflag) {
  105.         extern time_t time();
  106.         time_t t = time((time_t *)0);
  107.         char str[16];
  108.  
  109.         if (strftime(str, sizeof(str), "%T", localtime(&t)) > 0)
  110.             tprintf("%s ", str);
  111.     }
  112.     if (cflag) {
  113.         (void)printcall(tcp->pid);
  114.     }
  115.     if (tcp->scno >= nsyscall) {
  116.         tprintf("syscall_%u(", tcp->scno);
  117.         tcp->flags |= TCB_INSYSCALL;
  118.         return 0;
  119.     }
  120.     tprintf("%s(", sysent[tcp->scno].sys_name);
  121.     for (i=0; i<sysent[tcp->scno].nargs; i++) {
  122.         struct    user *u;
  123.         if (upeek(pid, (u_int)uoff(u_arg[0]) + (i*sizeof(u->u_arg[0])),
  124.                     &tcp->u_args[i]) < 0)
  125.             return -1;
  126.     }
  127.     res = (*sysent[tcp->scno].sys_func)(tcp);
  128.     if (fflush(tcp->outf) == EOF)
  129.         return -1;
  130.     tcp->flags |= TCB_INSYSCALL;
  131.     return 0;
  132. }
  133.  
  134. int
  135. printargs(tcp)
  136. struct tcb *tcp;
  137. {
  138.     int i, nargs = sysent[tcp->scno].nargs;
  139.  
  140.     if (tcp->flags & TCB_INSYSCALL)
  141.         return 0;
  142.  
  143.     for (i = 0; i < nargs; i++)
  144.         tprintf(i>0?", %#x":"%#x", tcp->u_args[i]);
  145.     return 0;
  146. }
  147.  
  148. int
  149. getrval2(pid)
  150. {
  151.     int val;
  152.  
  153.     if (upeek(pid, (unsigned)uoff(u_rval2), &val) < 0)
  154.         return -1;
  155.     return val;
  156. }
  157.  
  158. /*
  159.  * Apparently, indirect system calls have already be converted by ptrace(2),
  160.  * so if you see "indir" this program has gone astray.
  161.  */
  162. int
  163. sys_indir(tcp)
  164. struct tcb *tcp;
  165. {
  166.     u_int i, scno, nargs;
  167.  
  168.     if (entering(tcp)) {
  169.         if ((scno = tcp->u_args[0]) > nsyscall) {
  170.             (void)fprintf(stderr, "Bogus syscall: %u\n", scno);
  171.             return 0;
  172.         }
  173.         nargs = sysent[scno].nargs;
  174.         tprintf("%s", sysent[scno].sys_name);
  175.         for (i = 0; i < nargs; i++)
  176.             tprintf(", %#x", tcp->u_args[i+1]);
  177.     }
  178.     return 0;
  179. }
  180.