home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)process.c 2.3 92/01/10
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ptrace.h>
- #include <sys/file.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/wait.h>
- #include <sys/resource.h>
- #include <sys/utsname.h>
- #include <sys/ptrace.h>
- #include <sys/user.h>
- #include <machine/reg.h>
-
- #include "defs.h"
-
- int
- sys_gethostid(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- return RVAL_HEX;
- }
- return 0;
- }
-
- int
- sys_sethostname(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- (void)printstr(tcp->pid, tcp->u_args[0], -1);
- tprintf(", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_gethostname(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- if (syserror(tcp))
- tprintf("%#x", tcp->u_args[0]);
- else
- (void)printstr(tcp->pid, tcp->u_args[0], -1);
- tprintf(", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_getpid(tcp)
- struct tcb *tcp;
- {
- static char ppid[16];
-
- if (exiting(tcp)) {
- (void)sprintf(ppid, "[ppid: %u]", getrval2(tcp->pid));
- tcp->auxstr = ppid;
- return RVAL_STR;
- }
- return 0;
- }
-
- int
- sys_setdomainname(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- (void)printstr(tcp->pid, tcp->u_args[0], -1);
- tprintf(", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_getdomainname(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- if (syserror(tcp))
- tprintf("%#x", tcp->u_args[0]);
- else
- (void)printstr(tcp->pid, tcp->u_args[0], -1);
- tprintf(", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_rexit(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- (void)fprintf(stderr, "rexit returned!!\n");
- return -1;
- }
- /* special case: we stop tracing this process, finish line now */
- tprintf("%d) = ?\n", tcp->u_args[0]);
- tcp->flags |= TCB_EXITING;
- return 0;
- }
-
- static int vforking;
-
- int
- sys_fork(tcp)
- struct tcb *tcp;
- {
- int pid;
- struct tcb *tcpchild;
-
- if (entering(tcp)) {
- if (!followfork || vforking)
- return 0;
- if (setbpt(tcp) < 0)
- return 0;
- } else {
- int bpt = tcp->flags & TCB_BPTSET;
-
- if (!followfork)
- return 0;
- if (bpt)
- (void)clearbpt(tcp);
-
- if (syserror(tcp))
- return 0;
-
- pid = tcp->u_rval;
- if ((tcpchild = alloctcb(pid)) == NULLTCB) {
- (void)fprintf(stderr, " [tcb table full]\n");
- (void)kill(pid, SIGKILL);
- return -1;
- }
- if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
- perror("PTRACE_ATTACH");
- (void)fprintf(stderr, " - Too late?\n");
- droptcb(tcpchild);
- return 0;
- }
- tcpchild->flags |= TCB_ATTACHED;
- /* Child has BPT too, must be removed on first occasion */
- if (bpt) {
- tcpchild->flags |= TCB_BPTSET;
- tcpchild->baddr = tcp->baddr;
- bcopy((char *)tcp->inst, (char *)tcpchild->inst,
- sizeof tcpchild->inst);
- }
- newoutf(tcpchild);
- tcpchild->parent = tcp;
- tcp->nchildren++;
- (void)fprintf(stderr, "Process %u attached\n", pid);
- }
- return 0;
- }
-
- int
- sys_vfork(tcp)
- struct tcb *tcp;
- {
- /* XXX - cannot use the same trick for vfork */
- int res;
-
- vforking = 1;
- res = sys_fork(tcp);
- vforking = 0;
- return res;
- }
-
- static char eid[16];
-
- int
- sys_getuid(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- (void)sprintf(eid, "[euid %u]", getrval2(tcp->pid));
- tcp->auxstr = eid;
- return RVAL_STR;
- }
- return 0;
- }
-
- int
- sys_getgid(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- (void)sprintf(eid, "[egid %u]", getrval2(tcp->pid));
- tcp->auxstr = eid;
- return RVAL_STR;
- }
- return 0;
- }
-
- int
- sys_setreuid(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_setregid(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_setgroups(tcp)
- struct tcb *tcp;
- {
- int i, len, *gidset;
-
- if (entering(tcp)) {
- len = tcp->u_args[0];
- tprintf("%u, ", len);
- if ((gidset = (int *)malloc((unsigned)len * sizeof(int))) == NULL) {
- (void)fprintf(stderr, " [Out of memory]\n");
- return -1;
- }
- if (umove(tcp->pid, tcp->u_args[1],
- len * sizeof(int), (char *)gidset) < 0) {
- tprintf("%#x", tcp->u_args[1]);
- } else {
- tprintf("[");
- for (i = 0; i < len; i++)
- tprintf(" %u", gidset[i]);
- tprintf("]", gidset[i]);
- }
- free((char *)gidset);
- }
- return 0;
- }
-
- int
- sys_getgroups(tcp)
- struct tcb *tcp;
- {
- int i, len, *gidset;
-
- if (entering(tcp)) {
- len = tcp->u_args[0];
- tprintf("%u, ", len);
- } else {
- len = tcp->u_rval;
- if ((gidset = (int *)malloc((unsigned)len * sizeof(int))) == NULL) {
- (void)fprintf(stderr, " [Out of memory]\n");
- return -1;
- }
- if (umove(tcp->pid, tcp->u_args[1],
- len * sizeof(int), (char *)gidset) < 0) {
- tprintf("%#x", tcp->u_args[1]);
- } else {
- tprintf("[");
- for (i = 0; i < len; i++)
- tprintf(" %u", gidset[i]);
- tprintf("]", gidset[i]);
- }
- free((char *)gidset);
- }
- return 0;
- }
-
- int
- sys_setpgrp(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_getpgrp(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- tprintf("%u", tcp->u_args[0]);
- }
- return 0;
- }
-
- int
- sys_setpgid(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
- }
- return 0;
- }
-
- static
- printargv(pid, addr)
- {
- int cp;
-
- while(1) {
- if (umove(pid, addr, sizeof(char *), (char *)&cp) < 0)
- return -1;
- if (cp == 0)
- break;
- if (printstr(pid, cp, -1) < 0)
- return -1;
- addr += sizeof(char *);
- }
- return 0;
- }
-
- int
- sys_execv(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- (void)printstr(tcp->pid, tcp->u_args[0], -1);
- tprintf(", ");
- (void)printargv(tcp->pid, tcp->u_args[1]);
- } else {
- if (!syserror(tcp) && followfork)
- (void)fixvfork(tcp->pid);
- }
- return 0;
- }
-
- int
- sys_execve(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- (void)printstr(tcp->pid, tcp->u_args[0], -1);
- (void)tprintf(", ");
- (void)printargv(tcp->pid, tcp->u_args[1]);
- tprintf(", env: [");
- if (verbose)
- (void)printargv(tcp->pid, tcp->u_args[2]);
- else
- tprintf("%#x", tcp->u_args[2]);
- tprintf("]");
- } else {
- if (!syserror(tcp) && followfork)
- (void)fixvfork(tcp->pid);
- }
- return 0;
- }
-
- static Xlat wait4_options[] = {
- WNOHANG, "NOHANG",
- WUNTRACED, "UNTRACED",
- 0, NULL,
- };
-
- int
- sys_wait4(tcp)
- struct tcb *tcp;
- {
- int status;
- struct rusage rusage;
-
- if (entering(tcp)) {
- tprintf("%d, ", tcp->u_args[0]);
- if (tcp->nchildren > 0) /* There are traced children */ {
- tcp->flags |= TCB_SUSPENDED;
- tcp->waitpid = tcp->u_args[0];
- }
- } else {
- if (syserror(tcp) || tcp->u_rval == 0) {
- tprintf("%x, ", tcp->u_args[1]);
- if (!printflags(wait4_options, tcp->u_args[2]))
- tprintf("0");
- tprintf(", %x", tcp->u_args[3]);
- return 0;
- }
- /* status */
- if (tcp->u_args[1] == 0 ||
- umove(tcp->pid, tcp->u_args[1],
- sizeof status, (char *)&status) < 0)
- tprintf("(struct int *)0, ");
- else {
- if (WIFSTOPPED(status))
- tprintf("STOPPED(%s), ",
- signals[WSTOPSIG(status)]+3);
- else if WIFSIGNALED(status)
- tprintf("SIGNALED(%s), ",
- signals[WTERMSIG(status)]+3);
- else if WIFEXITED(status)
- tprintf("EXITED(%d), ",
- WEXITSTATUS(status));
- }
- /* options */
- if (!printflags(wait4_options, tcp->u_args[2]))
- tprintf("0");
- /* usage */
- if (tcp->u_args[3] == 0 ||
- umove(tcp->pid, tcp->u_args[3],
- sizeof rusage, (char *)&rusage) < 0)
- tprintf(", (struct rusage *)0");
- else
- tprintf(", {stime %u,%u utime %u,%u ...}",
- rusage.ru_stime.tv_sec, rusage.ru_stime.tv_usec,
- rusage.ru_utime.tv_sec, rusage.ru_utime.tv_usec);
- }
- return 0;
- }
-
- int
- sys_uname(tcp)
- struct tcb *tcp;
- {
- struct utsname uname;
-
- if (exiting(tcp)) {
- if (umove(tcp->pid, tcp->u_args[0],
- sizeof uname, (char *)&uname) < 0)
- tprintf("%#x", tcp->u_args[0]);
- else
- tprintf("{%s, %s, %s, %s, %s, %s}",
- uname.sysname, uname.nodename,
- uname.nodeext, uname.release,
- uname.version, uname.machine);
- }
- return 0;
- }
-
- static Xlat ptrace_cmds[] = {
- (int)PTRACE_TRACEME,"TRACEME", /* 0, by tracee to begin tracing */
- (int)PTRACE_PEEKTEXT,"PEEKTEXT",/* 1, read word from text segment */
- (int)PTRACE_PEEKDATA,"PEEKDATA",/* 2, read word from data segment */
- (int)PTRACE_PEEKUSER,"PEEKUSER",/* 3, read word from user struct */
- (int)PTRACE_POKETEXT,"POKETEXT",/* 4, write word into text segment */
- (int)PTRACE_POKEDATA,"POKEDATA", /* 5, write word into data segment */
- (int)PTRACE_POKEUSER,"POKEUSER", /* 6, write word into user struct */
- (int)PTRACE_CONT, "CONT", /* 7, continue process */
- (int)PTRACE_KILL, "KILL", /* 8, terminate process */
- (int)PTRACE_SINGLESTEP, "SINGLESTEP", /* 9, single step process */
- (int)PTRACE_ATTACH, "ATTACH", /* 10, attach to an existing process */
- (int)PTRACE_DETACH, "DETACH", /* 11, detach from a process */
- (int)PTRACE_GETREGS, "GETREGS", /* 12, get all registers */
- (int)PTRACE_SETREGS, "SETREGS", /* 13, set all registers */
- (int)PTRACE_GETFPREGS,"GETFPREGS", /* 14, get all floating point regs */
- (int)PTRACE_SETFPREGS,"SETFPREGS", /* 15, set all floating point regs */
- (int)PTRACE_READDATA, "READDATA", /* 16, read data segment */
- (int)PTRACE_WRITEDATA, "WRITEDATA", /* 17, write data segment */
- (int)PTRACE_READTEXT, "READTEXT", /* 18, read text segment */
- (int)PTRACE_WRITETEXT, "WRITETEXT", /* 19, write text segment */
- (int)PTRACE_GETFPAREGS, "GETFPAREGS", /* 20, get all fpa regs */
- (int)PTRACE_SETFPAREGS, "SETFPAREGS", /* 21, set all fpa regs */
- #ifdef sparc
- /* currently unimplemented */
- (int)PTRACE_GETWINDOW, "GETWINDOW", /* 22, get register window n */
- (int)PTRACE_SETWINDOW, "SETWINDOW", /* 23, set register window n */
- #else !sparc
- (int)PTRACE_22, "PTRACE_22", /* 22, filler */
- (int)PTRACE_23, "PTRACE_23", /* 23, filler */
- #endif !sparc
- (int)PTRACE_SYSCALL, "SYSCALL", /* 24, trap next sys call */
- (int)PTRACE_DUMPCORE, "DUMPCORE", /* 25, dump process core */
- #ifdef i386
- (int)PTRACE_SETWRBKPT, "SETWRBKPT", /* 26, set write breakpoint */
- (int)PTRACE_SETACBKPT, "SETACBKPT", /* 27, set access breakpoint */
- (int)PTRACE_CLRDR7, "CLRDR7", /* 28, clear debug register 7 */
- #else
- (int)PTRACE_26, "PTRACE_26", /* 26, filler */
- (int)PTRACE_27, "PTRACE_27", /* 27, filler */
- (int)PTRACE_28, "PTRACE_28", /* 28, filler */
- #endif
- (int)PTRACE_GETUCODE, "PTRACE_GETUCODE", /* 29, get u.u_code */
- 0, NULL,
- };
-
-
- static Xlat u[] = {
- uoff(u_pcb), "u_pcb",
- uoff(u_procp), "u_procp",
- uoff(u_ar0), "u_ar0",
- uoff(u_comm[0]), "u_comm",
- uoff(u_arg[0]), "u_arg",
- uoff(u_ap), "u_ap",
- uoff(u_qsave), "u_qsave",
- uoff(u_rval1), "u_rval1",
- uoff(u_rval2), "u_rval2",
- uoff(u_error), "u_error",
- uoff(u_eosys), "u_eosys",
- uoff(u_ssave), "u_ssave",
- uoff(u_signal[0]), "u_signal",
- uoff(u_sigmask[0]), "u_sigmask",
- uoff(u_sigonstack), "u_sigonstack",
- uoff(u_sigintr), "u_sigintr",
- uoff(u_sigreset), "u_sigreset",
- uoff(u_oldmask), "u_oldmask",
- uoff(u_code), "u_code",
- uoff(u_addr), "u_addr",
- uoff(u_sigstack), "u_sigstack",
- uoff(u_ofile), "u_ofile",
- uoff(u_pofile), "u_pofile",
- uoff(u_ofile_arr[0]), "u_ofile_arr",
- uoff(u_pofile_arr[0]), "u_pofile_arr",
- uoff(u_lastfile), "u_lastfile",
- uoff(u_cwd), "u_cwd",
- uoff(u_cdir), "u_cdir",
- uoff(u_rdir), "u_rdir",
- uoff(u_cmask), "u_cmask",
- uoff(u_ru), "u_ru",
- uoff(u_cru), "u_cru",
- uoff(u_timer[0]), "u_timer",
- uoff(u_XXX[0]), "u_XXX",
- uoff(u_ioch), "u_ioch",
- uoff(u_start), "u_start",
- uoff(u_acflag), "u_acflag",
- uoff(u_prof.pr_base), "u_prof.pr_base",
- uoff(u_prof.pr_size), "u_prof.pr_size",
- uoff(u_prof.pr_off), "u_prof.pr_off",
- uoff(u_prof.pr_scale), "u_prof.pr_scale",
- uoff(u_rlimit[0]), "u_rlimit",
- uoff(u_exdata.Ux_A), "u_exdata.Ux_A",
- uoff(u_exdata.ux_shell[0]), "u_exdata.ux_shell",
- uoff(u_lofault), "u_lofault",
- 0, NULL,
- };
-
- int
- sys_ptrace(tcp)
- struct tcb *tcp;
- {
- Xlat *x;
- int addr;
-
- if (entering(tcp)) {
- printxval(ptrace_cmds, tcp->u_args[0], "PTRACE_???");
- tprintf(", %u, ", tcp->u_args[1]);
- addr = tcp->u_args[2];
- if (tcp->u_args[0] == (int)PTRACE_PEEKUSER) {
- for (x = u; x->str; x++) {
- if (x->val >= addr)
- break;
- }
- if (x->val > addr && x != u) {
- x--;
- tprintf("%s[%x], ",
- x->str, addr - x->val);
- } else {
- tprintf("%s, ", x->str);
- }
- } else {
- tprintf("%#x, ", tcp->u_args[2]);
- }
- if (tcp->u_args[0] == (int)PTRACE_WRITEDATA ||
- tcp->u_args[0] == (int)PTRACE_WRITETEXT) {
- tprintf("%u, ", tcp->u_args[3]);
- (void)printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
- } else if (tcp->u_args[0] != (int)PTRACE_READDATA &&
- tcp->u_args[0] != (int)PTRACE_READTEXT) {
- tprintf("%#x", tcp->u_args[3]);
- }
- } else {
- if (tcp->u_args[0] == (int)PTRACE_READDATA ||
- tcp->u_args[0] == (int)PTRACE_READTEXT) {
- tprintf("%u, ", tcp->u_args[3]);
- (void)printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
- }
- }
- return 0;
- }
-
-