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