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