123385Smckusick /* 229105Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323385Smckusick * All rights reserved. The Berkeley software License Agreement 423385Smckusick * specifies the terms and conditions for redistribution. 523385Smckusick * 6*29946Skarels * @(#)sys_process.c 7.2 (Berkeley) 11/03/86 723385Smckusick */ 87426Sroot 99759Ssam #include "../machine/reg.h" 109759Ssam #include "../machine/psl.h" 119759Ssam #include "../machine/pte.h" 129759Ssam 1317095Sbloom #include "param.h" 1417095Sbloom #include "systm.h" 1517095Sbloom #include "dir.h" 1617095Sbloom #include "user.h" 1717095Sbloom #include "proc.h" 1817095Sbloom #include "inode.h" 1917095Sbloom #include "text.h" 2017095Sbloom #include "seg.h" 2117095Sbloom #include "vm.h" 2217095Sbloom #include "buf.h" 2317095Sbloom #include "acct.h" 2426278Skarels #include "ptrace.h" 257426Sroot 267501Sroot /* 277501Sroot * Priority for tracing 287501Sroot */ 297501Sroot #define IPCPRI PZERO 307501Sroot 317501Sroot /* 327501Sroot * Tracing variables. 337501Sroot * Used to pass trace command from 347501Sroot * parent to child being traced. 357501Sroot * This data base cannot be 367501Sroot * shared and is locked 377501Sroot * per user. 387501Sroot */ 397501Sroot struct { 407501Sroot int ip_lock; 417501Sroot int ip_req; 427501Sroot int *ip_addr; 437501Sroot int ip_data; 447501Sroot } ipc; 457501Sroot 467501Sroot /* 477501Sroot * sys-trace system call. 487501Sroot */ 497501Sroot ptrace() 507501Sroot { 517501Sroot register struct proc *p; 527501Sroot register struct a { 537501Sroot int req; 547501Sroot int pid; 557501Sroot int *addr; 567501Sroot int data; 577501Sroot } *uap; 587501Sroot 597501Sroot uap = (struct a *)u.u_ap; 607501Sroot if (uap->req <= 0) { 617501Sroot u.u_procp->p_flag |= STRC; 627501Sroot return; 637501Sroot } 647501Sroot p = pfind(uap->pid); 6512496Ssam if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid || 6612496Ssam !(p->p_flag & STRC)) { 677501Sroot u.u_error = ESRCH; 687501Sroot return; 697501Sroot } 707501Sroot while (ipc.ip_lock) 717501Sroot sleep((caddr_t)&ipc, IPCPRI); 727501Sroot ipc.ip_lock = p->p_pid; 737501Sroot ipc.ip_data = uap->data; 747501Sroot ipc.ip_addr = uap->addr; 757501Sroot ipc.ip_req = uap->req; 767501Sroot p->p_flag &= ~SWTED; 777501Sroot while (ipc.ip_req > 0) { 787501Sroot if (p->p_stat==SSTOP) 797501Sroot setrun(p); 807501Sroot sleep((caddr_t)&ipc, IPCPRI); 817501Sroot } 827501Sroot u.u_r.r_val1 = ipc.ip_data; 837501Sroot if (ipc.ip_req < 0) 847501Sroot u.u_error = EIO; 857501Sroot ipc.ip_lock = 0; 867501Sroot wakeup((caddr_t)&ipc); 877501Sroot } 887501Sroot 8926278Skarels #if defined(vax) 908952Sroot #define NIPCREG 16 918952Sroot int ipcreg[NIPCREG] = 928952Sroot {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; 938952Sroot #endif 94*29946Skarels #if defined(tahoe) 95*29946Skarels #define NIPCREG 18 96*29946Skarels int ipcreg[NIPCREG] = 97*29946Skarels {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,FP,SP,PC,RACH,RACL}; 98*29946Skarels #endif 998952Sroot 1008953Sroot #define PHYSOFF(p, o) \ 1018952Sroot ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0]))) 1028952Sroot 1037501Sroot /* 1047501Sroot * Code that the child process 1057501Sroot * executes to implement the command 1067501Sroot * of the parent process in tracing. 1077501Sroot */ 1087501Sroot procxmt() 1097501Sroot { 1107501Sroot register int i; 1117501Sroot register *p; 1127501Sroot register struct text *xp; 1137501Sroot 1147501Sroot if (ipc.ip_lock != u.u_procp->p_pid) 1157501Sroot return (0); 1167501Sroot u.u_procp->p_slptime = 0; 1177501Sroot i = ipc.ip_req; 1187501Sroot ipc.ip_req = 0; 1197501Sroot switch (i) { 1207501Sroot 12126278Skarels case PT_READ_I: /* read the child's text space */ 1227501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1237501Sroot goto error; 1247501Sroot ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); 1257501Sroot break; 1267501Sroot 12726278Skarels case PT_READ_D: /* read the child's data space */ 1287501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1297501Sroot goto error; 1307501Sroot ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 1317501Sroot break; 1327501Sroot 13326278Skarels case PT_READ_U: /* read the child's u. */ 1347501Sroot i = (int)ipc.ip_addr; 1357501Sroot if (i<0 || i >= ctob(UPAGES)) 1367501Sroot goto error; 1378952Sroot ipc.ip_data = *(int *)PHYSOFF(&u, i); 1387501Sroot break; 1397501Sroot 14026278Skarels case PT_WRITE_I: /* write the child's text space */ 1417501Sroot /* 1427501Sroot * If text, must assure exclusive use 1437501Sroot */ 1447501Sroot if (xp = u.u_procp->p_textp) { 1457501Sroot if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 1467501Sroot goto error; 14725535Skarels xp->x_flag |= XTRC; 1487501Sroot } 1497501Sroot i = -1; 1508952Sroot if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) { 1518952Sroot if (chgprot((caddr_t)ipc.ip_addr, RW) && 1528952Sroot chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 1538952Sroot i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 1548952Sroot (void) chgprot((caddr_t)ipc.ip_addr, RO); 1558952Sroot (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 1568952Sroot } 1577501Sroot if (i < 0) 1587501Sroot goto error; 159*29946Skarels #if defined(tahoe) 160*29946Skarels /* make sure the old value is not in cache */ 161*29946Skarels ckeyrelease(u.u_procp->p_ckey); 162*29946Skarels u.u_procp->p_ckey = getcodekey(); 163*29946Skarels #endif 164*29946Skarels if (xp) { 1657501Sroot xp->x_flag |= XWRIT; 166*29946Skarels #if defined(tahoe) 167*29946Skarels xp->x_ckey = u.u_procp->p_ckey; 168*29946Skarels #endif 169*29946Skarels } 1707501Sroot break; 1717501Sroot 17226278Skarels case PT_WRITE_D: /* write the child's data space */ 1737501Sroot if (suword((caddr_t)ipc.ip_addr, 0) < 0) 1747501Sroot goto error; 1757501Sroot (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 1767501Sroot break; 1777501Sroot 17826278Skarels case PT_WRITE_U: /* write the child's u. */ 1797501Sroot i = (int)ipc.ip_addr; 1808952Sroot p = (int *)PHYSOFF(&u, i); 1818952Sroot for (i=0; i<NIPCREG; i++) 1827501Sroot if (p == &u.u_ar0[ipcreg[i]]) 1837501Sroot goto ok; 1847501Sroot if (p == &u.u_ar0[PS]) { 1858952Sroot ipc.ip_data |= PSL_USERSET; 1867501Sroot ipc.ip_data &= ~PSL_USERCLR; 1877501Sroot goto ok; 1887501Sroot } 1897501Sroot goto error; 1907501Sroot 1917501Sroot ok: 1927501Sroot *p = ipc.ip_data; 1937501Sroot break; 1947501Sroot 19526278Skarels case PT_STEP: /* single step the child */ 19626278Skarels case PT_CONTINUE: /* continue the child */ 1977501Sroot if ((int)ipc.ip_addr != 1) 1987501Sroot u.u_ar0[PC] = (int)ipc.ip_addr; 1997501Sroot if ((unsigned)ipc.ip_data > NSIG) 2007501Sroot goto error; 2017501Sroot u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 20226278Skarels if (i == PT_STEP) 2037501Sroot u.u_ar0[PS] |= PSL_T; 2047501Sroot wakeup((caddr_t)&ipc); 2057501Sroot return (1); 2067501Sroot 20726278Skarels case PT_KILL: /* kill the child process */ 2087501Sroot wakeup((caddr_t)&ipc); 2097501Sroot exit(u.u_procp->p_cursig); 2107501Sroot 2117501Sroot default: 2127501Sroot error: 2137501Sroot ipc.ip_req = -1; 2147501Sroot } 2157501Sroot wakeup((caddr_t)&ipc); 2167501Sroot return (0); 2177501Sroot } 218