123385Smckusick /* 2*29105Smckusick * 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*29105Smckusick * @(#)sys_process.c 7.1 (Berkeley) 06/05/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 948952Sroot 958953Sroot #define PHYSOFF(p, o) \ 968952Sroot ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0]))) 978952Sroot 987501Sroot /* 997501Sroot * Code that the child process 1007501Sroot * executes to implement the command 1017501Sroot * of the parent process in tracing. 1027501Sroot */ 1037501Sroot procxmt() 1047501Sroot { 1057501Sroot register int i; 1067501Sroot register *p; 1077501Sroot register struct text *xp; 1087501Sroot 1097501Sroot if (ipc.ip_lock != u.u_procp->p_pid) 1107501Sroot return (0); 1117501Sroot u.u_procp->p_slptime = 0; 1127501Sroot i = ipc.ip_req; 1137501Sroot ipc.ip_req = 0; 1147501Sroot switch (i) { 1157501Sroot 11626278Skarels case PT_READ_I: /* read the child's text space */ 1177501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1187501Sroot goto error; 1197501Sroot ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); 1207501Sroot break; 1217501Sroot 12226278Skarels case PT_READ_D: /* read the child's data space */ 1237501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1247501Sroot goto error; 1257501Sroot ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 1267501Sroot break; 1277501Sroot 12826278Skarels case PT_READ_U: /* read the child's u. */ 1297501Sroot i = (int)ipc.ip_addr; 1307501Sroot if (i<0 || i >= ctob(UPAGES)) 1317501Sroot goto error; 1328952Sroot ipc.ip_data = *(int *)PHYSOFF(&u, i); 1337501Sroot break; 1347501Sroot 13526278Skarels case PT_WRITE_I: /* write the child's text space */ 1367501Sroot /* 1377501Sroot * If text, must assure exclusive use 1387501Sroot */ 1397501Sroot if (xp = u.u_procp->p_textp) { 1407501Sroot if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 1417501Sroot goto error; 14225535Skarels xp->x_flag |= XTRC; 1437501Sroot } 1447501Sroot i = -1; 1458952Sroot if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) { 1468952Sroot if (chgprot((caddr_t)ipc.ip_addr, RW) && 1478952Sroot chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 1488952Sroot i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 1498952Sroot (void) chgprot((caddr_t)ipc.ip_addr, RO); 1508952Sroot (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 1518952Sroot } 1527501Sroot if (i < 0) 1537501Sroot goto error; 1547501Sroot if (xp) 1557501Sroot xp->x_flag |= XWRIT; 1567501Sroot break; 1577501Sroot 15826278Skarels case PT_WRITE_D: /* write the child's data space */ 1597501Sroot if (suword((caddr_t)ipc.ip_addr, 0) < 0) 1607501Sroot goto error; 1617501Sroot (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 1627501Sroot break; 1637501Sroot 16426278Skarels case PT_WRITE_U: /* write the child's u. */ 1657501Sroot i = (int)ipc.ip_addr; 1668952Sroot p = (int *)PHYSOFF(&u, i); 1678952Sroot for (i=0; i<NIPCREG; i++) 1687501Sroot if (p == &u.u_ar0[ipcreg[i]]) 1697501Sroot goto ok; 1707501Sroot if (p == &u.u_ar0[PS]) { 1718952Sroot ipc.ip_data |= PSL_USERSET; 1727501Sroot ipc.ip_data &= ~PSL_USERCLR; 1737501Sroot goto ok; 1747501Sroot } 1757501Sroot goto error; 1767501Sroot 1777501Sroot ok: 1787501Sroot *p = ipc.ip_data; 1797501Sroot break; 1807501Sroot 18126278Skarels case PT_STEP: /* single step the child */ 18226278Skarels case PT_CONTINUE: /* continue the child */ 1837501Sroot if ((int)ipc.ip_addr != 1) 1847501Sroot u.u_ar0[PC] = (int)ipc.ip_addr; 1857501Sroot if ((unsigned)ipc.ip_data > NSIG) 1867501Sroot goto error; 1877501Sroot u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 18826278Skarels if (i == PT_STEP) 1897501Sroot u.u_ar0[PS] |= PSL_T; 1907501Sroot wakeup((caddr_t)&ipc); 1917501Sroot return (1); 1927501Sroot 19326278Skarels case PT_KILL: /* kill the child process */ 1947501Sroot wakeup((caddr_t)&ipc); 1957501Sroot exit(u.u_procp->p_cursig); 1967501Sroot 1977501Sroot default: 1987501Sroot error: 1997501Sroot ipc.ip_req = -1; 2007501Sroot } 2017501Sroot wakeup((caddr_t)&ipc); 2027501Sroot return (0); 2037501Sroot } 204