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 (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 #include <sys/types.h>
  31 #include <sys/t_lock.h>
  32 #include <sys/param.h>
  33 #include <sys/cmn_err.h>
  34 #include <sys/cred.h>
  35 #include <sys/priv.h>
  36 #include <sys/debug.h>
  37 #include <sys/errno.h>
  38 #include <sys/inline.h>
  39 #include <sys/kmem.h>
  40 #include <sys/mman.h>
  41 #include <sys/proc.h>
  42 #include <sys/brand.h>
  43 #include <sys/sobject.h>
  44 #include <sys/sysmacros.h>
  45 #include <sys/systm.h>
  46 #include <sys/uio.h>
  47 #include <sys/var.h>
  48 #include <sys/vfs.h>
  49 #include <sys/vnode.h>
  50 #include <sys/session.h>
  51 #include <sys/pcb.h>
  52 #include <sys/signal.h>
  53 #include <sys/user.h>
  54 #include <sys/disp.h>
  55 #include <sys/class.h>
  56 #include <sys/ts.h>
  57 #include <sys/bitmap.h>
  58 #include <sys/poll.h>
  59 #include <sys/shm_impl.h>
  60 #include <sys/fault.h>
  61 #include <sys/syscall.h>
  62 #include <sys/procfs.h>
  63 #include <sys/processor.h>
  64 #include <sys/cpuvar.h>
  65 #include <sys/copyops.h>
  66 #include <sys/time.h>
  67 #include <sys/msacct.h>
  68 #include <vm/as.h>
  69 #include <vm/rm.h>
  70 #include <vm/seg.h>
  71 #include <vm/seg_vn.h>
  72 #include <vm/seg_dev.h>
  73 #include <vm/seg_spt.h>
  74 #include <vm/page.h>
  75 #include <sys/vmparam.h>
  76 #include <sys/swap.h>
  77 #include <fs/proc/prdata.h>
  78 #include <sys/task.h>
  79 #include <sys/project.h>
  80 #include <sys/contract_impl.h>
  81 #include <sys/contract/process.h>
  82 #include <sys/contract/process_impl.h>
  83 #include <sys/schedctl.h>
  84 #include <sys/pool.h>
  85 #include <sys/zone.h>
  86 #include <sys/atomic.h>
  87 #include <sys/sdt.h>
  88 
  89 #define MAX_ITERS_SPIN  5
  90 
  91 typedef struct prpagev {
  92         uint_t *pg_protv;       /* vector of page permissions */
  93         char *pg_incore;        /* vector of incore flags */
  94         size_t pg_npages;       /* number of pages in protv and incore */
  95         ulong_t pg_pnbase;      /* pn within segment of first protv element */
  96 } prpagev_t;
  97 
  98 size_t pagev_lim = 256 * 1024;  /* limit on number of pages in prpagev_t */
  99 
 100 extern struct seg_ops segdev_ops;       /* needs a header file */
 101 extern struct seg_ops segspt_shmops;    /* needs a header file */
 102 
 103 static  int     set_watched_page(proc_t *, caddr_t, caddr_t, ulong_t, ulong_t);
 104 static  void    clear_watched_page(proc_t *, caddr_t, caddr_t, ulong_t);
 105 
 106 /*
 107  * Choose an lwp from the complete set of lwps for the process.
 108  * This is called for any operation applied to the process
 109  * file descriptor that requires an lwp to operate upon.
 110  *
 111  * Returns a pointer to the thread for the selected LWP,
 112  * and with the dispatcher lock held for the thread.
 113  *
 114  * The algorithm for choosing an lwp is critical for /proc semantics;
 115  * don't touch this code unless you know all of the implications.
 116  */
 117 kthread_t *
 118 prchoose(proc_t *p)
 119 {
 120         kthread_t *t;
 121         kthread_t *t_onproc = NULL;     /* running on processor */
 122         kthread_t *t_run = NULL;        /* runnable, on disp queue */
 123         kthread_t *t_sleep = NULL;      /* sleeping */
 124         kthread_t *t_hold = NULL;       /* sleeping, performing hold */
 125         kthread_t *t_susp = NULL;       /* suspended stop */
 126         kthread_t *t_jstop = NULL;      /* jobcontrol stop, w/o directed stop */
 127         kthread_t *t_jdstop = NULL;     /* jobcontrol stop with directed stop */
 128         kthread_t *t_req = NULL;        /* requested stop */
 129         kthread_t *t_istop = NULL;      /* event-of-interest stop */
 130         kthread_t *t_dtrace = NULL;     /* DTrace stop */
 131 
 132         ASSERT(MUTEX_HELD(&p->p_lock));
 133 
 134         /*
 135          * If the agent lwp exists, it takes precedence over all others.
 136          */
 137         if ((t = p->p_agenttp) != NULL) {
 138                 thread_lock(t);
 139                 return (t);
 140         }
 141 
 142         if ((t = p->p_tlist) == NULL)        /* start at the head of the list */
 143                 return (t);
 144         do {            /* for eacn lwp in the process */
 145                 if (VSTOPPED(t)) {      /* virtually stopped */
 146                         if (t_req == NULL)
 147                                 t_req = t;
 148                         continue;
 149                 }
 150 
 151                 thread_lock(t);         /* make sure thread is in good state */
 152                 switch (t->t_state) {
 153                 default:
 154                         panic("prchoose: bad thread state %d, thread 0x%p",
 155                             t->t_state, (void *)t);
 156                         /*NOTREACHED*/
 157                 case TS_SLEEP:
 158                         /* this is filthy */
 159                         if (t->t_wchan == (caddr_t)&p->p_holdlwps &&
 160                             t->t_wchan0 == NULL) {
 161                                 if (t_hold == NULL)
 162                                         t_hold = t;
 163                         } else {
 164                                 if (t_sleep == NULL)
 165                                         t_sleep = t;
 166                         }
 167                         break;
 168                 case TS_RUN:
 169                 case TS_WAIT:
 170                         if (t_run == NULL)
 171                                 t_run = t;
 172                         break;
 173                 case TS_ONPROC:
 174                         if (t_onproc == NULL)
 175                                 t_onproc = t;
 176                         break;
 177                 case TS_ZOMB:           /* last possible choice */
 178                         break;
 179                 case TS_STOPPED:
 180                         switch (t->t_whystop) {
 181                         case PR_SUSPENDED:
 182                                 if (t_susp == NULL)
 183                                         t_susp = t;
 184                                 break;
 185                         case PR_JOBCONTROL:
 186                                 if (t->t_proc_flag & TP_PRSTOP) {
 187                                         if (t_jdstop == NULL)
 188                                                 t_jdstop = t;
 189                                 } else {
 190                                         if (t_jstop == NULL)
 191                                                 t_jstop = t;
 192                                 }
 193                                 break;
 194                         case PR_REQUESTED:
 195                                 if (t->t_dtrace_stop && t_dtrace == NULL)
 196                                         t_dtrace = t;
 197                                 else if (t_req == NULL)
 198                                         t_req = t;
 199                                 break;
 200                         case PR_SYSENTRY:
 201                         case PR_SYSEXIT:
 202                         case PR_SIGNALLED:
 203                         case PR_FAULTED:
 204                                 /*
 205                                  * Make an lwp calling exit() be the
 206                                  * last lwp seen in the process.
 207                                  */
 208                                 if (t_istop == NULL ||
 209                                     (t_istop->t_whystop == PR_SYSENTRY &&
 210                                     t_istop->t_whatstop == SYS_exit))
 211                                         t_istop = t;
 212                                 break;
 213                         case PR_CHECKPOINT:     /* can't happen? */
 214                                 break;
 215                         default:
 216                                 panic("prchoose: bad t_whystop %d, thread 0x%p",
 217                                     t->t_whystop, (void *)t);
 218                                 /*NOTREACHED*/
 219                         }
 220                         break;
 221                 }
 222                 thread_unlock(t);
 223         } while ((t = t->t_forw) != p->p_tlist);
 224 
 225         if (t_onproc)
 226                 t = t_onproc;
 227         else if (t_run)
 228                 t = t_run;
 229         else if (t_sleep)
 230                 t = t_sleep;
 231         else if (t_jstop)
 232                 t = t_jstop;
 233         else if (t_jdstop)
 234                 t = t_jdstop;
 235         else if (t_istop)
 236                 t = t_istop;
 237         else if (t_dtrace)
 238                 t = t_dtrace;
 239         else if (t_req)
 240                 t = t_req;
 241         else if (t_hold)
 242                 t = t_hold;
 243         else if (t_susp)
 244                 t = t_susp;
 245         else                    /* TS_ZOMB */
 246                 t = p->p_tlist;
 247 
 248         if (t != NULL)
 249                 thread_lock(t);
 250         return (t);
 251 }
 252 
 253 /*
 254  * Wakeup anyone sleeping on the /proc vnode for the process/lwp to stop.
 255  * Also call pollwakeup() if any lwps are waiting in poll() for POLLPRI
 256  * on the /proc file descriptor.  Called from stop() when a traced
 257  * process stops on an event of interest.  Also called from exit()
 258  * and prinvalidate() to indicate POLLHUP and POLLERR respectively.
 259  */
 260 void
 261 prnotify(struct vnode *vp)
 262 {
 263         prcommon_t *pcp = VTOP(vp)->pr_common;
 264 
 265         mutex_enter(&pcp->prc_mutex);
 266         cv_broadcast(&pcp->prc_wait);
 267         mutex_exit(&pcp->prc_mutex);
 268         if (pcp->prc_flags & PRC_POLL) {
 269                 /*
 270                  * We call pollwakeup() with POLLHUP to ensure that
 271                  * the pollers are awakened even if they are polling
 272                  * for nothing (i.e., waiting for the process to exit).
 273                  * This enables the use of the PRC_POLL flag for optimization
 274                  * (we can turn off PRC_POLL only if we know no pollers remain).
 275                  */
 276                 pcp->prc_flags &= ~PRC_POLL;
 277                 pollwakeup(&pcp->prc_pollhead, POLLHUP);
 278         }
 279 }
 280 
 281 /* called immediately below, in prfree() */
 282 static void
 283 prfreenotify(vnode_t *vp)
 284 {
 285         prnode_t *pnp;
 286         prcommon_t *pcp;
 287 
 288         while (vp != NULL) {
 289                 pnp = VTOP(vp);
 290                 pcp = pnp->pr_common;
 291                 ASSERT(pcp->prc_thread == NULL);
 292                 pcp->prc_proc = NULL;
 293                 /*
 294                  * We can't call prnotify() here because we are holding
 295                  * pidlock.  We assert that there is no need to.
 296                  */
 297                 mutex_enter(&pcp->prc_mutex);
 298                 cv_broadcast(&pcp->prc_wait);
 299                 mutex_exit(&pcp->prc_mutex);
 300                 ASSERT(!(pcp->prc_flags & PRC_POLL));
 301 
 302                 vp = pnp->pr_next;
 303                 pnp->pr_next = NULL;
 304         }
 305 }
 306 
 307 /*
 308  * Called from a hook in freeproc() when a traced process is removed
 309  * from the process table.  The proc-table pointers of all associated
 310  * /proc vnodes are cleared to indicate that the process has gone away.
 311  */
 312 void
 313 prfree(proc_t *p)
 314 {
 315         uint_t slot = p->p_slot;
 316 
 317         ASSERT(MUTEX_HELD(&pidlock));
 318 
 319         /*
 320          * Block the process against /proc so it can be freed.
 321          * It cannot be freed while locked by some controlling process.
 322          * Lock ordering:
 323          *      pidlock -> pr_pidlock -> p->p_lock -> pcp->prc_mutex
 324          */
 325         mutex_enter(&pr_pidlock);   /* protects pcp->prc_proc */
 326         mutex_enter(&p->p_lock);
 327         while (p->p_proc_flag & P_PR_LOCK) {
 328                 mutex_exit(&pr_pidlock);
 329                 cv_wait(&pr_pid_cv[slot], &p->p_lock);
 330                 mutex_exit(&p->p_lock);
 331                 mutex_enter(&pr_pidlock);
 332                 mutex_enter(&p->p_lock);
 333         }
 334 
 335         ASSERT(p->p_tlist == NULL);
 336 
 337         prfreenotify(p->p_plist);
 338         p->p_plist = NULL;
 339 
 340         prfreenotify(p->p_trace);
 341         p->p_trace = NULL;
 342 
 343         /*
 344          * We broadcast to wake up everyone waiting for this process.
 345          * No one can reach this process from this point on.
 346          */
 347         cv_broadcast(&pr_pid_cv[slot]);
 348 
 349         mutex_exit(&p->p_lock);
 350         mutex_exit(&pr_pidlock);
 351 }
 352 
 353 /*
 354  * Called from a hook in exit() when a traced process is becoming a zombie.
 355  */
 356 void
 357 prexit(proc_t *p)
 358 {
 359         ASSERT(MUTEX_HELD(&p->p_lock));
 360 
 361         if (pr_watch_active(p)) {
 362                 pr_free_watchpoints(p);
 363                 watch_disable(curthread);
 364         }
 365         /* pr_free_watched_pages() is called in exit(), after dropping p_lock */
 366         if (p->p_trace) {
 367                 VTOP(p->p_trace)->pr_common->prc_flags |= PRC_DESTROY;
 368                 prnotify(p->p_trace);
 369         }
 370         cv_broadcast(&pr_pid_cv[p->p_slot]);     /* pauselwps() */
 371 }
 372 
 373 /*
 374  * Called when a thread calls lwp_exit().
 375  */
 376 void
 377 prlwpexit(kthread_t *t)
 378 {
 379         vnode_t *vp;
 380         prnode_t *pnp;
 381         prcommon_t *pcp;
 382         proc_t *p = ttoproc(t);
 383         lwpent_t *lep = p->p_lwpdir[t->t_dslot].ld_entry;
 384 
 385         ASSERT(t == curthread);
 386         ASSERT(MUTEX_HELD(&p->p_lock));
 387 
 388         /*
 389          * The process must be blocked against /proc to do this safely.
 390          * The lwp must not disappear while the process is marked P_PR_LOCK.
 391          * It is the caller's responsibility to have called prbarrier(p).
 392          */
 393         ASSERT(!(p->p_proc_flag & P_PR_LOCK));
 394 
 395         for (vp = p->p_plist; vp != NULL; vp = pnp->pr_next) {
 396                 pnp = VTOP(vp);
 397                 pcp = pnp->pr_common;
 398                 if (pcp->prc_thread == t) {
 399                         pcp->prc_thread = NULL;
 400                         pcp->prc_flags |= PRC_DESTROY;
 401                 }
 402         }
 403 
 404         for (vp = lep->le_trace; vp != NULL; vp = pnp->pr_next) {
 405                 pnp = VTOP(vp);
 406                 pcp = pnp->pr_common;
 407                 pcp->prc_thread = NULL;
 408                 pcp->prc_flags |= PRC_DESTROY;
 409                 prnotify(vp);
 410         }
 411 
 412         if (p->p_trace)
 413                 prnotify(p->p_trace);
 414 }
 415 
 416 /*
 417  * Called when a zombie thread is joined or when a
 418  * detached lwp exits.  Called from lwp_hash_out().
 419  */
 420 void
 421 prlwpfree(proc_t *p, lwpent_t *lep)
 422 {
 423         vnode_t *vp;
 424         prnode_t *pnp;
 425         prcommon_t *pcp;
 426 
 427         ASSERT(MUTEX_HELD(&p->p_lock));
 428 
 429         /*
 430          * The process must be blocked against /proc to do this safely.
 431          * The lwp must not disappear while the process is marked P_PR_LOCK.
 432          * It is the caller's responsibility to have called prbarrier(p).
 433          */
 434         ASSERT(!(p->p_proc_flag & P_PR_LOCK));
 435 
 436         vp = lep->le_trace;
 437         lep->le_trace = NULL;
 438         while (vp) {
 439                 prnotify(vp);
 440                 pnp = VTOP(vp);
 441                 pcp = pnp->pr_common;
 442                 ASSERT(pcp->prc_thread == NULL &&
 443                     (pcp->prc_flags & PRC_DESTROY));
 444                 pcp->prc_tslot = -1;
 445                 vp = pnp->pr_next;
 446                 pnp->pr_next = NULL;
 447         }
 448 
 449         if (p->p_trace)
 450                 prnotify(p->p_trace);
 451 }
 452 
 453 /*
 454  * Called from a hook in exec() when a thread starts exec().
 455  */
 456 void
 457 prexecstart(void)
 458 {
 459         proc_t *p = ttoproc(curthread);
 460         klwp_t *lwp = ttolwp(curthread);
 461 
 462         /*
 463          * The P_PR_EXEC flag blocks /proc operations for
 464          * the duration of the exec().
 465          * We can't start exec() while the process is
 466          * locked by /proc, so we call prbarrier().
 467          * lwp_nostop keeps the process from being stopped
 468          * via job control for the duration of the exec().
 469          */
 470 
 471         ASSERT(MUTEX_HELD(&p->p_lock));
 472         prbarrier(p);
 473         lwp->lwp_nostop++;
 474         p->p_proc_flag |= P_PR_EXEC;
 475 }
 476 
 477 /*
 478  * Called from a hook in exec() when a thread finishes exec().
 479  * The thread may or may not have succeeded.  Some other thread
 480  * may have beat it to the punch.
 481  */
 482 void
 483 prexecend(void)
 484 {
 485         proc_t *p = ttoproc(curthread);
 486         klwp_t *lwp = ttolwp(curthread);
 487         vnode_t *vp;
 488         prnode_t *pnp;
 489         prcommon_t *pcp;
 490         model_t model = p->p_model;
 491         id_t tid = curthread->t_tid;
 492         int tslot = curthread->t_dslot;
 493 
 494         ASSERT(MUTEX_HELD(&p->p_lock));
 495 
 496         lwp->lwp_nostop--;
 497         if (p->p_flag & SEXITLWPS) {
 498                 /*
 499                  * We are on our way to exiting because some
 500                  * other thread beat us in the race to exec().
 501                  * Don't clear the P_PR_EXEC flag in this case.
 502                  */
 503                 return;
 504         }
 505 
 506         /*
 507          * Wake up anyone waiting in /proc for the process to complete exec().
 508          */
 509         p->p_proc_flag &= ~P_PR_EXEC;
 510         if ((vp = p->p_trace) != NULL) {
 511                 pcp = VTOP(vp)->pr_common;
 512                 mutex_enter(&pcp->prc_mutex);
 513                 cv_broadcast(&pcp->prc_wait);
 514                 mutex_exit(&pcp->prc_mutex);
 515                 for (; vp != NULL; vp = pnp->pr_next) {
 516                         pnp = VTOP(vp);
 517                         pnp->pr_common->prc_datamodel = model;
 518                 }
 519         }
 520         if ((vp = p->p_lwpdir[tslot].ld_entry->le_trace) != NULL) {
 521                 /*
 522                  * We dealt with the process common above.
 523                  */
 524                 ASSERT(p->p_trace != NULL);
 525                 pcp = VTOP(vp)->pr_common;
 526                 mutex_enter(&pcp->prc_mutex);
 527                 cv_broadcast(&pcp->prc_wait);
 528                 mutex_exit(&pcp->prc_mutex);
 529                 for (; vp != NULL; vp = pnp->pr_next) {
 530                         pnp = VTOP(vp);
 531                         pcp = pnp->pr_common;
 532                         pcp->prc_datamodel = model;
 533                         pcp->prc_tid = tid;
 534                         pcp->prc_tslot = tslot;
 535                 }
 536         }
 537 }
 538 
 539 /*
 540  * Called from a hook in relvm() just before freeing the address space.
 541  * We free all the watched areas now.
 542  */
 543 void
 544 prrelvm(void)
 545 {
 546         proc_t *p = ttoproc(curthread);
 547 
 548         mutex_enter(&p->p_lock);
 549         prbarrier(p);   /* block all other /proc operations */
 550         if (pr_watch_active(p)) {
 551                 pr_free_watchpoints(p);
 552                 watch_disable(curthread);
 553         }
 554         mutex_exit(&p->p_lock);
 555         pr_free_watched_pages(p);
 556 }
 557 
 558 /*
 559  * Called from hooks in exec-related code when a traced process
 560  * attempts to exec(2) a setuid/setgid program or an unreadable
 561  * file.  Rather than fail the exec we invalidate the associated
 562  * /proc vnodes so that subsequent attempts to use them will fail.
 563  *
 564  * All /proc vnodes, except directory vnodes, are retained on a linked
 565  * list (rooted at p_plist in the process structure) until last close.
 566  *
 567  * A controlling process must re-open the /proc files in order to
 568  * regain control.
 569  */
 570 void
 571 prinvalidate(struct user *up)
 572 {
 573         kthread_t *t = curthread;
 574         proc_t *p = ttoproc(t);
 575         vnode_t *vp;
 576         prnode_t *pnp;
 577         int writers = 0;
 578 
 579         mutex_enter(&p->p_lock);
 580         prbarrier(p);   /* block all other /proc operations */
 581 
 582         /*
 583          * At this moment, there can be only one lwp in the process.
 584          */
 585         ASSERT(p->p_lwpcnt == 1 && p->p_zombcnt == 0);
 586 
 587         /*
 588          * Invalidate any currently active /proc vnodes.
 589          */
 590         for (vp = p->p_plist; vp != NULL; vp = pnp->pr_next) {
 591                 pnp = VTOP(vp);
 592                 switch (pnp->pr_type) {
 593                 case PR_PSINFO:         /* these files can read by anyone */
 594                 case PR_LPSINFO:
 595                 case PR_LWPSINFO:
 596                 case PR_LWPDIR:
 597                 case PR_LWPIDDIR:
 598                 case PR_USAGE:
 599                 case PR_LUSAGE:
 600                 case PR_LWPUSAGE:
 601                         break;
 602                 default:
 603                         pnp->pr_flags |= PR_INVAL;
 604                         break;
 605                 }
 606         }
 607         /*
 608          * Wake up anyone waiting for the process or lwp.
 609          * p->p_trace is guaranteed to be non-NULL if there
 610          * are any open /proc files for this process.
 611          */
 612         if ((vp = p->p_trace) != NULL) {
 613                 prcommon_t *pcp = VTOP(vp)->pr_pcommon;
 614 
 615                 prnotify(vp);
 616                 /*
 617                  * Are there any writers?
 618                  */
 619                 if ((writers = pcp->prc_writers) != 0) {
 620                         /*
 621                          * Clear the exclusive open flag (old /proc interface).
 622                          * Set prc_selfopens equal to prc_writers so that
 623                          * the next O_EXCL|O_WRITE open will succeed
 624                          * even with existing (though invalid) writers.
 625                          * prclose() must decrement prc_selfopens when
 626                          * the invalid files are closed.
 627                          */
 628                         pcp->prc_flags &= ~PRC_EXCL;
 629                         ASSERT(pcp->prc_selfopens <= writers);
 630                         pcp->prc_selfopens = writers;
 631                 }
 632         }
 633         vp = p->p_lwpdir[t->t_dslot].ld_entry->le_trace;
 634         while (vp != NULL) {
 635                 /*
 636                  * We should not invalidate the lwpiddir vnodes,
 637                  * but the necessities of maintaining the old
 638                  * ioctl()-based version of /proc require it.
 639                  */
 640                 pnp = VTOP(vp);
 641                 pnp->pr_flags |= PR_INVAL;
 642                 prnotify(vp);
 643                 vp = pnp->pr_next;
 644         }
 645 
 646         /*
 647          * If any tracing flags are in effect and any vnodes are open for
 648          * writing then set the requested-stop and run-on-last-close flags.
 649          * Otherwise, clear all tracing flags.
 650          */
 651         t->t_proc_flag &= ~TP_PAUSE;
 652         if ((p->p_proc_flag & P_PR_TRACE) && writers) {
 653                 t->t_proc_flag |= TP_PRSTOP;
 654                 aston(t);               /* so ISSIG will see the flag */
 655                 p->p_proc_flag |= P_PR_RUNLCL;
 656         } else {
 657                 premptyset(&up->u_entrymask);            /* syscalls */
 658                 premptyset(&up->u_exitmask);
 659                 up->u_systrap = 0;
 660                 premptyset(&p->p_sigmask);               /* signals */
 661                 premptyset(&p->p_fltmask);               /* faults */
 662                 t->t_proc_flag &= ~(TP_PRSTOP|TP_PRVSTOP|TP_STOPPING);
 663                 p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE);
 664                 prnostep(ttolwp(t));
 665         }
 666 
 667         mutex_exit(&p->p_lock);
 668 }
 669 
 670 /*
 671  * Acquire the controlled process's p_lock and mark it P_PR_LOCK.
 672  * Return with pr_pidlock held in all cases.
 673  * Return with p_lock held if the the process still exists.
 674  * Return value is the process pointer if the process still exists, else NULL.
 675  * If we lock the process, give ourself kernel priority to avoid deadlocks;
 676  * this is undone in prunlock().
 677  */
 678 proc_t *
 679 pr_p_lock(prnode_t *pnp)
 680 {
 681         proc_t *p;
 682         prcommon_t *pcp;
 683 
 684         mutex_enter(&pr_pidlock);
 685         if ((pcp = pnp->pr_pcommon) == NULL || (p = pcp->prc_proc) == NULL)
 686                 return (NULL);
 687         mutex_enter(&p->p_lock);
 688         while (p->p_proc_flag & P_PR_LOCK) {
 689                 /*
 690                  * This cv/mutex pair is persistent even if
 691                  * the process disappears while we sleep.
 692                  */
 693                 kcondvar_t *cv = &pr_pid_cv[p->p_slot];
 694                 kmutex_t *mp = &p->p_lock;
 695 
 696                 mutex_exit(&pr_pidlock);
 697                 cv_wait(cv, mp);
 698                 mutex_exit(mp);
 699                 mutex_enter(&pr_pidlock);
 700                 if (pcp->prc_proc == NULL)
 701                         return (NULL);
 702                 ASSERT(p == pcp->prc_proc);
 703                 mutex_enter(&p->p_lock);
 704         }
 705         p->p_proc_flag |= P_PR_LOCK;
 706         return (p);
 707 }
 708 
 709 /*
 710  * Lock the target process by setting P_PR_LOCK and grabbing p->p_lock.
 711  * This prevents any lwp of the process from disappearing and
 712  * blocks most operations that a process can perform on itself.
 713  * Returns 0 on success, a non-zero error number on failure.
 714  *
 715  * 'zdisp' is ZYES or ZNO to indicate whether prlock() should succeed when
 716  * the subject process is a zombie (ZYES) or fail for zombies (ZNO).
 717  *
 718  * error returns:
 719  *      ENOENT: process or lwp has disappeared or process is exiting
 720  *              (or has become a zombie and zdisp == ZNO).
 721  *      EAGAIN: procfs vnode has become invalid.
 722  *      EINTR:  signal arrived while waiting for exec to complete.
 723  */
 724 int
 725 prlock(prnode_t *pnp, int zdisp)
 726 {
 727         prcommon_t *pcp;
 728         proc_t *p;
 729 
 730 again:
 731         pcp = pnp->pr_common;
 732         p = pr_p_lock(pnp);
 733         mutex_exit(&pr_pidlock);
 734 
 735         /*
 736          * Return ENOENT immediately if there is no process.
 737          */
 738         if (p == NULL)
 739                 return (ENOENT);
 740 
 741         ASSERT(p == pcp->prc_proc && p->p_stat != 0 && p->p_stat != SIDL);
 742 
 743         /*
 744          * Return ENOENT if process entered zombie state or is exiting
 745          * and the 'zdisp' flag is set to ZNO indicating not to lock zombies.
 746          */
 747         if (zdisp == ZNO &&
 748             ((pcp->prc_flags & PRC_DESTROY) || (p->p_flag & SEXITING))) {
 749                 prunlock(pnp);
 750                 return (ENOENT);
 751         }
 752 
 753         /*
 754          * If lwp-specific, check to see if lwp has disappeared.
 755          */
 756         if (pcp->prc_flags & PRC_LWP) {
 757                 if ((zdisp == ZNO && (pcp->prc_flags & PRC_DESTROY)) ||
 758                     pcp->prc_tslot == -1) {
 759                         prunlock(pnp);
 760                         return (ENOENT);
 761                 }
 762         }
 763 
 764         /*
 765          * Return EAGAIN if we have encountered a security violation.
 766          * (The process exec'd a set-id or unreadable executable file.)
 767          */
 768         if (pnp->pr_flags & PR_INVAL) {
 769                 prunlock(pnp);
 770                 return (EAGAIN);
 771         }
 772 
 773         /*
 774          * If process is undergoing an exec(), wait for
 775          * completion and then start all over again.
 776          */
 777         if (p->p_proc_flag & P_PR_EXEC) {
 778                 pcp = pnp->pr_pcommon;       /* Put on the correct sleep queue */
 779                 mutex_enter(&pcp->prc_mutex);
 780                 prunlock(pnp);
 781                 if (!cv_wait_sig(&pcp->prc_wait, &pcp->prc_mutex)) {
 782                         mutex_exit(&pcp->prc_mutex);
 783                         return (EINTR);
 784                 }
 785                 mutex_exit(&pcp->prc_mutex);
 786                 goto again;
 787         }
 788 
 789         /*
 790          * We return holding p->p_lock.
 791          */
 792         return (0);
 793 }
 794 
 795 /*
 796  * Undo prlock() and pr_p_lock().
 797  * p->p_lock is still held; pr_pidlock is no longer held.
 798  *
 799  * prunmark() drops the P_PR_LOCK flag and wakes up another thread,
 800  * if any, waiting for the flag to be dropped; it retains p->p_lock.
 801  *
 802  * prunlock() calls prunmark() and then drops p->p_lock.
 803  */
 804 void
 805 prunmark(proc_t *p)
 806 {
 807         ASSERT(p->p_proc_flag & P_PR_LOCK);
 808         ASSERT(MUTEX_HELD(&p->p_lock));
 809 
 810         cv_signal(&pr_pid_cv[p->p_slot]);
 811         p->p_proc_flag &= ~P_PR_LOCK;
 812 }
 813 
 814 void
 815 prunlock(prnode_t *pnp)
 816 {
 817         prcommon_t *pcp = pnp->pr_common;
 818         proc_t *p = pcp->prc_proc;
 819 
 820         /*
 821          * If we (or someone) gave it a SIGKILL, and it is not
 822          * already a zombie, set it running unconditionally.
 823          */
 824         if ((p->p_flag & SKILLED) &&
 825             !(p->p_flag & SEXITING) &&
 826             !(pcp->prc_flags & PRC_DESTROY) &&
 827             !((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot == -1))
 828                 (void) pr_setrun(pnp, 0);
 829         prunmark(p);
 830         mutex_exit(&p->p_lock);
 831 }
 832 
 833 /*
 834  * Called while holding p->p_lock to delay until the process is unlocked.
 835  * We enter holding p->p_lock; p->p_lock is dropped and reacquired.
 836  * The process cannot become locked again until p->p_lock is dropped.
 837  */
 838 void
 839 prbarrier(proc_t *p)
 840 {
 841         ASSERT(MUTEX_HELD(&p->p_lock));
 842 
 843         if (p->p_proc_flag & P_PR_LOCK) {
 844                 /* The process is locked; delay until not locked */
 845                 uint_t slot = p->p_slot;
 846 
 847                 while (p->p_proc_flag & P_PR_LOCK)
 848                         cv_wait(&pr_pid_cv[slot], &p->p_lock);
 849                 cv_signal(&pr_pid_cv[slot]);
 850         }
 851 }
 852 
 853 /*
 854  * Return process/lwp status.
 855  * The u-block is mapped in by this routine and unmapped at the end.
 856  */
 857 void
 858 prgetstatus(proc_t *p, pstatus_t *sp, zone_t *zp)
 859 {
 860         kthread_t *t;
 861 
 862         ASSERT(MUTEX_HELD(&p->p_lock));
 863 
 864         t = prchoose(p);        /* returns locked thread */
 865         ASSERT(t != NULL);
 866         thread_unlock(t);
 867 
 868         /* just bzero the process part, prgetlwpstatus() does the rest */
 869         bzero(sp, sizeof (pstatus_t) - sizeof (lwpstatus_t));
 870         sp->pr_nlwp = p->p_lwpcnt;
 871         sp->pr_nzomb = p->p_zombcnt;
 872         prassignset(&sp->pr_sigpend, &p->p_sig);
 873         sp->pr_brkbase = (uintptr_t)p->p_brkbase;
 874         sp->pr_brksize = p->p_brksize;
 875         sp->pr_stkbase = (uintptr_t)prgetstackbase(p);
 876         sp->pr_stksize = p->p_stksize;
 877         sp->pr_pid = p->p_pid;
 878         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
 879             (p->p_flag & SZONETOP)) {
 880                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
 881                 /*
 882                  * Inside local zones, fake zsched's pid as parent pids for
 883                  * processes which reference processes outside of the zone.
 884                  */
 885                 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
 886         } else {
 887                 sp->pr_ppid = p->p_ppid;
 888         }
 889         sp->pr_pgid  = p->p_pgrp;
 890         sp->pr_sid   = p->p_sessp->s_sid;
 891         sp->pr_taskid = p->p_task->tk_tkid;
 892         sp->pr_projid = p->p_task->tk_proj->kpj_id;
 893         sp->pr_zoneid = p->p_zone->zone_id;
 894         hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
 895         hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
 896         TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime);
 897         TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime);
 898         prassignset(&sp->pr_sigtrace, &p->p_sigmask);
 899         prassignset(&sp->pr_flttrace, &p->p_fltmask);
 900         prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
 901         prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
 902         switch (p->p_model) {
 903         case DATAMODEL_ILP32:
 904                 sp->pr_dmodel = PR_MODEL_ILP32;
 905                 break;
 906         case DATAMODEL_LP64:
 907                 sp->pr_dmodel = PR_MODEL_LP64;
 908                 break;
 909         }
 910         if (p->p_agenttp)
 911                 sp->pr_agentid = p->p_agenttp->t_tid;
 912 
 913         /* get the chosen lwp's status */
 914         prgetlwpstatus(t, &sp->pr_lwp, zp);
 915 
 916         /* replicate the flags */
 917         sp->pr_flags = sp->pr_lwp.pr_flags;
 918 }
 919 
 920 #ifdef _SYSCALL32_IMPL
 921 void
 922 prgetlwpstatus32(kthread_t *t, lwpstatus32_t *sp, zone_t *zp)
 923 {
 924         proc_t *p = ttoproc(t);
 925         klwp_t *lwp = ttolwp(t);
 926         struct mstate *ms = &lwp->lwp_mstate;
 927         hrtime_t usr, sys;
 928         int flags;
 929         ulong_t instr;
 930 
 931         ASSERT(MUTEX_HELD(&p->p_lock));
 932 
 933         bzero(sp, sizeof (*sp));
 934         flags = 0L;
 935         if (t->t_state == TS_STOPPED) {
 936                 flags |= PR_STOPPED;
 937                 if ((t->t_schedflag & TS_PSTART) == 0)
 938                         flags |= PR_ISTOP;
 939         } else if (VSTOPPED(t)) {
 940                 flags |= PR_STOPPED|PR_ISTOP;
 941         }
 942         if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
 943                 flags |= PR_DSTOP;
 944         if (lwp->lwp_asleep)
 945                 flags |= PR_ASLEEP;
 946         if (t == p->p_agenttp)
 947                 flags |= PR_AGENT;
 948         if (!(t->t_proc_flag & TP_TWAIT))
 949                 flags |= PR_DETACH;
 950         if (t->t_proc_flag & TP_DAEMON)
 951                 flags |= PR_DAEMON;
 952         if (p->p_proc_flag & P_PR_FORK)
 953                 flags |= PR_FORK;
 954         if (p->p_proc_flag & P_PR_RUNLCL)
 955                 flags |= PR_RLC;
 956         if (p->p_proc_flag & P_PR_KILLCL)
 957                 flags |= PR_KLC;
 958         if (p->p_proc_flag & P_PR_ASYNC)
 959                 flags |= PR_ASYNC;
 960         if (p->p_proc_flag & P_PR_BPTADJ)
 961                 flags |= PR_BPTADJ;
 962         if (p->p_proc_flag & P_PR_PTRACE)
 963                 flags |= PR_PTRACE;
 964         if (p->p_flag & SMSACCT)
 965                 flags |= PR_MSACCT;
 966         if (p->p_flag & SMSFORK)
 967                 flags |= PR_MSFORK;
 968         if (p->p_flag & SVFWAIT)
 969                 flags |= PR_VFORKP;
 970         sp->pr_flags = flags;
 971         if (VSTOPPED(t)) {
 972                 sp->pr_why   = PR_REQUESTED;
 973                 sp->pr_what  = 0;
 974         } else {
 975                 sp->pr_why   = t->t_whystop;
 976                 sp->pr_what  = t->t_whatstop;
 977         }
 978         sp->pr_lwpid = t->t_tid;
 979         sp->pr_cursig  = lwp->lwp_cursig;
 980         prassignset(&sp->pr_lwppend, &t->t_sig);
 981         schedctl_finish_sigblock(t);
 982         prassignset(&sp->pr_lwphold, &t->t_hold);
 983         if (t->t_whystop == PR_FAULTED) {
 984                 siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info);
 985                 if (t->t_whatstop == FLTPAGE)
 986                         sp->pr_info.si_addr =
 987                             (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr;
 988         } else if (lwp->lwp_curinfo)
 989                 siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info);
 990         if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
 991             sp->pr_info.si_zoneid != zp->zone_id) {
 992                 sp->pr_info.si_pid = zp->zone_zsched->p_pid;
 993                 sp->pr_info.si_uid = 0;
 994                 sp->pr_info.si_ctid = -1;
 995                 sp->pr_info.si_zoneid = zp->zone_id;
 996         }
 997         sp->pr_altstack.ss_sp =
 998             (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp;
 999         sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size;
1000         sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags;
1001         prgetaction32(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1002         sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext;
1003         sp->pr_ustack = (caddr32_t)lwp->lwp_ustack;
1004         (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1005             sizeof (sp->pr_clname) - 1);
1006         if (flags & PR_STOPPED)
1007                 hrt2ts32(t->t_stoptime, &sp->pr_tstamp);
1008         usr = ms->ms_acct[LMS_USER];
1009         sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1010         scalehrtime(&usr);
1011         scalehrtime(&sys);
1012         hrt2ts32(usr, &sp->pr_utime);
1013         hrt2ts32(sys, &sp->pr_stime);
1014 
1015         /*
1016          * Fetch the current instruction, if not a system process.
1017          * We don't attempt this unless the lwp is stopped.
1018          */
1019         if ((p->p_flag & SSYS) || p->p_as == &kas)
1020                 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1021         else if (!(flags & PR_STOPPED))
1022                 sp->pr_flags |= PR_PCINVAL;
1023         else if (!prfetchinstr(lwp, &instr))
1024                 sp->pr_flags |= PR_PCINVAL;
1025         else
1026                 sp->pr_instr = (uint32_t)instr;
1027 
1028         /*
1029          * Drop p_lock while touching the lwp's stack.
1030          */
1031         mutex_exit(&p->p_lock);
1032         if (prisstep(lwp))
1033                 sp->pr_flags |= PR_STEP;
1034         if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1035                 int i;
1036 
1037                 sp->pr_syscall = get_syscall32_args(lwp,
1038                     (int *)sp->pr_sysarg, &i);
1039                 sp->pr_nsysarg = (ushort_t)i;
1040         }
1041         if ((flags & PR_STOPPED) || t == curthread)
1042                 prgetprregs32(lwp, sp->pr_reg);
1043         if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1044             (flags & PR_VFORKP)) {
1045                 long r1, r2;
1046                 user_t *up;
1047                 auxv_t *auxp;
1048                 int i;
1049 
1050                 sp->pr_errno = prgetrvals(lwp, &r1, &r2);
1051                 if (sp->pr_errno == 0) {
1052                         sp->pr_rval1 = (int32_t)r1;
1053                         sp->pr_rval2 = (int32_t)r2;
1054                         sp->pr_errpriv = PRIV_NONE;
1055                 } else
1056                         sp->pr_errpriv = lwp->lwp_badpriv;
1057 
1058                 if (t->t_sysnum == SYS_execve) {
1059                         up = PTOU(p);
1060                         sp->pr_sysarg[0] = 0;
1061                         sp->pr_sysarg[1] = (caddr32_t)up->u_argv;
1062                         sp->pr_sysarg[2] = (caddr32_t)up->u_envp;
1063                         for (i = 0, auxp = up->u_auxv;
1064                             i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1065                             i++, auxp++) {
1066                                 if (auxp->a_type == AT_SUN_EXECNAME) {
1067                                         sp->pr_sysarg[0] =
1068                                             (caddr32_t)
1069                                             (uintptr_t)auxp->a_un.a_ptr;
1070                                         break;
1071                                 }
1072                         }
1073                 }
1074         }
1075         if (prhasfp())
1076                 prgetprfpregs32(lwp, &sp->pr_fpreg);
1077         mutex_enter(&p->p_lock);
1078 }
1079 
1080 void
1081 prgetstatus32(proc_t *p, pstatus32_t *sp, zone_t *zp)
1082 {
1083         kthread_t *t;
1084 
1085         ASSERT(MUTEX_HELD(&p->p_lock));
1086 
1087         t = prchoose(p);        /* returns locked thread */
1088         ASSERT(t != NULL);
1089         thread_unlock(t);
1090 
1091         /* just bzero the process part, prgetlwpstatus32() does the rest */
1092         bzero(sp, sizeof (pstatus32_t) - sizeof (lwpstatus32_t));
1093         sp->pr_nlwp = p->p_lwpcnt;
1094         sp->pr_nzomb = p->p_zombcnt;
1095         prassignset(&sp->pr_sigpend, &p->p_sig);
1096         sp->pr_brkbase = (uint32_t)(uintptr_t)p->p_brkbase;
1097         sp->pr_brksize = (uint32_t)p->p_brksize;
1098         sp->pr_stkbase = (uint32_t)(uintptr_t)prgetstackbase(p);
1099         sp->pr_stksize = (uint32_t)p->p_stksize;
1100         sp->pr_pid   = p->p_pid;
1101         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
1102             (p->p_flag & SZONETOP)) {
1103                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
1104                 /*
1105                  * Inside local zones, fake zsched's pid as parent pids for
1106                  * processes which reference processes outside of the zone.
1107                  */
1108                 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
1109         } else {
1110                 sp->pr_ppid = p->p_ppid;
1111         }
1112         sp->pr_pgid  = p->p_pgrp;
1113         sp->pr_sid   = p->p_sessp->s_sid;
1114         sp->pr_taskid = p->p_task->tk_tkid;
1115         sp->pr_projid = p->p_task->tk_proj->kpj_id;
1116         sp->pr_zoneid = p->p_zone->zone_id;
1117         hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
1118         hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
1119         TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime);
1120         TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime);
1121         prassignset(&sp->pr_sigtrace, &p->p_sigmask);
1122         prassignset(&sp->pr_flttrace, &p->p_fltmask);
1123         prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
1124         prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
1125         switch (p->p_model) {
1126         case DATAMODEL_ILP32:
1127                 sp->pr_dmodel = PR_MODEL_ILP32;
1128                 break;
1129         case DATAMODEL_LP64:
1130                 sp->pr_dmodel = PR_MODEL_LP64;
1131                 break;
1132         }
1133         if (p->p_agenttp)
1134                 sp->pr_agentid = p->p_agenttp->t_tid;
1135 
1136         /* get the chosen lwp's status */
1137         prgetlwpstatus32(t, &sp->pr_lwp, zp);
1138 
1139         /* replicate the flags */
1140         sp->pr_flags = sp->pr_lwp.pr_flags;
1141 }
1142 #endif  /* _SYSCALL32_IMPL */
1143 
1144 /*
1145  * Return lwp status.
1146  */
1147 void
1148 prgetlwpstatus(kthread_t *t, lwpstatus_t *sp, zone_t *zp)
1149 {
1150         proc_t *p = ttoproc(t);
1151         klwp_t *lwp = ttolwp(t);
1152         struct mstate *ms = &lwp->lwp_mstate;
1153         hrtime_t usr, sys;
1154         int flags;
1155         ulong_t instr;
1156 
1157         ASSERT(MUTEX_HELD(&p->p_lock));
1158 
1159         bzero(sp, sizeof (*sp));
1160         flags = 0L;
1161         if (t->t_state == TS_STOPPED) {
1162                 flags |= PR_STOPPED;
1163                 if ((t->t_schedflag & TS_PSTART) == 0)
1164                         flags |= PR_ISTOP;
1165         } else if (VSTOPPED(t)) {
1166                 flags |= PR_STOPPED|PR_ISTOP;
1167         }
1168         if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
1169                 flags |= PR_DSTOP;
1170         if (lwp->lwp_asleep)
1171                 flags |= PR_ASLEEP;
1172         if (t == p->p_agenttp)
1173                 flags |= PR_AGENT;
1174         if (!(t->t_proc_flag & TP_TWAIT))
1175                 flags |= PR_DETACH;
1176         if (t->t_proc_flag & TP_DAEMON)
1177                 flags |= PR_DAEMON;
1178         if (p->p_proc_flag & P_PR_FORK)
1179                 flags |= PR_FORK;
1180         if (p->p_proc_flag & P_PR_RUNLCL)
1181                 flags |= PR_RLC;
1182         if (p->p_proc_flag & P_PR_KILLCL)
1183                 flags |= PR_KLC;
1184         if (p->p_proc_flag & P_PR_ASYNC)
1185                 flags |= PR_ASYNC;
1186         if (p->p_proc_flag & P_PR_BPTADJ)
1187                 flags |= PR_BPTADJ;
1188         if (p->p_proc_flag & P_PR_PTRACE)
1189                 flags |= PR_PTRACE;
1190         if (p->p_flag & SMSACCT)
1191                 flags |= PR_MSACCT;
1192         if (p->p_flag & SMSFORK)
1193                 flags |= PR_MSFORK;
1194         if (p->p_flag & SVFWAIT)
1195                 flags |= PR_VFORKP;
1196         if (p->p_pgidp->pid_pgorphaned)
1197                 flags |= PR_ORPHAN;
1198         if (p->p_pidflag & CLDNOSIGCHLD)
1199                 flags |= PR_NOSIGCHLD;
1200         if (p->p_pidflag & CLDWAITPID)
1201                 flags |= PR_WAITPID;
1202         sp->pr_flags = flags;
1203         if (VSTOPPED(t)) {
1204                 sp->pr_why   = PR_REQUESTED;
1205                 sp->pr_what  = 0;
1206         } else {
1207                 sp->pr_why   = t->t_whystop;
1208                 sp->pr_what  = t->t_whatstop;
1209         }
1210         sp->pr_lwpid = t->t_tid;
1211         sp->pr_cursig  = lwp->lwp_cursig;
1212         prassignset(&sp->pr_lwppend, &t->t_sig);
1213         schedctl_finish_sigblock(t);
1214         prassignset(&sp->pr_lwphold, &t->t_hold);
1215         if (t->t_whystop == PR_FAULTED)
1216                 bcopy(&lwp->lwp_siginfo,
1217                     &sp->pr_info, sizeof (k_siginfo_t));
1218         else if (lwp->lwp_curinfo)
1219                 bcopy(&lwp->lwp_curinfo->sq_info,
1220                     &sp->pr_info, sizeof (k_siginfo_t));
1221         if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
1222             sp->pr_info.si_zoneid != zp->zone_id) {
1223                 sp->pr_info.si_pid = zp->zone_zsched->p_pid;
1224                 sp->pr_info.si_uid = 0;
1225                 sp->pr_info.si_ctid = -1;
1226                 sp->pr_info.si_zoneid = zp->zone_id;
1227         }
1228         sp->pr_altstack = lwp->lwp_sigaltstack;
1229         prgetaction(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1230         sp->pr_oldcontext = (uintptr_t)lwp->lwp_oldcontext;
1231         sp->pr_ustack = lwp->lwp_ustack;
1232         (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1233             sizeof (sp->pr_clname) - 1);
1234         if (flags & PR_STOPPED)
1235                 hrt2ts(t->t_stoptime, &sp->pr_tstamp);
1236         usr = ms->ms_acct[LMS_USER];
1237         sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1238         scalehrtime(&usr);
1239         scalehrtime(&sys);
1240         hrt2ts(usr, &sp->pr_utime);
1241         hrt2ts(sys, &sp->pr_stime);
1242 
1243         /*
1244          * Fetch the current instruction, if not a system process.
1245          * We don't attempt this unless the lwp is stopped.
1246          */
1247         if ((p->p_flag & SSYS) || p->p_as == &kas)
1248                 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1249         else if (!(flags & PR_STOPPED))
1250                 sp->pr_flags |= PR_PCINVAL;
1251         else if (!prfetchinstr(lwp, &instr))
1252                 sp->pr_flags |= PR_PCINVAL;
1253         else
1254                 sp->pr_instr = instr;
1255 
1256         /*
1257          * Drop p_lock while touching the lwp's stack.
1258          */
1259         mutex_exit(&p->p_lock);
1260         if (prisstep(lwp))
1261                 sp->pr_flags |= PR_STEP;
1262         if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1263                 int i;
1264 
1265                 sp->pr_syscall = get_syscall_args(lwp,
1266                     (long *)sp->pr_sysarg, &i);
1267                 sp->pr_nsysarg = (ushort_t)i;
1268         }
1269         if ((flags & PR_STOPPED) || t == curthread)
1270                 prgetprregs(lwp, sp->pr_reg);
1271         if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1272             (flags & PR_VFORKP)) {
1273                 user_t *up;
1274                 auxv_t *auxp;
1275                 int i;
1276 
1277                 sp->pr_errno = prgetrvals(lwp, &sp->pr_rval1, &sp->pr_rval2);
1278                 if (sp->pr_errno == 0)
1279                         sp->pr_errpriv = PRIV_NONE;
1280                 else
1281                         sp->pr_errpriv = lwp->lwp_badpriv;
1282 
1283                 if (t->t_sysnum == SYS_execve) {
1284                         up = PTOU(p);
1285                         sp->pr_sysarg[0] = 0;
1286                         sp->pr_sysarg[1] = (uintptr_t)up->u_argv;
1287                         sp->pr_sysarg[2] = (uintptr_t)up->u_envp;
1288                         for (i = 0, auxp = up->u_auxv;
1289                             i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1290                             i++, auxp++) {
1291                                 if (auxp->a_type == AT_SUN_EXECNAME) {
1292                                         sp->pr_sysarg[0] =
1293                                             (uintptr_t)auxp->a_un.a_ptr;
1294                                         break;
1295                                 }
1296                         }
1297                 }
1298         }
1299         if (prhasfp())
1300                 prgetprfpregs(lwp, &sp->pr_fpreg);
1301         mutex_enter(&p->p_lock);
1302 }
1303 
1304 /*
1305  * Get the sigaction structure for the specified signal.  The u-block
1306  * must already have been mapped in by the caller.
1307  */
1308 void
1309 prgetaction(proc_t *p, user_t *up, uint_t sig, struct sigaction *sp)
1310 {
1311         int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1312 
1313         bzero(sp, sizeof (*sp));
1314 
1315         if (sig != 0 && (unsigned)sig < nsig) {
1316                 sp->sa_handler = up->u_signal[sig-1];
1317                 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1318                 if (sigismember(&up->u_sigonstack, sig))
1319                         sp->sa_flags |= SA_ONSTACK;
1320                 if (sigismember(&up->u_sigresethand, sig))
1321                         sp->sa_flags |= SA_RESETHAND;
1322                 if (sigismember(&up->u_sigrestart, sig))
1323                         sp->sa_flags |= SA_RESTART;
1324                 if (sigismember(&p->p_siginfo, sig))
1325                         sp->sa_flags |= SA_SIGINFO;
1326                 if (sigismember(&up->u_signodefer, sig))
1327                         sp->sa_flags |= SA_NODEFER;
1328                 if (sig == SIGCLD) {
1329                         if (p->p_flag & SNOWAIT)
1330                                 sp->sa_flags |= SA_NOCLDWAIT;
1331                         if ((p->p_flag & SJCTL) == 0)
1332                                 sp->sa_flags |= SA_NOCLDSTOP;
1333                 }
1334         }
1335 }
1336 
1337 #ifdef _SYSCALL32_IMPL
1338 void
1339 prgetaction32(proc_t *p, user_t *up, uint_t sig, struct sigaction32 *sp)
1340 {
1341         int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1342 
1343         bzero(sp, sizeof (*sp));
1344 
1345         if (sig != 0 && (unsigned)sig < nsig) {
1346                 sp->sa_handler = (caddr32_t)(uintptr_t)up->u_signal[sig-1];
1347                 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1348                 if (sigismember(&up->u_sigonstack, sig))
1349                         sp->sa_flags |= SA_ONSTACK;
1350                 if (sigismember(&up->u_sigresethand, sig))
1351                         sp->sa_flags |= SA_RESETHAND;
1352                 if (sigismember(&up->u_sigrestart, sig))
1353                         sp->sa_flags |= SA_RESTART;
1354                 if (sigismember(&p->p_siginfo, sig))
1355                         sp->sa_flags |= SA_SIGINFO;
1356                 if (sigismember(&up->u_signodefer, sig))
1357                         sp->sa_flags |= SA_NODEFER;
1358                 if (sig == SIGCLD) {
1359                         if (p->p_flag & SNOWAIT)
1360                                 sp->sa_flags |= SA_NOCLDWAIT;
1361                         if ((p->p_flag & SJCTL) == 0)
1362                                 sp->sa_flags |= SA_NOCLDSTOP;
1363                 }
1364         }
1365 }
1366 #endif  /* _SYSCALL32_IMPL */
1367 
1368 /*
1369  * Count the number of segments in this process's address space.
1370  */
1371 int
1372 prnsegs(struct as *as, int reserved)
1373 {
1374         int n = 0;
1375         struct seg *seg;
1376 
1377         ASSERT(as != &kas && AS_WRITE_HELD(as));
1378 
1379         for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
1380                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1381                 caddr_t saddr, naddr;
1382                 void *tmp = NULL;
1383 
1384                 if ((seg->s_flags & S_HOLE) != 0) {
1385                         continue;
1386                 }
1387 
1388                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1389                         (void) pr_getprot(seg, reserved, &tmp,
1390                             &saddr, &naddr, eaddr);
1391                         if (saddr != naddr)
1392                                 n++;
1393                 }
1394 
1395                 ASSERT(tmp == NULL);
1396         }
1397 
1398         return (n);
1399 }
1400 
1401 /*
1402  * Convert uint32_t to decimal string w/o leading zeros.
1403  * Add trailing null characters if 'len' is greater than string length.
1404  * Return the string length.
1405  */
1406 int
1407 pr_u32tos(uint32_t n, char *s, int len)
1408 {
1409         char cbuf[11];          /* 32-bit unsigned integer fits in 10 digits */
1410         char *cp = cbuf;
1411         char *end = s + len;
1412 
1413         do {
1414                 *cp++ = (char)(n % 10 + '0');
1415                 n /= 10;
1416         } while (n);
1417 
1418         len = (int)(cp - cbuf);
1419 
1420         do {
1421                 *s++ = *--cp;
1422         } while (cp > cbuf);
1423 
1424         while (s < end)              /* optional pad */
1425                 *s++ = '\0';
1426 
1427         return (len);
1428 }
1429 
1430 /*
1431  * Convert uint64_t to decimal string w/o leading zeros.
1432  * Return the string length.
1433  */
1434 static int
1435 pr_u64tos(uint64_t n, char *s)
1436 {
1437         char cbuf[21];          /* 64-bit unsigned integer fits in 20 digits */
1438         char *cp = cbuf;
1439         int len;
1440 
1441         do {
1442                 *cp++ = (char)(n % 10 + '0');
1443                 n /= 10;
1444         } while (n);
1445 
1446         len = (int)(cp - cbuf);
1447 
1448         do {
1449                 *s++ = *--cp;
1450         } while (cp > cbuf);
1451 
1452         return (len);
1453 }
1454 
1455 void
1456 pr_object_name(char *name, vnode_t *vp, struct vattr *vattr)
1457 {
1458         char *s = name;
1459         struct vfs *vfsp;
1460         struct vfssw *vfsswp;
1461 
1462         if ((vfsp = vp->v_vfsp) != NULL &&
1463             ((vfsswp = vfssw + vfsp->vfs_fstype), vfsswp->vsw_name) &&
1464             *vfsswp->vsw_name) {
1465                 (void) strcpy(s, vfsswp->vsw_name);
1466                 s += strlen(s);
1467                 *s++ = '.';
1468         }
1469         s += pr_u32tos(getmajor(vattr->va_fsid), s, 0);
1470         *s++ = '.';
1471         s += pr_u32tos(getminor(vattr->va_fsid), s, 0);
1472         *s++ = '.';
1473         s += pr_u64tos(vattr->va_nodeid, s);
1474         *s++ = '\0';
1475 }
1476 
1477 struct seg *
1478 break_seg(proc_t *p)
1479 {
1480         caddr_t addr = p->p_brkbase;
1481         struct seg *seg;
1482         struct vnode *vp;
1483 
1484         if (p->p_brksize != 0)
1485                 addr += p->p_brksize - 1;
1486         seg = as_segat(p->p_as, addr);
1487         if (seg != NULL && seg->s_ops == &segvn_ops &&
1488             (SEGOP_GETVP(seg, seg->s_base, &vp) != 0 || vp == NULL))
1489                 return (seg);
1490         return (NULL);
1491 }
1492 
1493 /*
1494  * Implementation of service functions to handle procfs generic chained
1495  * copyout buffers.
1496  */
1497 typedef struct pr_iobuf_list {
1498         list_node_t     piol_link;      /* buffer linkage */
1499         size_t          piol_size;      /* total size (header + data) */
1500         size_t          piol_usedsize;  /* amount to copy out from this buf */
1501 } piol_t;
1502 
1503 #define MAPSIZE (64 * 1024)
1504 #define PIOL_DATABUF(iol)       ((void *)(&(iol)[1]))
1505 
1506 void
1507 pr_iol_initlist(list_t *iolhead, size_t itemsize, int n)
1508 {
1509         piol_t  *iol;
1510         size_t  initial_size = MIN(1, n) * itemsize;
1511 
1512         list_create(iolhead, sizeof (piol_t), offsetof(piol_t, piol_link));
1513 
1514         ASSERT(list_head(iolhead) == NULL);
1515         ASSERT(itemsize < MAPSIZE - sizeof (*iol));
1516         ASSERT(initial_size > 0);
1517 
1518         /*
1519          * Someone creating chained copyout buffers may ask for less than
1520          * MAPSIZE if the amount of data to be buffered is known to be
1521          * smaller than that.
1522          * But in order to prevent involuntary self-denial of service,
1523          * the requested input size is clamped at MAPSIZE.
1524          */
1525         initial_size = MIN(MAPSIZE, initial_size + sizeof (*iol));
1526         iol = kmem_alloc(initial_size, KM_SLEEP);
1527         list_insert_head(iolhead, iol);
1528         iol->piol_usedsize = 0;
1529         iol->piol_size = initial_size;
1530 }
1531 
1532 void *
1533 pr_iol_newbuf(list_t *iolhead, size_t itemsize)
1534 {
1535         piol_t  *iol;
1536         char    *new;
1537 
1538         ASSERT(itemsize < MAPSIZE - sizeof (*iol));
1539         ASSERT(list_head(iolhead) != NULL);
1540 
1541         iol = (piol_t *)list_tail(iolhead);
1542 
1543         if (iol->piol_size <
1544             iol->piol_usedsize + sizeof (*iol) + itemsize) {
1545                 /*
1546                  * Out of space in the current buffer. Allocate more.
1547                  */
1548                 piol_t *newiol;
1549 
1550                 newiol = kmem_alloc(MAPSIZE, KM_SLEEP);
1551                 newiol->piol_size = MAPSIZE;
1552                 newiol->piol_usedsize = 0;
1553 
1554                 list_insert_after(iolhead, iol, newiol);
1555                 iol = list_next(iolhead, iol);
1556                 ASSERT(iol == newiol);
1557         }
1558         new = (char *)PIOL_DATABUF(iol) + iol->piol_usedsize;
1559         iol->piol_usedsize += itemsize;
1560         bzero(new, itemsize);
1561         return (new);
1562 }
1563 
1564 int
1565 pr_iol_copyout_and_free(list_t *iolhead, caddr_t *tgt, int errin)
1566 {
1567         int error = errin;
1568         piol_t  *iol;
1569 
1570         while ((iol = list_head(iolhead)) != NULL) {
1571                 list_remove(iolhead, iol);
1572                 if (!error) {
1573                         if (copyout(PIOL_DATABUF(iol), *tgt,
1574                             iol->piol_usedsize))
1575                                 error = EFAULT;
1576                         *tgt += iol->piol_usedsize;
1577                 }
1578                 kmem_free(iol, iol->piol_size);
1579         }
1580         list_destroy(iolhead);
1581 
1582         return (error);
1583 }
1584 
1585 int
1586 pr_iol_uiomove_and_free(list_t *iolhead, uio_t *uiop, int errin)
1587 {
1588         offset_t        off = uiop->uio_offset;
1589         char            *base;
1590         size_t          size;
1591         piol_t          *iol;
1592         int             error = errin;
1593 
1594         while ((iol = list_head(iolhead)) != NULL) {
1595                 list_remove(iolhead, iol);
1596                 base = PIOL_DATABUF(iol);
1597                 size = iol->piol_usedsize;
1598                 if (off <= size && error == 0 && uiop->uio_resid > 0)
1599                         error = uiomove(base + off, size - off,
1600                             UIO_READ, uiop);
1601                 off = MAX(0, off - (offset_t)size);
1602                 kmem_free(iol, iol->piol_size);
1603         }
1604         list_destroy(iolhead);
1605 
1606         return (error);
1607 }
1608 
1609 /*
1610  * Return an array of structures with memory map information.
1611  * We allocate here; the caller must deallocate.
1612  */
1613 int
1614 prgetmap(proc_t *p, int reserved, list_t *iolhead)
1615 {
1616         struct as *as = p->p_as;
1617         prmap_t *mp;
1618         struct seg *seg;
1619         struct seg *brkseg, *stkseg;
1620         struct vnode *vp;
1621         struct vattr vattr;
1622         uint_t prot;
1623 
1624         ASSERT(as != &kas && AS_WRITE_HELD(as));
1625 
1626         /*
1627          * Request an initial buffer size that doesn't waste memory
1628          * if the address space has only a small number of segments.
1629          */
1630         pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
1631 
1632         if ((seg = AS_SEGFIRST(as)) == NULL)
1633                 return (0);
1634 
1635         brkseg = break_seg(p);
1636         stkseg = as_segat(as, prgetstackbase(p));
1637 
1638         do {
1639                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1640                 caddr_t saddr, naddr;
1641                 void *tmp = NULL;
1642 
1643                 if ((seg->s_flags & S_HOLE) != 0) {
1644                         continue;
1645                 }
1646 
1647                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1648                         prot = pr_getprot(seg, reserved, &tmp,
1649                             &saddr, &naddr, eaddr);
1650                         if (saddr == naddr)
1651                                 continue;
1652 
1653                         mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1654 
1655                         mp->pr_vaddr = (uintptr_t)saddr;
1656                         mp->pr_size = naddr - saddr;
1657                         mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1658                         mp->pr_mflags = 0;
1659                         if (prot & PROT_READ)
1660                                 mp->pr_mflags |= MA_READ;
1661                         if (prot & PROT_WRITE)
1662                                 mp->pr_mflags |= MA_WRITE;
1663                         if (prot & PROT_EXEC)
1664                                 mp->pr_mflags |= MA_EXEC;
1665                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1666                                 mp->pr_mflags |= MA_SHARED;
1667                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1668                                 mp->pr_mflags |= MA_NORESERVE;
1669                         if (seg->s_ops == &segspt_shmops ||
1670                             (seg->s_ops == &segvn_ops &&
1671                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1672                                 mp->pr_mflags |= MA_ANON;
1673                         if (seg == brkseg)
1674                                 mp->pr_mflags |= MA_BREAK;
1675                         else if (seg == stkseg) {
1676                                 mp->pr_mflags |= MA_STACK;
1677                                 if (reserved) {
1678                                         size_t maxstack =
1679                                             ((size_t)p->p_stk_ctl +
1680                                             PAGEOFFSET) & PAGEMASK;
1681                                         mp->pr_vaddr =
1682                                             (uintptr_t)prgetstackbase(p) +
1683                                             p->p_stksize - maxstack;
1684                                         mp->pr_size = (uintptr_t)naddr -
1685                                             mp->pr_vaddr;
1686                                 }
1687                         }
1688                         if (seg->s_ops == &segspt_shmops)
1689                                 mp->pr_mflags |= MA_ISM | MA_SHM;
1690                         mp->pr_pagesize = PAGESIZE;
1691 
1692                         /*
1693                          * Manufacture a filename for the "object" directory.
1694                          */
1695                         vattr.va_mask = AT_FSID|AT_NODEID;
1696                         if (seg->s_ops == &segvn_ops &&
1697                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1698                             vp != NULL && vp->v_type == VREG &&
1699                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1700                                 if (vp == p->p_exec)
1701                                         (void) strcpy(mp->pr_mapname, "a.out");
1702                                 else
1703                                         pr_object_name(mp->pr_mapname,
1704                                             vp, &vattr);
1705                         }
1706 
1707                         /*
1708                          * Get the SysV shared memory id, if any.
1709                          */
1710                         if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1711                             (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1712                             SHMID_NONE) {
1713                                 if (mp->pr_shmid == SHMID_FREE)
1714                                         mp->pr_shmid = -1;
1715 
1716                                 mp->pr_mflags |= MA_SHM;
1717                         } else {
1718                                 mp->pr_shmid = -1;
1719                         }
1720                 }
1721                 ASSERT(tmp == NULL);
1722         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1723 
1724         return (0);
1725 }
1726 
1727 #ifdef _SYSCALL32_IMPL
1728 int
1729 prgetmap32(proc_t *p, int reserved, list_t *iolhead)
1730 {
1731         struct as *as = p->p_as;
1732         prmap32_t *mp;
1733         struct seg *seg;
1734         struct seg *brkseg, *stkseg;
1735         struct vnode *vp;
1736         struct vattr vattr;
1737         uint_t prot;
1738 
1739         ASSERT(as != &kas && AS_WRITE_HELD(as));
1740 
1741         /*
1742          * Request an initial buffer size that doesn't waste memory
1743          * if the address space has only a small number of segments.
1744          */
1745         pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
1746 
1747         if ((seg = AS_SEGFIRST(as)) == NULL)
1748                 return (0);
1749 
1750         brkseg = break_seg(p);
1751         stkseg = as_segat(as, prgetstackbase(p));
1752 
1753         do {
1754                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1755                 caddr_t saddr, naddr;
1756                 void *tmp = NULL;
1757 
1758                 if ((seg->s_flags & S_HOLE) != 0) {
1759                         continue;
1760                 }
1761 
1762                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1763                         prot = pr_getprot(seg, reserved, &tmp,
1764                             &saddr, &naddr, eaddr);
1765                         if (saddr == naddr)
1766                                 continue;
1767 
1768                         mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1769 
1770                         mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
1771                         mp->pr_size = (size32_t)(naddr - saddr);
1772                         mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1773                         mp->pr_mflags = 0;
1774                         if (prot & PROT_READ)
1775                                 mp->pr_mflags |= MA_READ;
1776                         if (prot & PROT_WRITE)
1777                                 mp->pr_mflags |= MA_WRITE;
1778                         if (prot & PROT_EXEC)
1779                                 mp->pr_mflags |= MA_EXEC;
1780                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1781                                 mp->pr_mflags |= MA_SHARED;
1782                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1783                                 mp->pr_mflags |= MA_NORESERVE;
1784                         if (seg->s_ops == &segspt_shmops ||
1785                             (seg->s_ops == &segvn_ops &&
1786                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1787                                 mp->pr_mflags |= MA_ANON;
1788                         if (seg == brkseg)
1789                                 mp->pr_mflags |= MA_BREAK;
1790                         else if (seg == stkseg) {
1791                                 mp->pr_mflags |= MA_STACK;
1792                                 if (reserved) {
1793                                         size_t maxstack =
1794                                             ((size_t)p->p_stk_ctl +
1795                                             PAGEOFFSET) & PAGEMASK;
1796                                         uintptr_t vaddr =
1797                                             (uintptr_t)prgetstackbase(p) +
1798                                             p->p_stksize - maxstack;
1799                                         mp->pr_vaddr = (caddr32_t)vaddr;
1800                                         mp->pr_size = (size32_t)
1801                                             ((uintptr_t)naddr - vaddr);
1802                                 }
1803                         }
1804                         if (seg->s_ops == &segspt_shmops)
1805                                 mp->pr_mflags |= MA_ISM | MA_SHM;
1806                         mp->pr_pagesize = PAGESIZE;
1807 
1808                         /*
1809                          * Manufacture a filename for the "object" directory.
1810                          */
1811                         vattr.va_mask = AT_FSID|AT_NODEID;
1812                         if (seg->s_ops == &segvn_ops &&
1813                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1814                             vp != NULL && vp->v_type == VREG &&
1815                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1816                                 if (vp == p->p_exec)
1817                                         (void) strcpy(mp->pr_mapname, "a.out");
1818                                 else
1819                                         pr_object_name(mp->pr_mapname,
1820                                             vp, &vattr);
1821                         }
1822 
1823                         /*
1824                          * Get the SysV shared memory id, if any.
1825                          */
1826                         if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1827                             (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1828                             SHMID_NONE) {
1829                                 if (mp->pr_shmid == SHMID_FREE)
1830                                         mp->pr_shmid = -1;
1831 
1832                                 mp->pr_mflags |= MA_SHM;
1833                         } else {
1834                                 mp->pr_shmid = -1;
1835                         }
1836                 }
1837                 ASSERT(tmp == NULL);
1838         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1839 
1840         return (0);
1841 }
1842 #endif  /* _SYSCALL32_IMPL */
1843 
1844 /*
1845  * Return the size of the /proc page data file.
1846  */
1847 size_t
1848 prpdsize(struct as *as)
1849 {
1850         struct seg *seg;
1851         size_t size;
1852 
1853         ASSERT(as != &kas && AS_WRITE_HELD(as));
1854 
1855         if ((seg = AS_SEGFIRST(as)) == NULL)
1856                 return (0);
1857 
1858         size = sizeof (prpageheader_t);
1859         do {
1860                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1861                 caddr_t saddr, naddr;
1862                 void *tmp = NULL;
1863                 size_t npage;
1864 
1865                 if ((seg->s_flags & S_HOLE) != 0) {
1866                         continue;
1867                 }
1868 
1869                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1870                         (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1871                         if ((npage = (naddr - saddr) / PAGESIZE) != 0)
1872                                 size += sizeof (prasmap_t) + round8(npage);
1873                 }
1874                 ASSERT(tmp == NULL);
1875         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1876 
1877         return (size);
1878 }
1879 
1880 #ifdef _SYSCALL32_IMPL
1881 size_t
1882 prpdsize32(struct as *as)
1883 {
1884         struct seg *seg;
1885         size_t size;
1886 
1887         ASSERT(as != &kas && AS_WRITE_HELD(as));
1888 
1889         if ((seg = AS_SEGFIRST(as)) == NULL)
1890                 return (0);
1891 
1892         size = sizeof (prpageheader32_t);
1893         do {
1894                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1895                 caddr_t saddr, naddr;
1896                 void *tmp = NULL;
1897                 size_t npage;
1898 
1899                 if ((seg->s_flags & S_HOLE) != 0) {
1900                         continue;
1901                 }
1902 
1903                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1904                         (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1905                         if ((npage = (naddr - saddr) / PAGESIZE) != 0)
1906                                 size += sizeof (prasmap32_t) + round8(npage);
1907                 }
1908                 ASSERT(tmp == NULL);
1909         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1910 
1911         return (size);
1912 }
1913 #endif  /* _SYSCALL32_IMPL */
1914 
1915 /*
1916  * Read page data information.
1917  */
1918 int
1919 prpdread(proc_t *p, uint_t hatid, struct uio *uiop)
1920 {
1921         struct as *as = p->p_as;
1922         caddr_t buf;
1923         size_t size;
1924         prpageheader_t *php;
1925         prasmap_t *pmp;
1926         struct seg *seg;
1927         int error;
1928 
1929 again:
1930         AS_LOCK_ENTER(as, RW_WRITER);
1931 
1932         if ((seg = AS_SEGFIRST(as)) == NULL) {
1933                 AS_LOCK_EXIT(as);
1934                 return (0);
1935         }
1936         size = prpdsize(as);
1937         if (uiop->uio_resid < size) {
1938                 AS_LOCK_EXIT(as);
1939                 return (E2BIG);
1940         }
1941 
1942         buf = kmem_zalloc(size, KM_SLEEP);
1943         php = (prpageheader_t *)buf;
1944         pmp = (prasmap_t *)(buf + sizeof (prpageheader_t));
1945 
1946         hrt2ts(gethrtime(), &php->pr_tstamp);
1947         php->pr_nmap = 0;
1948         php->pr_npage = 0;
1949         do {
1950                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1951                 caddr_t saddr, naddr;
1952                 void *tmp = NULL;
1953 
1954                 if ((seg->s_flags & S_HOLE) != 0) {
1955                         continue;
1956                 }
1957 
1958                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1959                         struct vnode *vp;
1960                         struct vattr vattr;
1961                         size_t len;
1962                         size_t npage;
1963                         uint_t prot;
1964                         uintptr_t next;
1965 
1966                         prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1967                         if ((len = (size_t)(naddr - saddr)) == 0)
1968                                 continue;
1969                         npage = len / PAGESIZE;
1970                         next = (uintptr_t)(pmp + 1) + round8(npage);
1971                         /*
1972                          * It's possible that the address space can change
1973                          * subtlely even though we're holding as->a_lock
1974                          * due to the nondeterminism of page_exists() in
1975                          * the presence of asychronously flushed pages or
1976                          * mapped files whose sizes are changing.
1977                          * page_exists() may be called indirectly from
1978                          * pr_getprot() by a SEGOP_INCORE() routine.
1979                          * If this happens we need to make sure we don't
1980                          * overrun the buffer whose size we computed based
1981                          * on the initial iteration through the segments.
1982                          * Once we've detected an overflow, we need to clean
1983                          * up the temporary memory allocated in pr_getprot()
1984                          * and retry. If there's a pending signal, we return
1985                          * EINTR so that this thread can be dislodged if
1986                          * a latent bug causes us to spin indefinitely.
1987                          */
1988                         if (next > (uintptr_t)buf + size) {
1989                                 pr_getprot_done(&tmp);
1990                                 AS_LOCK_EXIT(as);
1991 
1992                                 kmem_free(buf, size);
1993 
1994                                 if (ISSIG(curthread, JUSTLOOKING))
1995                                         return (EINTR);
1996 
1997                                 goto again;
1998                         }
1999 
2000                         php->pr_nmap++;
2001                         php->pr_npage += npage;
2002                         pmp->pr_vaddr = (uintptr_t)saddr;
2003                         pmp->pr_npage = npage;
2004                         pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
2005                         pmp->pr_mflags = 0;
2006                         if (prot & PROT_READ)
2007                                 pmp->pr_mflags |= MA_READ;
2008                         if (prot & PROT_WRITE)
2009                                 pmp->pr_mflags |= MA_WRITE;
2010                         if (prot & PROT_EXEC)
2011                                 pmp->pr_mflags |= MA_EXEC;
2012                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
2013                                 pmp->pr_mflags |= MA_SHARED;
2014                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
2015                                 pmp->pr_mflags |= MA_NORESERVE;
2016                         if (seg->s_ops == &segspt_shmops ||
2017                             (seg->s_ops == &segvn_ops &&
2018                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
2019                                 pmp->pr_mflags |= MA_ANON;
2020                         if (seg->s_ops == &segspt_shmops)
2021                                 pmp->pr_mflags |= MA_ISM | MA_SHM;
2022                         pmp->pr_pagesize = PAGESIZE;
2023                         /*
2024                          * Manufacture a filename for the "object" directory.
2025                          */
2026                         vattr.va_mask = AT_FSID|AT_NODEID;
2027                         if (seg->s_ops == &segvn_ops &&
2028                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2029                             vp != NULL && vp->v_type == VREG &&
2030                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2031                                 if (vp == p->p_exec)
2032                                         (void) strcpy(pmp->pr_mapname, "a.out");
2033                                 else
2034                                         pr_object_name(pmp->pr_mapname,
2035                                             vp, &vattr);
2036                         }
2037 
2038                         /*
2039                          * Get the SysV shared memory id, if any.
2040                          */
2041                         if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2042                             (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2043                             SHMID_NONE) {
2044                                 if (pmp->pr_shmid == SHMID_FREE)
2045                                         pmp->pr_shmid = -1;
2046 
2047                                 pmp->pr_mflags |= MA_SHM;
2048                         } else {
2049                                 pmp->pr_shmid = -1;
2050                         }
2051 
2052                         hat_getstat(as, saddr, len, hatid,
2053                             (char *)(pmp + 1), HAT_SYNC_ZERORM);
2054                         pmp = (prasmap_t *)next;
2055                 }
2056                 ASSERT(tmp == NULL);
2057         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2058 
2059         AS_LOCK_EXIT(as);
2060 
2061         ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2062         error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2063         kmem_free(buf, size);
2064 
2065         return (error);
2066 }
2067 
2068 #ifdef _SYSCALL32_IMPL
2069 int
2070 prpdread32(proc_t *p, uint_t hatid, struct uio *uiop)
2071 {
2072         struct as *as = p->p_as;
2073         caddr_t buf;
2074         size_t size;
2075         prpageheader32_t *php;
2076         prasmap32_t *pmp;
2077         struct seg *seg;
2078         int error;
2079 
2080 again:
2081         AS_LOCK_ENTER(as, RW_WRITER);
2082 
2083         if ((seg = AS_SEGFIRST(as)) == NULL) {
2084                 AS_LOCK_EXIT(as);
2085                 return (0);
2086         }
2087         size = prpdsize32(as);
2088         if (uiop->uio_resid < size) {
2089                 AS_LOCK_EXIT(as);
2090                 return (E2BIG);
2091         }
2092 
2093         buf = kmem_zalloc(size, KM_SLEEP);
2094         php = (prpageheader32_t *)buf;
2095         pmp = (prasmap32_t *)(buf + sizeof (prpageheader32_t));
2096 
2097         hrt2ts32(gethrtime(), &php->pr_tstamp);
2098         php->pr_nmap = 0;
2099         php->pr_npage = 0;
2100         do {
2101                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
2102                 caddr_t saddr, naddr;
2103                 void *tmp = NULL;
2104 
2105                 if ((seg->s_flags & S_HOLE) != 0) {
2106                         continue;
2107                 }
2108 
2109                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
2110                         struct vnode *vp;
2111                         struct vattr vattr;
2112                         size_t len;
2113                         size_t npage;
2114                         uint_t prot;
2115                         uintptr_t next;
2116 
2117                         prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
2118                         if ((len = (size_t)(naddr - saddr)) == 0)
2119                                 continue;
2120                         npage = len / PAGESIZE;
2121                         next = (uintptr_t)(pmp + 1) + round8(npage);
2122                         /*
2123                          * It's possible that the address space can change
2124                          * subtlely even though we're holding as->a_lock
2125                          * due to the nondeterminism of page_exists() in
2126                          * the presence of asychronously flushed pages or
2127                          * mapped files whose sizes are changing.
2128                          * page_exists() may be called indirectly from
2129                          * pr_getprot() by a SEGOP_INCORE() routine.
2130                          * If this happens we need to make sure we don't
2131                          * overrun the buffer whose size we computed based
2132                          * on the initial iteration through the segments.
2133                          * Once we've detected an overflow, we need to clean
2134                          * up the temporary memory allocated in pr_getprot()
2135                          * and retry. If there's a pending signal, we return
2136                          * EINTR so that this thread can be dislodged if
2137                          * a latent bug causes us to spin indefinitely.
2138                          */
2139                         if (next > (uintptr_t)buf + size) {
2140                                 pr_getprot_done(&tmp);
2141                                 AS_LOCK_EXIT(as);
2142 
2143                                 kmem_free(buf, size);
2144 
2145                                 if (ISSIG(curthread, JUSTLOOKING))
2146                                         return (EINTR);
2147 
2148                                 goto again;
2149                         }
2150 
2151                         php->pr_nmap++;
2152                         php->pr_npage += npage;
2153                         pmp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
2154                         pmp->pr_npage = (size32_t)npage;
2155                         pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
2156                         pmp->pr_mflags = 0;
2157                         if (prot & PROT_READ)
2158                                 pmp->pr_mflags |= MA_READ;
2159                         if (prot & PROT_WRITE)
2160                                 pmp->pr_mflags |= MA_WRITE;
2161                         if (prot & PROT_EXEC)
2162                                 pmp->pr_mflags |= MA_EXEC;
2163                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
2164                                 pmp->pr_mflags |= MA_SHARED;
2165                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
2166                                 pmp->pr_mflags |= MA_NORESERVE;
2167                         if (seg->s_ops == &segspt_shmops ||
2168                             (seg->s_ops == &segvn_ops &&
2169                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
2170                                 pmp->pr_mflags |= MA_ANON;
2171                         if (seg->s_ops == &segspt_shmops)
2172                                 pmp->pr_mflags |= MA_ISM | MA_SHM;
2173                         pmp->pr_pagesize = PAGESIZE;
2174                         /*
2175                          * Manufacture a filename for the "object" directory.
2176                          */
2177                         vattr.va_mask = AT_FSID|AT_NODEID;
2178                         if (seg->s_ops == &segvn_ops &&
2179                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2180                             vp != NULL && vp->v_type == VREG &&
2181                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2182                                 if (vp == p->p_exec)
2183                                         (void) strcpy(pmp->pr_mapname, "a.out");
2184                                 else
2185                                         pr_object_name(pmp->pr_mapname,
2186                                             vp, &vattr);
2187                         }
2188 
2189                         /*
2190                          * Get the SysV shared memory id, if any.
2191                          */
2192                         if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2193                             (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2194                             SHMID_NONE) {
2195                                 if (pmp->pr_shmid == SHMID_FREE)
2196                                         pmp->pr_shmid = -1;
2197 
2198                                 pmp->pr_mflags |= MA_SHM;
2199                         } else {
2200                                 pmp->pr_shmid = -1;
2201                         }
2202 
2203                         hat_getstat(as, saddr, len, hatid,
2204                             (char *)(pmp + 1), HAT_SYNC_ZERORM);
2205                         pmp = (prasmap32_t *)next;
2206                 }
2207                 ASSERT(tmp == NULL);
2208         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2209 
2210         AS_LOCK_EXIT(as);
2211 
2212         ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2213         error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2214         kmem_free(buf, size);
2215 
2216         return (error);
2217 }
2218 #endif  /* _SYSCALL32_IMPL */
2219 
2220 ushort_t
2221 prgetpctcpu(uint64_t pct)
2222 {
2223         /*
2224          * The value returned will be relevant in the zone of the examiner,
2225          * which may not be the same as the zone which performed the procfs
2226          * mount.
2227          */
2228         int nonline = zone_ncpus_online_get(curproc->p_zone);
2229 
2230         /*
2231          * Prorate over online cpus so we don't exceed 100%
2232          */
2233         if (nonline > 1)
2234                 pct /= nonline;
2235         pct >>= 16;               /* convert to 16-bit scaled integer */
2236         if (pct > 0x8000)    /* might happen, due to rounding */
2237                 pct = 0x8000;
2238         return ((ushort_t)pct);
2239 }
2240 
2241 /*
2242  * Return information used by ps(1).
2243  */
2244 void
2245 prgetpsinfo(proc_t *p, psinfo_t *psp)
2246 {
2247         kthread_t *t;
2248         struct cred *cred;
2249         hrtime_t hrutime, hrstime;
2250 
2251         ASSERT(MUTEX_HELD(&p->p_lock));
2252 
2253         if ((t = prchoose(p)) == NULL)  /* returns locked thread */
2254                 bzero(psp, sizeof (*psp));
2255         else {
2256                 thread_unlock(t);
2257                 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2258         }
2259 
2260         /*
2261          * only export SSYS and SMSACCT; everything else is off-limits to
2262          * userland apps.
2263          */
2264         psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2265         psp->pr_nlwp = p->p_lwpcnt;
2266         psp->pr_nzomb = p->p_zombcnt;
2267         mutex_enter(&p->p_crlock);
2268         cred = p->p_cred;
2269         psp->pr_uid = crgetruid(cred);
2270         psp->pr_euid = crgetuid(cred);
2271         psp->pr_gid = crgetrgid(cred);
2272         psp->pr_egid = crgetgid(cred);
2273         mutex_exit(&p->p_crlock);
2274         psp->pr_pid = p->p_pid;
2275         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
2276             (p->p_flag & SZONETOP)) {
2277                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
2278                 /*
2279                  * Inside local zones, fake zsched's pid as parent pids for
2280                  * processes which reference processes outside of the zone.
2281                  */
2282                 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
2283         } else {
2284                 psp->pr_ppid = p->p_ppid;
2285         }
2286         psp->pr_pgid = p->p_pgrp;
2287         psp->pr_sid = p->p_sessp->s_sid;
2288         psp->pr_taskid = p->p_task->tk_tkid;
2289         psp->pr_projid = p->p_task->tk_proj->kpj_id;
2290         psp->pr_poolid = p->p_pool->pool_id;
2291         psp->pr_zoneid = p->p_zone->zone_id;
2292         if ((psp->pr_contract = PRCTID(p)) == 0)
2293                 psp->pr_contract = -1;
2294         psp->pr_addr = (uintptr_t)prgetpsaddr(p);
2295         switch (p->p_model) {
2296         case DATAMODEL_ILP32:
2297                 psp->pr_dmodel = PR_MODEL_ILP32;
2298                 break;
2299         case DATAMODEL_LP64:
2300                 psp->pr_dmodel = PR_MODEL_LP64;
2301                 break;
2302         }
2303         hrutime = mstate_aggr_state(p, LMS_USER);
2304         hrstime = mstate_aggr_state(p, LMS_SYSTEM);
2305         hrt2ts((hrutime + hrstime), &psp->pr_time);
2306         TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime);
2307 
2308         if (t == NULL) {
2309                 int wcode = p->p_wcode;              /* must be atomic read */
2310 
2311                 if (wcode)
2312                         psp->pr_wstat = wstat(wcode, p->p_wdata);
2313                 psp->pr_ttydev = PRNODEV;
2314                 psp->pr_lwp.pr_state = SZOMB;
2315                 psp->pr_lwp.pr_sname = 'Z';
2316                 psp->pr_lwp.pr_bindpro = PBIND_NONE;
2317                 psp->pr_lwp.pr_bindpset = PS_NONE;
2318         } else {
2319                 user_t *up = PTOU(p);
2320                 struct as *as;
2321                 dev_t d;
2322                 extern dev_t rwsconsdev, rconsdev, uconsdev;
2323 
2324                 d = cttydev(p);
2325                 /*
2326                  * If the controlling terminal is the real
2327                  * or workstation console device, map to what the
2328                  * user thinks is the console device. Handle case when
2329                  * rwsconsdev or rconsdev is set to NODEV for Starfire.
2330                  */
2331                 if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
2332                         d = uconsdev;
2333                 psp->pr_ttydev = (d == NODEV) ? PRNODEV : d;
2334                 psp->pr_start = up->u_start;
2335                 bcopy(up->u_comm, psp->pr_fname,
2336                     MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2337                 bcopy(up->u_psargs, psp->pr_psargs,
2338                     MIN(PRARGSZ-1, PSARGSZ));
2339                 psp->pr_argc = up->u_argc;
2340                 psp->pr_argv = up->u_argv;
2341                 psp->pr_envp = up->u_envp;
2342 
2343                 /* get the chosen lwp's lwpsinfo */
2344                 prgetlwpsinfo(t, &psp->pr_lwp);
2345 
2346                 /* compute %cpu for the process */
2347                 if (p->p_lwpcnt == 1)
2348                         psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
2349                 else {
2350                         uint64_t pct = 0;
2351                         hrtime_t cur_time = gethrtime_unscaled();
2352 
2353                         t = p->p_tlist;
2354                         do {
2355                                 pct += cpu_update_pct(t, cur_time);
2356                         } while ((t = t->t_forw) != p->p_tlist);
2357 
2358                         psp->pr_pctcpu = prgetpctcpu(pct);
2359                 }
2360                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
2361                         psp->pr_size = 0;
2362                         psp->pr_rssize = 0;
2363                 } else {
2364                         mutex_exit(&p->p_lock);
2365                         AS_LOCK_ENTER(as, RW_READER);
2366                         psp->pr_size = btopr(as->a_resvsize) *
2367                             (PAGESIZE / 1024);
2368                         psp->pr_rssize = rm_asrss(as) * (PAGESIZE / 1024);
2369                         psp->pr_pctmem = rm_pctmemory(as);
2370                         AS_LOCK_EXIT(as);
2371                         mutex_enter(&p->p_lock);
2372                 }
2373         }
2374 }
2375 
2376 #ifdef _SYSCALL32_IMPL
2377 void
2378 prgetpsinfo32(proc_t *p, psinfo32_t *psp)
2379 {
2380         kthread_t *t;
2381         struct cred *cred;
2382         hrtime_t hrutime, hrstime;
2383 
2384         ASSERT(MUTEX_HELD(&p->p_lock));
2385 
2386         if ((t = prchoose(p)) == NULL)  /* returns locked thread */
2387                 bzero(psp, sizeof (*psp));
2388         else {
2389                 thread_unlock(t);
2390                 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2391         }
2392 
2393         /*
2394          * only export SSYS and SMSACCT; everything else is off-limits to
2395          * userland apps.
2396          */
2397         psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2398         psp->pr_nlwp = p->p_lwpcnt;
2399         psp->pr_nzomb = p->p_zombcnt;
2400         mutex_enter(&p->p_crlock);
2401         cred = p->p_cred;
2402         psp->pr_uid = crgetruid(cred);
2403         psp->pr_euid = crgetuid(cred);
2404         psp->pr_gid = crgetrgid(cred);
2405         psp->pr_egid = crgetgid(cred);
2406         mutex_exit(&p->p_crlock);
2407         psp->pr_pid = p->p_pid;
2408         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
2409             (p->p_flag & SZONETOP)) {
2410                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
2411                 /*
2412                  * Inside local zones, fake zsched's pid as parent pids for
2413                  * processes which reference processes outside of the zone.
2414                  */
2415                 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
2416         } else {
2417                 psp->pr_ppid = p->p_ppid;
2418         }
2419         psp->pr_pgid = p->p_pgrp;
2420         psp->pr_sid = p->p_sessp->s_sid;
2421         psp->pr_taskid = p->p_task->tk_tkid;
2422         psp->pr_projid = p->p_task->tk_proj->kpj_id;
2423         psp->pr_poolid = p->p_pool->pool_id;
2424         psp->pr_zoneid = p->p_zone->zone_id;
2425         if ((psp->pr_contract = PRCTID(p)) == 0)
2426                 psp->pr_contract = -1;
2427         psp->pr_addr = 0;    /* cannot represent 64-bit addr in 32 bits */
2428         switch (p->p_model) {
2429         case DATAMODEL_ILP32:
2430                 psp->pr_dmodel = PR_MODEL_ILP32;
2431                 break;
2432         case DATAMODEL_LP64:
2433                 psp->pr_dmodel = PR_MODEL_LP64;
2434                 break;
2435         }
2436         hrutime = mstate_aggr_state(p, LMS_USER);
2437         hrstime = mstate_aggr_state(p, LMS_SYSTEM);
2438         hrt2ts32(hrutime + hrstime, &psp->pr_time);
2439         TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime);
2440 
2441         if (t == NULL) {
2442                 extern int wstat(int, int);     /* needs a header file */
2443                 int wcode = p->p_wcode;              /* must be atomic read */
2444 
2445                 if (wcode)
2446                         psp->pr_wstat = wstat(wcode, p->p_wdata);
2447                 psp->pr_ttydev = PRNODEV32;
2448                 psp->pr_lwp.pr_state = SZOMB;
2449                 psp->pr_lwp.pr_sname = 'Z';
2450         } else {
2451                 user_t *up = PTOU(p);
2452                 struct as *as;
2453                 dev_t d;
2454                 extern dev_t rwsconsdev, rconsdev, uconsdev;
2455 
2456                 d = cttydev(p);
2457                 /*
2458                  * If the controlling terminal is the real
2459                  * or workstation console device, map to what the
2460                  * user thinks is the console device. Handle case when
2461                  * rwsconsdev or rconsdev is set to NODEV for Starfire.
2462                  */
2463                 if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
2464                         d = uconsdev;
2465                 (void) cmpldev(&psp->pr_ttydev, d);
2466                 TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start);
2467                 bcopy(up->u_comm, psp->pr_fname,
2468                     MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2469                 bcopy(up->u_psargs, psp->pr_psargs,
2470                     MIN(PRARGSZ-1, PSARGSZ));
2471                 psp->pr_argc = up->u_argc;
2472                 psp->pr_argv = (caddr32_t)up->u_argv;
2473                 psp->pr_envp = (caddr32_t)up->u_envp;
2474 
2475                 /* get the chosen lwp's lwpsinfo */
2476                 prgetlwpsinfo32(t, &psp->pr_lwp);
2477 
2478                 /* compute %cpu for the process */
2479                 if (p->p_lwpcnt == 1)
2480                         psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
2481                 else {
2482                         uint64_t pct = 0;
2483                         hrtime_t cur_time;
2484 
2485                         t = p->p_tlist;
2486                         cur_time = gethrtime_unscaled();
2487                         do {
2488                                 pct += cpu_update_pct(t, cur_time);
2489                         } while ((t = t->t_forw) != p->p_tlist);
2490 
2491                         psp->pr_pctcpu = prgetpctcpu(pct);
2492                 }
2493                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
2494                         psp->pr_size = 0;
2495                         psp->pr_rssize = 0;
2496                 } else {
2497                         mutex_exit(&p->p_lock);
2498                         AS_LOCK_ENTER(as, RW_READER);
2499                         psp->pr_size = (size32_t)
2500                             (btopr(as->a_resvsize) * (PAGESIZE / 1024));
2501                         psp->pr_rssize = (size32_t)
2502                             (rm_asrss(as) * (PAGESIZE / 1024));
2503                         psp->pr_pctmem = rm_pctmemory(as);
2504                         AS_LOCK_EXIT(as);
2505                         mutex_enter(&p->p_lock);
2506                 }
2507         }
2508 
2509         /*
2510          * If we are looking at an LP64 process, zero out
2511          * the fields that cannot be represented in ILP32.
2512          */
2513         if (p->p_model != DATAMODEL_ILP32) {
2514                 psp->pr_size = 0;
2515                 psp->pr_rssize = 0;
2516                 psp->pr_argv = 0;
2517                 psp->pr_envp = 0;
2518         }
2519 }
2520 
2521 #endif  /* _SYSCALL32_IMPL */
2522 
2523 void
2524 prgetlwpsinfo(kthread_t *t, lwpsinfo_t *psp)
2525 {
2526         klwp_t *lwp = ttolwp(t);
2527         sobj_ops_t *sobj;
2528         char c, state;
2529         uint64_t pct;
2530         int retval, niceval;
2531         hrtime_t hrutime, hrstime;
2532 
2533         ASSERT(MUTEX_HELD(&ttoproc(t)->p_lock));
2534 
2535         bzero(psp, sizeof (*psp));
2536 
2537         psp->pr_flag = 0;    /* lwpsinfo_t.pr_flag is deprecated */
2538         psp->pr_lwpid = t->t_tid;
2539         psp->pr_addr = (uintptr_t)t;
2540         psp->pr_wchan = (uintptr_t)t->t_wchan;
2541 
2542         /* map the thread state enum into a process state enum */
2543         state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
2544         switch (state) {
2545         case TS_SLEEP:          state = SSLEEP;         c = 'S';        break;
2546         case TS_RUN:            state = SRUN;           c = 'R';        break;
2547         case TS_ONPROC:         state = SONPROC;        c = 'O';        break;
2548         case TS_ZOMB:           state = SZOMB;          c = 'Z';        break;
2549         case TS_STOPPED:        state = SSTOP;          c = 'T';        break;
2550         case TS_WAIT:           state = SWAIT;          c = 'W';        break;
2551         default:                state = 0;              c = '?';        break;
2552         }
2553         psp->pr_state = state;
2554         psp->pr_sname = c;
2555         if ((sobj = t->t_sobj_ops) != NULL)
2556                 psp->pr_stype = SOBJ_TYPE(sobj);
2557         retval = CL_DONICE(t, NULL, 0, &niceval);
2558         if (retval == 0) {
2559                 psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
2560                 psp->pr_nice = niceval + NZERO;
2561         }
2562         psp->pr_syscall = t->t_sysnum;
2563         psp->pr_pri = t->t_pri;
2564         psp->pr_start.tv_sec = t->t_start;
2565         psp->pr_start.tv_nsec = 0L;
2566         hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
2567         scalehrtime(&hrutime);
2568         hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
2569             lwp->lwp_mstate.ms_acct[LMS_TRAP];
2570         scalehrtime(&hrstime);
2571         hrt2ts(hrutime + hrstime, &psp->pr_time);
2572         /* compute %cpu for the lwp */
2573         pct = cpu_update_pct(t, gethrtime_unscaled());
2574         psp->pr_pctcpu = prgetpctcpu(pct);
2575         psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15;  /* [0..99] */
2576         if (psp->pr_cpu > 99)
2577                 psp->pr_cpu = 99;
2578 
2579         (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
2580             sizeof (psp->pr_clname) - 1);
2581         bzero(psp->pr_name, sizeof (psp->pr_name));       /* XXX ??? */
2582         psp->pr_onpro = t->t_cpu->cpu_id;
2583         psp->pr_bindpro = t->t_bind_cpu;
2584         psp->pr_bindpset = t->t_bind_pset;
2585         psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
2586 }
2587 
2588 #ifdef _SYSCALL32_IMPL
2589 void
2590 prgetlwpsinfo32(kthread_t *t, lwpsinfo32_t *psp)
2591 {
2592         proc_t *p = ttoproc(t);
2593         klwp_t *lwp = ttolwp(t);
2594         sobj_ops_t *sobj;
2595         char c, state;
2596         uint64_t pct;
2597         int retval, niceval;
2598         hrtime_t hrutime, hrstime;
2599 
2600         ASSERT(MUTEX_HELD(&p->p_lock));
2601 
2602         bzero(psp, sizeof (*psp));
2603 
2604         psp->pr_flag = 0;    /* lwpsinfo_t.pr_flag is deprecated */
2605         psp->pr_lwpid = t->t_tid;
2606         psp->pr_addr = 0;    /* cannot represent 64-bit addr in 32 bits */
2607         psp->pr_wchan = 0;   /* cannot represent 64-bit addr in 32 bits */
2608 
2609         /* map the thread state enum into a process state enum */
2610         state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
2611         switch (state) {
2612         case TS_SLEEP:          state = SSLEEP;         c = 'S';        break;
2613         case TS_RUN:            state = SRUN;           c = 'R';        break;
2614         case TS_ONPROC:         state = SONPROC;        c = 'O';        break;
2615         case TS_ZOMB:           state = SZOMB;          c = 'Z';        break;
2616         case TS_STOPPED:        state = SSTOP;          c = 'T';        break;
2617         case TS_WAIT:           state = SWAIT;          c = 'W';        break;
2618         default:                state = 0;              c = '?';        break;
2619         }
2620         psp->pr_state = state;
2621         psp->pr_sname = c;
2622         if ((sobj = t->t_sobj_ops) != NULL)
2623                 psp->pr_stype = SOBJ_TYPE(sobj);
2624         retval = CL_DONICE(t, NULL, 0, &niceval);
2625         if (retval == 0) {
2626                 psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
2627                 psp->pr_nice = niceval + NZERO;
2628         } else {
2629                 psp->pr_oldpri = 0;
2630                 psp->pr_nice = 0;
2631         }
2632         psp->pr_syscall = t->t_sysnum;
2633         psp->pr_pri = t->t_pri;
2634         psp->pr_start.tv_sec = (time32_t)t->t_start;
2635         psp->pr_start.tv_nsec = 0L;
2636         hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
2637         scalehrtime(&hrutime);
2638         hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
2639             lwp->lwp_mstate.ms_acct[LMS_TRAP];
2640         scalehrtime(&hrstime);
2641         hrt2ts32(hrutime + hrstime, &psp->pr_time);
2642         /* compute %cpu for the lwp */
2643         pct = cpu_update_pct(t, gethrtime_unscaled());
2644         psp->pr_pctcpu = prgetpctcpu(pct);
2645         psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15;  /* [0..99] */
2646         if (psp->pr_cpu > 99)
2647                 psp->pr_cpu = 99;
2648 
2649         (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
2650             sizeof (psp->pr_clname) - 1);
2651         bzero(psp->pr_name, sizeof (psp->pr_name));       /* XXX ??? */
2652         psp->pr_onpro = t->t_cpu->cpu_id;
2653         psp->pr_bindpro = t->t_bind_cpu;
2654         psp->pr_bindpset = t->t_bind_pset;
2655         psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
2656 }
2657 #endif  /* _SYSCALL32_IMPL */
2658 
2659 #ifdef _SYSCALL32_IMPL
2660 
2661 #define PR_COPY_FIELD(s, d, field)       d->field = s->field
2662 
2663 #define PR_COPY_FIELD_ILP32(s, d, field)                                \
2664         if (s->pr_dmodel == PR_MODEL_ILP32) {                        \
2665                 d->field = s->field;                              \
2666         }
2667 
2668 #define PR_COPY_TIMESPEC(s, d, field)                           \
2669         TIMESPEC_TO_TIMESPEC32(&d->field, &s->field);
2670 
2671 #define PR_COPY_BUF(s, d, field)                                \
2672         bcopy(s->field, d->field, sizeof (d->field));
2673 
2674 #define PR_IGNORE_FIELD(s, d, field)
2675 
2676 void
2677 lwpsinfo_kto32(const struct lwpsinfo *src, struct lwpsinfo32 *dest)
2678 {
2679         bzero(dest, sizeof (*dest));
2680 
2681         PR_COPY_FIELD(src, dest, pr_flag);
2682         PR_COPY_FIELD(src, dest, pr_lwpid);
2683         PR_IGNORE_FIELD(src, dest, pr_addr);
2684         PR_IGNORE_FIELD(src, dest, pr_wchan);
2685         PR_COPY_FIELD(src, dest, pr_stype);
2686         PR_COPY_FIELD(src, dest, pr_state);
2687         PR_COPY_FIELD(src, dest, pr_sname);
2688         PR_COPY_FIELD(src, dest, pr_nice);
2689         PR_COPY_FIELD(src, dest, pr_syscall);
2690         PR_COPY_FIELD(src, dest, pr_oldpri);
2691         PR_COPY_FIELD(src, dest, pr_cpu);
2692         PR_COPY_FIELD(src, dest, pr_pri);
2693         PR_COPY_FIELD(src, dest, pr_pctcpu);
2694         PR_COPY_TIMESPEC(src, dest, pr_start);
2695         PR_COPY_BUF(src, dest, pr_clname);
2696         PR_COPY_BUF(src, dest, pr_name);
2697         PR_COPY_FIELD(src, dest, pr_onpro);
2698         PR_COPY_FIELD(src, dest, pr_bindpro);
2699         PR_COPY_FIELD(src, dest, pr_bindpset);
2700         PR_COPY_FIELD(src, dest, pr_lgrp);
2701 }
2702 
2703 void
2704 psinfo_kto32(const struct psinfo *src, struct psinfo32 *dest)
2705 {
2706         bzero(dest, sizeof (*dest));
2707 
2708         PR_COPY_FIELD(src, dest, pr_flag);
2709         PR_COPY_FIELD(src, dest, pr_nlwp);
2710         PR_COPY_FIELD(src, dest, pr_pid);
2711         PR_COPY_FIELD(src, dest, pr_ppid);
2712         PR_COPY_FIELD(src, dest, pr_pgid);
2713         PR_COPY_FIELD(src, dest, pr_sid);
2714         PR_COPY_FIELD(src, dest, pr_uid);
2715         PR_COPY_FIELD(src, dest, pr_euid);
2716         PR_COPY_FIELD(src, dest, pr_gid);
2717         PR_COPY_FIELD(src, dest, pr_egid);
2718         PR_IGNORE_FIELD(src, dest, pr_addr);
2719         PR_COPY_FIELD_ILP32(src, dest, pr_size);
2720         PR_COPY_FIELD_ILP32(src, dest, pr_rssize);
2721         PR_COPY_FIELD(src, dest, pr_ttydev);
2722         PR_COPY_FIELD(src, dest, pr_pctcpu);
2723         PR_COPY_FIELD(src, dest, pr_pctmem);
2724         PR_COPY_TIMESPEC(src, dest, pr_start);
2725         PR_COPY_TIMESPEC(src, dest, pr_time);
2726         PR_COPY_TIMESPEC(src, dest, pr_ctime);
2727         PR_COPY_BUF(src, dest, pr_fname);
2728         PR_COPY_BUF(src, dest, pr_psargs);
2729         PR_COPY_FIELD(src, dest, pr_wstat);
2730         PR_COPY_FIELD(src, dest, pr_argc);
2731         PR_COPY_FIELD_ILP32(src, dest, pr_argv);
2732         PR_COPY_FIELD_ILP32(src, dest, pr_envp);
2733         PR_COPY_FIELD(src, dest, pr_dmodel);
2734         PR_COPY_FIELD(src, dest, pr_taskid);
2735         PR_COPY_FIELD(src, dest, pr_projid);
2736         PR_COPY_FIELD(src, dest, pr_nzomb);
2737         PR_COPY_FIELD(src, dest, pr_poolid);
2738         PR_COPY_FIELD(src, dest, pr_contract);
2739         PR_COPY_FIELD(src, dest, pr_poolid);
2740         PR_COPY_FIELD(src, dest, pr_poolid);
2741 
2742         lwpsinfo_kto32(&src->pr_lwp, &dest->pr_lwp);
2743 }
2744 
2745 #undef  PR_COPY_FIELD
2746 #undef  PR_COPY_FIELD_ILP32
2747 #undef  PR_COPY_TIMESPEC
2748 #undef  PR_COPY_BUF
2749 #undef  PR_IGNORE_FIELD
2750 
2751 #endif  /* _SYSCALL32_IMPL */
2752 
2753 /*
2754  * This used to get called when microstate accounting was disabled but
2755  * microstate information was requested.  Since Microstate accounting is on
2756  * regardless of the proc flags, this simply makes it appear to procfs that
2757  * microstate accounting is on.  This is relatively meaningless since you
2758  * can't turn it off, but this is here for the sake of appearances.
2759  */
2760 
2761 /*ARGSUSED*/
2762 void
2763 estimate_msacct(kthread_t *t, hrtime_t curtime)
2764 {
2765         proc_t *p;
2766 
2767         if (t == NULL)
2768                 return;
2769 
2770         p = ttoproc(t);
2771         ASSERT(MUTEX_HELD(&p->p_lock));
2772 
2773         /*
2774          * A system process (p0) could be referenced if the thread is
2775          * in the process of exiting.  Don't turn on microstate accounting
2776          * in that case.
2777          */
2778         if (p->p_flag & SSYS)
2779                 return;
2780 
2781         /*
2782          * Loop through all the LWPs (kernel threads) in the process.
2783          */
2784         t = p->p_tlist;
2785         do {
2786                 t->t_proc_flag |= TP_MSACCT;
2787         } while ((t = t->t_forw) != p->p_tlist);
2788 
2789         p->p_flag |= SMSACCT;                        /* set process-wide MSACCT */
2790 }
2791 
2792 /*
2793  * It's not really possible to disable microstate accounting anymore.
2794  * However, this routine simply turns off the ms accounting flags in a process
2795  * This way procfs can still pretend to turn microstate accounting on and
2796  * off for a process, but it actually doesn't do anything.  This is
2797  * a neutered form of preemptive idiot-proofing.
2798  */
2799 void
2800 disable_msacct(proc_t *p)
2801 {
2802         kthread_t *t;
2803 
2804         ASSERT(MUTEX_HELD(&p->p_lock));
2805 
2806         p->p_flag &= ~SMSACCT;           /* clear process-wide MSACCT */
2807         /*
2808          * Loop through all the LWPs (kernel threads) in the process.
2809          */
2810         if ((t = p->p_tlist) != NULL) {
2811                 do {
2812                         /* clear per-thread flag */
2813                         t->t_proc_flag &= ~TP_MSACCT;
2814                 } while ((t = t->t_forw) != p->p_tlist);
2815         }
2816 }
2817 
2818 /*
2819  * Return resource usage information.
2820  */
2821 void
2822 prgetusage(kthread_t *t, prhusage_t *pup)
2823 {
2824         klwp_t *lwp = ttolwp(t);
2825         hrtime_t *mstimep;
2826         struct mstate *ms = &lwp->lwp_mstate;
2827         int state;
2828         int i;
2829         hrtime_t curtime;
2830         hrtime_t waitrq;
2831         hrtime_t tmp1;
2832 
2833         curtime = gethrtime_unscaled();
2834 
2835         pup->pr_lwpid        = t->t_tid;
2836         pup->pr_count        = 1;
2837         pup->pr_create       = ms->ms_start;
2838         pup->pr_term    = ms->ms_term;
2839         scalehrtime(&pup->pr_create);
2840         scalehrtime(&pup->pr_term);
2841         if (ms->ms_term == 0) {
2842                 pup->pr_rtime = curtime - ms->ms_start;
2843                 scalehrtime(&pup->pr_rtime);
2844         } else {
2845                 pup->pr_rtime = ms->ms_term - ms->ms_start;
2846                 scalehrtime(&pup->pr_rtime);
2847         }
2848 
2849 
2850         pup->pr_utime    = ms->ms_acct[LMS_USER];
2851         pup->pr_stime    = ms->ms_acct[LMS_SYSTEM];
2852         pup->pr_ttime    = ms->ms_acct[LMS_TRAP];
2853         pup->pr_tftime   = ms->ms_acct[LMS_TFAULT];
2854         pup->pr_dftime   = ms->ms_acct[LMS_DFAULT];
2855         pup->pr_kftime   = ms->ms_acct[LMS_KFAULT];
2856         pup->pr_ltime    = ms->ms_acct[LMS_USER_LOCK];
2857         pup->pr_slptime  = ms->ms_acct[LMS_SLEEP];
2858         pup->pr_wtime    = ms->ms_acct[LMS_WAIT_CPU];
2859         pup->pr_stoptime = ms->ms_acct[LMS_STOPPED];
2860 
2861         prscaleusage(pup);
2862 
2863         /*
2864          * Adjust for time waiting in the dispatcher queue.
2865          */
2866         waitrq = t->t_waitrq;        /* hopefully atomic */
2867         if (waitrq != 0) {
2868                 if (waitrq > curtime) {
2869                         curtime = gethrtime_unscaled();
2870                 }
2871                 tmp1 = curtime - waitrq;
2872                 scalehrtime(&tmp1);
2873                 pup->pr_wtime += tmp1;
2874                 curtime = waitrq;
2875         }
2876 
2877         /*
2878          * Adjust for time spent in current microstate.
2879          */
2880         if (ms->ms_state_start > curtime) {
2881                 curtime = gethrtime_unscaled();
2882         }
2883 
2884         i = 0;
2885         do {
2886                 switch (state = t->t_mstate) {
2887                 case LMS_SLEEP:
2888                         /*
2889                          * Update the timer for the current sleep state.
2890                          */
2891                         switch (state = ms->ms_prev) {
2892                         case LMS_TFAULT:
2893                         case LMS_DFAULT:
2894                         case LMS_KFAULT:
2895                         case LMS_USER_LOCK:
2896                                 break;
2897                         default:
2898                                 state = LMS_SLEEP;
2899                                 break;
2900                         }
2901                         break;
2902                 case LMS_TFAULT:
2903                 case LMS_DFAULT:
2904                 case LMS_KFAULT:
2905                 case LMS_USER_LOCK:
2906                         state = LMS_SYSTEM;
2907                         break;
2908                 }
2909                 switch (state) {
2910                 case LMS_USER:          mstimep = &pup->pr_utime;        break;
2911                 case LMS_SYSTEM:        mstimep = &pup->pr_stime;        break;
2912                 case LMS_TRAP:          mstimep = &pup->pr_ttime;        break;
2913                 case LMS_TFAULT:        mstimep = &pup->pr_tftime;       break;
2914                 case LMS_DFAULT:        mstimep = &pup->pr_dftime;       break;
2915                 case LMS_KFAULT:        mstimep = &pup->pr_kftime;       break;
2916                 case LMS_USER_LOCK:     mstimep = &pup->pr_ltime;        break;
2917                 case LMS_SLEEP:         mstimep = &pup->pr_slptime;      break;
2918                 case LMS_WAIT_CPU:      mstimep = &pup->pr_wtime;        break;
2919                 case LMS_STOPPED:       mstimep = &pup->pr_stoptime;     break;
2920                 default:                panic("prgetusage: unknown microstate");
2921                 }
2922                 tmp1 = curtime - ms->ms_state_start;
2923                 if (tmp1 < 0) {
2924                         curtime = gethrtime_unscaled();
2925                         i++;
2926                         continue;
2927                 }
2928                 scalehrtime(&tmp1);
2929         } while (tmp1 < 0 && i < MAX_ITERS_SPIN);
2930 
2931         *mstimep += tmp1;
2932 
2933         /* update pup timestamp */
2934         pup->pr_tstamp = curtime;
2935         scalehrtime(&pup->pr_tstamp);
2936 
2937         /*
2938          * Resource usage counters.
2939          */
2940         pup->pr_minf  = lwp->lwp_ru.minflt;
2941         pup->pr_majf  = lwp->lwp_ru.majflt;
2942         pup->pr_nswap = lwp->lwp_ru.nswap;
2943         pup->pr_inblk = lwp->lwp_ru.inblock;
2944         pup->pr_oublk = lwp->lwp_ru.oublock;
2945         pup->pr_msnd  = lwp->lwp_ru.msgsnd;
2946         pup->pr_mrcv  = lwp->lwp_ru.msgrcv;
2947         pup->pr_sigs  = lwp->lwp_ru.nsignals;
2948         pup->pr_vctx  = lwp->lwp_ru.nvcsw;
2949         pup->pr_ictx  = lwp->lwp_ru.nivcsw;
2950         pup->pr_sysc  = lwp->lwp_ru.sysc;
2951         pup->pr_ioch  = lwp->lwp_ru.ioch;
2952 }
2953 
2954 /*
2955  * Convert ms_acct stats from unscaled high-res time to nanoseconds
2956  */
2957 void
2958 prscaleusage(prhusage_t *usg)
2959 {
2960         scalehrtime(&usg->pr_utime);
2961         scalehrtime(&usg->pr_stime);
2962         scalehrtime(&usg->pr_ttime);
2963         scalehrtime(&usg->pr_tftime);
2964         scalehrtime(&usg->pr_dftime);
2965         scalehrtime(&usg->pr_kftime);
2966         scalehrtime(&usg->pr_ltime);
2967         scalehrtime(&usg->pr_slptime);
2968         scalehrtime(&usg->pr_wtime);
2969         scalehrtime(&usg->pr_stoptime);
2970 }
2971 
2972 
2973 /*
2974  * Sum resource usage information.
2975  */
2976 void
2977 praddusage(kthread_t *t, prhusage_t *pup)
2978 {
2979         klwp_t *lwp = ttolwp(t);
2980         hrtime_t *mstimep;
2981         struct mstate *ms = &lwp->lwp_mstate;
2982         int state;
2983         int i;
2984         hrtime_t curtime;
2985         hrtime_t waitrq;
2986         hrtime_t tmp;
2987         prhusage_t conv;
2988 
2989         curtime = gethrtime_unscaled();
2990 
2991         if (ms->ms_term == 0) {
2992                 tmp = curtime - ms->ms_start;
2993                 scalehrtime(&tmp);
2994                 pup->pr_rtime += tmp;
2995         } else {
2996                 tmp = ms->ms_term - ms->ms_start;
2997                 scalehrtime(&tmp);
2998                 pup->pr_rtime += tmp;
2999         }
3000 
3001         conv.pr_utime = ms->ms_acct[LMS_USER];
3002         conv.pr_stime = ms->ms_acct[LMS_SYSTEM];
3003         conv.pr_ttime = ms->ms_acct[LMS_TRAP];
3004         conv.pr_tftime = ms->ms_acct[LMS_TFAULT];
3005         conv.pr_dftime = ms->ms_acct[LMS_DFAULT];
3006         conv.pr_kftime = ms->ms_acct[LMS_KFAULT];
3007         conv.pr_ltime = ms->ms_acct[LMS_USER_LOCK];
3008         conv.pr_slptime = ms->ms_acct[LMS_SLEEP];
3009         conv.pr_wtime = ms->ms_acct[LMS_WAIT_CPU];
3010         conv.pr_stoptime = ms->ms_acct[LMS_STOPPED];
3011 
3012         prscaleusage(&conv);
3013 
3014         pup->pr_utime        += conv.pr_utime;
3015         pup->pr_stime        += conv.pr_stime;
3016         pup->pr_ttime        += conv.pr_ttime;
3017         pup->pr_tftime       += conv.pr_tftime;
3018         pup->pr_dftime       += conv.pr_dftime;
3019         pup->pr_kftime       += conv.pr_kftime;
3020         pup->pr_ltime        += conv.pr_ltime;
3021         pup->pr_slptime      += conv.pr_slptime;
3022         pup->pr_wtime        += conv.pr_wtime;
3023         pup->pr_stoptime += conv.pr_stoptime;
3024 
3025         /*
3026          * Adjust for time waiting in the dispatcher queue.
3027          */
3028         waitrq = t->t_waitrq;        /* hopefully atomic */
3029         if (waitrq != 0) {
3030                 if (waitrq > curtime) {
3031                         curtime = gethrtime_unscaled();
3032                 }
3033                 tmp = curtime - waitrq;
3034                 scalehrtime(&tmp);
3035                 pup->pr_wtime += tmp;
3036                 curtime = waitrq;
3037         }
3038 
3039         /*
3040          * Adjust for time spent in current microstate.
3041          */
3042         if (ms->ms_state_start > curtime) {
3043                 curtime = gethrtime_unscaled();
3044         }
3045 
3046         i = 0;
3047         do {
3048                 switch (state = t->t_mstate) {
3049                 case LMS_SLEEP:
3050                         /*
3051                          * Update the timer for the current sleep state.
3052                          */
3053                         switch (state = ms->ms_prev) {
3054                         case LMS_TFAULT:
3055                         case LMS_DFAULT:
3056                         case LMS_KFAULT:
3057                         case LMS_USER_LOCK:
3058                                 break;
3059                         default:
3060                                 state = LMS_SLEEP;
3061                                 break;
3062                         }
3063                         break;
3064                 case LMS_TFAULT:
3065                 case LMS_DFAULT:
3066                 case LMS_KFAULT:
3067                 case LMS_USER_LOCK:
3068                         state = LMS_SYSTEM;
3069                         break;
3070                 }
3071                 switch (state) {
3072                 case LMS_USER:          mstimep = &pup->pr_utime;        break;
3073                 case LMS_SYSTEM:        mstimep = &pup->pr_stime;        break;
3074                 case LMS_TRAP:          mstimep = &pup->pr_ttime;        break;
3075                 case LMS_TFAULT:        mstimep = &pup->pr_tftime;       break;
3076                 case LMS_DFAULT:        mstimep = &pup->pr_dftime;       break;
3077                 case LMS_KFAULT:        mstimep = &pup->pr_kftime;       break;
3078                 case LMS_USER_LOCK:     mstimep = &pup->pr_ltime;        break;
3079                 case LMS_SLEEP:         mstimep = &pup->pr_slptime;      break;
3080                 case LMS_WAIT_CPU:      mstimep = &pup->pr_wtime;        break;
3081                 case LMS_STOPPED:       mstimep = &pup->pr_stoptime;     break;
3082                 default:                panic("praddusage: unknown microstate");
3083                 }
3084                 tmp = curtime - ms->ms_state_start;
3085                 if (tmp < 0) {
3086                         curtime = gethrtime_unscaled();
3087                         i++;
3088                         continue;
3089                 }
3090                 scalehrtime(&tmp);
3091         } while (tmp < 0 && i < MAX_ITERS_SPIN);
3092 
3093         *mstimep += tmp;
3094 
3095         /* update pup timestamp */
3096         pup->pr_tstamp = curtime;
3097         scalehrtime(&pup->pr_tstamp);
3098 
3099         /*
3100          * Resource usage counters.
3101          */
3102         pup->pr_minf  += lwp->lwp_ru.minflt;
3103         pup->pr_majf  += lwp->lwp_ru.majflt;
3104         pup->pr_nswap += lwp->lwp_ru.nswap;
3105         pup->pr_inblk += lwp->lwp_ru.inblock;
3106         pup->pr_oublk += lwp->lwp_ru.oublock;
3107         pup->pr_msnd  += lwp->lwp_ru.msgsnd;
3108         pup->pr_mrcv  += lwp->lwp_ru.msgrcv;
3109         pup->pr_sigs  += lwp->lwp_ru.nsignals;
3110         pup->pr_vctx  += lwp->lwp_ru.nvcsw;
3111         pup->pr_ictx  += lwp->lwp_ru.nivcsw;
3112         pup->pr_sysc  += lwp->lwp_ru.sysc;
3113         pup->pr_ioch  += lwp->lwp_ru.ioch;
3114 }
3115 
3116 /*
3117  * Convert a prhusage_t to a prusage_t.
3118  * This means convert each hrtime_t to a timestruc_t
3119  * and copy the count fields uint64_t => ulong_t.
3120  */
3121 void
3122 prcvtusage(prhusage_t *pup, prusage_t *upup)
3123 {
3124         uint64_t *ullp;
3125         ulong_t *ulp;
3126         int i;
3127 
3128         upup->pr_lwpid = pup->pr_lwpid;
3129         upup->pr_count = pup->pr_count;
3130 
3131         hrt2ts(pup->pr_tstamp,       &upup->pr_tstamp);
3132         hrt2ts(pup->pr_create,       &upup->pr_create);
3133         hrt2ts(pup->pr_term, &upup->pr_term);
3134         hrt2ts(pup->pr_rtime,        &upup->pr_rtime);
3135         hrt2ts(pup->pr_utime,        &upup->pr_utime);
3136         hrt2ts(pup->pr_stime,        &upup->pr_stime);
3137         hrt2ts(pup->pr_ttime,        &upup->pr_ttime);
3138         hrt2ts(pup->pr_tftime,       &upup->pr_tftime);
3139         hrt2ts(pup->pr_dftime,       &upup->pr_dftime);
3140         hrt2ts(pup->pr_kftime,       &upup->pr_kftime);
3141         hrt2ts(pup->pr_ltime,        &upup->pr_ltime);
3142         hrt2ts(pup->pr_slptime,      &upup->pr_slptime);
3143         hrt2ts(pup->pr_wtime,        &upup->pr_wtime);
3144         hrt2ts(pup->pr_stoptime, &upup->pr_stoptime);
3145         bzero(upup->filltime, sizeof (upup->filltime));
3146 
3147         ullp = &pup->pr_minf;
3148         ulp = &upup->pr_minf;
3149         for (i = 0; i < 22; i++)
3150                 *ulp++ = (ulong_t)*ullp++;
3151 }
3152 
3153 #ifdef _SYSCALL32_IMPL
3154 void
3155 prcvtusage32(prhusage_t *pup, prusage32_t *upup)
3156 {
3157         uint64_t *ullp;
3158         uint32_t *ulp;
3159         int i;
3160 
3161         upup->pr_lwpid = pup->pr_lwpid;
3162         upup->pr_count = pup->pr_count;
3163 
3164         hrt2ts32(pup->pr_tstamp,     &upup->pr_tstamp);
3165         hrt2ts32(pup->pr_create,     &upup->pr_create);
3166         hrt2ts32(pup->pr_term,               &upup->pr_term);
3167         hrt2ts32(pup->pr_rtime,              &upup->pr_rtime);
3168         hrt2ts32(pup->pr_utime,              &upup->pr_utime);
3169         hrt2ts32(pup->pr_stime,              &upup->pr_stime);
3170         hrt2ts32(pup->pr_ttime,              &upup->pr_ttime);
3171         hrt2ts32(pup->pr_tftime,     &upup->pr_tftime);
3172         hrt2ts32(pup->pr_dftime,     &upup->pr_dftime);
3173         hrt2ts32(pup->pr_kftime,     &upup->pr_kftime);
3174         hrt2ts32(pup->pr_ltime,              &upup->pr_ltime);
3175         hrt2ts32(pup->pr_slptime,    &upup->pr_slptime);
3176         hrt2ts32(pup->pr_wtime,              &upup->pr_wtime);
3177         hrt2ts32(pup->pr_stoptime,   &upup->pr_stoptime);
3178         bzero(upup->filltime, sizeof (upup->filltime));
3179 
3180         ullp = &pup->pr_minf;
3181         ulp = &upup->pr_minf;
3182         for (i = 0; i < 22; i++)
3183                 *ulp++ = (uint32_t)*ullp++;
3184 }
3185 #endif  /* _SYSCALL32_IMPL */
3186 
3187 /*
3188  * Determine whether a set is empty.
3189  */
3190 int
3191 setisempty(uint32_t *sp, uint_t n)
3192 {
3193         while (n--)
3194                 if (*sp++)
3195                         return (0);
3196         return (1);
3197 }
3198 
3199 /*
3200  * Utility routine for establishing a watched area in the process.
3201  * Keep the list of watched areas sorted by virtual address.
3202  */
3203 int
3204 set_watched_area(proc_t *p, struct watched_area *pwa)
3205 {
3206         caddr_t vaddr = pwa->wa_vaddr;
3207         caddr_t eaddr = pwa->wa_eaddr;
3208         ulong_t flags = pwa->wa_flags;
3209         struct watched_area *target;
3210         avl_index_t where;
3211         int error = 0;
3212 
3213         /* we must not be holding p->p_lock, but the process must be locked */
3214         ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3215         ASSERT(p->p_proc_flag & P_PR_LOCK);
3216 
3217         /*
3218          * If this is our first watchpoint, enable watchpoints for the process.
3219          */
3220         if (!pr_watch_active(p)) {
3221                 kthread_t *t;
3222 
3223                 mutex_enter(&p->p_lock);
3224                 if ((t = p->p_tlist) != NULL) {
3225                         do {
3226                                 watch_enable(t);
3227                         } while ((t = t->t_forw) != p->p_tlist);
3228                 }
3229                 mutex_exit(&p->p_lock);
3230         }
3231 
3232         target = pr_find_watched_area(p, pwa, &where);
3233         if (target != NULL) {
3234                 /*
3235                  * We discovered an existing, overlapping watched area.
3236                  * Allow it only if it is an exact match.
3237                  */
3238                 if (target->wa_vaddr != vaddr ||
3239                     target->wa_eaddr != eaddr)
3240                         error = EINVAL;
3241                 else if (target->wa_flags != flags) {
3242                         error = set_watched_page(p, vaddr, eaddr,
3243                             flags, target->wa_flags);
3244                         target->wa_flags = flags;
3245                 }
3246                 kmem_free(pwa, sizeof (struct watched_area));
3247         } else {
3248                 avl_insert(&p->p_warea, pwa, where);
3249                 error = set_watched_page(p, vaddr, eaddr, flags, 0);
3250         }
3251 
3252         return (error);
3253 }
3254 
3255 /*
3256  * Utility routine for clearing a watched area in the process.
3257  * Must be an exact match of the virtual address.
3258  * size and flags don't matter.
3259  */
3260 int
3261 clear_watched_area(proc_t *p, struct watched_area *pwa)
3262 {
3263         struct watched_area *found;
3264 
3265         /* we must not be holding p->p_lock, but the process must be locked */
3266         ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3267         ASSERT(p->p_proc_flag & P_PR_LOCK);
3268 
3269 
3270         if (!pr_watch_active(p)) {
3271                 kmem_free(pwa, sizeof (struct watched_area));
3272                 return (0);
3273         }
3274 
3275         /*
3276          * Look for a matching address in the watched areas.  If a match is
3277          * found, clear the old watched area and adjust the watched page(s).  It
3278          * is not an error if there is no match.
3279          */
3280         if ((found = pr_find_watched_area(p, pwa, NULL)) != NULL &&
3281             found->wa_vaddr == pwa->wa_vaddr) {
3282                 clear_watched_page(p, found->wa_vaddr, found->wa_eaddr,
3283                     found->wa_flags);
3284                 avl_remove(&p->p_warea, found);
3285                 kmem_free(found, sizeof (struct watched_area));
3286         }
3287 
3288         kmem_free(pwa, sizeof (struct watched_area));
3289 
3290         /*
3291          * If we removed the last watched area from the process, disable
3292          * watchpoints.
3293          */
3294         if (!pr_watch_active(p)) {
3295                 kthread_t *t;
3296 
3297                 mutex_enter(&p->p_lock);
3298                 if ((t = p->p_tlist) != NULL) {
3299                         do {
3300                                 watch_disable(t);
3301                         } while ((t = t->t_forw) != p->p_tlist);
3302                 }
3303                 mutex_exit(&p->p_lock);
3304         }
3305 
3306         return (0);
3307 }
3308 
3309 /*
3310  * Frees all the watched_area structures
3311  */
3312 void
3313 pr_free_watchpoints(proc_t *p)
3314 {
3315         struct watched_area *delp;
3316         void *cookie;
3317 
3318         cookie = NULL;
3319         while ((delp = avl_destroy_nodes(&p->p_warea, &cookie)) != NULL)
3320                 kmem_free(delp, sizeof (struct watched_area));
3321 
3322         avl_destroy(&p->p_warea);
3323 }
3324 
3325 /*
3326  * This one is called by the traced process to unwatch all the
3327  * pages while deallocating the list of watched_page structs.
3328  */
3329 void
3330 pr_free_watched_pages(proc_t *p)
3331 {
3332         struct as *as = p->p_as;
3333         struct watched_page *pwp;
3334         uint_t prot;
3335         int    retrycnt, err;
3336         void *cookie;
3337 
3338         if (as == NULL || avl_numnodes(&as->a_wpage) == 0)
3339                 return;
3340 
3341         ASSERT(MUTEX_NOT_HELD(&curproc->p_lock));
3342         AS_LOCK_ENTER(as, RW_WRITER);
3343 
3344         pwp = avl_first(&as->a_wpage);
3345 
3346         cookie = NULL;
3347         while ((pwp = avl_destroy_nodes(&as->a_wpage, &cookie)) != NULL) {
3348                 retrycnt = 0;
3349                 if ((prot = pwp->wp_oprot) != 0) {
3350                         caddr_t addr = pwp->wp_vaddr;
3351                         struct seg *seg;
3352                 retry:
3353 
3354                         if ((pwp->wp_prot != prot ||
3355                             (pwp->wp_flags & WP_NOWATCH)) &&
3356                             (seg = as_segat(as, addr)) != NULL) {
3357                                 err = SEGOP_SETPROT(seg, addr, PAGESIZE, prot);
3358                                 if (err == IE_RETRY) {
3359                                         ASSERT(retrycnt == 0);
3360                                         retrycnt++;
3361                                         goto retry;
3362                                 }
3363                         }
3364                 }
3365                 kmem_free(pwp, sizeof (struct watched_page));
3366         }
3367 
3368         avl_destroy(&as->a_wpage);
3369         p->p_wprot = NULL;
3370 
3371         AS_LOCK_EXIT(as);
3372 }
3373 
3374 /*
3375  * Insert a watched area into the list of watched pages.
3376  * If oflags is zero then we are adding a new watched area.
3377  * Otherwise we are changing the flags of an existing watched area.
3378  */
3379 static int
3380 set_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr,
3381     ulong_t flags, ulong_t oflags)
3382 {
3383         struct as *as = p->p_as;
3384         avl_tree_t *pwp_tree;
3385         struct watched_page *pwp, *newpwp;
3386         struct watched_page tpw;
3387         avl_index_t where;
3388         struct seg *seg;
3389         uint_t prot;
3390         caddr_t addr;
3391 
3392         /*
3393          * We need to pre-allocate a list of structures before we grab the
3394          * address space lock to avoid calling kmem_alloc(KM_SLEEP) with locks
3395          * held.
3396          */
3397         newpwp = NULL;
3398         for (addr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3399             addr < eaddr; addr += PAGESIZE) {
3400                 pwp = kmem_zalloc(sizeof (struct watched_page), KM_SLEEP);
3401                 pwp->wp_list = newpwp;
3402                 newpwp = pwp;
3403         }
3404 
3405         AS_LOCK_ENTER(as, RW_WRITER);
3406 
3407         /*
3408          * Search for an existing watched page to contain the watched area.
3409          * If none is found, grab a new one from the available list
3410          * and insert it in the active list, keeping the list sorted
3411          * by user-level virtual address.
3412          */
3413         if (p->p_flag & SVFWAIT)
3414                 pwp_tree = &p->p_wpage;
3415         else
3416                 pwp_tree = &as->a_wpage;
3417 
3418 again:
3419         if (avl_numnodes(pwp_tree) > prnwatch) {
3420                 AS_LOCK_EXIT(as);
3421                 while (newpwp != NULL) {
3422                         pwp = newpwp->wp_list;
3423                         kmem_free(newpwp, sizeof (struct watched_page));
3424                         newpwp = pwp;
3425                 }
3426                 return (E2BIG);
3427         }
3428 
3429         tpw.wp_vaddr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3430         if ((pwp = avl_find(pwp_tree, &tpw, &where)) == NULL) {
3431                 pwp = newpwp;
3432                 newpwp = newpwp->wp_list;
3433                 pwp->wp_list = NULL;
3434                 pwp->wp_vaddr = (caddr_t)((uintptr_t)vaddr &
3435                     (uintptr_t)PAGEMASK);
3436                 avl_insert(pwp_tree, pwp, where);
3437         }
3438 
3439         ASSERT(vaddr >= pwp->wp_vaddr && vaddr < pwp->wp_vaddr + PAGESIZE);
3440 
3441         if (oflags & WA_READ)
3442                 pwp->wp_read--;
3443         if (oflags & WA_WRITE)
3444                 pwp->wp_write--;
3445         if (oflags & WA_EXEC)
3446                 pwp->wp_exec--;
3447 
3448         ASSERT(pwp->wp_read >= 0);
3449         ASSERT(pwp->wp_write >= 0);
3450         ASSERT(pwp->wp_exec >= 0);
3451 
3452         if (flags & WA_READ)
3453                 pwp->wp_read++;
3454         if (flags & WA_WRITE)
3455                 pwp->wp_write++;
3456         if (flags & WA_EXEC)
3457                 pwp->wp_exec++;
3458 
3459         if (!(p->p_flag & SVFWAIT)) {
3460                 vaddr = pwp->wp_vaddr;
3461                 if (pwp->wp_oprot == 0 &&
3462                     (seg = as_segat(as, vaddr)) != NULL) {
3463                         SEGOP_GETPROT(seg, vaddr, 0, &prot);
3464                         pwp->wp_oprot = (uchar_t)prot;
3465                         pwp->wp_prot = (uchar_t)prot;
3466                 }
3467                 if (pwp->wp_oprot != 0) {
3468                         prot = pwp->wp_oprot;
3469                         if (pwp->wp_read)
3470                                 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3471                         if (pwp->wp_write)
3472                                 prot &= ~PROT_WRITE;
3473                         if (pwp->wp_exec)
3474                                 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3475                         if (!(pwp->wp_flags & WP_NOWATCH) &&
3476                             pwp->wp_prot != prot &&
3477                             (pwp->wp_flags & WP_SETPROT) == 0) {
3478                                 pwp->wp_flags |= WP_SETPROT;
3479                                 pwp->wp_list = p->p_wprot;
3480                                 p->p_wprot = pwp;
3481                         }
3482                         pwp->wp_prot = (uchar_t)prot;
3483                 }
3484         }
3485 
3486         /*
3487          * If the watched area extends into the next page then do
3488          * it over again with the virtual address of the next page.
3489          */
3490         if ((vaddr = pwp->wp_vaddr + PAGESIZE) < eaddr)
3491                 goto again;
3492 
3493         AS_LOCK_EXIT(as);
3494 
3495         /*
3496          * Free any pages we may have over-allocated
3497          */
3498         while (newpwp != NULL) {
3499                 pwp = newpwp->wp_list;
3500                 kmem_free(newpwp, sizeof (struct watched_page));
3501                 newpwp = pwp;
3502         }
3503 
3504         return (0);
3505 }
3506 
3507 /*
3508  * Remove a watched area from the list of watched pages.
3509  * A watched area may extend over more than one page.
3510  */
3511 static void
3512 clear_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr, ulong_t flags)
3513 {
3514         struct as *as = p->p_as;
3515         struct watched_page *pwp;
3516         struct watched_page tpw;
3517         avl_tree_t *tree;
3518         avl_index_t where;
3519 
3520         AS_LOCK_ENTER(as, RW_WRITER);
3521 
3522         if (p->p_flag & SVFWAIT)
3523                 tree = &p->p_wpage;
3524         else
3525                 tree = &as->a_wpage;
3526 
3527         tpw.wp_vaddr = vaddr =
3528             (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3529         pwp = avl_find(tree, &tpw, &where);
3530         if (pwp == NULL)
3531                 pwp = avl_nearest(tree, where, AVL_AFTER);
3532 
3533         while (pwp != NULL && pwp->wp_vaddr < eaddr) {
3534                 ASSERT(vaddr <=  pwp->wp_vaddr);
3535 
3536                 if (flags & WA_READ)
3537                         pwp->wp_read--;
3538                 if (flags & WA_WRITE)
3539                         pwp->wp_write--;
3540                 if (flags & WA_EXEC)
3541                         pwp->wp_exec--;
3542 
3543                 if (pwp->wp_read + pwp->wp_write + pwp->wp_exec != 0) {
3544                         /*
3545                          * Reset the hat layer's protections on this page.
3546                          */
3547                         if (pwp->wp_oprot != 0) {
3548                                 uint_t prot = pwp->wp_oprot;
3549 
3550                                 if (pwp->wp_read)
3551                                         prot &=
3552                                             ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3553                                 if (pwp->wp_write)
3554                                         prot &= ~PROT_WRITE;
3555                                 if (pwp->wp_exec)
3556                                         prot &=
3557                                             ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3558                                 if (!(pwp->wp_flags & WP_NOWATCH) &&
3559                                     pwp->wp_prot != prot &&
3560                                     (pwp->wp_flags & WP_SETPROT) == 0) {
3561                                         pwp->wp_flags |= WP_SETPROT;
3562                                         pwp->wp_list = p->p_wprot;
3563                                         p->p_wprot = pwp;
3564                                 }
3565                                 pwp->wp_prot = (uchar_t)prot;
3566                         }
3567                 } else {
3568                         /*
3569                          * No watched areas remain in this page.
3570                          * Reset everything to normal.
3571                          */
3572                         if (pwp->wp_oprot != 0) {
3573                                 pwp->wp_prot = pwp->wp_oprot;
3574                                 if ((pwp->wp_flags & WP_SETPROT) == 0) {
3575                                         pwp->wp_flags |= WP_SETPROT;
3576                                         pwp->wp_list = p->p_wprot;
3577                                         p->p_wprot = pwp;
3578                                 }
3579                         }
3580                 }
3581 
3582                 pwp = AVL_NEXT(tree, pwp);
3583         }
3584 
3585         AS_LOCK_EXIT(as);
3586 }
3587 
3588 /*
3589  * Return the original protections for the specified page.
3590  */
3591 static void
3592 getwatchprot(struct as *as, caddr_t addr, uint_t *prot)
3593 {
3594         struct watched_page *pwp;
3595         struct watched_page tpw;
3596 
3597         ASSERT(AS_LOCK_HELD(as));
3598 
3599         tpw.wp_vaddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
3600         if ((pwp = avl_find(&as->a_wpage, &tpw, NULL)) != NULL)
3601                 *prot = pwp->wp_oprot;
3602 }
3603 
3604 static prpagev_t *
3605 pr_pagev_create(struct seg *seg, int check_noreserve)
3606 {
3607         prpagev_t *pagev = kmem_alloc(sizeof (prpagev_t), KM_SLEEP);
3608         size_t total_pages = seg_pages(seg);
3609 
3610         /*
3611          * Limit the size of our vectors to pagev_lim pages at a time.  We need
3612          * 4 or 5 bytes of storage per page, so this means we limit ourself
3613          * to about a megabyte of kernel heap by default.
3614          */
3615         pagev->pg_npages = MIN(total_pages, pagev_lim);
3616         pagev->pg_pnbase = 0;
3617 
3618         pagev->pg_protv =
3619             kmem_alloc(pagev->pg_npages * sizeof (uint_t), KM_SLEEP);
3620 
3621         if (check_noreserve)
3622                 pagev->pg_incore =
3623                     kmem_alloc(pagev->pg_npages * sizeof (char), KM_SLEEP);
3624         else
3625                 pagev->pg_incore = NULL;
3626 
3627         return (pagev);
3628 }
3629 
3630 static void
3631 pr_pagev_destroy(prpagev_t *pagev)
3632 {
3633         if (pagev->pg_incore != NULL)
3634                 kmem_free(pagev->pg_incore, pagev->pg_npages * sizeof (char));
3635 
3636         kmem_free(pagev->pg_protv, pagev->pg_npages * sizeof (uint_t));
3637         kmem_free(pagev, sizeof (prpagev_t));
3638 }
3639 
3640 static caddr_t
3641 pr_pagev_fill(prpagev_t *pagev, struct seg *seg, caddr_t addr, caddr_t eaddr)
3642 {
3643         ulong_t lastpg = seg_page(seg, eaddr - 1);
3644         ulong_t pn, pnlim;
3645         caddr_t saddr;
3646         size_t len;
3647 
3648         ASSERT(addr >= seg->s_base && addr <= eaddr);
3649 
3650         if (addr == eaddr)
3651                 return (eaddr);
3652 
3653 refill:
3654         ASSERT(addr < eaddr);
3655         pagev->pg_pnbase = seg_page(seg, addr);
3656         pnlim = pagev->pg_pnbase + pagev->pg_npages;
3657         saddr = addr;
3658 
3659         if (lastpg < pnlim)
3660                 len = (size_t)(eaddr - addr);
3661         else
3662                 len = pagev->pg_npages * PAGESIZE;
3663 
3664         if (pagev->pg_incore != NULL) {
3665                 /*
3666                  * INCORE cleverly has different semantics than GETPROT:
3667                  * it returns info on pages up to but NOT including addr + len.
3668                  */
3669                 SEGOP_INCORE(seg, addr, len, pagev->pg_incore);
3670                 pn = pagev->pg_pnbase;
3671 
3672                 do {
3673                         /*
3674                          * Guilty knowledge here:  We know that segvn_incore
3675                          * returns more than just the low-order bit that
3676                          * indicates the page is actually in memory.  If any
3677                          * bits are set, then the page has backing store.
3678                          */
3679                         if (pagev->pg_incore[pn++ - pagev->pg_pnbase])
3680                                 goto out;
3681 
3682                 } while ((addr += PAGESIZE) < eaddr && pn < pnlim);
3683 
3684                 /*
3685                  * If we examined all the pages in the vector but we're not
3686                  * at the end of the segment, take another lap.
3687                  */
3688                 if (addr < eaddr)
3689                         goto refill;
3690         }
3691 
3692         /*
3693          * Need to take len - 1 because addr + len is the address of the
3694          * first byte of the page just past the end of what we want.
3695          */
3696 out:
3697         SEGOP_GETPROT(seg, saddr, len - 1, pagev->pg_protv);
3698         return (addr);
3699 }
3700 
3701 static caddr_t
3702 pr_pagev_nextprot(prpagev_t *pagev, struct seg *seg,
3703     caddr_t *saddrp, caddr_t eaddr, uint_t *protp)
3704 {
3705         /*
3706          * Our starting address is either the specified address, or the base
3707          * address from the start of the pagev.  If the latter is greater,
3708          * this means a previous call to pr_pagev_fill has already scanned
3709          * further than the end of the previous mapping.
3710          */
3711         caddr_t base = seg->s_base + pagev->pg_pnbase * PAGESIZE;
3712         caddr_t addr = MAX(*saddrp, base);
3713         ulong_t pn = seg_page(seg, addr);
3714         uint_t prot, nprot;
3715 
3716         /*
3717          * If we're dealing with noreserve pages, then advance addr to
3718          * the address of the next page which has backing store.
3719          */
3720         if (pagev->pg_incore != NULL) {
3721                 while (pagev->pg_incore[pn - pagev->pg_pnbase] == 0) {
3722                         if ((addr += PAGESIZE) == eaddr) {
3723                                 *saddrp = addr;
3724                                 prot = 0;
3725                                 goto out;
3726                         }
3727                         if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
3728                                 addr = pr_pagev_fill(pagev, seg, addr, eaddr);
3729                                 if (addr == eaddr) {
3730                                         *saddrp = addr;
3731                                         prot = 0;
3732                                         goto out;
3733                                 }
3734                                 pn = seg_page(seg, addr);
3735                         }
3736                 }
3737         }
3738 
3739         /*
3740          * Get the protections on the page corresponding to addr.
3741          */
3742         pn = seg_page(seg, addr);
3743         ASSERT(pn >= pagev->pg_pnbase);
3744         ASSERT(pn < (pagev->pg_pnbase + pagev->pg_npages));
3745 
3746         prot = pagev->pg_protv[pn - pagev->pg_pnbase];
3747         getwatchprot(seg->s_as, addr, &prot);
3748         *saddrp = addr;
3749 
3750         /*
3751          * Now loop until we find a backed page with different protections
3752          * or we reach the end of this segment.
3753          */
3754         while ((addr += PAGESIZE) < eaddr) {
3755                 /*
3756                  * If pn has advanced to the page number following what we
3757                  * have information on, refill the page vector and reset
3758                  * addr and pn.  If pr_pagev_fill does not return the
3759                  * address of the next page, we have a discontiguity and
3760                  * thus have reached the end of the current mapping.
3761                  */
3762                 if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
3763                         caddr_t naddr = pr_pagev_fill(pagev, seg, addr, eaddr);
3764                         if (naddr != addr)
3765                                 goto out;
3766                         pn = seg_page(seg, addr);
3767                 }
3768 
3769                 /*
3770                  * The previous page's protections are in prot, and it has
3771                  * backing.  If this page is MAP_NORESERVE and has no backing,
3772                  * then end this mapping and return the previous protections.
3773                  */
3774                 if (pagev->pg_incore != NULL &&
3775                     pagev->pg_incore[pn - pagev->pg_pnbase] == 0)
3776                         break;
3777 
3778                 /*
3779                  * Otherwise end the mapping if this page's protections (nprot)
3780                  * are different than those in the previous page (prot).
3781                  */
3782                 nprot = pagev->pg_protv[pn - pagev->pg_pnbase];
3783                 getwatchprot(seg->s_as, addr, &nprot);
3784 
3785                 if (nprot != prot)
3786                         break;
3787         }
3788 
3789 out:
3790         *protp = prot;
3791         return (addr);
3792 }
3793 
3794 size_t
3795 pr_getsegsize(struct seg *seg, int reserved)
3796 {
3797         size_t size = seg->s_size;
3798 
3799         /*
3800          * If we're interested in the reserved space, return the size of the
3801          * segment itself.  Everything else in this function is a special case
3802          * to determine the actual underlying size of various segment types.
3803          */
3804         if (reserved)
3805                 return (size);
3806 
3807         /*
3808          * If this is a segvn mapping of a regular file, return the smaller
3809          * of the segment size and the remaining size of the file beyond
3810          * the file offset corresponding to seg->s_base.
3811          */
3812         if (seg->s_ops == &segvn_ops) {
3813                 vattr_t vattr;
3814                 vnode_t *vp;
3815 
3816                 vattr.va_mask = AT_SIZE;
3817 
3818                 if (SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3819                     vp != NULL && vp->v_type == VREG &&
3820                     VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3821 
3822                         u_offset_t fsize = vattr.va_size;
3823                         u_offset_t offset = SEGOP_GETOFFSET(seg, seg->s_base);
3824 
3825                         if (fsize < offset)
3826                                 fsize = 0;
3827                         else
3828                                 fsize -= offset;
3829 
3830                         fsize = roundup(fsize, (u_offset_t)PAGESIZE);
3831 
3832                         if (fsize < (u_offset_t)size)
3833                                 size = (size_t)fsize;
3834                 }
3835 
3836                 return (size);
3837         }
3838 
3839         /*
3840          * If this is an ISM shared segment, don't include pages that are
3841          * beyond the real size of the spt segment that backs it.
3842          */
3843         if (seg->s_ops == &segspt_shmops)
3844                 return (MIN(spt_realsize(seg), size));
3845 
3846         /*
3847          * If this is segment is a mapping from /dev/null, then this is a
3848          * reservation of virtual address space and has no actual size.
3849          * Such segments are backed by segdev and have type set to neither
3850          * MAP_SHARED nor MAP_PRIVATE.
3851          */
3852         if (seg->s_ops == &segdev_ops &&
3853             ((SEGOP_GETTYPE(seg, seg->s_base) &
3854             (MAP_SHARED | MAP_PRIVATE)) == 0))
3855                 return (0);
3856 
3857         /*
3858          * If this segment doesn't match one of the special types we handle,
3859          * just return the size of the segment itself.
3860          */
3861         return (size);
3862 }
3863 
3864 uint_t
3865 pr_getprot(struct seg *seg, int reserved, void **tmp,
3866     caddr_t *saddrp, caddr_t *naddrp, caddr_t eaddr)
3867 {
3868         struct as *as = seg->s_as;
3869 
3870         caddr_t saddr = *saddrp;
3871         caddr_t naddr;
3872 
3873         int check_noreserve;
3874         uint_t prot;
3875 
3876         union {
3877                 struct segvn_data *svd;
3878                 struct segdev_data *sdp;
3879                 void *data;
3880         } s;
3881 
3882         s.data = seg->s_data;
3883 
3884         ASSERT(AS_WRITE_HELD(as));
3885         ASSERT(saddr >= seg->s_base && saddr < eaddr);
3886         ASSERT(eaddr <= seg->s_base + seg->s_size);
3887 
3888         /*
3889          * Don't include MAP_NORESERVE pages in the address range
3890          * unless their mappings have actually materialized.
3891          * We cheat by knowing that segvn is the only segment
3892          * driver that supports MAP_NORESERVE.
3893          */
3894         check_noreserve =
3895             (!reserved && seg->s_ops == &segvn_ops && s.svd != NULL &&
3896             (s.svd->vp == NULL || s.svd->vp->v_type != VREG) &&
3897             (s.svd->flags & MAP_NORESERVE));
3898 
3899         /*
3900          * Examine every page only as a last resort.  We use guilty knowledge
3901          * of segvn and segdev to avoid this: if there are no per-page
3902          * protections present in the segment and we don't care about
3903          * MAP_NORESERVE, then s_data->prot is the prot for the whole segment.
3904          */
3905         if (!check_noreserve && saddr == seg->s_base &&
3906             seg->s_ops == &segvn_ops && s.svd != NULL && s.svd->pageprot == 0) {
3907                 prot = s.svd->prot;
3908                 getwatchprot(as, saddr, &prot);
3909                 naddr = eaddr;
3910 
3911         } else if (saddr == seg->s_base && seg->s_ops == &segdev_ops &&
3912             s.sdp != NULL && s.sdp->pageprot == 0) {
3913                 prot = s.sdp->prot;
3914                 getwatchprot(as, saddr, &prot);
3915                 naddr = eaddr;
3916 
3917         } else {
3918                 prpagev_t *pagev;
3919 
3920                 /*
3921                  * If addr is sitting at the start of the segment, then
3922                  * create a page vector to store protection and incore
3923                  * information for pages in the segment, and fill it.
3924                  * Otherwise, we expect *tmp to address the prpagev_t
3925                  * allocated by a previous call to this function.
3926                  */
3927                 if (saddr == seg->s_base) {
3928                         pagev = pr_pagev_create(seg, check_noreserve);
3929                         saddr = pr_pagev_fill(pagev, seg, saddr, eaddr);
3930 
3931                         ASSERT(*tmp == NULL);
3932                         *tmp = pagev;
3933 
3934                         ASSERT(saddr <= eaddr);
3935                         *saddrp = saddr;
3936 
3937                         if (saddr == eaddr) {
3938                                 naddr = saddr;
3939                                 prot = 0;
3940                                 goto out;
3941                         }
3942 
3943                 } else {
3944                         ASSERT(*tmp != NULL);
3945                         pagev = (prpagev_t *)*tmp;
3946                 }
3947 
3948                 naddr = pr_pagev_nextprot(pagev, seg, saddrp, eaddr, &prot);
3949                 ASSERT(naddr <= eaddr);
3950         }
3951 
3952 out:
3953         if (naddr == eaddr)
3954                 pr_getprot_done(tmp);
3955         *naddrp = naddr;
3956         return (prot);
3957 }
3958 
3959 void
3960 pr_getprot_done(void **tmp)
3961 {
3962         if (*tmp != NULL) {
3963                 pr_pagev_destroy((prpagev_t *)*tmp);
3964                 *tmp = NULL;
3965         }
3966 }
3967 
3968 /*
3969  * Return true iff the vnode is a /proc file from the object directory.
3970  */
3971 int
3972 pr_isobject(vnode_t *vp)
3973 {
3974         return (vn_matchops(vp, prvnodeops) && VTOP(vp)->pr_type == PR_OBJECT);
3975 }
3976 
3977 /*
3978  * Return true iff the vnode is a /proc file opened by the process itself.
3979  */
3980 int
3981 pr_isself(vnode_t *vp)
3982 {
3983         /*
3984          * XXX: To retain binary compatibility with the old
3985          * ioctl()-based version of /proc, we exempt self-opens
3986          * of /proc/<pid> from being marked close-on-exec.
3987          */
3988         return (vn_matchops(vp, prvnodeops) &&
3989             (VTOP(vp)->pr_flags & PR_ISSELF) &&
3990             VTOP(vp)->pr_type != PR_PIDDIR);
3991 }
3992 
3993 static ssize_t
3994 pr_getpagesize(struct seg *seg, caddr_t saddr, caddr_t *naddrp, caddr_t eaddr)
3995 {
3996         ssize_t pagesize, hatsize;
3997 
3998         ASSERT(AS_WRITE_HELD(seg->s_as));
3999         ASSERT(IS_P2ALIGNED(saddr, PAGESIZE));
4000         ASSERT(IS_P2ALIGNED(eaddr, PAGESIZE));
4001         ASSERT(saddr < eaddr);
4002 
4003         pagesize = hatsize = hat_getpagesize(seg->s_as->a_hat, saddr);
4004         ASSERT(pagesize == -1 || IS_P2ALIGNED(pagesize, pagesize));
4005         ASSERT(pagesize != 0);
4006 
4007         if (pagesize == -1)
4008                 pagesize = PAGESIZE;
4009 
4010         saddr += P2NPHASE((uintptr_t)saddr, pagesize);
4011 
4012         while (saddr < eaddr) {
4013                 if (hatsize != hat_getpagesize(seg->s_as->a_hat, saddr))
4014                         break;
4015                 ASSERT(IS_P2ALIGNED(saddr, pagesize));
4016                 saddr += pagesize;
4017         }
4018 
4019         *naddrp = ((saddr < eaddr) ? saddr : eaddr);
4020         return (hatsize);
4021 }
4022 
4023 /*
4024  * Return an array of structures with extended memory map information.
4025  * We allocate here; the caller must deallocate.
4026  */
4027 int
4028 prgetxmap(proc_t *p, list_t *iolhead)
4029 {
4030         struct as *as = p->p_as;
4031         prxmap_t *mp;
4032         struct seg *seg;
4033         struct seg *brkseg, *stkseg;
4034         struct vnode *vp;
4035         struct vattr vattr;
4036         uint_t prot;
4037 
4038         ASSERT(as != &kas && AS_WRITE_HELD(as));
4039 
4040         /*
4041          * Request an initial buffer size that doesn't waste memory
4042          * if the address space has only a small number of segments.
4043          */
4044         pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4045 
4046         if ((seg = AS_SEGFIRST(as)) == NULL)
4047                 return (0);
4048 
4049         brkseg = break_seg(p);
4050         stkseg = as_segat(as, prgetstackbase(p));
4051 
4052         do {
4053                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4054                 caddr_t saddr, naddr, baddr;
4055                 void *tmp = NULL;
4056                 ssize_t psz;
4057                 char *parr;
4058                 uint64_t npages;
4059                 uint64_t pagenum;
4060 
4061                 if ((seg->s_flags & S_HOLE) != 0) {
4062                         continue;
4063                 }
4064                 /*
4065                  * Segment loop part one: iterate from the base of the segment
4066                  * to its end, pausing at each address boundary (baddr) between
4067                  * ranges that have different virtual memory protections.
4068                  */
4069                 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4070                         prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4071                         ASSERT(baddr >= saddr && baddr <= eaddr);
4072 
4073                         /*
4074                          * Segment loop part two: iterate from the current
4075                          * position to the end of the protection boundary,
4076                          * pausing at each address boundary (naddr) between
4077                          * ranges that have different underlying page sizes.
4078                          */
4079                         for (; saddr < baddr; saddr = naddr) {
4080                                 psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4081                                 ASSERT(naddr >= saddr && naddr <= baddr);
4082 
4083                                 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4084 
4085                                 mp->pr_vaddr = (uintptr_t)saddr;
4086                                 mp->pr_size = naddr - saddr;
4087                                 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4088                                 mp->pr_mflags = 0;
4089                                 if (prot & PROT_READ)
4090                                         mp->pr_mflags |= MA_READ;
4091                                 if (prot & PROT_WRITE)
4092                                         mp->pr_mflags |= MA_WRITE;
4093                                 if (prot & PROT_EXEC)
4094                                         mp->pr_mflags |= MA_EXEC;
4095                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4096                                         mp->pr_mflags |= MA_SHARED;
4097                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4098                                         mp->pr_mflags |= MA_NORESERVE;
4099                                 if (seg->s_ops == &segspt_shmops ||
4100                                     (seg->s_ops == &segvn_ops &&
4101                                     (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4102                                     vp == NULL)))
4103                                         mp->pr_mflags |= MA_ANON;
4104                                 if (seg == brkseg)
4105                                         mp->pr_mflags |= MA_BREAK;
4106                                 else if (seg == stkseg)
4107                                         mp->pr_mflags |= MA_STACK;
4108                                 if (seg->s_ops == &segspt_shmops)
4109                                         mp->pr_mflags |= MA_ISM | MA_SHM;
4110 
4111                                 mp->pr_pagesize = PAGESIZE;
4112                                 if (psz == -1) {
4113                                         mp->pr_hatpagesize = 0;
4114                                 } else {
4115                                         mp->pr_hatpagesize = psz;
4116                                 }
4117 
4118                                 /*
4119                                  * Manufacture a filename for the "object" dir.
4120                                  */
4121                                 mp->pr_dev = PRNODEV;
4122                                 vattr.va_mask = AT_FSID|AT_NODEID;
4123                                 if (seg->s_ops == &segvn_ops &&
4124                                     SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4125                                     vp != NULL && vp->v_type == VREG &&
4126                                     VOP_GETATTR(vp, &vattr, 0, CRED(),
4127                                     NULL) == 0) {
4128                                         mp->pr_dev = vattr.va_fsid;
4129                                         mp->pr_ino = vattr.va_nodeid;
4130                                         if (vp == p->p_exec)
4131                                                 (void) strcpy(mp->pr_mapname,
4132                                                     "a.out");
4133                                         else
4134                                                 pr_object_name(mp->pr_mapname,
4135                                                     vp, &vattr);
4136                                 }
4137 
4138                                 /*
4139                                  * Get the SysV shared memory id, if any.
4140                                  */
4141                                 if ((mp->pr_mflags & MA_SHARED) &&
4142                                     p->p_segacct && (mp->pr_shmid = shmgetid(p,
4143                                     seg->s_base)) != SHMID_NONE) {
4144                                         if (mp->pr_shmid == SHMID_FREE)
4145                                                 mp->pr_shmid = -1;
4146 
4147                                         mp->pr_mflags |= MA_SHM;
4148                                 } else {
4149                                         mp->pr_shmid = -1;
4150                                 }
4151 
4152                                 npages = ((uintptr_t)(naddr - saddr)) >>
4153                                     PAGESHIFT;
4154                                 parr = kmem_zalloc(npages, KM_SLEEP);
4155 
4156                                 SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4157 
4158                                 for (pagenum = 0; pagenum < npages; pagenum++) {
4159                                         if (parr[pagenum] & SEG_PAGE_INCORE)
4160                                                 mp->pr_rss++;
4161                                         if (parr[pagenum] & SEG_PAGE_ANON)
4162                                                 mp->pr_anon++;
4163                                         if (parr[pagenum] & SEG_PAGE_LOCKED)
4164                                                 mp->pr_locked++;
4165                                 }
4166                                 kmem_free(parr, npages);
4167                         }
4168                 }
4169                 ASSERT(tmp == NULL);
4170         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4171 
4172         return (0);
4173 }
4174 
4175 /*
4176  * Return the process's credentials.  We don't need a 32-bit equivalent of
4177  * this function because prcred_t and prcred32_t are actually the same.
4178  */
4179 void
4180 prgetcred(proc_t *p, prcred_t *pcrp)
4181 {
4182         mutex_enter(&p->p_crlock);
4183         cred2prcred(p->p_cred, pcrp);
4184         mutex_exit(&p->p_crlock);
4185 }
4186 
4187 void
4188 prgetsecflags(proc_t *p, prsecflags_t *psfp)
4189 {
4190         ASSERT(psfp != NULL);
4191 
4192         psfp->pr_version = PRSECFLAGS_VERSION_CURRENT;
4193         psfp->pr_lower = p->p_secflags.psf_lower;
4194         psfp->pr_upper = p->p_secflags.psf_upper;
4195         psfp->pr_effective = p->p_secflags.psf_effective;
4196         psfp->pr_inherit = p->p_secflags.psf_inherit;
4197 }
4198 
4199 /*
4200  * Compute actual size of the prpriv_t structure.
4201  */
4202 
4203 size_t
4204 prgetprivsize(void)
4205 {
4206         return (priv_prgetprivsize(NULL));
4207 }
4208 
4209 /*
4210  * Return the process's privileges.  We don't need a 32-bit equivalent of
4211  * this function because prpriv_t and prpriv32_t are actually the same.
4212  */
4213 void
4214 prgetpriv(proc_t *p, prpriv_t *pprp)
4215 {
4216         mutex_enter(&p->p_crlock);
4217         cred2prpriv(p->p_cred, pprp);
4218         mutex_exit(&p->p_crlock);
4219 }
4220 
4221 #ifdef _SYSCALL32_IMPL
4222 /*
4223  * Return an array of structures with HAT memory map information.
4224  * We allocate here; the caller must deallocate.
4225  */
4226 int
4227 prgetxmap32(proc_t *p, list_t *iolhead)
4228 {
4229         struct as *as = p->p_as;
4230         prxmap32_t *mp;
4231         struct seg *seg;
4232         struct seg *brkseg, *stkseg;
4233         struct vnode *vp;
4234         struct vattr vattr;
4235         uint_t prot;
4236 
4237         ASSERT(as != &kas && AS_WRITE_HELD(as));
4238 
4239         /*
4240          * Request an initial buffer size that doesn't waste memory
4241          * if the address space has only a small number of segments.
4242          */
4243         pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4244 
4245         if ((seg = AS_SEGFIRST(as)) == NULL)
4246                 return (0);
4247 
4248         brkseg = break_seg(p);
4249         stkseg = as_segat(as, prgetstackbase(p));
4250 
4251         do {
4252                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4253                 caddr_t saddr, naddr, baddr;
4254                 void *tmp = NULL;
4255                 ssize_t psz;
4256                 char *parr;
4257                 uint64_t npages;
4258                 uint64_t pagenum;
4259 
4260                 if ((seg->s_flags & S_HOLE) != 0) {
4261                         continue;
4262                 }
4263 
4264                 /*
4265                  * Segment loop part one: iterate from the base of the segment
4266                  * to its end, pausing at each address boundary (baddr) between
4267                  * ranges that have different virtual memory protections.
4268                  */
4269                 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4270                         prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4271                         ASSERT(baddr >= saddr && baddr <= eaddr);
4272 
4273                         /*
4274                          * Segment loop part two: iterate from the current
4275                          * position to the end of the protection boundary,
4276                          * pausing at each address boundary (naddr) between
4277                          * ranges that have different underlying page sizes.
4278                          */
4279                         for (; saddr < baddr; saddr = naddr) {
4280                                 psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4281                                 ASSERT(naddr >= saddr && naddr <= baddr);
4282 
4283                                 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4284 
4285                                 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
4286                                 mp->pr_size = (size32_t)(naddr - saddr);
4287                                 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4288                                 mp->pr_mflags = 0;
4289                                 if (prot & PROT_READ)
4290                                         mp->pr_mflags |= MA_READ;
4291                                 if (prot & PROT_WRITE)
4292                                         mp->pr_mflags |= MA_WRITE;
4293                                 if (prot & PROT_EXEC)
4294                                         mp->pr_mflags |= MA_EXEC;
4295                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4296                                         mp->pr_mflags |= MA_SHARED;
4297                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4298                                         mp->pr_mflags |= MA_NORESERVE;
4299                                 if (seg->s_ops == &segspt_shmops ||
4300                                     (seg->s_ops == &segvn_ops &&
4301                                     (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4302                                     vp == NULL)))
4303                                         mp->pr_mflags |= MA_ANON;
4304                                 if (seg == brkseg)
4305                                         mp->pr_mflags |= MA_BREAK;
4306                                 else if (seg == stkseg)
4307                                         mp->pr_mflags |= MA_STACK;
4308                                 if (seg->s_ops == &segspt_shmops)
4309                                         mp->pr_mflags |= MA_ISM | MA_SHM;
4310 
4311                                 mp->pr_pagesize = PAGESIZE;
4312                                 if (psz == -1) {
4313                                         mp->pr_hatpagesize = 0;
4314                                 } else {
4315                                         mp->pr_hatpagesize = psz;
4316                                 }
4317 
4318                                 /*
4319                                  * Manufacture a filename for the "object" dir.
4320                                  */
4321                                 mp->pr_dev = PRNODEV32;
4322                                 vattr.va_mask = AT_FSID|AT_NODEID;
4323                                 if (seg->s_ops == &segvn_ops &&
4324                                     SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4325                                     vp != NULL && vp->v_type == VREG &&
4326                                     VOP_GETATTR(vp, &vattr, 0, CRED(),
4327                                     NULL) == 0) {
4328                                         (void) cmpldev(&mp->pr_dev,
4329                                             vattr.va_fsid);
4330                                         mp->pr_ino = vattr.va_nodeid;
4331                                         if (vp == p->p_exec)
4332                                                 (void) strcpy(mp->pr_mapname,
4333                                                     "a.out");
4334                                         else
4335                                                 pr_object_name(mp->pr_mapname,
4336                                                     vp, &vattr);
4337                                 }
4338 
4339                                 /*
4340                                  * Get the SysV shared memory id, if any.
4341                                  */
4342                                 if ((mp->pr_mflags & MA_SHARED) &&
4343                                     p->p_segacct && (mp->pr_shmid = shmgetid(p,
4344                                     seg->s_base)) != SHMID_NONE) {
4345                                         if (mp->pr_shmid == SHMID_FREE)
4346                                                 mp->pr_shmid = -1;
4347 
4348                                         mp->pr_mflags |= MA_SHM;
4349                                 } else {
4350                                         mp->pr_shmid = -1;
4351                                 }
4352 
4353                                 npages = ((uintptr_t)(naddr - saddr)) >>
4354                                     PAGESHIFT;
4355                                 parr = kmem_zalloc(npages, KM_SLEEP);
4356 
4357                                 SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4358 
4359                                 for (pagenum = 0; pagenum < npages; pagenum++) {
4360                                         if (parr[pagenum] & SEG_PAGE_INCORE)
4361                                                 mp->pr_rss++;
4362                                         if (parr[pagenum] & SEG_PAGE_ANON)
4363                                                 mp->pr_anon++;
4364                                         if (parr[pagenum] & SEG_PAGE_LOCKED)
4365                                                 mp->pr_locked++;
4366                                 }
4367                                 kmem_free(parr, npages);
4368                         }
4369                 }
4370                 ASSERT(tmp == NULL);
4371         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4372 
4373         return (0);
4374 }
4375 #endif  /* _SYSCALL32_IMPL */