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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 /*
  30  * Copyright 2019 Joyent, Inc.
  31  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  32  */
  33 
  34 #ifndef _SYS_PROC_PRDATA_H
  35 #define _SYS_PROC_PRDATA_H
  36 
  37 #include <sys/isa_defs.h>
  38 #include <sys/proc.h>
  39 #include <sys/vnode.h>
  40 #include <sys/prsystm.h>
  41 #include <sys/model.h>
  42 #include <sys/poll.h>
  43 #include <sys/list.h>
  44 
  45 #ifdef  __cplusplus
  46 extern "C" {
  47 #endif
  48 
  49 /*
  50  * Test for thread being stopped, not on an event of interest,
  51  * but with a directed stop in effect.
  52  */
  53 #define DSTOPPED(t)     \
  54         ((t)->t_state == TS_STOPPED && \
  55         ((t)->t_proc_flag & TP_PRSTOP))
  56 
  57 #define round4(r)       (((r) + 3) & (~3))
  58 #define round8(r)       (((r) + 7) & (~7))
  59 #define round16(r)      (((r) + 15) & (~15))
  60 #define roundlong(r)    (((r) + sizeof (long) - 1) & (~(sizeof (long) - 1)))
  61 
  62 #define PNSIZ   10                      /* max size of /proc name entries */
  63 #define PLNSIZ  10                      /* max size of /proc lwp name entries */
  64 
  65 /*
  66  * Common file object to which all /proc vnodes for a specific process
  67  * or lwp refer.  One for the process, one for each lwp.
  68  */
  69 typedef struct prcommon {
  70         kmutex_t        prc_mutex;      /* to wait for the proc/lwp to stop */
  71         kcondvar_t      prc_wait;       /* to wait for the proc/lwp to stop */
  72         ushort_t        prc_flags;      /* flags */
  73         uint_t          prc_writers;    /* number of write opens of prnodes */
  74         uint_t          prc_selfopens;  /* number of write opens by self */
  75         pid_t           prc_pid;        /* process id */
  76         model_t         prc_datamodel;  /* data model of the process */
  77         proc_t          *prc_proc;      /* process being traced */
  78         kthread_t       *prc_thread;    /* thread (lwp) being traced */
  79         int             prc_slot;       /* procdir slot number */
  80         id_t            prc_tid;        /* thread (lwp) id */
  81         int             prc_tslot;      /* lwpdir slot number, -1 if reaped */
  82         int             prc_refcnt;     /* this structure's reference count */
  83         struct pollhead prc_pollhead;   /* list of all pollers */
  84 } prcommon_t;
  85 
  86 /* prc_flags */
  87 #define PRC_DESTROY     0x01    /* process or lwp is being destroyed */
  88 #define PRC_LWP         0x02    /* structure refers to an lwp */
  89 #define PRC_SYS         0x04    /* process is a system process */
  90 #define PRC_POLL        0x08    /* poll() in progress on this process/lwp */
  91 #define PRC_EXCL        0x10    /* exclusive access granted (old /proc) */
  92 
  93 /*
  94  * Macros for mapping between i-numbers and pids.
  95  */
  96 #define pmkino(tslot, pslot, nodetype)          \
  97         (((((ino_t)(tslot) << nproc_highbit) |    \
  98         (ino_t)(pslot)) << 6) |                   \
  99         (nodetype) + 2)
 100 
 101 /* for old /proc interface */
 102 #define PRBIAS  64
 103 #define ptoi(n) ((int)(((n) + PRBIAS)))         /* pid to i-number */
 104 
 105 /*
 106  * Node types for /proc files (directories and files contained therein).
 107  */
 108 typedef enum prnodetype {
 109         PR_PROCDIR,             /* /proc                                */
 110         PR_SELF,                /* /proc/self                           */
 111         PR_PIDDIR,              /* /proc/<pid>                            */
 112         PR_AS,                  /* /proc/<pid>/as                 */
 113         PR_CTL,                 /* /proc/<pid>/ctl                        */
 114         PR_STATUS,              /* /proc/<pid>/status                     */
 115         PR_LSTATUS,             /* /proc/<pid>/lstatus                    */
 116         PR_PSINFO,              /* /proc/<pid>/psinfo                     */
 117         PR_LPSINFO,             /* /proc/<pid>/lpsinfo                    */
 118         PR_MAP,                 /* /proc/<pid>/map                        */
 119         PR_RMAP,                /* /proc/<pid>/rmap                       */
 120         PR_XMAP,                /* /proc/<pid>/xmap                       */
 121         PR_CRED,                /* /proc/<pid>/cred                       */
 122         PR_SIGACT,              /* /proc/<pid>/sigact                     */
 123         PR_AUXV,                /* /proc/<pid>/auxv                       */
 124 #if defined(__i386) || defined(__amd64)
 125         PR_LDT,                 /* /proc/<pid>/ldt                        */
 126 #endif
 127         PR_ARGV,                /* /proc/<pid>/argv                       */
 128         PR_CMDLINE,             /* /proc/<pid>/cmdline                    */
 129         PR_USAGE,               /* /proc/<pid>/usage                      */
 130         PR_LUSAGE,              /* /proc/<pid>/lusage                     */
 131         PR_PAGEDATA,            /* /proc/<pid>/pagedata                   */
 132         PR_WATCH,               /* /proc/<pid>/watch                      */
 133         PR_CURDIR,              /* /proc/<pid>/cwd                        */
 134         PR_ROOTDIR,             /* /proc/<pid>/root                       */
 135         PR_FDDIR,               /* /proc/<pid>/fd                 */
 136         PR_FD,                  /* /proc/<pid>/fd/nn                      */
 137         PR_FDINFODIR,           /* /proc/<pid>/fdinfo                     */
 138         PR_FDINFO,              /* /proc/<pid>/fdinfo/nn          */
 139         PR_OBJECTDIR,           /* /proc/<pid>/object                     */
 140         PR_OBJECT,              /* /proc/<pid>/object/xxx         */
 141         PR_LWPDIR,              /* /proc/<pid>/lwp                        */
 142         PR_LWPIDDIR,            /* /proc/<pid>/lwp/<lwpid>          */
 143         PR_LWPCTL,              /* /proc/<pid>/lwp/<lwpid>/lwpctl   */
 144         PR_LWPNAME,             /* /proc/<pid>/lwp/<lwpid>/lwpname  */
 145         PR_LWPSTATUS,           /* /proc/<pid>/lwp/<lwpid>/lwpstatus        */
 146         PR_LWPSINFO,            /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
 147         PR_LWPUSAGE,            /* /proc/<pid>/lwp/<lwpid>/lwpusage */
 148         PR_XREGS,               /* /proc/<pid>/lwp/<lwpid>/xregs    */
 149         PR_TMPLDIR,             /* /proc/<pid>/lwp/<lwpid>/templates        */
 150         PR_TMPL,                /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
 151         PR_SPYMASTER,           /* /proc/<pid>/lwp/<lwpid>/spymaster        */
 152 #if defined(__sparc)
 153         PR_GWINDOWS,            /* /proc/<pid>/lwp/<lwpid>/gwindows */
 154         PR_ASRS,                /* /proc/<pid>/lwp/<lwpid>/asrs             */
 155 #endif
 156         PR_PRIV,                /* /proc/<pid>/priv                       */
 157         PR_PATHDIR,             /* /proc/<pid>/path                       */
 158         PR_PATH,                /* /proc/<pid>/path/xxx                   */
 159         PR_CTDIR,               /* /proc/<pid>/contracts          */
 160         PR_CT,                  /* /proc/<pid>/contracts/<ctid>             */
 161         PR_SECFLAGS,            /* /proc/<pid>/secflags                   */
 162         PR_PIDFILE,             /* old process file                     */
 163         PR_LWPIDFILE,           /* old lwp file                         */
 164         PR_OPAGEDATA,           /* old page data file                   */
 165         PR_NFILES               /* number of /proc node types           */
 166 } prnodetype_t;
 167 
 168 typedef struct prnode {
 169         vnode_t         *pr_next;       /* list of all vnodes for process */
 170         uint_t          pr_flags;       /* private flags */
 171         kmutex_t        pr_mutex;       /* locks pr_files and child pr_flags */
 172         prnodetype_t    pr_type;        /* node type */
 173         mode_t          pr_mode;        /* file mode */
 174         ino_t           pr_ino;         /* node id (for stat(2)) */
 175         uint_t          pr_hatid;       /* hat layer id for page data files */
 176         prcommon_t      *pr_common;     /* common data structure */
 177         prcommon_t      *pr_pcommon;    /* process common data structure */
 178         vnode_t         *pr_parent;     /* parent directory */
 179         vnode_t         **pr_files;     /* contained files array (directory) */
 180         uint_t          pr_index;       /* position within parent */
 181         vnode_t         *pr_pidfile;    /* substitute vnode for old /proc */
 182         vnode_t         *pr_realvp;     /* real vnode, file in object,fd dirs */
 183         proc_t          *pr_owner;      /* the process that created this node */
 184         vnode_t         *pr_vnode;      /* pointer to vnode */
 185         struct contract *pr_contract;   /* contract pointer */
 186         int             pr_cttype;      /* active template type */
 187 } prnode_t;
 188 
 189 /*
 190  * Values for pr_flags.
 191  */
 192 #define PR_INVAL        0x01            /* vnode is invalidated */
 193 #define PR_ISSELF       0x02            /* vnode is a self-open */
 194 #define PR_AOUT         0x04            /* vnode is for an a.out path */
 195 #define PR_OFFMAX       0x08            /* vnode is a large file open */
 196 
 197 /*
 198  * Conversion macros.
 199  */
 200 #define VTOP(vp)        ((struct prnode *)(vp)->v_data)
 201 #define PTOV(pnp)       ((pnp)->pr_vnode)
 202 
 203 /*
 204  * Flags to prlock().
 205  */
 206 #define ZNO     0       /* Fail on encountering a zombie process. */
 207 #define ZYES    1       /* Allow zombies. */
 208 
 209 /*
 210  * Assign one set to another (possible different sizes).
 211  *
 212  * Assigning to a smaller set causes members to be lost.
 213  * Assigning to a larger set causes extra members to be cleared.
 214  */
 215 #define prassignset(ap, sp)                                     \
 216 {                                                               \
 217         register int _i_ = sizeof (*(ap))/sizeof (uint32_t);    \
 218         while (--_i_ >= 0)                                   \
 219                 ((uint32_t *)(ap))[_i_] =                       \
 220                     (_i_ >= sizeof (*(sp))/sizeof (uint32_t)) ?      \
 221                     0 : ((uint32_t *)(sp))[_i_];                \
 222 }
 223 
 224 /*
 225  * Determine whether or not a set (of arbitrary size) is empty.
 226  */
 227 #define prisempty(sp) \
 228         setisempty((uint32_t *)(sp), \
 229                 (uint_t)(sizeof (*(sp)) / sizeof (uint32_t)))
 230 
 231 /*
 232  * Resource usage with times as hrtime_t rather than timestruc_t.
 233  * Each member exactly matches the corresponding member in prusage_t.
 234  * This is for convenience of internal computation.
 235  */
 236 typedef struct prhusage {
 237         id_t            pr_lwpid;       /* lwp id.  0: process or defunct */
 238         int             pr_count;       /* number of contributing lwps */
 239         hrtime_t        pr_tstamp;      /* current time stamp */
 240         hrtime_t        pr_create;      /* process/lwp creation time stamp */
 241         hrtime_t        pr_term;        /* process/lwp termination time stamp */
 242         hrtime_t        pr_rtime;       /* total lwp real (elapsed) time */
 243         hrtime_t        pr_utime;       /* user level CPU time */
 244         hrtime_t        pr_stime;       /* system call CPU time */
 245         hrtime_t        pr_ttime;       /* other system trap CPU time */
 246         hrtime_t        pr_tftime;      /* text page fault sleep time */
 247         hrtime_t        pr_dftime;      /* data page fault sleep time */
 248         hrtime_t        pr_kftime;      /* kernel page fault sleep time */
 249         hrtime_t        pr_ltime;       /* user lock wait sleep time */
 250         hrtime_t        pr_slptime;     /* all other sleep time */
 251         hrtime_t        pr_wtime;       /* wait-cpu (latency) time */
 252         hrtime_t        pr_stoptime;    /* stopped time */
 253         hrtime_t        filltime[6];    /* filler for future expansion */
 254         uint64_t        pr_minf;        /* minor page faults */
 255         uint64_t        pr_majf;        /* major page faults */
 256         uint64_t        pr_nswap;       /* swaps */
 257         uint64_t        pr_inblk;       /* input blocks */
 258         uint64_t        pr_oublk;       /* output blocks */
 259         uint64_t        pr_msnd;        /* messages sent */
 260         uint64_t        pr_mrcv;        /* messages received */
 261         uint64_t        pr_sigs;        /* signals received */
 262         uint64_t        pr_vctx;        /* voluntary context switches */
 263         uint64_t        pr_ictx;        /* involuntary context switches */
 264         uint64_t        pr_sysc;        /* system calls */
 265         uint64_t        pr_ioch;        /* chars read and written */
 266         uint64_t        filler[10];     /* filler for future expansion */
 267 } prhusage_t;
 268 
 269 #if defined(_KERNEL)
 270 
 271 /* Exclude system processes from this test */
 272 #define PROCESS_NOT_32BIT(p)    \
 273         (!((p)->p_flag & SSYS) && (p)->p_as != &kas && \
 274         (p)->p_model != DATAMODEL_ILP32)
 275 
 276 extern  int     prnwatch;       /* number of supported watchpoints */
 277 extern  int     nproc_highbit;  /* highbit(v.v_nproc) */
 278 
 279 extern  struct vnodeops *prvnodeops;
 280 
 281 /*
 282  * Generic chained copyout buffers for procfs use.
 283  * In order to prevent procfs from making huge oversize kmem_alloc calls,
 284  * a list of smaller buffers can be concatenated and copied to userspace in
 285  * sequence.
 286  *
 287  * The implementation is opaque.
 288  *
 289  * A user of this will perform the following steps:
 290  *
 291  *      list_t  listhead;
 292  *      struct my *mp;
 293  *
 294  *      pr_iol_initlist(&listhead, sizeof (*mp), n);
 295  *      while (whatever) {
 296  *              mp = pr_iol_newbuf(&listhead, sizeof (*mp));
 297  *              ...
 298  *              error = ...
 299  *      }
 300  *
 301  * When done, depending on whether copyout() or uiomove() is supposed to
 302  * be used for transferring the buffered data to userspace, call either:
 303  *
 304  *      error = pr_iol_copyout_and_free(&listhead, &cmaddr, error);
 305  *
 306  * or else:
 307  *
 308  *      error = pr_iol_uiomove_and_free(&listhead, uiop, error);
 309  *
 310  * These two functions will in any case kmem_free() all list items, but
 311  * if an error occurred before they will not perform the copyout/uiomove.
 312  * If copyout/uiomove are done, the passed target address / uio_t
 313  * are updated. The error returned will either be the one passed in, or
 314  * the error that occurred during copyout/uiomove.
 315  */
 316 
 317 extern  void    pr_iol_initlist(list_t *head, size_t itemsize, int nitems);
 318 extern  void *  pr_iol_newbuf(list_t *head, size_t itemsize);
 319 extern  int     pr_iol_copyout_and_free(list_t *head, caddr_t *tgt, int errin);
 320 extern  int     pr_iol_uiomove_and_free(list_t *head, uio_t *uiop, int errin);
 321 extern  void    pr_iol_freelist(list_t *);
 322 
 323 #if defined(_SYSCALL32_IMPL)
 324 
 325 extern  int     prwritectl32(vnode_t *, struct uio *, cred_t *);
 326 extern  void    prgetaction32(proc_t *, user_t *, uint_t, struct sigaction32 *);
 327 extern  void    prcvtusage32(struct prhusage *, prusage32_t *);
 328 
 329 #endif  /* _SYSCALL32_IMPL */
 330 
 331 /* kludge to support old /proc interface */
 332 #if !defined(_SYS_OLD_PROCFS_H)
 333 extern  int     prgetmap(proc_t *, int, list_t *);
 334 extern  int     prgetxmap(proc_t *, list_t *);
 335 #if defined(_SYSCALL32_IMPL)
 336 extern  int     prgetmap32(proc_t *, int, list_t *);
 337 extern  int     prgetxmap32(proc_t *, list_t *);
 338 #endif  /* _SYSCALL32_IMPL */
 339 #endif /* !_SYS_OLD_PROCFS_H */
 340 
 341 extern  proc_t  *pr_p_lock(prnode_t *);
 342 extern  kthread_t *pr_thread(prnode_t *);
 343 extern  void    pr_stop(prnode_t *);
 344 extern  int     pr_wait_stop(prnode_t *, time_t);
 345 extern  int     pr_setrun(prnode_t *, ulong_t);
 346 extern  int     pr_wait(prcommon_t *, timestruc_t *, int);
 347 extern  void    pr_wait_die(prnode_t *);
 348 extern  int     pr_setsig(prnode_t *, siginfo_t *);
 349 extern  int     pr_kill(prnode_t *, int, cred_t *);
 350 extern  int     pr_unkill(prnode_t *, int);
 351 extern  int     pr_nice(proc_t *, int, cred_t *);
 352 extern  void    pr_setentryexit(proc_t *, sysset_t *, int);
 353 extern  int     pr_set(proc_t *, long);
 354 extern  int     pr_unset(proc_t *, long);
 355 extern  void    pr_sethold(prnode_t *, sigset_t *);
 356 extern  file_t  *pr_getf(proc_t *, uint_t, short *);
 357 extern  void    pr_releasef(file_t *);
 358 extern  void    pr_setfault(proc_t *, fltset_t *);
 359 extern  int     prusrio(proc_t *, enum uio_rw, struct uio *, int);
 360 extern  int     prreadargv(proc_t *, char *, size_t, size_t *);
 361 extern  int     prreadcmdline(proc_t *, char *, size_t, size_t *);
 362 extern  int     prreadenvv(proc_t *, char *, size_t, size_t *);
 363 extern  int     prwritectl(vnode_t *, struct uio *, cred_t *);
 364 extern  int     prlock(prnode_t *, int);
 365 extern  void    prunmark(proc_t *);
 366 extern  void    prunlock(prnode_t *);
 367 extern  size_t  prpdsize(struct as *);
 368 extern  int     prpdread(proc_t *, uint_t, struct uio *);
 369 extern  size_t  oprpdsize(struct as *);
 370 extern  int     oprpdread(struct as *, uint_t, struct uio *);
 371 extern  void    prgetaction(proc_t *, user_t *, uint_t, struct sigaction *);
 372 extern  void    prgetusage(kthread_t *, struct prhusage *);
 373 extern  void    praddusage(kthread_t *, struct prhusage *);
 374 extern  void    prcvtusage(struct prhusage *, prusage_t *);
 375 extern  void    prscaleusage(prhusage_t *);
 376 extern  kthread_t *prchoose(proc_t *);
 377 extern  void    allsetrun(proc_t *);
 378 extern  int     setisempty(uint32_t *, uint_t);
 379 extern  int     pr_u32tos(uint32_t, char *, int);
 380 extern  vnode_t *prlwpnode(prnode_t *, uint_t);
 381 extern  prnode_t *prgetnode(vnode_t *, prnodetype_t);
 382 extern  void    prfreenode(prnode_t *);
 383 extern  void    pr_object_name(char *, vnode_t *, struct vattr *);
 384 extern  int     set_watched_area(proc_t *, struct watched_area *);
 385 extern  int     clear_watched_area(proc_t *, struct watched_area *);
 386 extern  void    pr_free_watchpoints(proc_t *);
 387 extern  proc_t  *pr_cancel_watch(prnode_t *);
 388 extern  struct seg *break_seg(proc_t *);
 389 extern  void    prgethold(kthread_t *, sigset_t *);
 390 
 391 /*
 392  * Machine-dependent routines (defined in prmachdep.c).
 393  */
 394 extern  void    prgetprregs(klwp_t *, prgregset_t);
 395 extern  void    prsetprregs(klwp_t *, prgregset_t, int);
 396 
 397 #if defined(_SYSCALL32_IMPL)
 398 extern  void    prgetprregs32(klwp_t *, prgregset32_t);
 399 extern  void    prgregset_32ton(klwp_t *, prgregset32_t, prgregset_t);
 400 extern  void    prgetprfpregs32(klwp_t *, prfpregset32_t *);
 401 extern  void    prsetprfpregs32(klwp_t *, prfpregset32_t *);
 402 extern  size_t  prpdsize32(struct as *);
 403 extern  int     prpdread32(proc_t *, uint_t, struct uio *);
 404 extern  size_t  oprpdsize32(struct as *);
 405 extern  int     oprpdread32(struct as *, uint_t, struct uio *);
 406 #endif  /* _SYSCALL32_IMPL */
 407 
 408 extern  void    prpokethread(kthread_t *t);
 409 extern  int     prgetrvals(klwp_t *, long *, long *);
 410 extern  void    prgetprfpregs(klwp_t *, prfpregset_t *);
 411 extern  void    prsetprfpregs(klwp_t *, prfpregset_t *);
 412 extern  void    prgetprxregs(klwp_t *, caddr_t);
 413 extern  void    prsetprxregs(klwp_t *, caddr_t);
 414 extern  int     prgetprxregsize(proc_t *);
 415 extern  int     prhasfp(void);
 416 extern  int     prhasx(proc_t *);
 417 extern  caddr_t prgetstackbase(proc_t *);
 418 extern  caddr_t prgetpsaddr(proc_t *);
 419 extern  int     prisstep(klwp_t *);
 420 extern  void    prsvaddr(klwp_t *, caddr_t);
 421 extern  int     prfetchinstr(klwp_t *, ulong_t *);
 422 extern  ushort_t prgetpctcpu(uint64_t);
 423 
 424 #endif  /* _KERNEL */
 425 
 426 #ifdef  __cplusplus
 427 }
 428 #endif
 429 
 430 #endif  /* _SYS_PROC_PRDATA_H */