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