123385Smckusick /* 223385Smckusick * Copyright (c) 1982 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*25535Skarels * @(#)sys_process.c 6.5 (Berkeley) 11/26/85 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" 247426Sroot 257501Sroot /* 267501Sroot * Priority for tracing 277501Sroot */ 287501Sroot #define IPCPRI PZERO 297501Sroot 307501Sroot /* 317501Sroot * Tracing variables. 327501Sroot * Used to pass trace command from 337501Sroot * parent to child being traced. 347501Sroot * This data base cannot be 357501Sroot * shared and is locked 367501Sroot * per user. 377501Sroot */ 387501Sroot struct { 397501Sroot int ip_lock; 407501Sroot int ip_req; 417501Sroot int *ip_addr; 427501Sroot int ip_data; 437501Sroot } ipc; 447501Sroot 457501Sroot /* 467501Sroot * sys-trace system call. 477501Sroot */ 487501Sroot ptrace() 497501Sroot { 507501Sroot register struct proc *p; 517501Sroot register struct a { 527501Sroot int req; 537501Sroot int pid; 547501Sroot int *addr; 557501Sroot int data; 567501Sroot } *uap; 577501Sroot 587501Sroot uap = (struct a *)u.u_ap; 597501Sroot if (uap->req <= 0) { 607501Sroot u.u_procp->p_flag |= STRC; 617501Sroot return; 627501Sroot } 637501Sroot p = pfind(uap->pid); 6412496Ssam if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid || 6512496Ssam !(p->p_flag & STRC)) { 667501Sroot u.u_error = ESRCH; 677501Sroot return; 687501Sroot } 697501Sroot while (ipc.ip_lock) 707501Sroot sleep((caddr_t)&ipc, IPCPRI); 717501Sroot ipc.ip_lock = p->p_pid; 727501Sroot ipc.ip_data = uap->data; 737501Sroot ipc.ip_addr = uap->addr; 747501Sroot ipc.ip_req = uap->req; 757501Sroot p->p_flag &= ~SWTED; 767501Sroot while (ipc.ip_req > 0) { 777501Sroot if (p->p_stat==SSTOP) 787501Sroot setrun(p); 797501Sroot sleep((caddr_t)&ipc, IPCPRI); 807501Sroot } 817501Sroot u.u_r.r_val1 = ipc.ip_data; 827501Sroot if (ipc.ip_req < 0) 837501Sroot u.u_error = EIO; 847501Sroot ipc.ip_lock = 0; 857501Sroot wakeup((caddr_t)&ipc); 867501Sroot } 877501Sroot 888966Sroot #ifdef vax 898952Sroot #define NIPCREG 16 908952Sroot int ipcreg[NIPCREG] = 918952Sroot {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; 928952Sroot #endif 938952Sroot 948953Sroot #define PHYSOFF(p, o) \ 958952Sroot ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0]))) 968952Sroot 977501Sroot /* 987501Sroot * Code that the child process 997501Sroot * executes to implement the command 1007501Sroot * of the parent process in tracing. 1017501Sroot */ 1027501Sroot procxmt() 1037501Sroot { 1047501Sroot register int i; 1057501Sroot register *p; 1067501Sroot register struct text *xp; 1077501Sroot 1087501Sroot if (ipc.ip_lock != u.u_procp->p_pid) 1097501Sroot return (0); 1107501Sroot u.u_procp->p_slptime = 0; 1117501Sroot i = ipc.ip_req; 1127501Sroot ipc.ip_req = 0; 1137501Sroot switch (i) { 1147501Sroot 1157501Sroot /* read user I */ 1167501Sroot case 1: 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 1227501Sroot /* read user D */ 1237501Sroot case 2: 1247501Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 1257501Sroot goto error; 1267501Sroot ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 1277501Sroot break; 1287501Sroot 1297501Sroot /* read u */ 1307501Sroot case 3: 1317501Sroot i = (int)ipc.ip_addr; 1327501Sroot if (i<0 || i >= ctob(UPAGES)) 1337501Sroot goto error; 1348952Sroot ipc.ip_data = *(int *)PHYSOFF(&u, i); 1357501Sroot break; 1367501Sroot 1377501Sroot /* write user I */ 1387501Sroot /* Must set up to allow writing */ 1397501Sroot case 4: 1407501Sroot /* 1417501Sroot * If text, must assure exclusive use 1427501Sroot */ 1437501Sroot if (xp = u.u_procp->p_textp) { 1447501Sroot if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 1457501Sroot goto error; 146*25535Skarels xp->x_flag |= XTRC; 1477501Sroot } 1487501Sroot i = -1; 1498952Sroot if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) { 1508952Sroot if (chgprot((caddr_t)ipc.ip_addr, RW) && 1518952Sroot chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 1528952Sroot i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 1538952Sroot (void) chgprot((caddr_t)ipc.ip_addr, RO); 1548952Sroot (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 1558952Sroot } 1567501Sroot if (i < 0) 1577501Sroot goto error; 1587501Sroot if (xp) 1597501Sroot xp->x_flag |= XWRIT; 1607501Sroot break; 1617501Sroot 1627501Sroot /* write user D */ 1637501Sroot case 5: 1647501Sroot if (suword((caddr_t)ipc.ip_addr, 0) < 0) 1657501Sroot goto error; 1667501Sroot (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 1677501Sroot break; 1687501Sroot 1697501Sroot /* write u */ 1707501Sroot case 6: 1717501Sroot i = (int)ipc.ip_addr; 1728952Sroot p = (int *)PHYSOFF(&u, i); 1738952Sroot for (i=0; i<NIPCREG; i++) 1747501Sroot if (p == &u.u_ar0[ipcreg[i]]) 1757501Sroot goto ok; 1767501Sroot if (p == &u.u_ar0[PS]) { 1778952Sroot ipc.ip_data |= PSL_USERSET; 1787501Sroot ipc.ip_data &= ~PSL_USERCLR; 1797501Sroot goto ok; 1807501Sroot } 1817501Sroot goto error; 1827501Sroot 1837501Sroot ok: 1847501Sroot *p = ipc.ip_data; 1857501Sroot break; 1867501Sroot 1877501Sroot /* set signal and continue */ 1887501Sroot /* one version causes a trace-trap */ 1897501Sroot case 9: 1907501Sroot case 7: 1917501Sroot if ((int)ipc.ip_addr != 1) 1927501Sroot u.u_ar0[PC] = (int)ipc.ip_addr; 1937501Sroot if ((unsigned)ipc.ip_data > NSIG) 1947501Sroot goto error; 1957501Sroot u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 1969759Ssam if (i == 9) 1977501Sroot u.u_ar0[PS] |= PSL_T; 1987501Sroot wakeup((caddr_t)&ipc); 1997501Sroot return (1); 2007501Sroot 2017501Sroot /* force exit */ 2027501Sroot case 8: 2037501Sroot wakeup((caddr_t)&ipc); 2047501Sroot exit(u.u_procp->p_cursig); 2057501Sroot 2067501Sroot default: 2077501Sroot error: 2087501Sroot ipc.ip_req = -1; 2097501Sroot } 2107501Sroot wakeup((caddr_t)&ipc); 2117501Sroot return (0); 2127501Sroot } 213