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 2018 Joyent, Inc.
31 * Copyright 2019 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_USAGE, /* /proc/<pid>/usage */
128 PR_LUSAGE, /* /proc/<pid>/lusage */
129 PR_PAGEDATA, /* /proc/<pid>/pagedata */
130 PR_WATCH, /* /proc/<pid>/watch */
131 PR_CURDIR, /* /proc/<pid>/cwd */
132 PR_ROOTDIR, /* /proc/<pid>/root */
133 PR_FDDIR, /* /proc/<pid>/fd */
134 PR_FD, /* /proc/<pid>/fd/nn */
135 PR_FDINFODIR, /* /proc/<pid>/fdinfo */
136 PR_FDINFO, /* /proc/<pid>/fdinfo/nn */
137 PR_OBJECTDIR, /* /proc/<pid>/object */
138 PR_OBJECT, /* /proc/<pid>/object/xxx */
139 PR_LWPDIR, /* /proc/<pid>/lwp */
140 PR_LWPIDDIR, /* /proc/<pid>/lwp/<lwpid> */
141 PR_LWPCTL, /* /proc/<pid>/lwp/<lwpid>/lwpctl */
142 PR_LWPNAME, /* /proc/<pid>/lwp/<lwpid>/lwpname */
143 PR_LWPSTATUS, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */
144 PR_LWPSINFO, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */
145 PR_LWPUSAGE, /* /proc/<pid>/lwp/<lwpid>/lwpusage */
146 PR_XREGS, /* /proc/<pid>/lwp/<lwpid>/xregs */
147 PR_TMPLDIR, /* /proc/<pid>/lwp/<lwpid>/templates */
148 PR_TMPL, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */
149 PR_SPYMASTER, /* /proc/<pid>/lwp/<lwpid>/spymaster */
150 #if defined(__sparc)
151 PR_GWINDOWS, /* /proc/<pid>/lwp/<lwpid>/gwindows */
152 PR_ASRS, /* /proc/<pid>/lwp/<lwpid>/asrs */
153 #endif
154 PR_PRIV, /* /proc/<pid>/priv */
155 PR_PATHDIR, /* /proc/<pid>/path */
156 PR_PATH, /* /proc/<pid>/path/xxx */
157 PR_CTDIR, /* /proc/<pid>/contracts */
158 PR_CT, /* /proc/<pid>/contracts/<ctid> */
159 PR_SECFLAGS, /* /proc/<pid>/secflags */
160 PR_PIDFILE, /* old process file */
161 PR_LWPIDFILE, /* old lwp file */
162 PR_OPAGEDATA, /* old page data file */
163 PR_NFILES /* number of /proc node types */
164 } prnodetype_t;
165
166 typedef struct prnode {
167 vnode_t *pr_next; /* list of all vnodes for process */
168 uint_t pr_flags; /* private flags */
169 kmutex_t pr_mutex; /* locks pr_files and child pr_flags */
170 prnodetype_t pr_type; /* node type */
171 mode_t pr_mode; /* file mode */
172 ino_t pr_ino; /* node id (for stat(2)) */
173 uint_t pr_hatid; /* hat layer id for page data files */
174 prcommon_t *pr_common; /* common data structure */
175 prcommon_t *pr_pcommon; /* process common data structure */
176 vnode_t *pr_parent; /* parent directory */
177 vnode_t **pr_files; /* contained files array (directory) */
178 uint_t pr_index; /* position within parent */
179 vnode_t *pr_pidfile; /* substitute vnode for old /proc */
180 vnode_t *pr_realvp; /* real vnode, file in object,fd dirs */
181 proc_t *pr_owner; /* the process that created this node */
182 vnode_t *pr_vnode; /* pointer to vnode */
183 struct contract *pr_contract; /* contract pointer */
184 int pr_cttype; /* active template type */
185 } prnode_t;
186
187 /*
188 * Values for pr_flags.
189 */
190 #define PR_INVAL 0x01 /* vnode is invalidated */
191 #define PR_ISSELF 0x02 /* vnode is a self-open */
192 #define PR_AOUT 0x04 /* vnode is for an a.out path */
193 #define PR_OFFMAX 0x08 /* vnode is a large file open */
194
195 /*
196 * Conversion macros.
197 */
198 #define VTOP(vp) ((struct prnode *)(vp)->v_data)
199 #define PTOV(pnp) ((pnp)->pr_vnode)
200
201 /*
202 * Flags to prlock().
203 */
204 #define ZNO 0 /* Fail on encountering a zombie process. */
205 #define ZYES 1 /* Allow zombies. */
206
207 /*
208 * Assign one set to another (possible different sizes).
209 *
210 * Assigning to a smaller set causes members to be lost.
211 * Assigning to a larger set causes extra members to be cleared.
212 */
213 #define prassignset(ap, sp) \
214 { \
215 register int _i_ = sizeof (*(ap))/sizeof (uint32_t); \
216 while (--_i_ >= 0) \
217 ((uint32_t *)(ap))[_i_] = \
218 (_i_ >= sizeof (*(sp))/sizeof (uint32_t)) ? \
219 0 : ((uint32_t *)(sp))[_i_]; \
220 }
221
222 /*
223 * Determine whether or not a set (of arbitrary size) is empty.
224 */
225 #define prisempty(sp) \
226 setisempty((uint32_t *)(sp), \
227 (uint_t)(sizeof (*(sp)) / sizeof (uint32_t)))
228
229 /*
230 * Resource usage with times as hrtime_t rather than timestruc_t.
231 * Each member exactly matches the corresponding member in prusage_t.
232 * This is for convenience of internal computation.
233 */
234 typedef struct prhusage {
235 id_t pr_lwpid; /* lwp id. 0: process or defunct */
236 int pr_count; /* number of contributing lwps */
237 hrtime_t pr_tstamp; /* current time stamp */
238 hrtime_t pr_create; /* process/lwp creation time stamp */
239 hrtime_t pr_term; /* process/lwp termination time stamp */
240 hrtime_t pr_rtime; /* total lwp real (elapsed) time */
241 hrtime_t pr_utime; /* user level CPU time */
242 hrtime_t pr_stime; /* system call CPU time */
243 hrtime_t pr_ttime; /* other system trap CPU time */
244 hrtime_t pr_tftime; /* text page fault sleep time */
245 hrtime_t pr_dftime; /* data page fault sleep time */
246 hrtime_t pr_kftime; /* kernel page fault sleep time */
247 hrtime_t pr_ltime; /* user lock wait sleep time */
248 hrtime_t pr_slptime; /* all other sleep time */
249 hrtime_t pr_wtime; /* wait-cpu (latency) time */
250 hrtime_t pr_stoptime; /* stopped time */
251 hrtime_t filltime[6]; /* filler for future expansion */
252 uint64_t pr_minf; /* minor page faults */
253 uint64_t pr_majf; /* major page faults */
254 uint64_t pr_nswap; /* swaps */
255 uint64_t pr_inblk; /* input blocks */
256 uint64_t pr_oublk; /* output blocks */
257 uint64_t pr_msnd; /* messages sent */
258 uint64_t pr_mrcv; /* messages received */
259 uint64_t pr_sigs; /* signals received */
260 uint64_t pr_vctx; /* voluntary context switches */
261 uint64_t pr_ictx; /* involuntary context switches */
262 uint64_t pr_sysc; /* system calls */
263 uint64_t pr_ioch; /* chars read and written */
264 uint64_t filler[10]; /* filler for future expansion */
265 } prhusage_t;
266
267 #if defined(_KERNEL)
268
269 /* Exclude system processes from this test */
270 #define PROCESS_NOT_32BIT(p) \
271 (!((p)->p_flag & SSYS) && (p)->p_as != &kas && \
272 (p)->p_model != DATAMODEL_ILP32)
273
274 extern int prnwatch; /* number of supported watchpoints */
275 extern int nproc_highbit; /* highbit(v.v_nproc) */
276
277 extern struct vnodeops *prvnodeops;
278
279 /*
280 * Generic chained copyout buffers for procfs use.
281 * In order to prevent procfs from making huge oversize kmem_alloc calls,
282 * a list of smaller buffers can be concatenated and copied to userspace in
283 * sequence.
284 *
285 * The implementation is opaque.
286 *
287 * A user of this will perform the following steps:
288 *
289 * list_t listhead;
290 * struct my *mp;
291 *
292 * pr_iol_initlist(&listhead, sizeof (*mp), n);
293 * while (whatever) {
294 * mp = pr_iol_newbuf(&listhead, sizeof (*mp));
295 * ...
296 * error = ...
297 * }
298 *
299 * When done, depending on whether copyout() or uiomove() is supposed to
300 * be used for transferring the buffered data to userspace, call either:
301 *
302 * error = pr_iol_copyout_and_free(&listhead, &cmaddr, error);
303 *
304 * or else:
305 *
306 * error = pr_iol_uiomove_and_free(&listhead, uiop, error);
307 *
308 * These two functions will in any case kmem_free() all list items, but
309 * if an error occurred before they will not perform the copyout/uiomove.
310 * If copyout/uiomove are done, the passed target address / uio_t
311 * are updated. The error returned will either be the one passed in, or
312 * the error that occurred during copyout/uiomove.
313 */
314
315 extern void pr_iol_initlist(list_t *head, size_t itemsize, int nitems);
316 extern void * pr_iol_newbuf(list_t *head, size_t itemsize);
317 extern int pr_iol_copyout_and_free(list_t *head, caddr_t *tgt, int errin);
318 extern int pr_iol_uiomove_and_free(list_t *head, uio_t *uiop, int errin);
319 extern void pr_iol_freelist(list_t *);
320
321 #if defined(_SYSCALL32_IMPL)
322
323 extern int prwritectl32(vnode_t *, struct uio *, cred_t *);
324 extern void prgetaction32(proc_t *, user_t *, uint_t, struct sigaction32 *);
325 extern void prcvtusage32(struct prhusage *, prusage32_t *);
326
327 #endif /* _SYSCALL32_IMPL */
328
329 /* kludge to support old /proc interface */
330 #if !defined(_SYS_OLD_PROCFS_H)
331 extern int prgetmap(proc_t *, int, list_t *);
332 extern int prgetxmap(proc_t *, list_t *);
333 #if defined(_SYSCALL32_IMPL)
334 extern int prgetmap32(proc_t *, int, list_t *);
335 extern int prgetxmap32(proc_t *, list_t *);
336 #endif /* _SYSCALL32_IMPL */
337 #endif /* !_SYS_OLD_PROCFS_H */
338
339 extern proc_t *pr_p_lock(prnode_t *);
340 extern kthread_t *pr_thread(prnode_t *);
341 extern void pr_stop(prnode_t *);
342 extern int pr_wait_stop(prnode_t *, time_t);
343 extern int pr_setrun(prnode_t *, ulong_t);
344 extern int pr_wait(prcommon_t *, timestruc_t *, int);
345 extern void pr_wait_die(prnode_t *);
346 extern int pr_setsig(prnode_t *, siginfo_t *);
347 extern int pr_kill(prnode_t *, int, cred_t *);
348 extern int pr_unkill(prnode_t *, int);
349 extern int pr_nice(proc_t *, int, cred_t *);
350 extern void pr_setentryexit(proc_t *, sysset_t *, int);
351 extern int pr_set(proc_t *, long);
352 extern int pr_unset(proc_t *, long);
353 extern void pr_sethold(prnode_t *, sigset_t *);
354 extern file_t *pr_getf(proc_t *, uint_t, short *);
355 extern void pr_releasef(proc_t *, uint_t);
356 extern void pr_setfault(proc_t *, fltset_t *);
357 extern int prusrio(proc_t *, enum uio_rw, struct uio *, int);
358 extern int prwritectl(vnode_t *, struct uio *, cred_t *);
359 extern int prlock(prnode_t *, int);
360 extern void prunmark(proc_t *);
361 extern void prunlock(prnode_t *);
362 extern size_t prpdsize(struct as *);
363 extern int prpdread(proc_t *, uint_t, struct uio *);
364 extern size_t oprpdsize(struct as *);
365 extern int oprpdread(struct as *, uint_t, struct uio *);
366 extern void prgetaction(proc_t *, user_t *, uint_t, struct sigaction *);
367 extern void prgetusage(kthread_t *, struct prhusage *);
368 extern void praddusage(kthread_t *, struct prhusage *);
369 extern void prcvtusage(struct prhusage *, prusage_t *);
370 extern void prscaleusage(prhusage_t *);
371 extern kthread_t *prchoose(proc_t *);
372 extern void allsetrun(proc_t *);
373 extern int setisempty(uint32_t *, uint_t);
374 extern int pr_u32tos(uint32_t, char *, int);
375 extern vnode_t *prlwpnode(prnode_t *, uint_t);
376 extern prnode_t *prgetnode(vnode_t *, prnodetype_t);
377 extern void prfreenode(prnode_t *);
378 extern void pr_object_name(char *, vnode_t *, struct vattr *);
379 extern int set_watched_area(proc_t *, struct watched_area *);
380 extern int clear_watched_area(proc_t *, struct watched_area *);
381 extern void pr_free_watchpoints(proc_t *);
382 extern proc_t *pr_cancel_watch(prnode_t *);
383 extern struct seg *break_seg(proc_t *);
384
385 /*
386 * Machine-dependent routines (defined in prmachdep.c).
387 */
388 extern void prgetprregs(klwp_t *, prgregset_t);
389 extern void prsetprregs(klwp_t *, prgregset_t, int);
390
391 #if defined(_SYSCALL32_IMPL)
392 extern void prgetprregs32(klwp_t *, prgregset32_t);
393 extern void prgregset_32ton(klwp_t *, prgregset32_t, prgregset_t);
394 extern void prgetprfpregs32(klwp_t *, prfpregset32_t *);
395 extern void prsetprfpregs32(klwp_t *, prfpregset32_t *);
396 extern size_t prpdsize32(struct as *);
397 extern int prpdread32(proc_t *, uint_t, struct uio *);
398 extern size_t oprpdsize32(struct as *);
399 extern int oprpdread32(struct as *, uint_t, struct uio *);
400 #endif /* _SYSCALL32_IMPL */
401
402 extern void prpokethread(kthread_t *t);
403 extern int prgetrvals(klwp_t *, long *, long *);
404 extern void prgetprfpregs(klwp_t *, prfpregset_t *);
405 extern void prsetprfpregs(klwp_t *, prfpregset_t *);
406 extern void prgetprxregs(klwp_t *, caddr_t);
407 extern void prsetprxregs(klwp_t *, caddr_t);
408 extern int prgetprxregsize(proc_t *);
409 extern int prhasfp(void);
410 extern int prhasx(proc_t *);
411 extern caddr_t prgetstackbase(proc_t *);
412 extern caddr_t prgetpsaddr(proc_t *);
413 extern int prisstep(klwp_t *);
414 extern void prsvaddr(klwp_t *, caddr_t);
415 extern int prfetchinstr(klwp_t *, ulong_t *);
416 extern ushort_t prgetpctcpu(uint64_t);
417
418 #endif /* _KERNEL */
419
420 #ifdef __cplusplus
421 }
422 #endif
423
424 #endif /* _SYS_PROC_PRDATA_H */