home *** CD-ROM | disk | FTP | other *** search
- #include <sys/types.h>
- #include <sys/times.h>
- #include <sys/fs/prfcntl.h>
- #include <bsd/sys/types.h>
- #include <bsd/sys/socket.h>
- #include <bsd/sys/time.h>
- #include <bsd/netinet/in.h>
- #include <bsd/netdb.h>
- #define INKERNEL 1
- #include <signal.h>
- #undef INKERNEL
- #include <fcntl.h>
- #include <errno.h>
- #include <stdio.h>
- #include <unistd.h>
- #include "register.h"
- #include "symtab.h"
- #include "diblock.h"
- #include "instrn.h"
- #include "process.h"
- #include "sysentry.h"
- #include "res.h"
- #include "nels.h"
-
- #define TRUNCATED_READ_WRITE_LENGTH 32
-
- extern char *malloc();
- extern char *realloc();
- extern char *ctime();
- extern char *sysmess();
- extern sysentry *sysv_systab_entry();
- extern sysentry *bsd43_systab_entry();
- extern sysentry *posix_systab_entry();
-
- extern int sysv_print_open_flags();
- extern int bsd43_print_open_flags();
- extern int posix_print_open_flags();
-
- extern int sysv_print_open_mode();
- extern int bsd43_print_open_mode();
- extern int posix_print_open_mode();
-
- extern int sysv_print_stat();
- extern int bsd43_print_stat();
- extern int posix_print_stat();
-
- extern int sysv_print_ioctl_cmd();
- extern int bsd43_print_ioctl_cmd();
- extern int posix_print_ioctl_cmd();
-
- extern int sysv_print_ioctl_arg();
- extern int bsd43_print_ioctl_arg();
- extern int posix_print_ioctl_arg();
-
- extern int sysv_print_fdset();
- extern int bsd43_print_fdset();
- extern int posix_print_fdset();
-
- extern int sysv_print_whence();
- extern int bsd43_print_whence();
- extern int posix_print_whence();
-
- extern int sysv_print_statfs();
- extern int bsd43_print_statfs();
- extern int posix_print_statfs();
-
- extern int sysv_print_sigcontext();
- extern int bsd43_print_sigcontext();
- extern int posix_print_sigcontext();
-
- extern int bsd43_print_sigvec();
- extern int sysv_print_wait3_union_wait();
- extern int sysv_print_wait3_options();
- extern int sysv_print_wait3_rusage();
-
- extern int Aflag;
- extern int Iflag;
- extern int Nflag;
- extern int Pflag;
- extern int Sflag;
- extern int Tflag;
-
- extern char *sys_errnolist[];
- extern int sys_nerrno;
- extern FILE *outfp;
- extern int errno;
- extern unsigned long instruction_count;
- extern unsigned long instruction_count_since_last_syscall;
-
- unsigned long arg[NSYSARGS]; /* Arguments */
-
- dinstrn *GLOBALdipc;
- int return_errno; /* errno goes here. */
- long return_value0; /* Result 1 value goes here. */
- long return_value1; /* Result 2 value goes here. */
-
- sysentry *current_sysentp;
- char *sys_call_buf; /* Scratch buf. */
- unsigned int sys_call_bufz; /* Current size of above. */
-
- int need_leading_pipe;
-
- /*
- * Ensure that the scratch buffer (pointed to by 'sys_call_buf')
- * is at least 'n' bytes long.
- * Return -1 on error.
- */
- int
- bufset(n)
- unsigned int n;
- {
- if (sys_call_bufz >= n)
- return 0;
-
- if (sys_call_bufz == 0)
- sys_call_buf = malloc(n);
- else
- sys_call_buf = realloc(sys_call_buf, n);
-
- if (sys_call_buf == (char *)0)
- {
- vcouldnot("expand syscall buffer to %d bytes", n);
- return -1;
- }
-
- sys_call_bufz = n;
-
- return 0;
- }
-
- /*
- * Return the length of the string that starts
- * at address 'addr' in user memory (like strlen()).
- * Return -1 on error.
- */
- int
- mstrlen(addr)
- unsigned long addr;
- {
- int length;
- char c;
-
- length = 0;
-
- for (;;)
- {
- if (quiet_procmget(GLOBALdipc, addr, &c, sizeof(c)) == -1)
- return -1;
-
- if (c == '\0')
- break;
-
- length++;
- addr++;
- }
-
- return length;
- }
-
- int
- mgetstring(p)
- long p;
- {
- int length;
-
- if ((length = mstrlen(p)) == -1)
- return -1;
-
- length++;
-
- if (bufset((unsigned int)length) == -1)
- return -1;
-
- if (quiet_procmget(GLOBALdipc, (unsigned long)p, sys_call_buf, length) == -1)
- return -1;
-
- return length;
- }
-
- int
- mgets(addr, pp)
- unsigned long addr;
- char **pp;
- {
- int length;
-
- if (addr == (unsigned long)0)
- {
- *pp = (char *)0;
- return 0;
- }
-
- if ((length = mstrlen(addr)) == -1)
- return -1;
-
- length++;
-
- if (bufset((unsigned int)length) == -1)
- return -1;
-
- if (quiet_procmget(GLOBALdipc, addr, sys_call_buf, length) == -1)
- return -1;
-
- *pp = sys_call_buf;
-
- return length;
- }
-
- int
- mputstring(p)
- long p;
- {
- int length;
-
- length = strlen(sys_call_buf);
-
- length++;
-
- if (quiet_procmput(GLOBALdipc, (unsigned long)p, sys_call_buf, length) == -1)
- return -1;
-
- return length;
- }
-
- char **
- mgetvp(addr)
- unsigned long addr;
- {
- int nargs;
- int nchars;
- char **result;
- unsigned long saved_addr;
- char **pp;
- char *stringp;
-
- saved_addr = addr;
- nargs = 0;
- nchars = 0;
-
- for (;;)
- {
- char *p;
- int length;
-
- if (quiet_procmget(GLOBALdipc, addr, &p, sizeof(p)) == -1)
- return (char **)0;
-
- if (p == (char *)0)
- break;
-
- if ((length = mstrlen(p)) == -1)
- return (char **)0;
-
- nargs++;
- nchars += (length + 1);
- addr += sizeof(p);
- }
-
- nargs++;
-
- addr = saved_addr;
-
- if ((result = (char **)malloc(sizeof(char *) * nargs + nchars)) == (char **)0)
- {
- vcouldnot("allocate %d bytes during execve arg processing", sizeof(char *) * nargs + nchars);
- return (char **)0;
- }
-
- pp = result;
- stringp = (char *)(result + nargs);
-
- for (;;)
- {
- char *p;
- int length;
-
- if (quiet_procmget(GLOBALdipc, addr, &p, sizeof(p)) == -1)
- return (char **)0;
-
- if (p == (char *)0)
- break;
-
- if (mgetstring(p) == -1)
- return (char **)0;
-
- *pp++ = stringp;
-
- (void)strcpy(stringp, sys_call_buf);
- stringp += (strlen(sys_call_buf) + 1);
-
- addr += sizeof(p);
- }
-
- *pp = (char *)0;
-
- return result;
- }
-
- int
- mfreevp(p)
- char **p;
- {
- char **cpp;
-
- for (cpp = p; *cpp != (char *)0; cpp++)
- (void)free(*cpp);
-
- (void)free((char *)cpp);
-
- return 0;
- }
-
- int
- dmget(addr, n, pp)
- unsigned long addr;
- int n;
- char **pp;
- {
- if (addr == (unsigned long)0)
- *pp = (char *)0;
- else
- {
- if (proc_mem_contiguous(addr, n, pp))
- return 0;
-
- if (bufset(n) == -1)
- return -1;
-
- if (quiet_procmget(GLOBALdipc, addr, sys_call_buf, n) == -1)
- return -1;
-
- *pp = sys_call_buf;
- }
-
- return 0;
- }
-
- int
- mget(addr, p, n, pp)
- unsigned long addr;
- char *p;
- int n;
- char **pp;
- {
- if (addr == (unsigned long)0)
- *pp = (char *)0;
- else
- {
- if (quiet_procmget(GLOBALdipc, addr, p, n) == -1)
- return -1;
-
- *pp = p;
- }
-
- return 0;
- }
-
- int
- dmput(addr, p, n, s)
- unsigned long addr;
- char *p;
- int n;
- int s;
- {
- if (s != -1 && addr != (unsigned long)0 && p != (char *)0)
- {
- if (proc_mem_contiguous(addr, n, (char **)0))
- return 0;
-
- if (quiet_procmput(GLOBALdipc, addr, p, n) == -1)
- return -1;
- }
-
- return 0;
- }
-
- int
- mput(addr, p, n, s)
- unsigned long addr;
- char *p;
- int n;
- int s;
- {
- if (s != -1 && addr != (unsigned long)0 && p != (char *)0)
- {
- if (quiet_procmput(GLOBALdipc, addr, p, n) == -1)
- return -1;
- }
-
- return 0;
- }
-
- static
- int
- get_syscall_arg(i, resultp)
- int i;
- unsigned long *resultp;
- {
- unsigned long sp;
-
- switch (i)
- {
- case 0:
- if (quiet_procsget(R_V0, resultp) == -1)
- return -1;
- break;
-
- case 1:
- if (quiet_procsget(R_A0, resultp) == -1)
- return -1;
- break;
-
- case 2:
- if (quiet_procsget(R_A1, resultp) == -1)
- return -1;
- break;
-
- case 3:
- if (quiet_procsget(R_A2, resultp) == -1)
- return -1;
- break;
-
- case 4:
- if (quiet_procsget(R_A3, resultp) == -1)
- return -1;
- break;
-
- default:
- if (quiet_procsget(R_SP, &sp) == -1)
- return -1;
-
- if (quiet_procmget(GLOBALdipc, sp + (i - 1) * sizeof(int), resultp, sizeof(*resultp)) == -1)
- return -1;
- break;
- }
-
- return 0;
- }
-
- static
- void
- vis_char(outfp, c)
- FILE *outfp;
- int c;
- {
- if (c >= ' ' && c <= '~')
- {
- if (c == '\\' || c == '"')
- fprintf(outfp, "\\");
- fprintf(outfp, "%c", c);
- }
- else
- {
- switch (c)
- {
- case '\b':
- fprintf(outfp, "\\b");
- break;
-
- case '\f':
- fprintf(outfp, "\\f");
- break;
-
- case '\n':
- fprintf(outfp, "\\n");
- break;
-
- case '\r':
- fprintf(outfp, "\\r");
- break;
-
- case '\t':
- fprintf(outfp, "\\t");
- break;
-
- default:
- fprintf(outfp, "\\%03o", c);
- break;
- }
- }
- }
-
- static
- void
- vis_string_with_quotes(outfp, p)
- FILE *outfp;
- char *p;
- {
- if (p == (char *)0)
- fprintf(outfp, "(char *)0");
- else
- {
- fprintf(outfp, "\"");
- while (*p != '\0')
- vis_char(outfp, *p++);
- fprintf(outfp, "\"");
- }
- }
-
- void
- vis_quoted_truncated_buffer(outfp, truncated_length, buf, real_length)
- FILE *outfp;
- int truncated_length;
- char *buf;
- long real_length;
- {
- int i;
-
- if (buf == (char *)0)
- fprintf(outfp, "(char *)0");
- else
- {
- fprintf(outfp, "\"");
- for (i = 0; i < truncated_length; i++)
- vis_char(outfp, buf[i]);
- fprintf(outfp, "\"%s", (truncated_length < real_length) ? ".." : "");
- }
- }
-
- /*
- * See ~i/sys/signal.h
- */
- static char *signames[] =
- {
- "NULLSIG", /* undefined */
- "SIGHUP", /* hangup */
- "SIGINT", /* interrupt (rubout) */
- "SIGQUIT", /* quit (ASCII FS) */
- "SIGILL", /* illegal instruction (not reset when caught)*/
- "SIGTRAP", /* trace trap (not reset when caught) */
- "SIGABRT/SIGIOT", /* IOT instruction used by abort */
- "SIGXCPU/SIGEMT", /* exceeded CPU time limit/EMT instruction */
- /* SIGEMT (not possible on RISC/os) */
- "SIGFPE", /* floating point exception */
- "SIGKILL", /* kill (cannot be caught or ignored) */
- "SIGBUS", /* bus error */
- "SIGSEGV", /* segmentation violation */
- "SIGSYS", /* bad argument to system call */
- "SIGPIPE", /* write on a pipe with no one to read it */
- "SIGALRM", /* alarm clock */
- "SIGTERM", /* software termination signal from kill */
- "SIGUSR1", /* user defined signal 1 */
- "SIGUSR2", /* user defined signal 2 */
- "SIGCLD/SIGCHLD", /* death of a child/4.3BSD's name */
- "SIGXFSZ/SIGPWR", /* exceeded file size limit/power-fail */
- /* SIGPWR not possible on RISC/os */
- "SIGSTOP", /* sendable stop signal not from tty */
- "SIGTSTP", /* stop signal from tty */
- "SIGPOLL", /* pollable event occured */
- "SIGIO", /* input/output possible signal */
- "SIGURG", /* urgent condition on IO channel */
- "SIGWINCH", /* window size changes */
- "SIGVTALRM", /* virtual time alarm */
- "SIGPROF", /* profiling alarm */
- "SIGCONT", /* continue a stopped process */
- "SIGTTIN", /* to readers pgrp upon background tty read */
- "SIGTTOU", /* like TTIN for output */
- /* -- if (tp->t_local<OSTOP) */
- "SIGLOST", /* resource lost (eg, record-lock) */
- };
-
- char *
- signal_name(s)
- unsigned long s;
- {
- static char buf[128];
- int signo;
- int bits;
-
- signo = s & SIGNO_MASK;
- bits = s & ~SIGNO_MASK;
-
- if (signo >= 0 && signo < nels(signames))
- (void)strcpy(&buf[0], signames[signo]);
- else
- (void)sprintf(&buf[0], "%d", signo);
-
- if ((bits & SIGDEFER) == SIGDEFER)
- {
- bits &= ~SIGDEFER;
- (void)strcat(&buf[0], "|SIGDEFER");
- }
-
- if ((bits & SIGHOLD) == SIGHOLD)
- {
- bits &= ~SIGHOLD;
- (void)strcat(&buf[0], "|SIGHOLD");
- }
-
- if ((bits & SIGRELSE) == SIGRELSE)
- {
- bits &= ~SIGRELSE;
- (void)strcat(&buf[0], "|SIGRELSE");
- }
-
- if ((bits & SIGIGNORE) == SIGIGNORE)
- {
- bits &= ~SIGIGNORE;
- (void)strcat(&buf[0], "|SIGIGNORE");
- }
-
- if ((bits & SIGPAUSE) == SIGPAUSE)
- {
- bits &= ~SIGPAUSE;
- (void)strcat(&buf[0], "|SIGPAUSE");
- }
-
- if (bits != 0x0)
- (void)sprintf(&buf[0], "|0x%x", bits);
-
- return &buf[0];
- }
-
- char *
- signal_set(mask)
- unsigned long mask;
- {
- static char buf[1024];
- int s;
-
- buf[0] = '\0';
-
- (void)strcat(&buf[0], "{");
- for (s = 1; s < NSIG; s++)
- {
- unsigned long m;
-
- m = sigmask(s);
- if ((m & mask) == m)
- {
- (void)strcat(&buf[0], signames[s]);
- (void)strcat(&buf[0], ",");
- mask &= ~m;
- }
- }
- (void)strcat(&buf[0], "}");
-
- if (mask != 0x0)
- (void)sprintf(&buf[strlen(&buf[0])], "0x%x", mask);
-
- return &buf[0];
- }
-
- static char *family[] =
- {
- "UNSPEC",
- "UNIX",
- "INET",
- "IMPLINK",
- "PUP",
- "CHAOS",
- "NS",
- "NBS",
- "ECMA",
- "DATAKIT",
- "CCITT",
- "SNA",
- "DECnet",
- "DLI",
- "LAT",
- "HYLINK",
- "APPLETALK",
- };
-
- static
- char *
- say_family(f)
- int f;
- {
- static char buf[16];
-
- if (f < 0 || f >= nels(family))
- (void)sprintf(&buf[0], "%d", f);
- else
- {
- (void)strcpy(&buf[0], "AF_");
- (void)strcat(&buf[0], family[f]);
- }
-
- return &buf[0];
- }
-
- static
- char *
- say_addr(a)
- unsigned long a;
- {
- static char buf[32];
- int i;
-
- buf[0] = '\0';
-
- for (i = 0; i < sizeof(a); i++)
- {
- if (i != 0)
- buf[i * 4 - 1] = '.';
-
- (void)sprintf(&buf[i * 4], "%03d", (a >> (24 - (i * 8))) & 0xFF);
- }
-
- return &buf[0];
- }
-
- static
- void
- vis_address(outfp, s)
- FILE *outfp;
- struct sockaddr *s;
- {
- if (s->sa_family == AF_INET)
- {
- struct sockaddr_in is;
-
- *(struct sockaddr_in *)&is = *(struct sockaddr_in *)s;
- fprintf(outfp, "{");
- fprintf(outfp, "port=%d,", is.sin_port);
- fprintf(outfp, "addr=%s", say_addr(is.sin_addr.s_addr));
- fprintf(outfp, "}");
- }
- else
- vis_quoted_truncated_buffer(outfp, sizeof(s->sa_data), &s->sa_data[0], sizeof(s->sa_data));
- }
-
- void
- say_time(outfp, t)
- FILE *outfp;
- unsigned long t;
- {
- char *cp;
-
- cp = ctime(&t);
- cp[24] = '\0'; /* overwrite the newline */
- fprintf(outfp, "%lu[%s]", t, cp);
- }
-
- int
- printval(universe, arg, desc, args, return_value0, return_value1, direction)
- int universe;
- long arg;
- int desc;
- long *args;
- long return_value0;
- long return_value1;
- int direction;
- {
- int length;
- char **app;
- char **cpp;
- struct flock sheep;
-
- switch (desc)
- {
- case 'A': /* ioctl arg */
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_ioctl_arg(args);
-
- case U_BSD43:
- return bsd43_print_ioctl_arg(args);
-
- case U_POSIX:
- return posix_print_ioctl_arg(args);
-
- default:
- vcouldnot("print ioctl arg from unknown universe %d", universe);
- return -1;
- }
- break;
-
- case 'B': /* fcntl cmd */
- switch (arg)
- {
- case F_DUPFD:
- fprintf(outfp, "F_DUPFD");
- break;
-
- case F_GETFD:
- fprintf(outfp, "F_GETFD");
- break;
-
- case F_SETFD:
- fprintf(outfp, "F_SETFD");
- break;
-
- case F_GETFL:
- fprintf(outfp, "F_GETFL");
- break;
-
- case F_SETFL:
- fprintf(outfp, "F_SETFL");
- break;
-
- case F_GETLK:
- fprintf(outfp, "F_GETLK");
- break;
-
- case F_SETLK:
- fprintf(outfp, "F_SETLK");
- break;
-
- case F_SETLKW:
- fprintf(outfp, "F_SETLKW");
- break;
-
- case F_CHKFL:
- fprintf(outfp, "F_CHKFL");
- break;
-
- case F_GETOWN:
- fprintf(outfp, "F_GETOWN");
- break;
-
- case F_SETOWN:
- fprintf(outfp, "F_SETOWN");
- break;
-
- case PFCSEXEC:
- fprintf(outfp, "PFCSEXEC");
- break;
-
- case PFCREXEC:
- fprintf(outfp, "PFCREXEC");
- break;
-
- case PFCRUN:
- fprintf(outfp, "PFCRUN");
- break;
-
- case PFCSSTEP:
- fprintf(outfp, "PFCSSTEP");
- break;
-
- case PFCCSIG:
- fprintf(outfp, "PFCCSIG");
- break;
-
- case PFCWSTOP:
- fprintf(outfp, "PFCWSTOP");
- break;
-
- case PFCGMASK:
- fprintf(outfp, "PFCGMASK");
- break;
-
- case PFCSMASK:
- fprintf(outfp, "PFCSMASK");
- break;
-
- case PFCSTOP:
- fprintf(outfp, "PFCSTOP");
- break;
-
- case PFCGETPR:
- fprintf(outfp, "PFCGETPR");
- break;
-
- case PFCGETUSEG:
- fprintf(outfp, "PFCGETUSEG");
- break;
-
- case PFCGETREGS:
- fprintf(outfp, "PFCGETREGS");
- break;
-
- default:
- fprintf(outfp, "0x%x", arg);
- break;
- }
- break;
-
- case 'C': /* ioctl cmd */
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_ioctl_cmd(arg);
-
- case U_BSD43:
- return bsd43_print_ioctl_cmd(arg);
-
- case U_POSIX:
- return posix_print_ioctl_cmd(arg);
-
- default:
- vcouldnot("print ioctl cmd from unknown universe %d", universe);
- return -1;
- }
- break;
-
- case 'D': /* select fd_set */
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_fdset(args[0], arg);
-
- case U_BSD43:
- return bsd43_print_fdset(args[0], arg);
-
- case U_POSIX:
- return posix_print_fdset(args[0], arg);
-
- default:
- vcouldnot("print fdset from unknown universe %d", universe);
- return -1;
- }
- break;
-
- case 'E': /* envp */
- fprintf(outfp, "{");
- if (Aflag)
- {
- if ((app = mgetvp(arg)) == (char **)0)
- return -1;
-
- for (cpp = app; *cpp != (char *)0; cpp++)
- {
- vis_string_with_quotes(outfp, *cpp);
- fprintf(outfp, ",");
- }
-
- if (mfreevp(app) == -1)
- return -1;
- }
- else
- fprintf(outfp, "..");
- fprintf(outfp, "}");
- break;
-
- case 'F': /* filename */
- {
- char *cp;
-
- if (mgets(arg, &cp) == -1)
- return -1;
-
- vis_string_with_quotes(outfp, cp);
- }
- break;
-
- case 'G': /* getgroups() group set */
- fprintf(outfp, "{");
- if (direction == DIRN_EXIT)
- {
- length = return_value0;
-
- if (length < 0)
- length = 0;
-
- if (bufset((unsigned int)length * sizeof(int)) == -1)
- return -1;
-
- if (quiet_procmget(GLOBALdipc, (unsigned long)arg, sys_call_buf, length * sizeof(int)) == -1)
- return -1;
-
- {
- int i;
-
- for (i = 0; i < length; i++)
- fprintf(outfp, "%d, ", ((int *)sys_call_buf)[i]);
- }
- }
- fprintf(outfp, "}");
- break;
-
- case 'H': /* fcntl arg */
- switch (args[1])
- {
- case F_DUPFD:
- case F_GETFD:
- case F_SETFD:
- case F_GETFL:
- case F_SETFL:
- fprintf(outfp, "0x%x", arg);
- break;
-
- case F_GETLK:
- case F_SETLK:
- case F_SETLKW:
- if (quiet_procmget(GLOBALdipc, arg, (char *)&sheep, sizeof(sheep)) == -1)
- return -1;
-
- fprintf(outfp, "{");
- fprintf(outfp, "type=");
- switch (sheep.l_type)
- {
- case F_RDLCK:
- fprintf(outfp, "F_RDLCK");
- break;
-
- case F_WRLCK:
- fprintf(outfp, "F_WRLCK");
- break;
-
- case F_UNLCK:
- fprintf(outfp, "F_UNLCK");
- break;
-
- default:
- fprintf(outfp, "0x%x", sheep.l_type);
- break;
- }
- fprintf(outfp, ",");
- fprintf(outfp, "whence=%d,", sheep.l_whence);
- fprintf(outfp, "start=%d,", sheep.l_start);
- fprintf(outfp, "len=%d,", sheep.l_len);
- fprintf(outfp, "sysid=%d,", sheep.l_sysid);
- fprintf(outfp, "pid=%d,", sheep.l_pid);
- fprintf(outfp, "}");
- break;
-
- default:
- fprintf(outfp, "0x%x", arg);
- break;
- }
- break;
-
-
- case 'I': /* program address */
- fprintf(outfp, "%s", proc_text_address(arg));
- break;
-
- case 'J': /* signal action or program address */
- switch (arg)
- {
- case SIG_ERR:
- fprintf(outfp, "SIG_ERR");
- break;
-
- case SIG_DFL:
- fprintf(outfp, "SIG_DFL");
- break;
-
- case SIG_IGN:
- fprintf(outfp, "SIG_IGN");
- break;
-
- case SIG_HOLD:
- fprintf(outfp, "SIG_HOLD");
- break;
-
- default:
- fprintf(outfp, "%s", proc_text_address(arg));
- break;
- }
- break;
-
- case 'K': /* signal name */
- fprintf(outfp, "%s", signal_name(arg));
- break;
-
- case 'L': /* struct sockaddr */
- if (arg == (unsigned long)0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- struct sockaddr s;
-
- if (quiet_procmget(GLOBALdipc, arg, (char *)&s, sizeof(s)) == -1)
- return -1;
-
- fprintf(outfp, "{");
- fprintf(outfp, "family=%s,", say_family(s.sa_family));
- fprintf(outfp, "sa_data=");
- vis_address(outfp, &s);
- fprintf(outfp, "}");
- }
- break;
-
- case 'M': /* signal set mask */
- fprintf(outfp, "%s", signal_set(arg));
- break;
-
- case 'N': /* send()/recv() flags */
- if (arg == 0)
- fprintf(outfp, "0x0");
- else
- {
- int need_bar;
-
- need_bar = 0;
- if (arg & MSG_OOB)
- {
- fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_OOB");
- need_bar = 1;
- arg &= ~MSG_OOB;
- }
- if (arg & MSG_PEEK)
- {
- fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_PEEK");
- need_bar = 1;
- arg &= ~MSG_PEEK;
- }
- if (arg & MSG_DONTROUTE)
- {
- fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_DONTROUTE");
- need_bar = 1;
- arg &= ~MSG_DONTROUTE;
- }
- if (arg)
- fprintf(outfp, "%s0x%x", need_bar ? "|" : "", arg);
- }
- break;
-
- case 'O': /* open flags */
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_open_flags(arg);
-
- case U_BSD43:
- return bsd43_print_open_flags(arg);
-
- case U_POSIX:
- return posix_print_open_flags(arg);
-
- default:
- vcouldnot("print open flags from unknown universe %d", universe);
- return -1;
- }
- break;
-
- case 'P': /* access mode */
- if (arg == 0)
- fprintf(outfp, "F_OK");
- else
- {
- int need_bar;
-
- need_bar = 0;
- if (arg & R_OK)
- {
- fprintf(outfp, "%s%s", need_bar ? "|" : "", "R_OK");
- need_bar = 1;
- arg &= ~R_OK;
- }
- if (arg & W_OK)
- {
- fprintf(outfp, "%s%s", need_bar ? "|" : "", "W_OK");
- need_bar = 1;
- arg &= ~W_OK;
- }
- if (arg & X_OK)
- {
- fprintf(outfp, "%s%s", need_bar ? "|" : "", "X_OK");
- need_bar = 1;
- arg &= ~X_OK;
- }
- if (arg)
- fprintf(outfp, "%s0x%x", need_bar ? "|" : "", arg);
- }
- break;
-
- case 'Q': /* pair of int's (as in utime()) */
- if (arg == 0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- int i[2];
-
- if (quiet_procmget(GLOBALdipc, (unsigned long)arg, &i[0], sizeof(i)) == -1)
- return -1;
-
- fprintf(outfp, "{");
- say_time(outfp, i[0]);
- fprintf(outfp, ",");
- say_time(outfp, i[1]);
- fprintf(outfp, "}");
- }
- break;
-
- case 'R': /* read() buffer */
- if (direction == DIRN_ENTRY || args[0] == 100)
- fprintf(outfp, "\"\"");
- else
- {
- char *cp;
-
- length = return_value0;
-
- if (length < 0)
- length = 0;
- else if (Aflag == 0 && length > TRUNCATED_READ_WRITE_LENGTH)
- length = TRUNCATED_READ_WRITE_LENGTH;
-
- if (dmget((unsigned long)arg, length, &cp) == -1)
- return -1;
-
- vis_quoted_truncated_buffer(outfp, length, cp, return_value0);
- }
- break;
-
- case 'S': /* struct stat */
- if (direction == DIRN_EXIT)
- {
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_stat(arg);
-
- case U_BSD43:
- return bsd43_print_stat(arg);
-
- case U_POSIX:
- return posix_print_stat(arg);
-
- default:
- vcouldnot("print stat structure from unknown universe %d", universe);
- return -1;
- }
- }
- break;
-
- case 'T': /* struct timeval */
- if (arg == (unsigned long)0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- struct timeval t;
-
- if (quiet_procmget(GLOBALdipc, arg, (char *)&t, sizeof(t)) == -1)
- return -1;
-
- fprintf(outfp, "{");
- fprintf(outfp, "sec=%d,", t.tv_sec);
- fprintf(outfp, "usec=%d", t.tv_usec);
- fprintf(outfp, "}");
- }
- break;
-
- case 'U': /* pointer to an int */
- if (arg == (unsigned long)0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- int i;
-
- if (quiet_procmget(GLOBALdipc, arg, (char *)&i, sizeof(i)) == -1)
- return -1;
-
- fprintf(outfp, "{%d}", i);
- }
- break;
-
- case 'V': /* pair of struct timeval's */
- if (arg == (unsigned long)0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- struct timeval t[2];
-
- if (quiet_procmget(GLOBALdipc, arg, &t[0], sizeof(t)) == -1)
- return -1;
-
- fprintf(outfp, "{");
- fprintf(outfp, "{");
- fprintf(outfp, "sec=%d,", t[0].tv_sec);
- fprintf(outfp, "usec=%d", t[0].tv_usec);
- fprintf(outfp, "}");
- fprintf(outfp, "{");
- fprintf(outfp, "sec=%d,", t[1].tv_sec);
- fprintf(outfp, "usec=%d", t[1].tv_usec);
- fprintf(outfp, "}");
- fprintf(outfp, "}");
- }
- break;
-
- case 'W': /* write() buffer */
- {
- char *cp;
-
- length = args[2];
-
- if (Aflag == 0 && length > TRUNCATED_READ_WRITE_LENGTH)
- length = TRUNCATED_READ_WRITE_LENGTH;
-
- if (dmget((unsigned long)arg, length, &cp) == -1)
- return -1;
-
- vis_quoted_truncated_buffer(outfp, length, cp, args[2]);
- }
- break;
-
- case 'X': /* struct statfs */
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_statfs(arg);
-
- case U_BSD43:
- return bsd43_print_statfs(arg);
-
- case U_POSIX:
- return posix_print_statfs(arg);
-
- default:
- vcouldnot("print statfs structure from unknown universe %d", universe);
- return -1;
- }
- break;
-
- case 'Y': /* result pair */
- fprintf(outfp, "{%d,%d}", return_value0, return_value1);
- break;
-
- case 'Z': /* struct timezone */
- if (arg == (unsigned long)0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- struct timezone t;
-
- if (quiet_procmget(GLOBALdipc, arg, (char *)&t, sizeof(t)) == -1)
- return -1;
-
- fprintf(outfp, "{");
- fprintf(outfp, "minuteswest=%d,", t.tz_minuteswest);
- fprintf(outfp, "dsttime=%d", t.tz_dsttime);
- fprintf(outfp, "}");
- }
- break;
-
- case 'a': /* socket domain */
- switch (arg)
- {
- case PF_UNIX:
- fprintf(outfp, "PF_UNIX");
- break;
-
- case PF_INET:
- fprintf(outfp, "PF_INET");
- break;
-
- case PF_NS:
- fprintf(outfp, "PF_NS");
- break;
-
- case PF_IMPLINK:
- fprintf(outfp, "PF_IMPLINK");
- break;
-
- default:
- fprintf(outfp, "%d", arg);
- break;
- }
- break;
-
- case 'b': /* socket type */
- switch (arg)
- {
- case SOCK_STREAM:
- fprintf(outfp, "SOCK_STREAM");
- break;
-
- case SOCK_DGRAM:
- fprintf(outfp, "SOCK_DGRAM");
- break;
-
- case SOCK_RAW:
- fprintf(outfp, "SOCK_RAW");
- break;
-
- case SOCK_SEQPACKET:
- fprintf(outfp, "SOCK_SEQPACKET");
- break;
-
- case SOCK_RDM:
- fprintf(outfp, "SOCK_RDM");
- break;
-
- default:
- fprintf(outfp, "%d", arg);
- break;
- }
- break;
-
- case 'c': /* socket protocol */
- {
- struct protoent *p;
-
- if
- (
- args[0] == PF_INET
- &&
- (p = getprotobynumber(arg)) != (struct protoent *)0
- )
- fprintf(outfp, "%s", p->p_name);
- else
- fprintf(outfp, "%d", arg);
- }
- break;
-
- case 'd': /* int */
- fprintf(outfp, "%d", arg);
- break;
-
- case 'e': /* int -- result from execve()/exit() see i_syscall() */
- fprintf(outfp, "%d", arg);
- break;
-
- case 'f': /* pointer to a struct sigvec */
- if (bsd43_print_sigvec(arg) == -1)
- return -1;
- break;
-
- case 'g': /* setgroups() group set */
- fprintf(outfp, "{");
- {
- length = args[0];
-
- if (length < 0)
- length = 0;
-
- if (bufset((unsigned int)length * sizeof(int)) == -1)
- return -1;
-
- if (quiet_procmget(GLOBALdipc, (unsigned long)arg, sys_call_buf, length * sizeof(int)) == -1)
- return -1;
-
- {
- int i;
-
- for (i = 0; i < length; i++)
- fprintf(outfp, "%d, ", ((int *)sys_call_buf)[i]);
- }
- }
- fprintf(outfp, "}");
- break;
-
- case 'h': /* wait3 union wait */
- if (sysv_print_wait3_union_wait(arg) == -1)
- return -1;
- break;
-
- case 'i': /* wait3 options */
- if (sysv_print_wait3_options(arg) == -1)
- return -1;
- break;
-
- case 'j': /* wait3 rusage */
- if (sysv_print_wait3_rusage(arg) == -1)
- return -1;
- break;
-
- case 'k': /* times tms */
- {
- struct tms t;
- struct tms *tp;
-
- if (mget(arg, &t, sizeof(t), &tp) == -1)
- return -1;
-
- if (tp == (struct tms *)0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- fprintf(outfp, "{" /* } */);
-
- fprintf(outfp, "utime=%d,", t.tms_utime);
- fprintf(outfp, "stime=%d,", t.tms_stime);
- fprintf(outfp, "cutime=%d,", t.tms_cutime);
- fprintf(outfp, "cstime=%d,", t.tms_cstime);
-
- fprintf(outfp, /* { */ "}");
- }
-
- return 0;
- }
- break;
-
- case 'l': /* argp */
- fprintf(outfp, "{");
- if (Aflag)
- {
- if ((app = mgetvp(arg)) == (char **)0)
- return -1;
-
- for (cpp = app; *cpp != (char *)0; cpp++)
- {
- vis_string_with_quotes(outfp, *cpp);
- fprintf(outfp, ",");
- }
-
- if (mfreevp(app) == -1)
- return -1;
- }
- else
- fprintf(outfp, "..");
- fprintf(outfp, "}");
- break;
-
- case 'm': /* file creation mode */
- fprintf(outfp, "%s%o", (arg == 0) ? "" : "0", arg);
- break;
-
- case 'o': /* octal int */
- fprintf(outfp, "%s%o", (arg == 0) ? "" : "0", arg);
- break;
-
- case 'p': /* pointer */
- case 'x': /* " */
- fprintf(outfp, "0x%x", arg);
- break;
-
- case 's': /* outgoing string */
- if (direction == DIRN_EXIT)
- {
- char *cp;
-
- if (mgets(arg, &cp) == -1)
- return -1;
-
- vis_string_with_quotes(outfp, cp);
- }
- break;
-
- case 't': /* time_t */
- say_time(outfp, arg);
- break;
-
- case 'u': /* unsigned long */
- fprintf(outfp, "%lu", arg);
- break;
-
- case 'v': /* pointer to a time_t */
- if (arg == (unsigned long)0)
- fprintf(outfp, "0x%x", arg);
- else
- {
- long i;
-
- if (quiet_procmget(GLOBALdipc, arg, (char *)&i, sizeof(i)) == -1)
- return -1;
-
- fprintf(outfp, "{");
- say_time(outfp, i);
- fprintf(outfp, "}");
- }
- break;
-
- case 'w': /* lseek() whence */
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_whence(arg);
-
- case U_BSD43:
- return bsd43_print_whence(arg);
-
- case U_POSIX:
- return posix_print_whence(arg);
-
- default:
- vcouldnot("print whence from unknown universe %d", universe);
- return -1;
- }
- break;
-
- case 'y': /* sigcontext */
- switch (universe)
- {
- case U_SYSV:
- return sysv_print_sigcontext(outfp, arg);
-
- case U_BSD43:
- return bsd43_print_sigcontext(outfp, arg);
-
- case U_POSIX:
- return posix_print_sigcontext(outfp, arg);
-
- default:
- vcouldnot("print sigcontext from unknown universe %d", universe);
- return -1;
- }
- break;
-
- case '\0': /* unknown */
- default: /* " */
- fprintf(outfp, "0x%x", arg);
- break;
- }
-
- return 0;
- }
-
- static
- char *
- say_errno(e)
- int e;
- {
- if (e < 0 || e >= sys_nerrno)
- e = 0;
-
- return sys_errnolist[e];
- }
-
- static
- int
- show_syscall(universe, universe_name, current_sysentp, argp, return_value0, return_value1, return_errno, direction)
- int universe;
- char *universe_name;
- sysentry *current_sysentp;
- unsigned long *argp;
- long return_value0;
- long return_value1;
- int return_errno;
- int direction;
- {
- int i;
-
- fprintf(outfp, "%6d:", P.p_pid);
-
- fprintf(outfp, "%s_", universe_name);
-
- fprintf(outfp, "%s(", (current_sysentp->sy_name == (char *)0) ? "<unknown>" : current_sysentp->sy_name);
-
- for (i = 0; i < current_sysentp->sy_narg; i++)
- {
- if (i != 0)
- fprintf(outfp, ", ");
- if (printval(universe, argp[i], (int)current_sysentp->sy_desc[i], argp, return_value0, return_value1, direction) == -1)
- return -1;
- }
-
- fprintf(outfp, ")");
-
- if (direction == DIRN_EXIT)
- {
- fprintf(outfp, " = ");
-
- if (printval(universe, return_value0, (int)current_sysentp->sy_rdesc, argp, return_value0, return_value1, direction) == -1)
- return -1;
-
- if (return_errno != 0)
- {
- int saved_errno;
-
- saved_errno = errno;
- errno = return_errno;
- fprintf(outfp, " %s (%s)", say_errno(return_errno), sysmess());
- errno = saved_errno;
- }
- }
-
- if (Nflag)
- {
- fprintf(outfp, " [%d,%d]", instruction_count_since_last_syscall, instruction_count);
- instruction_count_since_last_syscall = 0;
- }
-
- if (Tflag)
- res_print();
-
- fprintf(outfp, "\n");
-
- return 0;
- }
-
- dinstrn *
- i_syscall(dipc, rs, rt, rd, shamt, funct)
- dinstrn *dipc;
- int rs;
- int rt;
- int rd;
- int shamt;
- int funct;
- {
- int stacki;
- unsigned long real_syscall_number;
- int syscall_number;
- int universe;
- char *universe_name;
- int argi;
- int r;
- int (*fp)();
-
- errno = 0;
-
- stacki = 0;
-
- current_sysentp = (sysentry *)0;
- universe_name = "<unknown universe>";
-
- GLOBALdipc = dipc;
-
- /*
- * Determine the system call number,
- * doing any indirection as required.
- */
- for (;;)
- {
- if (get_syscall_arg(stacki++, &real_syscall_number) == -1)
- return dipc;
-
- syscall_number = real_syscall_number % 1000;
-
- /*
- * This next test should really refer to
- * SYS_syscall
- * BSD43_SYS_syscall
- * POSIX_SYS_syscall
- * but the latter exists instead as
- * SYS_syscall
- * which would cause an embarrassing
- * name clash.
- * They all expand to 0 anyway,
- * so that's what we use.
- */
- if (syscall_number == 0)
- continue;
-
- switch (universe = real_syscall_number / 1000)
- {
- case U_SYSV:
- universe_name = "sysv";
- current_sysentp = sysv_systab_entry(syscall_number);
- break;
-
- case U_BSD43:
- universe_name = "bsd43";
- current_sysentp = bsd43_systab_entry(syscall_number);
- break;
-
- case U_POSIX:
- universe_name = "posix";
- current_sysentp = posix_systab_entry(syscall_number);
- break;
-
- case 0:
- default:
- break;
- }
-
- break;
- }
-
- if (current_sysentp == (sysentry *)0)
- {
- vcouldnot("execute unimplemented %s system call #%d", universe_name, real_syscall_number);
- return dipc;
- }
-
- if ((fp = current_sysentp->sy_call) == (int (*)())0)
- {
- vcouldnot("execute unimplemented %s system call \"%s\" [#%d]", universe_name, (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name, real_syscall_number);
- return dipc;
- }
-
- /*
- * Get the system call's arguments.
- */
- for (argi = 0; argi < current_sysentp->sy_narg; argi++)
- {
- if (get_syscall_arg(stacki++, &arg[argi]) == -1)
- return dipc;
- }
-
- /*
- * Print system call arguments before execution if desired.
- * (The 'e' kludge is for execve() and exit()...)
- */
- if (Pflag || (Sflag && current_sysentp->sy_rdesc == 'e'))
- {
- if (show_syscall(universe, universe_name, current_sysentp, &arg[0], (long)0, (long)0, 0, DIRN_ENTRY) == -1)
- return dipc;
- }
-
- /*
- * Run the system call.
- */
- switch (r = (*fp)(real_syscall_number))
- {
- case 0: /* OK */
- dipc = GLOBALdipc;
- break;
-
- case -1: /* Some internal error. */
- dipc = GLOBALdipc;
- return dipc;
-
- case -2: /* Unimpl. feature. */
- dipc = GLOBALdipc;
- if (!Pflag && !(Sflag && current_sysentp->sy_rdesc == 'e'))
- {
- if (show_syscall(universe, universe_name, current_sysentp, &arg[0], (long)0, (long)0, 0, DIRN_ENTRY) == -1)
- return dipc;
- }
-
- vcouldnot("execute unimplemented feature of %s system call \"%s\" [#%d]", universe_name, (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name, real_syscall_number);
- return dipc;
-
- case -3: /* OK, but don't copy errno/values to registers. */
- dipc = GLOBALdipc;
- break;
-
- default: /* Somebody stuffed up ... */
- dipc = GLOBALdipc;
- vcouldnot("execute %s system call \"%s\" [#%d]: unrecognised return value: %d", universe_name, (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name, real_syscall_number, r);
- return dipc;
- }
-
- if (r != -3)
- {
- /*
- * Pass back errno and return values.
- */
- if (return_errno == 0)
- {
- if (quiet_procsput(R_V0, (unsigned long)return_value0) == -1)
- return dipc;
-
- if (quiet_procsput(R_V1, (unsigned long)return_value1) == -1)
- return dipc;
-
- if (quiet_procsput(R_A3, 0) == -1)
- return dipc;
- }
- else
- {
- if (quiet_procsput(R_V0, (unsigned long)return_errno) == -1)
- return dipc;
-
- if (quiet_procsput(R_A3, 1) == -1)
- return dipc;
- }
- }
-
- /*
- * Print system call arguments and results
- * after execution if desired.
- */
- if (Sflag)
- {
- if (show_syscall(universe, universe_name, current_sysentp, &arg[0], return_value0, return_value1, return_errno, DIRN_EXIT) == -1)
- return dipc;
- }
-
- return dipc;
- }
-