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