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