1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * Copyright 2017 Joyent, Inc. 26 */ 27 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 29 /* All rights reserved. */ 30 31 #include <sys/types.h> 32 #include <sys/param.h> 33 #include <sys/vmparam.h> 34 #include <sys/var.h> 35 #include <sys/cmn_err.h> 36 #include <sys/cred.h> 37 #include <sys/debug.h> 38 #include <sys/errno.h> 39 #include <sys/file.h> 40 #include <sys/inline.h> 41 #include <sys/kmem.h> 42 #include <sys/proc.h> 43 #include <sys/brand.h> 44 #include <sys/sysmacros.h> 45 #include <sys/systm.h> 46 #include <sys/vfs.h> 47 #include <sys/vnode.h> 48 #include <sys/cpuvar.h> 49 #include <sys/session.h> 50 #include <sys/signal.h> 51 #include <sys/auxv.h> 52 #include <sys/user.h> 53 #include <sys/disp.h> 54 #include <sys/class.h> 55 #include <sys/ts.h> 56 #include <sys/mman.h> 57 #include <sys/fault.h> 58 #include <sys/syscall.h> 59 #include <sys/schedctl.h> 60 #include <sys/pset.h> 61 #include <sys/old_procfs.h> 62 #include <sys/zone.h> 63 #include <sys/time.h> 64 #include <sys/msacct.h> 65 #include <vm/rm.h> 66 #include <vm/as.h> 67 #include <vm/rm.h> 68 #include <vm/seg.h> 69 #include <vm/seg_vn.h> 70 #include <sys/contract_impl.h> 71 #include <sys/ctfs_impl.h> 72 #include <sys/ctfs.h> 73 74 #if defined(__i386) || defined(__i386_COMPAT) 75 #include <sys/sysi86.h> 76 #endif 77 78 #include <fs/proc/prdata.h> 79 80 static int isprwrioctl(int); 81 static ulong_t prmaprunflags(long); 82 static long prmapsetflags(long); 83 static void prsetrun(kthread_t *, prrun_t *); 84 static int propenm(prnode_t *, caddr_t, caddr_t, int *, cred_t *); 85 extern void oprgetstatus(kthread_t *, prstatus_t *, zone_t *); 86 extern void oprgetpsinfo(proc_t *, prpsinfo_t *, kthread_t *); 87 static int oprgetmap(proc_t *, list_t *); 88 89 static int 90 prctioctl(prnode_t *pnp, int cmd, intptr_t arg, int flag, cred_t *cr) 91 { 92 int error = 0; 93 ct_kparam_t kparam; 94 ct_param_t *param = &kparam.param; 95 ct_template_t *tmpl; 96 97 if (cmd != CT_TSET && cmd != CT_TGET) 98 return (EINVAL); 99 100 error = ctparam_copyin((void *)arg, &kparam, flag, cmd); 101 if (error != 0) 102 return (error); 103 104 if ((error = prlock(pnp, ZNO)) != 0) { 105 kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 106 return (error); 107 } 108 109 tmpl = pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[pnp->pr_cttype]; 110 if (tmpl == NULL) { 111 prunlock(pnp); 112 kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 113 return (ESTALE); 114 } 115 116 if (cmd == CT_TSET) 117 error = ctmpl_set(tmpl, &kparam, cr); 118 else 119 error = ctmpl_get(tmpl, &kparam); 120 121 prunlock(pnp); 122 123 if (cmd == CT_TGET && error == 0) { 124 error = ctparam_copyout(&kparam, (void *)arg, flag); 125 } else { 126 kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 127 } 128 129 return (error); 130 } 131 132 133 /* 134 * Control operations (lots). 135 */ 136 /*ARGSUSED*/ 137 #ifdef _SYSCALL32_IMPL 138 static int 139 prioctl64( 140 struct vnode *vp, 141 int cmd, 142 intptr_t arg, 143 int flag, 144 cred_t *cr, 145 int *rvalp, 146 caller_context_t *ct) 147 #else 148 int 149 prioctl( 150 struct vnode *vp, 151 int cmd, 152 intptr_t arg, 153 int flag, 154 cred_t *cr, 155 int *rvalp, 156 caller_context_t *ct) 157 #endif /* _SYSCALL32_IMPL */ 158 { 159 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 160 caddr_t cmaddr = (caddr_t)arg; 161 proc_t *p; 162 user_t *up; 163 kthread_t *t; 164 klwp_t *lwp; 165 prnode_t *pnp = VTOP(vp); 166 prcommon_t *pcp; 167 prnode_t *xpnp = NULL; 168 int error; 169 int zdisp; 170 void *thing = NULL; 171 size_t thingsize = 0; 172 173 /* 174 * For copyin()/copyout(). 175 */ 176 union { 177 caddr_t va; 178 int signo; 179 int nice; 180 uint_t lwpid; 181 long flags; 182 prstatus_t prstat; 183 prrun_t prrun; 184 sigset_t smask; 185 siginfo_t info; 186 sysset_t prmask; 187 prgregset_t regs; 188 prfpregset_t fpregs; 189 prpsinfo_t prps; 190 sigset_t holdmask; 191 fltset_t fltmask; 192 prcred_t prcred; 193 prhusage_t prhusage; 194 prmap_t prmap; 195 auxv_t auxv[__KERN_NAUXV_IMPL]; 196 } un; 197 198 if (pnp->pr_type == PR_TMPL) 199 return (prctioctl(pnp, cmd, arg, flag, cr)); 200 201 /* 202 * Support for old /proc interface. 203 */ 204 if (pnp->pr_pidfile != NULL) { 205 ASSERT(pnp->pr_type == PR_PIDDIR); 206 vp = pnp->pr_pidfile; 207 pnp = VTOP(vp); 208 ASSERT(pnp->pr_type == PR_PIDFILE); 209 } 210 211 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE) 212 return (ENOTTY); 213 214 /* 215 * Fail ioctls which are logically "write" requests unless 216 * the user has write permission. 217 */ 218 if ((flag & FWRITE) == 0 && isprwrioctl(cmd)) 219 return (EBADF); 220 221 /* 222 * Perform any necessary copyin() operations before 223 * locking the process. Helps avoid deadlocks and 224 * improves performance. 225 * 226 * Also, detect invalid ioctl codes here to avoid 227 * locking a process unnnecessarily. 228 * 229 * Also, prepare to allocate space that will be needed below, 230 * case by case. 231 */ 232 error = 0; 233 switch (cmd) { 234 case PIOCGETPR: 235 thingsize = sizeof (proc_t); 236 break; 237 case PIOCGETU: 238 thingsize = sizeof (user_t); 239 break; 240 case PIOCSTOP: 241 case PIOCWSTOP: 242 case PIOCLWPIDS: 243 case PIOCGTRACE: 244 case PIOCGENTRY: 245 case PIOCGEXIT: 246 case PIOCSRLC: 247 case PIOCRRLC: 248 case PIOCSFORK: 249 case PIOCRFORK: 250 case PIOCGREG: 251 case PIOCGFPREG: 252 case PIOCSTATUS: 253 case PIOCLSTATUS: 254 case PIOCPSINFO: 255 case PIOCMAXSIG: 256 case PIOCGXREGSIZE: 257 break; 258 case PIOCSXREG: /* set extra registers */ 259 case PIOCGXREG: /* get extra registers */ 260 #if defined(__sparc) 261 thingsize = sizeof (prxregset_t); 262 #else 263 thingsize = 0; 264 #endif 265 break; 266 case PIOCACTION: 267 thingsize = (nsig-1) * sizeof (struct sigaction); 268 break; 269 case PIOCGHOLD: 270 case PIOCNMAP: 271 case PIOCMAP: 272 case PIOCGFAULT: 273 case PIOCCFAULT: 274 case PIOCCRED: 275 case PIOCGROUPS: 276 case PIOCUSAGE: 277 case PIOCLUSAGE: 278 break; 279 case PIOCOPENPD: 280 /* 281 * We will need this below. 282 * Allocate it now, before locking the process. 283 */ 284 xpnp = prgetnode(vp, PR_OPAGEDATA); 285 break; 286 case PIOCNAUXV: 287 case PIOCAUXV: 288 break; 289 290 #if defined(__i386) || defined(__amd64) 291 case PIOCNLDT: 292 case PIOCLDT: 293 break; 294 #endif /* __i386 || __amd64 */ 295 296 #if defined(__sparc) 297 case PIOCGWIN: 298 thingsize = sizeof (gwindows_t); 299 break; 300 #endif /* __sparc */ 301 302 case PIOCOPENM: /* open mapped object for reading */ 303 if (cmaddr == NULL) 304 un.va = NULL; 305 else if (copyin(cmaddr, &un.va, sizeof (un.va))) 306 error = EFAULT; 307 break; 308 309 case PIOCRUN: /* make lwp or process runnable */ 310 if (cmaddr == NULL) 311 un.prrun.pr_flags = 0; 312 else if (copyin(cmaddr, &un.prrun, sizeof (un.prrun))) 313 error = EFAULT; 314 break; 315 316 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 317 if (copyin(cmaddr, &un.lwpid, sizeof (un.lwpid))) 318 error = EFAULT; 319 break; 320 321 case PIOCSTRACE: /* set signal trace mask */ 322 if (copyin(cmaddr, &un.smask, sizeof (un.smask))) 323 error = EFAULT; 324 break; 325 326 case PIOCSSIG: /* set current signal */ 327 if (cmaddr == NULL) 328 un.info.si_signo = 0; 329 else if (copyin(cmaddr, &un.info, sizeof (un.info))) 330 error = EFAULT; 331 break; 332 333 case PIOCKILL: /* send signal */ 334 case PIOCUNKILL: /* delete a signal */ 335 if (copyin(cmaddr, &un.signo, sizeof (un.signo))) 336 error = EFAULT; 337 break; 338 339 case PIOCNICE: /* set nice priority */ 340 if (copyin(cmaddr, &un.nice, sizeof (un.nice))) 341 error = EFAULT; 342 break; 343 344 case PIOCSENTRY: /* set syscall entry bit mask */ 345 case PIOCSEXIT: /* set syscall exit bit mask */ 346 if (copyin(cmaddr, &un.prmask, sizeof (un.prmask))) 347 error = EFAULT; 348 break; 349 350 case PIOCSET: /* set process flags */ 351 case PIOCRESET: /* reset process flags */ 352 if (copyin(cmaddr, &un.flags, sizeof (un.flags))) 353 error = EFAULT; 354 break; 355 356 case PIOCSREG: /* set general registers */ 357 if (copyin(cmaddr, un.regs, sizeof (un.regs))) 358 error = EFAULT; 359 break; 360 361 case PIOCSFPREG: /* set floating-point registers */ 362 if (copyin(cmaddr, &un.fpregs, sizeof (un.fpregs))) 363 error = EFAULT; 364 break; 365 366 case PIOCSHOLD: /* set signal-hold mask */ 367 if (copyin(cmaddr, &un.holdmask, sizeof (un.holdmask))) 368 error = EFAULT; 369 break; 370 371 case PIOCSFAULT: /* set mask of traced faults */ 372 if (copyin(cmaddr, &un.fltmask, sizeof (un.fltmask))) 373 error = EFAULT; 374 break; 375 376 default: 377 error = EINVAL; 378 break; 379 } 380 381 if (error) 382 return (error); 383 384 startover: 385 /* 386 * If we need kmem_alloc()d space then we allocate it now, before 387 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while 388 * holding the process lock leads to deadlock with the clock thread. 389 * (The clock thread wakes up the pageout daemon to free up space. 390 * If the clock thread blocks behind us and we are sleeping waiting 391 * for space, then space may never become available.) 392 */ 393 if (thingsize) { 394 ASSERT(thing == NULL); 395 thing = kmem_alloc(thingsize, KM_SLEEP); 396 } 397 398 switch (cmd) { 399 case PIOCPSINFO: 400 case PIOCGETPR: 401 case PIOCUSAGE: 402 case PIOCLUSAGE: 403 zdisp = ZYES; 404 break; 405 case PIOCSXREG: /* set extra registers */ 406 /* 407 * perform copyin before grabbing the process lock 408 */ 409 if (thing) { 410 if (copyin(cmaddr, thing, thingsize)) { 411 kmem_free(thing, thingsize); 412 return (EFAULT); 413 } 414 } 415 /* fall through... */ 416 default: 417 zdisp = ZNO; 418 break; 419 } 420 421 if ((error = prlock(pnp, zdisp)) != 0) { 422 if (thing != NULL) 423 kmem_free(thing, thingsize); 424 if (xpnp) 425 prfreenode(xpnp); 426 return (error); 427 } 428 429 pcp = pnp->pr_common; 430 p = pcp->prc_proc; 431 ASSERT(p != NULL); 432 433 /* 434 * Choose a thread/lwp for the operation. 435 */ 436 if (zdisp == ZNO && cmd != PIOCSTOP && cmd != PIOCWSTOP) { 437 if (pnp->pr_type == PR_LWPIDFILE && cmd != PIOCLSTATUS) { 438 t = pcp->prc_thread; 439 ASSERT(t != NULL); 440 } else { 441 t = prchoose(p); /* returns locked thread */ 442 ASSERT(t != NULL); 443 thread_unlock(t); 444 } 445 lwp = ttolwp(t); 446 } 447 448 error = 0; 449 switch (cmd) { 450 451 case PIOCGETPR: /* read struct proc */ 452 { 453 proc_t *prp = thing; 454 455 *prp = *p; 456 prunlock(pnp); 457 if (copyout(prp, cmaddr, sizeof (proc_t))) 458 error = EFAULT; 459 kmem_free(prp, sizeof (proc_t)); 460 thing = NULL; 461 break; 462 } 463 464 case PIOCGETU: /* read u-area */ 465 { 466 user_t *userp = thing; 467 468 up = PTOU(p); 469 *userp = *up; 470 prunlock(pnp); 471 if (copyout(userp, cmaddr, sizeof (user_t))) 472 error = EFAULT; 473 kmem_free(userp, sizeof (user_t)); 474 thing = NULL; 475 break; 476 } 477 478 case PIOCOPENM: /* open mapped object for reading */ 479 error = propenm(pnp, cmaddr, un.va, rvalp, cr); 480 /* propenm() called prunlock(pnp) */ 481 break; 482 483 case PIOCSTOP: /* stop process or lwp from running */ 484 case PIOCWSTOP: /* wait for process or lwp to stop */ 485 /* 486 * Can't apply to a system process. 487 */ 488 if ((p->p_flag & SSYS) || p->p_as == &kas) { 489 prunlock(pnp); 490 error = EBUSY; 491 break; 492 } 493 494 if (cmd == PIOCSTOP) 495 pr_stop(pnp); 496 497 /* 498 * If an lwp is waiting for itself or its process, don't wait. 499 * The stopped lwp would never see the fact that it is stopped. 500 */ 501 if ((pnp->pr_type == PR_LWPIDFILE)? 502 (pcp->prc_thread == curthread) : (p == curproc)) { 503 if (cmd == PIOCWSTOP) 504 error = EBUSY; 505 prunlock(pnp); 506 break; 507 } 508 509 if ((error = pr_wait_stop(pnp, (time_t)0)) != 0) 510 break; /* pr_wait_stop() unlocked the process */ 511 512 if (cmaddr == NULL) 513 prunlock(pnp); 514 else { 515 /* 516 * Return process/lwp status information. 517 */ 518 t = pr_thread(pnp); /* returns locked thread */ 519 thread_unlock(t); 520 oprgetstatus(t, &un.prstat, VTOZONE(vp)); 521 prunlock(pnp); 522 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat))) 523 error = EFAULT; 524 } 525 break; 526 527 case PIOCRUN: /* make lwp or process runnable */ 528 { 529 long flags = un.prrun.pr_flags; 530 531 /* 532 * Cannot set an lwp running is it is not stopped. 533 * Also, no lwp other than the /proc agent lwp can 534 * be set running so long as the /proc agent lwp exists. 535 */ 536 if ((!ISTOPPED(t) && !VSTOPPED(t) && 537 !(t->t_proc_flag & TP_PRSTOP)) || 538 (p->p_agenttp != NULL && 539 (t != p->p_agenttp || pnp->pr_type != PR_LWPIDFILE))) { 540 prunlock(pnp); 541 error = EBUSY; 542 break; 543 } 544 545 if (flags & (PRSHOLD|PRSTRACE|PRSFAULT|PRSVADDR)) 546 prsetrun(t, &un.prrun); 547 548 error = pr_setrun(pnp, prmaprunflags(flags)); 549 550 prunlock(pnp); 551 break; 552 } 553 554 case PIOCLWPIDS: /* get array of lwp identifiers */ 555 { 556 int nlwp; 557 int Nlwp; 558 id_t *idp; 559 id_t *Bidp; 560 561 Nlwp = nlwp = p->p_lwpcnt; 562 563 if (thing && thingsize != (Nlwp+1) * sizeof (id_t)) { 564 kmem_free(thing, thingsize); 565 thing = NULL; 566 } 567 if (thing == NULL) { 568 thingsize = (Nlwp+1) * sizeof (id_t); 569 thing = kmem_alloc(thingsize, KM_NOSLEEP); 570 } 571 if (thing == NULL) { 572 prunlock(pnp); 573 goto startover; 574 } 575 576 idp = thing; 577 thing = NULL; 578 Bidp = idp; 579 if ((t = p->p_tlist) != NULL) { 580 do { 581 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 582 ASSERT(nlwp > 0); 583 --nlwp; 584 *idp++ = t->t_tid; 585 } while ((t = t->t_forw) != p->p_tlist); 586 } 587 *idp = 0; 588 ASSERT(nlwp == 0); 589 prunlock(pnp); 590 if (copyout(Bidp, cmaddr, (Nlwp+1) * sizeof (id_t))) 591 error = EFAULT; 592 kmem_free(Bidp, (Nlwp+1) * sizeof (id_t)); 593 break; 594 } 595 596 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 597 { 598 vnode_t *xvp; 599 int n; 600 601 prunlock(pnp); 602 if ((xvp = prlwpnode(pnp, un.lwpid)) == NULL) 603 error = ENOENT; 604 else if (error = fassign(&xvp, flag & (FREAD|FWRITE), &n)) { 605 VN_RELE(xvp); 606 } else 607 *rvalp = n; 608 break; 609 } 610 611 case PIOCOPENPD: /* return /proc page data file descriptor */ 612 { 613 vnode_t *xvp = PTOV(xpnp); 614 vnode_t *dp = pnp->pr_parent; 615 int n; 616 617 if (pnp->pr_type == PR_LWPIDFILE) { 618 dp = VTOP(dp)->pr_parent; 619 dp = VTOP(dp)->pr_parent; 620 } 621 ASSERT(VTOP(dp)->pr_type == PR_PIDDIR); 622 623 VN_HOLD(dp); 624 pcp = pnp->pr_pcommon; 625 xpnp->pr_ino = ptoi(pcp->prc_pid); 626 xpnp->pr_common = pcp; 627 xpnp->pr_pcommon = pcp; 628 xpnp->pr_parent = dp; 629 630 xpnp->pr_next = p->p_plist; 631 p->p_plist = xvp; 632 633 prunlock(pnp); 634 if (error = fassign(&xvp, FREAD, &n)) { 635 VN_RELE(xvp); 636 } else 637 *rvalp = n; 638 639 xpnp = NULL; 640 break; 641 } 642 643 case PIOCGTRACE: /* get signal trace mask */ 644 prassignset(&un.smask, &p->p_sigmask); 645 prunlock(pnp); 646 if (copyout(&un.smask, cmaddr, sizeof (un.smask))) 647 error = EFAULT; 648 break; 649 650 case PIOCSTRACE: /* set signal trace mask */ 651 prdelset(&un.smask, SIGKILL); 652 prassignset(&p->p_sigmask, &un.smask); 653 if (!sigisempty(&p->p_sigmask)) 654 p->p_proc_flag |= P_PR_TRACE; 655 else if (prisempty(&p->p_fltmask)) { 656 up = PTOU(p); 657 if (up->u_systrap == 0) 658 p->p_proc_flag &= ~P_PR_TRACE; 659 } 660 prunlock(pnp); 661 break; 662 663 case PIOCSSIG: /* set current signal */ 664 error = pr_setsig(pnp, &un.info); 665 prunlock(pnp); 666 if (un.info.si_signo == SIGKILL && error == 0) 667 pr_wait_die(pnp); 668 break; 669 670 case PIOCKILL: /* send signal */ 671 { 672 int sig = (int)un.signo; 673 674 error = pr_kill(pnp, sig, cr); 675 prunlock(pnp); 676 if (sig == SIGKILL && error == 0) 677 pr_wait_die(pnp); 678 break; 679 } 680 681 case PIOCUNKILL: /* delete a signal */ 682 error = pr_unkill(pnp, (int)un.signo); 683 prunlock(pnp); 684 break; 685 686 case PIOCNICE: /* set nice priority */ 687 error = pr_nice(p, (int)un.nice, cr); 688 prunlock(pnp); 689 break; 690 691 case PIOCGENTRY: /* get syscall entry bit mask */ 692 case PIOCGEXIT: /* get syscall exit bit mask */ 693 up = PTOU(p); 694 if (cmd == PIOCGENTRY) { 695 prassignset(&un.prmask, &up->u_entrymask); 696 } else { 697 prassignset(&un.prmask, &up->u_exitmask); 698 } 699 prunlock(pnp); 700 if (copyout(&un.prmask, cmaddr, sizeof (un.prmask))) 701 error = EFAULT; 702 break; 703 704 case PIOCSENTRY: /* set syscall entry bit mask */ 705 case PIOCSEXIT: /* set syscall exit bit mask */ 706 pr_setentryexit(p, &un.prmask, cmd == PIOCSENTRY); 707 prunlock(pnp); 708 break; 709 710 case PIOCSRLC: /* obsolete: set running on last /proc close */ 711 error = pr_set(p, prmapsetflags(PR_RLC)); 712 prunlock(pnp); 713 break; 714 715 case PIOCRRLC: /* obsolete: reset run-on-last-close flag */ 716 error = pr_unset(p, prmapsetflags(PR_RLC)); 717 prunlock(pnp); 718 break; 719 720 case PIOCSFORK: /* obsolete: set inherit-on-fork flag */ 721 error = pr_set(p, prmapsetflags(PR_FORK)); 722 prunlock(pnp); 723 break; 724 725 case PIOCRFORK: /* obsolete: reset inherit-on-fork flag */ 726 error = pr_unset(p, prmapsetflags(PR_FORK)); 727 prunlock(pnp); 728 break; 729 730 case PIOCSET: /* set process flags */ 731 error = pr_set(p, prmapsetflags(un.flags)); 732 prunlock(pnp); 733 break; 734 735 case PIOCRESET: /* reset process flags */ 736 error = pr_unset(p, prmapsetflags(un.flags)); 737 prunlock(pnp); 738 break; 739 740 case PIOCGREG: /* get general registers */ 741 if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 742 bzero(un.regs, sizeof (un.regs)); 743 else { 744 /* drop p_lock while touching the lwp's stack */ 745 mutex_exit(&p->p_lock); 746 prgetprregs(lwp, un.regs); 747 mutex_enter(&p->p_lock); 748 } 749 prunlock(pnp); 750 if (copyout(un.regs, cmaddr, sizeof (un.regs))) 751 error = EFAULT; 752 break; 753 754 case PIOCSREG: /* set general registers */ 755 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 756 error = EBUSY; 757 else { 758 /* drop p_lock while touching the lwp's stack */ 759 mutex_exit(&p->p_lock); 760 prsetprregs(lwp, un.regs, 0); 761 mutex_enter(&p->p_lock); 762 } 763 prunlock(pnp); 764 break; 765 766 case PIOCGFPREG: /* get floating-point registers */ 767 if (!prhasfp()) { 768 prunlock(pnp); 769 error = EINVAL; /* No FP support */ 770 break; 771 } 772 773 if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 774 bzero(&un.fpregs, sizeof (un.fpregs)); 775 else { 776 /* drop p_lock while touching the lwp's stack */ 777 mutex_exit(&p->p_lock); 778 prgetprfpregs(lwp, &un.fpregs); 779 mutex_enter(&p->p_lock); 780 } 781 prunlock(pnp); 782 if (copyout(&un.fpregs, cmaddr, sizeof (un.fpregs))) 783 error = EFAULT; 784 break; 785 786 case PIOCSFPREG: /* set floating-point registers */ 787 if (!prhasfp()) 788 error = EINVAL; /* No FP support */ 789 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 790 error = EBUSY; 791 else { 792 /* drop p_lock while touching the lwp's stack */ 793 mutex_exit(&p->p_lock); 794 prsetprfpregs(lwp, &un.fpregs); 795 mutex_enter(&p->p_lock); 796 } 797 prunlock(pnp); 798 break; 799 800 case PIOCGXREGSIZE: /* get the size of the extra registers */ 801 { 802 int xregsize; 803 804 if (prhasx(p)) { 805 xregsize = prgetprxregsize(p); 806 prunlock(pnp); 807 if (copyout(&xregsize, cmaddr, sizeof (xregsize))) 808 error = EFAULT; 809 } else { 810 prunlock(pnp); 811 error = EINVAL; /* No extra register support */ 812 } 813 break; 814 } 815 816 case PIOCGXREG: /* get extra registers */ 817 if (prhasx(p)) { 818 bzero(thing, thingsize); 819 if (t->t_state == TS_STOPPED || VSTOPPED(t)) { 820 /* drop p_lock to touch the stack */ 821 mutex_exit(&p->p_lock); 822 prgetprxregs(lwp, thing); 823 mutex_enter(&p->p_lock); 824 } 825 prunlock(pnp); 826 if (copyout(thing, cmaddr, thingsize)) 827 error = EFAULT; 828 } else { 829 prunlock(pnp); 830 error = EINVAL; /* No extra register support */ 831 } 832 if (thing) { 833 kmem_free(thing, thingsize); 834 thing = NULL; 835 } 836 break; 837 838 case PIOCSXREG: /* set extra registers */ 839 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 840 error = EBUSY; 841 else if (!prhasx(p)) 842 error = EINVAL; /* No extra register support */ 843 else if (thing) { 844 /* drop p_lock while touching the lwp's stack */ 845 mutex_exit(&p->p_lock); 846 prsetprxregs(lwp, thing); 847 mutex_enter(&p->p_lock); 848 } 849 prunlock(pnp); 850 if (thing) { 851 kmem_free(thing, thingsize); 852 thing = NULL; 853 } 854 break; 855 856 case PIOCSTATUS: /* get process/lwp status */ 857 oprgetstatus(t, &un.prstat, VTOZONE(vp)); 858 prunlock(pnp); 859 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat))) 860 error = EFAULT; 861 break; 862 863 case PIOCLSTATUS: /* get status for process & all lwps */ 864 { 865 int Nlwp; 866 int nlwp; 867 prstatus_t *Bprsp; 868 prstatus_t *prsp; 869 870 nlwp = Nlwp = p->p_lwpcnt; 871 872 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus_t)) { 873 kmem_free(thing, thingsize); 874 thing = NULL; 875 } 876 if (thing == NULL) { 877 thingsize = (Nlwp+1) * sizeof (prstatus_t); 878 thing = kmem_alloc(thingsize, KM_NOSLEEP); 879 } 880 if (thing == NULL) { 881 prunlock(pnp); 882 goto startover; 883 } 884 885 Bprsp = thing; 886 thing = NULL; 887 prsp = Bprsp; 888 oprgetstatus(t, prsp, VTOZONE(vp)); 889 t = p->p_tlist; 890 do { 891 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 892 ASSERT(nlwp > 0); 893 --nlwp; 894 oprgetstatus(t, ++prsp, VTOZONE(vp)); 895 } while ((t = t->t_forw) != p->p_tlist); 896 ASSERT(nlwp == 0); 897 prunlock(pnp); 898 if (copyout(Bprsp, cmaddr, (Nlwp+1) * sizeof (prstatus_t))) 899 error = EFAULT; 900 901 kmem_free(Bprsp, (Nlwp+1) * sizeof (prstatus_t)); 902 break; 903 } 904 905 case PIOCPSINFO: /* get ps(1) information */ 906 { 907 prpsinfo_t *psp = &un.prps; 908 909 oprgetpsinfo(p, psp, 910 (pnp->pr_type == PR_LWPIDFILE)? pcp->prc_thread : NULL); 911 912 prunlock(pnp); 913 if (copyout(&un.prps, cmaddr, sizeof (un.prps))) 914 error = EFAULT; 915 break; 916 } 917 918 case PIOCMAXSIG: /* get maximum signal number */ 919 { 920 int n = nsig-1; 921 922 prunlock(pnp); 923 if (copyout(&n, cmaddr, sizeof (n))) 924 error = EFAULT; 925 break; 926 } 927 928 case PIOCACTION: /* get signal action structures */ 929 { 930 uint_t sig; 931 struct sigaction *sap = thing; 932 933 up = PTOU(p); 934 for (sig = 1; sig < nsig; sig++) 935 prgetaction(p, up, sig, &sap[sig-1]); 936 prunlock(pnp); 937 if (copyout(sap, cmaddr, (nsig-1) * sizeof (struct sigaction))) 938 error = EFAULT; 939 kmem_free(sap, (nsig-1) * sizeof (struct sigaction)); 940 thing = NULL; 941 break; 942 } 943 944 case PIOCGHOLD: /* get signal-hold mask */ 945 schedctl_finish_sigblock(t); 946 sigktou(&t->t_hold, &un.holdmask); 947 prunlock(pnp); 948 if (copyout(&un.holdmask, cmaddr, sizeof (un.holdmask))) 949 error = EFAULT; 950 break; 951 952 case PIOCSHOLD: /* set signal-hold mask */ 953 pr_sethold(pnp, &un.holdmask); 954 prunlock(pnp); 955 break; 956 957 case PIOCNMAP: /* get number of memory mappings */ 958 { 959 int n; 960 struct as *as = p->p_as; 961 962 if ((p->p_flag & SSYS) || as == &kas) 963 n = 0; 964 else { 965 mutex_exit(&p->p_lock); 966 AS_LOCK_ENTER(as, RW_WRITER); 967 n = prnsegs(as, 0); 968 AS_LOCK_EXIT(as); 969 mutex_enter(&p->p_lock); 970 } 971 prunlock(pnp); 972 if (copyout(&n, cmaddr, sizeof (int))) 973 error = EFAULT; 974 break; 975 } 976 977 case PIOCMAP: /* get memory map information */ 978 { 979 list_t iolhead; 980 struct as *as = p->p_as; 981 982 if ((p->p_flag & SSYS) || as == &kas) { 983 error = 0; 984 prunlock(pnp); 985 } else { 986 mutex_exit(&p->p_lock); 987 AS_LOCK_ENTER(as, RW_WRITER); 988 error = oprgetmap(p, &iolhead); 989 AS_LOCK_EXIT(as); 990 mutex_enter(&p->p_lock); 991 prunlock(pnp); 992 993 error = pr_iol_copyout_and_free(&iolhead, 994 &cmaddr, error); 995 } 996 /* 997 * The procfs PIOCMAP ioctl returns an all-zero buffer 998 * to indicate the end of the prmap[] array. 999 * Append it to whatever has already been copied out. 1000 */ 1001 bzero(&un.prmap, sizeof (un.prmap)); 1002 if (!error && copyout(&un.prmap, cmaddr, sizeof (un.prmap))) 1003 error = EFAULT; 1004 1005 break; 1006 } 1007 1008 case PIOCGFAULT: /* get mask of traced faults */ 1009 prassignset(&un.fltmask, &p->p_fltmask); 1010 prunlock(pnp); 1011 if (copyout(&un.fltmask, cmaddr, sizeof (un.fltmask))) 1012 error = EFAULT; 1013 break; 1014 1015 case PIOCSFAULT: /* set mask of traced faults */ 1016 pr_setfault(p, &un.fltmask); 1017 prunlock(pnp); 1018 break; 1019 1020 case PIOCCFAULT: /* clear current fault */ 1021 lwp->lwp_curflt = 0; 1022 prunlock(pnp); 1023 break; 1024 1025 case PIOCCRED: /* get process credentials */ 1026 { 1027 cred_t *cp; 1028 1029 mutex_enter(&p->p_crlock); 1030 cp = p->p_cred; 1031 un.prcred.pr_euid = crgetuid(cp); 1032 un.prcred.pr_ruid = crgetruid(cp); 1033 un.prcred.pr_suid = crgetsuid(cp); 1034 un.prcred.pr_egid = crgetgid(cp); 1035 un.prcred.pr_rgid = crgetrgid(cp); 1036 un.prcred.pr_sgid = crgetsgid(cp); 1037 un.prcred.pr_ngroups = crgetngroups(cp); 1038 mutex_exit(&p->p_crlock); 1039 1040 prunlock(pnp); 1041 if (copyout(&un.prcred, cmaddr, sizeof (un.prcred))) 1042 error = EFAULT; 1043 break; 1044 } 1045 1046 case PIOCGROUPS: /* get supplementary groups */ 1047 { 1048 cred_t *cp; 1049 1050 mutex_enter(&p->p_crlock); 1051 cp = p->p_cred; 1052 crhold(cp); 1053 mutex_exit(&p->p_crlock); 1054 1055 prunlock(pnp); 1056 if (copyout(crgetgroups(cp), cmaddr, 1057 MAX(crgetngroups(cp), 1) * sizeof (gid_t))) 1058 error = EFAULT; 1059 crfree(cp); 1060 break; 1061 } 1062 1063 case PIOCUSAGE: /* get usage info */ 1064 { 1065 /* 1066 * For an lwp file descriptor, return just the lwp usage. 1067 * For a process file descriptor, return total usage, 1068 * all current lwps plus all defunct lwps. 1069 */ 1070 prhusage_t *pup = &un.prhusage; 1071 prusage_t *upup; 1072 1073 bzero(pup, sizeof (*pup)); 1074 pup->pr_tstamp = gethrtime(); 1075 1076 if (pnp->pr_type == PR_LWPIDFILE) { 1077 t = pcp->prc_thread; 1078 if (t != NULL) 1079 prgetusage(t, pup); 1080 else 1081 error = ENOENT; 1082 } else { 1083 pup->pr_count = p->p_defunct; 1084 pup->pr_create = p->p_mstart; 1085 pup->pr_term = p->p_mterm; 1086 1087 pup->pr_rtime = p->p_mlreal; 1088 pup->pr_utime = p->p_acct[LMS_USER]; 1089 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 1090 pup->pr_ttime = p->p_acct[LMS_TRAP]; 1091 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 1092 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 1093 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 1094 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 1095 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 1096 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 1097 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 1098 1099 pup->pr_minf = p->p_ru.minflt; 1100 pup->pr_majf = p->p_ru.majflt; 1101 pup->pr_nswap = p->p_ru.nswap; 1102 pup->pr_inblk = p->p_ru.inblock; 1103 pup->pr_oublk = p->p_ru.oublock; 1104 pup->pr_msnd = p->p_ru.msgsnd; 1105 pup->pr_mrcv = p->p_ru.msgrcv; 1106 pup->pr_sigs = p->p_ru.nsignals; 1107 pup->pr_vctx = p->p_ru.nvcsw; 1108 pup->pr_ictx = p->p_ru.nivcsw; 1109 pup->pr_sysc = p->p_ru.sysc; 1110 pup->pr_ioch = p->p_ru.ioch; 1111 1112 /* 1113 * Add the usage information for each active lwp. 1114 */ 1115 if ((t = p->p_tlist) != NULL && 1116 !(pcp->prc_flags & PRC_DESTROY)) { 1117 do { 1118 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 1119 pup->pr_count++; 1120 praddusage(t, pup); 1121 } while ((t = t->t_forw) != p->p_tlist); 1122 } 1123 } 1124 1125 prunlock(pnp); 1126 1127 upup = kmem_zalloc(sizeof (*upup), KM_SLEEP); 1128 prcvtusage(&un.prhusage, upup); 1129 if (copyout(upup, cmaddr, sizeof (*upup))) 1130 error = EFAULT; 1131 kmem_free(upup, sizeof (*upup)); 1132 1133 break; 1134 } 1135 1136 case PIOCLUSAGE: /* get detailed usage info */ 1137 { 1138 int Nlwp; 1139 int nlwp; 1140 prusage_t *upup; 1141 prusage_t *Bupup; 1142 prhusage_t *pup; 1143 hrtime_t curtime; 1144 1145 nlwp = Nlwp = (pcp->prc_flags & PRC_DESTROY)? 0 : p->p_lwpcnt; 1146 1147 if (thing && thingsize != 1148 sizeof (prhusage_t) + (Nlwp+1) * sizeof (prusage_t)) { 1149 kmem_free(thing, thingsize); 1150 thing = NULL; 1151 } 1152 if (thing == NULL) { 1153 thingsize = sizeof (prhusage_t) + 1154 (Nlwp+1) * sizeof (prusage_t); 1155 thing = kmem_alloc(thingsize, KM_NOSLEEP); 1156 } 1157 if (thing == NULL) { 1158 prunlock(pnp); 1159 goto startover; 1160 } 1161 1162 pup = thing; 1163 upup = Bupup = (prusage_t *)(pup + 1); 1164 1165 ASSERT(p == pcp->prc_proc); 1166 1167 curtime = gethrtime(); 1168 1169 /* 1170 * First the summation over defunct lwps. 1171 */ 1172 bzero(pup, sizeof (*pup)); 1173 pup->pr_count = p->p_defunct; 1174 pup->pr_tstamp = curtime; 1175 pup->pr_create = p->p_mstart; 1176 pup->pr_term = p->p_mterm; 1177 1178 pup->pr_rtime = p->p_mlreal; 1179 pup->pr_utime = p->p_acct[LMS_USER]; 1180 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 1181 pup->pr_ttime = p->p_acct[LMS_TRAP]; 1182 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 1183 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 1184 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 1185 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 1186 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 1187 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 1188 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 1189 1190 pup->pr_minf = p->p_ru.minflt; 1191 pup->pr_majf = p->p_ru.majflt; 1192 pup->pr_nswap = p->p_ru.nswap; 1193 pup->pr_inblk = p->p_ru.inblock; 1194 pup->pr_oublk = p->p_ru.oublock; 1195 pup->pr_msnd = p->p_ru.msgsnd; 1196 pup->pr_mrcv = p->p_ru.msgrcv; 1197 pup->pr_sigs = p->p_ru.nsignals; 1198 pup->pr_vctx = p->p_ru.nvcsw; 1199 pup->pr_ictx = p->p_ru.nivcsw; 1200 pup->pr_sysc = p->p_ru.sysc; 1201 pup->pr_ioch = p->p_ru.ioch; 1202 1203 prcvtusage(pup, upup); 1204 1205 /* 1206 * Fill one prusage struct for each active lwp. 1207 */ 1208 if ((t = p->p_tlist) != NULL && 1209 !(pcp->prc_flags & PRC_DESTROY)) { 1210 do { 1211 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 1212 ASSERT(nlwp > 0); 1213 --nlwp; 1214 upup++; 1215 prgetusage(t, pup); 1216 prcvtusage(pup, upup); 1217 } while ((t = t->t_forw) != p->p_tlist); 1218 } 1219 ASSERT(nlwp == 0); 1220 1221 prunlock(pnp); 1222 if (copyout(Bupup, cmaddr, (Nlwp+1) * sizeof (prusage_t))) 1223 error = EFAULT; 1224 kmem_free(thing, thingsize); 1225 thing = NULL; 1226 break; 1227 } 1228 1229 case PIOCNAUXV: /* get number of aux vector entries */ 1230 { 1231 int n = __KERN_NAUXV_IMPL; 1232 1233 prunlock(pnp); 1234 if (copyout(&n, cmaddr, sizeof (int))) 1235 error = EFAULT; 1236 break; 1237 } 1238 1239 case PIOCAUXV: /* get aux vector (see sys/auxv.h) */ 1240 { 1241 up = PTOU(p); 1242 bcopy(up->u_auxv, un.auxv, 1243 __KERN_NAUXV_IMPL * sizeof (auxv_t)); 1244 prunlock(pnp); 1245 if (copyout(un.auxv, cmaddr, 1246 __KERN_NAUXV_IMPL * sizeof (auxv_t))) 1247 error = EFAULT; 1248 break; 1249 } 1250 1251 #if defined(__i386) || defined(__amd64) 1252 case PIOCNLDT: /* get number of LDT entries */ 1253 { 1254 int n; 1255 1256 mutex_exit(&p->p_lock); 1257 mutex_enter(&p->p_ldtlock); 1258 n = prnldt(p); 1259 mutex_exit(&p->p_ldtlock); 1260 mutex_enter(&p->p_lock); 1261 prunlock(pnp); 1262 if (copyout(&n, cmaddr, sizeof (n))) 1263 error = EFAULT; 1264 break; 1265 } 1266 1267 case PIOCLDT: /* get LDT entries */ 1268 { 1269 struct ssd *ssd; 1270 int n; 1271 1272 mutex_exit(&p->p_lock); 1273 mutex_enter(&p->p_ldtlock); 1274 n = prnldt(p); 1275 1276 if (thing && thingsize != (n+1) * sizeof (*ssd)) { 1277 kmem_free(thing, thingsize); 1278 thing = NULL; 1279 } 1280 if (thing == NULL) { 1281 thingsize = (n+1) * sizeof (*ssd); 1282 thing = kmem_alloc(thingsize, KM_NOSLEEP); 1283 } 1284 if (thing == NULL) { 1285 mutex_exit(&p->p_ldtlock); 1286 mutex_enter(&p->p_lock); 1287 prunlock(pnp); 1288 goto startover; 1289 } 1290 1291 ssd = thing; 1292 thing = NULL; 1293 if (n != 0) 1294 prgetldt(p, ssd); 1295 mutex_exit(&p->p_ldtlock); 1296 mutex_enter(&p->p_lock); 1297 prunlock(pnp); 1298 1299 /* mark the end of the list with a null entry */ 1300 bzero(&ssd[n], sizeof (*ssd)); 1301 if (copyout(ssd, cmaddr, (n+1) * sizeof (*ssd))) 1302 error = EFAULT; 1303 kmem_free(ssd, (n+1) * sizeof (*ssd)); 1304 break; 1305 } 1306 #endif /* __i386 || __amd64 */ 1307 1308 #if defined(__sparc) 1309 case PIOCGWIN: /* get gwindows_t (see sys/reg.h) */ 1310 { 1311 gwindows_t *gwp = thing; 1312 1313 /* drop p->p_lock while touching the stack */ 1314 mutex_exit(&p->p_lock); 1315 bzero(gwp, sizeof (*gwp)); 1316 prgetwindows(lwp, gwp); 1317 mutex_enter(&p->p_lock); 1318 prunlock(pnp); 1319 if (copyout(gwp, cmaddr, sizeof (*gwp))) 1320 error = EFAULT; 1321 kmem_free(gwp, sizeof (gwindows_t)); 1322 thing = NULL; 1323 break; 1324 } 1325 #endif /* __sparc */ 1326 1327 default: 1328 prunlock(pnp); 1329 error = EINVAL; 1330 break; 1331 1332 } 1333 1334 ASSERT(thing == NULL); 1335 ASSERT(xpnp == NULL); 1336 return (error); 1337 } 1338 1339 #ifdef _SYSCALL32_IMPL 1340 1341 static int oprgetmap32(proc_t *, list_t *); 1342 1343 void 1344 oprgetstatus32(kthread_t *t, prstatus32_t *sp, zone_t *zp) 1345 { 1346 proc_t *p = ttoproc(t); 1347 klwp_t *lwp = ttolwp(t); 1348 int32_t flags; 1349 user_t *up; 1350 ulong_t instr; 1351 1352 ASSERT(MUTEX_HELD(&p->p_lock)); 1353 1354 up = PTOU(p); 1355 bzero(sp, sizeof (*sp)); 1356 flags = 0L; 1357 if (t->t_state == TS_STOPPED) { 1358 flags |= PR_STOPPED; 1359 if ((t->t_schedflag & TS_PSTART) == 0) 1360 flags |= PR_ISTOP; 1361 } else if (VSTOPPED(t)) { 1362 flags |= PR_STOPPED|PR_ISTOP; 1363 } 1364 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP)) 1365 flags |= PR_DSTOP; 1366 if (lwp->lwp_asleep) 1367 flags |= PR_ASLEEP; 1368 if (p->p_proc_flag & P_PR_FORK) 1369 flags |= PR_FORK; 1370 if (p->p_proc_flag & P_PR_RUNLCL) 1371 flags |= PR_RLC; 1372 if (p->p_proc_flag & P_PR_KILLCL) 1373 flags |= PR_KLC; 1374 if (p->p_proc_flag & P_PR_ASYNC) 1375 flags |= PR_ASYNC; 1376 if (p->p_proc_flag & P_PR_BPTADJ) 1377 flags |= PR_BPTADJ; 1378 if (p->p_proc_flag & P_PR_PTRACE) 1379 flags |= PR_PCOMPAT; 1380 if (t->t_proc_flag & TP_MSACCT) 1381 flags |= PR_MSACCT; 1382 sp->pr_flags = flags; 1383 if (VSTOPPED(t)) { 1384 sp->pr_why = PR_REQUESTED; 1385 sp->pr_what = 0; 1386 } else { 1387 sp->pr_why = t->t_whystop; 1388 sp->pr_what = t->t_whatstop; 1389 } 1390 1391 if (t->t_whystop == PR_FAULTED) { 1392 siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info); 1393 if (t->t_whatstop == FLTPAGE) 1394 sp->pr_info.si_addr = 1395 (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr; 1396 } else if (lwp->lwp_curinfo) 1397 siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info); 1398 1399 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID && 1400 sp->pr_info.si_zoneid != zp->zone_id) { 1401 sp->pr_info.si_pid = zp->zone_zsched->p_pid; 1402 sp->pr_info.si_uid = 0; 1403 sp->pr_info.si_ctid = -1; 1404 sp->pr_info.si_zoneid = zp->zone_id; 1405 } 1406 1407 sp->pr_cursig = lwp->lwp_cursig; 1408 prassignset(&sp->pr_sigpend, &p->p_sig); 1409 prassignset(&sp->pr_lwppend, &t->t_sig); 1410 schedctl_finish_sigblock(t); 1411 prassignset(&sp->pr_sighold, &t->t_hold); 1412 sp->pr_altstack.ss_sp = 1413 (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp; 1414 sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size; 1415 sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags; 1416 prgetaction32(p, up, lwp->lwp_cursig, &sp->pr_action); 1417 sp->pr_pid = p->p_pid; 1418 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 1419 (p->p_flag & SZONETOP)) { 1420 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 1421 /* 1422 * Inside local zones, fake zsched's pid as parent pids for 1423 * processes which reference processes outside of the zone. 1424 */ 1425 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 1426 } else { 1427 sp->pr_ppid = p->p_ppid; 1428 } 1429 sp->pr_pgrp = p->p_pgrp; 1430 sp->pr_sid = p->p_sessp->s_sid; 1431 hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime); 1432 hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime); 1433 TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime); 1434 TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime); 1435 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name, 1436 sizeof (sp->pr_clname) - 1); 1437 sp->pr_who = t->t_tid; 1438 sp->pr_nlwp = p->p_lwpcnt; 1439 sp->pr_brkbase = (caddr32_t)(uintptr_t)p->p_brkbase; 1440 sp->pr_brksize = (size32_t)p->p_brksize; 1441 sp->pr_stkbase = (caddr32_t)(uintptr_t)prgetstackbase(p); 1442 sp->pr_stksize = (size32_t)p->p_stksize; 1443 sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext; 1444 sp->pr_processor = t->t_cpu->cpu_id; 1445 sp->pr_bind = t->t_bind_cpu; 1446 1447 /* 1448 * Fetch the current instruction, if not a system process. 1449 * We don't attempt this unless the lwp is stopped. 1450 */ 1451 if ((p->p_flag & SSYS) || p->p_as == &kas) 1452 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL); 1453 else if (!(flags & PR_STOPPED)) 1454 sp->pr_flags |= PR_PCINVAL; 1455 else if (!prfetchinstr(lwp, &instr)) 1456 sp->pr_flags |= PR_PCINVAL; 1457 else 1458 sp->pr_instr = (uint32_t)instr; 1459 1460 /* 1461 * Drop p_lock while touching the lwp's stack. 1462 */ 1463 mutex_exit(&p->p_lock); 1464 if (prisstep(lwp)) 1465 sp->pr_flags |= PR_STEP; 1466 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) { 1467 int i; 1468 auxv_t *auxp; 1469 1470 sp->pr_syscall = get_syscall32_args(lwp, 1471 (int *)sp->pr_sysarg, &i); 1472 sp->pr_nsysarg = (short)i; 1473 if (t->t_whystop == PR_SYSEXIT && t->t_sysnum == SYS_execve) { 1474 sp->pr_sysarg[0] = 0; 1475 sp->pr_sysarg[1] = (caddr32_t)up->u_argv; 1476 sp->pr_sysarg[2] = (caddr32_t)up->u_envp; 1477 for (i = 0, auxp = up->u_auxv; 1478 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]); 1479 i++, auxp++) { 1480 if (auxp->a_type == AT_SUN_EXECNAME) { 1481 sp->pr_sysarg[0] = 1482 (caddr32_t) 1483 (uintptr_t)auxp->a_un.a_ptr; 1484 break; 1485 } 1486 } 1487 } 1488 } 1489 if ((flags & PR_STOPPED) || t == curthread) 1490 prgetprregs32(lwp, sp->pr_reg); 1491 mutex_enter(&p->p_lock); 1492 } 1493 1494 void 1495 oprgetpsinfo32(proc_t *p, prpsinfo32_t *psp, kthread_t *tp) 1496 { 1497 kthread_t *t; 1498 char c, state; 1499 user_t *up; 1500 dev_t d; 1501 uint64_t pct; 1502 int retval, niceval; 1503 cred_t *cred; 1504 struct as *as; 1505 hrtime_t hrutime, hrstime, cur_time; 1506 1507 ASSERT(MUTEX_HELD(&p->p_lock)); 1508 1509 bzero(psp, sizeof (*psp)); 1510 1511 if ((t = tp) == NULL) 1512 t = prchoose(p); /* returns locked thread */ 1513 else 1514 thread_lock(t); 1515 1516 /* kludge: map thread state enum into process state enum */ 1517 1518 if (t == NULL) { 1519 state = TS_ZOMB; 1520 } else { 1521 state = VSTOPPED(t) ? TS_STOPPED : t->t_state; 1522 thread_unlock(t); 1523 } 1524 1525 switch (state) { 1526 case TS_SLEEP: state = SSLEEP; break; 1527 case TS_RUN: state = SRUN; break; 1528 case TS_ONPROC: state = SONPROC; break; 1529 case TS_ZOMB: state = SZOMB; break; 1530 case TS_STOPPED: state = SSTOP; break; 1531 default: state = 0; break; 1532 } 1533 switch (state) { 1534 case SSLEEP: c = 'S'; break; 1535 case SRUN: c = 'R'; break; 1536 case SZOMB: c = 'Z'; break; 1537 case SSTOP: c = 'T'; break; 1538 case SIDL: c = 'I'; break; 1539 case SONPROC: c = 'O'; break; 1540 #ifdef SXBRK 1541 case SXBRK: c = 'X'; break; 1542 #endif 1543 default: c = '?'; break; 1544 } 1545 psp->pr_state = state; 1546 psp->pr_sname = c; 1547 psp->pr_zomb = (state == SZOMB); 1548 /* 1549 * only export SSYS and SMSACCT; everything else is off-limits to 1550 * userland apps. 1551 */ 1552 psp->pr_flag = p->p_flag & (SSYS | SMSACCT); 1553 1554 mutex_enter(&p->p_crlock); 1555 cred = p->p_cred; 1556 psp->pr_uid = crgetruid(cred); 1557 psp->pr_gid = crgetrgid(cred); 1558 psp->pr_euid = crgetuid(cred); 1559 psp->pr_egid = crgetgid(cred); 1560 mutex_exit(&p->p_crlock); 1561 1562 psp->pr_pid = p->p_pid; 1563 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 1564 (p->p_flag & SZONETOP)) { 1565 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 1566 /* 1567 * Inside local zones, fake zsched's pid as parent pids for 1568 * processes which reference processes outside of the zone. 1569 */ 1570 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 1571 } else { 1572 psp->pr_ppid = p->p_ppid; 1573 } 1574 psp->pr_pgrp = p->p_pgrp; 1575 psp->pr_sid = p->p_sessp->s_sid; 1576 psp->pr_addr = 0; /* cannot represent 64-bit addr in 32 bits */ 1577 hrutime = mstate_aggr_state(p, LMS_USER); 1578 hrstime = mstate_aggr_state(p, LMS_SYSTEM); 1579 hrt2ts32(hrutime + hrstime, &psp->pr_time); 1580 TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime); 1581 switch (p->p_model) { 1582 case DATAMODEL_ILP32: 1583 psp->pr_dmodel = PR_MODEL_ILP32; 1584 break; 1585 case DATAMODEL_LP64: 1586 psp->pr_dmodel = PR_MODEL_LP64; 1587 break; 1588 } 1589 if (state == SZOMB || t == NULL) { 1590 int wcode = p->p_wcode; /* must be atomic read */ 1591 1592 if (wcode) 1593 psp->pr_wstat = wstat(wcode, p->p_wdata); 1594 psp->pr_lttydev = PRNODEV32; 1595 psp->pr_ottydev = (o_dev_t)PRNODEV32; 1596 psp->pr_size = 0; 1597 psp->pr_rssize = 0; 1598 psp->pr_pctmem = 0; 1599 } else { 1600 up = PTOU(p); 1601 psp->pr_wchan = 0; /* cannot represent in 32 bits */ 1602 psp->pr_pri = t->t_pri; 1603 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name, 1604 sizeof (psp->pr_clname) - 1); 1605 retval = CL_DONICE(t, NULL, 0, &niceval); 1606 if (retval == 0) { 1607 psp->pr_oldpri = v.v_maxsyspri - psp->pr_pri; 1608 psp->pr_nice = niceval + NZERO; 1609 } else { 1610 psp->pr_oldpri = 0; 1611 psp->pr_nice = 0; 1612 } 1613 d = cttydev(p); 1614 #ifdef sun 1615 { 1616 extern dev_t rwsconsdev, rconsdev, uconsdev; 1617 /* 1618 * If the controlling terminal is the real 1619 * or workstation console device, map to what the 1620 * user thinks is the console device. Handle case when 1621 * rwsconsdev or rconsdev is set to NODEV for Starfire. 1622 */ 1623 if ((d == rwsconsdev || d == rconsdev) && d != NODEV) 1624 d = uconsdev; 1625 } 1626 #endif 1627 (void) cmpldev(&psp->pr_lttydev, d); 1628 psp->pr_ottydev = cmpdev(d); 1629 TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start); 1630 bcopy(up->u_comm, psp->pr_fname, 1631 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1)); 1632 bcopy(up->u_psargs, psp->pr_psargs, 1633 MIN(PRARGSZ-1, PSARGSZ)); 1634 psp->pr_syscall = t->t_sysnum; 1635 psp->pr_argc = up->u_argc; 1636 psp->pr_argv = (caddr32_t)up->u_argv; 1637 psp->pr_envp = (caddr32_t)up->u_envp; 1638 1639 /* compute %cpu for the lwp or process */ 1640 pct = 0; 1641 if ((t = tp) == NULL) 1642 t = p->p_tlist; 1643 cur_time = gethrtime_unscaled(); 1644 do { 1645 pct += cpu_update_pct(t, cur_time); 1646 if (tp != NULL) /* just do the one lwp */ 1647 break; 1648 } while ((t = t->t_forw) != p->p_tlist); 1649 1650 psp->pr_pctcpu = prgetpctcpu(pct); 1651 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */ 1652 if (psp->pr_cpu > 99) 1653 psp->pr_cpu = 99; 1654 1655 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 1656 psp->pr_size = 0; 1657 psp->pr_rssize = 0; 1658 psp->pr_pctmem = 0; 1659 } else { 1660 mutex_exit(&p->p_lock); 1661 AS_LOCK_ENTER(as, RW_READER); 1662 psp->pr_size = (size32_t)btopr(as->a_resvsize); 1663 psp->pr_rssize = (size32_t)rm_asrss(as); 1664 psp->pr_pctmem = rm_pctmemory(as); 1665 AS_LOCK_EXIT(as); 1666 mutex_enter(&p->p_lock); 1667 } 1668 } 1669 psp->pr_bysize = (size32_t)ptob(psp->pr_size); 1670 psp->pr_byrssize = (size32_t)ptob(psp->pr_rssize); 1671 1672 /* 1673 * If we are looking at an LP64 process, zero out 1674 * the fields that cannot be represented in ILP32. 1675 */ 1676 if (p->p_model != DATAMODEL_ILP32) { 1677 psp->pr_size = 0; 1678 psp->pr_rssize = 0; 1679 psp->pr_bysize = 0; 1680 psp->pr_byrssize = 0; 1681 psp->pr_argv = 0; 1682 psp->pr_envp = 0; 1683 } 1684 } 1685 1686 /*ARGSUSED*/ 1687 static int 1688 prioctl32( 1689 struct vnode *vp, 1690 int cmd, 1691 intptr_t arg, 1692 int flag, 1693 cred_t *cr, 1694 int *rvalp, 1695 caller_context_t *ct) 1696 { 1697 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 1698 caddr_t cmaddr = (caddr_t)arg; 1699 proc_t *p; 1700 user_t *up; 1701 kthread_t *t; 1702 klwp_t *lwp; 1703 prnode_t *pnp = VTOP(vp); 1704 prcommon_t *pcp; 1705 prnode_t *xpnp = NULL; 1706 int error; 1707 int zdisp; 1708 void *thing = NULL; 1709 size_t thingsize = 0; 1710 1711 /* 1712 * For copyin()/copyout(). 1713 */ 1714 union { 1715 caddr32_t va; 1716 int signo; 1717 int nice; 1718 uint_t lwpid; 1719 int32_t flags; 1720 prstatus32_t prstat; 1721 prrun32_t prrun; 1722 sigset_t smask; 1723 siginfo32_t info; 1724 sysset_t prmask; 1725 prgregset32_t regs; 1726 prfpregset32_t fpregs; 1727 prpsinfo32_t prps; 1728 sigset_t holdmask; 1729 fltset_t fltmask; 1730 prcred_t prcred; 1731 prusage32_t prusage; 1732 prhusage_t prhusage; 1733 ioc_prmap32_t prmap; 1734 auxv32_t auxv[__KERN_NAUXV_IMPL]; 1735 } un32; 1736 1737 /* 1738 * Native objects for internal use. 1739 */ 1740 union { 1741 caddr_t va; 1742 int signo; 1743 int nice; 1744 uint_t lwpid; 1745 long flags; 1746 prstatus_t prstat; 1747 prrun_t prrun; 1748 sigset_t smask; 1749 siginfo_t info; 1750 sysset_t prmask; 1751 prgregset_t regs; 1752 prpsinfo_t prps; 1753 sigset_t holdmask; 1754 fltset_t fltmask; 1755 prcred_t prcred; 1756 prusage_t prusage; 1757 prhusage_t prhusage; 1758 auxv_t auxv[__KERN_NAUXV_IMPL]; 1759 } un; 1760 1761 if (pnp->pr_type == PR_TMPL) 1762 return (prctioctl(pnp, cmd, arg, flag, cr)); 1763 1764 /* 1765 * Support for old /proc interface. 1766 */ 1767 if (pnp->pr_pidfile != NULL) { 1768 ASSERT(pnp->pr_type == PR_PIDDIR); 1769 vp = pnp->pr_pidfile; 1770 pnp = VTOP(vp); 1771 ASSERT(pnp->pr_type == PR_PIDFILE); 1772 } 1773 1774 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE) 1775 return (ENOTTY); 1776 1777 /* 1778 * Fail ioctls which are logically "write" requests unless 1779 * the user has write permission. 1780 */ 1781 if ((flag & FWRITE) == 0 && isprwrioctl(cmd)) 1782 return (EBADF); 1783 1784 /* 1785 * Perform any necessary copyin() operations before 1786 * locking the process. Helps avoid deadlocks and 1787 * improves performance. 1788 * 1789 * Also, detect invalid ioctl codes here to avoid 1790 * locking a process unnnecessarily. 1791 * 1792 * Also, prepare to allocate space that will be needed below, 1793 * case by case. 1794 */ 1795 error = 0; 1796 switch (cmd) { 1797 case PIOCGETPR: 1798 thingsize = sizeof (proc_t); 1799 break; 1800 case PIOCGETU: 1801 thingsize = sizeof (user_t); 1802 break; 1803 case PIOCSTOP: 1804 case PIOCWSTOP: 1805 case PIOCLWPIDS: 1806 case PIOCGTRACE: 1807 case PIOCGENTRY: 1808 case PIOCGEXIT: 1809 case PIOCSRLC: 1810 case PIOCRRLC: 1811 case PIOCSFORK: 1812 case PIOCRFORK: 1813 case PIOCGREG: 1814 case PIOCGFPREG: 1815 case PIOCSTATUS: 1816 case PIOCLSTATUS: 1817 case PIOCPSINFO: 1818 case PIOCMAXSIG: 1819 case PIOCGXREGSIZE: 1820 break; 1821 case PIOCSXREG: /* set extra registers */ 1822 case PIOCGXREG: /* get extra registers */ 1823 #if defined(__sparc) 1824 thingsize = sizeof (prxregset_t); 1825 #else 1826 thingsize = 0; 1827 #endif 1828 break; 1829 case PIOCACTION: 1830 thingsize = (nsig-1) * sizeof (struct sigaction32); 1831 break; 1832 case PIOCGHOLD: 1833 case PIOCNMAP: 1834 case PIOCMAP: 1835 case PIOCGFAULT: 1836 case PIOCCFAULT: 1837 case PIOCCRED: 1838 case PIOCGROUPS: 1839 case PIOCUSAGE: 1840 case PIOCLUSAGE: 1841 break; 1842 case PIOCOPENPD: 1843 /* 1844 * We will need this below. 1845 * Allocate it now, before locking the process. 1846 */ 1847 xpnp = prgetnode(vp, PR_OPAGEDATA); 1848 break; 1849 case PIOCNAUXV: 1850 case PIOCAUXV: 1851 break; 1852 1853 #if defined(__i386) || defined(__i386_COMPAT) 1854 case PIOCNLDT: 1855 case PIOCLDT: 1856 break; 1857 #endif /* __i386 || __i386_COMPAT */ 1858 1859 #if defined(__sparc) 1860 case PIOCGWIN: 1861 thingsize = sizeof (gwindows32_t); 1862 break; 1863 #endif /* __sparc */ 1864 1865 case PIOCOPENM: /* open mapped object for reading */ 1866 if (cmaddr == NULL) 1867 un32.va = NULL; 1868 else if (copyin(cmaddr, &un32.va, sizeof (un32.va))) 1869 error = EFAULT; 1870 break; 1871 1872 case PIOCRUN: /* make lwp or process runnable */ 1873 if (cmaddr == NULL) 1874 un32.prrun.pr_flags = 0; 1875 else if (copyin(cmaddr, &un32.prrun, sizeof (un32.prrun))) 1876 error = EFAULT; 1877 break; 1878 1879 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 1880 if (copyin(cmaddr, &un32.lwpid, sizeof (un32.lwpid))) 1881 error = EFAULT; 1882 break; 1883 1884 case PIOCSTRACE: /* set signal trace mask */ 1885 if (copyin(cmaddr, &un32.smask, sizeof (un32.smask))) 1886 error = EFAULT; 1887 break; 1888 1889 case PIOCSSIG: /* set current signal */ 1890 if (cmaddr == NULL) 1891 un32.info.si_signo = 0; 1892 else if (copyin(cmaddr, &un32.info, sizeof (un32.info))) 1893 error = EFAULT; 1894 break; 1895 1896 case PIOCKILL: /* send signal */ 1897 case PIOCUNKILL: /* delete a signal */ 1898 if (copyin(cmaddr, &un32.signo, sizeof (un32.signo))) 1899 error = EFAULT; 1900 break; 1901 1902 case PIOCNICE: /* set nice priority */ 1903 if (copyin(cmaddr, &un32.nice, sizeof (un32.nice))) 1904 error = EFAULT; 1905 break; 1906 1907 case PIOCSENTRY: /* set syscall entry bit mask */ 1908 case PIOCSEXIT: /* set syscall exit bit mask */ 1909 if (copyin(cmaddr, &un32.prmask, sizeof (un32.prmask))) 1910 error = EFAULT; 1911 break; 1912 1913 case PIOCSET: /* set process flags */ 1914 case PIOCRESET: /* reset process flags */ 1915 if (copyin(cmaddr, &un32.flags, sizeof (un32.flags))) 1916 error = EFAULT; 1917 break; 1918 1919 case PIOCSREG: /* set general registers */ 1920 if (copyin(cmaddr, un32.regs, sizeof (un32.regs))) 1921 error = EFAULT; 1922 break; 1923 1924 case PIOCSFPREG: /* set floating-point registers */ 1925 if (copyin(cmaddr, &un32.fpregs, sizeof (un32.fpregs))) 1926 error = EFAULT; 1927 break; 1928 1929 case PIOCSHOLD: /* set signal-hold mask */ 1930 if (copyin(cmaddr, &un32.holdmask, sizeof (un32.holdmask))) 1931 error = EFAULT; 1932 break; 1933 1934 case PIOCSFAULT: /* set mask of traced faults */ 1935 if (copyin(cmaddr, &un32.fltmask, sizeof (un32.fltmask))) 1936 error = EFAULT; 1937 break; 1938 1939 default: 1940 error = EINVAL; 1941 break; 1942 } 1943 1944 if (error) 1945 return (error); 1946 1947 startover: 1948 /* 1949 * If we need kmem_alloc()d space then we allocate it now, before 1950 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while 1951 * holding the process lock leads to deadlock with the clock thread. 1952 * (The clock thread wakes up the pageout daemon to free up space. 1953 * If the clock thread blocks behind us and we are sleeping waiting 1954 * for space, then space may never become available.) 1955 */ 1956 if (thingsize) { 1957 ASSERT(thing == NULL); 1958 thing = kmem_alloc(thingsize, KM_SLEEP); 1959 } 1960 1961 switch (cmd) { 1962 case PIOCPSINFO: 1963 case PIOCGETPR: 1964 case PIOCUSAGE: 1965 case PIOCLUSAGE: 1966 zdisp = ZYES; 1967 break; 1968 case PIOCSXREG: /* set extra registers */ 1969 /* 1970 * perform copyin before grabbing the process lock 1971 */ 1972 if (thing) { 1973 if (copyin(cmaddr, thing, thingsize)) { 1974 kmem_free(thing, thingsize); 1975 return (EFAULT); 1976 } 1977 } 1978 /* fall through... */ 1979 default: 1980 zdisp = ZNO; 1981 break; 1982 } 1983 1984 if ((error = prlock(pnp, zdisp)) != 0) { 1985 if (thing != NULL) 1986 kmem_free(thing, thingsize); 1987 if (xpnp) 1988 prfreenode(xpnp); 1989 return (error); 1990 } 1991 1992 pcp = pnp->pr_common; 1993 p = pcp->prc_proc; 1994 ASSERT(p != NULL); 1995 1996 /* 1997 * Choose a thread/lwp for the operation. 1998 */ 1999 if (zdisp == ZNO && cmd != PIOCSTOP && cmd != PIOCWSTOP) { 2000 if (pnp->pr_type == PR_LWPIDFILE && cmd != PIOCLSTATUS) { 2001 t = pcp->prc_thread; 2002 ASSERT(t != NULL); 2003 } else { 2004 t = prchoose(p); /* returns locked thread */ 2005 ASSERT(t != NULL); 2006 thread_unlock(t); 2007 } 2008 lwp = ttolwp(t); 2009 } 2010 2011 error = 0; 2012 switch (cmd) { 2013 2014 case PIOCGETPR: /* read struct proc */ 2015 { 2016 proc_t *prp = thing; 2017 2018 *prp = *p; 2019 prunlock(pnp); 2020 if (copyout(prp, cmaddr, sizeof (proc_t))) 2021 error = EFAULT; 2022 kmem_free(prp, sizeof (proc_t)); 2023 thing = NULL; 2024 break; 2025 } 2026 2027 case PIOCGETU: /* read u-area */ 2028 { 2029 user_t *userp = thing; 2030 2031 up = PTOU(p); 2032 *userp = *up; 2033 prunlock(pnp); 2034 if (copyout(userp, cmaddr, sizeof (user_t))) 2035 error = EFAULT; 2036 kmem_free(userp, sizeof (user_t)); 2037 thing = NULL; 2038 break; 2039 } 2040 2041 case PIOCOPENM: /* open mapped object for reading */ 2042 if (PROCESS_NOT_32BIT(p) && cmaddr != NULL) { 2043 prunlock(pnp); 2044 error = EOVERFLOW; 2045 break; 2046 } 2047 error = propenm(pnp, cmaddr, 2048 (caddr_t)(uintptr_t)un32.va, rvalp, cr); 2049 /* propenm() called prunlock(pnp) */ 2050 break; 2051 2052 case PIOCSTOP: /* stop process or lwp from running */ 2053 case PIOCWSTOP: /* wait for process or lwp to stop */ 2054 /* 2055 * Can't apply to a system process. 2056 */ 2057 if ((p->p_flag & SSYS) || p->p_as == &kas) { 2058 prunlock(pnp); 2059 error = EBUSY; 2060 break; 2061 } 2062 2063 if (cmd == PIOCSTOP) 2064 pr_stop(pnp); 2065 2066 /* 2067 * If an lwp is waiting for itself or its process, don't wait. 2068 * The lwp will never see the fact that itself is stopped. 2069 */ 2070 if ((pnp->pr_type == PR_LWPIDFILE)? 2071 (pcp->prc_thread == curthread) : (p == curproc)) { 2072 if (cmd == PIOCWSTOP) 2073 error = EBUSY; 2074 prunlock(pnp); 2075 break; 2076 } 2077 2078 if ((error = pr_wait_stop(pnp, (time_t)0)) != 0) 2079 break; /* pr_wait_stop() unlocked the process */ 2080 2081 if (cmaddr == NULL) 2082 prunlock(pnp); 2083 else if (PROCESS_NOT_32BIT(p)) { 2084 prunlock(pnp); 2085 error = EOVERFLOW; 2086 } else { 2087 /* 2088 * Return process/lwp status information. 2089 */ 2090 t = pr_thread(pnp); /* returns locked thread */ 2091 thread_unlock(t); 2092 oprgetstatus32(t, &un32.prstat, VTOZONE(vp)); 2093 prunlock(pnp); 2094 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat))) 2095 error = EFAULT; 2096 } 2097 break; 2098 2099 case PIOCRUN: /* make lwp or process runnable */ 2100 { 2101 long flags = un32.prrun.pr_flags; 2102 2103 /* 2104 * Cannot set an lwp running is it is not stopped. 2105 * Also, no lwp other than the /proc agent lwp can 2106 * be set running so long as the /proc agent lwp exists. 2107 */ 2108 if ((!ISTOPPED(t) && !VSTOPPED(t) && 2109 !(t->t_proc_flag & TP_PRSTOP)) || 2110 (p->p_agenttp != NULL && 2111 (t != p->p_agenttp || pnp->pr_type != PR_LWPIDFILE))) { 2112 prunlock(pnp); 2113 error = EBUSY; 2114 break; 2115 } 2116 2117 if ((flags & PRSVADDR) && PROCESS_NOT_32BIT(p)) { 2118 prunlock(pnp); 2119 error = EOVERFLOW; 2120 break; 2121 } 2122 2123 if (flags & (PRSHOLD|PRSTRACE|PRSFAULT|PRSVADDR)) { 2124 un.prrun.pr_flags = (int)flags; 2125 un.prrun.pr_trace = un32.prrun.pr_trace; 2126 un.prrun.pr_sighold = un32.prrun.pr_sighold; 2127 un.prrun.pr_fault = un32.prrun.pr_fault; 2128 un.prrun.pr_vaddr = 2129 (caddr_t)(uintptr_t)un32.prrun.pr_vaddr; 2130 prsetrun(t, &un.prrun); 2131 } 2132 2133 error = pr_setrun(pnp, prmaprunflags(flags)); 2134 2135 prunlock(pnp); 2136 break; 2137 } 2138 2139 case PIOCLWPIDS: /* get array of lwp identifiers */ 2140 { 2141 int nlwp; 2142 int Nlwp; 2143 id_t *idp; 2144 id_t *Bidp; 2145 2146 Nlwp = nlwp = p->p_lwpcnt; 2147 2148 if (thing && thingsize != (Nlwp+1) * sizeof (id_t)) { 2149 kmem_free(thing, thingsize); 2150 thing = NULL; 2151 } 2152 if (thing == NULL) { 2153 thingsize = (Nlwp+1) * sizeof (id_t); 2154 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2155 } 2156 if (thing == NULL) { 2157 prunlock(pnp); 2158 goto startover; 2159 } 2160 2161 idp = thing; 2162 thing = NULL; 2163 Bidp = idp; 2164 if ((t = p->p_tlist) != NULL) { 2165 do { 2166 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2167 ASSERT(nlwp > 0); 2168 --nlwp; 2169 *idp++ = t->t_tid; 2170 } while ((t = t->t_forw) != p->p_tlist); 2171 } 2172 *idp = 0; 2173 ASSERT(nlwp == 0); 2174 prunlock(pnp); 2175 if (copyout(Bidp, cmaddr, (Nlwp+1) * sizeof (id_t))) 2176 error = EFAULT; 2177 kmem_free(Bidp, (Nlwp+1) * sizeof (id_t)); 2178 break; 2179 } 2180 2181 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 2182 { 2183 vnode_t *xvp; 2184 int n; 2185 2186 prunlock(pnp); 2187 if ((xvp = prlwpnode(pnp, un32.lwpid)) == NULL) 2188 error = ENOENT; 2189 else if (error = fassign(&xvp, flag & (FREAD|FWRITE), &n)) { 2190 VN_RELE(xvp); 2191 } else 2192 *rvalp = n; 2193 break; 2194 } 2195 2196 case PIOCOPENPD: /* return /proc page data file descriptor */ 2197 { 2198 vnode_t *xvp = PTOV(xpnp); 2199 vnode_t *dp = pnp->pr_parent; 2200 int n; 2201 2202 if (PROCESS_NOT_32BIT(p)) { 2203 prunlock(pnp); 2204 prfreenode(xpnp); 2205 xpnp = NULL; 2206 error = EOVERFLOW; 2207 break; 2208 } 2209 2210 if (pnp->pr_type == PR_LWPIDFILE) { 2211 dp = VTOP(dp)->pr_parent; 2212 dp = VTOP(dp)->pr_parent; 2213 } 2214 ASSERT(VTOP(dp)->pr_type == PR_PIDDIR); 2215 2216 VN_HOLD(dp); 2217 pcp = pnp->pr_pcommon; 2218 xpnp->pr_ino = ptoi(pcp->prc_pid); 2219 xpnp->pr_common = pcp; 2220 xpnp->pr_pcommon = pcp; 2221 xpnp->pr_parent = dp; 2222 2223 xpnp->pr_next = p->p_plist; 2224 p->p_plist = xvp; 2225 2226 prunlock(pnp); 2227 if (error = fassign(&xvp, FREAD, &n)) { 2228 VN_RELE(xvp); 2229 } else 2230 *rvalp = n; 2231 2232 xpnp = NULL; 2233 break; 2234 } 2235 2236 case PIOCGTRACE: /* get signal trace mask */ 2237 prassignset(&un32.smask, &p->p_sigmask); 2238 prunlock(pnp); 2239 if (copyout(&un32.smask, cmaddr, sizeof (un32.smask))) 2240 error = EFAULT; 2241 break; 2242 2243 case PIOCSTRACE: /* set signal trace mask */ 2244 prdelset(&un32.smask, SIGKILL); 2245 prassignset(&p->p_sigmask, &un32.smask); 2246 if (!sigisempty(&p->p_sigmask)) 2247 p->p_proc_flag |= P_PR_TRACE; 2248 else if (prisempty(&p->p_fltmask)) { 2249 up = PTOU(p); 2250 if (up->u_systrap == 0) 2251 p->p_proc_flag &= ~P_PR_TRACE; 2252 } 2253 prunlock(pnp); 2254 break; 2255 2256 case PIOCSSIG: /* set current signal */ 2257 if (un32.info.si_signo != 0 && PROCESS_NOT_32BIT(p)) { 2258 prunlock(pnp); 2259 error = EOVERFLOW; 2260 } else { 2261 bzero(&un.info, sizeof (un.info)); 2262 siginfo_32tok(&un32.info, (k_siginfo_t *)&un.info); 2263 error = pr_setsig(pnp, &un.info); 2264 prunlock(pnp); 2265 if (un32.info.si_signo == SIGKILL && error == 0) 2266 pr_wait_die(pnp); 2267 } 2268 break; 2269 2270 case PIOCKILL: /* send signal */ 2271 error = pr_kill(pnp, un32.signo, cr); 2272 prunlock(pnp); 2273 if (un32.signo == SIGKILL && error == 0) 2274 pr_wait_die(pnp); 2275 break; 2276 2277 case PIOCUNKILL: /* delete a signal */ 2278 error = pr_unkill(pnp, un32.signo); 2279 prunlock(pnp); 2280 break; 2281 2282 case PIOCNICE: /* set nice priority */ 2283 error = pr_nice(p, un32.nice, cr); 2284 prunlock(pnp); 2285 break; 2286 2287 case PIOCGENTRY: /* get syscall entry bit mask */ 2288 case PIOCGEXIT: /* get syscall exit bit mask */ 2289 up = PTOU(p); 2290 if (cmd == PIOCGENTRY) { 2291 prassignset(&un32.prmask, &up->u_entrymask); 2292 } else { 2293 prassignset(&un32.prmask, &up->u_exitmask); 2294 } 2295 prunlock(pnp); 2296 if (copyout(&un32.prmask, cmaddr, sizeof (un32.prmask))) 2297 error = EFAULT; 2298 break; 2299 2300 case PIOCSENTRY: /* set syscall entry bit mask */ 2301 case PIOCSEXIT: /* set syscall exit bit mask */ 2302 pr_setentryexit(p, &un32.prmask, cmd == PIOCSENTRY); 2303 prunlock(pnp); 2304 break; 2305 2306 case PIOCSRLC: /* obsolete: set running on last /proc close */ 2307 error = pr_set(p, prmapsetflags(PR_RLC)); 2308 prunlock(pnp); 2309 break; 2310 2311 case PIOCRRLC: /* obsolete: reset run-on-last-close flag */ 2312 error = pr_unset(p, prmapsetflags(PR_RLC)); 2313 prunlock(pnp); 2314 break; 2315 2316 case PIOCSFORK: /* obsolete: set inherit-on-fork flag */ 2317 error = pr_set(p, prmapsetflags(PR_FORK)); 2318 prunlock(pnp); 2319 break; 2320 2321 case PIOCRFORK: /* obsolete: reset inherit-on-fork flag */ 2322 error = pr_unset(p, prmapsetflags(PR_FORK)); 2323 prunlock(pnp); 2324 break; 2325 2326 case PIOCSET: /* set process flags */ 2327 error = pr_set(p, prmapsetflags((long)un32.flags)); 2328 prunlock(pnp); 2329 break; 2330 2331 case PIOCRESET: /* reset process flags */ 2332 error = pr_unset(p, prmapsetflags((long)un32.flags)); 2333 prunlock(pnp); 2334 break; 2335 2336 case PIOCGREG: /* get general registers */ 2337 if (PROCESS_NOT_32BIT(p)) 2338 error = EOVERFLOW; 2339 else if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 2340 bzero(un32.regs, sizeof (un32.regs)); 2341 else { 2342 /* drop p_lock while touching the lwp's stack */ 2343 mutex_exit(&p->p_lock); 2344 prgetprregs32(lwp, un32.regs); 2345 mutex_enter(&p->p_lock); 2346 } 2347 prunlock(pnp); 2348 if (error == 0 && 2349 copyout(un32.regs, cmaddr, sizeof (un32.regs))) 2350 error = EFAULT; 2351 break; 2352 2353 case PIOCSREG: /* set general registers */ 2354 if (PROCESS_NOT_32BIT(p)) 2355 error = EOVERFLOW; 2356 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 2357 error = EBUSY; 2358 else { 2359 /* drop p_lock while touching the lwp's stack */ 2360 mutex_exit(&p->p_lock); 2361 prgregset_32ton(lwp, un32.regs, un.regs); 2362 prsetprregs(lwp, un.regs, 0); 2363 mutex_enter(&p->p_lock); 2364 } 2365 prunlock(pnp); 2366 break; 2367 2368 case PIOCGFPREG: /* get floating-point registers */ 2369 if (!prhasfp()) 2370 error = EINVAL; /* No FP support */ 2371 else if (PROCESS_NOT_32BIT(p)) 2372 error = EOVERFLOW; 2373 else if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 2374 bzero(&un32.fpregs, sizeof (un32.fpregs)); 2375 else { 2376 /* drop p_lock while touching the lwp's stack */ 2377 mutex_exit(&p->p_lock); 2378 prgetprfpregs32(lwp, &un32.fpregs); 2379 mutex_enter(&p->p_lock); 2380 } 2381 prunlock(pnp); 2382 if (error == 0 && 2383 copyout(&un32.fpregs, cmaddr, sizeof (un32.fpregs))) 2384 error = EFAULT; 2385 break; 2386 2387 case PIOCSFPREG: /* set floating-point registers */ 2388 if (!prhasfp()) 2389 error = EINVAL; /* No FP support */ 2390 else if (PROCESS_NOT_32BIT(p)) 2391 error = EOVERFLOW; 2392 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 2393 error = EBUSY; 2394 else { 2395 /* drop p_lock while touching the lwp's stack */ 2396 mutex_exit(&p->p_lock); 2397 prsetprfpregs32(lwp, &un32.fpregs); 2398 mutex_enter(&p->p_lock); 2399 } 2400 prunlock(pnp); 2401 break; 2402 2403 case PIOCGXREGSIZE: /* get the size of the extra registers */ 2404 { 2405 int xregsize; 2406 2407 if (prhasx(p)) { 2408 xregsize = prgetprxregsize(p); 2409 prunlock(pnp); 2410 if (copyout(&xregsize, cmaddr, sizeof (xregsize))) 2411 error = EFAULT; 2412 } else { 2413 prunlock(pnp); 2414 error = EINVAL; /* No extra register support */ 2415 } 2416 break; 2417 } 2418 2419 case PIOCGXREG: /* get extra registers */ 2420 if (PROCESS_NOT_32BIT(p)) 2421 error = EOVERFLOW; 2422 else if (!prhasx(p)) 2423 error = EINVAL; /* No extra register support */ 2424 else { 2425 bzero(thing, thingsize); 2426 if (t->t_state == TS_STOPPED || VSTOPPED(t)) { 2427 /* drop p_lock to touch the stack */ 2428 mutex_exit(&p->p_lock); 2429 prgetprxregs(lwp, thing); 2430 mutex_enter(&p->p_lock); 2431 } 2432 } 2433 prunlock(pnp); 2434 if (error == 0 && 2435 copyout(thing, cmaddr, thingsize)) 2436 error = EFAULT; 2437 if (thing) { 2438 kmem_free(thing, thingsize); 2439 thing = NULL; 2440 } 2441 break; 2442 2443 case PIOCSXREG: /* set extra registers */ 2444 if (PROCESS_NOT_32BIT(p)) 2445 error = EOVERFLOW; 2446 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 2447 error = EBUSY; 2448 else if (!prhasx(p)) 2449 error = EINVAL; /* No extra register support */ 2450 else if (thing) { 2451 /* drop p_lock while touching the lwp's stack */ 2452 mutex_exit(&p->p_lock); 2453 prsetprxregs(lwp, thing); 2454 mutex_enter(&p->p_lock); 2455 } 2456 prunlock(pnp); 2457 if (thing) { 2458 kmem_free(thing, thingsize); 2459 thing = NULL; 2460 } 2461 break; 2462 2463 case PIOCSTATUS: /* get process/lwp status */ 2464 if (PROCESS_NOT_32BIT(p)) { 2465 prunlock(pnp); 2466 error = EOVERFLOW; 2467 break; 2468 } 2469 oprgetstatus32(t, &un32.prstat, VTOZONE(vp)); 2470 prunlock(pnp); 2471 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat))) 2472 error = EFAULT; 2473 break; 2474 2475 case PIOCLSTATUS: /* get status for process & all lwps */ 2476 { 2477 int Nlwp; 2478 int nlwp; 2479 prstatus32_t *Bprsp; 2480 prstatus32_t *prsp; 2481 2482 if (PROCESS_NOT_32BIT(p)) { 2483 prunlock(pnp); 2484 if (thing) { 2485 kmem_free(thing, thingsize); 2486 thing = NULL; 2487 } 2488 error = EOVERFLOW; 2489 break; 2490 } 2491 2492 nlwp = Nlwp = p->p_lwpcnt; 2493 2494 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus32_t)) { 2495 kmem_free(thing, thingsize); 2496 thing = NULL; 2497 } 2498 if (thing == NULL) { 2499 thingsize = (Nlwp+1) * sizeof (prstatus32_t); 2500 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2501 } 2502 if (thing == NULL) { 2503 prunlock(pnp); 2504 goto startover; 2505 } 2506 2507 Bprsp = (prstatus32_t *)thing; 2508 thing = NULL; 2509 prsp = Bprsp; 2510 oprgetstatus32(t, prsp, VTOZONE(vp)); 2511 t = p->p_tlist; 2512 do { 2513 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2514 ASSERT(nlwp > 0); 2515 --nlwp; 2516 oprgetstatus32(t, ++prsp, VTOZONE(vp)); 2517 } while ((t = t->t_forw) != p->p_tlist); 2518 ASSERT(nlwp == 0); 2519 prunlock(pnp); 2520 if (copyout(Bprsp, cmaddr, (Nlwp+1) * sizeof (prstatus32_t))) 2521 error = EFAULT; 2522 2523 kmem_free(Bprsp, (Nlwp + 1) * sizeof (prstatus32_t)); 2524 break; 2525 } 2526 2527 case PIOCPSINFO: /* get ps(1) information */ 2528 { 2529 prpsinfo32_t *psp = &un32.prps; 2530 2531 oprgetpsinfo32(p, psp, 2532 (pnp->pr_type == PR_LWPIDFILE)? pcp->prc_thread : NULL); 2533 2534 prunlock(pnp); 2535 if (copyout(&un32.prps, cmaddr, sizeof (un32.prps))) 2536 error = EFAULT; 2537 break; 2538 } 2539 2540 case PIOCMAXSIG: /* get maximum signal number */ 2541 { 2542 int n = nsig-1; 2543 2544 prunlock(pnp); 2545 if (copyout(&n, cmaddr, sizeof (int))) 2546 error = EFAULT; 2547 break; 2548 } 2549 2550 case PIOCACTION: /* get signal action structures */ 2551 { 2552 uint_t sig; 2553 struct sigaction32 *sap = thing; 2554 2555 if (PROCESS_NOT_32BIT(p)) 2556 error = EOVERFLOW; 2557 else { 2558 up = PTOU(p); 2559 for (sig = 1; sig < nsig; sig++) 2560 prgetaction32(p, up, sig, &sap[sig-1]); 2561 } 2562 prunlock(pnp); 2563 if (error == 0 && 2564 copyout(sap, cmaddr, (nsig-1)*sizeof (struct sigaction32))) 2565 error = EFAULT; 2566 kmem_free(sap, (nsig-1)*sizeof (struct sigaction32)); 2567 thing = NULL; 2568 break; 2569 } 2570 2571 case PIOCGHOLD: /* get signal-hold mask */ 2572 schedctl_finish_sigblock(t); 2573 sigktou(&t->t_hold, &un32.holdmask); 2574 prunlock(pnp); 2575 if (copyout(&un32.holdmask, cmaddr, sizeof (un32.holdmask))) 2576 error = EFAULT; 2577 break; 2578 2579 case PIOCSHOLD: /* set signal-hold mask */ 2580 pr_sethold(pnp, &un32.holdmask); 2581 prunlock(pnp); 2582 break; 2583 2584 case PIOCNMAP: /* get number of memory mappings */ 2585 { 2586 int n; 2587 struct as *as = p->p_as; 2588 2589 if ((p->p_flag & SSYS) || as == &kas) 2590 n = 0; 2591 else { 2592 mutex_exit(&p->p_lock); 2593 AS_LOCK_ENTER(as, RW_WRITER); 2594 n = prnsegs(as, 0); 2595 AS_LOCK_EXIT(as); 2596 mutex_enter(&p->p_lock); 2597 } 2598 prunlock(pnp); 2599 if (copyout(&n, cmaddr, sizeof (int))) 2600 error = EFAULT; 2601 break; 2602 } 2603 2604 case PIOCMAP: /* get memory map information */ 2605 { 2606 list_t iolhead; 2607 struct as *as = p->p_as; 2608 2609 if ((p->p_flag & SSYS) || as == &kas) { 2610 error = 0; 2611 prunlock(pnp); 2612 } else if (PROCESS_NOT_32BIT(p)) { 2613 error = EOVERFLOW; 2614 prunlock(pnp); 2615 } else { 2616 mutex_exit(&p->p_lock); 2617 AS_LOCK_ENTER(as, RW_WRITER); 2618 error = oprgetmap32(p, &iolhead); 2619 AS_LOCK_EXIT(as); 2620 mutex_enter(&p->p_lock); 2621 prunlock(pnp); 2622 2623 error = pr_iol_copyout_and_free(&iolhead, 2624 &cmaddr, error); 2625 } 2626 /* 2627 * The procfs PIOCMAP ioctl returns an all-zero buffer 2628 * to indicate the end of the prmap[] array. 2629 * Append it to whatever has already been copied out. 2630 */ 2631 bzero(&un32.prmap, sizeof (un32.prmap)); 2632 if (!error && 2633 copyout(&un32.prmap, cmaddr, sizeof (un32.prmap))) 2634 error = EFAULT; 2635 break; 2636 } 2637 2638 case PIOCGFAULT: /* get mask of traced faults */ 2639 prassignset(&un32.fltmask, &p->p_fltmask); 2640 prunlock(pnp); 2641 if (copyout(&un32.fltmask, cmaddr, sizeof (un32.fltmask))) 2642 error = EFAULT; 2643 break; 2644 2645 case PIOCSFAULT: /* set mask of traced faults */ 2646 pr_setfault(p, &un32.fltmask); 2647 prunlock(pnp); 2648 break; 2649 2650 case PIOCCFAULT: /* clear current fault */ 2651 lwp->lwp_curflt = 0; 2652 prunlock(pnp); 2653 break; 2654 2655 case PIOCCRED: /* get process credentials */ 2656 { 2657 cred_t *cp; 2658 2659 mutex_enter(&p->p_crlock); 2660 cp = p->p_cred; 2661 un32.prcred.pr_euid = crgetuid(cp); 2662 un32.prcred.pr_ruid = crgetruid(cp); 2663 un32.prcred.pr_suid = crgetsuid(cp); 2664 un32.prcred.pr_egid = crgetgid(cp); 2665 un32.prcred.pr_rgid = crgetrgid(cp); 2666 un32.prcred.pr_sgid = crgetsgid(cp); 2667 un32.prcred.pr_ngroups = crgetngroups(cp); 2668 mutex_exit(&p->p_crlock); 2669 2670 prunlock(pnp); 2671 if (copyout(&un32.prcred, cmaddr, sizeof (un32.prcred))) 2672 error = EFAULT; 2673 break; 2674 } 2675 2676 case PIOCGROUPS: /* get supplementary groups */ 2677 { 2678 cred_t *cp; 2679 2680 mutex_enter(&p->p_crlock); 2681 cp = p->p_cred; 2682 crhold(cp); 2683 mutex_exit(&p->p_crlock); 2684 2685 prunlock(pnp); 2686 if (copyout(crgetgroups(cp), cmaddr, 2687 MAX(crgetngroups(cp), 1) * sizeof (gid_t))) 2688 error = EFAULT; 2689 crfree(cp); 2690 break; 2691 } 2692 2693 case PIOCUSAGE: /* get usage info */ 2694 { 2695 /* 2696 * For an lwp file descriptor, return just the lwp usage. 2697 * For a process file descriptor, return total usage, 2698 * all current lwps plus all defunct lwps. 2699 */ 2700 prhusage_t *pup = &un32.prhusage; 2701 prusage32_t *upup; 2702 2703 bzero(pup, sizeof (*pup)); 2704 pup->pr_tstamp = gethrtime(); 2705 2706 if (pnp->pr_type == PR_LWPIDFILE) { 2707 t = pcp->prc_thread; 2708 if (t != NULL) 2709 prgetusage(t, pup); 2710 else 2711 error = ENOENT; 2712 } else { 2713 pup->pr_count = p->p_defunct; 2714 pup->pr_create = p->p_mstart; 2715 pup->pr_term = p->p_mterm; 2716 2717 pup->pr_rtime = p->p_mlreal; 2718 pup->pr_utime = p->p_acct[LMS_USER]; 2719 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 2720 pup->pr_ttime = p->p_acct[LMS_TRAP]; 2721 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 2722 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 2723 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 2724 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 2725 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 2726 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 2727 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 2728 2729 pup->pr_minf = p->p_ru.minflt; 2730 pup->pr_majf = p->p_ru.majflt; 2731 pup->pr_nswap = p->p_ru.nswap; 2732 pup->pr_inblk = p->p_ru.inblock; 2733 pup->pr_oublk = p->p_ru.oublock; 2734 pup->pr_msnd = p->p_ru.msgsnd; 2735 pup->pr_mrcv = p->p_ru.msgrcv; 2736 pup->pr_sigs = p->p_ru.nsignals; 2737 pup->pr_vctx = p->p_ru.nvcsw; 2738 pup->pr_ictx = p->p_ru.nivcsw; 2739 pup->pr_sysc = p->p_ru.sysc; 2740 pup->pr_ioch = p->p_ru.ioch; 2741 2742 /* 2743 * Add the usage information for each active lwp. 2744 */ 2745 if ((t = p->p_tlist) != NULL && 2746 !(pcp->prc_flags & PRC_DESTROY)) { 2747 do { 2748 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2749 pup->pr_count++; 2750 praddusage(t, pup); 2751 } while ((t = t->t_forw) != p->p_tlist); 2752 } 2753 } 2754 2755 prunlock(pnp); 2756 2757 upup = kmem_alloc(sizeof (*upup), KM_SLEEP); 2758 prcvtusage32(pup, upup); 2759 if (copyout(upup, cmaddr, sizeof (*upup))) 2760 error = EFAULT; 2761 kmem_free(upup, sizeof (*upup)); 2762 2763 break; 2764 } 2765 2766 case PIOCLUSAGE: /* get detailed usage info */ 2767 { 2768 int Nlwp; 2769 int nlwp; 2770 prusage32_t *upup; 2771 prusage32_t *Bupup; 2772 prhusage_t *pup; 2773 hrtime_t curtime; 2774 2775 nlwp = Nlwp = (pcp->prc_flags & PRC_DESTROY)? 0 : p->p_lwpcnt; 2776 2777 if (thing && thingsize != 2778 sizeof (prhusage_t) + (Nlwp+1) * sizeof (prusage32_t)) { 2779 kmem_free(thing, thingsize); 2780 thing = NULL; 2781 } 2782 if (thing == NULL) { 2783 thingsize = sizeof (prhusage_t) + 2784 (Nlwp+1) * sizeof (prusage32_t); 2785 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2786 } 2787 if (thing == NULL) { 2788 prunlock(pnp); 2789 goto startover; 2790 } 2791 2792 pup = (prhusage_t *)thing; 2793 upup = Bupup = (prusage32_t *)(pup + 1); 2794 2795 ASSERT(p == pcp->prc_proc); 2796 2797 curtime = gethrtime(); 2798 2799 /* 2800 * First the summation over defunct lwps. 2801 */ 2802 bzero(pup, sizeof (*pup)); 2803 pup->pr_count = p->p_defunct; 2804 pup->pr_tstamp = curtime; 2805 pup->pr_create = p->p_mstart; 2806 pup->pr_term = p->p_mterm; 2807 2808 pup->pr_rtime = p->p_mlreal; 2809 pup->pr_utime = p->p_acct[LMS_USER]; 2810 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 2811 pup->pr_ttime = p->p_acct[LMS_TRAP]; 2812 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 2813 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 2814 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 2815 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 2816 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 2817 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 2818 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 2819 2820 pup->pr_minf = p->p_ru.minflt; 2821 pup->pr_majf = p->p_ru.majflt; 2822 pup->pr_nswap = p->p_ru.nswap; 2823 pup->pr_inblk = p->p_ru.inblock; 2824 pup->pr_oublk = p->p_ru.oublock; 2825 pup->pr_msnd = p->p_ru.msgsnd; 2826 pup->pr_mrcv = p->p_ru.msgrcv; 2827 pup->pr_sigs = p->p_ru.nsignals; 2828 pup->pr_vctx = p->p_ru.nvcsw; 2829 pup->pr_ictx = p->p_ru.nivcsw; 2830 pup->pr_sysc = p->p_ru.sysc; 2831 pup->pr_ioch = p->p_ru.ioch; 2832 2833 prcvtusage32(pup, upup); 2834 2835 /* 2836 * Fill one prusage struct for each active lwp. 2837 */ 2838 if ((t = p->p_tlist) != NULL && 2839 !(pcp->prc_flags & PRC_DESTROY)) { 2840 do { 2841 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2842 ASSERT(nlwp > 0); 2843 --nlwp; 2844 upup++; 2845 prgetusage(t, pup); 2846 prcvtusage32(pup, upup); 2847 } while ((t = t->t_forw) != p->p_tlist); 2848 } 2849 ASSERT(nlwp == 0); 2850 2851 prunlock(pnp); 2852 if (copyout(Bupup, cmaddr, (Nlwp+1) * sizeof (prusage32_t))) 2853 error = EFAULT; 2854 kmem_free(thing, thingsize); 2855 thing = NULL; 2856 break; 2857 } 2858 2859 case PIOCNAUXV: /* get number of aux vector entries */ 2860 { 2861 int n = __KERN_NAUXV_IMPL; 2862 2863 prunlock(pnp); 2864 if (copyout(&n, cmaddr, sizeof (int))) 2865 error = EFAULT; 2866 break; 2867 } 2868 2869 case PIOCAUXV: /* get aux vector (see sys/auxv.h) */ 2870 { 2871 int i; 2872 2873 if (PROCESS_NOT_32BIT(p)) { 2874 prunlock(pnp); 2875 error = EOVERFLOW; 2876 } else { 2877 up = PTOU(p); 2878 for (i = 0; i < __KERN_NAUXV_IMPL; i++) { 2879 un32.auxv[i].a_type = up->u_auxv[i].a_type; 2880 un32.auxv[i].a_un.a_val = 2881 (int32_t)up->u_auxv[i].a_un.a_val; 2882 } 2883 prunlock(pnp); 2884 if (copyout(un32.auxv, cmaddr, 2885 __KERN_NAUXV_IMPL * sizeof (auxv32_t))) 2886 error = EFAULT; 2887 } 2888 break; 2889 } 2890 2891 #if defined(__i386) || defined(__i386_COMPAT) 2892 case PIOCNLDT: /* get number of LDT entries */ 2893 { 2894 int n; 2895 2896 mutex_exit(&p->p_lock); 2897 mutex_enter(&p->p_ldtlock); 2898 n = prnldt(p); 2899 mutex_exit(&p->p_ldtlock); 2900 mutex_enter(&p->p_lock); 2901 prunlock(pnp); 2902 if (copyout(&n, cmaddr, sizeof (n))) 2903 error = EFAULT; 2904 break; 2905 } 2906 2907 case PIOCLDT: /* get LDT entries */ 2908 { 2909 struct ssd *ssd; 2910 int n; 2911 2912 mutex_exit(&p->p_lock); 2913 mutex_enter(&p->p_ldtlock); 2914 n = prnldt(p); 2915 2916 if (thing && thingsize != (n+1) * sizeof (*ssd)) { 2917 kmem_free(thing, thingsize); 2918 thing = NULL; 2919 } 2920 if (thing == NULL) { 2921 thingsize = (n+1) * sizeof (*ssd); 2922 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2923 } 2924 if (thing == NULL) { 2925 mutex_exit(&p->p_ldtlock); 2926 mutex_enter(&p->p_lock); 2927 prunlock(pnp); 2928 goto startover; 2929 } 2930 2931 ssd = thing; 2932 thing = NULL; 2933 if (n != 0) 2934 prgetldt(p, ssd); 2935 mutex_exit(&p->p_ldtlock); 2936 mutex_enter(&p->p_lock); 2937 prunlock(pnp); 2938 2939 /* mark the end of the list with a null entry */ 2940 bzero(&ssd[n], sizeof (*ssd)); 2941 if (copyout(ssd, cmaddr, (n+1) * sizeof (*ssd))) 2942 error = EFAULT; 2943 kmem_free(ssd, (n+1) * sizeof (*ssd)); 2944 break; 2945 } 2946 #endif /* __i386 || __i386_COMPAT */ 2947 2948 #if defined(__sparc) 2949 case PIOCGWIN: /* get gwindows_t (see sys/reg.h) */ 2950 { 2951 gwindows32_t *gwp = thing; 2952 2953 if (PROCESS_NOT_32BIT(p)) { 2954 prunlock(pnp); 2955 error = EOVERFLOW; 2956 } else { 2957 /* drop p->p_lock while touching the stack */ 2958 mutex_exit(&p->p_lock); 2959 bzero(gwp, sizeof (*gwp)); 2960 prgetwindows32(lwp, gwp); 2961 mutex_enter(&p->p_lock); 2962 prunlock(pnp); 2963 if (copyout(gwp, cmaddr, sizeof (*gwp))) 2964 error = EFAULT; 2965 } 2966 kmem_free(gwp, sizeof (*gwp)); 2967 thing = NULL; 2968 break; 2969 } 2970 #endif /* __sparc */ 2971 2972 default: 2973 prunlock(pnp); 2974 error = EINVAL; 2975 break; 2976 2977 } 2978 2979 ASSERT(thing == NULL); 2980 ASSERT(xpnp == NULL); 2981 return (error); 2982 } 2983 #endif /* _SYSCALL32_IMPL */ 2984 2985 /* 2986 * Distinguish "writeable" ioctl requests from others. 2987 */ 2988 static int 2989 isprwrioctl(int cmd) 2990 { 2991 switch (cmd) { 2992 case PIOCSTOP: 2993 case PIOCRUN: 2994 case PIOCSTRACE: 2995 case PIOCSSIG: 2996 case PIOCKILL: 2997 case PIOCUNKILL: 2998 case PIOCNICE: 2999 case PIOCSENTRY: 3000 case PIOCSEXIT: 3001 case PIOCSRLC: 3002 case PIOCRRLC: 3003 case PIOCSREG: 3004 case PIOCSFPREG: 3005 case PIOCSXREG: 3006 case PIOCSHOLD: 3007 case PIOCSFAULT: 3008 case PIOCCFAULT: 3009 case PIOCSFORK: 3010 case PIOCRFORK: 3011 case PIOCSET: 3012 case PIOCRESET: 3013 return (1); 3014 } 3015 return (0); 3016 } 3017 3018 /* 3019 * Map the ioctl() interface run flags to the new interface run flags. 3020 */ 3021 static ulong_t 3022 prmaprunflags(long flags) 3023 { 3024 ulong_t newflags = 0; 3025 3026 if (flags & PRCSIG) 3027 newflags |= 0x01; 3028 if (flags & PRCFAULT) 3029 newflags |= 0x02; 3030 if (flags & PRSTEP) 3031 newflags |= 0x04; 3032 if (flags & PRSABORT) 3033 newflags |= 0x08; 3034 if (flags & PRSTOP) 3035 newflags |= 0x10; 3036 return (newflags); 3037 } 3038 3039 /* 3040 * Map the ioctl() interface settable mode flags to the new interface flags. 3041 */ 3042 static long 3043 prmapsetflags(long flags) 3044 { 3045 long newflags = 0; 3046 3047 #define ALLFLAGS \ 3048 (PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_MSACCT|PR_PCOMPAT) 3049 3050 if (flags & ~ALLFLAGS) 3051 newflags = 0xffff; /* forces EINVAL */ 3052 if (flags & PR_FORK) 3053 newflags |= (0x00100000 | 0x08000000); 3054 if (flags & PR_RLC) 3055 newflags |= 0x00200000; 3056 if (flags & PR_KLC) 3057 newflags |= 0x00400000; 3058 if (flags & PR_ASYNC) 3059 newflags |= 0x00800000; 3060 if (flags & PR_MSACCT) 3061 newflags |= 0x01000000; 3062 if (flags & PR_BPTADJ) 3063 newflags |= 0x02000000; 3064 if (flags & PR_PCOMPAT) 3065 newflags |= 0x04000000; 3066 return (newflags); 3067 } 3068 3069 /* 3070 * Apply PIOCRUN options specific to the ioctl() interface. 3071 */ 3072 static void 3073 prsetrun(kthread_t *t, prrun_t *prp) 3074 { 3075 proc_t *p = ttoproc(t); 3076 klwp_t *lwp = ttolwp(t); 3077 long flags = prp->pr_flags; 3078 user_t *up = PTOU(p); 3079 3080 ASSERT(MUTEX_HELD(&p->p_lock)); 3081 3082 if (flags & PRSHOLD) { 3083 schedctl_finish_sigblock(t); 3084 sigutok(&prp->pr_sighold, &t->t_hold); 3085 t->t_sig_check = 1; /* so ISSIG will be done */ 3086 } 3087 if (flags & PRSTRACE) { 3088 prdelset(&prp->pr_trace, SIGKILL); 3089 prassignset(&p->p_sigmask, &prp->pr_trace); 3090 if (!sigisempty(&p->p_sigmask)) 3091 p->p_proc_flag |= P_PR_TRACE; 3092 else if (prisempty(&p->p_fltmask)) { 3093 if (up->u_systrap == 0) 3094 p->p_proc_flag &= ~P_PR_TRACE; 3095 } 3096 } 3097 if (flags & PRSFAULT) { 3098 prassignset(&p->p_fltmask, &prp->pr_fault); 3099 if (!prisempty(&p->p_fltmask)) 3100 p->p_proc_flag |= P_PR_TRACE; 3101 else if (sigisempty(&p->p_sigmask)) { 3102 if (up->u_systrap == 0) 3103 p->p_proc_flag &= ~P_PR_TRACE; 3104 } 3105 } 3106 /* 3107 * prsvaddr() must be called before prstep() because 3108 * stepping can depend on the current value of the PC. 3109 * We drop p_lock while touching the lwp's registers (on stack). 3110 */ 3111 if (flags & PRSVADDR) { 3112 mutex_exit(&p->p_lock); 3113 prsvaddr(lwp, prp->pr_vaddr); 3114 mutex_enter(&p->p_lock); 3115 } 3116 } 3117 3118 /* 3119 * Common code for PIOCOPENM 3120 * Returns with the process unlocked. 3121 */ 3122 static int 3123 propenm(prnode_t *pnp, caddr_t cmaddr, caddr_t va, int *rvalp, cred_t *cr) 3124 { 3125 proc_t *p = pnp->pr_common->prc_proc; 3126 struct as *as = p->p_as; 3127 int error = 0; 3128 struct seg *seg; 3129 struct vnode *xvp; 3130 int n; 3131 3132 /* 3133 * By fiat, a system process has no address space. 3134 */ 3135 if ((p->p_flag & SSYS) || as == &kas) { 3136 error = EINVAL; 3137 } else if (cmaddr) { 3138 /* 3139 * We drop p_lock before grabbing the address 3140 * space lock in order to avoid a deadlock with 3141 * the clock thread. The process will not 3142 * disappear and its address space will not 3143 * change because it is marked P_PR_LOCK. 3144 */ 3145 mutex_exit(&p->p_lock); 3146 AS_LOCK_ENTER(as, RW_READER); 3147 seg = as_segat(as, va); 3148 if (seg != NULL && 3149 seg->s_ops == &segvn_ops && 3150 SEGOP_GETVP(seg, va, &xvp) == 0 && 3151 xvp != NULL && 3152 xvp->v_type == VREG) { 3153 VN_HOLD(xvp); 3154 } else { 3155 error = EINVAL; 3156 } 3157 AS_LOCK_EXIT(as); 3158 mutex_enter(&p->p_lock); 3159 } else if ((xvp = p->p_exec) == NULL) { 3160 error = EINVAL; 3161 } else { 3162 VN_HOLD(xvp); 3163 } 3164 3165 prunlock(pnp); 3166 3167 if (error == 0) { 3168 if ((error = VOP_ACCESS(xvp, VREAD, 0, cr, NULL)) == 0) 3169 error = fassign(&xvp, FREAD, &n); 3170 if (error) { 3171 VN_RELE(xvp); 3172 } else { 3173 *rvalp = n; 3174 } 3175 } 3176 3177 return (error); 3178 } 3179 3180 /* 3181 * Return old version of process/lwp status. 3182 * The u-block is mapped in by this routine and unmapped at the end. 3183 */ 3184 void 3185 oprgetstatus(kthread_t *t, prstatus_t *sp, zone_t *zp) 3186 { 3187 proc_t *p = ttoproc(t); 3188 klwp_t *lwp = ttolwp(t); 3189 int flags; 3190 user_t *up; 3191 ulong_t instr; 3192 3193 ASSERT(MUTEX_HELD(&p->p_lock)); 3194 3195 up = PTOU(p); 3196 bzero(sp, sizeof (*sp)); 3197 flags = 0; 3198 if (t->t_state == TS_STOPPED) { 3199 flags |= PR_STOPPED; 3200 if ((t->t_schedflag & TS_PSTART) == 0) 3201 flags |= PR_ISTOP; 3202 } else if (VSTOPPED(t)) { 3203 flags |= PR_STOPPED|PR_ISTOP; 3204 } 3205 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP)) 3206 flags |= PR_DSTOP; 3207 if (lwp->lwp_asleep) 3208 flags |= PR_ASLEEP; 3209 if (p->p_proc_flag & P_PR_FORK) 3210 flags |= PR_FORK; 3211 if (p->p_proc_flag & P_PR_RUNLCL) 3212 flags |= PR_RLC; 3213 if (p->p_proc_flag & P_PR_KILLCL) 3214 flags |= PR_KLC; 3215 if (p->p_proc_flag & P_PR_ASYNC) 3216 flags |= PR_ASYNC; 3217 if (p->p_proc_flag & P_PR_BPTADJ) 3218 flags |= PR_BPTADJ; 3219 if (p->p_proc_flag & P_PR_PTRACE) 3220 flags |= PR_PCOMPAT; 3221 if (t->t_proc_flag & TP_MSACCT) 3222 flags |= PR_MSACCT; 3223 sp->pr_flags = flags; 3224 if (VSTOPPED(t)) { 3225 sp->pr_why = PR_REQUESTED; 3226 sp->pr_what = 0; 3227 } else { 3228 sp->pr_why = t->t_whystop; 3229 sp->pr_what = t->t_whatstop; 3230 } 3231 3232 if (t->t_whystop == PR_FAULTED) 3233 bcopy(&lwp->lwp_siginfo, 3234 &sp->pr_info, sizeof (k_siginfo_t)); 3235 else if (lwp->lwp_curinfo) 3236 bcopy(&lwp->lwp_curinfo->sq_info, 3237 &sp->pr_info, sizeof (k_siginfo_t)); 3238 3239 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID && 3240 sp->pr_info.si_zoneid != zp->zone_id) { 3241 sp->pr_info.si_pid = zp->zone_zsched->p_pid; 3242 sp->pr_info.si_uid = 0; 3243 sp->pr_info.si_ctid = -1; 3244 sp->pr_info.si_zoneid = zp->zone_id; 3245 } 3246 3247 sp->pr_cursig = lwp->lwp_cursig; 3248 prassignset(&sp->pr_sigpend, &p->p_sig); 3249 prassignset(&sp->pr_lwppend, &t->t_sig); 3250 schedctl_finish_sigblock(t); 3251 prassignset(&sp->pr_sighold, &t->t_hold); 3252 sp->pr_altstack = lwp->lwp_sigaltstack; 3253 prgetaction(p, up, lwp->lwp_cursig, &sp->pr_action); 3254 sp->pr_pid = p->p_pid; 3255 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 3256 (p->p_flag & SZONETOP)) { 3257 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 3258 /* 3259 * Inside local zones, fake zsched's pid as parent pids for 3260 * processes which reference processes outside of the zone. 3261 */ 3262 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 3263 } else { 3264 sp->pr_ppid = p->p_ppid; 3265 } 3266 sp->pr_pgrp = p->p_pgrp; 3267 sp->pr_sid = p->p_sessp->s_sid; 3268 hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime); 3269 hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime); 3270 TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime); 3271 TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime); 3272 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name, 3273 sizeof (sp->pr_clname) - 1); 3274 sp->pr_who = t->t_tid; 3275 sp->pr_nlwp = p->p_lwpcnt; 3276 sp->pr_brkbase = p->p_brkbase; 3277 sp->pr_brksize = p->p_brksize; 3278 sp->pr_stkbase = prgetstackbase(p); 3279 sp->pr_stksize = p->p_stksize; 3280 sp->pr_oldcontext = (struct ucontext *)lwp->lwp_oldcontext; 3281 sp->pr_processor = t->t_cpu->cpu_id; 3282 sp->pr_bind = t->t_bind_cpu; 3283 3284 /* 3285 * Fetch the current instruction, if not a system process. 3286 * We don't attempt this unless the lwp is stopped. 3287 */ 3288 if ((p->p_flag & SSYS) || p->p_as == &kas) 3289 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL); 3290 else if (!(flags & PR_STOPPED)) 3291 sp->pr_flags |= PR_PCINVAL; 3292 else if (!prfetchinstr(lwp, &instr)) 3293 sp->pr_flags |= PR_PCINVAL; 3294 else 3295 sp->pr_instr = instr; 3296 3297 /* 3298 * Drop p_lock while touching the lwp's stack. 3299 */ 3300 mutex_exit(&p->p_lock); 3301 if (prisstep(lwp)) 3302 sp->pr_flags |= PR_STEP; 3303 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) { 3304 int i; 3305 auxv_t *auxp; 3306 3307 sp->pr_syscall = get_syscall_args(lwp, 3308 (long *)sp->pr_sysarg, &i); 3309 sp->pr_nsysarg = (short)i; 3310 if (t->t_whystop == PR_SYSEXIT && t->t_sysnum == SYS_execve) { 3311 sp->pr_sysarg[0] = 0; 3312 sp->pr_sysarg[1] = (uintptr_t)up->u_argv; 3313 sp->pr_sysarg[2] = (uintptr_t)up->u_envp; 3314 for (i = 0, auxp = up->u_auxv; 3315 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]); 3316 i++, auxp++) { 3317 if (auxp->a_type == AT_SUN_EXECNAME) { 3318 sp->pr_sysarg[0] = 3319 (uintptr_t)auxp->a_un.a_ptr; 3320 break; 3321 } 3322 } 3323 } 3324 } 3325 if ((flags & PR_STOPPED) || t == curthread) 3326 prgetprregs(lwp, sp->pr_reg); 3327 mutex_enter(&p->p_lock); 3328 } 3329 3330 /* 3331 * Return old version of information used by ps(1). 3332 */ 3333 void 3334 oprgetpsinfo(proc_t *p, prpsinfo_t *psp, kthread_t *tp) 3335 { 3336 kthread_t *t; 3337 char c, state; 3338 user_t *up; 3339 dev_t d; 3340 uint64_t pct; 3341 int retval, niceval; 3342 cred_t *cred; 3343 struct as *as; 3344 hrtime_t hrutime, hrstime, cur_time; 3345 3346 ASSERT(MUTEX_HELD(&p->p_lock)); 3347 3348 bzero(psp, sizeof (*psp)); 3349 3350 if ((t = tp) == NULL) 3351 t = prchoose(p); /* returns locked thread */ 3352 else 3353 thread_lock(t); 3354 3355 /* kludge: map thread state enum into process state enum */ 3356 3357 if (t == NULL) { 3358 state = TS_ZOMB; 3359 } else { 3360 state = VSTOPPED(t) ? TS_STOPPED : t->t_state; 3361 thread_unlock(t); 3362 } 3363 3364 switch (state) { 3365 case TS_SLEEP: state = SSLEEP; break; 3366 case TS_RUN: state = SRUN; break; 3367 case TS_ONPROC: state = SONPROC; break; 3368 case TS_ZOMB: state = SZOMB; break; 3369 case TS_STOPPED: state = SSTOP; break; 3370 default: state = 0; break; 3371 } 3372 switch (state) { 3373 case SSLEEP: c = 'S'; break; 3374 case SRUN: c = 'R'; break; 3375 case SZOMB: c = 'Z'; break; 3376 case SSTOP: c = 'T'; break; 3377 case SIDL: c = 'I'; break; 3378 case SONPROC: c = 'O'; break; 3379 #ifdef SXBRK 3380 case SXBRK: c = 'X'; break; 3381 #endif 3382 default: c = '?'; break; 3383 } 3384 psp->pr_state = state; 3385 psp->pr_sname = c; 3386 psp->pr_zomb = (state == SZOMB); 3387 /* 3388 * only export SSYS and SMSACCT; everything else is off-limits to 3389 * userland apps. 3390 */ 3391 psp->pr_flag = p->p_flag & (SSYS | SMSACCT); 3392 3393 mutex_enter(&p->p_crlock); 3394 cred = p->p_cred; 3395 psp->pr_uid = crgetruid(cred); 3396 psp->pr_gid = crgetrgid(cred); 3397 psp->pr_euid = crgetuid(cred); 3398 psp->pr_egid = crgetgid(cred); 3399 mutex_exit(&p->p_crlock); 3400 3401 psp->pr_pid = p->p_pid; 3402 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 3403 (p->p_flag & SZONETOP)) { 3404 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 3405 /* 3406 * Inside local zones, fake zsched's pid as parent pids for 3407 * processes which reference processes outside of the zone. 3408 */ 3409 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 3410 } else { 3411 psp->pr_ppid = p->p_ppid; 3412 } 3413 psp->pr_pgrp = p->p_pgrp; 3414 psp->pr_sid = p->p_sessp->s_sid; 3415 psp->pr_addr = prgetpsaddr(p); 3416 hrutime = mstate_aggr_state(p, LMS_USER); 3417 hrstime = mstate_aggr_state(p, LMS_SYSTEM); 3418 hrt2ts(hrutime + hrstime, &psp->pr_time); 3419 TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime); 3420 switch (p->p_model) { 3421 case DATAMODEL_ILP32: 3422 psp->pr_dmodel = PR_MODEL_ILP32; 3423 break; 3424 case DATAMODEL_LP64: 3425 psp->pr_dmodel = PR_MODEL_LP64; 3426 break; 3427 } 3428 if (state == SZOMB || t == NULL) { 3429 int wcode = p->p_wcode; /* must be atomic read */ 3430 3431 if (wcode) 3432 psp->pr_wstat = wstat(wcode, p->p_wdata); 3433 psp->pr_lttydev = PRNODEV; 3434 psp->pr_ottydev = (o_dev_t)PRNODEV; 3435 psp->pr_size = 0; 3436 psp->pr_rssize = 0; 3437 psp->pr_pctmem = 0; 3438 } else { 3439 up = PTOU(p); 3440 psp->pr_wchan = t->t_wchan; 3441 psp->pr_pri = t->t_pri; 3442 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name, 3443 sizeof (psp->pr_clname) - 1); 3444 retval = CL_DONICE(t, NULL, 0, &niceval); 3445 if (retval == 0) { 3446 psp->pr_oldpri = v.v_maxsyspri - psp->pr_pri; 3447 psp->pr_nice = niceval + NZERO; 3448 } else { 3449 psp->pr_oldpri = 0; 3450 psp->pr_nice = 0; 3451 } 3452 d = cttydev(p); 3453 #ifdef sun 3454 { 3455 extern dev_t rwsconsdev, rconsdev, uconsdev; 3456 /* 3457 * If the controlling terminal is the real 3458 * or workstation console device, map to what the 3459 * user thinks is the console device. Handle case when 3460 * rwsconsdev or rconsdev is set to NODEV for Starfire. 3461 */ 3462 if ((d == rwsconsdev || d == rconsdev) && d != NODEV) 3463 d = uconsdev; 3464 } 3465 #endif 3466 psp->pr_lttydev = (d == NODEV) ? PRNODEV : d; 3467 psp->pr_ottydev = cmpdev(d); 3468 psp->pr_start = up->u_start; 3469 bcopy(up->u_comm, psp->pr_fname, 3470 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1)); 3471 bcopy(up->u_psargs, psp->pr_psargs, 3472 MIN(PRARGSZ-1, PSARGSZ)); 3473 psp->pr_syscall = t->t_sysnum; 3474 psp->pr_argc = up->u_argc; 3475 psp->pr_argv = (char **)up->u_argv; 3476 psp->pr_envp = (char **)up->u_envp; 3477 3478 /* compute %cpu for the lwp or process */ 3479 pct = 0; 3480 if ((t = tp) == NULL) 3481 t = p->p_tlist; 3482 cur_time = gethrtime_unscaled(); 3483 do { 3484 pct += cpu_update_pct(t, cur_time); 3485 if (tp != NULL) /* just do the one lwp */ 3486 break; 3487 } while ((t = t->t_forw) != p->p_tlist); 3488 3489 psp->pr_pctcpu = prgetpctcpu(pct); 3490 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */ 3491 if (psp->pr_cpu > 99) 3492 psp->pr_cpu = 99; 3493 3494 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 3495 psp->pr_size = 0; 3496 psp->pr_rssize = 0; 3497 psp->pr_pctmem = 0; 3498 } else { 3499 mutex_exit(&p->p_lock); 3500 AS_LOCK_ENTER(as, RW_READER); 3501 psp->pr_size = btopr(as->a_resvsize); 3502 psp->pr_rssize = rm_asrss(as); 3503 psp->pr_pctmem = rm_pctmemory(as); 3504 AS_LOCK_EXIT(as); 3505 mutex_enter(&p->p_lock); 3506 } 3507 } 3508 psp->pr_bysize = ptob(psp->pr_size); 3509 psp->pr_byrssize = ptob(psp->pr_rssize); 3510 } 3511 3512 /* 3513 * Return an array of structures with memory map information. 3514 * We allocate here; the caller must deallocate. 3515 * The caller is also responsible to append the zero-filled entry 3516 * that terminates the PIOCMAP output buffer. 3517 */ 3518 static int 3519 oprgetmap(proc_t *p, list_t *iolhead) 3520 { 3521 struct as *as = p->p_as; 3522 prmap_t *mp; 3523 struct seg *seg; 3524 struct seg *brkseg, *stkseg; 3525 uint_t prot; 3526 3527 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3528 3529 /* 3530 * Request an initial buffer size that doesn't waste memory 3531 * if the address space has only a small number of segments. 3532 */ 3533 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 3534 3535 if ((seg = AS_SEGFIRST(as)) == NULL) 3536 return (0); 3537 3538 brkseg = break_seg(p); 3539 stkseg = as_segat(as, prgetstackbase(p)); 3540 3541 do { 3542 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3543 caddr_t saddr, naddr; 3544 void *tmp = NULL; 3545 3546 if ((seg->s_flags & S_HOLE) != 0) { 3547 continue; 3548 } 3549 3550 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3551 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3552 if (saddr == naddr) 3553 continue; 3554 3555 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 3556 3557 mp->pr_vaddr = saddr; 3558 mp->pr_size = naddr - saddr; 3559 mp->pr_off = SEGOP_GETOFFSET(seg, saddr); 3560 mp->pr_mflags = 0; 3561 if (prot & PROT_READ) 3562 mp->pr_mflags |= MA_READ; 3563 if (prot & PROT_WRITE) 3564 mp->pr_mflags |= MA_WRITE; 3565 if (prot & PROT_EXEC) 3566 mp->pr_mflags |= MA_EXEC; 3567 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3568 mp->pr_mflags |= MA_SHARED; 3569 if (seg == brkseg) 3570 mp->pr_mflags |= MA_BREAK; 3571 else if (seg == stkseg) 3572 mp->pr_mflags |= MA_STACK; 3573 mp->pr_pagesize = PAGESIZE; 3574 } 3575 ASSERT(tmp == NULL); 3576 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3577 3578 return (0); 3579 } 3580 3581 #ifdef _SYSCALL32_IMPL 3582 static int 3583 oprgetmap32(proc_t *p, list_t *iolhead) 3584 { 3585 struct as *as = p->p_as; 3586 ioc_prmap32_t *mp; 3587 struct seg *seg; 3588 struct seg *brkseg, *stkseg; 3589 uint_t prot; 3590 3591 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3592 3593 /* 3594 * Request an initial buffer size that doesn't waste memory 3595 * if the address space has only a small number of segments. 3596 */ 3597 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 3598 3599 if ((seg = AS_SEGFIRST(as)) == NULL) 3600 return (0); 3601 3602 brkseg = break_seg(p); 3603 stkseg = as_segat(as, prgetstackbase(p)); 3604 3605 do { 3606 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3607 caddr_t saddr, naddr; 3608 void *tmp = NULL; 3609 3610 if ((seg->s_flags & S_HOLE) != 0) { 3611 continue; 3612 } 3613 3614 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3615 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3616 if (saddr == naddr) 3617 continue; 3618 3619 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 3620 3621 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr; 3622 mp->pr_size = (size32_t)(naddr - saddr); 3623 mp->pr_off = (off32_t)SEGOP_GETOFFSET(seg, saddr); 3624 mp->pr_mflags = 0; 3625 if (prot & PROT_READ) 3626 mp->pr_mflags |= MA_READ; 3627 if (prot & PROT_WRITE) 3628 mp->pr_mflags |= MA_WRITE; 3629 if (prot & PROT_EXEC) 3630 mp->pr_mflags |= MA_EXEC; 3631 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3632 mp->pr_mflags |= MA_SHARED; 3633 if (seg == brkseg) 3634 mp->pr_mflags |= MA_BREAK; 3635 else if (seg == stkseg) 3636 mp->pr_mflags |= MA_STACK; 3637 mp->pr_pagesize = PAGESIZE; 3638 } 3639 ASSERT(tmp == NULL); 3640 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3641 3642 return (0); 3643 } 3644 #endif /* _SYSCALL32_IMPL */ 3645 3646 /* 3647 * Return the size of the old /proc page data file. 3648 */ 3649 size_t 3650 oprpdsize(struct as *as) 3651 { 3652 struct seg *seg; 3653 size_t size; 3654 3655 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3656 3657 if ((seg = AS_SEGFIRST(as)) == NULL) 3658 return (0); 3659 3660 size = sizeof (prpageheader_t); 3661 do { 3662 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3663 caddr_t saddr, naddr; 3664 void *tmp = NULL; 3665 size_t npage; 3666 3667 if ((seg->s_flags & S_HOLE) != 0) { 3668 continue; 3669 } 3670 3671 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3672 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3673 if ((npage = (naddr - saddr) / PAGESIZE) != 0) 3674 size += sizeof (prasmap_t) + roundlong(npage); 3675 } 3676 ASSERT(tmp == NULL); 3677 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3678 3679 return (size); 3680 } 3681 3682 #ifdef _SYSCALL32_IMPL 3683 size_t 3684 oprpdsize32(struct as *as) 3685 { 3686 struct seg *seg; 3687 size_t size; 3688 3689 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3690 3691 if ((seg = AS_SEGFIRST(as)) == NULL) 3692 return (0); 3693 3694 size = sizeof (ioc_prpageheader32_t); 3695 do { 3696 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3697 caddr_t saddr, naddr; 3698 void *tmp = NULL; 3699 size_t npage; 3700 3701 if ((seg->s_flags & S_HOLE) != 0) { 3702 continue; 3703 } 3704 3705 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3706 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3707 if ((npage = (naddr - saddr) / PAGESIZE) != 0) 3708 size += sizeof (ioc_prmap32_t) + round4(npage); 3709 } 3710 ASSERT(tmp == NULL); 3711 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3712 3713 return (size); 3714 } 3715 #endif /* _SYSCALL32_IMPL */ 3716 3717 /* 3718 * Read old /proc page data information. 3719 */ 3720 int 3721 oprpdread(struct as *as, uint_t hatid, struct uio *uiop) 3722 { 3723 caddr_t buf; 3724 size_t size; 3725 prpageheader_t *php; 3726 prasmap_t *pmp; 3727 struct seg *seg; 3728 int error; 3729 3730 again: 3731 AS_LOCK_ENTER(as, RW_WRITER); 3732 3733 if ((seg = AS_SEGFIRST(as)) == NULL) { 3734 AS_LOCK_EXIT(as); 3735 return (0); 3736 } 3737 size = oprpdsize(as); 3738 if (uiop->uio_resid < size) { 3739 AS_LOCK_EXIT(as); 3740 return (E2BIG); 3741 } 3742 3743 buf = kmem_zalloc(size, KM_SLEEP); 3744 php = (prpageheader_t *)buf; 3745 pmp = (prasmap_t *)(buf + sizeof (prpageheader_t)); 3746 3747 hrt2ts(gethrtime(), &php->pr_tstamp); 3748 php->pr_nmap = 0; 3749 php->pr_npage = 0; 3750 do { 3751 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3752 caddr_t saddr, naddr; 3753 void *tmp = NULL; 3754 3755 if ((seg->s_flags & S_HOLE) != 0) { 3756 continue; 3757 } 3758 3759 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3760 size_t len; 3761 size_t npage; 3762 uint_t prot; 3763 uintptr_t next; 3764 3765 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3766 if ((len = naddr - saddr) == 0) 3767 continue; 3768 npage = len / PAGESIZE; 3769 next = (uintptr_t)(pmp + 1) + roundlong(npage); 3770 /* 3771 * It's possible that the address space can change 3772 * subtlely even though we're holding as->a_lock 3773 * due to the nondeterminism of page_exists() in 3774 * the presence of asychronously flushed pages or 3775 * mapped files whose sizes are changing. 3776 * page_exists() may be called indirectly from 3777 * pr_getprot() by a SEGOP_INCORE() routine. 3778 * If this happens we need to make sure we don't 3779 * overrun the buffer whose size we computed based 3780 * on the initial iteration through the segments. 3781 * Once we've detected an overflow, we need to clean 3782 * up the temporary memory allocated in pr_getprot() 3783 * and retry. If there's a pending signal, we return 3784 * EINTR so that this thread can be dislodged if 3785 * a latent bug causes us to spin indefinitely. 3786 */ 3787 if (next > (uintptr_t)buf + size) { 3788 pr_getprot_done(&tmp); 3789 AS_LOCK_EXIT(as); 3790 3791 kmem_free(buf, size); 3792 3793 if (ISSIG(curthread, JUSTLOOKING)) 3794 return (EINTR); 3795 3796 goto again; 3797 } 3798 3799 php->pr_nmap++; 3800 php->pr_npage += npage; 3801 pmp->pr_vaddr = saddr; 3802 pmp->pr_npage = npage; 3803 pmp->pr_off = SEGOP_GETOFFSET(seg, saddr); 3804 pmp->pr_mflags = 0; 3805 if (prot & PROT_READ) 3806 pmp->pr_mflags |= MA_READ; 3807 if (prot & PROT_WRITE) 3808 pmp->pr_mflags |= MA_WRITE; 3809 if (prot & PROT_EXEC) 3810 pmp->pr_mflags |= MA_EXEC; 3811 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3812 pmp->pr_mflags |= MA_SHARED; 3813 pmp->pr_pagesize = PAGESIZE; 3814 hat_getstat(as, saddr, len, hatid, 3815 (char *)(pmp + 1), HAT_SYNC_ZERORM); 3816 pmp = (prasmap_t *)next; 3817 } 3818 ASSERT(tmp == NULL); 3819 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3820 3821 AS_LOCK_EXIT(as); 3822 3823 ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size); 3824 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop); 3825 kmem_free(buf, size); 3826 3827 return (error); 3828 } 3829 3830 #ifdef _SYSCALL32_IMPL 3831 int 3832 oprpdread32(struct as *as, uint_t hatid, struct uio *uiop) 3833 { 3834 caddr_t buf; 3835 size_t size; 3836 ioc_prpageheader32_t *php; 3837 ioc_prasmap32_t *pmp; 3838 struct seg *seg; 3839 int error; 3840 3841 again: 3842 AS_LOCK_ENTER(as, RW_WRITER); 3843 3844 if ((seg = AS_SEGFIRST(as)) == NULL) { 3845 AS_LOCK_EXIT(as); 3846 return (0); 3847 } 3848 size = oprpdsize32(as); 3849 if (uiop->uio_resid < size) { 3850 AS_LOCK_EXIT(as); 3851 return (E2BIG); 3852 } 3853 3854 buf = kmem_zalloc(size, KM_SLEEP); 3855 php = (ioc_prpageheader32_t *)buf; 3856 pmp = (ioc_prasmap32_t *)(buf + sizeof (ioc_prpageheader32_t)); 3857 3858 hrt2ts32(gethrtime(), &php->pr_tstamp); 3859 php->pr_nmap = 0; 3860 php->pr_npage = 0; 3861 do { 3862 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3863 caddr_t saddr, naddr; 3864 void *tmp = NULL; 3865 3866 if ((seg->s_flags & S_HOLE) != 0) { 3867 continue; 3868 } 3869 3870 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3871 size_t len; 3872 size_t npage; 3873 uint_t prot; 3874 uintptr_t next; 3875 3876 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3877 if ((len = naddr - saddr) == 0) 3878 continue; 3879 npage = len / PAGESIZE; 3880 next = (uintptr_t)(pmp + 1) + round4(npage); 3881 /* 3882 * It's possible that the address space can change 3883 * subtlely even though we're holding as->a_lock 3884 * due to the nondeterminism of page_exists() in 3885 * the presence of asychronously flushed pages or 3886 * mapped files whose sizes are changing. 3887 * page_exists() may be called indirectly from 3888 * pr_getprot() by a SEGOP_INCORE() routine. 3889 * If this happens we need to make sure we don't 3890 * overrun the buffer whose size we computed based 3891 * on the initial iteration through the segments. 3892 * Once we've detected an overflow, we need to clean 3893 * up the temporary memory allocated in pr_getprot() 3894 * and retry. If there's a pending signal, we return 3895 * EINTR so that this thread can be dislodged if 3896 * a latent bug causes us to spin indefinitely. 3897 */ 3898 if (next > (uintptr_t)buf + size) { 3899 pr_getprot_done(&tmp); 3900 AS_LOCK_EXIT(as); 3901 3902 kmem_free(buf, size); 3903 3904 if (ISSIG(curthread, JUSTLOOKING)) 3905 return (EINTR); 3906 3907 goto again; 3908 } 3909 3910 php->pr_nmap++; 3911 php->pr_npage += npage; 3912 pmp->pr_vaddr = (uint32_t)(uintptr_t)saddr; 3913 pmp->pr_npage = (uint32_t)npage; 3914 pmp->pr_off = (int32_t)SEGOP_GETOFFSET(seg, saddr); 3915 pmp->pr_mflags = 0; 3916 if (prot & PROT_READ) 3917 pmp->pr_mflags |= MA_READ; 3918 if (prot & PROT_WRITE) 3919 pmp->pr_mflags |= MA_WRITE; 3920 if (prot & PROT_EXEC) 3921 pmp->pr_mflags |= MA_EXEC; 3922 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3923 pmp->pr_mflags |= MA_SHARED; 3924 pmp->pr_pagesize = PAGESIZE; 3925 hat_getstat(as, saddr, len, hatid, 3926 (char *)(pmp + 1), HAT_SYNC_ZERORM); 3927 pmp = (ioc_prasmap32_t *)next; 3928 } 3929 ASSERT(tmp == NULL); 3930 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3931 3932 AS_LOCK_EXIT(as); 3933 3934 ASSERT((uintptr_t)pmp == (uintptr_t)buf + size); 3935 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop); 3936 kmem_free(buf, size); 3937 3938 return (error); 3939 } 3940 #endif /* _SYSCALL32_IMPL */ 3941 3942 /*ARGSUSED*/ 3943 #ifdef _SYSCALL32_IMPL 3944 int 3945 prioctl( 3946 struct vnode *vp, 3947 int cmd, 3948 intptr_t arg, 3949 int flag, 3950 cred_t *cr, 3951 int *rvalp, 3952 caller_context_t *ct) 3953 { 3954 switch (curproc->p_model) { 3955 case DATAMODEL_ILP32: 3956 return (prioctl32(vp, cmd, arg, flag, cr, rvalp, ct)); 3957 case DATAMODEL_LP64: 3958 return (prioctl64(vp, cmd, arg, flag, cr, rvalp, ct)); 3959 default: 3960 return (ENOSYS); 3961 } 3962 } 3963 #endif /* _SYSCALL32_IMPL */ 3964