home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)process.c 1.5 91/09/05
- */
-
- #include <stdio.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)) {
- fprintf(outf, "%x", tcp->u_args[0]);
- }
- return 0;
- }
-
- int
- sys_sethostname(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- printstr(tcp->pid, tcp->u_args[0], -1);
- fprintf(outf, ", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_gethostname(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- if (syserror(tcp))
- fprintf(outf, "%#x", tcp->u_args[0]);
- else
- printstr(tcp->pid, tcp->u_args[0], -1);
- fprintf(outf, ", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_getpid(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- fprintf(outf, "[ppid: %u]", getrval2(tcp->pid));
- }
- return 0;
- }
-
- int
- sys_setdomainname(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- printstr(tcp->pid, tcp->u_args[0], -1);
- fprintf(outf, ", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_getdomainname(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- if (syserror(tcp))
- fprintf(outf, "%#x", tcp->u_args[0]);
- else
- printstr(tcp->pid, tcp->u_args[0], -1);
- fprintf(outf, ", %u", tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_rexit(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- fprintf(stderr, "rexit returned!!\n");
- return -1;
- }
- /* special case: we stop tracing this process, finish line now */
- fprintf(outf, "%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)
- clearbpt(tcp);
-
- if (syserror(tcp))
- return 0;
-
- pid = tcp->u_rval;
- if ((tcpchild = alloctcb(pid)) == NULLTCB) {
- fprintf(stderr, " [tcb table full]\n");
- /* XXX */kill(pid, SIGKILL);
- return 0;
- }
- if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
- perror("PTRACE_ATTACH");
- fprintf(stderr, " - Too late?\n");
- /* XXX */kill(pid, SIGKILL);
- 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(tcp->inst, tcpchild->inst, sizeof tcpchild->inst);
- }
- newoutf(tcpchild);
- tcpchild->parent = tcp;
- tcp->nchildren++;
- 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;
- }
-
- int
- sys_getuid(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- fprintf(outf, "[euid %u]", getrval2(tcp->pid));
- }
- return 0;
- }
-
- int
- sys_getgid(tcp)
- struct tcb *tcp;
- {
- if (exiting(tcp)) {
- fprintf(outf, "[egid %u]", getrval2(tcp->pid));
- }
- return 0;
- }
-
- int
- sys_setreuid(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- fprintf(outf, "%u, %u", tcp->u_args[0], tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_setregid(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- fprintf(outf, "%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];
- fprintf(outf, "%u, [", len);
- if ((gidset = (int *)malloc(len * sizeof(int))) == NULL) {
- fprintf(stderr, " [Out of memory]\n");
- return -1;
- }
- umove(tcp->pid, tcp->u_args[1], len * sizeof(int), (char *)gidset);
- for (i = 0; i < len; i++)
- fprintf(outf, " %u", gidset[i]);
- fprintf(outf, "]", 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];
- fprintf(outf, "%u, [", len);
- } else {
- len = tcp->u_rval;
- if ((gidset = (int *)malloc(len * sizeof(int))) == NULL) {
- fprintf(stderr, " [Out of memory]\n");
- return -1;
- }
- umove(tcp->pid, tcp->u_args[1], len * sizeof(int), (char *)gidset);
- for (i = 0; i < len; i++)
- fprintf(outf, " %u", gidset[i]);
- fprintf(outf, "]", gidset[i]);
- free((char *)gidset);
- }
- return 0;
- }
-
- int
- sys_setpgrp(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- fprintf(outf, "%u, %u", tcp->u_args[0], tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_getpgrp(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- fprintf(outf, "%u", tcp->u_args[0]);
- }
- return 0;
- }
-
- int
- sys_setpgid(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- fprintf(outf, "%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 *);
- }
- }
-
- int
- sys_execv(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- printstr(tcp->pid, tcp->u_args[0], -1);
- fprintf(outf, ", ");
- printargv(tcp->pid, tcp->u_args[1]);
- }
- return 0;
- }
-
- int
- sys_execve(tcp)
- struct tcb *tcp;
- {
- int cp, addr;
-
- if (entering(tcp)) {
- printstr(tcp->pid, tcp->u_args[0], -1);
- fprintf(outf, ", ");
- printargv(tcp->pid, tcp->u_args[1]);
- fprintf(outf, ", env: [");
- printargv(tcp->pid, tcp->u_args[2]);
- fprintf(outf, "]");
- }
- return 0;
- }
-
- static Xlat wait4_options[] = {
- WNOHANG, "NOHANG",
- WUNTRACED, "UNTRACED",
- 0, NULL,
- };
-
- int
- sys_wait4(tcp)
- struct tcb *tcp;
- {
- int options, status;
- struct rusage rusage;
-
- if (entering(tcp)) {
- fprintf(outf, "%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 (tcp->u_rval == 0 || tcp->u_error) {
- fprintf(outf, "%x, %x, %x", tcp->u_args[1],
- tcp->u_args[2], tcp->u_args[3]);
- return 0;
- }
- /* status */
- if (tcp->u_args[1]) {
- umove(tcp->pid, tcp->u_args[1], sizeof status,
- (char *)&status);
- if (WIFSTOPPED(status))
- fprintf(outf, "STOPPED(%s), ",
- signals[WSTOPSIG(status)]+3);
- else if WIFSIGNALED(status)
- fprintf(outf, "SIGNALED(%s), ",
- signals[WTERMSIG(status)]+3);
- else if WIFEXITED(status)
- fprintf(outf, "EXITED(%d), ",
- WEXITSTATUS(status));
- } else
- fprintf(outf, "(struct int *)0, ");
- /* options */
- if (!printflags(wait4_options, tcp->u_args[2]))
- putc('0', outf);
- /* usage */
- if (tcp->u_args[3]) {
- umove(tcp->pid, tcp->u_args[3], sizeof rusage,
- (char *)&rusage);
- fprintf(outf, ", {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);
- } else
- fprintf(outf, ", (struct rusage *)0");
- }
- return 0;
- }
-
- int
- sys_uname(tcp)
- struct tcb *tcp;
- {
- struct utsname uname;
-
- if (exiting(tcp)) {
- umove(tcp->pid, tcp->u_args[0], sizeof uname, (char *)&uname);
- fprintf(outf, "{%s, %s, %s, %s, %s, %s}",
- uname.sysname, uname.nodename,
- uname.nodeext, uname.release,
- uname.version, uname.machine);
- }
- return 0;
- }
-
- static Xlat ptrace_cmds[] = {
- PTRACE_TRACEME, "TRACEME", /* 0, by tracee to begin tracing */
- PTRACE_PEEKTEXT,"PEEKTEXT", /* 1, read word from text segment */
- PTRACE_PEEKDATA,"PEEKDATA", /* 2, read word from data segment */
- PTRACE_PEEKUSER,"PEEKUSER", /* 3, read word from user struct */
- PTRACE_POKETEXT,"POKETEXT", /* 4, write word into text segment */
- PTRACE_POKEDATA,"POKEDATA", /* 5, write word into data segment */
- PTRACE_POKEUSER,"POKEUSER", /* 6, write word into user struct */
- PTRACE_CONT, "CONT", /* 7, continue process */
- PTRACE_KILL, "KILL", /* 8, terminate process */
- PTRACE_SINGLESTEP, "SINGLESTEP", /* 9, single step process */
- PTRACE_ATTACH, "ATTACH", /* 10, attach to an existing process */
- PTRACE_DETACH, "DETACH", /* 11, detach from a process */
- PTRACE_GETREGS, "GETREGS", /* 12, get all registers */
- PTRACE_SETREGS, "SETREGS", /* 13, set all registers */
- PTRACE_GETFPREGS,"GETFPREGS", /* 14, get all floating point regs */
- PTRACE_SETFPREGS,"SETFPREGS", /* 15, set all floating point regs */
- PTRACE_READDATA, "READDATA", /* 16, read data segment */
- PTRACE_WRITEDATA, "WRITEDATA", /* 17, write data segment */
- PTRACE_READTEXT, "READTEXT", /* 18, read text segment */
- PTRACE_WRITETEXT, "WRITETEXT", /* 19, write text segment */
- PTRACE_GETFPAREGS, "GETFPAREGS", /* 20, get all fpa regs */
- PTRACE_SETFPAREGS, "SETFPAREGS", /* 21, set all fpa regs */
- #ifdef sparc
- /* currently unimplemented */
- PTRACE_GETWINDOW, "GETWINDOW", /* 22, get register window n */
- PTRACE_SETWINDOW, "SETWINDOW", /* 23, set register window n */
- #else !sparc
- PTRACE_22, "PTRACE_22", /* 22, filler */
- PTRACE_23, "PTRACE_23", /* 23, filler */
- #endif !sparc
- PTRACE_SYSCALL, "SYSCALL", /* 24, trap next sys call */
- PTRACE_DUMPCORE, "DUMPCORE", /* 25, dump process core */
- #ifdef i386
- PTRACE_SETWRBKPT, "SETWRBKPT", /* 26, set write breakpoint */
- PTRACE_SETACBKPT, "SETACBKPT", /* 27, set access breakpoint */
- PTRACE_CLRDR7, "CLRDR7", /* 28, clear debug register 7 */
- #else
- PTRACE_26, "PTRACE_26", /* 26, filler */
- PTRACE_27, "PTRACE_27", /* 27, filler */
- PTRACE_28, "PTRACE_28", /* 28, filler */
- #endif
- 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;
- {
- char *cmd;
- Xlat *x;
- int addr;
-
- cmd = xlookup(ptrace_cmds, tcp->u_args[0]);
- if (!cmd) cmd = "PTRACE_???";
- if (entering(tcp)) {
- fprintf(outf, "%s, %u, ", cmd, tcp->u_args[1]);
- addr = tcp->u_args[2];
- if (tcp->u_args[0] == PTRACE_PEEKUSER) {
- for (x = u; x->str; x++) {
- if (x->val >= addr)
- break;
- }
- if (x->val > addr && x != u) {
- x--;
- fprintf(outf, "%s[%x], ",
- x->str, addr - x->val);
- } else {
- fprintf(outf, "%s, ", x->str);
- }
- } else {
- fprintf(outf, "%#x, ", tcp->u_args[2]);
- }
- if (tcp->u_args[0] == PTRACE_WRITEDATA ||
- tcp->u_args[0] == PTRACE_WRITETEXT) {
- fprintf(outf, "%u, ", tcp->u_args[3]);
- printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
- } else if (tcp->u_args[0] != PTRACE_READDATA &&
- tcp->u_args[0] != PTRACE_READTEXT) {
- fprintf(outf, "%#x", tcp->u_args[3]);
- }
- } else {
- if (tcp->u_args[0] == PTRACE_READDATA ||
- tcp->u_args[0] == PTRACE_READTEXT) {
- fprintf(outf, "%u, ", tcp->u_args[3]);
- printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
- }
- }
- return 0;
- }
-
-