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) 2014, 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/param.h>
  32 #include <sys/time.h>
  33 #include <sys/cred.h>
  34 #include <sys/policy.h>
  35 #include <sys/debug.h>
  36 #include <sys/dirent.h>
  37 #include <sys/errno.h>
  38 #include <sys/file.h>
  39 #include <sys/inline.h>
  40 #include <sys/kmem.h>
  41 #include <sys/pathname.h>
  42 #include <sys/proc.h>
  43 #include <sys/brand.h>
  44 #include <sys/signal.h>
  45 #include <sys/stat.h>
  46 #include <sys/sysmacros.h>
  47 #include <sys/systm.h>
  48 #include <sys/zone.h>
  49 #include <sys/uio.h>
  50 #include <sys/var.h>
  51 #include <sys/mode.h>
  52 #include <sys/poll.h>
  53 #include <sys/user.h>
  54 #include <sys/vfs.h>
  55 #include <sys/vfs_opreg.h>
  56 #include <sys/gfs.h>
  57 #include <sys/vnode.h>
  58 #include <sys/fault.h>
  59 #include <sys/syscall.h>
  60 #include <sys/procfs.h>
  61 #include <sys/atomic.h>
  62 #include <sys/cmn_err.h>
  63 #include <sys/contract_impl.h>
  64 #include <sys/ctfs.h>
  65 #include <sys/avl.h>
  66 #include <fs/fs_subr.h>
  67 #include <vm/rm.h>
  68 #include <vm/as.h>
  69 #include <vm/seg.h>
  70 #include <vm/seg_vn.h>
  71 #include <vm/hat.h>
  72 #include <fs/proc/prdata.h>
  73 #if defined(__sparc)
  74 #include <sys/regset.h>
  75 #endif
  76 #if defined(__x86)
  77 #include <sys/sysi86.h>
  78 #endif
  79 
  80 /*
  81  * Created by prinit.
  82  */
  83 vnodeops_t *prvnodeops;
  84 
  85 /*
  86  * Directory characteristics (patterned after the s5 file system).
  87  */
  88 #define PRROOTINO       2
  89 
  90 #define PRDIRSIZE       14
  91 struct prdirect {
  92         ushort_t        d_ino;
  93         char            d_name[PRDIRSIZE];
  94 };
  95 
  96 #define PRSDSIZE        (sizeof (struct prdirect))
  97 
  98 /*
  99  * Directory characteristics.
 100  */
 101 typedef struct prdirent {
 102         ino64_t         d_ino;          /* "inode number" of entry */
 103         off64_t         d_off;          /* offset of disk directory entry */
 104         unsigned short  d_reclen;       /* length of this record */
 105         char            d_name[14];     /* name of file */
 106 } prdirent_t;
 107 
 108 /*
 109  * Contents of a /proc/<pid> directory.
 110  * Reuse d_ino field for the /proc file type.
 111  */
 112 static prdirent_t piddir[] = {
 113         { PR_PIDDIR,     1 * sizeof (prdirent_t), sizeof (prdirent_t),
 114                 "." },
 115         { PR_PROCDIR,    2 * sizeof (prdirent_t), sizeof (prdirent_t),
 116                 ".." },
 117         { PR_AS,         3 * sizeof (prdirent_t), sizeof (prdirent_t),
 118                 "as" },
 119         { PR_CTL,        4 * sizeof (prdirent_t), sizeof (prdirent_t),
 120                 "ctl" },
 121         { PR_STATUS,     5 * sizeof (prdirent_t), sizeof (prdirent_t),
 122                 "status" },
 123         { PR_LSTATUS,    6 * sizeof (prdirent_t), sizeof (prdirent_t),
 124                 "lstatus" },
 125         { PR_PSINFO,     7 * sizeof (prdirent_t), sizeof (prdirent_t),
 126                 "psinfo" },
 127         { PR_LPSINFO,    8 * sizeof (prdirent_t), sizeof (prdirent_t),
 128                 "lpsinfo" },
 129         { PR_MAP,        9 * sizeof (prdirent_t), sizeof (prdirent_t),
 130                 "map" },
 131         { PR_RMAP,      10 * sizeof (prdirent_t), sizeof (prdirent_t),
 132                 "rmap" },
 133         { PR_XMAP,      11 * sizeof (prdirent_t), sizeof (prdirent_t),
 134                 "xmap" },
 135         { PR_CRED,      12 * sizeof (prdirent_t), sizeof (prdirent_t),
 136                 "cred" },
 137         { PR_SIGACT,    13 * sizeof (prdirent_t), sizeof (prdirent_t),
 138                 "sigact" },
 139         { PR_AUXV,      14 * sizeof (prdirent_t), sizeof (prdirent_t),
 140                 "auxv" },
 141         { PR_USAGE,     15 * sizeof (prdirent_t), sizeof (prdirent_t),
 142                 "usage" },
 143         { PR_LUSAGE,    16 * sizeof (prdirent_t), sizeof (prdirent_t),
 144                 "lusage" },
 145         { PR_PAGEDATA,  17 * sizeof (prdirent_t), sizeof (prdirent_t),
 146                 "pagedata" },
 147         { PR_WATCH,     18 * sizeof (prdirent_t), sizeof (prdirent_t),
 148                 "watch" },
 149         { PR_CURDIR,    19 * sizeof (prdirent_t), sizeof (prdirent_t),
 150                 "cwd" },
 151         { PR_ROOTDIR,   20 * sizeof (prdirent_t), sizeof (prdirent_t),
 152                 "root" },
 153         { PR_FDDIR,     21 * sizeof (prdirent_t), sizeof (prdirent_t),
 154                 "fd" },
 155         { PR_OBJECTDIR, 22 * sizeof (prdirent_t), sizeof (prdirent_t),
 156                 "object" },
 157         { PR_LWPDIR,    23 * sizeof (prdirent_t), sizeof (prdirent_t),
 158                 "lwp" },
 159         { PR_PRIV,      24 * sizeof (prdirent_t), sizeof (prdirent_t),
 160                 "priv" },
 161         { PR_PATHDIR,   25 * sizeof (prdirent_t), sizeof (prdirent_t),
 162                 "path" },
 163         { PR_CTDIR,     26 * sizeof (prdirent_t), sizeof (prdirent_t),
 164                 "contracts" },
 165         { PR_SECFLAGS,  27 * sizeof (prdirent_t), sizeof (prdirent_t),
 166                 "secflags" },
 167 #if defined(__x86)
 168         { PR_LDT,       28 * sizeof (prdirent_t), sizeof (prdirent_t),
 169                 "ldt" },
 170 #endif
 171 };
 172 
 173 #define NPIDDIRFILES    (sizeof (piddir) / sizeof (piddir[0]) - 2)
 174 
 175 /*
 176  * Contents of a /proc/<pid>/lwp/<lwpid> directory.
 177  */
 178 static prdirent_t lwpiddir[] = {
 179         { PR_LWPIDDIR,   1 * sizeof (prdirent_t), sizeof (prdirent_t),
 180                 "." },
 181         { PR_LWPDIR,     2 * sizeof (prdirent_t), sizeof (prdirent_t),
 182                 ".." },
 183         { PR_LWPCTL,     3 * sizeof (prdirent_t), sizeof (prdirent_t),
 184                 "lwpctl" },
 185         { PR_LWPSTATUS,  4 * sizeof (prdirent_t), sizeof (prdirent_t),
 186                 "lwpstatus" },
 187         { PR_LWPSINFO,   5 * sizeof (prdirent_t), sizeof (prdirent_t),
 188                 "lwpsinfo" },
 189         { PR_LWPUSAGE,   6 * sizeof (prdirent_t), sizeof (prdirent_t),
 190                 "lwpusage" },
 191         { PR_XREGS,      7 * sizeof (prdirent_t), sizeof (prdirent_t),
 192                 "xregs" },
 193         { PR_TMPLDIR,    8 * sizeof (prdirent_t), sizeof (prdirent_t),
 194                 "templates" },
 195         { PR_SPYMASTER,  9 * sizeof (prdirent_t), sizeof (prdirent_t),
 196                 "spymaster" },
 197 #if defined(__sparc)
 198         { PR_GWINDOWS,  10 * sizeof (prdirent_t), sizeof (prdirent_t),
 199                 "gwindows" },
 200         { PR_ASRS,      11 * sizeof (prdirent_t), sizeof (prdirent_t),
 201                 "asrs" },
 202 #endif
 203 };
 204 
 205 #define NLWPIDDIRFILES  (sizeof (lwpiddir) / sizeof (lwpiddir[0]) - 2)
 206 
 207 /*
 208  * Span of entries in the array files (lstatus, lpsinfo, lusage).
 209  * We make the span larger than the size of the structure on purpose,
 210  * to make sure that programs cannot use the structure size by mistake.
 211  * Align _ILP32 structures at 8 bytes, _LP64 structures at 16 bytes.
 212  */
 213 #ifdef _LP64
 214 #define LSPAN(type)     (round16(sizeof (type)) + 16)
 215 #define LSPAN32(type)   (round8(sizeof (type)) + 8)
 216 #else
 217 #define LSPAN(type)     (round8(sizeof (type)) + 8)
 218 #endif
 219 
 220 static void rebuild_objdir(struct as *);
 221 static void prfreecommon(prcommon_t *);
 222 static int praccess(vnode_t *, int, int, cred_t *, caller_context_t *);
 223 
 224 static int
 225 propen(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct)
 226 {
 227         vnode_t *vp = *vpp;
 228         prnode_t *pnp = VTOP(vp);
 229         prcommon_t *pcp = pnp->pr_pcommon;
 230         prnodetype_t type = pnp->pr_type;
 231         vnode_t *rvp;
 232         vtype_t vtype;
 233         proc_t *p;
 234         int error = 0;
 235         prnode_t *npnp = NULL;
 236 
 237         /*
 238          * Nothing to do for the /proc directory itself.
 239          */
 240         if (type == PR_PROCDIR)
 241                 return (0);
 242 
 243         /*
 244          * If we are opening an underlying mapped object, reject opens
 245          * for writing regardless of the objects's access modes.
 246          * If we are opening a file in the /proc/pid/fd directory,
 247          * reject the open for any but a regular file or directory.
 248          * Just do it if we are opening the current or root directory.
 249          */
 250         switch (type) {
 251         case PR_OBJECT:
 252         case PR_FD:
 253         case PR_CURDIR:
 254         case PR_ROOTDIR:
 255                 rvp = pnp->pr_realvp;
 256                 vtype = rvp->v_type;
 257                 if ((type == PR_OBJECT && (flag & FWRITE)) ||
 258                     (type == PR_FD && vtype != VREG && vtype != VDIR))
 259                         error = EACCES;
 260                 else {
 261                         /*
 262                          * Need to hold rvp since VOP_OPEN() may release it.
 263                          */
 264                         VN_HOLD(rvp);
 265                         error = VOP_OPEN(&rvp, flag, cr, ct);
 266                         if (error) {
 267                                 VN_RELE(rvp);
 268                         } else {
 269                                 *vpp = rvp;
 270                                 VN_RELE(vp);
 271                         }
 272                 }
 273                 return (error);
 274         default:
 275                 break;
 276         }
 277 
 278         /*
 279          * If we are opening the pagedata file, allocate a prnode now
 280          * to avoid calling kmem_alloc() while holding p->p_lock.
 281          */
 282         if (type == PR_PAGEDATA || type == PR_OPAGEDATA)
 283                 npnp = prgetnode(vp, type);
 284 
 285         /*
 286          * If the process exists, lock it now.
 287          * Otherwise we have a race condition with prclose().
 288          */
 289         p = pr_p_lock(pnp);
 290         mutex_exit(&pr_pidlock);
 291         if (p == NULL) {
 292                 if (npnp != NULL)
 293                         prfreenode(npnp);
 294                 return (ENOENT);
 295         }
 296         ASSERT(p == pcp->prc_proc);
 297         ASSERT(p->p_proc_flag & P_PR_LOCK);
 298 
 299         /*
 300          * Maintain a count of opens for write.  Allow exactly one
 301          * O_WRITE|O_EXCL request and fail subsequent ones.
 302          * Don't fail opens of old (bletch!) /proc lwp files.
 303          * Special case for open by the process itself:
 304          * Always allow the open by self and discount this
 305          * open for other opens for writing.
 306          */
 307         if (flag & FWRITE) {
 308                 if (p == curproc) {
 309                         pcp->prc_selfopens++;
 310                         pnp->pr_flags |= PR_ISSELF;
 311                 } else if (type == PR_LWPIDFILE) {
 312                         /* EMPTY */;
 313                 } else if (flag & FEXCL) {
 314                         if (pcp->prc_writers > pcp->prc_selfopens) {
 315                                 error = EBUSY;
 316                                 goto out;
 317                         }
 318                         /* semantic for old /proc interface */
 319                         if (type == PR_PIDDIR)
 320                                 pcp->prc_flags |= PRC_EXCL;
 321                 } else if (pcp->prc_flags & PRC_EXCL) {
 322                         ASSERT(pcp->prc_writers > pcp->prc_selfopens);
 323                         error = secpolicy_proc_excl_open(cr);
 324                         if (error)
 325                                 goto out;
 326                 }
 327                 pcp->prc_writers++;
 328                 /*
 329                  * The vnode may have become invalid between the
 330                  * VOP_LOOKUP() of the /proc vnode and the VOP_OPEN().
 331                  * If so, do now what prinvalidate() should have done.
 332                  */
 333                 if ((pnp->pr_flags & PR_INVAL) ||
 334                     (type == PR_PIDDIR &&
 335                     (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
 336                         if (p != curproc)
 337                                 pcp->prc_selfopens++;
 338                         ASSERT(pcp->prc_selfopens <= pcp->prc_writers);
 339                         if (pcp->prc_selfopens == pcp->prc_writers)
 340                                 pcp->prc_flags &= ~PRC_EXCL;
 341                 }
 342         }
 343 
 344         /*
 345          * If this is a large file open, indicate that in our flags -- some
 346          * procfs structures are not off_t-neutral (e.g., priovec_t), and
 347          * the open will need to be differentiated where 32-bit processes
 348          * pass these structures across the user/kernel boundary.
 349          */
 350         if (flag & FOFFMAX)
 351                 pnp->pr_flags |= PR_OFFMAX;
 352 
 353         /*
 354          * Do file-specific things.
 355          */
 356         switch (type) {
 357         default:
 358                 break;
 359         case PR_PAGEDATA:
 360         case PR_OPAGEDATA:
 361                 /*
 362                  * Enable data collection for page data file;
 363                  * get unique id from the hat layer.
 364                  */
 365                 {
 366                         int id;
 367 
 368                         /*
 369                          * Drop p->p_lock to call hat_startstat()
 370                          */
 371                         mutex_exit(&p->p_lock);
 372                         if ((p->p_flag & SSYS) || p->p_as == &kas ||
 373                             (id = hat_startstat(p->p_as)) == -1) {
 374                                 mutex_enter(&p->p_lock);
 375                                 error = ENOMEM;
 376                         } else if (pnp->pr_hatid == 0) {
 377                                 mutex_enter(&p->p_lock);
 378                                 pnp->pr_hatid = (uint_t)id;
 379                         } else {
 380                                 mutex_enter(&p->p_lock);
 381                                 /*
 382                                  * Use our newly allocated prnode.
 383                                  */
 384                                 npnp->pr_hatid = (uint_t)id;
 385                                 /*
 386                                  * prgetnode() initialized most of the prnode.
 387                                  * Duplicate the remainder.
 388                                  */
 389                                 npnp->pr_ino = pnp->pr_ino;
 390                                 npnp->pr_common = pnp->pr_common;
 391                                 npnp->pr_pcommon = pnp->pr_pcommon;
 392                                 npnp->pr_parent = pnp->pr_parent;
 393                                 VN_HOLD(npnp->pr_parent);
 394                                 npnp->pr_index = pnp->pr_index;
 395 
 396                                 npnp->pr_next = p->p_plist;
 397                                 p->p_plist = PTOV(npnp);
 398 
 399                                 VN_RELE(PTOV(pnp));
 400                                 pnp = npnp;
 401                                 npnp = NULL;
 402                                 *vpp = PTOV(pnp);
 403                         }
 404                 }
 405                 break;
 406         }
 407 
 408 out:
 409         prunlock(pnp);
 410 
 411         if (npnp != NULL)
 412                 prfreenode(npnp);
 413         return (error);
 414 }
 415 
 416 /* ARGSUSED */
 417 static int
 418 prclose(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
 419     caller_context_t *ct)
 420 {
 421         prnode_t *pnp = VTOP(vp);
 422         prcommon_t *pcp = pnp->pr_pcommon;
 423         prnodetype_t type = pnp->pr_type;
 424         proc_t *p;
 425         kthread_t *t;
 426         user_t *up;
 427 
 428         /*
 429          * Nothing to do for the /proc directory itself.
 430          */
 431         if (type == PR_PROCDIR)
 432                 return (0);
 433 
 434         ASSERT(type != PR_OBJECT && type != PR_FD &&
 435             type != PR_CURDIR && type != PR_ROOTDIR);
 436 
 437         /*
 438          * If the process exists, lock it now.
 439          * Otherwise we have a race condition with propen().
 440          * Hold pr_pidlock across the reference to prc_selfopens,
 441          * and prc_writers in case there is no process anymore,
 442          * to cover the case of concurrent calls to prclose()
 443          * after the process has been reaped by freeproc().
 444          */
 445         p = pr_p_lock(pnp);
 446 
 447         /*
 448          * There is nothing more to do until the last close of
 449          * the file table entry except to clear the pr_owner
 450          * field of the prnode and notify any waiters
 451          * (their file descriptor may have just been closed).
 452          */
 453         if (count > 1) {
 454                 mutex_exit(&pr_pidlock);
 455                 if (pnp->pr_owner == curproc && !fisopen(vp))
 456                         pnp->pr_owner = NULL;
 457                 if (p != NULL) {
 458                         prnotify(vp);
 459                         prunlock(pnp);
 460                 }
 461                 return (0);
 462         }
 463 
 464         /*
 465          * Decrement the count of self-opens for writing.
 466          * Decrement the total count of opens for writing.
 467          * Cancel exclusive opens when only self-opens remain.
 468          */
 469         if (flag & FWRITE) {
 470                 /*
 471                  * prc_selfopens also contains the count of
 472                  * invalid writers.  See prinvalidate().
 473                  */
 474                 if ((pnp->pr_flags & (PR_ISSELF|PR_INVAL)) ||
 475                     (type == PR_PIDDIR &&
 476                     (VTOP(pnp->pr_pidfile)->pr_flags & PR_INVAL))) {
 477                         ASSERT(pcp->prc_selfopens != 0);
 478                         --pcp->prc_selfopens;
 479                 }
 480                 ASSERT(pcp->prc_writers != 0);
 481                 if (--pcp->prc_writers == pcp->prc_selfopens)
 482                         pcp->prc_flags &= ~PRC_EXCL;
 483         }
 484         ASSERT(pcp->prc_writers >= pcp->prc_selfopens);
 485         mutex_exit(&pr_pidlock);
 486         if (pnp->pr_owner == curproc && !fisopen(vp))
 487                 pnp->pr_owner = NULL;
 488 
 489         /*
 490          * If there is no process, there is nothing more to do.
 491          */
 492         if (p == NULL)
 493                 return (0);
 494 
 495         ASSERT(p == pcp->prc_proc);
 496         prnotify(vp);   /* notify waiters */
 497 
 498         /*
 499          * Do file-specific things.
 500          */
 501         switch (type) {
 502         default:
 503                 break;
 504         case PR_PAGEDATA:
 505         case PR_OPAGEDATA:
 506                 /*
 507                  * This is a page data file.
 508                  * Free the hat level statistics.
 509                  * Drop p->p_lock before calling hat_freestat().
 510                  */
 511                 mutex_exit(&p->p_lock);
 512                 if (p->p_as != &kas && pnp->pr_hatid != 0)
 513                         hat_freestat(p->p_as, pnp->pr_hatid);
 514                 mutex_enter(&p->p_lock);
 515                 pnp->pr_hatid = 0;
 516                 break;
 517         }
 518 
 519         /*
 520          * On last close of all writable file descriptors,
 521          * perform run-on-last-close and/or kill-on-last-close logic.
 522          * Can't do this is the /proc agent lwp still exists.
 523          */
 524         if (pcp->prc_writers == 0 &&
 525             p->p_agenttp == NULL &&
 526             !(pcp->prc_flags & PRC_DESTROY) &&
 527             p->p_stat != SZOMB &&
 528             (p->p_proc_flag & (P_PR_RUNLCL|P_PR_KILLCL))) {
 529                 int killproc;
 530 
 531                 /*
 532                  * Cancel any watchpoints currently in effect.
 533                  * The process might disappear during this operation.
 534                  */
 535                 if (pr_cancel_watch(pnp) == NULL)
 536                         return (0);
 537                 /*
 538                  * If any tracing flags are set, clear them.
 539                  */
 540                 if (p->p_proc_flag & P_PR_TRACE) {
 541                         up = PTOU(p);
 542                         premptyset(&up->u_entrymask);
 543                         premptyset(&up->u_exitmask);
 544                         up->u_systrap = 0;
 545                 }
 546                 premptyset(&p->p_sigmask);
 547                 premptyset(&p->p_fltmask);
 548                 killproc = (p->p_proc_flag & P_PR_KILLCL);
 549                 p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE);
 550                 /*
 551                  * Cancel any outstanding single-step requests.
 552                  */
 553                 if ((t = p->p_tlist) != NULL) {
 554                         /*
 555                          * Drop p_lock because prnostep() touches the stack.
 556                          * The loop is safe because the process is P_PR_LOCK'd.
 557                          */
 558                         mutex_exit(&p->p_lock);
 559                         do {
 560                                 prnostep(ttolwp(t));
 561                         } while ((t = t->t_forw) != p->p_tlist);
 562                         mutex_enter(&p->p_lock);
 563                 }
 564                 /*
 565                  * Set runnable all lwps stopped by /proc.
 566                  */
 567                 if (killproc)
 568                         sigtoproc(p, NULL, SIGKILL);
 569                 else
 570                         allsetrun(p);
 571         }
 572 
 573         prunlock(pnp);
 574         return (0);
 575 }
 576 
 577 /*
 578  * Array of read functions, indexed by /proc file type.
 579  */
 580 static int pr_read_inval(), pr_read_as(), pr_read_status(),
 581         pr_read_lstatus(), pr_read_psinfo(), pr_read_lpsinfo(),
 582         pr_read_map(), pr_read_rmap(), pr_read_xmap(),
 583         pr_read_cred(), pr_read_sigact(), pr_read_auxv(),
 584 #if defined(__x86)
 585         pr_read_ldt(),
 586 #endif
 587         pr_read_usage(), pr_read_lusage(), pr_read_pagedata(),
 588         pr_read_watch(), pr_read_lwpstatus(), pr_read_lwpsinfo(),
 589         pr_read_lwpusage(), pr_read_xregs(), pr_read_priv(),
 590         pr_read_spymaster(), pr_read_secflags(),
 591 #if defined(__sparc)
 592         pr_read_gwindows(), pr_read_asrs(),
 593 #endif
 594         pr_read_piddir(), pr_read_pidfile(), pr_read_opagedata();
 595 
 596 static int (*pr_read_function[PR_NFILES])() = {
 597         pr_read_inval,          /* /proc                                */
 598         pr_read_inval,          /* /proc/self                           */
 599         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
 600         pr_read_as,             /* /proc/<pid>/as                 */
 601         pr_read_inval,          /* /proc/<pid>/ctl                        */
 602         pr_read_status,         /* /proc/<pid>/status                     */
 603         pr_read_lstatus,        /* /proc/<pid>/lstatus                    */
 604         pr_read_psinfo,         /* /proc/<pid>/psinfo                     */
 605         pr_read_lpsinfo,        /* /proc/<pid>/lpsinfo                    */
 606         pr_read_map,            /* /proc/<pid>/map                        */
 607         pr_read_rmap,           /* /proc/<pid>/rmap                       */
 608         pr_read_xmap,           /* /proc/<pid>/xmap                       */
 609         pr_read_cred,           /* /proc/<pid>/cred                       */
 610         pr_read_sigact,         /* /proc/<pid>/sigact                     */
 611         pr_read_auxv,           /* /proc/<pid>/auxv                       */
 612 #if defined(__x86)
 613         pr_read_ldt,            /* /proc/<pid>/ldt                        */
 614 #endif
 615         pr_read_usage,          /* /proc/<pid>/usage                      */
 616         pr_read_lusage,         /* /proc/<pid>/lusage                     */
 617         pr_read_pagedata,       /* /proc/<pid>/pagedata                   */
 618         pr_read_watch,          /* /proc/<pid>/watch                      */
 619         pr_read_inval,          /* /proc/<pid>/cwd                        */
 620         pr_read_inval,          /* /proc/<pid>/root                       */
 621         pr_read_inval,          /* /proc/<pid>/fd                 */
 622         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
 623         pr_read_inval,          /* /proc/<pid>/object                     */
 624         pr_read_inval,          /* /proc/<pid>/object/xxx         */
 625         pr_read_inval,          /* /proc/<pid>/lwp                        */
 626         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
 627         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
 628         pr_read_lwpstatus,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
 629         pr_read_lwpsinfo,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
 630         pr_read_lwpusage,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
 631         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
 632         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
 633         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 634         pr_read_spymaster,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 635 #if defined(__sparc)
 636         pr_read_gwindows,       /* /proc/<pid>/lwp/<lwpid>/gwindows */
 637         pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs             */
 638 #endif
 639         pr_read_priv,           /* /proc/<pid>/priv                       */
 640         pr_read_inval,          /* /proc/<pid>/path                       */
 641         pr_read_inval,          /* /proc/<pid>/path/xxx                   */
 642         pr_read_inval,          /* /proc/<pid>/contracts          */
 643         pr_read_inval,          /* /proc/<pid>/contracts/<ctid>             */
 644         pr_read_secflags,       /* /proc/<pid>/secflags                   */
 645         pr_read_pidfile,        /* old process file                     */
 646         pr_read_pidfile,        /* old lwp file                         */
 647         pr_read_opagedata,      /* old pagedata file                    */
 648 };
 649 
 650 /* ARGSUSED */
 651 static int
 652 pr_read_inval(prnode_t *pnp, uio_t *uiop)
 653 {
 654         /*
 655          * No read() on any /proc directory, use getdents(2) instead.
 656          * Cannot read a control file either.
 657          * An underlying mapped object file cannot get here.
 658          */
 659         return (EINVAL);
 660 }
 661 
 662 static int
 663 pr_uioread(void *base, long count, uio_t *uiop)
 664 {
 665         int error = 0;
 666 
 667         ASSERT(count >= 0);
 668         count -= uiop->uio_offset;
 669         if (count > 0 && uiop->uio_offset >= 0) {
 670                 error = uiomove((char *)base + uiop->uio_offset,
 671                     count, UIO_READ, uiop);
 672         }
 673 
 674         return (error);
 675 }
 676 
 677 static int
 678 pr_read_as(prnode_t *pnp, uio_t *uiop)
 679 {
 680         int error;
 681 
 682         ASSERT(pnp->pr_type == PR_AS);
 683 
 684         if ((error = prlock(pnp, ZNO)) == 0) {
 685                 proc_t *p = pnp->pr_common->prc_proc;
 686                 struct as *as = p->p_as;
 687 
 688                 /*
 689                  * /proc I/O cannot be done to a system process.
 690                  * A 32-bit process cannot read a 64-bit process.
 691                  */
 692                 if ((p->p_flag & SSYS) || as == &kas) {
 693                         error = 0;
 694 #ifdef _SYSCALL32_IMPL
 695                 } else if (curproc->p_model == DATAMODEL_ILP32 &&
 696                     PROCESS_NOT_32BIT(p)) {
 697                         error = EOVERFLOW;
 698 #endif
 699                 } else {
 700                         /*
 701                          * We don't hold p_lock over an i/o operation because
 702                          * that could lead to deadlock with the clock thread.
 703                          */
 704                         mutex_exit(&p->p_lock);
 705                         error = prusrio(p, UIO_READ, uiop, 0);
 706                         mutex_enter(&p->p_lock);
 707                 }
 708                 prunlock(pnp);
 709         }
 710 
 711         return (error);
 712 }
 713 
 714 static int
 715 pr_read_status(prnode_t *pnp, uio_t *uiop)
 716 {
 717         pstatus_t *sp;
 718         int error;
 719 
 720         ASSERT(pnp->pr_type == PR_STATUS);
 721 
 722         /*
 723          * We kmem_alloc() the pstatus structure because
 724          * it is so big it might blow the kernel stack.
 725          */
 726         sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
 727         if ((error = prlock(pnp, ZNO)) == 0) {
 728                 prgetstatus(pnp->pr_common->prc_proc, sp, VTOZONE(PTOV(pnp)));
 729                 prunlock(pnp);
 730                 error = pr_uioread(sp, sizeof (*sp), uiop);
 731         }
 732         kmem_free(sp, sizeof (*sp));
 733         return (error);
 734 }
 735 
 736 static int
 737 pr_read_lstatus(prnode_t *pnp, uio_t *uiop)
 738 {
 739         proc_t *p;
 740         kthread_t *t;
 741         lwpdir_t *ldp;
 742         size_t size;
 743         prheader_t *php;
 744         lwpstatus_t *sp;
 745         int error;
 746         int nlwp;
 747         int i;
 748 
 749         ASSERT(pnp->pr_type == PR_LSTATUS);
 750 
 751         if ((error = prlock(pnp, ZNO)) != 0)
 752                 return (error);
 753         p = pnp->pr_common->prc_proc;
 754         nlwp = p->p_lwpcnt;
 755         size = sizeof (prheader_t) + nlwp * LSPAN(lwpstatus_t);
 756 
 757         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
 758         mutex_exit(&p->p_lock);
 759         php = kmem_zalloc(size, KM_SLEEP);
 760         mutex_enter(&p->p_lock);
 761         /* p->p_lwpcnt can't change while process is locked */
 762         ASSERT(nlwp == p->p_lwpcnt);
 763 
 764         php->pr_nent = nlwp;
 765         php->pr_entsize = LSPAN(lwpstatus_t);
 766 
 767         sp = (lwpstatus_t *)(php + 1);
 768         for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
 769                 if (ldp->ld_entry == NULL ||
 770                     (t = ldp->ld_entry->le_thread) == NULL)
 771                         continue;
 772                 prgetlwpstatus(t, sp, VTOZONE(PTOV(pnp)));
 773                 sp = (lwpstatus_t *)((caddr_t)sp + LSPAN(lwpstatus_t));
 774         }
 775         prunlock(pnp);
 776 
 777         error = pr_uioread(php, size, uiop);
 778         kmem_free(php, size);
 779         return (error);
 780 }
 781 
 782 static int
 783 pr_read_psinfo(prnode_t *pnp, uio_t *uiop)
 784 {
 785         psinfo_t psinfo;
 786         proc_t *p;
 787         int error = 0;
 788 
 789         ASSERT(pnp->pr_type == PR_PSINFO);
 790 
 791         /*
 792          * We don't want the full treatment of prlock(pnp) here.
 793          * This file is world-readable and never goes invalid.
 794          * It doesn't matter if we are in the middle of an exec().
 795          */
 796         p = pr_p_lock(pnp);
 797         mutex_exit(&pr_pidlock);
 798         if (p == NULL)
 799                 error = ENOENT;
 800         else {
 801                 ASSERT(p == pnp->pr_common->prc_proc);
 802                 prgetpsinfo(p, &psinfo);
 803                 prunlock(pnp);
 804                 error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
 805         }
 806         return (error);
 807 }
 808 
 809 static int
 810 pr_read_lpsinfo(prnode_t *pnp, uio_t *uiop)
 811 {
 812         proc_t *p;
 813         kthread_t *t;
 814         lwpdir_t *ldp;
 815         lwpent_t *lep;
 816         size_t size;
 817         prheader_t *php;
 818         lwpsinfo_t *sp;
 819         int error;
 820         int nlwp;
 821         int i;
 822 
 823         ASSERT(pnp->pr_type == PR_LPSINFO);
 824 
 825         /*
 826          * We don't want the full treatment of prlock(pnp) here.
 827          * This file is world-readable and never goes invalid.
 828          * It doesn't matter if we are in the middle of an exec().
 829          */
 830         p = pr_p_lock(pnp);
 831         mutex_exit(&pr_pidlock);
 832         if (p == NULL)
 833                 return (ENOENT);
 834         ASSERT(p == pnp->pr_common->prc_proc);
 835         if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
 836                 prunlock(pnp);
 837                 return (ENOENT);
 838         }
 839         size = sizeof (prheader_t) + nlwp * LSPAN(lwpsinfo_t);
 840 
 841         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
 842         mutex_exit(&p->p_lock);
 843         php = kmem_zalloc(size, KM_SLEEP);
 844         mutex_enter(&p->p_lock);
 845         /* p->p_lwpcnt can't change while process is locked */
 846         ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
 847 
 848         php->pr_nent = nlwp;
 849         php->pr_entsize = LSPAN(lwpsinfo_t);
 850 
 851         sp = (lwpsinfo_t *)(php + 1);
 852         for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
 853                 if ((lep = ldp->ld_entry) == NULL)
 854                         continue;
 855                 if ((t = lep->le_thread) != NULL)
 856                         prgetlwpsinfo(t, sp);
 857                 else {
 858                         bzero(sp, sizeof (*sp));
 859                         sp->pr_lwpid = lep->le_lwpid;
 860                         sp->pr_state = SZOMB;
 861                         sp->pr_sname = 'Z';
 862                         sp->pr_start.tv_sec = lep->le_start;
 863                         sp->pr_bindpro = PBIND_NONE;
 864                         sp->pr_bindpset = PS_NONE;
 865                 }
 866                 sp = (lwpsinfo_t *)((caddr_t)sp + LSPAN(lwpsinfo_t));
 867         }
 868         prunlock(pnp);
 869 
 870         error = pr_uioread(php, size, uiop);
 871         kmem_free(php, size);
 872         return (error);
 873 }
 874 
 875 static int
 876 pr_read_map_common(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
 877 {
 878         proc_t *p;
 879         struct as *as;
 880         list_t iolhead;
 881         int error;
 882 
 883 readmap_common:
 884         if ((error = prlock(pnp, ZNO)) != 0)
 885                 return (error);
 886 
 887         p = pnp->pr_common->prc_proc;
 888         as = p->p_as;
 889 
 890         if ((p->p_flag & SSYS) || as == &kas) {
 891                 prunlock(pnp);
 892                 return (0);
 893         }
 894 
 895         if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
 896                 prunlock(pnp);
 897                 delay(1);
 898                 goto readmap_common;
 899         }
 900         mutex_exit(&p->p_lock);
 901 
 902         switch (type) {
 903         case PR_XMAP:
 904                 error = prgetxmap(p, &iolhead);
 905                 break;
 906         case PR_RMAP:
 907                 error = prgetmap(p, 1, &iolhead);
 908                 break;
 909         case PR_MAP:
 910                 error = prgetmap(p, 0, &iolhead);
 911                 break;
 912         }
 913 
 914         AS_LOCK_EXIT(as);
 915         mutex_enter(&p->p_lock);
 916         prunlock(pnp);
 917 
 918         error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
 919 
 920         return (error);
 921 }
 922 
 923 static int
 924 pr_read_map(prnode_t *pnp, uio_t *uiop)
 925 {
 926         ASSERT(pnp->pr_type == PR_MAP);
 927         return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 928 }
 929 
 930 static int
 931 pr_read_rmap(prnode_t *pnp, uio_t *uiop)
 932 {
 933         ASSERT(pnp->pr_type == PR_RMAP);
 934         return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 935 }
 936 
 937 static int
 938 pr_read_xmap(prnode_t *pnp, uio_t *uiop)
 939 {
 940         ASSERT(pnp->pr_type == PR_XMAP);
 941         return (pr_read_map_common(pnp, uiop, pnp->pr_type));
 942 }
 943 
 944 static int
 945 pr_read_cred(prnode_t *pnp, uio_t *uiop)
 946 {
 947         proc_t *p;
 948         prcred_t *pcrp;
 949         int error;
 950         size_t count;
 951 
 952         ASSERT(pnp->pr_type == PR_CRED);
 953 
 954         /*
 955          * We kmem_alloc() the prcred_t structure because
 956          * the number of supplementary groups is variable.
 957          */
 958         pcrp =
 959             kmem_alloc(sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1),
 960             KM_SLEEP);
 961 
 962         if ((error = prlock(pnp, ZNO)) != 0)
 963                 goto out;
 964         p = pnp->pr_common->prc_proc;
 965         ASSERT(p != NULL);
 966 
 967         prgetcred(p, pcrp);
 968         prunlock(pnp);
 969 
 970         count = sizeof (prcred_t);
 971         if (pcrp->pr_ngroups > 1)
 972                 count += sizeof (gid_t) * (pcrp->pr_ngroups - 1);
 973         error = pr_uioread(pcrp, count, uiop);
 974 out:
 975         kmem_free(pcrp, sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1));
 976         return (error);
 977 }
 978 
 979 static int
 980 pr_read_priv(prnode_t *pnp, uio_t *uiop)
 981 {
 982         proc_t *p;
 983         size_t psize = prgetprivsize();
 984         prpriv_t *ppriv = kmem_alloc(psize, KM_SLEEP);
 985         int error;
 986 
 987         ASSERT(pnp->pr_type == PR_PRIV);
 988 
 989         if ((error = prlock(pnp, ZNO)) != 0)
 990                 goto out;
 991         p = pnp->pr_common->prc_proc;
 992         ASSERT(p != NULL);
 993 
 994         prgetpriv(p, ppriv);
 995         prunlock(pnp);
 996 
 997         error = pr_uioread(ppriv, psize, uiop);
 998 out:
 999         kmem_free(ppriv, psize);
1000         return (error);
1001 }
1002 
1003 static int
1004 pr_read_sigact(prnode_t *pnp, uio_t *uiop)
1005 {
1006         int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1007         proc_t *p;
1008         struct sigaction *sap;
1009         int sig;
1010         int error;
1011         user_t *up;
1012 
1013         ASSERT(pnp->pr_type == PR_SIGACT);
1014 
1015         /*
1016          * We kmem_alloc() the sigaction array because
1017          * it is so big it might blow the kernel stack.
1018          */
1019         sap = kmem_alloc((nsig-1) * sizeof (struct sigaction), KM_SLEEP);
1020 
1021         if ((error = prlock(pnp, ZNO)) != 0)
1022                 goto out;
1023         p = pnp->pr_common->prc_proc;
1024         ASSERT(p != NULL);
1025 
1026         if (uiop->uio_offset >= (nsig-1)*sizeof (struct sigaction)) {
1027                 prunlock(pnp);
1028                 goto out;
1029         }
1030 
1031         up = PTOU(p);
1032         for (sig = 1; sig < nsig; sig++)
1033                 prgetaction(p, up, sig, &sap[sig-1]);
1034         prunlock(pnp);
1035 
1036         error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction), uiop);
1037 out:
1038         kmem_free(sap, (nsig-1) * sizeof (struct sigaction));
1039         return (error);
1040 }
1041 
1042 static int
1043 pr_read_auxv(prnode_t *pnp, uio_t *uiop)
1044 {
1045         auxv_t auxv[__KERN_NAUXV_IMPL];
1046         proc_t *p;
1047         user_t *up;
1048         int error;
1049 
1050         ASSERT(pnp->pr_type == PR_AUXV);
1051 
1052         if ((error = prlock(pnp, ZNO)) != 0)
1053                 return (error);
1054 
1055         if (uiop->uio_offset >= sizeof (auxv)) {
1056                 prunlock(pnp);
1057                 return (0);
1058         }
1059 
1060         p = pnp->pr_common->prc_proc;
1061         up = PTOU(p);
1062         bcopy(up->u_auxv, auxv, sizeof (auxv));
1063         prunlock(pnp);
1064 
1065         return (pr_uioread(auxv, sizeof (auxv), uiop));
1066 }
1067 
1068 #if defined(__x86)
1069 /*
1070  * XX64
1071  *      This is almost certainly broken for the amd64 kernel, because
1072  *      we have two kinds of LDT structures to export -- one for compatibility
1073  *      mode, and one for long mode, sigh.
1074  *
1075  *      For now lets just have a ldt of size 0 for 64-bit processes.
1076  */
1077 static int
1078 pr_read_ldt(prnode_t *pnp, uio_t *uiop)
1079 {
1080         proc_t *p;
1081         struct ssd *ssd;
1082         size_t size;
1083         int error;
1084 
1085         ASSERT(pnp->pr_type == PR_LDT);
1086 
1087         if ((error = prlock(pnp, ZNO)) != 0)
1088                 return (error);
1089         p = pnp->pr_common->prc_proc;
1090 
1091         mutex_exit(&p->p_lock);
1092         mutex_enter(&p->p_ldtlock);
1093         size = prnldt(p) * sizeof (struct ssd);
1094         if (uiop->uio_offset >= size) {
1095                 mutex_exit(&p->p_ldtlock);
1096                 mutex_enter(&p->p_lock);
1097                 prunlock(pnp);
1098                 return (0);
1099         }
1100 
1101         ssd = kmem_alloc(size, KM_SLEEP);
1102         prgetldt(p, ssd);
1103         mutex_exit(&p->p_ldtlock);
1104         mutex_enter(&p->p_lock);
1105         prunlock(pnp);
1106 
1107         error = pr_uioread(ssd, size, uiop);
1108         kmem_free(ssd, size);
1109         return (error);
1110 }
1111 #endif  /* __x86 */
1112 
1113 static int
1114 pr_read_usage(prnode_t *pnp, uio_t *uiop)
1115 {
1116         prhusage_t *pup;
1117         prusage_t *upup;
1118         proc_t *p;
1119         kthread_t *t;
1120         int error;
1121 
1122         ASSERT(pnp->pr_type == PR_USAGE);
1123 
1124         /* allocate now, before locking the process */
1125         pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1126         upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1127 
1128         /*
1129          * We don't want the full treatment of prlock(pnp) here.
1130          * This file is world-readable and never goes invalid.
1131          * It doesn't matter if we are in the middle of an exec().
1132          */
1133         p = pr_p_lock(pnp);
1134         mutex_exit(&pr_pidlock);
1135         if (p == NULL) {
1136                 error = ENOENT;
1137                 goto out;
1138         }
1139         ASSERT(p == pnp->pr_common->prc_proc);
1140 
1141         if (uiop->uio_offset >= sizeof (prusage_t)) {
1142                 prunlock(pnp);
1143                 error = 0;
1144                 goto out;
1145         }
1146 
1147         pup->pr_tstamp = gethrtime();
1148 
1149         pup->pr_count  = p->p_defunct;
1150         pup->pr_create = p->p_mstart;
1151         pup->pr_term   = p->p_mterm;
1152 
1153         pup->pr_rtime    = p->p_mlreal;
1154         pup->pr_utime    = p->p_acct[LMS_USER];
1155         pup->pr_stime    = p->p_acct[LMS_SYSTEM];
1156         pup->pr_ttime    = p->p_acct[LMS_TRAP];
1157         pup->pr_tftime   = p->p_acct[LMS_TFAULT];
1158         pup->pr_dftime   = p->p_acct[LMS_DFAULT];
1159         pup->pr_kftime   = p->p_acct[LMS_KFAULT];
1160         pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
1161         pup->pr_slptime  = p->p_acct[LMS_SLEEP];
1162         pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
1163         pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1164 
1165         pup->pr_minf  = p->p_ru.minflt;
1166         pup->pr_majf  = p->p_ru.majflt;
1167         pup->pr_nswap = p->p_ru.nswap;
1168         pup->pr_inblk = p->p_ru.inblock;
1169         pup->pr_oublk = p->p_ru.oublock;
1170         pup->pr_msnd  = p->p_ru.msgsnd;
1171         pup->pr_mrcv  = p->p_ru.msgrcv;
1172         pup->pr_sigs  = p->p_ru.nsignals;
1173         pup->pr_vctx  = p->p_ru.nvcsw;
1174         pup->pr_ictx  = p->p_ru.nivcsw;
1175         pup->pr_sysc  = p->p_ru.sysc;
1176         pup->pr_ioch  = p->p_ru.ioch;
1177 
1178         /*
1179          * Add the usage information for each active lwp.
1180          */
1181         if ((t = p->p_tlist) != NULL &&
1182             !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
1183                 do {
1184                         if (t->t_proc_flag & TP_LWPEXIT)
1185                                 continue;
1186                         pup->pr_count++;
1187                         praddusage(t, pup);
1188                 } while ((t = t->t_forw) != p->p_tlist);
1189         }
1190 
1191         prunlock(pnp);
1192 
1193         prcvtusage(pup, upup);
1194 
1195         error = pr_uioread(upup, sizeof (prusage_t), uiop);
1196 out:
1197         kmem_free(pup, sizeof (*pup));
1198         kmem_free(upup, sizeof (*upup));
1199         return (error);
1200 }
1201 
1202 static int
1203 pr_read_lusage(prnode_t *pnp, uio_t *uiop)
1204 {
1205         int nlwp;
1206         prhusage_t *pup;
1207         prheader_t *php;
1208         prusage_t *upup;
1209         size_t size;
1210         hrtime_t curtime;
1211         proc_t *p;
1212         kthread_t *t;
1213         lwpdir_t *ldp;
1214         int error;
1215         int i;
1216 
1217         ASSERT(pnp->pr_type == PR_LUSAGE);
1218 
1219         /*
1220          * We don't want the full treatment of prlock(pnp) here.
1221          * This file is world-readable and never goes invalid.
1222          * It doesn't matter if we are in the middle of an exec().
1223          */
1224         p = pr_p_lock(pnp);
1225         mutex_exit(&pr_pidlock);
1226         if (p == NULL)
1227                 return (ENOENT);
1228         ASSERT(p == pnp->pr_common->prc_proc);
1229         if ((nlwp = p->p_lwpcnt) == 0) {
1230                 prunlock(pnp);
1231                 return (ENOENT);
1232         }
1233 
1234         size = sizeof (prheader_t) + (nlwp + 1) * LSPAN(prusage_t);
1235         if (uiop->uio_offset >= size) {
1236                 prunlock(pnp);
1237                 return (0);
1238         }
1239 
1240         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1241         mutex_exit(&p->p_lock);
1242         pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
1243         mutex_enter(&p->p_lock);
1244         /* p->p_lwpcnt can't change while process is locked */
1245         ASSERT(nlwp == p->p_lwpcnt);
1246 
1247         php = (prheader_t *)(pup + 1);
1248         upup = (prusage_t *)(php + 1);
1249 
1250         php->pr_nent = nlwp + 1;
1251         php->pr_entsize = LSPAN(prusage_t);
1252 
1253         curtime = gethrtime();
1254 
1255         /*
1256          * First the summation over defunct lwps.
1257          */
1258         pup->pr_count  = p->p_defunct;
1259         pup->pr_tstamp = curtime;
1260         pup->pr_create = p->p_mstart;
1261         pup->pr_term   = p->p_mterm;
1262 
1263         pup->pr_rtime    = p->p_mlreal;
1264         pup->pr_utime    = p->p_acct[LMS_USER];
1265         pup->pr_stime    = p->p_acct[LMS_SYSTEM];
1266         pup->pr_ttime    = p->p_acct[LMS_TRAP];
1267         pup->pr_tftime   = p->p_acct[LMS_TFAULT];
1268         pup->pr_dftime   = p->p_acct[LMS_DFAULT];
1269         pup->pr_kftime   = p->p_acct[LMS_KFAULT];
1270         pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
1271         pup->pr_slptime  = p->p_acct[LMS_SLEEP];
1272         pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
1273         pup->pr_stoptime = p->p_acct[LMS_STOPPED];
1274 
1275         pup->pr_minf  = p->p_ru.minflt;
1276         pup->pr_majf  = p->p_ru.majflt;
1277         pup->pr_nswap = p->p_ru.nswap;
1278         pup->pr_inblk = p->p_ru.inblock;
1279         pup->pr_oublk = p->p_ru.oublock;
1280         pup->pr_msnd  = p->p_ru.msgsnd;
1281         pup->pr_mrcv  = p->p_ru.msgrcv;
1282         pup->pr_sigs  = p->p_ru.nsignals;
1283         pup->pr_vctx  = p->p_ru.nvcsw;
1284         pup->pr_ictx  = p->p_ru.nivcsw;
1285         pup->pr_sysc  = p->p_ru.sysc;
1286         pup->pr_ioch  = p->p_ru.ioch;
1287 
1288         prcvtusage(pup, upup);
1289 
1290         /*
1291          * Fill one prusage struct for each active lwp.
1292          */
1293         for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1294                 if (ldp->ld_entry == NULL ||
1295                     (t = ldp->ld_entry->le_thread) == NULL)
1296                         continue;
1297                 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
1298                 ASSERT(nlwp > 0);
1299                 --nlwp;
1300                 upup = (prusage_t *)((caddr_t)upup + LSPAN(prusage_t));
1301                 prgetusage(t, pup);
1302                 prcvtusage(pup, upup);
1303         }
1304         ASSERT(nlwp == 0);
1305 
1306         prunlock(pnp);
1307 
1308         error = pr_uioread(php, size, uiop);
1309         kmem_free(pup, size + sizeof (prhusage_t));
1310         return (error);
1311 }
1312 
1313 static int
1314 pr_read_pagedata(prnode_t *pnp, uio_t *uiop)
1315 {
1316         proc_t *p;
1317         int error;
1318 
1319         ASSERT(pnp->pr_type == PR_PAGEDATA);
1320 
1321         if ((error = prlock(pnp, ZNO)) != 0)
1322                 return (error);
1323 
1324         p = pnp->pr_common->prc_proc;
1325         if ((p->p_flag & SSYS) || p->p_as == &kas) {
1326                 prunlock(pnp);
1327                 return (0);
1328         }
1329 
1330         mutex_exit(&p->p_lock);
1331         error = prpdread(p, pnp->pr_hatid, uiop);
1332         mutex_enter(&p->p_lock);
1333 
1334         prunlock(pnp);
1335         return (error);
1336 }
1337 
1338 static int
1339 pr_read_opagedata(prnode_t *pnp, uio_t *uiop)
1340 {
1341         proc_t *p;
1342         struct as *as;
1343         int error;
1344 
1345         ASSERT(pnp->pr_type == PR_OPAGEDATA);
1346 
1347         if ((error = prlock(pnp, ZNO)) != 0)
1348                 return (error);
1349 
1350         p = pnp->pr_common->prc_proc;
1351         as = p->p_as;
1352         if ((p->p_flag & SSYS) || as == &kas) {
1353                 prunlock(pnp);
1354                 return (0);
1355         }
1356 
1357         mutex_exit(&p->p_lock);
1358         error = oprpdread(as, pnp->pr_hatid, uiop);
1359         mutex_enter(&p->p_lock);
1360 
1361         prunlock(pnp);
1362         return (error);
1363 }
1364 
1365 static int
1366 pr_read_watch(prnode_t *pnp, uio_t *uiop)
1367 {
1368         proc_t *p;
1369         int error;
1370         prwatch_t *Bpwp;
1371         size_t size;
1372         prwatch_t *pwp;
1373         int nwarea;
1374         struct watched_area *pwarea;
1375 
1376         ASSERT(pnp->pr_type == PR_WATCH);
1377 
1378         if ((error = prlock(pnp, ZNO)) != 0)
1379                 return (error);
1380 
1381         p = pnp->pr_common->prc_proc;
1382         nwarea = avl_numnodes(&p->p_warea);
1383         size = nwarea * sizeof (prwatch_t);
1384         if (uiop->uio_offset >= size) {
1385                 prunlock(pnp);
1386                 return (0);
1387         }
1388 
1389         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1390         mutex_exit(&p->p_lock);
1391         Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
1392         mutex_enter(&p->p_lock);
1393         /* p->p_nwarea can't change while process is locked */
1394         ASSERT(nwarea == avl_numnodes(&p->p_warea));
1395 
1396         /* gather the watched areas */
1397         for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
1398             pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
1399                 pwp->pr_vaddr = (uintptr_t)pwarea->wa_vaddr;
1400                 pwp->pr_size = pwarea->wa_eaddr - pwarea->wa_vaddr;
1401                 pwp->pr_wflags = (int)pwarea->wa_flags;
1402         }
1403 
1404         prunlock(pnp);
1405 
1406         error = pr_uioread(Bpwp, size, uiop);
1407         kmem_free(Bpwp, size);
1408         return (error);
1409 }
1410 
1411 static int
1412 pr_read_lwpstatus(prnode_t *pnp, uio_t *uiop)
1413 {
1414         lwpstatus_t *sp;
1415         int error;
1416 
1417         ASSERT(pnp->pr_type == PR_LWPSTATUS);
1418 
1419         /*
1420          * We kmem_alloc() the lwpstatus structure because
1421          * it is so big it might blow the kernel stack.
1422          */
1423         sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1424 
1425         if ((error = prlock(pnp, ZNO)) != 0)
1426                 goto out;
1427 
1428         if (uiop->uio_offset >= sizeof (*sp)) {
1429                 prunlock(pnp);
1430                 goto out;
1431         }
1432 
1433         prgetlwpstatus(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
1434         prunlock(pnp);
1435 
1436         error = pr_uioread(sp, sizeof (*sp), uiop);
1437 out:
1438         kmem_free(sp, sizeof (*sp));
1439         return (error);
1440 }
1441 
1442 static int
1443 pr_read_lwpsinfo(prnode_t *pnp, uio_t *uiop)
1444 {
1445         lwpsinfo_t lwpsinfo;
1446         proc_t *p;
1447         kthread_t *t;
1448         lwpent_t *lep;
1449 
1450         ASSERT(pnp->pr_type == PR_LWPSINFO);
1451 
1452         /*
1453          * We don't want the full treatment of prlock(pnp) here.
1454          * This file is world-readable and never goes invalid.
1455          * It doesn't matter if we are in the middle of an exec().
1456          */
1457         p = pr_p_lock(pnp);
1458         mutex_exit(&pr_pidlock);
1459         if (p == NULL)
1460                 return (ENOENT);
1461         ASSERT(p == pnp->pr_common->prc_proc);
1462         if (pnp->pr_common->prc_tslot == -1) {
1463                 prunlock(pnp);
1464                 return (ENOENT);
1465         }
1466 
1467         if (uiop->uio_offset >= sizeof (lwpsinfo)) {
1468                 prunlock(pnp);
1469                 return (0);
1470         }
1471 
1472         if ((t = pnp->pr_common->prc_thread) != NULL)
1473                 prgetlwpsinfo(t, &lwpsinfo);
1474         else {
1475                 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
1476                 bzero(&lwpsinfo, sizeof (lwpsinfo));
1477                 lwpsinfo.pr_lwpid = lep->le_lwpid;
1478                 lwpsinfo.pr_state = SZOMB;
1479                 lwpsinfo.pr_sname = 'Z';
1480                 lwpsinfo.pr_start.tv_sec = lep->le_start;
1481                 lwpsinfo.pr_bindpro = PBIND_NONE;
1482                 lwpsinfo.pr_bindpset = PS_NONE;
1483         }
1484         prunlock(pnp);
1485 
1486         return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
1487 }
1488 
1489 static int
1490 pr_read_lwpusage(prnode_t *pnp, uio_t *uiop)
1491 {
1492         prhusage_t *pup;
1493         prusage_t *upup;
1494         proc_t *p;
1495         int error;
1496 
1497         ASSERT(pnp->pr_type == PR_LWPUSAGE);
1498 
1499         /* allocate now, before locking the process */
1500         pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
1501         upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
1502 
1503         /*
1504          * We don't want the full treatment of prlock(pnp) here.
1505          * This file is world-readable and never goes invalid.
1506          * It doesn't matter if we are in the middle of an exec().
1507          */
1508         p = pr_p_lock(pnp);
1509         mutex_exit(&pr_pidlock);
1510         if (p == NULL) {
1511                 error = ENOENT;
1512                 goto out;
1513         }
1514         ASSERT(p == pnp->pr_common->prc_proc);
1515         if (pnp->pr_common->prc_thread == NULL) {
1516                 prunlock(pnp);
1517                 error = ENOENT;
1518                 goto out;
1519         }
1520         if (uiop->uio_offset >= sizeof (prusage_t)) {
1521                 prunlock(pnp);
1522                 error = 0;
1523                 goto out;
1524         }
1525 
1526         pup->pr_tstamp = gethrtime();
1527         prgetusage(pnp->pr_common->prc_thread, pup);
1528 
1529         prunlock(pnp);
1530 
1531         prcvtusage(pup, upup);
1532 
1533         error = pr_uioread(upup, sizeof (prusage_t), uiop);
1534 out:
1535         kmem_free(pup, sizeof (*pup));
1536         kmem_free(upup, sizeof (*upup));
1537         return (error);
1538 }
1539 
1540 /* ARGSUSED */
1541 static int
1542 pr_read_xregs(prnode_t *pnp, uio_t *uiop)
1543 {
1544 #if defined(__sparc)
1545         proc_t *p;
1546         kthread_t *t;
1547         int error;
1548         char *xreg;
1549         size_t size;
1550 
1551         ASSERT(pnp->pr_type == PR_XREGS);
1552 
1553         xreg = kmem_zalloc(sizeof (prxregset_t), KM_SLEEP);
1554 
1555         if ((error = prlock(pnp, ZNO)) != 0)
1556                 goto out;
1557 
1558         p = pnp->pr_common->prc_proc;
1559         t = pnp->pr_common->prc_thread;
1560 
1561         size = prhasx(p)? prgetprxregsize(p) : 0;
1562         if (uiop->uio_offset >= size) {
1563                 prunlock(pnp);
1564                 goto out;
1565         }
1566 
1567         /* drop p->p_lock while (possibly) touching the stack */
1568         mutex_exit(&p->p_lock);
1569         prgetprxregs(ttolwp(t), xreg);
1570         mutex_enter(&p->p_lock);
1571         prunlock(pnp);
1572 
1573         error = pr_uioread(xreg, size, uiop);
1574 out:
1575         kmem_free(xreg, sizeof (prxregset_t));
1576         return (error);
1577 #else
1578         return (0);
1579 #endif
1580 }
1581 
1582 static int
1583 pr_read_spymaster(prnode_t *pnp, uio_t *uiop)
1584 {
1585         psinfo_t psinfo;
1586         int error;
1587         klwp_t *lwp;
1588 
1589         ASSERT(pnp->pr_type == PR_SPYMASTER);
1590 
1591         if ((error = prlock(pnp, ZNO)) != 0)
1592                 return (error);
1593 
1594         lwp = pnp->pr_common->prc_thread->t_lwp;
1595 
1596         if (lwp->lwp_spymaster == NULL) {
1597                 prunlock(pnp);
1598                 return (0);
1599         }
1600 
1601         bcopy(lwp->lwp_spymaster, &psinfo, sizeof (psinfo_t));
1602         prunlock(pnp);
1603 
1604         return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
1605 }
1606 
1607 static int
1608 pr_read_secflags(prnode_t *pnp, uio_t *uiop)
1609 {
1610         prsecflags_t ret;
1611         int error;
1612         proc_t *p;
1613 
1614         ASSERT(pnp->pr_type == PR_SECFLAGS);
1615 
1616         if ((error = prlock(pnp, ZNO)) != 0)
1617                 return (error);
1618 
1619         p = pnp->pr_common->prc_proc;
1620         prgetsecflags(p, &ret);
1621         prunlock(pnp);
1622 
1623         return (pr_uioread(&ret, sizeof (ret), uiop));
1624 }
1625 
1626 #if defined(__sparc)
1627 
1628 static int
1629 pr_read_gwindows(prnode_t *pnp, uio_t *uiop)
1630 {
1631         proc_t *p;
1632         kthread_t *t;
1633         gwindows_t *gwp;
1634         int error;
1635         size_t size;
1636 
1637         ASSERT(pnp->pr_type == PR_GWINDOWS);
1638 
1639         gwp = kmem_zalloc(sizeof (gwindows_t), KM_SLEEP);
1640 
1641         if ((error = prlock(pnp, ZNO)) != 0)
1642                 goto out;
1643 
1644         p = pnp->pr_common->prc_proc;
1645         t = pnp->pr_common->prc_thread;
1646 
1647         /*
1648          * Drop p->p_lock while touching the stack.
1649          * The P_PR_LOCK flag prevents the lwp from
1650          * disappearing while we do this.
1651          */
1652         mutex_exit(&p->p_lock);
1653         if ((size = prnwindows(ttolwp(t))) != 0)
1654                 size = sizeof (gwindows_t) -
1655                     (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow);
1656         if (uiop->uio_offset >= size) {
1657                 mutex_enter(&p->p_lock);
1658                 prunlock(pnp);
1659                 goto out;
1660         }
1661         prgetwindows(ttolwp(t), gwp);
1662         mutex_enter(&p->p_lock);
1663         prunlock(pnp);
1664 
1665         error = pr_uioread(gwp, size, uiop);
1666 out:
1667         kmem_free(gwp, sizeof (gwindows_t));
1668         return (error);
1669 }
1670 
1671 /* ARGSUSED */
1672 static int
1673 pr_read_asrs(prnode_t *pnp, uio_t *uiop)
1674 {
1675         int error;
1676 
1677         ASSERT(pnp->pr_type == PR_ASRS);
1678 
1679         /* the asrs file exists only for sparc v9 _LP64 processes */
1680         if ((error = prlock(pnp, ZNO)) == 0) {
1681                 proc_t *p = pnp->pr_common->prc_proc;
1682                 kthread_t *t = pnp->pr_common->prc_thread;
1683                 asrset_t asrset;
1684 
1685                 if (p->p_model != DATAMODEL_LP64 ||
1686                     uiop->uio_offset >= sizeof (asrset_t)) {
1687                         prunlock(pnp);
1688                         return (0);
1689                 }
1690 
1691                 /*
1692                  * Drop p->p_lock while touching the stack.
1693                  * The P_PR_LOCK flag prevents the lwp from
1694                  * disappearing while we do this.
1695                  */
1696                 mutex_exit(&p->p_lock);
1697                 prgetasregs(ttolwp(t), asrset);
1698                 mutex_enter(&p->p_lock);
1699                 prunlock(pnp);
1700 
1701                 error = pr_uioread(&asrset[0], sizeof (asrset_t), uiop);
1702         }
1703 
1704         return (error);
1705 }
1706 
1707 #endif  /* __sparc */
1708 
1709 static int
1710 pr_read_piddir(prnode_t *pnp, uio_t *uiop)
1711 {
1712         ASSERT(pnp->pr_type == PR_PIDDIR);
1713         ASSERT(pnp->pr_pidfile != NULL);
1714 
1715         /* use the underlying PR_PIDFILE to read the process */
1716         pnp = VTOP(pnp->pr_pidfile);
1717         ASSERT(pnp->pr_type == PR_PIDFILE);
1718 
1719         return (pr_read_pidfile(pnp, uiop));
1720 }
1721 
1722 static int
1723 pr_read_pidfile(prnode_t *pnp, uio_t *uiop)
1724 {
1725         int error;
1726 
1727         ASSERT(pnp->pr_type == PR_PIDFILE || pnp->pr_type == PR_LWPIDFILE);
1728 
1729         if ((error = prlock(pnp, ZNO)) == 0) {
1730                 proc_t *p = pnp->pr_common->prc_proc;
1731                 struct as *as = p->p_as;
1732 
1733                 if ((p->p_flag & SSYS) || as == &kas) {
1734                         /*
1735                          * /proc I/O cannot be done to a system process.
1736                          */
1737                         error = EIO;    /* old /proc semantics */
1738                 } else {
1739                         /*
1740                          * We drop p_lock because we don't want to hold
1741                          * it over an I/O operation because that could
1742                          * lead to deadlock with the clock thread.
1743                          * The process will not disappear and its address
1744                          * space will not change because it is marked P_PR_LOCK.
1745                          */
1746                         mutex_exit(&p->p_lock);
1747                         error = prusrio(p, UIO_READ, uiop, 1);
1748                         mutex_enter(&p->p_lock);
1749                 }
1750                 prunlock(pnp);
1751         }
1752 
1753         return (error);
1754 }
1755 
1756 #ifdef _SYSCALL32_IMPL
1757 
1758 /*
1759  * Array of ILP32 read functions, indexed by /proc file type.
1760  */
1761 static int pr_read_status_32(),
1762         pr_read_lstatus_32(), pr_read_psinfo_32(), pr_read_lpsinfo_32(),
1763         pr_read_map_32(), pr_read_rmap_32(), pr_read_xmap_32(),
1764         pr_read_sigact_32(), pr_read_auxv_32(),
1765         pr_read_usage_32(), pr_read_lusage_32(), pr_read_pagedata_32(),
1766         pr_read_watch_32(), pr_read_lwpstatus_32(), pr_read_lwpsinfo_32(),
1767         pr_read_lwpusage_32(), pr_read_spymaster_32(),
1768 #if defined(__sparc)
1769         pr_read_gwindows_32(),
1770 #endif
1771         pr_read_opagedata_32();
1772 
1773 static int (*pr_read_function_32[PR_NFILES])() = {
1774         pr_read_inval,          /* /proc                                */
1775         pr_read_inval,          /* /proc/self                           */
1776         pr_read_piddir,         /* /proc/<pid> (old /proc read()) */
1777         pr_read_as,             /* /proc/<pid>/as                 */
1778         pr_read_inval,          /* /proc/<pid>/ctl                        */
1779         pr_read_status_32,      /* /proc/<pid>/status                     */
1780         pr_read_lstatus_32,     /* /proc/<pid>/lstatus                    */
1781         pr_read_psinfo_32,      /* /proc/<pid>/psinfo                     */
1782         pr_read_lpsinfo_32,     /* /proc/<pid>/lpsinfo                    */
1783         pr_read_map_32,         /* /proc/<pid>/map                        */
1784         pr_read_rmap_32,        /* /proc/<pid>/rmap                       */
1785         pr_read_xmap_32,        /* /proc/<pid>/xmap                       */
1786         pr_read_cred,           /* /proc/<pid>/cred                       */
1787         pr_read_sigact_32,      /* /proc/<pid>/sigact                     */
1788         pr_read_auxv_32,        /* /proc/<pid>/auxv                       */
1789 #if defined(__x86)
1790         pr_read_ldt,            /* /proc/<pid>/ldt                        */
1791 #endif
1792         pr_read_usage_32,       /* /proc/<pid>/usage                      */
1793         pr_read_lusage_32,      /* /proc/<pid>/lusage                     */
1794         pr_read_pagedata_32,    /* /proc/<pid>/pagedata                   */
1795         pr_read_watch_32,       /* /proc/<pid>/watch                      */
1796         pr_read_inval,          /* /proc/<pid>/cwd                        */
1797         pr_read_inval,          /* /proc/<pid>/root                       */
1798         pr_read_inval,          /* /proc/<pid>/fd                 */
1799         pr_read_inval,          /* /proc/<pid>/fd/nn                      */
1800         pr_read_inval,          /* /proc/<pid>/object                     */
1801         pr_read_inval,          /* /proc/<pid>/object/xxx         */
1802         pr_read_inval,          /* /proc/<pid>/lwp                        */
1803         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>          */
1804         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
1805         pr_read_lwpstatus_32,   /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
1806         pr_read_lwpsinfo_32,    /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
1807         pr_read_lwpusage_32,    /* /proc/<pid>/lwp/<lwpid>/lwpusage */
1808         pr_read_xregs,          /* /proc/<pid>/lwp/<lwpid>/xregs    */
1809         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates        */
1810         pr_read_inval,          /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
1811         pr_read_spymaster_32,   /* /proc/<pid>/lwp/<lwpid>/spymaster        */
1812 #if defined(__sparc)
1813         pr_read_gwindows_32,    /* /proc/<pid>/lwp/<lwpid>/gwindows */
1814         pr_read_asrs,           /* /proc/<pid>/lwp/<lwpid>/asrs             */
1815 #endif
1816         pr_read_priv,           /* /proc/<pid>/priv                       */
1817         pr_read_inval,          /* /proc/<pid>/path                       */
1818         pr_read_inval,          /* /proc/<pid>/path/xxx                   */
1819         pr_read_inval,          /* /proc/<pid>/contracts          */
1820         pr_read_inval,          /* /proc/<pid>/contracts/<ctid>             */
1821         pr_read_secflags,       /* /proc/<pid>/secflags                   */
1822         pr_read_pidfile,        /* old process file                     */
1823         pr_read_pidfile,        /* old lwp file                         */
1824         pr_read_opagedata_32,   /* old pagedata file                    */
1825 };
1826 
1827 static int
1828 pr_read_status_32(prnode_t *pnp, uio_t *uiop)
1829 {
1830         pstatus32_t *sp;
1831         proc_t *p;
1832         int error;
1833 
1834         ASSERT(pnp->pr_type == PR_STATUS);
1835 
1836         /*
1837          * We kmem_alloc() the pstatus structure because
1838          * it is so big it might blow the kernel stack.
1839          */
1840         sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
1841         if ((error = prlock(pnp, ZNO)) == 0) {
1842                 /*
1843                  * A 32-bit process cannot get the status of a 64-bit process.
1844                  * The fields for the 64-bit quantities are not large enough.
1845                  */
1846                 p = pnp->pr_common->prc_proc;
1847                 if (PROCESS_NOT_32BIT(p)) {
1848                         prunlock(pnp);
1849                         error = EOVERFLOW;
1850                 } else {
1851                         prgetstatus32(pnp->pr_common->prc_proc, sp,
1852                             VTOZONE(PTOV(pnp)));
1853                         prunlock(pnp);
1854                         error = pr_uioread(sp, sizeof (*sp), uiop);
1855                 }
1856         }
1857         kmem_free((caddr_t)sp, sizeof (*sp));
1858         return (error);
1859 }
1860 
1861 static int
1862 pr_read_lstatus_32(prnode_t *pnp, uio_t *uiop)
1863 {
1864         proc_t *p;
1865         kthread_t *t;
1866         lwpdir_t *ldp;
1867         size_t size;
1868         prheader32_t *php;
1869         lwpstatus32_t *sp;
1870         int error;
1871         int nlwp;
1872         int i;
1873 
1874         ASSERT(pnp->pr_type == PR_LSTATUS);
1875 
1876         if ((error = prlock(pnp, ZNO)) != 0)
1877                 return (error);
1878         p = pnp->pr_common->prc_proc;
1879         /*
1880          * A 32-bit process cannot get the status of a 64-bit process.
1881          * The fields for the 64-bit quantities are not large enough.
1882          */
1883         if (PROCESS_NOT_32BIT(p)) {
1884                 prunlock(pnp);
1885                 return (EOVERFLOW);
1886         }
1887         nlwp = p->p_lwpcnt;
1888         size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpstatus32_t);
1889 
1890         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1891         mutex_exit(&p->p_lock);
1892         php = kmem_zalloc(size, KM_SLEEP);
1893         mutex_enter(&p->p_lock);
1894         /* p->p_lwpcnt can't change while process is locked */
1895         ASSERT(nlwp == p->p_lwpcnt);
1896 
1897         php->pr_nent = nlwp;
1898         php->pr_entsize = LSPAN32(lwpstatus32_t);
1899 
1900         sp = (lwpstatus32_t *)(php + 1);
1901         for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1902                 if (ldp->ld_entry == NULL ||
1903                     (t = ldp->ld_entry->le_thread) == NULL)
1904                         continue;
1905                 prgetlwpstatus32(t, sp, VTOZONE(PTOV(pnp)));
1906                 sp = (lwpstatus32_t *)((caddr_t)sp + LSPAN32(lwpstatus32_t));
1907         }
1908         prunlock(pnp);
1909 
1910         error = pr_uioread(php, size, uiop);
1911         kmem_free(php, size);
1912         return (error);
1913 }
1914 
1915 static int
1916 pr_read_psinfo_32(prnode_t *pnp, uio_t *uiop)
1917 {
1918         psinfo32_t psinfo;
1919         proc_t *p;
1920         int error = 0;
1921 
1922         ASSERT(pnp->pr_type == PR_PSINFO);
1923 
1924         /*
1925          * We don't want the full treatment of prlock(pnp) here.
1926          * This file is world-readable and never goes invalid.
1927          * It doesn't matter if we are in the middle of an exec().
1928          */
1929         p = pr_p_lock(pnp);
1930         mutex_exit(&pr_pidlock);
1931         if (p == NULL)
1932                 error = ENOENT;
1933         else {
1934                 ASSERT(p == pnp->pr_common->prc_proc);
1935                 prgetpsinfo32(p, &psinfo);
1936                 prunlock(pnp);
1937                 error = pr_uioread(&psinfo, sizeof (psinfo), uiop);
1938         }
1939         return (error);
1940 }
1941 
1942 static int
1943 pr_read_lpsinfo_32(prnode_t *pnp, uio_t *uiop)
1944 {
1945         proc_t *p;
1946         kthread_t *t;
1947         lwpdir_t *ldp;
1948         lwpent_t *lep;
1949         size_t size;
1950         prheader32_t *php;
1951         lwpsinfo32_t *sp;
1952         int error;
1953         int nlwp;
1954         int i;
1955 
1956         ASSERT(pnp->pr_type == PR_LPSINFO);
1957 
1958         /*
1959          * We don't want the full treatment of prlock(pnp) here.
1960          * This file is world-readable and never goes invalid.
1961          * It doesn't matter if we are in the middle of an exec().
1962          */
1963         p = pr_p_lock(pnp);
1964         mutex_exit(&pr_pidlock);
1965         if (p == NULL)
1966                 return (ENOENT);
1967         ASSERT(p == pnp->pr_common->prc_proc);
1968         if ((nlwp = p->p_lwpcnt + p->p_zombcnt) == 0) {
1969                 prunlock(pnp);
1970                 return (ENOENT);
1971         }
1972         size = sizeof (prheader32_t) + nlwp * LSPAN32(lwpsinfo32_t);
1973 
1974         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
1975         mutex_exit(&p->p_lock);
1976         php = kmem_zalloc(size, KM_SLEEP);
1977         mutex_enter(&p->p_lock);
1978         /* p->p_lwpcnt can't change while process is locked */
1979         ASSERT(nlwp == p->p_lwpcnt + p->p_zombcnt);
1980 
1981         php->pr_nent = nlwp;
1982         php->pr_entsize = LSPAN32(lwpsinfo32_t);
1983 
1984         sp = (lwpsinfo32_t *)(php + 1);
1985         for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
1986                 if ((lep = ldp->ld_entry) == NULL)
1987                         continue;
1988                 if ((t = lep->le_thread) != NULL)
1989                         prgetlwpsinfo32(t, sp);
1990                 else {
1991                         bzero(sp, sizeof (*sp));
1992                         sp->pr_lwpid = lep->le_lwpid;
1993                         sp->pr_state = SZOMB;
1994                         sp->pr_sname = 'Z';
1995                         sp->pr_start.tv_sec = (time32_t)lep->le_start;
1996                 }
1997                 sp = (lwpsinfo32_t *)((caddr_t)sp + LSPAN32(lwpsinfo32_t));
1998         }
1999         prunlock(pnp);
2000 
2001         error = pr_uioread(php, size, uiop);
2002         kmem_free(php, size);
2003         return (error);
2004 }
2005 
2006 static int
2007 pr_read_map_common_32(prnode_t *pnp, uio_t *uiop, prnodetype_t type)
2008 {
2009         proc_t *p;
2010         struct as *as;
2011         list_t  iolhead;
2012         int error;
2013 
2014 readmap32_common:
2015         if ((error = prlock(pnp, ZNO)) != 0)
2016                 return (error);
2017 
2018         p = pnp->pr_common->prc_proc;
2019         as = p->p_as;
2020 
2021         if ((p->p_flag & SSYS) || as == &kas) {
2022                 prunlock(pnp);
2023                 return (0);
2024         }
2025 
2026         if (PROCESS_NOT_32BIT(p)) {
2027                 prunlock(pnp);
2028                 return (EOVERFLOW);
2029         }
2030 
2031         if (!AS_LOCK_TRYENTER(as, RW_WRITER)) {
2032                 prunlock(pnp);
2033                 delay(1);
2034                 goto readmap32_common;
2035         }
2036         mutex_exit(&p->p_lock);
2037 
2038         switch (type) {
2039         case PR_XMAP:
2040                 error = prgetxmap32(p, &iolhead);
2041                 break;
2042         case PR_RMAP:
2043                 error = prgetmap32(p, 1, &iolhead);
2044                 break;
2045         case PR_MAP:
2046                 error = prgetmap32(p, 0, &iolhead);
2047                 break;
2048         }
2049         AS_LOCK_EXIT(as);
2050         mutex_enter(&p->p_lock);
2051         prunlock(pnp);
2052 
2053         error = pr_iol_uiomove_and_free(&iolhead, uiop, error);
2054 
2055         return (error);
2056 }
2057 
2058 static int
2059 pr_read_map_32(prnode_t *pnp, uio_t *uiop)
2060 {
2061         ASSERT(pnp->pr_type == PR_MAP);
2062         return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2063 }
2064 
2065 static int
2066 pr_read_rmap_32(prnode_t *pnp, uio_t *uiop)
2067 {
2068         ASSERT(pnp->pr_type == PR_RMAP);
2069         return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2070 }
2071 
2072 static int
2073 pr_read_xmap_32(prnode_t *pnp, uio_t *uiop)
2074 {
2075         ASSERT(pnp->pr_type == PR_XMAP);
2076         return (pr_read_map_common_32(pnp, uiop, pnp->pr_type));
2077 }
2078 
2079 static int
2080 pr_read_sigact_32(prnode_t *pnp, uio_t *uiop)
2081 {
2082         int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
2083         proc_t *p;
2084         struct sigaction32 *sap;
2085         int sig;
2086         int error;
2087         user_t *up;
2088 
2089         ASSERT(pnp->pr_type == PR_SIGACT);
2090 
2091         /*
2092          * We kmem_alloc() the sigaction32 array because
2093          * it is so big it might blow the kernel stack.
2094          */
2095         sap = kmem_alloc((nsig-1) * sizeof (struct sigaction32), KM_SLEEP);
2096 
2097         if ((error = prlock(pnp, ZNO)) != 0)
2098                 goto out;
2099         p = pnp->pr_common->prc_proc;
2100 
2101         if (PROCESS_NOT_32BIT(p)) {
2102                 prunlock(pnp);
2103                 error = EOVERFLOW;
2104                 goto out;
2105         }
2106 
2107         if (uiop->uio_offset >= (nsig-1) * sizeof (struct sigaction32)) {
2108                 prunlock(pnp);
2109                 goto out;
2110         }
2111 
2112         up = PTOU(p);
2113         for (sig = 1; sig < nsig; sig++)
2114                 prgetaction32(p, up, sig, &sap[sig-1]);
2115         prunlock(pnp);
2116 
2117         error = pr_uioread(sap, (nsig - 1) * sizeof (struct sigaction32), uiop);
2118 out:
2119         kmem_free(sap, (nsig-1) * sizeof (struct sigaction32));
2120         return (error);
2121 }
2122 
2123 static int
2124 pr_read_auxv_32(prnode_t *pnp, uio_t *uiop)
2125 {
2126         auxv32_t auxv[__KERN_NAUXV_IMPL];
2127         proc_t *p;
2128         user_t *up;
2129         int error;
2130         int i;
2131 
2132         ASSERT(pnp->pr_type == PR_AUXV);
2133 
2134         if ((error = prlock(pnp, ZNO)) != 0)
2135                 return (error);
2136         p = pnp->pr_common->prc_proc;
2137 
2138         if (PROCESS_NOT_32BIT(p)) {
2139                 prunlock(pnp);
2140                 return (EOVERFLOW);
2141         }
2142 
2143         if (uiop->uio_offset >= sizeof (auxv)) {
2144                 prunlock(pnp);
2145                 return (0);
2146         }
2147 
2148         up = PTOU(p);
2149         for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
2150                 auxv[i].a_type = (int32_t)up->u_auxv[i].a_type;
2151                 auxv[i].a_un.a_val = (int32_t)up->u_auxv[i].a_un.a_val;
2152         }
2153         prunlock(pnp);
2154 
2155         return (pr_uioread(auxv, sizeof (auxv), uiop));
2156 }
2157 
2158 static int
2159 pr_read_usage_32(prnode_t *pnp, uio_t *uiop)
2160 {
2161         prhusage_t *pup;
2162         prusage32_t *upup;
2163         proc_t *p;
2164         kthread_t *t;
2165         int error;
2166 
2167         ASSERT(pnp->pr_type == PR_USAGE);
2168 
2169         /* allocate now, before locking the process */
2170         pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2171         upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2172 
2173         /*
2174          * We don't want the full treatment of prlock(pnp) here.
2175          * This file is world-readable and never goes invalid.
2176          * It doesn't matter if we are in the middle of an exec().
2177          */
2178         p = pr_p_lock(pnp);
2179         mutex_exit(&pr_pidlock);
2180         if (p == NULL) {
2181                 error = ENOENT;
2182                 goto out;
2183         }
2184         ASSERT(p == pnp->pr_common->prc_proc);
2185 
2186         if (uiop->uio_offset >= sizeof (prusage32_t)) {
2187                 prunlock(pnp);
2188                 error = 0;
2189                 goto out;
2190         }
2191 
2192         pup->pr_tstamp = gethrtime();
2193 
2194         pup->pr_count  = p->p_defunct;
2195         pup->pr_create = p->p_mstart;
2196         pup->pr_term   = p->p_mterm;
2197 
2198         pup->pr_rtime    = p->p_mlreal;
2199         pup->pr_utime    = p->p_acct[LMS_USER];
2200         pup->pr_stime    = p->p_acct[LMS_SYSTEM];
2201         pup->pr_ttime    = p->p_acct[LMS_TRAP];
2202         pup->pr_tftime   = p->p_acct[LMS_TFAULT];
2203         pup->pr_dftime   = p->p_acct[LMS_DFAULT];
2204         pup->pr_kftime   = p->p_acct[LMS_KFAULT];
2205         pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
2206         pup->pr_slptime  = p->p_acct[LMS_SLEEP];
2207         pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
2208         pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2209 
2210         pup->pr_minf  = p->p_ru.minflt;
2211         pup->pr_majf  = p->p_ru.majflt;
2212         pup->pr_nswap = p->p_ru.nswap;
2213         pup->pr_inblk = p->p_ru.inblock;
2214         pup->pr_oublk = p->p_ru.oublock;
2215         pup->pr_msnd  = p->p_ru.msgsnd;
2216         pup->pr_mrcv  = p->p_ru.msgrcv;
2217         pup->pr_sigs  = p->p_ru.nsignals;
2218         pup->pr_vctx  = p->p_ru.nvcsw;
2219         pup->pr_ictx  = p->p_ru.nivcsw;
2220         pup->pr_sysc  = p->p_ru.sysc;
2221         pup->pr_ioch  = p->p_ru.ioch;
2222 
2223         /*
2224          * Add the usage information for each active lwp.
2225          */
2226         if ((t = p->p_tlist) != NULL &&
2227             !(pnp->pr_pcommon->prc_flags & PRC_DESTROY)) {
2228                 do {
2229                         if (t->t_proc_flag & TP_LWPEXIT)
2230                                 continue;
2231                         pup->pr_count++;
2232                         praddusage(t, pup);
2233                 } while ((t = t->t_forw) != p->p_tlist);
2234         }
2235 
2236         prunlock(pnp);
2237 
2238         prcvtusage32(pup, upup);
2239 
2240         error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2241 out:
2242         kmem_free(pup, sizeof (*pup));
2243         kmem_free(upup, sizeof (*upup));
2244         return (error);
2245 }
2246 
2247 static int
2248 pr_read_lusage_32(prnode_t *pnp, uio_t *uiop)
2249 {
2250         int nlwp;
2251         prhusage_t *pup;
2252         prheader32_t *php;
2253         prusage32_t *upup;
2254         size_t size;
2255         hrtime_t curtime;
2256         proc_t *p;
2257         kthread_t *t;
2258         lwpdir_t *ldp;
2259         int error;
2260         int i;
2261 
2262         ASSERT(pnp->pr_type == PR_LUSAGE);
2263 
2264         /*
2265          * We don't want the full treatment of prlock(pnp) here.
2266          * This file is world-readable and never goes invalid.
2267          * It doesn't matter if we are in the middle of an exec().
2268          */
2269         p = pr_p_lock(pnp);
2270         mutex_exit(&pr_pidlock);
2271         if (p == NULL)
2272                 return (ENOENT);
2273         ASSERT(p == pnp->pr_common->prc_proc);
2274         if ((nlwp = p->p_lwpcnt) == 0) {
2275                 prunlock(pnp);
2276                 return (ENOENT);
2277         }
2278 
2279         size = sizeof (prheader32_t) + (nlwp + 1) * LSPAN32(prusage32_t);
2280         if (uiop->uio_offset >= size) {
2281                 prunlock(pnp);
2282                 return (0);
2283         }
2284 
2285         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2286         mutex_exit(&p->p_lock);
2287         pup = kmem_zalloc(size + sizeof (prhusage_t), KM_SLEEP);
2288         mutex_enter(&p->p_lock);
2289         /* p->p_lwpcnt can't change while process is locked */
2290         ASSERT(nlwp == p->p_lwpcnt);
2291 
2292         php = (prheader32_t *)(pup + 1);
2293         upup = (prusage32_t *)(php + 1);
2294 
2295         php->pr_nent = nlwp + 1;
2296         php->pr_entsize = LSPAN32(prusage32_t);
2297 
2298         curtime = gethrtime();
2299 
2300         /*
2301          * First the summation over defunct lwps.
2302          */
2303         pup->pr_count  = p->p_defunct;
2304         pup->pr_tstamp = curtime;
2305         pup->pr_create = p->p_mstart;
2306         pup->pr_term   = p->p_mterm;
2307 
2308         pup->pr_rtime    = p->p_mlreal;
2309         pup->pr_utime    = p->p_acct[LMS_USER];
2310         pup->pr_stime    = p->p_acct[LMS_SYSTEM];
2311         pup->pr_ttime    = p->p_acct[LMS_TRAP];
2312         pup->pr_tftime   = p->p_acct[LMS_TFAULT];
2313         pup->pr_dftime   = p->p_acct[LMS_DFAULT];
2314         pup->pr_kftime   = p->p_acct[LMS_KFAULT];
2315         pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
2316         pup->pr_slptime  = p->p_acct[LMS_SLEEP];
2317         pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
2318         pup->pr_stoptime = p->p_acct[LMS_STOPPED];
2319 
2320         pup->pr_minf  = p->p_ru.minflt;
2321         pup->pr_majf  = p->p_ru.majflt;
2322         pup->pr_nswap = p->p_ru.nswap;
2323         pup->pr_inblk = p->p_ru.inblock;
2324         pup->pr_oublk = p->p_ru.oublock;
2325         pup->pr_msnd  = p->p_ru.msgsnd;
2326         pup->pr_mrcv  = p->p_ru.msgrcv;
2327         pup->pr_sigs  = p->p_ru.nsignals;
2328         pup->pr_vctx  = p->p_ru.nvcsw;
2329         pup->pr_ictx  = p->p_ru.nivcsw;
2330         pup->pr_sysc  = p->p_ru.sysc;
2331         pup->pr_ioch  = p->p_ru.ioch;
2332 
2333         prcvtusage32(pup, upup);
2334 
2335         /*
2336          * Fill one prusage struct for each active lwp.
2337          */
2338         for (ldp = p->p_lwpdir, i = 0; i < p->p_lwpdir_sz; i++, ldp++) {
2339                 if (ldp->ld_entry == NULL ||
2340                     (t = ldp->ld_entry->le_thread) == NULL)
2341                         continue;
2342                 ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
2343                 ASSERT(nlwp > 0);
2344                 --nlwp;
2345                 upup = (prusage32_t *)
2346                     ((caddr_t)upup + LSPAN32(prusage32_t));
2347                 prgetusage(t, pup);
2348                 prcvtusage32(pup, upup);
2349         }
2350         ASSERT(nlwp == 0);
2351 
2352         prunlock(pnp);
2353 
2354         error = pr_uioread(php, size, uiop);
2355         kmem_free(pup, size + sizeof (prhusage_t));
2356         return (error);
2357 }
2358 
2359 static int
2360 pr_read_pagedata_32(prnode_t *pnp, uio_t *uiop)
2361 {
2362         proc_t *p;
2363         int error;
2364 
2365         ASSERT(pnp->pr_type == PR_PAGEDATA);
2366 
2367         if ((error = prlock(pnp, ZNO)) != 0)
2368                 return (error);
2369 
2370         p = pnp->pr_common->prc_proc;
2371         if ((p->p_flag & SSYS) || p->p_as == &kas) {
2372                 prunlock(pnp);
2373                 return (0);
2374         }
2375 
2376         if (PROCESS_NOT_32BIT(p)) {
2377                 prunlock(pnp);
2378                 return (EOVERFLOW);
2379         }
2380 
2381         mutex_exit(&p->p_lock);
2382         error = prpdread32(p, pnp->pr_hatid, uiop);
2383         mutex_enter(&p->p_lock);
2384 
2385         prunlock(pnp);
2386         return (error);
2387 }
2388 
2389 static int
2390 pr_read_opagedata_32(prnode_t *pnp, uio_t *uiop)
2391 {
2392         proc_t *p;
2393         struct as *as;
2394         int error;
2395 
2396         ASSERT(pnp->pr_type == PR_OPAGEDATA);
2397 
2398         if ((error = prlock(pnp, ZNO)) != 0)
2399                 return (error);
2400 
2401         p = pnp->pr_common->prc_proc;
2402         as = p->p_as;
2403 
2404         if ((p->p_flag & SSYS) || as == &kas) {
2405                 prunlock(pnp);
2406                 return (0);
2407         }
2408 
2409         if (PROCESS_NOT_32BIT(p)) {
2410                 prunlock(pnp);
2411                 return (EOVERFLOW);
2412         }
2413 
2414         mutex_exit(&p->p_lock);
2415         error = oprpdread32(as, pnp->pr_hatid, uiop);
2416         mutex_enter(&p->p_lock);
2417 
2418         prunlock(pnp);
2419         return (error);
2420 }
2421 
2422 static int
2423 pr_read_watch_32(prnode_t *pnp, uio_t *uiop)
2424 {
2425         proc_t *p;
2426         int error;
2427         prwatch32_t *Bpwp;
2428         size_t size;
2429         prwatch32_t *pwp;
2430         int nwarea;
2431         struct watched_area *pwarea;
2432 
2433         ASSERT(pnp->pr_type == PR_WATCH);
2434 
2435         if ((error = prlock(pnp, ZNO)) != 0)
2436                 return (error);
2437 
2438         p = pnp->pr_common->prc_proc;
2439         if (PROCESS_NOT_32BIT(p)) {
2440                 prunlock(pnp);
2441                 return (EOVERFLOW);
2442         }
2443         nwarea = avl_numnodes(&p->p_warea);
2444         size = nwarea * sizeof (prwatch32_t);
2445         if (uiop->uio_offset >= size) {
2446                 prunlock(pnp);
2447                 return (0);
2448         }
2449 
2450         /* drop p->p_lock to do kmem_alloc(KM_SLEEP) */
2451         mutex_exit(&p->p_lock);
2452         Bpwp = pwp = kmem_zalloc(size, KM_SLEEP);
2453         mutex_enter(&p->p_lock);
2454         /* p->p_nwarea can't change while process is locked */
2455         ASSERT(nwarea == avl_numnodes(&p->p_warea));
2456 
2457         /* gather the watched areas */
2458         for (pwarea = avl_first(&p->p_warea); pwarea != NULL;
2459             pwarea = AVL_NEXT(&p->p_warea, pwarea), pwp++) {
2460                 pwp->pr_vaddr = (caddr32_t)(uintptr_t)pwarea->wa_vaddr;
2461                 pwp->pr_size = (size32_t)(pwarea->wa_eaddr - pwarea->wa_vaddr);
2462                 pwp->pr_wflags = (int)pwarea->wa_flags;
2463         }
2464 
2465         prunlock(pnp);
2466 
2467         error = pr_uioread(Bpwp, size, uiop);
2468         kmem_free(Bpwp, size);
2469         return (error);
2470 }
2471 
2472 static int
2473 pr_read_lwpstatus_32(prnode_t *pnp, uio_t *uiop)
2474 {
2475         lwpstatus32_t *sp;
2476         proc_t *p;
2477         int error;
2478 
2479         ASSERT(pnp->pr_type == PR_LWPSTATUS);
2480 
2481         /*
2482          * We kmem_alloc() the lwpstatus structure because
2483          * it is so big it might blow the kernel stack.
2484          */
2485         sp = kmem_alloc(sizeof (*sp), KM_SLEEP);
2486 
2487         if ((error = prlock(pnp, ZNO)) != 0)
2488                 goto out;
2489 
2490         /*
2491          * A 32-bit process cannot get the status of a 64-bit process.
2492          * The fields for the 64-bit quantities are not large enough.
2493          */
2494         p = pnp->pr_common->prc_proc;
2495         if (PROCESS_NOT_32BIT(p)) {
2496                 prunlock(pnp);
2497                 error = EOVERFLOW;
2498                 goto out;
2499         }
2500 
2501         if (uiop->uio_offset >= sizeof (*sp)) {
2502                 prunlock(pnp);
2503                 goto out;
2504         }
2505 
2506         prgetlwpstatus32(pnp->pr_common->prc_thread, sp, VTOZONE(PTOV(pnp)));
2507         prunlock(pnp);
2508 
2509         error = pr_uioread(sp, sizeof (*sp), uiop);
2510 out:
2511         kmem_free(sp, sizeof (*sp));
2512         return (error);
2513 }
2514 
2515 static int
2516 pr_read_lwpsinfo_32(prnode_t *pnp, uio_t *uiop)
2517 {
2518         lwpsinfo32_t lwpsinfo;
2519         proc_t *p;
2520         kthread_t *t;
2521         lwpent_t *lep;
2522 
2523         ASSERT(pnp->pr_type == PR_LWPSINFO);
2524 
2525         /*
2526          * We don't want the full treatment of prlock(pnp) here.
2527          * This file is world-readable and never goes invalid.
2528          * It doesn't matter if we are in the middle of an exec().
2529          */
2530         p = pr_p_lock(pnp);
2531         mutex_exit(&pr_pidlock);
2532         if (p == NULL)
2533                 return (ENOENT);
2534         ASSERT(p == pnp->pr_common->prc_proc);
2535         if (pnp->pr_common->prc_tslot == -1) {
2536                 prunlock(pnp);
2537                 return (ENOENT);
2538         }
2539 
2540         if (uiop->uio_offset >= sizeof (lwpsinfo)) {
2541                 prunlock(pnp);
2542                 return (0);
2543         }
2544 
2545         if ((t = pnp->pr_common->prc_thread) != NULL)
2546                 prgetlwpsinfo32(t, &lwpsinfo);
2547         else {
2548                 lep = p->p_lwpdir[pnp->pr_common->prc_tslot].ld_entry;
2549                 bzero(&lwpsinfo, sizeof (lwpsinfo));
2550                 lwpsinfo.pr_lwpid = lep->le_lwpid;
2551                 lwpsinfo.pr_state = SZOMB;
2552                 lwpsinfo.pr_sname = 'Z';
2553                 lwpsinfo.pr_start.tv_sec = (time32_t)lep->le_start;
2554         }
2555         prunlock(pnp);
2556 
2557         return (pr_uioread(&lwpsinfo, sizeof (lwpsinfo), uiop));
2558 }
2559 
2560 static int
2561 pr_read_lwpusage_32(prnode_t *pnp, uio_t *uiop)
2562 {
2563         prhusage_t *pup;
2564         prusage32_t *upup;
2565         proc_t *p;
2566         int error;
2567 
2568         ASSERT(pnp->pr_type == PR_LWPUSAGE);
2569 
2570         /* allocate now, before locking the process */
2571         pup = kmem_zalloc(sizeof (*pup), KM_SLEEP);
2572         upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
2573 
2574         /*
2575          * We don't want the full treatment of prlock(pnp) here.
2576          * This file is world-readable and never goes invalid.
2577          * It doesn't matter if we are in the middle of an exec().
2578          */
2579         p = pr_p_lock(pnp);
2580         mutex_exit(&pr_pidlock);
2581         if (p == NULL) {
2582                 error = ENOENT;
2583                 goto out;
2584         }
2585         ASSERT(p == pnp->pr_common->prc_proc);
2586         if (pnp->pr_common->prc_thread == NULL) {
2587                 prunlock(pnp);
2588                 error = ENOENT;
2589                 goto out;
2590         }
2591         if (uiop->uio_offset >= sizeof (prusage32_t)) {
2592                 prunlock(pnp);
2593                 error = 0;
2594                 goto out;
2595         }
2596 
2597         pup->pr_tstamp = gethrtime();
2598         prgetusage(pnp->pr_common->prc_thread, pup);
2599 
2600         prunlock(pnp);
2601 
2602         prcvtusage32(pup, upup);
2603 
2604         error = pr_uioread(upup, sizeof (prusage32_t), uiop);
2605 out:
2606         kmem_free(pup, sizeof (*pup));
2607         kmem_free(upup, sizeof (*upup));
2608         return (error);
2609 }
2610 
2611 static int
2612 pr_read_spymaster_32(prnode_t *pnp, uio_t *uiop)
2613 {
2614         psinfo32_t psinfo;
2615         int error;
2616         klwp_t *lwp;
2617 
2618         ASSERT(pnp->pr_type == PR_SPYMASTER);
2619 
2620         if ((error = prlock(pnp, ZNO)) != 0)
2621                 return (error);
2622 
2623         lwp = pnp->pr_common->prc_thread->t_lwp;
2624 
2625         if (lwp->lwp_spymaster == NULL) {
2626                 prunlock(pnp);
2627                 return (0);
2628         }
2629 
2630         psinfo_kto32(lwp->lwp_spymaster, &psinfo);
2631         prunlock(pnp);
2632 
2633         return (pr_uioread(&psinfo, sizeof (psinfo), uiop));
2634 }
2635 
2636 #if defined(__sparc)
2637 static int
2638 pr_read_gwindows_32(prnode_t *pnp, uio_t *uiop)
2639 {
2640         proc_t *p;
2641         kthread_t *t;
2642         gwindows32_t *gwp;
2643         int error;
2644         size_t size;
2645 
2646         ASSERT(pnp->pr_type == PR_GWINDOWS);
2647 
2648         gwp = kmem_zalloc(sizeof (gwindows32_t), KM_SLEEP);
2649 
2650         if ((error = prlock(pnp, ZNO)) != 0)
2651                 goto out;
2652 
2653         p = pnp->pr_common->prc_proc;
2654         t = pnp->pr_common->prc_thread;
2655 
2656         if (PROCESS_NOT_32BIT(p)) {
2657                 prunlock(pnp);
2658                 error = EOVERFLOW;
2659                 goto out;
2660         }
2661 
2662         /*
2663          * Drop p->p_lock while touching the stack.
2664          * The P_PR_LOCK flag prevents the lwp from
2665          * disappearing while we do this.
2666          */
2667         mutex_exit(&p->p_lock);
2668         if ((size = prnwindows(ttolwp(t))) != 0)
2669                 size = sizeof (gwindows32_t) -
2670                     (SPARC_MAXREGWINDOW - size) * sizeof (struct rwindow32);
2671         if (uiop->uio_offset >= size) {
2672                 mutex_enter(&p->p_lock);
2673                 prunlock(pnp);
2674                 goto out;
2675         }
2676         prgetwindows32(ttolwp(t), gwp);
2677         mutex_enter(&p->p_lock);
2678         prunlock(pnp);
2679 
2680         error = pr_uioread(gwp, size, uiop);
2681 out:
2682         kmem_free(gwp, sizeof (gwindows32_t));
2683         return (error);
2684 }
2685 #endif  /* __sparc */
2686 
2687 #endif  /* _SYSCALL32_IMPL */
2688 
2689 /* ARGSUSED */
2690 static int
2691 prread(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2692 {
2693         prnode_t *pnp = VTOP(vp);
2694 
2695         ASSERT(pnp->pr_type < PR_NFILES);
2696 
2697 #ifdef _SYSCALL32_IMPL
2698         /*
2699          * What is read from the /proc files depends on the data
2700          * model of the caller.  An LP64 process will see LP64
2701          * data.  An ILP32 process will see ILP32 data.
2702          */
2703         if (curproc->p_model == DATAMODEL_LP64)
2704                 return (pr_read_function[pnp->pr_type](pnp, uiop));
2705         else
2706                 return (pr_read_function_32[pnp->pr_type](pnp, uiop));
2707 #else
2708         return (pr_read_function[pnp->pr_type](pnp, uiop));
2709 #endif
2710 }
2711 
2712 /* ARGSUSED */
2713 static int
2714 prwrite(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, caller_context_t *ct)
2715 {
2716         prnode_t *pnp = VTOP(vp);
2717         int old = 0;
2718         int error;
2719         ssize_t resid;
2720 
2721         ASSERT(pnp->pr_type < PR_NFILES);
2722 
2723         /*
2724          * Only a handful of /proc files are writable, enumerate them here.
2725          */
2726         switch (pnp->pr_type) {
2727         case PR_PIDDIR:         /* directory write()s: visceral revulsion. */
2728                 ASSERT(pnp->pr_pidfile != NULL);
2729                 /* use the underlying PR_PIDFILE to write the process */
2730                 vp = pnp->pr_pidfile;
2731                 pnp = VTOP(vp);
2732                 ASSERT(pnp->pr_type == PR_PIDFILE);
2733                 /* FALLTHROUGH */
2734         case PR_PIDFILE:
2735         case PR_LWPIDFILE:
2736                 old = 1;
2737                 /* FALLTHROUGH */
2738         case PR_AS:
2739                 if ((error = prlock(pnp, ZNO)) == 0) {
2740                         proc_t *p = pnp->pr_common->prc_proc;
2741                         struct as *as = p->p_as;
2742 
2743                         if ((p->p_flag & SSYS) || as == &kas) {
2744                                 /*
2745                                  * /proc I/O cannot be done to a system process.
2746                                  */
2747                                 error = EIO;
2748 #ifdef _SYSCALL32_IMPL
2749                         } else if (curproc->p_model == DATAMODEL_ILP32 &&
2750                             PROCESS_NOT_32BIT(p)) {
2751                                 error = EOVERFLOW;
2752 #endif
2753                         } else {
2754                                 /*
2755                                  * See comments above (pr_read_pidfile)
2756                                  * about this locking dance.
2757                                  */
2758                                 mutex_exit(&p->p_lock);
2759                                 error = prusrio(p, UIO_WRITE, uiop, old);
2760                                 mutex_enter(&p->p_lock);
2761                         }
2762                         prunlock(pnp);
2763                 }
2764                 return (error);
2765 
2766         case PR_CTL:
2767         case PR_LWPCTL:
2768                 resid = uiop->uio_resid;
2769                 /*
2770                  * Perform the action on the control file
2771                  * by passing curthreads credentials
2772                  * and not target process's credentials.
2773                  */
2774 #ifdef _SYSCALL32_IMPL
2775                 if (curproc->p_model == DATAMODEL_ILP32)
2776                         error = prwritectl32(vp, uiop, CRED());
2777                 else
2778                         error = prwritectl(vp, uiop, CRED());
2779 #else
2780                 error = prwritectl(vp, uiop, CRED());
2781 #endif
2782                 /*
2783                  * This hack makes sure that the EINTR is passed
2784                  * all the way back to the caller's write() call.
2785                  */
2786                 if (error == EINTR)
2787                         uiop->uio_resid = resid;
2788                 return (error);
2789 
2790         default:
2791                 return ((vp->v_type == VDIR)? EISDIR : EBADF);
2792         }
2793         /* NOTREACHED */
2794 }
2795 
2796 static int
2797 prgetattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
2798     caller_context_t *ct)
2799 {
2800         prnode_t *pnp = VTOP(vp);
2801         prnodetype_t type = pnp->pr_type;
2802         prcommon_t *pcp;
2803         proc_t *p;
2804         struct as *as;
2805         int error;
2806         vnode_t *rvp;
2807         timestruc_t now;
2808         extern uint_t nproc;
2809         int ngroups;
2810         int nsig;
2811 
2812         /*
2813          * This ugly bit of code allows us to keep both versions of this
2814          * function from the same source.
2815          */
2816 #ifdef _LP64
2817         int iam32bit = (curproc->p_model == DATAMODEL_ILP32);
2818 #define PR_OBJSIZE(obj32, obj64)        \
2819         (iam32bit ? sizeof (obj32) : sizeof (obj64))
2820 #define PR_OBJSPAN(obj32, obj64)        \
2821         (iam32bit ? LSPAN32(obj32) : LSPAN(obj64))
2822 #else
2823 #define PR_OBJSIZE(obj32, obj64)        \
2824         (sizeof (obj64))
2825 #define PR_OBJSPAN(obj32, obj64)        \
2826         (LSPAN(obj64))
2827 #endif
2828 
2829         /*
2830          * Return all the attributes.  Should be refined
2831          * so that it returns only those asked for.
2832          * Most of this is complete fakery anyway.
2833          */
2834 
2835         /*
2836          * For files in the /proc/<pid>/object directory,
2837          * return the attributes of the underlying object.
2838          * For files in the /proc/<pid>/fd directory,
2839          * return the attributes of the underlying file, but
2840          * make it look inaccessible if it is not a regular file.
2841          * Make directories look like symlinks.
2842          */
2843         switch (type) {
2844         case PR_CURDIR:
2845         case PR_ROOTDIR:
2846                 if (!(flags & ATTR_REAL))
2847                         break;
2848                 /* restrict full knowledge of the attributes to owner or root */
2849                 if ((error = praccess(vp, 0, 0, cr, ct)) != 0)
2850                         return (error);
2851                 /* FALLTHROUGH */
2852         case PR_OBJECT:
2853         case PR_FD:
2854                 rvp = pnp->pr_realvp;
2855                 error = VOP_GETATTR(rvp, vap, flags, cr, ct);
2856                 if (error)
2857                         return (error);
2858                 if (type == PR_FD) {
2859                         if (rvp->v_type != VREG && rvp->v_type != VDIR)
2860                                 vap->va_mode = 0;
2861                         else
2862                                 vap->va_mode &= pnp->pr_mode;
2863                 }
2864                 if (type == PR_OBJECT)
2865                         vap->va_mode &= 07555;
2866                 if (rvp->v_type == VDIR && !(flags & ATTR_REAL)) {
2867                         vap->va_type = VLNK;
2868                         vap->va_size = 0;
2869                         vap->va_nlink = 1;
2870                 }
2871                 return (0);
2872         default:
2873                 break;
2874         }
2875 
2876         bzero(vap, sizeof (*vap));
2877         /*
2878          * Large Files: Internally proc now uses VPROC to indicate
2879          * a proc file. Since we have been returning VREG through
2880          * VOP_GETATTR() until now, we continue to do this so as
2881          * not to break apps depending on this return value.
2882          */
2883         vap->va_type = (vp->v_type == VPROC) ? VREG : vp->v_type;
2884         vap->va_mode = pnp->pr_mode;
2885         vap->va_fsid = vp->v_vfsp->vfs_dev;
2886         vap->va_blksize = DEV_BSIZE;
2887         vap->va_rdev = 0;
2888         vap->va_seq = 0;
2889 
2890         if (type == PR_PROCDIR) {
2891                 vap->va_uid = 0;
2892                 vap->va_gid = 0;
2893                 vap->va_nlink = nproc + 2;
2894                 vap->va_nodeid = (ino64_t)PRROOTINO;
2895                 gethrestime(&now);
2896                 vap->va_atime = vap->va_mtime = vap->va_ctime = now;
2897                 vap->va_size = (v.v_proc + 2) * PRSDSIZE;
2898                 vap->va_nblocks = btod(vap->va_size);
2899                 return (0);
2900         }
2901 
2902         /*
2903          * /proc/<pid>/self is a symbolic link, and has no prcommon member
2904          */
2905         if (type == PR_SELF) {
2906                 vap->va_uid = crgetruid(CRED());
2907                 vap->va_gid = crgetrgid(CRED());
2908                 vap->va_nodeid = (ino64_t)PR_SELF;
2909                 gethrestime(&now);
2910                 vap->va_atime = vap->va_mtime = vap->va_ctime = now;
2911                 vap->va_nlink = 1;
2912                 vap->va_type = VLNK;
2913                 vap->va_size = 0;
2914                 return (0);
2915         }
2916 
2917         p = pr_p_lock(pnp);
2918         mutex_exit(&pr_pidlock);
2919         if (p == NULL)
2920                 return (ENOENT);
2921         pcp = pnp->pr_common;
2922 
2923         mutex_enter(&p->p_crlock);
2924         vap->va_uid = crgetruid(p->p_cred);
2925         vap->va_gid = crgetrgid(p->p_cred);
2926         mutex_exit(&p->p_crlock);
2927 
2928         vap->va_nlink = 1;
2929         vap->va_nodeid = pnp->pr_ino? pnp->pr_ino :
2930             pmkino(pcp->prc_tslot, pcp->prc_slot, pnp->pr_type);
2931         if ((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot != -1) {
2932                 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2933                     vap->va_ctime.tv_sec =
2934                     p->p_lwpdir[pcp->prc_tslot].ld_entry->le_start;
2935                 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2936                     vap->va_ctime.tv_nsec = 0;
2937         } else {
2938                 user_t *up = PTOU(p);
2939                 vap->va_atime.tv_sec = vap->va_mtime.tv_sec =
2940                     vap->va_ctime.tv_sec = up->u_start.tv_sec;
2941                 vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec =
2942                     vap->va_ctime.tv_nsec = up->u_start.tv_nsec;
2943         }
2944 
2945         switch (type) {
2946         case PR_PIDDIR:
2947                 /* va_nlink: count 'lwp', 'object' and 'fd' directory links */
2948                 vap->va_nlink = 5;
2949                 vap->va_size = sizeof (piddir);
2950                 break;
2951         case PR_OBJECTDIR:
2952                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2953                         vap->va_size = 2 * PRSDSIZE;
2954                 else {
2955                         mutex_exit(&p->p_lock);
2956                         AS_LOCK_ENTER(as, RW_WRITER);
2957                         if (as->a_updatedir)
2958                                 rebuild_objdir(as);
2959                         vap->va_size = (as->a_sizedir + 2) * PRSDSIZE;
2960                         AS_LOCK_EXIT(as);
2961                         mutex_enter(&p->p_lock);
2962                 }
2963                 vap->va_nlink = 2;
2964                 break;
2965         case PR_PATHDIR:
2966                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
2967                         vap->va_size = (P_FINFO(p)->fi_nfiles + 4) * PRSDSIZE;
2968                 else {
2969                         mutex_exit(&p->p_lock);
2970                         AS_LOCK_ENTER(as, RW_WRITER);
2971                         if (as->a_updatedir)
2972                                 rebuild_objdir(as);
2973                         vap->va_size = (as->a_sizedir + 4 +
2974                             P_FINFO(p)->fi_nfiles) * PRSDSIZE;
2975                         AS_LOCK_EXIT(as);
2976                         mutex_enter(&p->p_lock);
2977                 }
2978                 vap->va_nlink = 2;
2979                 break;
2980         case PR_PATH:
2981         case PR_CURDIR:
2982         case PR_ROOTDIR:
2983         case PR_CT:
2984                 vap->va_type = VLNK;
2985                 vap->va_size = 0;
2986                 break;
2987         case PR_FDDIR:
2988                 vap->va_nlink = 2;
2989                 vap->va_size = (P_FINFO(p)->fi_nfiles + 2) * PRSDSIZE;
2990                 break;
2991         case PR_LWPDIR:
2992                 /*
2993                  * va_nlink: count each lwp as a directory link.
2994                  * va_size: size of p_lwpdir + 2
2995                  */
2996                 vap->va_nlink = p->p_lwpcnt + p->p_zombcnt + 2;
2997                 vap->va_size = (p->p_lwpdir_sz + 2) * PRSDSIZE;
2998                 break;
2999         case PR_LWPIDDIR:
3000                 vap->va_nlink = 2;
3001                 vap->va_size = sizeof (lwpiddir);
3002                 break;
3003         case PR_CTDIR:
3004                 vap->va_nlink = 2;
3005                 vap->va_size = (avl_numnodes(&p->p_ct_held) + 2) * PRSDSIZE;
3006                 break;
3007         case PR_TMPLDIR:
3008                 vap->va_nlink = 2;
3009                 vap->va_size = (ct_ntypes + 2) * PRSDSIZE;
3010                 break;
3011         case PR_AS:
3012         case PR_PIDFILE:
3013         case PR_LWPIDFILE:
3014                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3015                         vap->va_size = 0;
3016                 else
3017                         vap->va_size = as->a_resvsize;
3018                 break;
3019         case PR_STATUS:
3020                 vap->va_size = PR_OBJSIZE(pstatus32_t, pstatus_t);
3021                 break;
3022         case PR_LSTATUS:
3023                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3024                     p->p_lwpcnt * PR_OBJSPAN(lwpstatus32_t, lwpstatus_t);
3025                 break;
3026         case PR_PSINFO:
3027                 vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3028                 break;
3029         case PR_LPSINFO:
3030                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3031                     (p->p_lwpcnt + p->p_zombcnt) *
3032                     PR_OBJSPAN(lwpsinfo32_t, lwpsinfo_t);
3033                 break;
3034         case PR_MAP:
3035         case PR_RMAP:
3036         case PR_XMAP:
3037                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3038                         vap->va_size = 0;
3039                 else {
3040                         mutex_exit(&p->p_lock);
3041                         AS_LOCK_ENTER(as, RW_WRITER);
3042                         if (type == PR_MAP)
3043                                 vap->va_mtime = as->a_updatetime;
3044                         if (type == PR_XMAP)
3045                                 vap->va_size = prnsegs(as, 0) *
3046                                     PR_OBJSIZE(prxmap32_t, prxmap_t);
3047                         else
3048                                 vap->va_size = prnsegs(as, type == PR_RMAP) *
3049                                     PR_OBJSIZE(prmap32_t, prmap_t);
3050                         AS_LOCK_EXIT(as);
3051                         mutex_enter(&p->p_lock);
3052                 }
3053                 break;
3054         case PR_CRED:
3055                 mutex_enter(&p->p_crlock);
3056                 vap->va_size = sizeof (prcred_t);
3057                 ngroups = crgetngroups(p->p_cred);
3058                 if (ngroups > 1)
3059                         vap->va_size += (ngroups - 1) * sizeof (gid_t);
3060                 mutex_exit(&p->p_crlock);
3061                 break;
3062         case PR_PRIV:
3063                 vap->va_size = prgetprivsize();
3064                 break;
3065         case PR_SECFLAGS:
3066                 vap->va_size = sizeof (prsecflags_t);
3067                 break;
3068         case PR_SIGACT:
3069                 nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
3070                 vap->va_size = (nsig-1) *
3071                     PR_OBJSIZE(struct sigaction32, struct sigaction);
3072                 break;
3073         case PR_AUXV:
3074                 vap->va_size = __KERN_NAUXV_IMPL * PR_OBJSIZE(auxv32_t, auxv_t);
3075                 break;
3076 #if defined(__x86)
3077         case PR_LDT:
3078                 mutex_exit(&p->p_lock);
3079                 mutex_enter(&p->p_ldtlock);
3080                 vap->va_size = prnldt(p) * sizeof (struct ssd);
3081                 mutex_exit(&p->p_ldtlock);
3082                 mutex_enter(&p->p_lock);
3083                 break;
3084 #endif
3085         case PR_USAGE:
3086                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3087                 break;
3088         case PR_LUSAGE:
3089                 vap->va_size = PR_OBJSIZE(prheader32_t, prheader_t) +
3090                     (p->p_lwpcnt + 1) * PR_OBJSPAN(prusage32_t, prusage_t);
3091                 break;
3092         case PR_PAGEDATA:
3093                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3094                         vap->va_size = 0;
3095                 else {
3096                         /*
3097                          * We can drop p->p_lock before grabbing the
3098                          * address space lock because p->p_as will not
3099                          * change while the process is marked P_PR_LOCK.
3100                          */
3101                         mutex_exit(&p->p_lock);
3102                         AS_LOCK_ENTER(as, RW_WRITER);
3103 #ifdef _LP64
3104                         vap->va_size = iam32bit?
3105                             prpdsize32(as) : prpdsize(as);
3106 #else
3107                         vap->va_size = prpdsize(as);
3108 #endif
3109                         AS_LOCK_EXIT(as);
3110                         mutex_enter(&p->p_lock);
3111                 }
3112                 break;
3113         case PR_OPAGEDATA:
3114                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas)
3115                         vap->va_size = 0;
3116                 else {
3117                         mutex_exit(&p->p_lock);
3118                         AS_LOCK_ENTER(as, RW_WRITER);
3119 #ifdef _LP64
3120                         vap->va_size = iam32bit?
3121                             oprpdsize32(as) : oprpdsize(as);
3122 #else
3123                         vap->va_size = oprpdsize(as);
3124 #endif
3125                         AS_LOCK_EXIT(as);
3126                         mutex_enter(&p->p_lock);
3127                 }
3128                 break;
3129         case PR_WATCH:
3130                 vap->va_size = avl_numnodes(&p->p_warea) *
3131                     PR_OBJSIZE(prwatch32_t, prwatch_t);
3132                 break;
3133         case PR_LWPSTATUS:
3134                 vap->va_size = PR_OBJSIZE(lwpstatus32_t, lwpstatus_t);
3135                 break;
3136         case PR_LWPSINFO:
3137                 vap->va_size = PR_OBJSIZE(lwpsinfo32_t, lwpsinfo_t);
3138                 break;
3139         case PR_LWPUSAGE:
3140                 vap->va_size = PR_OBJSIZE(prusage32_t, prusage_t);
3141                 break;
3142         case PR_XREGS:
3143                 if (prhasx(p))
3144                         vap->va_size = prgetprxregsize(p);
3145                 else
3146                         vap->va_size = 0;
3147                 break;
3148         case PR_SPYMASTER:
3149                 if (pnp->pr_common->prc_thread->t_lwp->lwp_spymaster != NULL) {
3150                         vap->va_size = PR_OBJSIZE(psinfo32_t, psinfo_t);
3151                 } else {
3152                         vap->va_size = 0;
3153                 }
3154                 break;
3155 #if defined(__sparc)
3156         case PR_GWINDOWS:
3157         {
3158                 kthread_t *t;
3159                 int n;
3160 
3161                 /*
3162                  * If there is no lwp then just make the size zero.
3163                  * This can happen if the lwp exits between the VOP_LOOKUP()
3164                  * of the /proc/<pid>/lwp/<lwpid>/gwindows file and the
3165                  * VOP_GETATTR() of the resulting vnode.
3166                  */
3167                 if ((t = pcp->prc_thread) == NULL) {
3168                         vap->va_size = 0;
3169                         break;
3170                 }
3171                 /*
3172                  * Drop p->p_lock while touching the stack.
3173                  * The P_PR_LOCK flag prevents the lwp from
3174                  * disappearing while we do this.
3175                  */
3176                 mutex_exit(&p->p_lock);
3177                 if ((n = prnwindows(ttolwp(t))) == 0)
3178                         vap->va_size = 0;
3179                 else
3180                         vap->va_size = PR_OBJSIZE(gwindows32_t, gwindows_t) -
3181                             (SPARC_MAXREGWINDOW - n) *
3182                             PR_OBJSIZE(struct rwindow32, struct rwindow);
3183                 mutex_enter(&p->p_lock);
3184                 break;
3185         }
3186         case PR_ASRS:
3187 #ifdef _LP64
3188                 if (p->p_model == DATAMODEL_LP64)
3189                         vap->va_size = sizeof (asrset_t);
3190                 else
3191 #endif
3192                         vap->va_size = 0;
3193                 break;
3194 #endif
3195         case PR_CTL:
3196         case PR_LWPCTL:
3197         default:
3198                 vap->va_size = 0;
3199                 break;
3200         }
3201 
3202         prunlock(pnp);
3203         vap->va_nblocks = (fsblkcnt64_t)btod(vap->va_size);
3204         return (0);
3205 }
3206 
3207 static int
3208 praccess(vnode_t *vp, int mode, int flags, cred_t *cr, caller_context_t *ct)
3209 {
3210         prnode_t *pnp = VTOP(vp);
3211         prnodetype_t type = pnp->pr_type;
3212         int vmode;
3213         vtype_t vtype;
3214         proc_t *p;
3215         int error = 0;
3216         vnode_t *rvp;
3217         vnode_t *xvp;
3218 
3219         if ((mode & VWRITE) && vn_is_readonly(vp))
3220                 return (EROFS);
3221 
3222         switch (type) {
3223         case PR_PROCDIR:
3224                 break;
3225 
3226         case PR_OBJECT:
3227         case PR_FD:
3228                 /*
3229                  * Disallow write access to the underlying objects.
3230                  * Disallow access to underlying non-regular-file fds.
3231                  * Disallow access to fds with other than existing open modes.
3232                  */
3233                 rvp = pnp->pr_realvp;
3234                 vtype = rvp->v_type;
3235                 vmode = pnp->pr_mode;
3236                 if ((type == PR_OBJECT && (mode & VWRITE)) ||
3237                     (type == PR_FD && vtype != VREG && vtype != VDIR) ||
3238                     (type == PR_FD && (vmode & mode) != mode &&
3239                     secpolicy_proc_access(cr) != 0))
3240                         return (EACCES);
3241                 return (VOP_ACCESS(rvp, mode, flags, cr, ct));
3242 
3243         case PR_PSINFO:         /* these files can be read by anyone */
3244         case PR_LPSINFO:
3245         case PR_LWPSINFO:
3246         case PR_LWPDIR:
3247         case PR_LWPIDDIR:
3248         case PR_USAGE:
3249         case PR_LUSAGE:
3250         case PR_LWPUSAGE:
3251                 p = pr_p_lock(pnp);
3252                 mutex_exit(&pr_pidlock);
3253                 if (p == NULL)
3254                         return (ENOENT);
3255                 prunlock(pnp);
3256                 break;
3257 
3258         default:
3259                 /*
3260                  * Except for the world-readable files above,
3261                  * only /proc/pid exists if the process is a zombie.
3262                  */
3263                 if ((error = prlock(pnp,
3264                     (type == PR_PIDDIR)? ZYES : ZNO)) != 0)
3265                         return (error);
3266                 p = pnp->pr_common->prc_proc;
3267                 if (p != curproc)
3268                         error = priv_proc_cred_perm(cr, p, NULL, mode);
3269 
3270                 if (error != 0 || p == curproc || (p->p_flag & SSYS) ||
3271                     p->p_as == &kas || (xvp = p->p_exec) == NULL) {
3272                         prunlock(pnp);
3273                 } else {
3274                         /*
3275                          * Determine if the process's executable is readable.
3276                          * We have to drop p->p_lock before the secpolicy
3277                          * and VOP operation.
3278                          */
3279                         VN_HOLD(xvp);
3280                         prunlock(pnp);
3281                         if (secpolicy_proc_access(cr) != 0)
3282                                 error = VOP_ACCESS(xvp, VREAD, 0, cr, ct);
3283                         VN_RELE(xvp);
3284                 }
3285                 if (error)
3286                         return (error);
3287                 break;
3288         }
3289 
3290         if (type == PR_CURDIR || type == PR_ROOTDIR) {
3291                 /*
3292                  * Final access check on the underlying directory vnode.
3293                  */
3294                 return (VOP_ACCESS(pnp->pr_realvp, mode, flags, cr, ct));
3295         }
3296 
3297         /*
3298          * Visceral revulsion:  For compatibility with old /proc,
3299          * allow the /proc/<pid> directory to be opened for writing.
3300          */
3301         vmode = pnp->pr_mode;
3302         if (type == PR_PIDDIR)
3303                 vmode |= VWRITE;
3304         if ((vmode & mode) != mode)
3305                 error = secpolicy_proc_access(cr);
3306         return (error);
3307 }
3308 
3309 /*
3310  * Array of lookup functions, indexed by /proc file type.
3311  */
3312 static vnode_t *pr_lookup_notdir(), *pr_lookup_procdir(), *pr_lookup_piddir(),
3313         *pr_lookup_objectdir(), *pr_lookup_lwpdir(), *pr_lookup_lwpiddir(),
3314         *pr_lookup_fddir(), *pr_lookup_pathdir(), *pr_lookup_tmpldir(),
3315         *pr_lookup_ctdir();
3316 
3317 static vnode_t *(*pr_lookup_function[PR_NFILES])() = {
3318         pr_lookup_procdir,      /* /proc                                */
3319         pr_lookup_notdir,       /* /proc/self                           */
3320         pr_lookup_piddir,       /* /proc/<pid>                            */
3321         pr_lookup_notdir,       /* /proc/<pid>/as                 */
3322         pr_lookup_notdir,       /* /proc/<pid>/ctl                        */
3323         pr_lookup_notdir,       /* /proc/<pid>/status                     */
3324         pr_lookup_notdir,       /* /proc/<pid>/lstatus                    */
3325         pr_lookup_notdir,       /* /proc/<pid>/psinfo                     */
3326         pr_lookup_notdir,       /* /proc/<pid>/lpsinfo                    */
3327         pr_lookup_notdir,       /* /proc/<pid>/map                        */
3328         pr_lookup_notdir,       /* /proc/<pid>/rmap                       */
3329         pr_lookup_notdir,       /* /proc/<pid>/xmap                       */
3330         pr_lookup_notdir,       /* /proc/<pid>/cred                       */
3331         pr_lookup_notdir,       /* /proc/<pid>/sigact                     */
3332         pr_lookup_notdir,       /* /proc/<pid>/auxv                       */
3333 #if defined(__x86)
3334         pr_lookup_notdir,       /* /proc/<pid>/ldt                        */
3335 #endif
3336         pr_lookup_notdir,       /* /proc/<pid>/usage                      */
3337         pr_lookup_notdir,       /* /proc/<pid>/lusage                     */
3338         pr_lookup_notdir,       /* /proc/<pid>/pagedata                   */
3339         pr_lookup_notdir,       /* /proc/<pid>/watch                      */
3340         pr_lookup_notdir,       /* /proc/<pid>/cwd                        */
3341         pr_lookup_notdir,       /* /proc/<pid>/root                       */
3342         pr_lookup_fddir,        /* /proc/<pid>/fd                 */
3343         pr_lookup_notdir,       /* /proc/<pid>/fd/nn                      */
3344         pr_lookup_objectdir,    /* /proc/<pid>/object                     */
3345         pr_lookup_notdir,       /* /proc/<pid>/object/xxx         */
3346         pr_lookup_lwpdir,       /* /proc/<pid>/lwp                        */
3347         pr_lookup_lwpiddir,     /* /proc/<pid>/lwp/<lwpid>          */
3348         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
3349         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
3350         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
3351         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/lwpusage */
3352         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/xregs    */
3353         pr_lookup_tmpldir,      /* /proc/<pid>/lwp/<lwpid>/templates        */
3354         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
3355         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/spymaster        */
3356 #if defined(__sparc)
3357         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/gwindows */
3358         pr_lookup_notdir,       /* /proc/<pid>/lwp/<lwpid>/asrs             */
3359 #endif
3360         pr_lookup_notdir,       /* /proc/<pid>/priv                       */
3361         pr_lookup_pathdir,      /* /proc/<pid>/path                       */
3362         pr_lookup_notdir,       /* /proc/<pid>/path/xxx                   */
3363         pr_lookup_ctdir,        /* /proc/<pid>/contracts          */
3364         pr_lookup_notdir,       /* /proc/<pid>/contracts/<ctid>             */
3365         pr_lookup_notdir,       /* /proc/<pid>/secflags                   */
3366         pr_lookup_notdir,       /* old process file                     */
3367         pr_lookup_notdir,       /* old lwp file                         */
3368         pr_lookup_notdir,       /* old pagedata file                    */
3369 };
3370 
3371 static int
3372 prlookup(vnode_t *dp, char *comp, vnode_t **vpp, pathname_t *pathp,
3373     int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
3374     int *direntflags, pathname_t *realpnp)
3375 {
3376         prnode_t *pnp = VTOP(dp);
3377         prnodetype_t type = pnp->pr_type;
3378         int error;
3379 
3380         ASSERT(dp->v_type == VDIR);
3381         ASSERT(type < PR_NFILES);
3382 
3383         if (type != PR_PROCDIR && strcmp(comp, "..") == 0) {
3384                 VN_HOLD(pnp->pr_parent);
3385                 *vpp = pnp->pr_parent;
3386                 return (0);
3387         }
3388 
3389         if (*comp == '\0' ||
3390             strcmp(comp, ".") == 0 || strcmp(comp, "..") == 0) {
3391                 VN_HOLD(dp);
3392                 *vpp = dp;
3393                 return (0);
3394         }
3395 
3396         switch (type) {
3397         case PR_CURDIR:
3398         case PR_ROOTDIR:
3399                 /* restrict lookup permission to owner or root */
3400                 if ((error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3401                         return (error);
3402                 /* FALLTHROUGH */
3403         case PR_FD:
3404                 dp = pnp->pr_realvp;
3405                 return (VOP_LOOKUP(dp, comp, vpp, pathp, flags, rdir, cr, ct,
3406                     direntflags, realpnp));
3407         default:
3408                 break;
3409         }
3410 
3411         if ((type == PR_OBJECTDIR || type == PR_FDDIR || type == PR_PATHDIR) &&
3412             (error = praccess(dp, VEXEC, 0, cr, ct)) != 0)
3413                 return (error);
3414 
3415         /* XXX - Do we need to pass ct, direntflags, or realpnp? */
3416         *vpp = (pr_lookup_function[type](dp, comp));
3417 
3418         return ((*vpp == NULL) ? ENOENT : 0);
3419 }
3420 
3421 /* ARGSUSED */
3422 static int
3423 prcreate(vnode_t *dp, char *comp, vattr_t *vap, vcexcl_t excl,
3424     int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
3425     vsecattr_t *vsecp)
3426 {
3427         int error;
3428 
3429         if ((error = prlookup(dp, comp, vpp, NULL, 0, NULL, cr,
3430             ct, NULL, NULL)) != 0) {
3431                 if (error == ENOENT)    /* can't O_CREAT nonexistent files */
3432                         error = EACCES;         /* unwriteable directories */
3433         } else {
3434                 if (excl == EXCL)                       /* O_EXCL */
3435                         error = EEXIST;
3436                 else if (vap->va_mask & AT_SIZE) {       /* O_TRUNC */
3437                         vnode_t *vp = *vpp;
3438                         uint_t mask;
3439 
3440                         if (vp->v_type == VDIR)
3441                                 error = EISDIR;
3442                         else if (vp->v_type != VPROC ||
3443                             VTOP(vp)->pr_type != PR_FD)
3444                                 error = EACCES;
3445                         else {          /* /proc/<pid>/fd/<n> */
3446                                 vp = VTOP(vp)->pr_realvp;
3447                                 mask = vap->va_mask;
3448                                 vap->va_mask = AT_SIZE;
3449                                 error = VOP_SETATTR(vp, vap, 0, cr, ct);
3450                                 vap->va_mask = mask;
3451                         }
3452                 }
3453                 if (error) {
3454                         VN_RELE(*vpp);
3455                         *vpp = NULL;
3456                 }
3457         }
3458         return (error);
3459 }
3460 
3461 /* ARGSUSED */
3462 static vnode_t *
3463 pr_lookup_notdir(vnode_t *dp, char *comp)
3464 {
3465         return (NULL);
3466 }
3467 
3468 /*
3469  * Find or construct a process vnode for the given pid.
3470  */
3471 static vnode_t *
3472 pr_lookup_procdir(vnode_t *dp, char *comp)
3473 {
3474         pid_t pid;
3475         prnode_t *pnp;
3476         prcommon_t *pcp;
3477         vnode_t *vp;
3478         proc_t *p;
3479         int c;
3480 
3481         ASSERT(VTOP(dp)->pr_type == PR_PROCDIR);
3482 
3483         if (strcmp(comp, "self") == 0) {
3484                 pnp = prgetnode(dp, PR_SELF);
3485                 return (PTOV(pnp));
3486         } else {
3487                 pid = 0;
3488                 while ((c = *comp++) != '\0') {
3489                         if (c < '0' || c > '9')
3490                                 return (NULL);
3491                         pid = 10*pid + c - '0';
3492                         if (pid > maxpid)
3493                                 return (NULL);
3494                 }
3495         }
3496 
3497         pnp = prgetnode(dp, PR_PIDDIR);
3498 
3499         mutex_enter(&pidlock);
3500         if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
3501                 mutex_exit(&pidlock);
3502                 prfreenode(pnp);
3503                 return (NULL);
3504         }
3505         ASSERT(p->p_stat != 0);
3506 
3507         /* NOTE: we're holding pidlock across the policy call. */
3508         if (secpolicy_basic_procinfo(CRED(), p, curproc) != 0) {
3509                 mutex_exit(&pidlock);
3510                 prfreenode(pnp);
3511                 return (NULL);
3512         }
3513 
3514         mutex_enter(&p->p_lock);
3515         mutex_exit(&pidlock);
3516 
3517         /*
3518          * If a process vnode already exists and it is not invalid
3519          * and it was created by the current process and it belongs
3520          * to the same /proc mount point as our parent vnode, then
3521          * just use it and discard the newly-allocated prnode.
3522          */
3523         for (vp = p->p_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3524                 if (!(VTOP(VTOP(vp)->pr_pidfile)->pr_flags & PR_INVAL) &&
3525                     VTOP(vp)->pr_owner == curproc &&
3526                     vp->v_vfsp == dp->v_vfsp) {
3527                         ASSERT(!(VTOP(vp)->pr_flags & PR_INVAL));
3528                         VN_HOLD(vp);
3529                         prfreenode(pnp);
3530                         mutex_exit(&p->p_lock);
3531                         return (vp);
3532                 }
3533         }
3534         pnp->pr_owner = curproc;
3535 
3536         /*
3537          * prgetnode() initialized most of the prnode.
3538          * Finish the job.
3539          */
3540         pcp = pnp->pr_common;        /* the newly-allocated prcommon struct */
3541         if ((vp = p->p_trace) != NULL) {
3542                 /* discard the new prcommon and use the existing prcommon */
3543                 prfreecommon(pcp);
3544                 pcp = VTOP(vp)->pr_common;
3545                 mutex_enter(&pcp->prc_mutex);
3546                 ASSERT(pcp->prc_refcnt > 0);
3547                 pcp->prc_refcnt++;
3548                 mutex_exit(&pcp->prc_mutex);
3549                 pnp->pr_common = pcp;
3550         } else {
3551                 /* initialize the new prcommon struct */
3552                 if ((p->p_flag & SSYS) || p->p_as == &kas)
3553                         pcp->prc_flags |= PRC_SYS;
3554                 if (p->p_stat == SZOMB)
3555                         pcp->prc_flags |= PRC_DESTROY;
3556                 pcp->prc_proc = p;
3557                 pcp->prc_datamodel = p->p_model;
3558                 pcp->prc_pid = p->p_pid;
3559                 pcp->prc_slot = p->p_slot;
3560         }
3561         pnp->pr_pcommon = pcp;
3562         pnp->pr_parent = dp;
3563         VN_HOLD(dp);
3564         /*
3565          * Link in the old, invalid directory vnode so we
3566          * can later determine the last close of the file.
3567          */
3568         pnp->pr_next = p->p_trace;
3569         p->p_trace = dp = PTOV(pnp);
3570 
3571         /*
3572          * Kludge for old /proc: initialize the PR_PIDFILE as well.
3573          */
3574         vp = pnp->pr_pidfile;
3575         pnp = VTOP(vp);
3576         pnp->pr_ino = ptoi(pcp->prc_pid);
3577         pnp->pr_common = pcp;
3578         pnp->pr_pcommon = pcp;
3579         pnp->pr_parent = dp;
3580         pnp->pr_next = p->p_plist;
3581         p->p_plist = vp;
3582 
3583         mutex_exit(&p->p_lock);
3584         return (dp);
3585 }
3586 
3587 static vnode_t *
3588 pr_lookup_piddir(vnode_t *dp, char *comp)
3589 {
3590         prnode_t *dpnp = VTOP(dp);
3591         vnode_t *vp;
3592         prnode_t *pnp;
3593         proc_t *p;
3594         user_t *up;
3595         prdirent_t *dirp;
3596         int i;
3597         enum prnodetype type;
3598 
3599         ASSERT(dpnp->pr_type == PR_PIDDIR);
3600 
3601         for (i = 0; i < NPIDDIRFILES; i++) {
3602                 /* Skip "." and ".." */
3603                 dirp = &piddir[i+2];
3604                 if (strcmp(comp, dirp->d_name) == 0)
3605                         break;
3606         }
3607 
3608         if (i >= NPIDDIRFILES)
3609                 return (NULL);
3610 
3611         type = (int)dirp->d_ino;
3612         pnp = prgetnode(dp, type);
3613 
3614         p = pr_p_lock(dpnp);
3615         mutex_exit(&pr_pidlock);
3616         if (p == NULL) {
3617                 prfreenode(pnp);
3618                 return (NULL);
3619         }
3620         if (dpnp->pr_pcommon->prc_flags & PRC_DESTROY) {
3621                 switch (type) {
3622                 case PR_PSINFO:
3623                 case PR_USAGE:
3624                         break;
3625                 default:
3626                         prunlock(dpnp);
3627                         prfreenode(pnp);
3628                         return (NULL);
3629                 }
3630         }
3631 
3632         switch (type) {
3633         case PR_CURDIR:
3634         case PR_ROOTDIR:
3635                 up = PTOU(p);
3636                 vp = (type == PR_CURDIR)? up->u_cdir :
3637                     (up->u_rdir? up->u_rdir : rootdir);
3638 
3639                 if (vp == NULL) {       /* can't happen? */
3640                         prunlock(dpnp);
3641                         prfreenode(pnp);
3642                         return (NULL);
3643                 }
3644                 /*
3645                  * Fill in the prnode so future references will
3646                  * be able to find the underlying object's vnode.
3647                  */
3648                 VN_HOLD(vp);
3649                 pnp->pr_realvp = vp;
3650                 break;
3651         default:
3652                 break;
3653         }
3654 
3655         mutex_enter(&dpnp->pr_mutex);
3656 
3657         if ((vp = dpnp->pr_files[i]) != NULL &&
3658             !(VTOP(vp)->pr_flags & PR_INVAL)) {
3659                 VN_HOLD(vp);
3660                 mutex_exit(&dpnp->pr_mutex);
3661                 prunlock(dpnp);
3662                 prfreenode(pnp);
3663                 return (vp);
3664         }
3665 
3666         /*
3667          * prgetnode() initialized most of the prnode.
3668          * Finish the job.
3669          */
3670         pnp->pr_common = dpnp->pr_common;
3671         pnp->pr_pcommon = dpnp->pr_pcommon;
3672         pnp->pr_parent = dp;
3673         VN_HOLD(dp);
3674         pnp->pr_index = i;
3675 
3676         dpnp->pr_files[i] = vp = PTOV(pnp);
3677 
3678         /*
3679          * Link new vnode into list of all /proc vnodes for the process.
3680          */
3681         if (vp->v_type == VPROC) {
3682                 pnp->pr_next = p->p_plist;
3683                 p->p_plist = vp;
3684         }
3685         mutex_exit(&dpnp->pr_mutex);
3686         prunlock(dpnp);
3687         return (vp);
3688 }
3689 
3690 static vnode_t *
3691 pr_lookup_objectdir(vnode_t *dp, char *comp)
3692 {
3693         prnode_t *dpnp = VTOP(dp);
3694         prnode_t *pnp;
3695         proc_t *p;
3696         struct seg *seg;
3697         struct as *as;
3698         vnode_t *vp;
3699         vattr_t vattr;
3700 
3701         ASSERT(dpnp->pr_type == PR_OBJECTDIR);
3702 
3703         pnp = prgetnode(dp, PR_OBJECT);
3704 
3705         if (prlock(dpnp, ZNO) != 0) {
3706                 prfreenode(pnp);
3707                 return (NULL);
3708         }
3709         p = dpnp->pr_common->prc_proc;
3710         if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3711                 prunlock(dpnp);
3712                 prfreenode(pnp);
3713                 return (NULL);
3714         }
3715 
3716         /*
3717          * We drop p_lock before grabbing the address space lock
3718          * in order to avoid a deadlock with the clock thread.
3719          * The process will not disappear and its address space
3720          * will not change because it is marked P_PR_LOCK.
3721          */
3722         mutex_exit(&p->p_lock);
3723         AS_LOCK_ENTER(as, RW_READER);
3724         if ((seg = AS_SEGFIRST(as)) == NULL) {
3725                 vp = NULL;
3726                 goto out;
3727         }
3728         if (strcmp(comp, "a.out") == 0) {
3729                 vp = p->p_exec;
3730                 goto out;
3731         }
3732         do {
3733                 /*
3734                  * Manufacture a filename for the "object" directory.
3735                  */
3736                 vattr.va_mask = AT_FSID|AT_NODEID;
3737                 if (seg->s_ops == &segvn_ops &&
3738                     SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3739                     vp != NULL && vp->v_type == VREG &&
3740                     VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3741                         char name[64];
3742 
3743                         if (vp == p->p_exec) /* "a.out" */
3744                                 continue;
3745                         pr_object_name(name, vp, &vattr);
3746                         if (strcmp(name, comp) == 0)
3747                                 goto out;
3748                 }
3749         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3750 
3751         vp = NULL;
3752 out:
3753         if (vp != NULL) {
3754                 VN_HOLD(vp);
3755         }
3756         AS_LOCK_EXIT(as);
3757         mutex_enter(&p->p_lock);
3758         prunlock(dpnp);
3759 
3760         if (vp == NULL)
3761                 prfreenode(pnp);
3762         else {
3763                 /*
3764                  * Fill in the prnode so future references will
3765                  * be able to find the underlying object's vnode.
3766                  * Don't link this prnode into the list of all
3767                  * prnodes for the process; this is a one-use node.
3768                  * Its use is entirely to catch and fail opens for writing.
3769                  */
3770                 pnp->pr_realvp = vp;
3771                 vp = PTOV(pnp);
3772         }
3773 
3774         return (vp);
3775 }
3776 
3777 /*
3778  * Find or construct an lwp vnode for the given lwpid.
3779  */
3780 static vnode_t *
3781 pr_lookup_lwpdir(vnode_t *dp, char *comp)
3782 {
3783         id_t tid;       /* same type as t->t_tid */
3784         int want_agent;
3785         prnode_t *dpnp = VTOP(dp);
3786         prnode_t *pnp;
3787         prcommon_t *pcp;
3788         vnode_t *vp;
3789         proc_t *p;
3790         kthread_t *t;
3791         lwpdir_t *ldp;
3792         lwpent_t *lep;
3793         int tslot;
3794         int c;
3795 
3796         ASSERT(dpnp->pr_type == PR_LWPDIR);
3797 
3798         tid = 0;
3799         if (strcmp(comp, "agent") == 0)
3800                 want_agent = 1;
3801         else {
3802                 want_agent = 0;
3803                 while ((c = *comp++) != '\0') {
3804                         id_t otid;
3805 
3806                         if (c < '0' || c > '9')
3807                                 return (NULL);
3808                         otid = tid;
3809                         tid = 10*tid + c - '0';
3810                         if (tid/10 != otid)     /* integer overflow */
3811                                 return (NULL);
3812                 }
3813         }
3814 
3815         pnp = prgetnode(dp, PR_LWPIDDIR);
3816 
3817         p = pr_p_lock(dpnp);
3818         mutex_exit(&pr_pidlock);
3819         if (p == NULL) {
3820                 prfreenode(pnp);
3821                 return (NULL);
3822         }
3823 
3824         if (want_agent) {
3825                 if ((t = p->p_agenttp) == NULL)
3826                         lep = NULL;
3827                 else {
3828                         tid = t->t_tid;
3829                         tslot = t->t_dslot;
3830                         lep = p->p_lwpdir[tslot].ld_entry;
3831                 }
3832         } else {
3833                 if ((ldp = lwp_hash_lookup(p, tid)) == NULL)
3834                         lep = NULL;
3835                 else {
3836                         tslot = (int)(ldp - p->p_lwpdir);
3837                         lep = ldp->ld_entry;
3838                 }
3839         }
3840 
3841         if (lep == NULL) {
3842                 prunlock(dpnp);
3843                 prfreenode(pnp);
3844                 return (NULL);
3845         }
3846 
3847         /*
3848          * If an lwp vnode already exists and it is not invalid
3849          * and it was created by the current process and it belongs
3850          * to the same /proc mount point as our parent vnode, then
3851          * just use it and discard the newly-allocated prnode.
3852          */
3853         for (vp = lep->le_trace; vp != NULL; vp = VTOP(vp)->pr_next) {
3854                 if (!(VTOP(vp)->pr_flags & PR_INVAL) &&
3855                     VTOP(vp)->pr_owner == curproc &&
3856                     vp->v_vfsp == dp->v_vfsp) {
3857                         VN_HOLD(vp);
3858                         prunlock(dpnp);
3859                         prfreenode(pnp);
3860                         return (vp);
3861                 }
3862         }
3863         pnp->pr_owner = curproc;
3864 
3865         /*
3866          * prgetnode() initialized most of the prnode.
3867          * Finish the job.
3868          */
3869         pcp = pnp->pr_common;        /* the newly-allocated prcommon struct */
3870         if ((vp = lep->le_trace) != NULL) {
3871                 /* discard the new prcommon and use the existing prcommon */
3872                 prfreecommon(pcp);
3873                 pcp = VTOP(vp)->pr_common;
3874                 mutex_enter(&pcp->prc_mutex);
3875                 ASSERT(pcp->prc_refcnt > 0);
3876                 pcp->prc_refcnt++;
3877                 mutex_exit(&pcp->prc_mutex);
3878                 pnp->pr_common = pcp;
3879         } else {
3880                 /* initialize the new prcommon struct */
3881                 pcp->prc_flags |= PRC_LWP;
3882                 if ((p->p_flag & SSYS) || p->p_as == &kas)
3883                         pcp->prc_flags |= PRC_SYS;
3884                 if ((t = lep->le_thread) == NULL)
3885                         pcp->prc_flags |= PRC_DESTROY;
3886                 pcp->prc_proc = p;
3887                 pcp->prc_datamodel = dpnp->pr_pcommon->prc_datamodel;
3888                 pcp->prc_pid = p->p_pid;
3889                 pcp->prc_slot = p->p_slot;
3890                 pcp->prc_thread = t;
3891                 pcp->prc_tid = tid;
3892                 pcp->prc_tslot = tslot;
3893         }
3894         pnp->pr_pcommon = dpnp->pr_pcommon;
3895         pnp->pr_parent = dp;
3896         VN_HOLD(dp);
3897         /*
3898          * Link in the old, invalid directory vnode so we
3899          * can later determine the last close of the file.
3900          */
3901         pnp->pr_next = lep->le_trace;
3902         lep->le_trace = vp = PTOV(pnp);
3903         prunlock(dpnp);
3904         return (vp);
3905 }
3906 
3907 static vnode_t *
3908 pr_lookup_lwpiddir(vnode_t *dp, char *comp)
3909 {
3910         prnode_t *dpnp = VTOP(dp);
3911         vnode_t *vp;
3912         prnode_t *pnp;
3913         proc_t *p;
3914         prdirent_t *dirp;
3915         int i;
3916         enum prnodetype type;
3917 
3918         ASSERT(dpnp->pr_type == PR_LWPIDDIR);
3919 
3920         for (i = 0; i < NLWPIDDIRFILES; i++) {
3921                 /* Skip "." and ".." */
3922                 dirp = &lwpiddir[i+2];
3923                 if (strcmp(comp, dirp->d_name) == 0)
3924                         break;
3925         }
3926 
3927         if (i >= NLWPIDDIRFILES)
3928                 return (NULL);
3929 
3930         type = (int)dirp->d_ino;
3931         pnp = prgetnode(dp, type);
3932 
3933         p = pr_p_lock(dpnp);
3934         mutex_exit(&pr_pidlock);
3935         if (p == NULL) {
3936                 prfreenode(pnp);
3937                 return (NULL);
3938         }
3939         if (dpnp->pr_common->prc_flags & PRC_DESTROY) {
3940                 /*
3941                  * Only the lwpsinfo file is present for zombie lwps.
3942                  * Nothing is present if the lwp has been reaped.
3943                  */
3944                 if (dpnp->pr_common->prc_tslot == -1 ||
3945                     type != PR_LWPSINFO) {
3946                         prunlock(dpnp);
3947                         prfreenode(pnp);
3948                         return (NULL);
3949                 }
3950         }
3951 
3952 #if defined(__sparc)
3953         /* the asrs file exists only for sparc v9 _LP64 processes */
3954         if (type == PR_ASRS && p->p_model != DATAMODEL_LP64) {
3955                 prunlock(dpnp);
3956                 prfreenode(pnp);
3957                 return (NULL);
3958         }
3959 #endif
3960 
3961         mutex_enter(&dpnp->pr_mutex);
3962 
3963         if ((vp = dpnp->pr_files[i]) != NULL &&
3964             !(VTOP(vp)->pr_flags & PR_INVAL)) {
3965                 VN_HOLD(vp);
3966                 mutex_exit(&dpnp->pr_mutex);
3967                 prunlock(dpnp);
3968                 prfreenode(pnp);
3969                 return (vp);
3970         }
3971 
3972         /*
3973          * prgetnode() initialized most of the prnode.
3974          * Finish the job.
3975          */
3976         pnp->pr_common = dpnp->pr_common;
3977         pnp->pr_pcommon = dpnp->pr_pcommon;
3978         pnp->pr_parent = dp;
3979         VN_HOLD(dp);
3980         pnp->pr_index = i;
3981 
3982         dpnp->pr_files[i] = vp = PTOV(pnp);
3983 
3984         /*
3985          * Link new vnode into list of all /proc vnodes for the process.
3986          */
3987         if (vp->v_type == VPROC) {
3988                 pnp->pr_next = p->p_plist;
3989                 p->p_plist = vp;
3990         }
3991         mutex_exit(&dpnp->pr_mutex);
3992         prunlock(dpnp);
3993         return (vp);
3994 }
3995 
3996 /*
3997  * Lookup one of the process's open files.
3998  */
3999 static vnode_t *
4000 pr_lookup_fddir(vnode_t *dp, char *comp)
4001 {
4002         prnode_t *dpnp = VTOP(dp);
4003         prnode_t *pnp;
4004         vnode_t *vp = NULL;
4005         proc_t *p;
4006         file_t *fp;
4007         uint_t fd;
4008         int c;
4009         uf_entry_t *ufp;
4010         uf_info_t *fip;
4011 
4012         ASSERT(dpnp->pr_type == PR_FDDIR);
4013 
4014         fd = 0;
4015         while ((c = *comp++) != '\0') {
4016                 int ofd;
4017                 if (c < '0' || c > '9')
4018                         return (NULL);
4019                 ofd = fd;
4020                 fd = 10*fd + c - '0';
4021                 if (fd/10 != ofd)       /* integer overflow */
4022                         return (NULL);
4023         }
4024 
4025         pnp = prgetnode(dp, PR_FD);
4026 
4027         if (prlock(dpnp, ZNO) != 0) {
4028                 prfreenode(pnp);
4029                 return (NULL);
4030         }
4031         p = dpnp->pr_common->prc_proc;
4032         if ((p->p_flag & SSYS) || p->p_as == &kas) {
4033                 prunlock(dpnp);
4034                 prfreenode(pnp);
4035                 return (NULL);
4036         }
4037 
4038         fip = P_FINFO(p);
4039         mutex_exit(&p->p_lock);
4040         mutex_enter(&fip->fi_lock);
4041         if (fd < fip->fi_nfiles) {
4042                 UF_ENTER(ufp, fip, fd);
4043                 if ((fp = ufp->uf_file) != NULL) {
4044                         pnp->pr_mode = 07111;
4045                         if (fp->f_flag & FREAD)
4046                                 pnp->pr_mode |= 0444;
4047                         if (fp->f_flag & FWRITE)
4048                                 pnp->pr_mode |= 0222;
4049                         vp = fp->f_vnode;
4050                         VN_HOLD(vp);
4051                 }
4052                 UF_EXIT(ufp);
4053         }
4054         mutex_exit(&fip->fi_lock);
4055         mutex_enter(&p->p_lock);
4056         prunlock(dpnp);
4057 
4058         if (vp == NULL)
4059                 prfreenode(pnp);
4060         else {
4061                 /*
4062                  * Fill in the prnode so future references will
4063                  * be able to find the underlying object's vnode.
4064                  * Don't link this prnode into the list of all
4065                  * prnodes for the process; this is a one-use node.
4066                  */
4067                 pnp->pr_realvp = vp;
4068                 pnp->pr_parent = dp;         /* needed for prlookup */
4069                 VN_HOLD(dp);
4070                 vp = PTOV(pnp);
4071                 if (pnp->pr_realvp->v_type == VDIR)
4072                         vp->v_type = VDIR;
4073         }
4074 
4075         return (vp);
4076 }
4077 
4078 static vnode_t *
4079 pr_lookup_pathdir(vnode_t *dp, char *comp)
4080 {
4081         prnode_t *dpnp = VTOP(dp);
4082         prnode_t *pnp;
4083         vnode_t *vp = NULL;
4084         proc_t *p;
4085         uint_t fd, flags = 0;
4086         int c;
4087         uf_entry_t *ufp;
4088         uf_info_t *fip;
4089         enum { NAME_FD, NAME_OBJECT, NAME_ROOT, NAME_CWD, NAME_UNKNOWN } type;
4090         char *tmp;
4091         int idx;
4092         struct seg *seg;
4093         struct as *as = NULL;
4094         vattr_t vattr;
4095 
4096         ASSERT(dpnp->pr_type == PR_PATHDIR);
4097 
4098         /*
4099          * First, check if this is a numeric entry, in which case we have a
4100          * file descriptor.
4101          */
4102         fd = 0;
4103         type = NAME_FD;
4104         tmp = comp;
4105         while ((c = *tmp++) != '\0') {
4106                 int ofd;
4107                 if (c < '0' || c > '9') {
4108                         type = NAME_UNKNOWN;
4109                         break;
4110                 }
4111                 ofd = fd;
4112                 fd = 10*fd + c - '0';
4113                 if (fd/10 != ofd) {     /* integer overflow */
4114                         type = NAME_UNKNOWN;
4115                         break;
4116                 }
4117         }
4118 
4119         /*
4120          * Next, see if it is one of the special values {root, cwd}.
4121          */
4122         if (type == NAME_UNKNOWN) {
4123                 if (strcmp(comp, "root") == 0)
4124                         type = NAME_ROOT;
4125                 else if (strcmp(comp, "cwd") == 0)
4126                         type = NAME_CWD;
4127         }
4128 
4129         /*
4130          * Grab the necessary data from the process
4131          */
4132         if (prlock(dpnp, ZNO) != 0)
4133                 return (NULL);
4134         p = dpnp->pr_common->prc_proc;
4135 
4136         fip = P_FINFO(p);
4137 
4138         switch (type) {
4139         case NAME_ROOT:
4140                 if ((vp = PTOU(p)->u_rdir) == NULL)
4141                         vp = p->p_zone->zone_rootvp;
4142                 VN_HOLD(vp);
4143                 break;
4144         case NAME_CWD:
4145                 vp = PTOU(p)->u_cdir;
4146                 VN_HOLD(vp);
4147                 break;
4148         default:
4149                 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
4150                         prunlock(dpnp);
4151                         return (NULL);
4152                 }
4153         }
4154         mutex_exit(&p->p_lock);
4155 
4156         /*
4157          * Determine if this is an object entry
4158          */
4159         if (type == NAME_UNKNOWN) {
4160                 /*
4161                  * Start with the inode index immediately after the number of
4162                  * files.
4163                  */
4164                 mutex_enter(&fip->fi_lock);
4165                 idx = fip->fi_nfiles + 4;
4166                 mutex_exit(&fip->fi_lock);
4167 
4168                 if (strcmp(comp, "a.out") == 0) {
4169                         if (p->p_execdir != NULL) {
4170                                 vp = p->p_execdir;
4171                                 VN_HOLD(vp);
4172                                 type = NAME_OBJECT;
4173                                 flags |= PR_AOUT;
4174                         } else {
4175                                 vp = p->p_exec;
4176                                 VN_HOLD(vp);
4177                                 type = NAME_OBJECT;
4178                         }
4179                 } else {
4180                         AS_LOCK_ENTER(as, RW_READER);
4181                         if ((seg = AS_SEGFIRST(as)) != NULL) {
4182                                 do {
4183                                         /*
4184                                          * Manufacture a filename for the
4185                                          * "object" directory.
4186                                          */
4187                                         vattr.va_mask = AT_FSID|AT_NODEID;
4188                                         if (seg->s_ops == &segvn_ops &&
4189                                             SEGOP_GETVP(seg, seg->s_base, &vp)
4190                                             == 0 &&
4191                                             vp != NULL && vp->v_type == VREG &&
4192                                             VOP_GETATTR(vp, &vattr, 0, CRED(),
4193                                             NULL) == 0) {
4194                                                 char name[64];
4195 
4196                                                 if (vp == p->p_exec)
4197                                                         continue;
4198                                                 idx++;
4199                                                 pr_object_name(name, vp,
4200                                                     &vattr);
4201                                                 if (strcmp(name, comp) == 0)
4202                                                         break;
4203                                         }
4204                                 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4205                         }
4206 
4207                         if (seg == NULL) {
4208                                 vp = NULL;
4209                         } else {
4210                                 VN_HOLD(vp);
4211                                 type = NAME_OBJECT;
4212                         }
4213 
4214                         AS_LOCK_EXIT(as);
4215                 }
4216         }
4217 
4218 
4219         switch (type) {
4220         case NAME_FD:
4221                 mutex_enter(&fip->fi_lock);
4222                 if (fd < fip->fi_nfiles) {
4223                         UF_ENTER(ufp, fip, fd);
4224                         if (ufp->uf_file != NULL) {
4225                                 vp = ufp->uf_file->f_vnode;
4226                                 VN_HOLD(vp);
4227                         }
4228                         UF_EXIT(ufp);
4229                 }
4230                 mutex_exit(&fip->fi_lock);
4231                 idx = fd + 4;
4232                 break;
4233         case NAME_ROOT:
4234                 idx = 2;
4235                 break;
4236         case NAME_CWD:
4237                 idx = 3;
4238                 break;
4239         case NAME_OBJECT:
4240         case NAME_UNKNOWN:
4241                 /* Nothing to do */
4242                 break;
4243         }
4244 
4245         mutex_enter(&p->p_lock);
4246         prunlock(dpnp);
4247 
4248         if (vp != NULL) {
4249                 pnp = prgetnode(dp, PR_PATH);
4250 
4251                 pnp->pr_flags |= flags;
4252                 pnp->pr_common = dpnp->pr_common;
4253                 pnp->pr_pcommon = dpnp->pr_pcommon;
4254                 pnp->pr_realvp = vp;
4255                 pnp->pr_parent = dp;         /* needed for prlookup */
4256                 pnp->pr_ino = pmkino(idx, dpnp->pr_common->prc_slot, PR_PATH);
4257                 VN_HOLD(dp);
4258                 vp = PTOV(pnp);
4259                 vp->v_type = VLNK;
4260         }
4261 
4262         return (vp);
4263 }
4264 
4265 /*
4266  * Look up one of the process's active templates.
4267  */
4268 static vnode_t *
4269 pr_lookup_tmpldir(vnode_t *dp, char *comp)
4270 {
4271         prnode_t *dpnp = VTOP(dp);
4272         prnode_t *pnp;
4273         vnode_t *vp = NULL;
4274         proc_t *p;
4275         int i;
4276 
4277         ASSERT(dpnp->pr_type == PR_TMPLDIR);
4278 
4279         for (i = 0; i < ct_ntypes; i++)
4280                 if (strcmp(comp, ct_types[i]->ct_type_name) == 0)
4281                         break;
4282         if (i == ct_ntypes)
4283                 return (NULL);
4284 
4285         pnp = prgetnode(dp, PR_TMPL);
4286 
4287         if (prlock(dpnp, ZNO) != 0) {
4288                 prfreenode(pnp);
4289                 return (NULL);
4290         }
4291         p = dpnp->pr_common->prc_proc;
4292         if ((p->p_flag & SSYS) || p->p_as == &kas ||
4293             (dpnp->pr_common->prc_flags & (PRC_DESTROY | PRC_LWP)) != PRC_LWP) {
4294                 prunlock(dpnp);
4295                 prfreenode(pnp);
4296                 return (NULL);
4297         }
4298         if (ttolwp(dpnp->pr_common->prc_thread)->lwp_ct_active[i] != NULL) {
4299                 pnp->pr_common = dpnp->pr_common;
4300                 pnp->pr_pcommon = dpnp->pr_pcommon;
4301                 pnp->pr_parent = dp;
4302                 pnp->pr_cttype = i;
4303                 VN_HOLD(dp);
4304                 vp = PTOV(pnp);
4305         } else {
4306                 prfreenode(pnp);
4307         }
4308         prunlock(dpnp);
4309 
4310         return (vp);
4311 }
4312 
4313 /*
4314  * Look up one of the contracts owned by the process.
4315  */
4316 static vnode_t *
4317 pr_lookup_ctdir(vnode_t *dp, char *comp)
4318 {
4319         prnode_t *dpnp = VTOP(dp);
4320         prnode_t *pnp;
4321         vnode_t *vp = NULL;
4322         proc_t *p;
4323         id_t id = 0;
4324         contract_t *ct;
4325         int c;
4326 
4327         ASSERT(dpnp->pr_type == PR_CTDIR);
4328 
4329         while ((c = *comp++) != '\0') {
4330                 id_t oid;
4331                 if (c < '0' || c > '9')
4332                         return (NULL);
4333                 oid = id;
4334                 id = 10 * id + c - '0';
4335                 if (id / 10 != oid)     /* integer overflow */
4336                         return (NULL);
4337         }
4338 
4339         /*
4340          * Search all contracts; we'll filter below.
4341          */
4342         ct = contract_ptr(id, GLOBAL_ZONEUNIQID);
4343         if (ct == NULL)
4344                 return (NULL);
4345 
4346         pnp = prgetnode(dp, PR_CT);
4347 
4348         if (prlock(dpnp, ZNO) != 0) {
4349                 prfreenode(pnp);
4350                 contract_rele(ct);
4351                 return (NULL);
4352         }
4353         p = dpnp->pr_common->prc_proc;
4354         /*
4355          * We only allow lookups of contracts owned by this process, or,
4356          * if we are zsched and this is a zone's procfs, contracts on
4357          * stuff in the zone which are held by processes or contracts
4358          * outside the zone.  (see logic in contract_status_common)
4359          */
4360         if ((ct->ct_owner != p) &&
4361             !(p == VTOZONE(dp)->zone_zsched && ct->ct_state < CTS_ORPHAN &&
4362             VTOZONE(dp)->zone_uniqid == contract_getzuniqid(ct) &&
4363             VTOZONE(dp)->zone_uniqid != GLOBAL_ZONEUNIQID &&
4364             ct->ct_czuniqid == GLOBAL_ZONEUNIQID)) {
4365                 prunlock(dpnp);
4366                 prfreenode(pnp);
4367                 contract_rele(ct);
4368                 return (NULL);
4369         }
4370         pnp->pr_common = dpnp->pr_common;
4371         pnp->pr_pcommon = dpnp->pr_pcommon;
4372         pnp->pr_contract = ct;
4373         pnp->pr_parent = dp;
4374         pnp->pr_ino = pmkino(id, pnp->pr_common->prc_slot, PR_CT);
4375         VN_HOLD(dp);
4376         prunlock(dpnp);
4377         vp = PTOV(pnp);
4378 
4379         return (vp);
4380 }
4381 
4382 /*
4383  * Construct an lwp vnode for the old /proc interface.
4384  * We stand on our head to make the /proc plumbing correct.
4385  */
4386 vnode_t *
4387 prlwpnode(prnode_t *pnp, uint_t tid)
4388 {
4389         char comp[12];
4390         vnode_t *dp;
4391         vnode_t *vp;
4392         prcommon_t *pcp;
4393         proc_t *p;
4394 
4395         /*
4396          * Lookup the /proc/<pid>/lwp/<lwpid> directory vnode.
4397          */
4398         if (pnp->pr_type == PR_PIDFILE) {
4399                 dp = pnp->pr_parent;         /* /proc/<pid> */
4400                 VN_HOLD(dp);
4401                 vp = pr_lookup_piddir(dp, "lwp");
4402                 VN_RELE(dp);
4403                 if ((dp = vp) == NULL)          /* /proc/<pid>/lwp */
4404                         return (NULL);
4405         } else if (pnp->pr_type == PR_LWPIDFILE) {
4406                 dp = pnp->pr_parent;         /* /proc/<pid>/lwp/<lwpid> */
4407                 dp = VTOP(dp)->pr_parent;    /* /proc/<pid>/lwp */
4408                 VN_HOLD(dp);
4409         } else {
4410                 return (NULL);
4411         }
4412 
4413         (void) pr_u32tos(tid, comp, sizeof (comp));
4414         vp = pr_lookup_lwpdir(dp, comp);
4415         VN_RELE(dp);
4416         if ((dp = vp) == NULL)
4417                 return (NULL);
4418 
4419         pnp = prgetnode(dp, PR_LWPIDFILE);
4420         vp = PTOV(pnp);
4421 
4422         /*
4423          * prgetnode() initialized most of the prnode.
4424          * Finish the job.
4425          */
4426         pcp = VTOP(dp)->pr_common;
4427         pnp->pr_ino = ptoi(pcp->prc_pid);
4428         pnp->pr_common = pcp;
4429         pnp->pr_pcommon = VTOP(dp)->pr_pcommon;
4430         pnp->pr_parent = dp;
4431         /*
4432          * Link new vnode into list of all /proc vnodes for the process.
4433          */
4434         p = pr_p_lock(pnp);
4435         mutex_exit(&pr_pidlock);
4436         if (p == NULL) {
4437                 VN_RELE(dp);
4438                 prfreenode(pnp);
4439                 vp = NULL;
4440         } else if (pcp->prc_thread == NULL) {
4441                 prunlock(pnp);
4442                 VN_RELE(dp);
4443                 prfreenode(pnp);
4444                 vp = NULL;
4445         } else {
4446                 pnp->pr_next = p->p_plist;
4447                 p->p_plist = vp;
4448                 prunlock(pnp);
4449         }
4450 
4451         return (vp);
4452 }
4453 
4454 #if defined(DEBUG)
4455 
4456 static  uint32_t nprnode;
4457 static  uint32_t nprcommon;
4458 
4459 #define INCREMENT(x)    atomic_inc_32(&x);
4460 #define DECREMENT(x)    atomic_dec_32(&x);
4461 
4462 #else
4463 
4464 #define INCREMENT(x)
4465 #define DECREMENT(x)
4466 
4467 #endif  /* DEBUG */
4468 
4469 /*
4470  * New /proc vnode required; allocate it and fill in most of the fields.
4471  */
4472 prnode_t *
4473 prgetnode(vnode_t *dp, prnodetype_t type)
4474 {
4475         prnode_t *pnp;
4476         prcommon_t *pcp;
4477         vnode_t *vp;
4478         ulong_t nfiles;
4479 
4480         INCREMENT(nprnode);
4481         pnp = kmem_zalloc(sizeof (prnode_t), KM_SLEEP);
4482 
4483         mutex_init(&pnp->pr_mutex, NULL, MUTEX_DEFAULT, NULL);
4484         pnp->pr_type = type;
4485 
4486         pnp->pr_vnode = vn_alloc(KM_SLEEP);
4487 
4488         vp = PTOV(pnp);
4489         vp->v_flag = VNOCACHE|VNOMAP|VNOSWAP|VNOMOUNT;
4490         vn_setops(vp, prvnodeops);
4491         vp->v_vfsp = dp->v_vfsp;
4492         vp->v_type = VPROC;
4493         vp->v_data = (caddr_t)pnp;
4494 
4495         switch (type) {
4496         case PR_PIDDIR:
4497         case PR_LWPIDDIR:
4498                 /*
4499                  * We need a prcommon and a files array for each of these.
4500                  */
4501                 INCREMENT(nprcommon);
4502 
4503                 pcp = kmem_zalloc(sizeof (prcommon_t), KM_SLEEP);
4504                 pcp->prc_refcnt = 1;
4505                 pnp->pr_common = pcp;
4506                 mutex_init(&pcp->prc_mutex, NULL, MUTEX_DEFAULT, NULL);
4507                 cv_init(&pcp->prc_wait, NULL, CV_DEFAULT, NULL);
4508 
4509                 nfiles = (type == PR_PIDDIR)? NPIDDIRFILES : NLWPIDDIRFILES;
4510                 pnp->pr_files =
4511                     kmem_zalloc(nfiles * sizeof (vnode_t *), KM_SLEEP);
4512 
4513                 vp->v_type = VDIR;
4514                 /*
4515                  * Mode should be read-search by all, but we cannot so long
4516                  * as we must support compatibility mode with old /proc.
4517                  * Make /proc/<pid> be read by owner only, search by all.
4518                  * Make /proc/<pid>/lwp/<lwpid> read-search by all.  Also,
4519                  * set VDIROPEN on /proc/<pid> so it can be opened for writing.
4520                  */
4521                 if (type == PR_PIDDIR) {
4522                         /* kludge for old /proc interface */
4523                         prnode_t *xpnp = prgetnode(dp, PR_PIDFILE);
4524                         pnp->pr_pidfile = PTOV(xpnp);
4525                         pnp->pr_mode = 0511;
4526                         vp->v_flag |= VDIROPEN;
4527                 } else {
4528                         pnp->pr_mode = 0555;
4529                 }
4530 
4531                 break;
4532 
4533         case PR_CURDIR:
4534         case PR_ROOTDIR:
4535         case PR_FDDIR:
4536         case PR_OBJECTDIR:
4537         case PR_PATHDIR:
4538         case PR_CTDIR:
4539         case PR_TMPLDIR:
4540                 vp->v_type = VDIR;
4541                 pnp->pr_mode = 0500; /* read-search by owner only */
4542                 break;
4543 
4544         case PR_CT:
4545                 vp->v_type = VLNK;
4546                 pnp->pr_mode = 0500; /* read-search by owner only */
4547                 break;
4548 
4549         case PR_PATH:
4550         case PR_SELF:
4551                 vp->v_type = VLNK;
4552                 pnp->pr_mode = 0777;
4553                 break;
4554 
4555         case PR_LWPDIR:
4556                 vp->v_type = VDIR;
4557                 pnp->pr_mode = 0555; /* read-search by all */
4558                 break;
4559 
4560         case PR_AS:
4561         case PR_TMPL:
4562                 pnp->pr_mode = 0600; /* read-write by owner only */
4563                 break;
4564 
4565         case PR_CTL:
4566         case PR_LWPCTL:
4567                 pnp->pr_mode = 0200; /* write-only by owner only */
4568                 break;
4569 
4570         case PR_PIDFILE:
4571         case PR_LWPIDFILE:
4572                 pnp->pr_mode = 0600; /* read-write by owner only */
4573                 break;
4574 
4575         case PR_PSINFO:
4576         case PR_LPSINFO:
4577         case PR_LWPSINFO:
4578         case PR_USAGE:
4579         case PR_LUSAGE:
4580         case PR_LWPUSAGE:
4581                 pnp->pr_mode = 0444; /* read-only by all */
4582                 break;
4583 
4584         default:
4585                 pnp->pr_mode = 0400; /* read-only by owner only */
4586                 break;
4587         }
4588         vn_exists(vp);
4589         return (pnp);
4590 }
4591 
4592 /*
4593  * Free the storage obtained from prgetnode().
4594  */
4595 void
4596 prfreenode(prnode_t *pnp)
4597 {
4598         vnode_t *vp;
4599         ulong_t nfiles;
4600 
4601         vn_invalid(PTOV(pnp));
4602         vn_free(PTOV(pnp));
4603         mutex_destroy(&pnp->pr_mutex);
4604 
4605         switch (pnp->pr_type) {
4606         case PR_PIDDIR:
4607                 /* kludge for old /proc interface */
4608                 if (pnp->pr_pidfile != NULL) {
4609                         prfreenode(VTOP(pnp->pr_pidfile));
4610                         pnp->pr_pidfile = NULL;
4611                 }
4612                 /* FALLTHROUGH */
4613         case PR_LWPIDDIR:
4614                 /*
4615                  * We allocated a prcommon and a files array for each of these.
4616                  */
4617                 prfreecommon(pnp->pr_common);
4618                 nfiles = (pnp->pr_type == PR_PIDDIR)?
4619                     NPIDDIRFILES : NLWPIDDIRFILES;
4620                 kmem_free(pnp->pr_files, nfiles * sizeof (vnode_t *));
4621                 break;
4622         default:
4623                 break;
4624         }
4625         /*
4626          * If there is an underlying vnode, be sure
4627          * to release it after freeing the prnode.
4628          */
4629         vp = pnp->pr_realvp;
4630         kmem_free(pnp, sizeof (*pnp));
4631         DECREMENT(nprnode);
4632         if (vp != NULL) {
4633                 VN_RELE(vp);
4634         }
4635 }
4636 
4637 /*
4638  * Free a prcommon structure, if the reference count reaches zero.
4639  */
4640 static void
4641 prfreecommon(prcommon_t *pcp)
4642 {
4643         mutex_enter(&pcp->prc_mutex);
4644         ASSERT(pcp->prc_refcnt > 0);
4645         if (--pcp->prc_refcnt != 0)
4646                 mutex_exit(&pcp->prc_mutex);
4647         else {
4648                 mutex_exit(&pcp->prc_mutex);
4649                 ASSERT(pcp->prc_pollhead.ph_list == NULL);
4650                 ASSERT(pcp->prc_refcnt == 0);
4651                 ASSERT(pcp->prc_selfopens == 0 && pcp->prc_writers == 0);
4652                 mutex_destroy(&pcp->prc_mutex);
4653                 cv_destroy(&pcp->prc_wait);
4654                 kmem_free(pcp, sizeof (prcommon_t));
4655                 DECREMENT(nprcommon);
4656         }
4657 }
4658 
4659 /*
4660  * Array of readdir functions, indexed by /proc file type.
4661  */
4662 static int pr_readdir_notdir(), pr_readdir_procdir(), pr_readdir_piddir(),
4663         pr_readdir_objectdir(), pr_readdir_lwpdir(), pr_readdir_lwpiddir(),
4664         pr_readdir_fddir(), pr_readdir_pathdir(), pr_readdir_tmpldir(),
4665         pr_readdir_ctdir();
4666 
4667 static int (*pr_readdir_function[PR_NFILES])() = {
4668         pr_readdir_procdir,     /* /proc                                */
4669         pr_readdir_notdir,      /* /proc/self                           */
4670         pr_readdir_piddir,      /* /proc/<pid>                            */
4671         pr_readdir_notdir,      /* /proc/<pid>/as                 */
4672         pr_readdir_notdir,      /* /proc/<pid>/ctl                        */
4673         pr_readdir_notdir,      /* /proc/<pid>/status                     */
4674         pr_readdir_notdir,      /* /proc/<pid>/lstatus                    */
4675         pr_readdir_notdir,      /* /proc/<pid>/psinfo                     */
4676         pr_readdir_notdir,      /* /proc/<pid>/lpsinfo                    */
4677         pr_readdir_notdir,      /* /proc/<pid>/map                        */
4678         pr_readdir_notdir,      /* /proc/<pid>/rmap                       */
4679         pr_readdir_notdir,      /* /proc/<pid>/xmap                       */
4680         pr_readdir_notdir,      /* /proc/<pid>/cred                       */
4681         pr_readdir_notdir,      /* /proc/<pid>/sigact                     */
4682         pr_readdir_notdir,      /* /proc/<pid>/auxv                       */
4683 #if defined(__x86)
4684         pr_readdir_notdir,      /* /proc/<pid>/ldt                        */
4685 #endif
4686         pr_readdir_notdir,      /* /proc/<pid>/usage                      */
4687         pr_readdir_notdir,      /* /proc/<pid>/lusage                     */
4688         pr_readdir_notdir,      /* /proc/<pid>/pagedata                   */
4689         pr_readdir_notdir,      /* /proc/<pid>/watch                      */
4690         pr_readdir_notdir,      /* /proc/<pid>/cwd                        */
4691         pr_readdir_notdir,      /* /proc/<pid>/root                       */
4692         pr_readdir_fddir,       /* /proc/<pid>/fd                 */
4693         pr_readdir_notdir,      /* /proc/<pid>/fd/nn                      */
4694         pr_readdir_objectdir,   /* /proc/<pid>/object                     */
4695         pr_readdir_notdir,      /* /proc/<pid>/object/xxx         */
4696         pr_readdir_lwpdir,      /* /proc/<pid>/lwp                        */
4697         pr_readdir_lwpiddir,    /* /proc/<pid>/lwp/<lwpid>          */
4698         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
4699         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
4700         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
4701         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/lwpusage */
4702         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/xregs    */
4703         pr_readdir_tmpldir,     /* /proc/<pid>/lwp/<lwpid>/templates        */
4704         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
4705         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/spymaster        */
4706 #if defined(__sparc)
4707         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/gwindows */
4708         pr_readdir_notdir,      /* /proc/<pid>/lwp/<lwpid>/asrs             */
4709 #endif
4710         pr_readdir_notdir,      /* /proc/<pid>/priv                       */
4711         pr_readdir_pathdir,     /* /proc/<pid>/path                       */
4712         pr_readdir_notdir,      /* /proc/<pid>/path/xxx                   */
4713         pr_readdir_ctdir,       /* /proc/<pid>/contracts          */
4714         pr_readdir_notdir,      /* /proc/<pid>/contracts/<ctid>             */
4715         pr_readdir_notdir,      /* /proc/<pid>/secflags                   */
4716         pr_readdir_notdir,      /* old process file                     */
4717         pr_readdir_notdir,      /* old lwp file                         */
4718         pr_readdir_notdir,      /* old pagedata file                    */
4719 };
4720 
4721 /* ARGSUSED */
4722 static int
4723 prreaddir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
4724     caller_context_t *ct, int flags)
4725 {
4726         prnode_t *pnp = VTOP(vp);
4727 
4728         ASSERT(pnp->pr_type < PR_NFILES);
4729 
4730         /* XXX - Do we need to pass ct and flags? */
4731         return (pr_readdir_function[pnp->pr_type](pnp, uiop, eofp));
4732 }
4733 
4734 /* ARGSUSED */
4735 static int
4736 pr_readdir_notdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4737 {
4738         return (ENOTDIR);
4739 }
4740 
4741 /* ARGSUSED */
4742 static int
4743 pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4744 {
4745         zoneid_t zoneid;
4746         gfs_readdir_state_t gstate;
4747         int error, eof = 0;
4748         offset_t n;
4749 
4750         ASSERT(pnp->pr_type == PR_PROCDIR);
4751 
4752         zoneid = VTOZONE(PTOV(pnp))->zone_id;
4753 
4754         if ((error = gfs_readdir_init(&gstate, PNSIZ, PRSDSIZE, uiop,
4755             PRROOTINO, PRROOTINO, 0)) != 0)
4756                 return (error);
4757 
4758         /*
4759          * Loop until user's request is satisfied or until all processes
4760          * have been examined.
4761          */
4762         while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
4763                 uint_t pid;
4764                 int pslot;
4765                 proc_t *p;
4766 
4767                 /*
4768                  * Find next entry.  Skip processes not visible where
4769                  * this /proc was mounted.
4770                  */
4771                 mutex_enter(&pidlock);
4772                 while (n < v.v_proc &&
4773                     ((p = pid_entry(n)) == NULL || p->p_stat == SIDL ||
4774                     (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) ||
4775                     secpolicy_basic_procinfo(CRED(), p, curproc) != 0))
4776                         n++;
4777 
4778                 /*
4779                  * Stop when entire proc table has been examined.
4780                  */
4781                 if (n >= v.v_proc) {
4782                         mutex_exit(&pidlock);
4783                         eof = 1;
4784                         break;
4785                 }
4786 
4787                 ASSERT(p->p_stat != 0);
4788                 pid = p->p_pid;
4789                 pslot = p->p_slot;
4790                 mutex_exit(&pidlock);
4791                 error = gfs_readdir_emitn(&gstate, uiop, n,
4792                     pmkino(0, pslot, PR_PIDDIR), pid);
4793                 if (error)
4794                         break;
4795         }
4796 
4797         return (gfs_readdir_fini(&gstate, error, eofp, eof));
4798 }
4799 
4800 /* ARGSUSED */
4801 static int
4802 pr_readdir_piddir(prnode_t *pnp, uio_t *uiop, int *eofp)
4803 {
4804         int zombie = ((pnp->pr_pcommon->prc_flags & PRC_DESTROY) != 0);
4805         prdirent_t dirent;
4806         prdirent_t *dirp;
4807         offset_t off;
4808         int error;
4809 
4810         ASSERT(pnp->pr_type == PR_PIDDIR);
4811 
4812         if (uiop->uio_offset < 0 ||
4813             uiop->uio_offset % sizeof (prdirent_t) != 0 ||
4814             uiop->uio_resid < sizeof (prdirent_t))
4815                 return (EINVAL);
4816         if (pnp->pr_pcommon->prc_proc == NULL)
4817                 return (ENOENT);
4818         if (uiop->uio_offset >= sizeof (piddir))
4819                 goto out;
4820 
4821         /*
4822          * Loop until user's request is satisfied, omitting some
4823          * files along the way if the process is a zombie.
4824          */
4825         for (dirp = &piddir[uiop->uio_offset / sizeof (prdirent_t)];
4826             uiop->uio_resid >= sizeof (prdirent_t) &&
4827             dirp < &piddir[NPIDDIRFILES+2];
4828             uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
4829                 off = uiop->uio_offset;
4830                 if (zombie) {
4831                         switch (dirp->d_ino) {
4832                         case PR_PIDDIR:
4833                         case PR_PROCDIR:
4834                         case PR_PSINFO:
4835                         case PR_USAGE:
4836                                 break;
4837                         default:
4838                                 continue;
4839                         }
4840                 }
4841                 bcopy(dirp, &dirent, sizeof (prdirent_t));
4842                 if (dirent.d_ino == PR_PROCDIR)
4843                         dirent.d_ino = PRROOTINO;
4844                 else
4845                         dirent.d_ino = pmkino(0, pnp->pr_pcommon->prc_slot,
4846                             dirent.d_ino);
4847                 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
4848                     UIO_READ, uiop)) != 0)
4849                         return (error);
4850         }
4851 out:
4852         if (eofp)
4853                 *eofp = (uiop->uio_offset >= sizeof (piddir));
4854         return (0);
4855 }
4856 
4857 static void
4858 rebuild_objdir(struct as *as)
4859 {
4860         struct seg *seg;
4861         vnode_t *vp;
4862         vattr_t vattr;
4863         vnode_t **dir;
4864         ulong_t nalloc;
4865         ulong_t nentries;
4866         int i, j;
4867         ulong_t nold, nnew;
4868 
4869         ASSERT(AS_WRITE_HELD(as));
4870 
4871         if (as->a_updatedir == 0 && as->a_objectdir != NULL)
4872                 return;
4873         as->a_updatedir = 0;
4874 
4875         if ((nalloc = avl_numnodes(&as->a_segtree)) == 0 ||
4876             (seg = AS_SEGFIRST(as)) == NULL)    /* can't happen? */
4877                 return;
4878 
4879         /*
4880          * Allocate space for the new object directory.
4881          * (This is usually about two times too many entries.)
4882          */
4883         nalloc = (nalloc + 0xf) & ~0xf;             /* multiple of 16 */
4884         dir = kmem_zalloc(nalloc * sizeof (vnode_t *), KM_SLEEP);
4885 
4886         /* fill in the new directory with desired entries */
4887         nentries = 0;
4888         do {
4889                 vattr.va_mask = AT_FSID|AT_NODEID;
4890                 if (seg->s_ops == &segvn_ops &&
4891                     SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
4892                     vp != NULL && vp->v_type == VREG &&
4893                     VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
4894                         for (i = 0; i < nentries; i++)
4895                                 if (vp == dir[i])
4896                                         break;
4897                         if (i == nentries) {
4898                                 ASSERT(nentries < nalloc);
4899                                 dir[nentries++] = vp;
4900                         }
4901                 }
4902         } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4903 
4904         if (as->a_objectdir == NULL) {       /* first time */
4905                 as->a_objectdir = dir;
4906                 as->a_sizedir = nalloc;
4907                 return;
4908         }
4909 
4910         /*
4911          * Null out all of the defunct entries in the old directory.
4912          */
4913         nold = 0;
4914         nnew = nentries;
4915         for (i = 0; i < as->a_sizedir; i++) {
4916                 if ((vp = as->a_objectdir[i]) != NULL) {
4917                         for (j = 0; j < nentries; j++) {
4918                                 if (vp == dir[j]) {
4919                                         dir[j] = NULL;
4920                                         nnew--;
4921                                         break;
4922                                 }
4923                         }
4924                         if (j == nentries)
4925                                 as->a_objectdir[i] = NULL;
4926                         else
4927                                 nold++;
4928                 }
4929         }
4930 
4931         if (nold + nnew > as->a_sizedir) {
4932                 /*
4933                  * Reallocate the old directory to have enough
4934                  * space for the old and new entries combined.
4935                  * Round up to the next multiple of 16.
4936                  */
4937                 ulong_t newsize = (nold + nnew + 0xf) & ~0xf;
4938                 vnode_t **newdir = kmem_zalloc(newsize * sizeof (vnode_t *),
4939                     KM_SLEEP);
4940                 bcopy(as->a_objectdir, newdir,
4941                     as->a_sizedir * sizeof (vnode_t *));
4942                 kmem_free(as->a_objectdir, as->a_sizedir * sizeof (vnode_t *));
4943                 as->a_objectdir = newdir;
4944                 as->a_sizedir = newsize;
4945         }
4946 
4947         /*
4948          * Move all new entries to the old directory and
4949          * deallocate the space used by the new directory.
4950          */
4951         if (nnew) {
4952                 for (i = 0, j = 0; i < nentries; i++) {
4953                         if ((vp = dir[i]) == NULL)
4954                                 continue;
4955                         for (; j < as->a_sizedir; j++) {
4956                                 if (as->a_objectdir[j] != NULL)
4957                                         continue;
4958                                 as->a_objectdir[j++] = vp;
4959                                 break;
4960                         }
4961                 }
4962         }
4963         kmem_free(dir, nalloc * sizeof (vnode_t *));
4964 }
4965 
4966 /*
4967  * Return the vnode from a slot in the process's object directory.
4968  * The caller must have locked the process's address space.
4969  * The only caller is below, in pr_readdir_objectdir().
4970  */
4971 static vnode_t *
4972 obj_entry(struct as *as, int slot)
4973 {
4974         ASSERT(AS_LOCK_HELD(as));
4975         if (as->a_objectdir == NULL)
4976                 return (NULL);
4977         ASSERT(slot < as->a_sizedir);
4978         return (as->a_objectdir[slot]);
4979 }
4980 
4981 /* ARGSUSED */
4982 static int
4983 pr_readdir_objectdir(prnode_t *pnp, uio_t *uiop, int *eofp)
4984 {
4985         gfs_readdir_state_t gstate;
4986         int error, eof = 0;
4987         offset_t n;
4988         int pslot;
4989         size_t objdirsize;
4990         proc_t *p;
4991         struct as *as;
4992         vnode_t *vp;
4993 
4994         ASSERT(pnp->pr_type == PR_OBJECTDIR);
4995 
4996         if ((error = prlock(pnp, ZNO)) != 0)
4997                 return (error);
4998         p = pnp->pr_common->prc_proc;
4999         pslot = p->p_slot;
5000 
5001         /*
5002          * We drop p_lock before grabbing the address space lock
5003          * in order to avoid a deadlock with the clock thread.
5004          * The process will not disappear and its address space
5005          * will not change because it is marked P_PR_LOCK.
5006          */
5007         mutex_exit(&p->p_lock);
5008 
5009         if ((error = gfs_readdir_init(&gstate, 64, PRSDSIZE, uiop,
5010             pmkino(0, pslot, PR_PIDDIR),
5011             pmkino(0, pslot, PR_OBJECTDIR), 0)) != 0) {
5012                 mutex_enter(&p->p_lock);
5013                 prunlock(pnp);
5014                 return (error);
5015         }
5016 
5017         if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5018                 as = NULL;
5019                 objdirsize = 0;
5020         }
5021 
5022         /*
5023          * Loop until user's request is satisfied or until
5024          * all mapped objects have been examined. Cannot hold
5025          * the address space lock for the following call as
5026          * gfs_readdir_pred() utimately causes a call to uiomove().
5027          */
5028         while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5029                 vattr_t vattr;
5030                 char str[64];
5031 
5032                 /*
5033                  * Set the correct size of the directory just
5034                  * in case the process has changed it's address
5035                  * space via mmap/munmap calls.
5036                  */
5037                 if (as != NULL) {
5038                         AS_LOCK_ENTER(as, RW_WRITER);
5039                         if (as->a_updatedir)
5040                                 rebuild_objdir(as);
5041                         objdirsize = as->a_sizedir;
5042                 }
5043 
5044                 /*
5045                  * Find next object.
5046                  */
5047                 vattr.va_mask = AT_FSID | AT_NODEID;
5048                 while (n < objdirsize && (((vp = obj_entry(as, n)) == NULL) ||
5049                     (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL)
5050                     != 0))) {
5051                         vattr.va_mask = AT_FSID | AT_NODEID;
5052                         n++;
5053                 }
5054 
5055                 if (as != NULL)
5056                         AS_LOCK_EXIT(as);
5057 
5058                 /*
5059                  * Stop when all objects have been reported.
5060                  */
5061                 if (n >= objdirsize) {
5062                         eof = 1;
5063                         break;
5064                 }
5065 
5066                 if (vp == p->p_exec)
5067                         (void) strcpy(str, "a.out");
5068                 else
5069                         pr_object_name(str, vp, &vattr);
5070 
5071                 error = gfs_readdir_emit(&gstate, uiop, n, vattr.va_nodeid,
5072                     str, 0);
5073 
5074                 if (error)
5075                         break;
5076         }
5077 
5078         mutex_enter(&p->p_lock);
5079         prunlock(pnp);
5080 
5081         return (gfs_readdir_fini(&gstate, error, eofp, eof));
5082 }
5083 
5084 /* ARGSUSED */
5085 static int
5086 pr_readdir_lwpdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5087 {
5088         gfs_readdir_state_t gstate;
5089         int error, eof = 0;
5090         offset_t tslot;
5091         proc_t *p;
5092         int pslot;
5093         lwpdir_t *lwpdir;
5094         int lwpdirsize;
5095 
5096         ASSERT(pnp->pr_type == PR_LWPDIR);
5097 
5098         p = pr_p_lock(pnp);
5099         mutex_exit(&pr_pidlock);
5100         if (p == NULL)
5101                 return (ENOENT);
5102         ASSERT(p == pnp->pr_common->prc_proc);
5103         pslot = p->p_slot;
5104         lwpdir = p->p_lwpdir;
5105         lwpdirsize = p->p_lwpdir_sz;
5106 
5107         /*
5108          * Drop p->p_lock so we can safely do uiomove().
5109          * The lwp directory will not change because
5110          * we have the process locked with P_PR_LOCK.
5111          */
5112         mutex_exit(&p->p_lock);
5113 
5114 
5115         if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5116             pmkino(0, pslot, PR_PIDDIR),
5117             pmkino(0, pslot, PR_LWPDIR), 0)) != 0) {
5118                 mutex_enter(&p->p_lock);
5119                 prunlock(pnp);
5120                 return (error);
5121         }
5122 
5123         /*
5124          * Loop until user's request is satisfied or until all lwps
5125          * have been examined.
5126          */
5127         while ((error = gfs_readdir_pred(&gstate, uiop, &tslot)) == 0) {
5128                 lwpent_t *lep;
5129                 uint_t tid;
5130 
5131                 /*
5132                  * Find next LWP.
5133                  */
5134                 while (tslot < lwpdirsize &&
5135                     ((lep = lwpdir[tslot].ld_entry) == NULL))
5136                         tslot++;
5137                 /*
5138                  * Stop when all lwps have been reported.
5139                  */
5140                 if (tslot >= lwpdirsize) {
5141                         eof = 1;
5142                         break;
5143                 }
5144 
5145                 tid = lep->le_lwpid;
5146                 error = gfs_readdir_emitn(&gstate, uiop, tslot,
5147                     pmkino(tslot, pslot, PR_LWPIDDIR), tid);
5148                 if (error)
5149                         break;
5150         }
5151 
5152         mutex_enter(&p->p_lock);
5153         prunlock(pnp);
5154 
5155         return (gfs_readdir_fini(&gstate, error, eofp, eof));
5156 }
5157 
5158 /* ARGSUSED */
5159 static int
5160 pr_readdir_lwpiddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5161 {
5162         prcommon_t *pcp = pnp->pr_common;
5163         int zombie = ((pcp->prc_flags & PRC_DESTROY) != 0);
5164         prdirent_t dirent;
5165         prdirent_t *dirp;
5166         offset_t off;
5167         int error;
5168         int pslot;
5169         int tslot;
5170 
5171         ASSERT(pnp->pr_type == PR_LWPIDDIR);
5172 
5173         if (uiop->uio_offset < 0 ||
5174             uiop->uio_offset % sizeof (prdirent_t) != 0 ||
5175             uiop->uio_resid < sizeof (prdirent_t))
5176                 return (EINVAL);
5177         if (pcp->prc_proc == NULL || pcp->prc_tslot == -1)
5178                 return (ENOENT);
5179         if (uiop->uio_offset >= sizeof (lwpiddir))
5180                 goto out;
5181 
5182         /*
5183          * Loop until user's request is satisfied, omitting some files
5184          * along the way if the lwp is a zombie and also depending
5185          * on the data model of the process.
5186          */
5187         pslot = pcp->prc_slot;
5188         tslot = pcp->prc_tslot;
5189         for (dirp = &lwpiddir[uiop->uio_offset / sizeof (prdirent_t)];
5190             uiop->uio_resid >= sizeof (prdirent_t) &&
5191             dirp < &lwpiddir[NLWPIDDIRFILES+2];
5192             uiop->uio_offset = off + sizeof (prdirent_t), dirp++) {
5193                 off = uiop->uio_offset;
5194                 if (zombie) {
5195                         switch (dirp->d_ino) {
5196                         case PR_LWPIDDIR:
5197                         case PR_LWPDIR:
5198                         case PR_LWPSINFO:
5199                                 break;
5200                         default:
5201                                 continue;
5202                         }
5203                 }
5204 #if defined(__sparc)
5205                 /* the asrs file exists only for sparc v9 _LP64 processes */
5206                 if (dirp->d_ino == PR_ASRS &&
5207                     pcp->prc_datamodel != DATAMODEL_LP64)
5208                         continue;
5209 #endif
5210                 bcopy(dirp, &dirent, sizeof (prdirent_t));
5211                 if (dirent.d_ino == PR_LWPDIR)
5212                         dirent.d_ino = pmkino(0, pslot, dirp->d_ino);
5213                 else
5214                         dirent.d_ino = pmkino(tslot, pslot, dirp->d_ino);
5215                 if ((error = uiomove((caddr_t)&dirent, sizeof (prdirent_t),
5216                     UIO_READ, uiop)) != 0)
5217                         return (error);
5218         }
5219 out:
5220         if (eofp)
5221                 *eofp = (uiop->uio_offset >= sizeof (lwpiddir));
5222         return (0);
5223 }
5224 
5225 /* ARGSUSED */
5226 static int
5227 pr_readdir_fddir(prnode_t *pnp, uio_t *uiop, int *eofp)
5228 {
5229         gfs_readdir_state_t gstate;
5230         int error, eof = 0;
5231         offset_t n;
5232         proc_t *p;
5233         int pslot;
5234         int fddirsize;
5235         uf_info_t *fip;
5236 
5237         ASSERT(pnp->pr_type == PR_FDDIR);
5238 
5239         if ((error = prlock(pnp, ZNO)) != 0)
5240                 return (error);
5241         p = pnp->pr_common->prc_proc;
5242         pslot = p->p_slot;
5243         fip = P_FINFO(p);
5244         mutex_exit(&p->p_lock);
5245 
5246         if ((error = gfs_readdir_init(&gstate, PLNSIZ, PRSDSIZE, uiop,
5247             pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_FDDIR), 0)) != 0) {
5248                 mutex_enter(&p->p_lock);
5249                 prunlock(pnp);
5250                 return (error);
5251         }
5252 
5253         mutex_enter(&fip->fi_lock);
5254         if ((p->p_flag & SSYS) || p->p_as == &kas)
5255                 fddirsize = 0;
5256         else
5257                 fddirsize = fip->fi_nfiles;
5258 
5259         /*
5260          * Loop until user's request is satisfied or until
5261          * all file descriptors have been examined.
5262          */
5263         while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5264                 /*
5265                  * Find next fd.
5266                  */
5267                 while (n < fddirsize && fip->fi_list[n].uf_file == NULL)
5268                         n++;
5269                 /*
5270                  * Stop when all fds have been reported.
5271                  */
5272                 if (n >= fddirsize) {
5273                         eof = 1;
5274                         break;
5275                 }
5276 
5277                 error = gfs_readdir_emitn(&gstate, uiop, n,
5278                     pmkino(n, pslot, PR_FD), n);
5279                 if (error)
5280                         break;
5281         }
5282 
5283         mutex_exit(&fip->fi_lock);
5284         mutex_enter(&p->p_lock);
5285         prunlock(pnp);
5286 
5287         return (gfs_readdir_fini(&gstate, error, eofp, eof));
5288 }
5289 
5290 /* ARGSUSED */
5291 static int
5292 pr_readdir_pathdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5293 {
5294         longlong_t bp[DIRENT64_RECLEN(64) / sizeof (longlong_t)];
5295         dirent64_t *dirent = (dirent64_t *)bp;
5296         int reclen;
5297         ssize_t oresid;
5298         offset_t off, idx;
5299         int error = 0;
5300         proc_t *p;
5301         int fd, obj;
5302         int pslot;
5303         int fddirsize;
5304         uf_info_t *fip;
5305         struct as *as = NULL;
5306         size_t objdirsize;
5307         vattr_t vattr;
5308         vnode_t *vp;
5309 
5310         ASSERT(pnp->pr_type == PR_PATHDIR);
5311 
5312         if (uiop->uio_offset < 0 ||
5313             uiop->uio_resid <= 0 ||
5314             (uiop->uio_offset % PRSDSIZE) != 0)
5315                 return (EINVAL);
5316         oresid = uiop->uio_resid;
5317         bzero(bp, sizeof (bp));
5318 
5319         if ((error = prlock(pnp, ZNO)) != 0)
5320                 return (error);
5321         p = pnp->pr_common->prc_proc;
5322         fip = P_FINFO(p);
5323         pslot = p->p_slot;
5324         mutex_exit(&p->p_lock);
5325 
5326         if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
5327                 as = NULL;
5328                 objdirsize = 0;
5329         } else {
5330                 AS_LOCK_ENTER(as, RW_WRITER);
5331                 if (as->a_updatedir)
5332                         rebuild_objdir(as);
5333                 objdirsize = as->a_sizedir;
5334                 AS_LOCK_EXIT(as);
5335                 as = NULL;
5336         }
5337 
5338         mutex_enter(&fip->fi_lock);
5339         if ((p->p_flag & SSYS) || p->p_as == &kas)
5340                 fddirsize = 0;
5341         else
5342                 fddirsize = fip->fi_nfiles;
5343 
5344         for (; uiop->uio_resid > 0; uiop->uio_offset = off + PRSDSIZE) {
5345                 /*
5346                  * There are 4 special files in the path directory: ".", "..",
5347                  * "root", and "cwd".  We handle those specially here.
5348                  */
5349                 off = uiop->uio_offset;
5350                 idx = off / PRSDSIZE;
5351                 if (off == 0) {                         /* "." */
5352                         dirent->d_ino = pmkino(0, pslot, PR_PATHDIR);
5353                         dirent->d_name[0] = '.';
5354                         dirent->d_name[1] = '\0';
5355                         reclen = DIRENT64_RECLEN(1);
5356                 } else if (idx == 1) {                  /* ".." */
5357                         dirent->d_ino = pmkino(0, pslot, PR_PIDDIR);
5358                         dirent->d_name[0] = '.';
5359                         dirent->d_name[1] = '.';
5360                         dirent->d_name[2] = '\0';
5361                         reclen = DIRENT64_RECLEN(2);
5362                 } else if (idx == 2) {                  /* "root" */
5363                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5364                         (void) strcpy(dirent->d_name, "root");
5365                         reclen = DIRENT64_RECLEN(4);
5366                 } else if (idx == 3) {                  /* "cwd" */
5367                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5368                         (void) strcpy(dirent->d_name, "cwd");
5369                         reclen = DIRENT64_RECLEN(3);
5370                 } else if (idx < 4 + fddirsize) {
5371                         /*
5372                          * In this case, we have one of the file descriptors.
5373                          */
5374                         fd = idx - 4;
5375                         if (fip->fi_list[fd].uf_file == NULL)
5376                                 continue;
5377                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5378                         (void) pr_u32tos(fd, dirent->d_name, PLNSIZ+1);
5379                         reclen = DIRENT64_RECLEN(PLNSIZ);
5380                 } else if (idx < 4 + fddirsize + objdirsize) {
5381                         if (fip != NULL) {
5382                                 mutex_exit(&fip->fi_lock);
5383                                 fip = NULL;
5384                         }
5385 
5386                         /*
5387                          * We drop p_lock before grabbing the address space lock
5388                          * in order to avoid a deadlock with the clock thread.
5389                          * The process will not disappear and its address space
5390                          * will not change because it is marked P_PR_LOCK.
5391                          */
5392                         if (as == NULL) {
5393                                 as = p->p_as;
5394                                 AS_LOCK_ENTER(as, RW_WRITER);
5395                         }
5396 
5397                         if (as->a_updatedir) {
5398                                 rebuild_objdir(as);
5399                                 objdirsize = as->a_sizedir;
5400                         }
5401 
5402                         obj = idx - 4 - fddirsize;
5403                         if ((vp = obj_entry(as, obj)) == NULL)
5404                                 continue;
5405                         vattr.va_mask = AT_FSID|AT_NODEID;
5406                         if (VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) != 0)
5407                                 continue;
5408                         if (vp == p->p_exec)
5409                                 (void) strcpy(dirent->d_name, "a.out");
5410                         else
5411                                 pr_object_name(dirent->d_name, vp, &vattr);
5412                         dirent->d_ino = pmkino(idx, pslot, PR_PATH);
5413                         reclen = DIRENT64_RECLEN(strlen(dirent->d_name));
5414                 } else {
5415                         break;
5416                 }
5417 
5418                 dirent->d_off = uiop->uio_offset + PRSDSIZE;
5419                 dirent->d_reclen = (ushort_t)reclen;
5420                 if (reclen > uiop->uio_resid) {
5421                         /*
5422                          * Error if no entries have been returned yet.
5423                          */
5424                         if (uiop->uio_resid == oresid)
5425                                 error = EINVAL;
5426                         break;
5427                 }
5428                 /*
5429                  * Drop the address space lock to do the uiomove().
5430                  */
5431                 if (as != NULL)
5432                         AS_LOCK_EXIT(as);
5433 
5434                 error = uiomove((caddr_t)dirent, reclen, UIO_READ, uiop);
5435                 if (as != NULL)
5436                         AS_LOCK_ENTER(as, RW_WRITER);
5437 
5438                 if (error)
5439                         break;
5440         }
5441 
5442         if (error == 0 && eofp)
5443                 *eofp = (uiop->uio_offset >= (fddirsize + 2) * PRSDSIZE);
5444 
5445         if (fip != NULL)
5446                 mutex_exit(&fip->fi_lock);
5447         if (as != NULL)
5448                 AS_LOCK_EXIT(as);
5449         mutex_enter(&p->p_lock);
5450         prunlock(pnp);
5451         return (error);
5452 }
5453 
5454 static int
5455 pr_readdir_tmpldir(prnode_t *pnp, uio_t *uiop, int *eofp)
5456 {
5457         proc_t *p;
5458         int pslot, tslot;
5459         gfs_readdir_state_t gstate;
5460         int error, eof = 0;
5461         offset_t n;
5462 
5463         ASSERT(pnp->pr_type == PR_TMPLDIR);
5464 
5465         if ((error = prlock(pnp, ZNO)) != 0)
5466                 return (error);
5467         p = pnp->pr_common->prc_proc;
5468         pslot = pnp->pr_common->prc_slot;
5469         tslot = pnp->pr_common->prc_tslot;
5470         mutex_exit(&p->p_lock);
5471 
5472         if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5473             pmkino(tslot, pslot, PR_LWPDIR),
5474             pmkino(tslot, pslot, PR_TMPLDIR), 0)) != 0) {
5475                 mutex_enter(&p->p_lock);
5476                 prunlock(pnp);
5477                 return (error);
5478         }
5479 
5480         while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5481                 /*
5482                  * Check for an active template.  Reading a directory's
5483                  * contents is already racy, so we don't bother taking
5484                  * any locks.
5485                  */
5486                 while (n < ct_ntypes &&
5487                     pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[n] == NULL)
5488                         n++;
5489                 /*
5490                  * Stop when all types have been reported.
5491                  */
5492                 if (n >= ct_ntypes) {
5493                         eof = 1;
5494                         break;
5495                 }
5496                 /*
5497                  * The pmkino invocation below will need to be updated
5498                  * when we create our fifth contract type.
5499                  */
5500                 ASSERT(ct_ntypes <= 4);
5501                 error = gfs_readdir_emit(&gstate, uiop, n,
5502                     pmkino((tslot << 2) | n, pslot, PR_TMPL),
5503                     ct_types[n]->ct_type_name, 0);
5504                 if (error)
5505                         break;
5506         }
5507 
5508         mutex_enter(&p->p_lock);
5509         prunlock(pnp);
5510 
5511         return (gfs_readdir_fini(&gstate, error, eofp, eof));
5512 }
5513 
5514 static int
5515 pr_readdir_ctdir(prnode_t *pnp, uio_t *uiop, int *eofp)
5516 {
5517         proc_t *p;
5518         int pslot;
5519         gfs_readdir_state_t gstate;
5520         int error, eof = 0;
5521         offset_t n;
5522         uint64_t zid;
5523 
5524         ASSERT(pnp->pr_type == PR_CTDIR);
5525 
5526         if ((error = prlock(pnp, ZNO)) != 0)
5527                 return (error);
5528         p = pnp->pr_common->prc_proc;
5529         pslot = p->p_slot;
5530         mutex_exit(&p->p_lock);
5531 
5532         if ((error = gfs_readdir_init(&gstate, PRDIRSIZE, PRSDSIZE, uiop,
5533             pmkino(0, pslot, PR_PIDDIR), pmkino(0, pslot, PR_CTDIR), 0)) != 0) {
5534                 mutex_enter(&p->p_lock);
5535                 prunlock(pnp);
5536                 return (error);
5537         }
5538 
5539         zid = VTOZONE(pnp->pr_vnode)->zone_uniqid;
5540         while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
5541                 id_t next = contract_plookup(p, n, zid);
5542                 if (next == -1) {
5543                         eof = 1;
5544                         break;
5545                 }
5546                 error = gfs_readdir_emitn(&gstate, uiop, next,
5547                     pmkino(next, pslot, PR_CT), next);
5548                 if (error)
5549                         break;
5550         }
5551 
5552         mutex_enter(&p->p_lock);
5553         prunlock(pnp);
5554 
5555         return (gfs_readdir_fini(&gstate, error, eofp, eof));
5556 }
5557 
5558 /* ARGSUSED */
5559 static int
5560 prfsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
5561 {
5562         return (0);
5563 }
5564 
5565 /*
5566  * Utility: remove a /proc vnode from a linked list, threaded through pr_next.
5567  */
5568 static void
5569 pr_list_unlink(vnode_t *pvp, vnode_t **listp)
5570 {
5571         vnode_t *vp;
5572         prnode_t *pnp;
5573 
5574         while ((vp = *listp) != NULL) {
5575                 pnp = VTOP(vp);
5576                 if (vp == pvp) {
5577                         *listp = pnp->pr_next;
5578                         pnp->pr_next = NULL;
5579                         break;
5580                 }
5581                 listp = &pnp->pr_next;
5582         }
5583 }
5584 
5585 /* ARGSUSED */
5586 static void
5587 prinactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
5588 {
5589         prnode_t *pnp = VTOP(vp);
5590         prnodetype_t type = pnp->pr_type;
5591         proc_t *p;
5592         vnode_t *dp;
5593         vnode_t *ovp = NULL;
5594         prnode_t *opnp = NULL;
5595 
5596         switch (type) {
5597         case PR_OBJECT:
5598         case PR_FD:
5599         case PR_SELF:
5600         case PR_PATH:
5601                 /* These are not linked into the usual lists */
5602                 ASSERT(vp->v_count == 1);
5603                 if ((dp = pnp->pr_parent) != NULL)
5604                         VN_RELE(dp);
5605                 prfreenode(pnp);
5606                 return;
5607         default:
5608                 break;
5609         }
5610 
5611         mutex_enter(&pr_pidlock);
5612         if (pnp->pr_pcommon == NULL)
5613                 p = NULL;
5614         else if ((p = pnp->pr_pcommon->prc_proc) != NULL)
5615                 mutex_enter(&p->p_lock);
5616         mutex_enter(&vp->v_lock);
5617 
5618         if (type == PR_PROCDIR || vp->v_count > 1) {
5619                 vp->v_count--;
5620                 mutex_exit(&vp->v_lock);
5621                 if (p != NULL)
5622                         mutex_exit(&p->p_lock);
5623                 mutex_exit(&pr_pidlock);
5624                 return;
5625         }
5626 
5627         if ((dp = pnp->pr_parent) != NULL) {
5628                 prnode_t *dpnp;
5629 
5630                 switch (type) {
5631                 case PR_PIDFILE:
5632                 case PR_LWPIDFILE:
5633                 case PR_OPAGEDATA:
5634                         break;
5635                 default:
5636                         dpnp = VTOP(dp);
5637                         mutex_enter(&dpnp->pr_mutex);
5638                         if (dpnp->pr_files != NULL &&
5639                             dpnp->pr_files[pnp->pr_index] == vp)
5640                                 dpnp->pr_files[pnp->pr_index] = NULL;
5641                         mutex_exit(&dpnp->pr_mutex);
5642                         break;
5643                 }
5644                 pnp->pr_parent = NULL;
5645         }
5646 
5647         ASSERT(vp->v_count == 1);
5648 
5649         /*
5650          * If we allocated an old /proc/pid node, free it too.
5651          */
5652         if (pnp->pr_pidfile != NULL) {
5653                 ASSERT(type == PR_PIDDIR);
5654                 ovp = pnp->pr_pidfile;
5655                 opnp = VTOP(ovp);
5656                 ASSERT(opnp->pr_type == PR_PIDFILE);
5657                 pnp->pr_pidfile = NULL;
5658         }
5659 
5660         mutex_exit(&pr_pidlock);
5661 
5662         if (p != NULL) {
5663                 /*
5664                  * Remove the vnodes from the lists of
5665                  * /proc vnodes for the process.
5666                  */
5667                 int slot;
5668 
5669                 switch (type) {
5670                 case PR_PIDDIR:
5671                         pr_list_unlink(vp, &p->p_trace);
5672                         break;
5673                 case PR_LWPIDDIR:
5674                         if ((slot = pnp->pr_common->prc_tslot) != -1) {
5675                                 lwpent_t *lep = p->p_lwpdir[slot].ld_entry;
5676                                 pr_list_unlink(vp, &lep->le_trace);
5677                         }
5678                         break;
5679                 default:
5680                         pr_list_unlink(vp, &p->p_plist);
5681                         break;
5682                 }
5683                 if (ovp != NULL)
5684                         pr_list_unlink(ovp, &p->p_plist);
5685                 mutex_exit(&p->p_lock);
5686         }
5687 
5688         mutex_exit(&vp->v_lock);
5689 
5690         if (type == PR_CT && pnp->pr_contract != NULL) {
5691                 contract_rele(pnp->pr_contract);
5692                 pnp->pr_contract = NULL;
5693         }
5694 
5695         if (opnp != NULL)
5696                 prfreenode(opnp);
5697         prfreenode(pnp);
5698         if (dp != NULL) {
5699                 VN_RELE(dp);
5700         }
5701 }
5702 
5703 /* ARGSUSED */
5704 static int
5705 prseek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
5706 {
5707         return (0);
5708 }
5709 
5710 /*
5711  * We use the p_execdir member of proc_t to expand the %d token in core file
5712  * paths (the directory path for the executable that dumped core; see
5713  * coreadm(1M) for details). We'd like gcore(1) to be able to expand %d in
5714  * the same way as core dumping from the kernel, but there's no convenient
5715  * and comprehensible way to export the path name for p_execdir. To solve
5716  * this, we try to find the actual path to the executable that was used. In
5717  * pr_lookup_pathdir(), we mark the a.out path name vnode with the PR_AOUT
5718  * flag, and use that here to indicate that more work is needed beyond the
5719  * call to vnodetopath().
5720  */
5721 static int
5722 prreadlink_lookup(prnode_t *pnp, char *buf, size_t size, cred_t *cr)
5723 {
5724         proc_t *p;
5725         vnode_t *vp, *execvp, *vrootp;
5726         int ret;
5727         size_t len;
5728         dirent64_t *dp;
5729         size_t dlen = DIRENT64_RECLEN(MAXPATHLEN);
5730         char *dbuf;
5731 
5732         p = curproc;
5733         mutex_enter(&p->p_lock);
5734         if ((vrootp = PTOU(p)->u_rdir) == NULL)
5735                 vrootp = rootdir;
5736         VN_HOLD(vrootp);
5737         mutex_exit(&p->p_lock);
5738 
5739         ret = vnodetopath(vrootp, pnp->pr_realvp, buf, size, cr);
5740 
5741         /*
5742          * If PR_AOUT isn't set, then we looked up the path for the vnode;
5743          * otherwise, we looked up the path for (what we believe to be) the
5744          * containing directory.
5745          */
5746         if ((pnp->pr_flags & PR_AOUT) == 0) {
5747                 VN_RELE(vrootp);
5748                 return (ret);
5749         }
5750 
5751         /*
5752          * Fail if there's a problem locking the process. This will only
5753          * occur if the process is changing so the information we would
5754          * report would already be invalid.
5755          */
5756         if (prlock(pnp, ZNO) != 0) {
5757                 VN_RELE(vrootp);
5758                 return (EIO);
5759         }
5760 
5761         p = pnp->pr_common->prc_proc;
5762         mutex_exit(&p->p_lock);
5763 
5764         execvp = p->p_exec;
5765         VN_HOLD(execvp);
5766 
5767         /*
5768          * If our initial lookup of the directory failed, fall back to
5769          * the path name information for p_exec.
5770          */
5771         if (ret != 0) {
5772                 mutex_enter(&p->p_lock);
5773                 prunlock(pnp);
5774                 ret = vnodetopath(vrootp, execvp, buf, size, cr);
5775                 VN_RELE(execvp);
5776                 VN_RELE(vrootp);
5777                 return (ret);
5778         }
5779 
5780         len = strlen(buf);
5781 
5782         /*
5783          * We use u_comm as a guess for the last component of the full
5784          * executable path name. If there isn't going to be enough space
5785          * we fall back to using the p_exec so that we can have _an_
5786          * answer even if it's not perfect.
5787          */
5788         if (strlen(PTOU(p)->u_comm) + len + 1 < size) {
5789                 buf[len] = '/';
5790                 (void) strcpy(buf + len + 1, PTOU(p)->u_comm);
5791                 mutex_enter(&p->p_lock);
5792                 prunlock(pnp);
5793 
5794                 /*
5795                  * Do a forward lookup of our u_comm guess.
5796                  */
5797                 if (lookupnameat(buf + len + 1, UIO_SYSSPACE, FOLLOW, NULLVPP,
5798                     &vp, pnp->pr_realvp) == 0) {
5799                         if (vn_compare(vp, execvp)) {
5800                                 VN_RELE(vp);
5801                                 VN_RELE(execvp);
5802                                 VN_RELE(vrootp);
5803                                 return (0);
5804                         }
5805 
5806                         VN_RELE(vp);
5807                 }
5808         } else {
5809                 mutex_enter(&p->p_lock);
5810                 prunlock(pnp);
5811         }
5812 
5813         dbuf = kmem_alloc(dlen, KM_SLEEP);
5814 
5815         /*
5816          * Try to find a matching vnode by iterating through the directory's
5817          * entries. If that fails, fall back to the path information for
5818          * p_exec.
5819          */
5820         if ((ret = dirfindvp(vrootp, pnp->pr_realvp, execvp, cr, dbuf,
5821             dlen, &dp)) == 0 && strlen(dp->d_name) + len + 1 < size) {
5822                 buf[len] = '/';
5823                 (void) strcpy(buf + len + 1, dp->d_name);
5824         } else {
5825                 ret = vnodetopath(vrootp, execvp, buf, size, cr);
5826         }
5827 
5828         kmem_free(dbuf, dlen);
5829         VN_RELE(execvp);
5830         VN_RELE(vrootp);
5831 
5832         return (ret);
5833 }
5834 
5835 /* ARGSUSED */
5836 static int
5837 prreadlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ctp)
5838 {
5839         prnode_t *pnp = VTOP(vp);
5840         char *buf;
5841         int ret = EINVAL;
5842         char idbuf[16];
5843         int length, rlength;
5844         contract_t *ct;
5845 
5846         switch (pnp->pr_type) {
5847         case PR_SELF:
5848                 (void) snprintf(idbuf, sizeof (idbuf), "%d", curproc->p_pid);
5849                 ret = uiomove(idbuf, strlen(idbuf), UIO_READ, uiop);
5850                 break;
5851         case PR_OBJECT:
5852         case PR_FD:
5853         case PR_CURDIR:
5854         case PR_ROOTDIR:
5855                 if (pnp->pr_realvp->v_type == VDIR)
5856                         ret = 0;
5857                 break;
5858         case PR_PATH:
5859                 buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
5860 
5861                 if ((ret = prreadlink_lookup(pnp, buf, MAXPATHLEN, cr)) == 0)
5862                         ret = uiomove(buf, strlen(buf), UIO_READ, uiop);
5863 
5864                 kmem_free(buf, MAXPATHLEN);
5865                 break;
5866         case PR_CT:
5867                 ASSERT(pnp->pr_contract != NULL);
5868                 ct = pnp->pr_contract;
5869                 length = sizeof (CTFS_ROOT "//") + sizeof (idbuf) +
5870                     strlen(ct->ct_type->ct_type_name);
5871                 buf = kmem_alloc(length, KM_SLEEP);
5872                 rlength = snprintf(buf, length, CTFS_ROOT "/%s/%d",
5873                     ct->ct_type->ct_type_name, ct->ct_id);
5874                 ASSERT(rlength < length);
5875                 ret = uiomove(buf, rlength, UIO_READ, uiop);
5876                 kmem_free(buf, length);
5877                 break;
5878         default:
5879                 break;
5880         }
5881 
5882         return (ret);
5883 }
5884 
5885 /*ARGSUSED2*/
5886 static int
5887 prcmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
5888 {
5889         prnode_t *pp1, *pp2;
5890 
5891         if (vp1 == vp2)
5892                 return (1);
5893 
5894         if (!vn_matchops(vp1, prvnodeops) || !vn_matchops(vp2, prvnodeops))
5895                 return (0);
5896 
5897         pp1 = VTOP(vp1);
5898         pp2 = VTOP(vp2);
5899 
5900         if (pp1->pr_type != pp2->pr_type)
5901                 return (0);
5902         if (pp1->pr_type == PR_PROCDIR)
5903                 return (1);
5904         if (pp1->pr_ino || pp2->pr_ino)
5905                 return (pp2->pr_ino == pp1->pr_ino);
5906 
5907         if (pp1->pr_common == NULL || pp2->pr_common == NULL)
5908                 return (0);
5909 
5910         return (pp1->pr_common->prc_slot == pp2->pr_common->prc_slot &&
5911             pp1->pr_common->prc_tslot == pp2->pr_common->prc_tslot);
5912 }
5913 
5914 static int
5915 prrealvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
5916 {
5917         vnode_t *rvp;
5918 
5919         if ((rvp = VTOP(vp)->pr_realvp) != NULL) {
5920                 vp = rvp;
5921                 if (VOP_REALVP(vp, &rvp, ct) == 0)
5922                         vp = rvp;
5923         }
5924 
5925         *vpp = vp;
5926         return (0);
5927 }
5928 
5929 /*
5930  * Return the answer requested to poll().
5931  * POLLIN, POLLRDNORM, and POLLOUT are recognized as in fs_poll().
5932  * In addition, these have special meaning for /proc files:
5933  *      POLLPRI         process or lwp stopped on an event of interest
5934  *      POLLERR         /proc file descriptor is invalid
5935  *      POLLHUP         process or lwp has terminated
5936  */
5937 /*ARGSUSED5*/
5938 static int
5939 prpoll(vnode_t *vp, short events, int anyyet, short *reventsp,
5940     pollhead_t **phpp, caller_context_t *ct)
5941 {
5942         prnode_t *pnp = VTOP(vp);
5943         prcommon_t *pcp = pnp->pr_common;
5944         pollhead_t *php = &pcp->prc_pollhead;
5945         proc_t *p;
5946         short revents;
5947         int error;
5948         int lockstate;
5949 
5950         ASSERT(pnp->pr_type < PR_NFILES);
5951 
5952         /*
5953          * Support for old /proc interface.
5954          */
5955         if (pnp->pr_pidfile != NULL) {
5956                 vp = pnp->pr_pidfile;
5957                 pnp = VTOP(vp);
5958                 ASSERT(pnp->pr_type == PR_PIDFILE);
5959                 ASSERT(pnp->pr_common == pcp);
5960         }
5961 
5962         *reventsp = revents = 0;
5963         *phpp = (pollhead_t *)NULL;
5964 
5965         if (vp->v_type == VDIR) {
5966                 *reventsp |= POLLNVAL;
5967                 return (0);
5968         }
5969 
5970         /* avoid deadlock with prnotify() */
5971         if (pollunlock(&lockstate) != 0) {
5972                 *reventsp = POLLNVAL;
5973                 return (0);
5974         }
5975 
5976         if ((error = prlock(pnp, ZNO)) != 0) {
5977                 pollrelock(lockstate);
5978                 switch (error) {
5979                 case ENOENT:            /* process or lwp died */
5980                         *reventsp = POLLHUP;
5981                         error = 0;
5982                         break;
5983                 case EAGAIN:            /* invalidated */
5984                         *reventsp = POLLERR;
5985                         error = 0;
5986                         break;
5987                 }
5988                 return (error);
5989         }
5990 
5991         /*
5992          * We have the process marked locked (P_PR_LOCK) and we are holding
5993          * its p->p_lock.  We want to unmark the process but retain
5994          * exclusive control w.r.t. other /proc controlling processes
5995          * before reacquiring the polling locks.
5996          *
5997          * prunmark() does this for us.  It unmarks the process
5998          * but retains p->p_lock so we still have exclusive control.
5999          * We will drop p->p_lock at the end to relinquish control.
6000          *
6001          * We cannot call prunlock() at the end to relinquish control
6002          * because prunlock(), like prunmark(), may drop and reacquire
6003          * p->p_lock and that would lead to a lock order violation
6004          * w.r.t. the polling locks we are about to reacquire.
6005          */
6006         p = pcp->prc_proc;
6007         ASSERT(p != NULL);
6008         prunmark(p);
6009 
6010         pollrelock(lockstate);          /* reacquire dropped poll locks */
6011 
6012         if ((p->p_flag & SSYS) || p->p_as == &kas)
6013                 revents = POLLNVAL;
6014         else {
6015                 short ev;
6016 
6017                 if ((ev = (events & (POLLIN|POLLRDNORM))) != 0)
6018                         revents |= ev;
6019                 /*
6020                  * POLLWRNORM (same as POLLOUT) really should not be
6021                  * used to indicate that the process or lwp stopped.
6022                  * However, USL chose to use POLLWRNORM rather than
6023                  * POLLPRI to indicate this, so we just accept either
6024                  * requested event to indicate stopped.  (grr...)
6025                  */
6026                 if ((ev = (events & (POLLPRI|POLLOUT|POLLWRNORM))) != 0) {
6027                         kthread_t *t;
6028 
6029                         if (pcp->prc_flags & PRC_LWP) {
6030                                 t = pcp->prc_thread;
6031                                 ASSERT(t != NULL);
6032                                 thread_lock(t);
6033                         } else {
6034                                 t = prchoose(p);        /* returns locked t */
6035                                 ASSERT(t != NULL);
6036                         }
6037 
6038                         if (ISTOPPED(t) || VSTOPPED(t))
6039                                 revents |= ev;
6040                         thread_unlock(t);
6041                 }
6042         }
6043 
6044         *reventsp = revents;
6045         if ((!anyyet && revents == 0) || (events & POLLET)) {
6046                 /*
6047                  * Arrange to wake up the polling lwp when
6048                  * the target process/lwp stops or terminates
6049                  * or when the file descriptor becomes invalid.
6050                  */
6051                 pcp->prc_flags |= PRC_POLL;
6052                 *phpp = php;
6053         }
6054         mutex_exit(&p->p_lock);
6055         return (0);
6056 }
6057 
6058 /* in prioctl.c */
6059 extern int prioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
6060         caller_context_t *);
6061 
6062 /*
6063  * /proc vnode operations vector
6064  */
6065 const fs_operation_def_t pr_vnodeops_template[] = {
6066         VOPNAME_OPEN,           { .vop_open = propen },
6067         VOPNAME_CLOSE,          { .vop_close = prclose },
6068         VOPNAME_READ,           { .vop_read = prread },
6069         VOPNAME_WRITE,          { .vop_write = prwrite },
6070         VOPNAME_IOCTL,          { .vop_ioctl = prioctl },
6071         VOPNAME_GETATTR,        { .vop_getattr = prgetattr },
6072         VOPNAME_ACCESS,         { .vop_access = praccess },
6073         VOPNAME_LOOKUP,         { .vop_lookup = prlookup },
6074         VOPNAME_CREATE,         { .vop_create = prcreate },
6075         VOPNAME_READDIR,        { .vop_readdir = prreaddir },
6076         VOPNAME_READLINK,       { .vop_readlink = prreadlink },
6077         VOPNAME_FSYNC,          { .vop_fsync = prfsync },
6078         VOPNAME_INACTIVE,       { .vop_inactive = prinactive },
6079         VOPNAME_SEEK,           { .vop_seek = prseek },
6080         VOPNAME_CMP,            { .vop_cmp = prcmp },
6081         VOPNAME_FRLOCK,         { .error = fs_error },
6082         VOPNAME_REALVP,         { .vop_realvp = prrealvp },
6083         VOPNAME_POLL,           { .vop_poll = prpoll },
6084         VOPNAME_DISPOSE,        { .error = fs_error },
6085         VOPNAME_SHRLOCK,        { .error = fs_error },
6086         NULL,                   NULL
6087 };