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         THREAD_KPRI_REQUEST();
 707         return (p);
 708 }
 709 
 710 /*
 711  * Lock the target process by setting P_PR_LOCK and grabbing p->p_lock.
 712  * This prevents any lwp of the process from disappearing and
 713  * blocks most operations that a process can perform on itself.
 714  * Returns 0 on success, a non-zero error number on failure.
 715  *
 716  * 'zdisp' is ZYES or ZNO to indicate whether prlock() should succeed when
 717  * the subject process is a zombie (ZYES) or fail for zombies (ZNO).
 718  *
 719  * error returns:
 720  *      ENOENT: process or lwp has disappeared or process is exiting
 721  *              (or has become a zombie and zdisp == ZNO).
 722  *      EAGAIN: procfs vnode has become invalid.
 723  *      EINTR:  signal arrived while waiting for exec to complete.
 724  */
 725 int
 726 prlock(prnode_t *pnp, int zdisp)
 727 {
 728         prcommon_t *pcp;
 729         proc_t *p;
 730 
 731 again:
 732         pcp = pnp->pr_common;
 733         p = pr_p_lock(pnp);
 734         mutex_exit(&pr_pidlock);
 735 
 736         /*
 737          * Return ENOENT immediately if there is no process.
 738          */
 739         if (p == NULL)
 740                 return (ENOENT);
 741 
 742         ASSERT(p == pcp->prc_proc && p->p_stat != 0 && p->p_stat != SIDL);
 743 
 744         /*
 745          * Return ENOENT if process entered zombie state or is exiting
 746          * and the 'zdisp' flag is set to ZNO indicating not to lock zombies.
 747          */
 748         if (zdisp == ZNO &&
 749             ((pcp->prc_flags & PRC_DESTROY) || (p->p_flag & SEXITING))) {
 750                 prunlock(pnp);
 751                 return (ENOENT);
 752         }
 753 
 754         /*
 755          * If lwp-specific, check to see if lwp has disappeared.
 756          */
 757         if (pcp->prc_flags & PRC_LWP) {
 758                 if ((zdisp == ZNO && (pcp->prc_flags & PRC_DESTROY)) ||
 759                     pcp->prc_tslot == -1) {
 760                         prunlock(pnp);
 761                         return (ENOENT);
 762                 }
 763         }
 764 
 765         /*
 766          * Return EAGAIN if we have encountered a security violation.
 767          * (The process exec'd a set-id or unreadable executable file.)
 768          */
 769         if (pnp->pr_flags & PR_INVAL) {
 770                 prunlock(pnp);
 771                 return (EAGAIN);
 772         }
 773 
 774         /*
 775          * If process is undergoing an exec(), wait for
 776          * completion and then start all over again.
 777          */
 778         if (p->p_proc_flag & P_PR_EXEC) {
 779                 pcp = pnp->pr_pcommon;       /* Put on the correct sleep queue */
 780                 mutex_enter(&pcp->prc_mutex);
 781                 prunlock(pnp);
 782                 if (!cv_wait_sig(&pcp->prc_wait, &pcp->prc_mutex)) {
 783                         mutex_exit(&pcp->prc_mutex);
 784                         return (EINTR);
 785                 }
 786                 mutex_exit(&pcp->prc_mutex);
 787                 goto again;
 788         }
 789 
 790         /*
 791          * We return holding p->p_lock.
 792          */
 793         return (0);
 794 }
 795 
 796 /*
 797  * Undo prlock() and pr_p_lock().
 798  * p->p_lock is still held; pr_pidlock is no longer held.
 799  *
 800  * prunmark() drops the P_PR_LOCK flag and wakes up another thread,
 801  * if any, waiting for the flag to be dropped; it retains p->p_lock.
 802  *
 803  * prunlock() calls prunmark() and then drops p->p_lock.
 804  */
 805 void
 806 prunmark(proc_t *p)
 807 {
 808         ASSERT(p->p_proc_flag & P_PR_LOCK);
 809         ASSERT(MUTEX_HELD(&p->p_lock));
 810 
 811         cv_signal(&pr_pid_cv[p->p_slot]);
 812         p->p_proc_flag &= ~P_PR_LOCK;
 813         THREAD_KPRI_RELEASE();
 814 }
 815 
 816 void
 817 prunlock(prnode_t *pnp)
 818 {
 819         prcommon_t *pcp = pnp->pr_common;
 820         proc_t *p = pcp->prc_proc;
 821 
 822         /*
 823          * If we (or someone) gave it a SIGKILL, and it is not
 824          * already a zombie, set it running unconditionally.
 825          */
 826         if ((p->p_flag & SKILLED) &&
 827             !(p->p_flag & SEXITING) &&
 828             !(pcp->prc_flags & PRC_DESTROY) &&
 829             !((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot == -1))
 830                 (void) pr_setrun(pnp, 0);
 831         prunmark(p);
 832         mutex_exit(&p->p_lock);
 833 }
 834 
 835 /*
 836  * Called while holding p->p_lock to delay until the process is unlocked.
 837  * We enter holding p->p_lock; p->p_lock is dropped and reacquired.
 838  * The process cannot become locked again until p->p_lock is dropped.
 839  */
 840 void
 841 prbarrier(proc_t *p)
 842 {
 843         ASSERT(MUTEX_HELD(&p->p_lock));
 844 
 845         if (p->p_proc_flag & P_PR_LOCK) {
 846                 /* The process is locked; delay until not locked */
 847                 uint_t slot = p->p_slot;
 848 
 849                 while (p->p_proc_flag & P_PR_LOCK)
 850                         cv_wait(&pr_pid_cv[slot], &p->p_lock);
 851                 cv_signal(&pr_pid_cv[slot]);
 852         }
 853 }
 854 
 855 /*
 856  * Return process/lwp status.
 857  * The u-block is mapped in by this routine and unmapped at the end.
 858  */
 859 void
 860 prgetstatus(proc_t *p, pstatus_t *sp, zone_t *zp)
 861 {
 862         kthread_t *t;
 863 
 864         ASSERT(MUTEX_HELD(&p->p_lock));
 865 
 866         t = prchoose(p);        /* returns locked thread */
 867         ASSERT(t != NULL);
 868         thread_unlock(t);
 869 
 870         /* just bzero the process part, prgetlwpstatus() does the rest */
 871         bzero(sp, sizeof (pstatus_t) - sizeof (lwpstatus_t));
 872         sp->pr_nlwp = p->p_lwpcnt;
 873         sp->pr_nzomb = p->p_zombcnt;
 874         prassignset(&sp->pr_sigpend, &p->p_sig);
 875         sp->pr_brkbase = (uintptr_t)p->p_brkbase;
 876         sp->pr_brksize = p->p_brksize;
 877         sp->pr_stkbase = (uintptr_t)prgetstackbase(p);
 878         sp->pr_stksize = p->p_stksize;
 879         sp->pr_pid = p->p_pid;
 880         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
 881             (p->p_flag & SZONETOP)) {
 882                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
 883                 /*
 884                  * Inside local zones, fake zsched's pid as parent pids for
 885                  * processes which reference processes outside of the zone.
 886                  */
 887                 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
 888         } else {
 889                 sp->pr_ppid = p->p_ppid;
 890         }
 891         sp->pr_pgid  = p->p_pgrp;
 892         sp->pr_sid   = p->p_sessp->s_sid;
 893         sp->pr_taskid = p->p_task->tk_tkid;
 894         sp->pr_projid = p->p_task->tk_proj->kpj_id;
 895         sp->pr_zoneid = p->p_zone->zone_id;
 896         bcopy(&p->p_secflags, &sp->pr_secflags, sizeof (psecflags_t));
 897         hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
 898         hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
 899         TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime);
 900         TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime);
 901         prassignset(&sp->pr_sigtrace, &p->p_sigmask);
 902         prassignset(&sp->pr_flttrace, &p->p_fltmask);
 903         prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
 904         prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
 905         switch (p->p_model) {
 906         case DATAMODEL_ILP32:
 907                 sp->pr_dmodel = PR_MODEL_ILP32;
 908                 break;
 909         case DATAMODEL_LP64:
 910                 sp->pr_dmodel = PR_MODEL_LP64;
 911                 break;
 912         }
 913         if (p->p_agenttp)
 914                 sp->pr_agentid = p->p_agenttp->t_tid;
 915 
 916         /* get the chosen lwp's status */
 917         prgetlwpstatus(t, &sp->pr_lwp, zp);
 918 
 919         /* replicate the flags */
 920         sp->pr_flags = sp->pr_lwp.pr_flags;
 921 }
 922 
 923 #ifdef _SYSCALL32_IMPL
 924 void
 925 prgetlwpstatus32(kthread_t *t, lwpstatus32_t *sp, zone_t *zp)
 926 {
 927         proc_t *p = ttoproc(t);
 928         klwp_t *lwp = ttolwp(t);
 929         struct mstate *ms = &lwp->lwp_mstate;
 930         hrtime_t usr, sys;
 931         int flags;
 932         ulong_t instr;
 933 
 934         ASSERT(MUTEX_HELD(&p->p_lock));
 935 
 936         bzero(sp, sizeof (*sp));
 937         flags = 0L;
 938         if (t->t_state == TS_STOPPED) {
 939                 flags |= PR_STOPPED;
 940                 if ((t->t_schedflag & TS_PSTART) == 0)
 941                         flags |= PR_ISTOP;
 942         } else if (VSTOPPED(t)) {
 943                 flags |= PR_STOPPED|PR_ISTOP;
 944         }
 945         if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
 946                 flags |= PR_DSTOP;
 947         if (lwp->lwp_asleep)
 948                 flags |= PR_ASLEEP;
 949         if (t == p->p_agenttp)
 950                 flags |= PR_AGENT;
 951         if (!(t->t_proc_flag & TP_TWAIT))
 952                 flags |= PR_DETACH;
 953         if (t->t_proc_flag & TP_DAEMON)
 954                 flags |= PR_DAEMON;
 955         if (p->p_proc_flag & P_PR_FORK)
 956                 flags |= PR_FORK;
 957         if (p->p_proc_flag & P_PR_RUNLCL)
 958                 flags |= PR_RLC;
 959         if (p->p_proc_flag & P_PR_KILLCL)
 960                 flags |= PR_KLC;
 961         if (p->p_proc_flag & P_PR_ASYNC)
 962                 flags |= PR_ASYNC;
 963         if (p->p_proc_flag & P_PR_BPTADJ)
 964                 flags |= PR_BPTADJ;
 965         if (p->p_proc_flag & P_PR_PTRACE)
 966                 flags |= PR_PTRACE;
 967         if (p->p_flag & SMSACCT)
 968                 flags |= PR_MSACCT;
 969         if (p->p_flag & SMSFORK)
 970                 flags |= PR_MSFORK;
 971         if (p->p_flag & SVFWAIT)
 972                 flags |= PR_VFORKP;
 973         sp->pr_flags = flags;
 974         if (VSTOPPED(t)) {
 975                 sp->pr_why   = PR_REQUESTED;
 976                 sp->pr_what  = 0;
 977         } else {
 978                 sp->pr_why   = t->t_whystop;
 979                 sp->pr_what  = t->t_whatstop;
 980         }
 981         sp->pr_lwpid = t->t_tid;
 982         sp->pr_cursig  = lwp->lwp_cursig;
 983         prassignset(&sp->pr_lwppend, &t->t_sig);
 984         schedctl_finish_sigblock(t);
 985         prassignset(&sp->pr_lwphold, &t->t_hold);
 986         if (t->t_whystop == PR_FAULTED) {
 987                 siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info);
 988                 if (t->t_whatstop == FLTPAGE)
 989                         sp->pr_info.si_addr =
 990                             (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr;
 991         } else if (lwp->lwp_curinfo)
 992                 siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info);
 993         if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
 994             sp->pr_info.si_zoneid != zp->zone_id) {
 995                 sp->pr_info.si_pid = zp->zone_zsched->p_pid;
 996                 sp->pr_info.si_uid = 0;
 997                 sp->pr_info.si_ctid = -1;
 998                 sp->pr_info.si_zoneid = zp->zone_id;
 999         }
1000         sp->pr_altstack.ss_sp =
1001             (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp;
1002         sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size;
1003         sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags;
1004         prgetaction32(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1005         sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext;
1006         sp->pr_ustack = (caddr32_t)lwp->lwp_ustack;
1007         (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1008             sizeof (sp->pr_clname) - 1);
1009         if (flags & PR_STOPPED)
1010                 hrt2ts32(t->t_stoptime, &sp->pr_tstamp);
1011         usr = ms->ms_acct[LMS_USER];
1012         sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1013         scalehrtime(&usr);
1014         scalehrtime(&sys);
1015         hrt2ts32(usr, &sp->pr_utime);
1016         hrt2ts32(sys, &sp->pr_stime);
1017 
1018         /*
1019          * Fetch the current instruction, if not a system process.
1020          * We don't attempt this unless the lwp is stopped.
1021          */
1022         if ((p->p_flag & SSYS) || p->p_as == &kas)
1023                 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1024         else if (!(flags & PR_STOPPED))
1025                 sp->pr_flags |= PR_PCINVAL;
1026         else if (!prfetchinstr(lwp, &instr))
1027                 sp->pr_flags |= PR_PCINVAL;
1028         else
1029                 sp->pr_instr = (uint32_t)instr;
1030 
1031         /*
1032          * Drop p_lock while touching the lwp's stack.
1033          */
1034         mutex_exit(&p->p_lock);
1035         if (prisstep(lwp))
1036                 sp->pr_flags |= PR_STEP;
1037         if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1038                 int i;
1039 
1040                 sp->pr_syscall = get_syscall32_args(lwp,
1041                     (int *)sp->pr_sysarg, &i);
1042                 sp->pr_nsysarg = (ushort_t)i;
1043         }
1044         if ((flags & PR_STOPPED) || t == curthread)
1045                 prgetprregs32(lwp, sp->pr_reg);
1046         if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1047             (flags & PR_VFORKP)) {
1048                 long r1, r2;
1049                 user_t *up;
1050                 auxv_t *auxp;
1051                 int i;
1052 
1053                 sp->pr_errno = prgetrvals(lwp, &r1, &r2);
1054                 if (sp->pr_errno == 0) {
1055                         sp->pr_rval1 = (int32_t)r1;
1056                         sp->pr_rval2 = (int32_t)r2;
1057                         sp->pr_errpriv = PRIV_NONE;
1058                 } else
1059                         sp->pr_errpriv = lwp->lwp_badpriv;
1060 
1061                 if (t->t_sysnum == SYS_execve) {
1062                         up = PTOU(p);
1063                         sp->pr_sysarg[0] = 0;
1064                         sp->pr_sysarg[1] = (caddr32_t)up->u_argv;
1065                         sp->pr_sysarg[2] = (caddr32_t)up->u_envp;
1066                         for (i = 0, auxp = up->u_auxv;
1067                             i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1068                             i++, auxp++) {
1069                                 if (auxp->a_type == AT_SUN_EXECNAME) {
1070                                         sp->pr_sysarg[0] =
1071                                             (caddr32_t)
1072                                             (uintptr_t)auxp->a_un.a_ptr;
1073                                         break;
1074                                 }
1075                         }
1076                 }
1077         }
1078         if (prhasfp())
1079                 prgetprfpregs32(lwp, &sp->pr_fpreg);
1080         mutex_enter(&p->p_lock);
1081 }
1082 
1083 void
1084 prgetstatus32(proc_t *p, pstatus32_t *sp, zone_t *zp)
1085 {
1086         kthread_t *t;
1087 
1088         ASSERT(MUTEX_HELD(&p->p_lock));
1089 
1090         t = prchoose(p);        /* returns locked thread */
1091         ASSERT(t != NULL);
1092         thread_unlock(t);
1093 
1094         /* just bzero the process part, prgetlwpstatus32() does the rest */
1095         bzero(sp, sizeof (pstatus32_t) - sizeof (lwpstatus32_t));
1096         sp->pr_nlwp = p->p_lwpcnt;
1097         sp->pr_nzomb = p->p_zombcnt;
1098         prassignset(&sp->pr_sigpend, &p->p_sig);
1099         sp->pr_brkbase = (uint32_t)(uintptr_t)p->p_brkbase;
1100         sp->pr_brksize = (uint32_t)p->p_brksize;
1101         sp->pr_stkbase = (uint32_t)(uintptr_t)prgetstackbase(p);
1102         sp->pr_stksize = (uint32_t)p->p_stksize;
1103         sp->pr_pid   = p->p_pid;
1104         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
1105             (p->p_flag & SZONETOP)) {
1106                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
1107                 /*
1108                  * Inside local zones, fake zsched's pid as parent pids for
1109                  * processes which reference processes outside of the zone.
1110                  */
1111                 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
1112         } else {
1113                 sp->pr_ppid = p->p_ppid;
1114         }
1115         sp->pr_pgid  = p->p_pgrp;
1116         sp->pr_sid   = p->p_sessp->s_sid;
1117         sp->pr_taskid = p->p_task->tk_tkid;
1118         sp->pr_projid = p->p_task->tk_proj->kpj_id;
1119         sp->pr_zoneid = p->p_zone->zone_id;
1120         bcopy(&p->p_secflags, &sp->pr_secflags, sizeof (psecflags_t));
1121         hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
1122         hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
1123         TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime);
1124         TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime);
1125         prassignset(&sp->pr_sigtrace, &p->p_sigmask);
1126         prassignset(&sp->pr_flttrace, &p->p_fltmask);
1127         prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
1128         prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
1129         switch (p->p_model) {
1130         case DATAMODEL_ILP32:
1131                 sp->pr_dmodel = PR_MODEL_ILP32;
1132                 break;
1133         case DATAMODEL_LP64:
1134                 sp->pr_dmodel = PR_MODEL_LP64;
1135                 break;
1136         }
1137         if (p->p_agenttp)
1138                 sp->pr_agentid = p->p_agenttp->t_tid;
1139 
1140         /* get the chosen lwp's status */
1141         prgetlwpstatus32(t, &sp->pr_lwp, zp);
1142 
1143         /* replicate the flags */
1144         sp->pr_flags = sp->pr_lwp.pr_flags;
1145 }
1146 #endif  /* _SYSCALL32_IMPL */
1147 
1148 /*
1149  * Return lwp status.
1150  */
1151 void
1152 prgetlwpstatus(kthread_t *t, lwpstatus_t *sp, zone_t *zp)
1153 {
1154         proc_t *p = ttoproc(t);
1155         klwp_t *lwp = ttolwp(t);
1156         struct mstate *ms = &lwp->lwp_mstate;
1157         hrtime_t usr, sys;
1158         int flags;
1159         ulong_t instr;
1160 
1161         ASSERT(MUTEX_HELD(&p->p_lock));
1162 
1163         bzero(sp, sizeof (*sp));
1164         flags = 0L;
1165         if (t->t_state == TS_STOPPED) {
1166                 flags |= PR_STOPPED;
1167                 if ((t->t_schedflag & TS_PSTART) == 0)
1168                         flags |= PR_ISTOP;
1169         } else if (VSTOPPED(t)) {
1170                 flags |= PR_STOPPED|PR_ISTOP;
1171         }
1172         if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
1173                 flags |= PR_DSTOP;
1174         if (lwp->lwp_asleep)
1175                 flags |= PR_ASLEEP;
1176         if (t == p->p_agenttp)
1177                 flags |= PR_AGENT;
1178         if (!(t->t_proc_flag & TP_TWAIT))
1179                 flags |= PR_DETACH;
1180         if (t->t_proc_flag & TP_DAEMON)
1181                 flags |= PR_DAEMON;
1182         if (p->p_proc_flag & P_PR_FORK)
1183                 flags |= PR_FORK;
1184         if (p->p_proc_flag & P_PR_RUNLCL)
1185                 flags |= PR_RLC;
1186         if (p->p_proc_flag & P_PR_KILLCL)
1187                 flags |= PR_KLC;
1188         if (p->p_proc_flag & P_PR_ASYNC)
1189                 flags |= PR_ASYNC;
1190         if (p->p_proc_flag & P_PR_BPTADJ)
1191                 flags |= PR_BPTADJ;
1192         if (p->p_proc_flag & P_PR_PTRACE)
1193                 flags |= PR_PTRACE;
1194         if (p->p_flag & SMSACCT)
1195                 flags |= PR_MSACCT;
1196         if (p->p_flag & SMSFORK)
1197                 flags |= PR_MSFORK;
1198         if (p->p_flag & SVFWAIT)
1199                 flags |= PR_VFORKP;
1200         if (p->p_pgidp->pid_pgorphaned)
1201                 flags |= PR_ORPHAN;
1202         if (p->p_pidflag & CLDNOSIGCHLD)
1203                 flags |= PR_NOSIGCHLD;
1204         if (p->p_pidflag & CLDWAITPID)
1205                 flags |= PR_WAITPID;
1206         sp->pr_flags = flags;
1207         if (VSTOPPED(t)) {
1208                 sp->pr_why   = PR_REQUESTED;
1209                 sp->pr_what  = 0;
1210         } else {
1211                 sp->pr_why   = t->t_whystop;
1212                 sp->pr_what  = t->t_whatstop;
1213         }
1214         sp->pr_lwpid = t->t_tid;
1215         sp->pr_cursig  = lwp->lwp_cursig;
1216         prassignset(&sp->pr_lwppend, &t->t_sig);
1217         schedctl_finish_sigblock(t);
1218         prassignset(&sp->pr_lwphold, &t->t_hold);
1219         if (t->t_whystop == PR_FAULTED)
1220                 bcopy(&lwp->lwp_siginfo,
1221                     &sp->pr_info, sizeof (k_siginfo_t));
1222         else if (lwp->lwp_curinfo)
1223                 bcopy(&lwp->lwp_curinfo->sq_info,
1224                     &sp->pr_info, sizeof (k_siginfo_t));
1225         if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
1226             sp->pr_info.si_zoneid != zp->zone_id) {
1227                 sp->pr_info.si_pid = zp->zone_zsched->p_pid;
1228                 sp->pr_info.si_uid = 0;
1229                 sp->pr_info.si_ctid = -1;
1230                 sp->pr_info.si_zoneid = zp->zone_id;
1231         }
1232         sp->pr_altstack = lwp->lwp_sigaltstack;
1233         prgetaction(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1234         sp->pr_oldcontext = (uintptr_t)lwp->lwp_oldcontext;
1235         sp->pr_ustack = lwp->lwp_ustack;
1236         (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1237             sizeof (sp->pr_clname) - 1);
1238         if (flags & PR_STOPPED)
1239                 hrt2ts(t->t_stoptime, &sp->pr_tstamp);
1240         usr = ms->ms_acct[LMS_USER];
1241         sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1242         scalehrtime(&usr);
1243         scalehrtime(&sys);
1244         hrt2ts(usr, &sp->pr_utime);
1245         hrt2ts(sys, &sp->pr_stime);
1246 
1247         /*
1248          * Fetch the current instruction, if not a system process.
1249          * We don't attempt this unless the lwp is stopped.
1250          */
1251         if ((p->p_flag & SSYS) || p->p_as == &kas)
1252                 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1253         else if (!(flags & PR_STOPPED))
1254                 sp->pr_flags |= PR_PCINVAL;
1255         else if (!prfetchinstr(lwp, &instr))
1256                 sp->pr_flags |= PR_PCINVAL;
1257         else
1258                 sp->pr_instr = instr;
1259 
1260         /*
1261          * Drop p_lock while touching the lwp's stack.
1262          */
1263         mutex_exit(&p->p_lock);
1264         if (prisstep(lwp))
1265                 sp->pr_flags |= PR_STEP;
1266         if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1267                 int i;
1268 
1269                 sp->pr_syscall = get_syscall_args(lwp,
1270                     (long *)sp->pr_sysarg, &i);
1271                 sp->pr_nsysarg = (ushort_t)i;
1272         }
1273         if ((flags & PR_STOPPED) || t == curthread)
1274                 prgetprregs(lwp, sp->pr_reg);
1275         if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1276             (flags & PR_VFORKP)) {
1277                 user_t *up;
1278                 auxv_t *auxp;
1279                 int i;
1280 
1281                 sp->pr_errno = prgetrvals(lwp, &sp->pr_rval1, &sp->pr_rval2);
1282                 if (sp->pr_errno == 0)
1283                         sp->pr_errpriv = PRIV_NONE;
1284                 else
1285                         sp->pr_errpriv = lwp->lwp_badpriv;
1286 
1287                 if (t->t_sysnum == SYS_execve) {
1288                         up = PTOU(p);
1289                         sp->pr_sysarg[0] = 0;
1290                         sp->pr_sysarg[1] = (uintptr_t)up->u_argv;
1291                         sp->pr_sysarg[2] = (uintptr_t)up->u_envp;
1292                         for (i = 0, auxp = up->u_auxv;
1293                             i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1294                             i++, auxp++) {
1295                                 if (auxp->a_type == AT_SUN_EXECNAME) {
1296                                         sp->pr_sysarg[0] =
1297                                             (uintptr_t)auxp->a_un.a_ptr;
1298                                         break;
1299                                 }
1300                         }
1301                 }
1302         }
1303         if (prhasfp())
1304                 prgetprfpregs(lwp, &sp->pr_fpreg);
1305         mutex_enter(&p->p_lock);
1306 }
1307 
1308 /*
1309  * Get the sigaction structure for the specified signal.  The u-block
1310  * must already have been mapped in by the caller.
1311  */
1312 void
1313 prgetaction(proc_t *p, user_t *up, uint_t sig, struct sigaction *sp)
1314 {
1315         int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1316 
1317         bzero(sp, sizeof (*sp));
1318 
1319         if (sig != 0 && (unsigned)sig < nsig) {
1320                 sp->sa_handler = up->u_signal[sig-1];
1321                 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1322                 if (sigismember(&up->u_sigonstack, sig))
1323                         sp->sa_flags |= SA_ONSTACK;
1324                 if (sigismember(&up->u_sigresethand, sig))
1325                         sp->sa_flags |= SA_RESETHAND;
1326                 if (sigismember(&up->u_sigrestart, sig))
1327                         sp->sa_flags |= SA_RESTART;
1328                 if (sigismember(&p->p_siginfo, sig))
1329                         sp->sa_flags |= SA_SIGINFO;
1330                 if (sigismember(&up->u_signodefer, sig))
1331                         sp->sa_flags |= SA_NODEFER;
1332                 if (sig == SIGCLD) {
1333                         if (p->p_flag & SNOWAIT)
1334                                 sp->sa_flags |= SA_NOCLDWAIT;
1335                         if ((p->p_flag & SJCTL) == 0)
1336                                 sp->sa_flags |= SA_NOCLDSTOP;
1337                 }
1338         }
1339 }
1340 
1341 #ifdef _SYSCALL32_IMPL
1342 void
1343 prgetaction32(proc_t *p, user_t *up, uint_t sig, struct sigaction32 *sp)
1344 {
1345         int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1346 
1347         bzero(sp, sizeof (*sp));
1348 
1349         if (sig != 0 && (unsigned)sig < nsig) {
1350                 sp->sa_handler = (caddr32_t)(uintptr_t)up->u_signal[sig-1];
1351                 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1352                 if (sigismember(&up->u_sigonstack, sig))
1353                         sp->sa_flags |= SA_ONSTACK;
1354                 if (sigismember(&up->u_sigresethand, sig))
1355                         sp->sa_flags |= SA_RESETHAND;
1356                 if (sigismember(&up->u_sigrestart, sig))
1357                         sp->sa_flags |= SA_RESTART;
1358                 if (sigismember(&p->p_siginfo, sig))
1359                         sp->sa_flags |= SA_SIGINFO;
1360                 if (sigismember(&up->u_signodefer, sig))
1361                         sp->sa_flags |= SA_NODEFER;
1362                 if (sig == SIGCLD) {
1363                         if (p->p_flag & SNOWAIT)
1364                                 sp->sa_flags |= SA_NOCLDWAIT;
1365                         if ((p->p_flag & SJCTL) == 0)
1366                                 sp->sa_flags |= SA_NOCLDSTOP;
1367                 }
1368         }
1369 }
1370 #endif  /* _SYSCALL32_IMPL */
1371 
1372 /*
1373  * Count the number of segments in this process's address space.
1374  */
1375 int
1376 prnsegs(struct as *as, int reserved)
1377 {
1378         int n = 0;
1379         struct seg *seg;
1380 
1381         ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1382 
1383         for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
1384                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1385                 caddr_t saddr, naddr;
1386                 void *tmp = NULL;
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, &as->a_lock));
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                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1644                         prot = pr_getprot(seg, reserved, &tmp,
1645                             &saddr, &naddr, eaddr);
1646                         if (saddr == naddr)
1647                                 continue;
1648 
1649                         mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1650 
1651                         mp->pr_vaddr = (uintptr_t)saddr;
1652                         mp->pr_size = naddr - saddr;
1653                         mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1654                         mp->pr_mflags = 0;
1655                         if (prot & PROT_READ)
1656                                 mp->pr_mflags |= MA_READ;
1657                         if (prot & PROT_WRITE)
1658                                 mp->pr_mflags |= MA_WRITE;
1659                         if (prot & PROT_EXEC)
1660                                 mp->pr_mflags |= MA_EXEC;
1661                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1662                                 mp->pr_mflags |= MA_SHARED;
1663                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1664                                 mp->pr_mflags |= MA_NORESERVE;
1665                         if (seg->s_ops == &segspt_shmops ||
1666                             (seg->s_ops == &segvn_ops &&
1667                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1668                                 mp->pr_mflags |= MA_ANON;
1669                         if (seg == brkseg)
1670                                 mp->pr_mflags |= MA_BREAK;
1671                         else if (seg == stkseg) {
1672                                 mp->pr_mflags |= MA_STACK;
1673                                 if (reserved) {
1674                                         size_t maxstack =
1675                                             ((size_t)p->p_stk_ctl +
1676                                             PAGEOFFSET) & PAGEMASK;
1677                                         mp->pr_vaddr =
1678                                             (uintptr_t)prgetstackbase(p) +
1679                                             p->p_stksize - maxstack;
1680                                         mp->pr_size = (uintptr_t)naddr -
1681                                             mp->pr_vaddr;
1682                                 }
1683                         }
1684                         if (seg->s_ops == &segspt_shmops)
1685                                 mp->pr_mflags |= MA_ISM | MA_SHM;
1686                         mp->pr_pagesize = PAGESIZE;
1687 
1688                         /*
1689                          * Manufacture a filename for the "object" directory.
1690                          */
1691                         vattr.va_mask = AT_FSID|AT_NODEID;
1692                         if (seg->s_ops == &segvn_ops &&
1693                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1694                             vp != NULL && vp->v_type == VREG &&
1695                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1696                                 if (vp == p->p_exec)
1697                                         (void) strcpy(mp->pr_mapname, "a.out");
1698                                 else
1699                                         pr_object_name(mp->pr_mapname,
1700                                             vp, &vattr);
1701                         }
1702 
1703                         /*
1704                          * Get the SysV shared memory id, if any.
1705                          */
1706                         if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1707                             (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1708                             SHMID_NONE) {
1709                                 if (mp->pr_shmid == SHMID_FREE)
1710                                         mp->pr_shmid = -1;
1711 
1712                                 mp->pr_mflags |= MA_SHM;
1713                         } else {
1714                                 mp->pr_shmid = -1;
1715                         }
1716                 }
1717                 ASSERT(tmp == NULL);
1718         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1719 
1720         return (0);
1721 }
1722 
1723 #ifdef _SYSCALL32_IMPL
1724 int
1725 prgetmap32(proc_t *p, int reserved, list_t *iolhead)
1726 {
1727         struct as *as = p->p_as;
1728         prmap32_t *mp;
1729         struct seg *seg;
1730         struct seg *brkseg, *stkseg;
1731         struct vnode *vp;
1732         struct vattr vattr;
1733         uint_t prot;
1734 
1735         ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1736 
1737         /*
1738          * Request an initial buffer size that doesn't waste memory
1739          * if the address space has only a small number of segments.
1740          */
1741         pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
1742 
1743         if ((seg = AS_SEGFIRST(as)) == NULL)
1744                 return (0);
1745 
1746         brkseg = break_seg(p);
1747         stkseg = as_segat(as, prgetstackbase(p));
1748 
1749         do {
1750                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1751                 caddr_t saddr, naddr;
1752                 void *tmp = NULL;
1753 
1754                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1755                         prot = pr_getprot(seg, reserved, &tmp,
1756                             &saddr, &naddr, eaddr);
1757                         if (saddr == naddr)
1758                                 continue;
1759 
1760                         mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1761 
1762                         mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
1763                         mp->pr_size = (size32_t)(naddr - saddr);
1764                         mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1765                         mp->pr_mflags = 0;
1766                         if (prot & PROT_READ)
1767                                 mp->pr_mflags |= MA_READ;
1768                         if (prot & PROT_WRITE)
1769                                 mp->pr_mflags |= MA_WRITE;
1770                         if (prot & PROT_EXEC)
1771                                 mp->pr_mflags |= MA_EXEC;
1772                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1773                                 mp->pr_mflags |= MA_SHARED;
1774                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1775                                 mp->pr_mflags |= MA_NORESERVE;
1776                         if (seg->s_ops == &segspt_shmops ||
1777                             (seg->s_ops == &segvn_ops &&
1778                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1779                                 mp->pr_mflags |= MA_ANON;
1780                         if (seg == brkseg)
1781                                 mp->pr_mflags |= MA_BREAK;
1782                         else if (seg == stkseg) {
1783                                 mp->pr_mflags |= MA_STACK;
1784                                 if (reserved) {
1785                                         size_t maxstack =
1786                                             ((size_t)p->p_stk_ctl +
1787                                             PAGEOFFSET) & PAGEMASK;
1788                                         uintptr_t vaddr =
1789                                             (uintptr_t)prgetstackbase(p) +
1790                                             p->p_stksize - maxstack;
1791                                         mp->pr_vaddr = (caddr32_t)vaddr;
1792                                         mp->pr_size = (size32_t)
1793                                             ((uintptr_t)naddr - vaddr);
1794                                 }
1795                         }
1796                         if (seg->s_ops == &segspt_shmops)
1797                                 mp->pr_mflags |= MA_ISM | MA_SHM;
1798                         mp->pr_pagesize = PAGESIZE;
1799 
1800                         /*
1801                          * Manufacture a filename for the "object" directory.
1802                          */
1803                         vattr.va_mask = AT_FSID|AT_NODEID;
1804                         if (seg->s_ops == &segvn_ops &&
1805                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1806                             vp != NULL && vp->v_type == VREG &&
1807                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1808                                 if (vp == p->p_exec)
1809                                         (void) strcpy(mp->pr_mapname, "a.out");
1810                                 else
1811                                         pr_object_name(mp->pr_mapname,
1812                                             vp, &vattr);
1813                         }
1814 
1815                         /*
1816                          * Get the SysV shared memory id, if any.
1817                          */
1818                         if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1819                             (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1820                             SHMID_NONE) {
1821                                 if (mp->pr_shmid == SHMID_FREE)
1822                                         mp->pr_shmid = -1;
1823 
1824                                 mp->pr_mflags |= MA_SHM;
1825                         } else {
1826                                 mp->pr_shmid = -1;
1827                         }
1828                 }
1829                 ASSERT(tmp == NULL);
1830         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1831 
1832         return (0);
1833 }
1834 #endif  /* _SYSCALL32_IMPL */
1835 
1836 /*
1837  * Return the size of the /proc page data file.
1838  */
1839 size_t
1840 prpdsize(struct as *as)
1841 {
1842         struct seg *seg;
1843         size_t size;
1844 
1845         ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1846 
1847         if ((seg = AS_SEGFIRST(as)) == NULL)
1848                 return (0);
1849 
1850         size = sizeof (prpageheader_t);
1851         do {
1852                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1853                 caddr_t saddr, naddr;
1854                 void *tmp = NULL;
1855                 size_t npage;
1856 
1857                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1858                         (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1859                         if ((npage = (naddr - saddr) / PAGESIZE) != 0)
1860                                 size += sizeof (prasmap_t) + round8(npage);
1861                 }
1862                 ASSERT(tmp == NULL);
1863         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1864 
1865         return (size);
1866 }
1867 
1868 #ifdef _SYSCALL32_IMPL
1869 size_t
1870 prpdsize32(struct as *as)
1871 {
1872         struct seg *seg;
1873         size_t size;
1874 
1875         ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1876 
1877         if ((seg = AS_SEGFIRST(as)) == NULL)
1878                 return (0);
1879 
1880         size = sizeof (prpageheader32_t);
1881         do {
1882                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1883                 caddr_t saddr, naddr;
1884                 void *tmp = NULL;
1885                 size_t npage;
1886 
1887                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1888                         (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1889                         if ((npage = (naddr - saddr) / PAGESIZE) != 0)
1890                                 size += sizeof (prasmap32_t) + round8(npage);
1891                 }
1892                 ASSERT(tmp == NULL);
1893         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1894 
1895         return (size);
1896 }
1897 #endif  /* _SYSCALL32_IMPL */
1898 
1899 /*
1900  * Read page data information.
1901  */
1902 int
1903 prpdread(proc_t *p, uint_t hatid, struct uio *uiop)
1904 {
1905         struct as *as = p->p_as;
1906         caddr_t buf;
1907         size_t size;
1908         prpageheader_t *php;
1909         prasmap_t *pmp;
1910         struct seg *seg;
1911         int error;
1912 
1913 again:
1914         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
1915 
1916         if ((seg = AS_SEGFIRST(as)) == NULL) {
1917                 AS_LOCK_EXIT(as, &as->a_lock);
1918                 return (0);
1919         }
1920         size = prpdsize(as);
1921         if (uiop->uio_resid < size) {
1922                 AS_LOCK_EXIT(as, &as->a_lock);
1923                 return (E2BIG);
1924         }
1925 
1926         buf = kmem_zalloc(size, KM_SLEEP);
1927         php = (prpageheader_t *)buf;
1928         pmp = (prasmap_t *)(buf + sizeof (prpageheader_t));
1929 
1930         hrt2ts(gethrtime(), &php->pr_tstamp);
1931         php->pr_nmap = 0;
1932         php->pr_npage = 0;
1933         do {
1934                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1935                 caddr_t saddr, naddr;
1936                 void *tmp = NULL;
1937 
1938                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1939                         struct vnode *vp;
1940                         struct vattr vattr;
1941                         size_t len;
1942                         size_t npage;
1943                         uint_t prot;
1944                         uintptr_t next;
1945 
1946                         prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1947                         if ((len = (size_t)(naddr - saddr)) == 0)
1948                                 continue;
1949                         npage = len / PAGESIZE;
1950                         next = (uintptr_t)(pmp + 1) + round8(npage);
1951                         /*
1952                          * It's possible that the address space can change
1953                          * subtlely even though we're holding as->a_lock
1954                          * due to the nondeterminism of page_exists() in
1955                          * the presence of asychronously flushed pages or
1956                          * mapped files whose sizes are changing.
1957                          * page_exists() may be called indirectly from
1958                          * pr_getprot() by a SEGOP_INCORE() routine.
1959                          * If this happens we need to make sure we don't
1960                          * overrun the buffer whose size we computed based
1961                          * on the initial iteration through the segments.
1962                          * Once we've detected an overflow, we need to clean
1963                          * up the temporary memory allocated in pr_getprot()
1964                          * and retry. If there's a pending signal, we return
1965                          * EINTR so that this thread can be dislodged if
1966                          * a latent bug causes us to spin indefinitely.
1967                          */
1968                         if (next > (uintptr_t)buf + size) {
1969                                 pr_getprot_done(&tmp);
1970                                 AS_LOCK_EXIT(as, &as->a_lock);
1971 
1972                                 kmem_free(buf, size);
1973 
1974                                 if (ISSIG(curthread, JUSTLOOKING))
1975                                         return (EINTR);
1976 
1977                                 goto again;
1978                         }
1979 
1980                         php->pr_nmap++;
1981                         php->pr_npage += npage;
1982                         pmp->pr_vaddr = (uintptr_t)saddr;
1983                         pmp->pr_npage = npage;
1984                         pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1985                         pmp->pr_mflags = 0;
1986                         if (prot & PROT_READ)
1987                                 pmp->pr_mflags |= MA_READ;
1988                         if (prot & PROT_WRITE)
1989                                 pmp->pr_mflags |= MA_WRITE;
1990                         if (prot & PROT_EXEC)
1991                                 pmp->pr_mflags |= MA_EXEC;
1992                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1993                                 pmp->pr_mflags |= MA_SHARED;
1994                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1995                                 pmp->pr_mflags |= MA_NORESERVE;
1996                         if (seg->s_ops == &segspt_shmops ||
1997                             (seg->s_ops == &segvn_ops &&
1998                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1999                                 pmp->pr_mflags |= MA_ANON;
2000                         if (seg->s_ops == &segspt_shmops)
2001                                 pmp->pr_mflags |= MA_ISM | MA_SHM;
2002                         pmp->pr_pagesize = PAGESIZE;
2003                         /*
2004                          * Manufacture a filename for the "object" directory.
2005                          */
2006                         vattr.va_mask = AT_FSID|AT_NODEID;
2007                         if (seg->s_ops == &segvn_ops &&
2008                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2009                             vp != NULL && vp->v_type == VREG &&
2010                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2011                                 if (vp == p->p_exec)
2012                                         (void) strcpy(pmp->pr_mapname, "a.out");
2013                                 else
2014                                         pr_object_name(pmp->pr_mapname,
2015                                             vp, &vattr);
2016                         }
2017 
2018                         /*
2019                          * Get the SysV shared memory id, if any.
2020                          */
2021                         if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2022                             (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2023                             SHMID_NONE) {
2024                                 if (pmp->pr_shmid == SHMID_FREE)
2025                                         pmp->pr_shmid = -1;
2026 
2027                                 pmp->pr_mflags |= MA_SHM;
2028                         } else {
2029                                 pmp->pr_shmid = -1;
2030                         }
2031 
2032                         hat_getstat(as, saddr, len, hatid,
2033                             (char *)(pmp + 1), HAT_SYNC_ZERORM);
2034                         pmp = (prasmap_t *)next;
2035                 }
2036                 ASSERT(tmp == NULL);
2037         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2038 
2039         AS_LOCK_EXIT(as, &as->a_lock);
2040 
2041         ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2042         error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2043         kmem_free(buf, size);
2044 
2045         return (error);
2046 }
2047 
2048 #ifdef _SYSCALL32_IMPL
2049 int
2050 prpdread32(proc_t *p, uint_t hatid, struct uio *uiop)
2051 {
2052         struct as *as = p->p_as;
2053         caddr_t buf;
2054         size_t size;
2055         prpageheader32_t *php;
2056         prasmap32_t *pmp;
2057         struct seg *seg;
2058         int error;
2059 
2060 again:
2061         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
2062 
2063         if ((seg = AS_SEGFIRST(as)) == NULL) {
2064                 AS_LOCK_EXIT(as, &as->a_lock);
2065                 return (0);
2066         }
2067         size = prpdsize32(as);
2068         if (uiop->uio_resid < size) {
2069                 AS_LOCK_EXIT(as, &as->a_lock);
2070                 return (E2BIG);
2071         }
2072 
2073         buf = kmem_zalloc(size, KM_SLEEP);
2074         php = (prpageheader32_t *)buf;
2075         pmp = (prasmap32_t *)(buf + sizeof (prpageheader32_t));
2076 
2077         hrt2ts32(gethrtime(), &php->pr_tstamp);
2078         php->pr_nmap = 0;
2079         php->pr_npage = 0;
2080         do {
2081                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
2082                 caddr_t saddr, naddr;
2083                 void *tmp = NULL;
2084 
2085                 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
2086                         struct vnode *vp;
2087                         struct vattr vattr;
2088                         size_t len;
2089                         size_t npage;
2090                         uint_t prot;
2091                         uintptr_t next;
2092 
2093                         prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
2094                         if ((len = (size_t)(naddr - saddr)) == 0)
2095                                 continue;
2096                         npage = len / PAGESIZE;
2097                         next = (uintptr_t)(pmp + 1) + round8(npage);
2098                         /*
2099                          * It's possible that the address space can change
2100                          * subtlely even though we're holding as->a_lock
2101                          * due to the nondeterminism of page_exists() in
2102                          * the presence of asychronously flushed pages or
2103                          * mapped files whose sizes are changing.
2104                          * page_exists() may be called indirectly from
2105                          * pr_getprot() by a SEGOP_INCORE() routine.
2106                          * If this happens we need to make sure we don't
2107                          * overrun the buffer whose size we computed based
2108                          * on the initial iteration through the segments.
2109                          * Once we've detected an overflow, we need to clean
2110                          * up the temporary memory allocated in pr_getprot()
2111                          * and retry. If there's a pending signal, we return
2112                          * EINTR so that this thread can be dislodged if
2113                          * a latent bug causes us to spin indefinitely.
2114                          */
2115                         if (next > (uintptr_t)buf + size) {
2116                                 pr_getprot_done(&tmp);
2117                                 AS_LOCK_EXIT(as, &as->a_lock);
2118 
2119                                 kmem_free(buf, size);
2120 
2121                                 if (ISSIG(curthread, JUSTLOOKING))
2122                                         return (EINTR);
2123 
2124                                 goto again;
2125                         }
2126 
2127                         php->pr_nmap++;
2128                         php->pr_npage += npage;
2129                         pmp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
2130                         pmp->pr_npage = (size32_t)npage;
2131                         pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
2132                         pmp->pr_mflags = 0;
2133                         if (prot & PROT_READ)
2134                                 pmp->pr_mflags |= MA_READ;
2135                         if (prot & PROT_WRITE)
2136                                 pmp->pr_mflags |= MA_WRITE;
2137                         if (prot & PROT_EXEC)
2138                                 pmp->pr_mflags |= MA_EXEC;
2139                         if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
2140                                 pmp->pr_mflags |= MA_SHARED;
2141                         if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
2142                                 pmp->pr_mflags |= MA_NORESERVE;
2143                         if (seg->s_ops == &segspt_shmops ||
2144                             (seg->s_ops == &segvn_ops &&
2145                             (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
2146                                 pmp->pr_mflags |= MA_ANON;
2147                         if (seg->s_ops == &segspt_shmops)
2148                                 pmp->pr_mflags |= MA_ISM | MA_SHM;
2149                         pmp->pr_pagesize = PAGESIZE;
2150                         /*
2151                          * Manufacture a filename for the "object" directory.
2152                          */
2153                         vattr.va_mask = AT_FSID|AT_NODEID;
2154                         if (seg->s_ops == &segvn_ops &&
2155                             SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2156                             vp != NULL && vp->v_type == VREG &&
2157                             VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2158                                 if (vp == p->p_exec)
2159                                         (void) strcpy(pmp->pr_mapname, "a.out");
2160                                 else
2161                                         pr_object_name(pmp->pr_mapname,
2162                                             vp, &vattr);
2163                         }
2164 
2165                         /*
2166                          * Get the SysV shared memory id, if any.
2167                          */
2168                         if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2169                             (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2170                             SHMID_NONE) {
2171                                 if (pmp->pr_shmid == SHMID_FREE)
2172                                         pmp->pr_shmid = -1;
2173 
2174                                 pmp->pr_mflags |= MA_SHM;
2175                         } else {
2176                                 pmp->pr_shmid = -1;
2177                         }
2178 
2179                         hat_getstat(as, saddr, len, hatid,
2180                             (char *)(pmp + 1), HAT_SYNC_ZERORM);
2181                         pmp = (prasmap32_t *)next;
2182                 }
2183                 ASSERT(tmp == NULL);
2184         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2185 
2186         AS_LOCK_EXIT(as, &as->a_lock);
2187 
2188         ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2189         error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2190         kmem_free(buf, size);
2191 
2192         return (error);
2193 }
2194 #endif  /* _SYSCALL32_IMPL */
2195 
2196 ushort_t
2197 prgetpctcpu(uint64_t pct)
2198 {
2199         /*
2200          * The value returned will be relevant in the zone of the examiner,
2201          * which may not be the same as the zone which performed the procfs
2202          * mount.
2203          */
2204         int nonline = zone_ncpus_online_get(curproc->p_zone);
2205 
2206         /*
2207          * Prorate over online cpus so we don't exceed 100%
2208          */
2209         if (nonline > 1)
2210                 pct /= nonline;
2211         pct >>= 16;               /* convert to 16-bit scaled integer */
2212         if (pct > 0x8000)    /* might happen, due to rounding */
2213                 pct = 0x8000;
2214         return ((ushort_t)pct);
2215 }
2216 
2217 /*
2218  * Return information used by ps(1).
2219  */
2220 void
2221 prgetpsinfo(proc_t *p, psinfo_t *psp)
2222 {
2223         kthread_t *t;
2224         struct cred *cred;
2225         hrtime_t hrutime, hrstime;
2226 
2227         ASSERT(MUTEX_HELD(&p->p_lock));
2228 
2229         if ((t = prchoose(p)) == NULL)  /* returns locked thread */
2230                 bzero(psp, sizeof (*psp));
2231         else {
2232                 thread_unlock(t);
2233                 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2234         }
2235 
2236         /*
2237          * only export SSYS and SMSACCT; everything else is off-limits to
2238          * userland apps.
2239          */
2240         psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2241         psp->pr_nlwp = p->p_lwpcnt;
2242         psp->pr_nzomb = p->p_zombcnt;
2243         mutex_enter(&p->p_crlock);
2244         cred = p->p_cred;
2245         psp->pr_uid = crgetruid(cred);
2246         psp->pr_euid = crgetuid(cred);
2247         psp->pr_gid = crgetrgid(cred);
2248         psp->pr_egid = crgetgid(cred);
2249         mutex_exit(&p->p_crlock);
2250         psp->pr_pid = p->p_pid;
2251         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
2252             (p->p_flag & SZONETOP)) {
2253                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
2254                 /*
2255                  * Inside local zones, fake zsched's pid as parent pids for
2256                  * processes which reference processes outside of the zone.
2257                  */
2258                 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
2259         } else {
2260                 psp->pr_ppid = p->p_ppid;
2261         }
2262         psp->pr_pgid = p->p_pgrp;
2263         psp->pr_sid = p->p_sessp->s_sid;
2264         psp->pr_taskid = p->p_task->tk_tkid;
2265         psp->pr_projid = p->p_task->tk_proj->kpj_id;
2266         psp->pr_poolid = p->p_pool->pool_id;
2267         psp->pr_zoneid = p->p_zone->zone_id;
2268         if ((psp->pr_contract = PRCTID(p)) == 0)
2269                 psp->pr_contract = -1;
2270         psp->pr_addr = (uintptr_t)prgetpsaddr(p);
2271         switch (p->p_model) {
2272         case DATAMODEL_ILP32:
2273                 psp->pr_dmodel = PR_MODEL_ILP32;
2274                 break;
2275         case DATAMODEL_LP64:
2276                 psp->pr_dmodel = PR_MODEL_LP64;
2277                 break;
2278         }
2279         hrutime = mstate_aggr_state(p, LMS_USER);
2280         hrstime = mstate_aggr_state(p, LMS_SYSTEM);
2281         hrt2ts((hrutime + hrstime), &psp->pr_time);
2282         TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime);
2283 
2284         if (t == NULL) {
2285                 int wcode = p->p_wcode;              /* must be atomic read */
2286 
2287                 if (wcode)
2288                         psp->pr_wstat = wstat(wcode, p->p_wdata);
2289                 psp->pr_ttydev = PRNODEV;
2290                 psp->pr_lwp.pr_state = SZOMB;
2291                 psp->pr_lwp.pr_sname = 'Z';
2292                 psp->pr_lwp.pr_bindpro = PBIND_NONE;
2293                 psp->pr_lwp.pr_bindpset = PS_NONE;
2294         } else {
2295                 user_t *up = PTOU(p);
2296                 struct as *as;
2297                 dev_t d;
2298                 extern dev_t rwsconsdev, rconsdev, uconsdev;
2299 
2300                 d = cttydev(p);
2301                 /*
2302                  * If the controlling terminal is the real
2303                  * or workstation console device, map to what the
2304                  * user thinks is the console device. Handle case when
2305                  * rwsconsdev or rconsdev is set to NODEV for Starfire.
2306                  */
2307                 if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
2308                         d = uconsdev;
2309                 psp->pr_ttydev = (d == NODEV) ? PRNODEV : d;
2310                 psp->pr_start = up->u_start;
2311                 bcopy(up->u_comm, psp->pr_fname,
2312                     MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2313                 bcopy(up->u_psargs, psp->pr_psargs,
2314                     MIN(PRARGSZ-1, PSARGSZ));
2315                 psp->pr_argc = up->u_argc;
2316                 psp->pr_argv = up->u_argv;
2317                 psp->pr_envp = up->u_envp;
2318 
2319                 /* get the chosen lwp's lwpsinfo */
2320                 prgetlwpsinfo(t, &psp->pr_lwp);
2321 
2322                 /* compute %cpu for the process */
2323                 if (p->p_lwpcnt == 1)
2324                         psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
2325                 else {
2326                         uint64_t pct = 0;
2327                         hrtime_t cur_time = gethrtime_unscaled();
2328 
2329                         t = p->p_tlist;
2330                         do {
2331                                 pct += cpu_update_pct(t, cur_time);
2332                         } while ((t = t->t_forw) != p->p_tlist);
2333 
2334                         psp->pr_pctcpu = prgetpctcpu(pct);
2335                 }
2336                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
2337                         psp->pr_size = 0;
2338                         psp->pr_rssize = 0;
2339                 } else {
2340                         mutex_exit(&p->p_lock);
2341                         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
2342                         psp->pr_size = btopr(as->a_resvsize) *
2343                             (PAGESIZE / 1024);
2344                         psp->pr_rssize = rm_asrss(as) * (PAGESIZE / 1024);
2345                         psp->pr_pctmem = rm_pctmemory(as);
2346                         AS_LOCK_EXIT(as, &as->a_lock);
2347                         mutex_enter(&p->p_lock);
2348                 }
2349         }
2350 }
2351 
2352 #ifdef _SYSCALL32_IMPL
2353 void
2354 prgetpsinfo32(proc_t *p, psinfo32_t *psp)
2355 {
2356         kthread_t *t;
2357         struct cred *cred;
2358         hrtime_t hrutime, hrstime;
2359 
2360         ASSERT(MUTEX_HELD(&p->p_lock));
2361 
2362         if ((t = prchoose(p)) == NULL)  /* returns locked thread */
2363                 bzero(psp, sizeof (*psp));
2364         else {
2365                 thread_unlock(t);
2366                 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2367         }
2368 
2369         /*
2370          * only export SSYS and SMSACCT; everything else is off-limits to
2371          * userland apps.
2372          */
2373         psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2374         psp->pr_nlwp = p->p_lwpcnt;
2375         psp->pr_nzomb = p->p_zombcnt;
2376         mutex_enter(&p->p_crlock);
2377         cred = p->p_cred;
2378         psp->pr_uid = crgetruid(cred);
2379         psp->pr_euid = crgetuid(cred);
2380         psp->pr_gid = crgetrgid(cred);
2381         psp->pr_egid = crgetgid(cred);
2382         mutex_exit(&p->p_crlock);
2383         psp->pr_pid = p->p_pid;
2384         if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
2385             (p->p_flag & SZONETOP)) {
2386                 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
2387                 /*
2388                  * Inside local zones, fake zsched's pid as parent pids for
2389                  * processes which reference processes outside of the zone.
2390                  */
2391                 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
2392         } else {
2393                 psp->pr_ppid = p->p_ppid;
2394         }
2395         psp->pr_pgid = p->p_pgrp;
2396         psp->pr_sid = p->p_sessp->s_sid;
2397         psp->pr_taskid = p->p_task->tk_tkid;
2398         psp->pr_projid = p->p_task->tk_proj->kpj_id;
2399         psp->pr_poolid = p->p_pool->pool_id;
2400         psp->pr_zoneid = p->p_zone->zone_id;
2401         if ((psp->pr_contract = PRCTID(p)) == 0)
2402                 psp->pr_contract = -1;
2403         psp->pr_addr = 0;    /* cannot represent 64-bit addr in 32 bits */
2404         switch (p->p_model) {
2405         case DATAMODEL_ILP32:
2406                 psp->pr_dmodel = PR_MODEL_ILP32;
2407                 break;
2408         case DATAMODEL_LP64:
2409                 psp->pr_dmodel = PR_MODEL_LP64;
2410                 break;
2411         }
2412         hrutime = mstate_aggr_state(p, LMS_USER);
2413         hrstime = mstate_aggr_state(p, LMS_SYSTEM);
2414         hrt2ts32(hrutime + hrstime, &psp->pr_time);
2415         TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime);
2416 
2417         if (t == NULL) {
2418                 extern int wstat(int, int);     /* needs a header file */
2419                 int wcode = p->p_wcode;              /* must be atomic read */
2420 
2421                 if (wcode)
2422                         psp->pr_wstat = wstat(wcode, p->p_wdata);
2423                 psp->pr_ttydev = PRNODEV32;
2424                 psp->pr_lwp.pr_state = SZOMB;
2425                 psp->pr_lwp.pr_sname = 'Z';
2426         } else {
2427                 user_t *up = PTOU(p);
2428                 struct as *as;
2429                 dev_t d;
2430                 extern dev_t rwsconsdev, rconsdev, uconsdev;
2431 
2432                 d = cttydev(p);
2433                 /*
2434                  * If the controlling terminal is the real
2435                  * or workstation console device, map to what the
2436                  * user thinks is the console device. Handle case when
2437                  * rwsconsdev or rconsdev is set to NODEV for Starfire.
2438                  */
2439                 if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
2440                         d = uconsdev;
2441                 (void) cmpldev(&psp->pr_ttydev, d);
2442                 TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start);
2443                 bcopy(up->u_comm, psp->pr_fname,
2444                     MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2445                 bcopy(up->u_psargs, psp->pr_psargs,
2446                     MIN(PRARGSZ-1, PSARGSZ));
2447                 psp->pr_argc = up->u_argc;
2448                 psp->pr_argv = (caddr32_t)up->u_argv;
2449                 psp->pr_envp = (caddr32_t)up->u_envp;
2450 
2451                 /* get the chosen lwp's lwpsinfo */
2452                 prgetlwpsinfo32(t, &psp->pr_lwp);
2453 
2454                 /* compute %cpu for the process */
2455                 if (p->p_lwpcnt == 1)
2456                         psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
2457                 else {
2458                         uint64_t pct = 0;
2459                         hrtime_t cur_time;
2460 
2461                         t = p->p_tlist;
2462                         cur_time = gethrtime_unscaled();
2463                         do {
2464                                 pct += cpu_update_pct(t, cur_time);
2465                         } while ((t = t->t_forw) != p->p_tlist);
2466 
2467                         psp->pr_pctcpu = prgetpctcpu(pct);
2468                 }
2469                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
2470                         psp->pr_size = 0;
2471                         psp->pr_rssize = 0;
2472                 } else {
2473                         mutex_exit(&p->p_lock);
2474                         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
2475                         psp->pr_size = (size32_t)
2476                             (btopr(as->a_resvsize) * (PAGESIZE / 1024));
2477                         psp->pr_rssize = (size32_t)
2478                             (rm_asrss(as) * (PAGESIZE / 1024));
2479                         psp->pr_pctmem = rm_pctmemory(as);
2480                         AS_LOCK_EXIT(as, &as->a_lock);
2481                         mutex_enter(&p->p_lock);
2482                 }
2483         }
2484 
2485         /*
2486          * If we are looking at an LP64 process, zero out
2487          * the fields that cannot be represented in ILP32.
2488          */
2489         if (p->p_model != DATAMODEL_ILP32) {
2490                 psp->pr_size = 0;
2491                 psp->pr_rssize = 0;
2492                 psp->pr_argv = 0;
2493                 psp->pr_envp = 0;
2494         }
2495 }
2496 
2497 #endif  /* _SYSCALL32_IMPL */
2498 
2499 void
2500 prgetlwpsinfo(kthread_t *t, lwpsinfo_t *psp)
2501 {
2502         klwp_t *lwp = ttolwp(t);
2503         sobj_ops_t *sobj;
2504         char c, state;
2505         uint64_t pct;
2506         int retval, niceval;
2507         hrtime_t hrutime, hrstime;
2508 
2509         ASSERT(MUTEX_HELD(&ttoproc(t)->p_lock));
2510 
2511         bzero(psp, sizeof (*psp));
2512 
2513         psp->pr_flag = 0;    /* lwpsinfo_t.pr_flag is deprecated */
2514         psp->pr_lwpid = t->t_tid;
2515         psp->pr_addr = (uintptr_t)t;
2516         psp->pr_wchan = (uintptr_t)t->t_wchan;
2517 
2518         /* map the thread state enum into a process state enum */
2519         state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
2520         switch (state) {
2521         case TS_SLEEP:          state = SSLEEP;         c = 'S';        break;
2522         case TS_RUN:            state = SRUN;           c = 'R';        break;
2523         case TS_ONPROC:         state = SONPROC;        c = 'O';        break;
2524         case TS_ZOMB:           state = SZOMB;          c = 'Z';        break;
2525         case TS_STOPPED:        state = SSTOP;          c = 'T';        break;
2526         case TS_WAIT:           state = SWAIT;          c = 'W';        break;
2527         default:                state = 0;              c = '?';        break;
2528         }
2529         psp->pr_state = state;
2530         psp->pr_sname = c;
2531         if ((sobj = t->t_sobj_ops) != NULL)
2532                 psp->pr_stype = SOBJ_TYPE(sobj);
2533         retval = CL_DONICE(t, NULL, 0, &niceval);
2534         if (retval == 0) {
2535                 psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
2536                 psp->pr_nice = niceval + NZERO;
2537         }
2538         psp->pr_syscall = t->t_sysnum;
2539         psp->pr_pri = t->t_pri;
2540         psp->pr_start.tv_sec = t->t_start;
2541         psp->pr_start.tv_nsec = 0L;
2542         hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
2543         scalehrtime(&hrutime);
2544         hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
2545             lwp->lwp_mstate.ms_acct[LMS_TRAP];
2546         scalehrtime(&hrstime);
2547         hrt2ts(hrutime + hrstime, &psp->pr_time);
2548         /* compute %cpu for the lwp */
2549         pct = cpu_update_pct(t, gethrtime_unscaled());
2550         psp->pr_pctcpu = prgetpctcpu(pct);
2551         psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15;  /* [0..99] */
2552         if (psp->pr_cpu > 99)
2553                 psp->pr_cpu = 99;
2554 
2555         (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
2556             sizeof (psp->pr_clname) - 1);
2557         bzero(psp->pr_name, sizeof (psp->pr_name));       /* XXX ??? */
2558         psp->pr_onpro = t->t_cpu->cpu_id;
2559         psp->pr_bindpro = t->t_bind_cpu;
2560         psp->pr_bindpset = t->t_bind_pset;
2561         psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
2562 }
2563 
2564 #ifdef _SYSCALL32_IMPL
2565 void
2566 prgetlwpsinfo32(kthread_t *t, lwpsinfo32_t *psp)
2567 {
2568         proc_t *p = ttoproc(t);
2569         klwp_t *lwp = ttolwp(t);
2570         sobj_ops_t *sobj;
2571         char c, state;
2572         uint64_t pct;
2573         int retval, niceval;
2574         hrtime_t hrutime, hrstime;
2575 
2576         ASSERT(MUTEX_HELD(&p->p_lock));
2577 
2578         bzero(psp, sizeof (*psp));
2579 
2580         psp->pr_flag = 0;    /* lwpsinfo_t.pr_flag is deprecated */
2581         psp->pr_lwpid = t->t_tid;
2582         psp->pr_addr = 0;    /* cannot represent 64-bit addr in 32 bits */
2583         psp->pr_wchan = 0;   /* cannot represent 64-bit addr in 32 bits */
2584 
2585         /* map the thread state enum into a process state enum */
2586         state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
2587         switch (state) {
2588         case TS_SLEEP:          state = SSLEEP;         c = 'S';        break;
2589         case TS_RUN:            state = SRUN;           c = 'R';        break;
2590         case TS_ONPROC:         state = SONPROC;        c = 'O';        break;
2591         case TS_ZOMB:           state = SZOMB;          c = 'Z';        break;
2592         case TS_STOPPED:        state = SSTOP;          c = 'T';        break;
2593         case TS_WAIT:           state = SWAIT;          c = 'W';        break;
2594         default:                state = 0;              c = '?';        break;
2595         }
2596         psp->pr_state = state;
2597         psp->pr_sname = c;
2598         if ((sobj = t->t_sobj_ops) != NULL)
2599                 psp->pr_stype = SOBJ_TYPE(sobj);
2600         retval = CL_DONICE(t, NULL, 0, &niceval);
2601         if (retval == 0) {
2602                 psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
2603                 psp->pr_nice = niceval + NZERO;
2604         } else {
2605                 psp->pr_oldpri = 0;
2606                 psp->pr_nice = 0;
2607         }
2608         psp->pr_syscall = t->t_sysnum;
2609         psp->pr_pri = t->t_pri;
2610         psp->pr_start.tv_sec = (time32_t)t->t_start;
2611         psp->pr_start.tv_nsec = 0L;
2612         hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
2613         scalehrtime(&hrutime);
2614         hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
2615             lwp->lwp_mstate.ms_acct[LMS_TRAP];
2616         scalehrtime(&hrstime);
2617         hrt2ts32(hrutime + hrstime, &psp->pr_time);
2618         /* compute %cpu for the lwp */
2619         pct = cpu_update_pct(t, gethrtime_unscaled());
2620         psp->pr_pctcpu = prgetpctcpu(pct);
2621         psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15;  /* [0..99] */
2622         if (psp->pr_cpu > 99)
2623                 psp->pr_cpu = 99;
2624 
2625         (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
2626             sizeof (psp->pr_clname) - 1);
2627         bzero(psp->pr_name, sizeof (psp->pr_name));       /* XXX ??? */
2628         psp->pr_onpro = t->t_cpu->cpu_id;
2629         psp->pr_bindpro = t->t_bind_cpu;
2630         psp->pr_bindpset = t->t_bind_pset;
2631         psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
2632 }
2633 #endif  /* _SYSCALL32_IMPL */
2634 
2635 #ifdef _SYSCALL32_IMPL
2636 
2637 #define PR_COPY_FIELD(s, d, field)       d->field = s->field
2638 
2639 #define PR_COPY_FIELD_ILP32(s, d, field)                                \
2640         if (s->pr_dmodel == PR_MODEL_ILP32) {                        \
2641                 d->field = s->field;                              \
2642         }
2643 
2644 #define PR_COPY_TIMESPEC(s, d, field)                           \
2645         TIMESPEC_TO_TIMESPEC32(&d->field, &s->field);
2646 
2647 #define PR_COPY_BUF(s, d, field)                                \
2648         bcopy(s->field, d->field, sizeof (d->field));
2649 
2650 #define PR_IGNORE_FIELD(s, d, field)
2651 
2652 void
2653 lwpsinfo_kto32(const struct lwpsinfo *src, struct lwpsinfo32 *dest)
2654 {
2655         bzero(dest, sizeof (*dest));
2656 
2657         PR_COPY_FIELD(src, dest, pr_flag);
2658         PR_COPY_FIELD(src, dest, pr_lwpid);
2659         PR_IGNORE_FIELD(src, dest, pr_addr);
2660         PR_IGNORE_FIELD(src, dest, pr_wchan);
2661         PR_COPY_FIELD(src, dest, pr_stype);
2662         PR_COPY_FIELD(src, dest, pr_state);
2663         PR_COPY_FIELD(src, dest, pr_sname);
2664         PR_COPY_FIELD(src, dest, pr_nice);
2665         PR_COPY_FIELD(src, dest, pr_syscall);
2666         PR_COPY_FIELD(src, dest, pr_oldpri);
2667         PR_COPY_FIELD(src, dest, pr_cpu);
2668         PR_COPY_FIELD(src, dest, pr_pri);
2669         PR_COPY_FIELD(src, dest, pr_pctcpu);
2670         PR_COPY_TIMESPEC(src, dest, pr_start);
2671         PR_COPY_BUF(src, dest, pr_clname);
2672         PR_COPY_BUF(src, dest, pr_name);
2673         PR_COPY_FIELD(src, dest, pr_onpro);
2674         PR_COPY_FIELD(src, dest, pr_bindpro);
2675         PR_COPY_FIELD(src, dest, pr_bindpset);
2676         PR_COPY_FIELD(src, dest, pr_lgrp);
2677 }
2678 
2679 void
2680 psinfo_kto32(const struct psinfo *src, struct psinfo32 *dest)
2681 {
2682         bzero(dest, sizeof (*dest));
2683 
2684         PR_COPY_FIELD(src, dest, pr_flag);
2685         PR_COPY_FIELD(src, dest, pr_nlwp);
2686         PR_COPY_FIELD(src, dest, pr_pid);
2687         PR_COPY_FIELD(src, dest, pr_ppid);
2688         PR_COPY_FIELD(src, dest, pr_pgid);
2689         PR_COPY_FIELD(src, dest, pr_sid);
2690         PR_COPY_FIELD(src, dest, pr_uid);
2691         PR_COPY_FIELD(src, dest, pr_euid);
2692         PR_COPY_FIELD(src, dest, pr_gid);
2693         PR_COPY_FIELD(src, dest, pr_egid);
2694         PR_IGNORE_FIELD(src, dest, pr_addr);
2695         PR_COPY_FIELD_ILP32(src, dest, pr_size);
2696         PR_COPY_FIELD_ILP32(src, dest, pr_rssize);
2697         PR_COPY_FIELD(src, dest, pr_ttydev);
2698         PR_COPY_FIELD(src, dest, pr_pctcpu);
2699         PR_COPY_FIELD(src, dest, pr_pctmem);
2700         PR_COPY_TIMESPEC(src, dest, pr_start);
2701         PR_COPY_TIMESPEC(src, dest, pr_time);
2702         PR_COPY_TIMESPEC(src, dest, pr_ctime);
2703         PR_COPY_BUF(src, dest, pr_fname);
2704         PR_COPY_BUF(src, dest, pr_psargs);
2705         PR_COPY_FIELD(src, dest, pr_wstat);
2706         PR_COPY_FIELD(src, dest, pr_argc);
2707         PR_COPY_FIELD_ILP32(src, dest, pr_argv);
2708         PR_COPY_FIELD_ILP32(src, dest, pr_envp);
2709         PR_COPY_FIELD(src, dest, pr_dmodel);
2710         PR_COPY_FIELD(src, dest, pr_taskid);
2711         PR_COPY_FIELD(src, dest, pr_projid);
2712         PR_COPY_FIELD(src, dest, pr_nzomb);
2713         PR_COPY_FIELD(src, dest, pr_poolid);
2714         PR_COPY_FIELD(src, dest, pr_contract);
2715         PR_COPY_FIELD(src, dest, pr_poolid);
2716         PR_COPY_FIELD(src, dest, pr_poolid);
2717 
2718         lwpsinfo_kto32(&src->pr_lwp, &dest->pr_lwp);
2719 }
2720 
2721 #undef  PR_COPY_FIELD
2722 #undef  PR_COPY_FIELD_ILP32
2723 #undef  PR_COPY_TIMESPEC
2724 #undef  PR_COPY_BUF
2725 #undef  PR_IGNORE_FIELD
2726 
2727 #endif  /* _SYSCALL32_IMPL */
2728 
2729 /*
2730  * This used to get called when microstate accounting was disabled but
2731  * microstate information was requested.  Since Microstate accounting is on
2732  * regardless of the proc flags, this simply makes it appear to procfs that
2733  * microstate accounting is on.  This is relatively meaningless since you
2734  * can't turn it off, but this is here for the sake of appearances.
2735  */
2736 
2737 /*ARGSUSED*/
2738 void
2739 estimate_msacct(kthread_t *t, hrtime_t curtime)
2740 {
2741         proc_t *p;
2742 
2743         if (t == NULL)
2744                 return;
2745 
2746         p = ttoproc(t);
2747         ASSERT(MUTEX_HELD(&p->p_lock));
2748 
2749         /*
2750          * A system process (p0) could be referenced if the thread is
2751          * in the process of exiting.  Don't turn on microstate accounting
2752          * in that case.
2753          */
2754         if (p->p_flag & SSYS)
2755                 return;
2756 
2757         /*
2758          * Loop through all the LWPs (kernel threads) in the process.
2759          */
2760         t = p->p_tlist;
2761         do {
2762                 t->t_proc_flag |= TP_MSACCT;
2763         } while ((t = t->t_forw) != p->p_tlist);
2764 
2765         p->p_flag |= SMSACCT;                        /* set process-wide MSACCT */
2766 }
2767 
2768 /*
2769  * It's not really possible to disable microstate accounting anymore.
2770  * However, this routine simply turns off the ms accounting flags in a process
2771  * This way procfs can still pretend to turn microstate accounting on and
2772  * off for a process, but it actually doesn't do anything.  This is
2773  * a neutered form of preemptive idiot-proofing.
2774  */
2775 void
2776 disable_msacct(proc_t *p)
2777 {
2778         kthread_t *t;
2779 
2780         ASSERT(MUTEX_HELD(&p->p_lock));
2781 
2782         p->p_flag &= ~SMSACCT;           /* clear process-wide MSACCT */
2783         /*
2784          * Loop through all the LWPs (kernel threads) in the process.
2785          */
2786         if ((t = p->p_tlist) != NULL) {
2787                 do {
2788                         /* clear per-thread flag */
2789                         t->t_proc_flag &= ~TP_MSACCT;
2790                 } while ((t = t->t_forw) != p->p_tlist);
2791         }
2792 }
2793 
2794 /*
2795  * Return resource usage information.
2796  */
2797 void
2798 prgetusage(kthread_t *t, prhusage_t *pup)
2799 {
2800         klwp_t *lwp = ttolwp(t);
2801         hrtime_t *mstimep;
2802         struct mstate *ms = &lwp->lwp_mstate;
2803         int state;
2804         int i;
2805         hrtime_t curtime;
2806         hrtime_t waitrq;
2807         hrtime_t tmp1;
2808 
2809         curtime = gethrtime_unscaled();
2810 
2811         pup->pr_lwpid        = t->t_tid;
2812         pup->pr_count        = 1;
2813         pup->pr_create       = ms->ms_start;
2814         pup->pr_term    = ms->ms_term;
2815         scalehrtime(&pup->pr_create);
2816         scalehrtime(&pup->pr_term);
2817         if (ms->ms_term == 0) {
2818                 pup->pr_rtime = curtime - ms->ms_start;
2819                 scalehrtime(&pup->pr_rtime);
2820         } else {
2821                 pup->pr_rtime = ms->ms_term - ms->ms_start;
2822                 scalehrtime(&pup->pr_rtime);
2823         }
2824 
2825 
2826         pup->pr_utime    = ms->ms_acct[LMS_USER];
2827         pup->pr_stime    = ms->ms_acct[LMS_SYSTEM];
2828         pup->pr_ttime    = ms->ms_acct[LMS_TRAP];
2829         pup->pr_tftime   = ms->ms_acct[LMS_TFAULT];
2830         pup->pr_dftime   = ms->ms_acct[LMS_DFAULT];
2831         pup->pr_kftime   = ms->ms_acct[LMS_KFAULT];
2832         pup->pr_ltime    = ms->ms_acct[LMS_USER_LOCK];
2833         pup->pr_slptime  = ms->ms_acct[LMS_SLEEP];
2834         pup->pr_wtime    = ms->ms_acct[LMS_WAIT_CPU];
2835         pup->pr_stoptime = ms->ms_acct[LMS_STOPPED];
2836 
2837         prscaleusage(pup);
2838 
2839         /*
2840          * Adjust for time waiting in the dispatcher queue.
2841          */
2842         waitrq = t->t_waitrq;        /* hopefully atomic */
2843         if (waitrq != 0) {
2844                 if (waitrq > curtime) {
2845                         curtime = gethrtime_unscaled();
2846                 }
2847                 tmp1 = curtime - waitrq;
2848                 scalehrtime(&tmp1);
2849                 pup->pr_wtime += tmp1;
2850                 curtime = waitrq;
2851         }
2852 
2853         /*
2854          * Adjust for time spent in current microstate.
2855          */
2856         if (ms->ms_state_start > curtime) {
2857                 curtime = gethrtime_unscaled();
2858         }
2859 
2860         i = 0;
2861         do {
2862                 switch (state = t->t_mstate) {
2863                 case LMS_SLEEP:
2864                         /*
2865                          * Update the timer for the current sleep state.
2866                          */
2867                         switch (state = ms->ms_prev) {
2868                         case LMS_TFAULT:
2869                         case LMS_DFAULT:
2870                         case LMS_KFAULT:
2871                         case LMS_USER_LOCK:
2872                                 break;
2873                         default:
2874                                 state = LMS_SLEEP;
2875                                 break;
2876                         }
2877                         break;
2878                 case LMS_TFAULT:
2879                 case LMS_DFAULT:
2880                 case LMS_KFAULT:
2881                 case LMS_USER_LOCK:
2882                         state = LMS_SYSTEM;
2883                         break;
2884                 }
2885                 switch (state) {
2886                 case LMS_USER:          mstimep = &pup->pr_utime;        break;
2887                 case LMS_SYSTEM:        mstimep = &pup->pr_stime;        break;
2888                 case LMS_TRAP:          mstimep = &pup->pr_ttime;        break;
2889                 case LMS_TFAULT:        mstimep = &pup->pr_tftime;       break;
2890                 case LMS_DFAULT:        mstimep = &pup->pr_dftime;       break;
2891                 case LMS_KFAULT:        mstimep = &pup->pr_kftime;       break;
2892                 case LMS_USER_LOCK:     mstimep = &pup->pr_ltime;        break;
2893                 case LMS_SLEEP:         mstimep = &pup->pr_slptime;      break;
2894                 case LMS_WAIT_CPU:      mstimep = &pup->pr_wtime;        break;
2895                 case LMS_STOPPED:       mstimep = &pup->pr_stoptime;     break;
2896                 default:                panic("prgetusage: unknown microstate");
2897                 }
2898                 tmp1 = curtime - ms->ms_state_start;
2899                 if (tmp1 < 0) {
2900                         curtime = gethrtime_unscaled();
2901                         i++;
2902                         continue;
2903                 }
2904                 scalehrtime(&tmp1);
2905         } while (tmp1 < 0 && i < MAX_ITERS_SPIN);
2906 
2907         *mstimep += tmp1;
2908 
2909         /* update pup timestamp */
2910         pup->pr_tstamp = curtime;
2911         scalehrtime(&pup->pr_tstamp);
2912 
2913         /*
2914          * Resource usage counters.
2915          */
2916         pup->pr_minf  = lwp->lwp_ru.minflt;
2917         pup->pr_majf  = lwp->lwp_ru.majflt;
2918         pup->pr_nswap = lwp->lwp_ru.nswap;
2919         pup->pr_inblk = lwp->lwp_ru.inblock;
2920         pup->pr_oublk = lwp->lwp_ru.oublock;
2921         pup->pr_msnd  = lwp->lwp_ru.msgsnd;
2922         pup->pr_mrcv  = lwp->lwp_ru.msgrcv;
2923         pup->pr_sigs  = lwp->lwp_ru.nsignals;
2924         pup->pr_vctx  = lwp->lwp_ru.nvcsw;
2925         pup->pr_ictx  = lwp->lwp_ru.nivcsw;
2926         pup->pr_sysc  = lwp->lwp_ru.sysc;
2927         pup->pr_ioch  = lwp->lwp_ru.ioch;
2928 }
2929 
2930 /*
2931  * Convert ms_acct stats from unscaled high-res time to nanoseconds
2932  */
2933 void
2934 prscaleusage(prhusage_t *usg)
2935 {
2936         scalehrtime(&usg->pr_utime);
2937         scalehrtime(&usg->pr_stime);
2938         scalehrtime(&usg->pr_ttime);
2939         scalehrtime(&usg->pr_tftime);
2940         scalehrtime(&usg->pr_dftime);
2941         scalehrtime(&usg->pr_kftime);
2942         scalehrtime(&usg->pr_ltime);
2943         scalehrtime(&usg->pr_slptime);
2944         scalehrtime(&usg->pr_wtime);
2945         scalehrtime(&usg->pr_stoptime);
2946 }
2947 
2948 
2949 /*
2950  * Sum resource usage information.
2951  */
2952 void
2953 praddusage(kthread_t *t, prhusage_t *pup)
2954 {
2955         klwp_t *lwp = ttolwp(t);
2956         hrtime_t *mstimep;
2957         struct mstate *ms = &lwp->lwp_mstate;
2958         int state;
2959         int i;
2960         hrtime_t curtime;
2961         hrtime_t waitrq;
2962         hrtime_t tmp;
2963         prhusage_t conv;
2964 
2965         curtime = gethrtime_unscaled();
2966 
2967         if (ms->ms_term == 0) {
2968                 tmp = curtime - ms->ms_start;
2969                 scalehrtime(&tmp);
2970                 pup->pr_rtime += tmp;
2971         } else {
2972                 tmp = ms->ms_term - ms->ms_start;
2973                 scalehrtime(&tmp);
2974                 pup->pr_rtime += tmp;
2975         }
2976 
2977         conv.pr_utime = ms->ms_acct[LMS_USER];
2978         conv.pr_stime = ms->ms_acct[LMS_SYSTEM];
2979         conv.pr_ttime = ms->ms_acct[LMS_TRAP];
2980         conv.pr_tftime = ms->ms_acct[LMS_TFAULT];
2981         conv.pr_dftime = ms->ms_acct[LMS_DFAULT];
2982         conv.pr_kftime = ms->ms_acct[LMS_KFAULT];
2983         conv.pr_ltime = ms->ms_acct[LMS_USER_LOCK];
2984         conv.pr_slptime = ms->ms_acct[LMS_SLEEP];
2985         conv.pr_wtime = ms->ms_acct[LMS_WAIT_CPU];
2986         conv.pr_stoptime = ms->ms_acct[LMS_STOPPED];
2987 
2988         prscaleusage(&conv);
2989 
2990         pup->pr_utime        += conv.pr_utime;
2991         pup->pr_stime        += conv.pr_stime;
2992         pup->pr_ttime        += conv.pr_ttime;
2993         pup->pr_tftime       += conv.pr_tftime;
2994         pup->pr_dftime       += conv.pr_dftime;
2995         pup->pr_kftime       += conv.pr_kftime;
2996         pup->pr_ltime        += conv.pr_ltime;
2997         pup->pr_slptime      += conv.pr_slptime;
2998         pup->pr_wtime        += conv.pr_wtime;
2999         pup->pr_stoptime += conv.pr_stoptime;
3000 
3001         /*
3002          * Adjust for time waiting in the dispatcher queue.
3003          */
3004         waitrq = t->t_waitrq;        /* hopefully atomic */
3005         if (waitrq != 0) {
3006                 if (waitrq > curtime) {
3007                         curtime = gethrtime_unscaled();
3008                 }
3009                 tmp = curtime - waitrq;
3010                 scalehrtime(&tmp);
3011                 pup->pr_wtime += tmp;
3012                 curtime = waitrq;
3013         }
3014 
3015         /*
3016          * Adjust for time spent in current microstate.
3017          */
3018         if (ms->ms_state_start > curtime) {
3019                 curtime = gethrtime_unscaled();
3020         }
3021 
3022         i = 0;
3023         do {
3024                 switch (state = t->t_mstate) {
3025                 case LMS_SLEEP:
3026                         /*
3027                          * Update the timer for the current sleep state.
3028                          */
3029                         switch (state = ms->ms_prev) {
3030                         case LMS_TFAULT:
3031                         case LMS_DFAULT:
3032                         case LMS_KFAULT:
3033                         case LMS_USER_LOCK:
3034                                 break;
3035                         default:
3036                                 state = LMS_SLEEP;
3037                                 break;
3038                         }
3039                         break;
3040                 case LMS_TFAULT:
3041                 case LMS_DFAULT:
3042                 case LMS_KFAULT:
3043                 case LMS_USER_LOCK:
3044                         state = LMS_SYSTEM;
3045                         break;
3046                 }
3047                 switch (state) {
3048                 case LMS_USER:          mstimep = &pup->pr_utime;        break;
3049                 case LMS_SYSTEM:        mstimep = &pup->pr_stime;        break;
3050                 case LMS_TRAP:          mstimep = &pup->pr_ttime;        break;
3051                 case LMS_TFAULT:        mstimep = &pup->pr_tftime;       break;
3052                 case LMS_DFAULT:        mstimep = &pup->pr_dftime;       break;
3053                 case LMS_KFAULT:        mstimep = &pup->pr_kftime;       break;
3054                 case LMS_USER_LOCK:     mstimep = &pup->pr_ltime;        break;
3055                 case LMS_SLEEP:         mstimep = &pup->pr_slptime;      break;
3056                 case LMS_WAIT_CPU:      mstimep = &pup->pr_wtime;        break;
3057                 case LMS_STOPPED:       mstimep = &pup->pr_stoptime;     break;
3058                 default:                panic("praddusage: unknown microstate");
3059                 }
3060                 tmp = curtime - ms->ms_state_start;
3061                 if (tmp < 0) {
3062                         curtime = gethrtime_unscaled();
3063                         i++;
3064                         continue;
3065                 }
3066                 scalehrtime(&tmp);
3067         } while (tmp < 0 && i < MAX_ITERS_SPIN);
3068 
3069         *mstimep += tmp;
3070 
3071         /* update pup timestamp */
3072         pup->pr_tstamp = curtime;
3073         scalehrtime(&pup->pr_tstamp);
3074 
3075         /*
3076          * Resource usage counters.
3077          */
3078         pup->pr_minf  += lwp->lwp_ru.minflt;
3079         pup->pr_majf  += lwp->lwp_ru.majflt;
3080         pup->pr_nswap += lwp->lwp_ru.nswap;
3081         pup->pr_inblk += lwp->lwp_ru.inblock;
3082         pup->pr_oublk += lwp->lwp_ru.oublock;
3083         pup->pr_msnd  += lwp->lwp_ru.msgsnd;
3084         pup->pr_mrcv  += lwp->lwp_ru.msgrcv;
3085         pup->pr_sigs  += lwp->lwp_ru.nsignals;
3086         pup->pr_vctx  += lwp->lwp_ru.nvcsw;
3087         pup->pr_ictx  += lwp->lwp_ru.nivcsw;
3088         pup->pr_sysc  += lwp->lwp_ru.sysc;
3089         pup->pr_ioch  += lwp->lwp_ru.ioch;
3090 }
3091 
3092 /*
3093  * Convert a prhusage_t to a prusage_t.
3094  * This means convert each hrtime_t to a timestruc_t
3095  * and copy the count fields uint64_t => ulong_t.
3096  */
3097 void
3098 prcvtusage(prhusage_t *pup, prusage_t *upup)
3099 {
3100         uint64_t *ullp;
3101         ulong_t *ulp;
3102         int i;
3103 
3104         upup->pr_lwpid = pup->pr_lwpid;
3105         upup->pr_count = pup->pr_count;
3106 
3107         hrt2ts(pup->pr_tstamp,       &upup->pr_tstamp);
3108         hrt2ts(pup->pr_create,       &upup->pr_create);
3109         hrt2ts(pup->pr_term, &upup->pr_term);
3110         hrt2ts(pup->pr_rtime,        &upup->pr_rtime);
3111         hrt2ts(pup->pr_utime,        &upup->pr_utime);
3112         hrt2ts(pup->pr_stime,        &upup->pr_stime);
3113         hrt2ts(pup->pr_ttime,        &upup->pr_ttime);
3114         hrt2ts(pup->pr_tftime,       &upup->pr_tftime);
3115         hrt2ts(pup->pr_dftime,       &upup->pr_dftime);
3116         hrt2ts(pup->pr_kftime,       &upup->pr_kftime);
3117         hrt2ts(pup->pr_ltime,        &upup->pr_ltime);
3118         hrt2ts(pup->pr_slptime,      &upup->pr_slptime);
3119         hrt2ts(pup->pr_wtime,        &upup->pr_wtime);
3120         hrt2ts(pup->pr_stoptime, &upup->pr_stoptime);
3121         bzero(upup->filltime, sizeof (upup->filltime));
3122 
3123         ullp = &pup->pr_minf;
3124         ulp = &upup->pr_minf;
3125         for (i = 0; i < 22; i++)
3126                 *ulp++ = (ulong_t)*ullp++;
3127 }
3128 
3129 #ifdef _SYSCALL32_IMPL
3130 void
3131 prcvtusage32(prhusage_t *pup, prusage32_t *upup)
3132 {
3133         uint64_t *ullp;
3134         uint32_t *ulp;
3135         int i;
3136 
3137         upup->pr_lwpid = pup->pr_lwpid;
3138         upup->pr_count = pup->pr_count;
3139 
3140         hrt2ts32(pup->pr_tstamp,     &upup->pr_tstamp);
3141         hrt2ts32(pup->pr_create,     &upup->pr_create);
3142         hrt2ts32(pup->pr_term,               &upup->pr_term);
3143         hrt2ts32(pup->pr_rtime,              &upup->pr_rtime);
3144         hrt2ts32(pup->pr_utime,              &upup->pr_utime);
3145         hrt2ts32(pup->pr_stime,              &upup->pr_stime);
3146         hrt2ts32(pup->pr_ttime,              &upup->pr_ttime);
3147         hrt2ts32(pup->pr_tftime,     &upup->pr_tftime);
3148         hrt2ts32(pup->pr_dftime,     &upup->pr_dftime);
3149         hrt2ts32(pup->pr_kftime,     &upup->pr_kftime);
3150         hrt2ts32(pup->pr_ltime,              &upup->pr_ltime);
3151         hrt2ts32(pup->pr_slptime,    &upup->pr_slptime);
3152         hrt2ts32(pup->pr_wtime,              &upup->pr_wtime);
3153         hrt2ts32(pup->pr_stoptime,   &upup->pr_stoptime);
3154         bzero(upup->filltime, sizeof (upup->filltime));
3155 
3156         ullp = &pup->pr_minf;
3157         ulp = &upup->pr_minf;
3158         for (i = 0; i < 22; i++)
3159                 *ulp++ = (uint32_t)*ullp++;
3160 }
3161 #endif  /* _SYSCALL32_IMPL */
3162 
3163 /*
3164  * Determine whether a set is empty.
3165  */
3166 int
3167 setisempty(uint32_t *sp, uint_t n)
3168 {
3169         while (n--)
3170                 if (*sp++)
3171                         return (0);
3172         return (1);
3173 }
3174 
3175 /*
3176  * Utility routine for establishing a watched area in the process.
3177  * Keep the list of watched areas sorted by virtual address.
3178  */
3179 int
3180 set_watched_area(proc_t *p, struct watched_area *pwa)
3181 {
3182         caddr_t vaddr = pwa->wa_vaddr;
3183         caddr_t eaddr = pwa->wa_eaddr;
3184         ulong_t flags = pwa->wa_flags;
3185         struct watched_area *target;
3186         avl_index_t where;
3187         int error = 0;
3188 
3189         /* we must not be holding p->p_lock, but the process must be locked */
3190         ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3191         ASSERT(p->p_proc_flag & P_PR_LOCK);
3192 
3193         /*
3194          * If this is our first watchpoint, enable watchpoints for the process.
3195          */
3196         if (!pr_watch_active(p)) {
3197                 kthread_t *t;
3198 
3199                 mutex_enter(&p->p_lock);
3200                 if ((t = p->p_tlist) != NULL) {
3201                         do {
3202                                 watch_enable(t);
3203                         } while ((t = t->t_forw) != p->p_tlist);
3204                 }
3205                 mutex_exit(&p->p_lock);
3206         }
3207 
3208         target = pr_find_watched_area(p, pwa, &where);
3209         if (target != NULL) {
3210                 /*
3211                  * We discovered an existing, overlapping watched area.
3212                  * Allow it only if it is an exact match.
3213                  */
3214                 if (target->wa_vaddr != vaddr ||
3215                     target->wa_eaddr != eaddr)
3216                         error = EINVAL;
3217                 else if (target->wa_flags != flags) {
3218                         error = set_watched_page(p, vaddr, eaddr,
3219                             flags, target->wa_flags);
3220                         target->wa_flags = flags;
3221                 }
3222                 kmem_free(pwa, sizeof (struct watched_area));
3223         } else {
3224                 avl_insert(&p->p_warea, pwa, where);
3225                 error = set_watched_page(p, vaddr, eaddr, flags, 0);
3226         }
3227 
3228         return (error);
3229 }
3230 
3231 /*
3232  * Utility routine for clearing a watched area in the process.
3233  * Must be an exact match of the virtual address.
3234  * size and flags don't matter.
3235  */
3236 int
3237 clear_watched_area(proc_t *p, struct watched_area *pwa)
3238 {
3239         struct watched_area *found;
3240 
3241         /* we must not be holding p->p_lock, but the process must be locked */
3242         ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3243         ASSERT(p->p_proc_flag & P_PR_LOCK);
3244 
3245 
3246         if (!pr_watch_active(p)) {
3247                 kmem_free(pwa, sizeof (struct watched_area));
3248                 return (0);
3249         }
3250 
3251         /*
3252          * Look for a matching address in the watched areas.  If a match is
3253          * found, clear the old watched area and adjust the watched page(s).  It
3254          * is not an error if there is no match.
3255          */
3256         if ((found = pr_find_watched_area(p, pwa, NULL)) != NULL &&
3257             found->wa_vaddr == pwa->wa_vaddr) {
3258                 clear_watched_page(p, found->wa_vaddr, found->wa_eaddr,
3259                     found->wa_flags);
3260                 avl_remove(&p->p_warea, found);
3261                 kmem_free(found, sizeof (struct watched_area));
3262         }
3263 
3264         kmem_free(pwa, sizeof (struct watched_area));
3265 
3266         /*
3267          * If we removed the last watched area from the process, disable
3268          * watchpoints.
3269          */
3270         if (!pr_watch_active(p)) {
3271                 kthread_t *t;
3272 
3273                 mutex_enter(&p->p_lock);
3274                 if ((t = p->p_tlist) != NULL) {
3275                         do {
3276                                 watch_disable(t);
3277                         } while ((t = t->t_forw) != p->p_tlist);
3278                 }
3279                 mutex_exit(&p->p_lock);
3280         }
3281 
3282         return (0);
3283 }
3284 
3285 /*
3286  * Frees all the watched_area structures
3287  */
3288 void
3289 pr_free_watchpoints(proc_t *p)
3290 {
3291         struct watched_area *delp;
3292         void *cookie;
3293 
3294         cookie = NULL;
3295         while ((delp = avl_destroy_nodes(&p->p_warea, &cookie)) != NULL)
3296                 kmem_free(delp, sizeof (struct watched_area));
3297 
3298         avl_destroy(&p->p_warea);
3299 }
3300 
3301 /*
3302  * This one is called by the traced process to unwatch all the
3303  * pages while deallocating the list of watched_page structs.
3304  */
3305 void
3306 pr_free_watched_pages(proc_t *p)
3307 {
3308         struct as *as = p->p_as;
3309         struct watched_page *pwp;
3310         uint_t prot;
3311         int    retrycnt, err;
3312         void *cookie;
3313 
3314         if (as == NULL || avl_numnodes(&as->a_wpage) == 0)
3315                 return;
3316 
3317         ASSERT(MUTEX_NOT_HELD(&curproc->p_lock));
3318         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3319 
3320         pwp = avl_first(&as->a_wpage);
3321 
3322         cookie = NULL;
3323         while ((pwp = avl_destroy_nodes(&as->a_wpage, &cookie)) != NULL) {
3324                 retrycnt = 0;
3325                 if ((prot = pwp->wp_oprot) != 0) {
3326                         caddr_t addr = pwp->wp_vaddr;
3327                         struct seg *seg;
3328                 retry:
3329 
3330                         if ((pwp->wp_prot != prot ||
3331                             (pwp->wp_flags & WP_NOWATCH)) &&
3332                             (seg = as_segat(as, addr)) != NULL) {
3333                                 err = SEGOP_SETPROT(seg, addr, PAGESIZE, prot);
3334                                 if (err == IE_RETRY) {
3335                                         ASSERT(retrycnt == 0);
3336                                         retrycnt++;
3337                                         goto retry;
3338                                 }
3339                         }
3340                 }
3341                 kmem_free(pwp, sizeof (struct watched_page));
3342         }
3343 
3344         avl_destroy(&as->a_wpage);
3345         p->p_wprot = NULL;
3346 
3347         AS_LOCK_EXIT(as, &as->a_lock);
3348 }
3349 
3350 /*
3351  * Insert a watched area into the list of watched pages.
3352  * If oflags is zero then we are adding a new watched area.
3353  * Otherwise we are changing the flags of an existing watched area.
3354  */
3355 static int
3356 set_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr,
3357         ulong_t flags, ulong_t oflags)
3358 {
3359         struct as *as = p->p_as;
3360         avl_tree_t *pwp_tree;
3361         struct watched_page *pwp, *newpwp;
3362         struct watched_page tpw;
3363         avl_index_t where;
3364         struct seg *seg;
3365         uint_t prot;
3366         caddr_t addr;
3367 
3368         /*
3369          * We need to pre-allocate a list of structures before we grab the
3370          * address space lock to avoid calling kmem_alloc(KM_SLEEP) with locks
3371          * held.
3372          */
3373         newpwp = NULL;
3374         for (addr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3375             addr < eaddr; addr += PAGESIZE) {
3376                 pwp = kmem_zalloc(sizeof (struct watched_page), KM_SLEEP);
3377                 pwp->wp_list = newpwp;
3378                 newpwp = pwp;
3379         }
3380 
3381         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3382 
3383         /*
3384          * Search for an existing watched page to contain the watched area.
3385          * If none is found, grab a new one from the available list
3386          * and insert it in the active list, keeping the list sorted
3387          * by user-level virtual address.
3388          */
3389         if (p->p_flag & SVFWAIT)
3390                 pwp_tree = &p->p_wpage;
3391         else
3392                 pwp_tree = &as->a_wpage;
3393 
3394 again:
3395         if (avl_numnodes(pwp_tree) > prnwatch) {
3396                 AS_LOCK_EXIT(as, &as->a_lock);
3397                 while (newpwp != NULL) {
3398                         pwp = newpwp->wp_list;
3399                         kmem_free(newpwp, sizeof (struct watched_page));
3400                         newpwp = pwp;
3401                 }
3402                 return (E2BIG);
3403         }
3404 
3405         tpw.wp_vaddr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3406         if ((pwp = avl_find(pwp_tree, &tpw, &where)) == NULL) {
3407                 pwp = newpwp;
3408                 newpwp = newpwp->wp_list;
3409                 pwp->wp_list = NULL;
3410                 pwp->wp_vaddr = (caddr_t)((uintptr_t)vaddr &
3411                     (uintptr_t)PAGEMASK);
3412                 avl_insert(pwp_tree, pwp, where);
3413         }
3414 
3415         ASSERT(vaddr >= pwp->wp_vaddr && vaddr < pwp->wp_vaddr + PAGESIZE);
3416 
3417         if (oflags & WA_READ)
3418                 pwp->wp_read--;
3419         if (oflags & WA_WRITE)
3420                 pwp->wp_write--;
3421         if (oflags & WA_EXEC)
3422                 pwp->wp_exec--;
3423 
3424         ASSERT(pwp->wp_read >= 0);
3425         ASSERT(pwp->wp_write >= 0);
3426         ASSERT(pwp->wp_exec >= 0);
3427 
3428         if (flags & WA_READ)
3429                 pwp->wp_read++;
3430         if (flags & WA_WRITE)
3431                 pwp->wp_write++;
3432         if (flags & WA_EXEC)
3433                 pwp->wp_exec++;
3434 
3435         if (!(p->p_flag & SVFWAIT)) {
3436                 vaddr = pwp->wp_vaddr;
3437                 if (pwp->wp_oprot == 0 &&
3438                     (seg = as_segat(as, vaddr)) != NULL) {
3439                         SEGOP_GETPROT(seg, vaddr, 0, &prot);
3440                         pwp->wp_oprot = (uchar_t)prot;
3441                         pwp->wp_prot = (uchar_t)prot;
3442                 }
3443                 if (pwp->wp_oprot != 0) {
3444                         prot = pwp->wp_oprot;
3445                         if (pwp->wp_read)
3446                                 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3447                         if (pwp->wp_write)
3448                                 prot &= ~PROT_WRITE;
3449                         if (pwp->wp_exec)
3450                                 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3451                         if (!(pwp->wp_flags & WP_NOWATCH) &&
3452                             pwp->wp_prot != prot &&
3453                             (pwp->wp_flags & WP_SETPROT) == 0) {
3454                                 pwp->wp_flags |= WP_SETPROT;
3455                                 pwp->wp_list = p->p_wprot;
3456                                 p->p_wprot = pwp;
3457                         }
3458                         pwp->wp_prot = (uchar_t)prot;
3459                 }
3460         }
3461 
3462         /*
3463          * If the watched area extends into the next page then do
3464          * it over again with the virtual address of the next page.
3465          */
3466         if ((vaddr = pwp->wp_vaddr + PAGESIZE) < eaddr)
3467                 goto again;
3468 
3469         AS_LOCK_EXIT(as, &as->a_lock);
3470 
3471         /*
3472          * Free any pages we may have over-allocated
3473          */
3474         while (newpwp != NULL) {
3475                 pwp = newpwp->wp_list;
3476                 kmem_free(newpwp, sizeof (struct watched_page));
3477                 newpwp = pwp;
3478         }
3479 
3480         return (0);
3481 }
3482 
3483 /*
3484  * Remove a watched area from the list of watched pages.
3485  * A watched area may extend over more than one page.
3486  */
3487 static void
3488 clear_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr, ulong_t flags)
3489 {
3490         struct as *as = p->p_as;
3491         struct watched_page *pwp;
3492         struct watched_page tpw;
3493         avl_tree_t *tree;
3494         avl_index_t where;
3495 
3496         AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3497 
3498         if (p->p_flag & SVFWAIT)
3499                 tree = &p->p_wpage;
3500         else
3501                 tree = &as->a_wpage;
3502 
3503         tpw.wp_vaddr = vaddr =
3504             (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3505         pwp = avl_find(tree, &tpw, &where);
3506         if (pwp == NULL)
3507                 pwp = avl_nearest(tree, where, AVL_AFTER);
3508 
3509         while (pwp != NULL && pwp->wp_vaddr < eaddr) {
3510                 ASSERT(vaddr <=  pwp->wp_vaddr);
3511 
3512                 if (flags & WA_READ)
3513                         pwp->wp_read--;
3514                 if (flags & WA_WRITE)
3515                         pwp->wp_write--;
3516                 if (flags & WA_EXEC)
3517                         pwp->wp_exec--;
3518 
3519                 if (pwp->wp_read + pwp->wp_write + pwp->wp_exec != 0) {
3520                         /*
3521                          * Reset the hat layer's protections on this page.
3522                          */
3523                         if (pwp->wp_oprot != 0) {
3524                                 uint_t prot = pwp->wp_oprot;
3525 
3526                                 if (pwp->wp_read)
3527                                         prot &=
3528                                             ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3529                                 if (pwp->wp_write)
3530                                         prot &= ~PROT_WRITE;
3531                                 if (pwp->wp_exec)
3532                                         prot &=
3533                                             ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3534                                 if (!(pwp->wp_flags & WP_NOWATCH) &&
3535                                     pwp->wp_prot != prot &&
3536                                     (pwp->wp_flags & WP_SETPROT) == 0) {
3537                                         pwp->wp_flags |= WP_SETPROT;
3538                                         pwp->wp_list = p->p_wprot;
3539                                         p->p_wprot = pwp;
3540                                 }
3541                                 pwp->wp_prot = (uchar_t)prot;
3542                         }
3543                 } else {
3544                         /*
3545                          * No watched areas remain in this page.
3546                          * Reset everything to normal.
3547                          */
3548                         if (pwp->wp_oprot != 0) {
3549                                 pwp->wp_prot = pwp->wp_oprot;
3550                                 if ((pwp->wp_flags & WP_SETPROT) == 0) {
3551                                         pwp->wp_flags |= WP_SETPROT;
3552                                         pwp->wp_list = p->p_wprot;
3553                                         p->p_wprot = pwp;
3554                                 }
3555                         }
3556                 }
3557 
3558                 pwp = AVL_NEXT(tree, pwp);
3559         }
3560 
3561         AS_LOCK_EXIT(as, &as->a_lock);
3562 }
3563 
3564 /*
3565  * Return the original protections for the specified page.
3566  */
3567 static void
3568 getwatchprot(struct as *as, caddr_t addr, uint_t *prot)
3569 {
3570         struct watched_page *pwp;
3571         struct watched_page tpw;
3572 
3573         ASSERT(AS_LOCK_HELD(as, &as->a_lock));
3574 
3575         tpw.wp_vaddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
3576         if ((pwp = avl_find(&as->a_wpage, &tpw, NULL)) != NULL)
3577                 *prot = pwp->wp_oprot;
3578 }
3579 
3580 static prpagev_t *
3581 pr_pagev_create(struct seg *seg, int check_noreserve)
3582 {
3583         prpagev_t *pagev = kmem_alloc(sizeof (prpagev_t), KM_SLEEP);
3584         size_t total_pages = seg_pages(seg);
3585 
3586         /*
3587          * Limit the size of our vectors to pagev_lim pages at a time.  We need
3588          * 4 or 5 bytes of storage per page, so this means we limit ourself
3589          * to about a megabyte of kernel heap by default.
3590          */
3591         pagev->pg_npages = MIN(total_pages, pagev_lim);
3592         pagev->pg_pnbase = 0;
3593 
3594         pagev->pg_protv =
3595             kmem_alloc(pagev->pg_npages * sizeof (uint_t), KM_SLEEP);
3596 
3597         if (check_noreserve)
3598                 pagev->pg_incore =
3599                     kmem_alloc(pagev->pg_npages * sizeof (char), KM_SLEEP);
3600         else
3601                 pagev->pg_incore = NULL;
3602 
3603         return (pagev);
3604 }
3605 
3606 static void
3607 pr_pagev_destroy(prpagev_t *pagev)
3608 {
3609         if (pagev->pg_incore != NULL)
3610                 kmem_free(pagev->pg_incore, pagev->pg_npages * sizeof (char));
3611 
3612         kmem_free(pagev->pg_protv, pagev->pg_npages * sizeof (uint_t));
3613         kmem_free(pagev, sizeof (prpagev_t));
3614 }
3615 
3616 static caddr_t
3617 pr_pagev_fill(prpagev_t *pagev, struct seg *seg, caddr_t addr, caddr_t eaddr)
3618 {
3619         ulong_t lastpg = seg_page(seg, eaddr - 1);
3620         ulong_t pn, pnlim;
3621         caddr_t saddr;
3622         size_t len;
3623 
3624         ASSERT(addr >= seg->s_base && addr <= eaddr);
3625 
3626         if (addr == eaddr)
3627                 return (eaddr);
3628 
3629 refill:
3630         ASSERT(addr < eaddr);
3631         pagev->pg_pnbase = seg_page(seg, addr);
3632         pnlim = pagev->pg_pnbase + pagev->pg_npages;
3633         saddr = addr;
3634 
3635         if (lastpg < pnlim)
3636                 len = (size_t)(eaddr - addr);
3637         else
3638                 len = pagev->pg_npages * PAGESIZE;
3639 
3640         if (pagev->pg_incore != NULL) {
3641                 /*
3642                  * INCORE cleverly has different semantics than GETPROT:
3643                  * it returns info on pages up to but NOT including addr + len.
3644                  */
3645                 SEGOP_INCORE(seg, addr, len, pagev->pg_incore);
3646                 pn = pagev->pg_pnbase;
3647 
3648                 do {
3649                         /*
3650                          * Guilty knowledge here:  We know that segvn_incore
3651                          * returns more than just the low-order bit that
3652                          * indicates the page is actually in memory.  If any
3653                          * bits are set, then the page has backing store.
3654                          */
3655                         if (pagev->pg_incore[pn++ - pagev->pg_pnbase])
3656                                 goto out;
3657 
3658                 } while ((addr += PAGESIZE) < eaddr && pn < pnlim);
3659 
3660                 /*
3661                  * If we examined all the pages in the vector but we're not
3662                  * at the end of the segment, take another lap.
3663                  */
3664                 if (addr < eaddr)
3665                         goto refill;
3666         }
3667 
3668         /*
3669          * Need to take len - 1 because addr + len is the address of the
3670          * first byte of the page just past the end of what we want.
3671          */
3672 out:
3673         SEGOP_GETPROT(seg, saddr, len - 1, pagev->pg_protv);
3674         return (addr);
3675 }
3676 
3677 static caddr_t
3678 pr_pagev_nextprot(prpagev_t *pagev, struct seg *seg,
3679     caddr_t *saddrp, caddr_t eaddr, uint_t *protp)
3680 {
3681         /*
3682          * Our starting address is either the specified address, or the base
3683          * address from the start of the pagev.  If the latter is greater,
3684          * this means a previous call to pr_pagev_fill has already scanned
3685          * further than the end of the previous mapping.
3686          */
3687         caddr_t base = seg->s_base + pagev->pg_pnbase * PAGESIZE;
3688         caddr_t addr = MAX(*saddrp, base);
3689         ulong_t pn = seg_page(seg, addr);
3690         uint_t prot, nprot;
3691 
3692         /*
3693          * If we're dealing with noreserve pages, then advance addr to
3694          * the address of the next page which has backing store.
3695          */
3696         if (pagev->pg_incore != NULL) {
3697                 while (pagev->pg_incore[pn - pagev->pg_pnbase] == 0) {
3698                         if ((addr += PAGESIZE) == eaddr) {
3699                                 *saddrp = addr;
3700                                 prot = 0;
3701                                 goto out;
3702                         }
3703                         if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
3704                                 addr = pr_pagev_fill(pagev, seg, addr, eaddr);
3705                                 if (addr == eaddr) {
3706                                         *saddrp = addr;
3707                                         prot = 0;
3708                                         goto out;
3709                                 }
3710                                 pn = seg_page(seg, addr);
3711                         }
3712                 }
3713         }
3714 
3715         /*
3716          * Get the protections on the page corresponding to addr.
3717          */
3718         pn = seg_page(seg, addr);
3719         ASSERT(pn >= pagev->pg_pnbase);
3720         ASSERT(pn < (pagev->pg_pnbase + pagev->pg_npages));
3721 
3722         prot = pagev->pg_protv[pn - pagev->pg_pnbase];
3723         getwatchprot(seg->s_as, addr, &prot);
3724         *saddrp = addr;
3725 
3726         /*
3727          * Now loop until we find a backed page with different protections
3728          * or we reach the end of this segment.
3729          */
3730         while ((addr += PAGESIZE) < eaddr) {
3731                 /*
3732                  * If pn has advanced to the page number following what we
3733                  * have information on, refill the page vector and reset
3734                  * addr and pn.  If pr_pagev_fill does not return the
3735                  * address of the next page, we have a discontiguity and
3736                  * thus have reached the end of the current mapping.
3737                  */
3738                 if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
3739                         caddr_t naddr = pr_pagev_fill(pagev, seg, addr, eaddr);
3740                         if (naddr != addr)
3741                                 goto out;
3742                         pn = seg_page(seg, addr);
3743                 }
3744 
3745                 /*
3746                  * The previous page's protections are in prot, and it has
3747                  * backing.  If this page is MAP_NORESERVE and has no backing,
3748                  * then end this mapping and return the previous protections.
3749                  */
3750                 if (pagev->pg_incore != NULL &&
3751                     pagev->pg_incore[pn - pagev->pg_pnbase] == 0)
3752                         break;
3753 
3754                 /*
3755                  * Otherwise end the mapping if this page's protections (nprot)
3756                  * are different than those in the previous page (prot).
3757                  */
3758                 nprot = pagev->pg_protv[pn - pagev->pg_pnbase];
3759                 getwatchprot(seg->s_as, addr, &nprot);
3760 
3761                 if (nprot != prot)
3762                         break;
3763         }
3764 
3765 out:
3766         *protp = prot;
3767         return (addr);
3768 }
3769 
3770 size_t
3771 pr_getsegsize(struct seg *seg, int reserved)
3772 {
3773         size_t size = seg->s_size;
3774 
3775         /*
3776          * If we're interested in the reserved space, return the size of the
3777          * segment itself.  Everything else in this function is a special case
3778          * to determine the actual underlying size of various segment types.
3779          */
3780         if (reserved)
3781                 return (size);
3782 
3783         /*
3784          * If this is a segvn mapping of a regular file, return the smaller
3785          * of the segment size and the remaining size of the file beyond
3786          * the file offset corresponding to seg->s_base.
3787          */
3788         if (seg->s_ops == &segvn_ops) {
3789                 vattr_t vattr;
3790                 vnode_t *vp;
3791 
3792                 vattr.va_mask = AT_SIZE;
3793 
3794                 if (SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3795                     vp != NULL && vp->v_type == VREG &&
3796                     VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3797 
3798                         u_offset_t fsize = vattr.va_size;
3799                         u_offset_t offset = SEGOP_GETOFFSET(seg, seg->s_base);
3800 
3801                         if (fsize < offset)
3802                                 fsize = 0;
3803                         else
3804                                 fsize -= offset;
3805 
3806                         fsize = roundup(fsize, (u_offset_t)PAGESIZE);
3807 
3808                         if (fsize < (u_offset_t)size)
3809                                 size = (size_t)fsize;
3810                 }
3811 
3812                 return (size);
3813         }
3814 
3815         /*
3816          * If this is an ISM shared segment, don't include pages that are
3817          * beyond the real size of the spt segment that backs it.
3818          */
3819         if (seg->s_ops == &segspt_shmops)
3820                 return (MIN(spt_realsize(seg), size));
3821 
3822         /*
3823          * If this is segment is a mapping from /dev/null, then this is a
3824          * reservation of virtual address space and has no actual size.
3825          * Such segments are backed by segdev and have type set to neither
3826          * MAP_SHARED nor MAP_PRIVATE.
3827          */
3828         if (seg->s_ops == &segdev_ops &&
3829             ((SEGOP_GETTYPE(seg, seg->s_base) &
3830             (MAP_SHARED | MAP_PRIVATE)) == 0))
3831                 return (0);
3832 
3833         /*
3834          * If this segment doesn't match one of the special types we handle,
3835          * just return the size of the segment itself.
3836          */
3837         return (size);
3838 }
3839 
3840 uint_t
3841 pr_getprot(struct seg *seg, int reserved, void **tmp,
3842         caddr_t *saddrp, caddr_t *naddrp, caddr_t eaddr)
3843 {
3844         struct as *as = seg->s_as;
3845 
3846         caddr_t saddr = *saddrp;
3847         caddr_t naddr;
3848 
3849         int check_noreserve;
3850         uint_t prot;
3851 
3852         union {
3853                 struct segvn_data *svd;
3854                 struct segdev_data *sdp;
3855                 void *data;
3856         } s;
3857 
3858         s.data = seg->s_data;
3859 
3860         ASSERT(AS_WRITE_HELD(as, &as->a_lock));
3861         ASSERT(saddr >= seg->s_base && saddr < eaddr);
3862         ASSERT(eaddr <= seg->s_base + seg->s_size);
3863 
3864         /*
3865          * Don't include MAP_NORESERVE pages in the address range
3866          * unless their mappings have actually materialized.
3867          * We cheat by knowing that segvn is the only segment
3868          * driver that supports MAP_NORESERVE.
3869          */
3870         check_noreserve =
3871             (!reserved && seg->s_ops == &segvn_ops && s.svd != NULL &&
3872             (s.svd->vp == NULL || s.svd->vp->v_type != VREG) &&
3873             (s.svd->flags & MAP_NORESERVE));
3874 
3875         /*
3876          * Examine every page only as a last resort.  We use guilty knowledge
3877          * of segvn and segdev to avoid this: if there are no per-page
3878          * protections present in the segment and we don't care about
3879          * MAP_NORESERVE, then s_data->prot is the prot for the whole segment.
3880          */
3881         if (!check_noreserve && saddr == seg->s_base &&
3882             seg->s_ops == &segvn_ops && s.svd != NULL && s.svd->pageprot == 0) {
3883                 prot = s.svd->prot;
3884                 getwatchprot(as, saddr, &prot);
3885                 naddr = eaddr;
3886 
3887         } else if (saddr == seg->s_base && seg->s_ops == &segdev_ops &&
3888             s.sdp != NULL && s.sdp->pageprot == 0) {
3889                 prot = s.sdp->prot;
3890                 getwatchprot(as, saddr, &prot);
3891                 naddr = eaddr;
3892 
3893         } else {
3894                 prpagev_t *pagev;
3895 
3896                 /*
3897                  * If addr is sitting at the start of the segment, then
3898                  * create a page vector to store protection and incore
3899                  * information for pages in the segment, and fill it.
3900                  * Otherwise, we expect *tmp to address the prpagev_t
3901                  * allocated by a previous call to this function.
3902                  */
3903                 if (saddr == seg->s_base) {
3904                         pagev = pr_pagev_create(seg, check_noreserve);
3905                         saddr = pr_pagev_fill(pagev, seg, saddr, eaddr);
3906 
3907                         ASSERT(*tmp == NULL);
3908                         *tmp = pagev;
3909 
3910                         ASSERT(saddr <= eaddr);
3911                         *saddrp = saddr;
3912 
3913                         if (saddr == eaddr) {
3914                                 naddr = saddr;
3915                                 prot = 0;
3916                                 goto out;
3917                         }
3918 
3919                 } else {
3920                         ASSERT(*tmp != NULL);
3921                         pagev = (prpagev_t *)*tmp;
3922                 }
3923 
3924                 naddr = pr_pagev_nextprot(pagev, seg, saddrp, eaddr, &prot);
3925                 ASSERT(naddr <= eaddr);
3926         }
3927 
3928 out:
3929         if (naddr == eaddr)
3930                 pr_getprot_done(tmp);
3931         *naddrp = naddr;
3932         return (prot);
3933 }
3934 
3935 void
3936 pr_getprot_done(void **tmp)
3937 {
3938         if (*tmp != NULL) {
3939                 pr_pagev_destroy((prpagev_t *)*tmp);
3940                 *tmp = NULL;
3941         }
3942 }
3943 
3944 /*
3945  * Return true iff the vnode is a /proc file from the object directory.
3946  */
3947 int
3948 pr_isobject(vnode_t *vp)
3949 {
3950         return (vn_matchops(vp, prvnodeops) && VTOP(vp)->pr_type == PR_OBJECT);
3951 }
3952 
3953 /*
3954  * Return true iff the vnode is a /proc file opened by the process itself.
3955  */
3956 int
3957 pr_isself(vnode_t *vp)
3958 {
3959         /*
3960          * XXX: To retain binary compatibility with the old
3961          * ioctl()-based version of /proc, we exempt self-opens
3962          * of /proc/<pid> from being marked close-on-exec.
3963          */
3964         return (vn_matchops(vp, prvnodeops) &&
3965             (VTOP(vp)->pr_flags & PR_ISSELF) &&
3966             VTOP(vp)->pr_type != PR_PIDDIR);
3967 }
3968 
3969 static ssize_t
3970 pr_getpagesize(struct seg *seg, caddr_t saddr, caddr_t *naddrp, caddr_t eaddr)
3971 {
3972         ssize_t pagesize, hatsize;
3973 
3974         ASSERT(AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
3975         ASSERT(IS_P2ALIGNED(saddr, PAGESIZE));
3976         ASSERT(IS_P2ALIGNED(eaddr, PAGESIZE));
3977         ASSERT(saddr < eaddr);
3978 
3979         pagesize = hatsize = hat_getpagesize(seg->s_as->a_hat, saddr);
3980         ASSERT(pagesize == -1 || IS_P2ALIGNED(pagesize, pagesize));
3981         ASSERT(pagesize != 0);
3982 
3983         if (pagesize == -1)
3984                 pagesize = PAGESIZE;
3985 
3986         saddr += P2NPHASE((uintptr_t)saddr, pagesize);
3987 
3988         while (saddr < eaddr) {
3989                 if (hatsize != hat_getpagesize(seg->s_as->a_hat, saddr))
3990                         break;
3991                 ASSERT(IS_P2ALIGNED(saddr, pagesize));
3992                 saddr += pagesize;
3993         }
3994 
3995         *naddrp = ((saddr < eaddr) ? saddr : eaddr);
3996         return (hatsize);
3997 }
3998 
3999 /*
4000  * Return an array of structures with extended memory map information.
4001  * We allocate here; the caller must deallocate.
4002  */
4003 int
4004 prgetxmap(proc_t *p, list_t *iolhead)
4005 {
4006         struct as *as = p->p_as;
4007         prxmap_t *mp;
4008         struct seg *seg;
4009         struct seg *brkseg, *stkseg;
4010         struct vnode *vp;
4011         struct vattr vattr;
4012         uint_t prot;
4013 
4014         ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
4015 
4016         /*
4017          * Request an initial buffer size that doesn't waste memory
4018          * if the address space has only a small number of segments.
4019          */
4020         pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4021 
4022         if ((seg = AS_SEGFIRST(as)) == NULL)
4023                 return (0);
4024 
4025         brkseg = break_seg(p);
4026         stkseg = as_segat(as, prgetstackbase(p));
4027 
4028         do {
4029                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4030                 caddr_t saddr, naddr, baddr;
4031                 void *tmp = NULL;
4032                 ssize_t psz;
4033                 char *parr;
4034                 uint64_t npages;
4035                 uint64_t pagenum;
4036 
4037                 /*
4038                  * Segment loop part one: iterate from the base of the segment
4039                  * to its end, pausing at each address boundary (baddr) between
4040                  * ranges that have different virtual memory protections.
4041                  */
4042                 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4043                         prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4044                         ASSERT(baddr >= saddr && baddr <= eaddr);
4045 
4046                         /*
4047                          * Segment loop part two: iterate from the current
4048                          * position to the end of the protection boundary,
4049                          * pausing at each address boundary (naddr) between
4050                          * ranges that have different underlying page sizes.
4051                          */
4052                         for (; saddr < baddr; saddr = naddr) {
4053                                 psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4054                                 ASSERT(naddr >= saddr && naddr <= baddr);
4055 
4056                                 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4057 
4058                                 mp->pr_vaddr = (uintptr_t)saddr;
4059                                 mp->pr_size = naddr - saddr;
4060                                 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4061                                 mp->pr_mflags = 0;
4062                                 if (prot & PROT_READ)
4063                                         mp->pr_mflags |= MA_READ;
4064                                 if (prot & PROT_WRITE)
4065                                         mp->pr_mflags |= MA_WRITE;
4066                                 if (prot & PROT_EXEC)
4067                                         mp->pr_mflags |= MA_EXEC;
4068                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4069                                         mp->pr_mflags |= MA_SHARED;
4070                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4071                                         mp->pr_mflags |= MA_NORESERVE;
4072                                 if (seg->s_ops == &segspt_shmops ||
4073                                     (seg->s_ops == &segvn_ops &&
4074                                     (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4075                                     vp == NULL)))
4076                                         mp->pr_mflags |= MA_ANON;
4077                                 if (seg == brkseg)
4078                                         mp->pr_mflags |= MA_BREAK;
4079                                 else if (seg == stkseg)
4080                                         mp->pr_mflags |= MA_STACK;
4081                                 if (seg->s_ops == &segspt_shmops)
4082                                         mp->pr_mflags |= MA_ISM | MA_SHM;
4083 
4084                                 mp->pr_pagesize = PAGESIZE;
4085                                 if (psz == -1) {
4086                                         mp->pr_hatpagesize = 0;
4087                                 } else {
4088                                         mp->pr_hatpagesize = psz;
4089                                 }
4090 
4091                                 /*
4092                                  * Manufacture a filename for the "object" dir.
4093                                  */
4094                                 mp->pr_dev = PRNODEV;
4095                                 vattr.va_mask = AT_FSID|AT_NODEID;
4096                                 if (seg->s_ops == &segvn_ops &&
4097                                     SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4098                                     vp != NULL && vp->v_type == VREG &&
4099                                     VOP_GETATTR(vp, &vattr, 0, CRED(),
4100                                     NULL) == 0) {
4101                                         mp->pr_dev = vattr.va_fsid;
4102                                         mp->pr_ino = vattr.va_nodeid;
4103                                         if (vp == p->p_exec)
4104                                                 (void) strcpy(mp->pr_mapname,
4105                                                     "a.out");
4106                                         else
4107                                                 pr_object_name(mp->pr_mapname,
4108                                                     vp, &vattr);
4109                                 }
4110 
4111                                 /*
4112                                  * Get the SysV shared memory id, if any.
4113                                  */
4114                                 if ((mp->pr_mflags & MA_SHARED) &&
4115                                     p->p_segacct && (mp->pr_shmid = shmgetid(p,
4116                                     seg->s_base)) != SHMID_NONE) {
4117                                         if (mp->pr_shmid == SHMID_FREE)
4118                                                 mp->pr_shmid = -1;
4119 
4120                                         mp->pr_mflags |= MA_SHM;
4121                                 } else {
4122                                         mp->pr_shmid = -1;
4123                                 }
4124 
4125                                 npages = ((uintptr_t)(naddr - saddr)) >>
4126                                     PAGESHIFT;
4127                                 parr = kmem_zalloc(npages, KM_SLEEP);
4128 
4129                                 SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4130 
4131                                 for (pagenum = 0; pagenum < npages; pagenum++) {
4132                                         if (parr[pagenum] & SEG_PAGE_INCORE)
4133                                                 mp->pr_rss++;
4134                                         if (parr[pagenum] & SEG_PAGE_ANON)
4135                                                 mp->pr_anon++;
4136                                         if (parr[pagenum] & SEG_PAGE_LOCKED)
4137                                                 mp->pr_locked++;
4138                                 }
4139                                 kmem_free(parr, npages);
4140                         }
4141                 }
4142                 ASSERT(tmp == NULL);
4143         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4144 
4145         return (0);
4146 }
4147 
4148 /*
4149  * Return the process's credentials.  We don't need a 32-bit equivalent of
4150  * this function because prcred_t and prcred32_t are actually the same.
4151  */
4152 void
4153 prgetcred(proc_t *p, prcred_t *pcrp)
4154 {
4155         mutex_enter(&p->p_crlock);
4156         cred2prcred(p->p_cred, pcrp);
4157         mutex_exit(&p->p_crlock);
4158 }
4159 
4160 /*
4161  * Compute actual size of the prpriv_t structure.
4162  */
4163 
4164 size_t
4165 prgetprivsize(void)
4166 {
4167         return (priv_prgetprivsize(NULL));
4168 }
4169 
4170 /*
4171  * Return the process's privileges.  We don't need a 32-bit equivalent of
4172  * this function because prpriv_t and prpriv32_t are actually the same.
4173  */
4174 void
4175 prgetpriv(proc_t *p, prpriv_t *pprp)
4176 {
4177         mutex_enter(&p->p_crlock);
4178         cred2prpriv(p->p_cred, pprp);
4179         mutex_exit(&p->p_crlock);
4180 }
4181 
4182 #ifdef _SYSCALL32_IMPL
4183 /*
4184  * Return an array of structures with HAT memory map information.
4185  * We allocate here; the caller must deallocate.
4186  */
4187 int
4188 prgetxmap32(proc_t *p, list_t *iolhead)
4189 {
4190         struct as *as = p->p_as;
4191         prxmap32_t *mp;
4192         struct seg *seg;
4193         struct seg *brkseg, *stkseg;
4194         struct vnode *vp;
4195         struct vattr vattr;
4196         uint_t prot;
4197 
4198         ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
4199 
4200         /*
4201          * Request an initial buffer size that doesn't waste memory
4202          * if the address space has only a small number of segments.
4203          */
4204         pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4205 
4206         if ((seg = AS_SEGFIRST(as)) == NULL)
4207                 return (0);
4208 
4209         brkseg = break_seg(p);
4210         stkseg = as_segat(as, prgetstackbase(p));
4211 
4212         do {
4213                 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4214                 caddr_t saddr, naddr, baddr;
4215                 void *tmp = NULL;
4216                 ssize_t psz;
4217                 char *parr;
4218                 uint64_t npages;
4219                 uint64_t pagenum;
4220 
4221                 /*
4222                  * Segment loop part one: iterate from the base of the segment
4223                  * to its end, pausing at each address boundary (baddr) between
4224                  * ranges that have different virtual memory protections.
4225                  */
4226                 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4227                         prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4228                         ASSERT(baddr >= saddr && baddr <= eaddr);
4229 
4230                         /*
4231                          * Segment loop part two: iterate from the current
4232                          * position to the end of the protection boundary,
4233                          * pausing at each address boundary (naddr) between
4234                          * ranges that have different underlying page sizes.
4235                          */
4236                         for (; saddr < baddr; saddr = naddr) {
4237                                 psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4238                                 ASSERT(naddr >= saddr && naddr <= baddr);
4239 
4240                                 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4241 
4242                                 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
4243                                 mp->pr_size = (size32_t)(naddr - saddr);
4244                                 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4245                                 mp->pr_mflags = 0;
4246                                 if (prot & PROT_READ)
4247                                         mp->pr_mflags |= MA_READ;
4248                                 if (prot & PROT_WRITE)
4249                                         mp->pr_mflags |= MA_WRITE;
4250                                 if (prot & PROT_EXEC)
4251                                         mp->pr_mflags |= MA_EXEC;
4252                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4253                                         mp->pr_mflags |= MA_SHARED;
4254                                 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4255                                         mp->pr_mflags |= MA_NORESERVE;
4256                                 if (seg->s_ops == &segspt_shmops ||
4257                                     (seg->s_ops == &segvn_ops &&
4258                                     (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4259                                     vp == NULL)))
4260                                         mp->pr_mflags |= MA_ANON;
4261                                 if (seg == brkseg)
4262                                         mp->pr_mflags |= MA_BREAK;
4263                                 else if (seg == stkseg)
4264                                         mp->pr_mflags |= MA_STACK;
4265                                 if (seg->s_ops == &segspt_shmops)
4266                                         mp->pr_mflags |= MA_ISM | MA_SHM;
4267 
4268                                 mp->pr_pagesize = PAGESIZE;
4269                                 if (psz == -1) {
4270                                         mp->pr_hatpagesize = 0;
4271                                 } else {
4272                                         mp->pr_hatpagesize = psz;
4273                                 }
4274 
4275                                 /*
4276                                  * Manufacture a filename for the "object" dir.
4277                                  */
4278                                 mp->pr_dev = PRNODEV32;
4279                                 vattr.va_mask = AT_FSID|AT_NODEID;
4280                                 if (seg->s_ops == &segvn_ops &&
4281                                     SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4282                                     vp != NULL && vp->v_type == VREG &&
4283                                     VOP_GETATTR(vp, &vattr, 0, CRED(),
4284                                     NULL) == 0) {
4285                                         (void) cmpldev(&mp->pr_dev,
4286                                             vattr.va_fsid);
4287                                         mp->pr_ino = vattr.va_nodeid;
4288                                         if (vp == p->p_exec)
4289                                                 (void) strcpy(mp->pr_mapname,
4290                                                     "a.out");
4291                                         else
4292                                                 pr_object_name(mp->pr_mapname,
4293                                                     vp, &vattr);
4294                                 }
4295 
4296                                 /*
4297                                  * Get the SysV shared memory id, if any.
4298                                  */
4299                                 if ((mp->pr_mflags & MA_SHARED) &&
4300                                     p->p_segacct && (mp->pr_shmid = shmgetid(p,
4301                                     seg->s_base)) != SHMID_NONE) {
4302                                         if (mp->pr_shmid == SHMID_FREE)
4303                                                 mp->pr_shmid = -1;
4304 
4305                                         mp->pr_mflags |= MA_SHM;
4306                                 } else {
4307                                         mp->pr_shmid = -1;
4308                                 }
4309 
4310                                 npages = ((uintptr_t)(naddr - saddr)) >>
4311                                     PAGESHIFT;
4312                                 parr = kmem_zalloc(npages, KM_SLEEP);
4313 
4314                                 SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4315 
4316                                 for (pagenum = 0; pagenum < npages; pagenum++) {
4317                                         if (parr[pagenum] & SEG_PAGE_INCORE)
4318                                                 mp->pr_rss++;
4319                                         if (parr[pagenum] & SEG_PAGE_ANON)
4320                                                 mp->pr_anon++;
4321                                         if (parr[pagenum] & SEG_PAGE_LOCKED)
4322                                                 mp->pr_locked++;
4323                                 }
4324                                 kmem_free(parr, npages);
4325                         }
4326                 }
4327                 ASSERT(tmp == NULL);
4328         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4329 
4330         return (0);
4331 }
4332 #endif  /* _SYSCALL32_IMPL */