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