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