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