xref: /illumos-gate/usr/src/uts/common/fs/proc/prdata.h (revision 3448eae2e9d99e7fadeb43056eb8e788c7ea93be)
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 2020 OmniOS Community Edition (OmniOSce) Association.
32  * Copyright 2023 Oxide Computer Company
33  */
34 
35 #ifndef _SYS_PROC_PRDATA_H
36 #define	_SYS_PROC_PRDATA_H
37 
38 #include <sys/isa_defs.h>
39 #include <sys/proc.h>
40 #include <sys/vnode.h>
41 #include <sys/prsystm.h>
42 #include <sys/model.h>
43 #include <sys/poll.h>
44 #include <sys/list.h>
45 
46 #ifdef	__cplusplus
47 extern "C" {
48 #endif
49 
50 /*
51  * Test for thread being stopped, not on an event of interest,
52  * but with a directed stop in effect.
53  */
54 #define	DSTOPPED(t)	\
55 	((t)->t_state == TS_STOPPED && \
56 	((t)->t_proc_flag & TP_PRSTOP))
57 
58 #define	round4(r)	(((r) + 3) & (~3))
59 #define	round8(r)	(((r) + 7) & (~7))
60 #define	round16(r)	(((r) + 15) & (~15))
61 #define	roundlong(r)	(((r) + sizeof (long) - 1) & (~(sizeof (long) - 1)))
62 
63 #define	PNSIZ	10			/* max size of /proc name entries */
64 #define	PLNSIZ	10			/* max size of /proc lwp name entries */
65 
66 /*
67  * Common file object to which all /proc vnodes for a specific process
68  * or lwp refer.  One for the process, one for each lwp.
69  */
70 typedef struct prcommon {
71 	kmutex_t	prc_mutex;	/* to wait for the proc/lwp to stop */
72 	kcondvar_t	prc_wait;	/* to wait for the proc/lwp to stop */
73 	ushort_t	prc_flags;	/* flags */
74 	uint_t		prc_writers;	/* number of write opens of prnodes */
75 	uint_t		prc_selfopens;	/* number of write opens by self */
76 	pid_t		prc_pid;	/* process id */
77 	model_t		prc_datamodel;	/* data model of the process */
78 	proc_t		*prc_proc;	/* process being traced */
79 	kthread_t	*prc_thread;	/* thread (lwp) being traced */
80 	int		prc_slot;	/* procdir slot number */
81 	id_t		prc_tid;	/* thread (lwp) id */
82 	int		prc_tslot;	/* lwpdir slot number, -1 if reaped */
83 	int		prc_refcnt;	/* this structure's reference count */
84 	struct pollhead	prc_pollhead;	/* list of all pollers */
85 } prcommon_t;
86 
87 /* prc_flags */
88 #define	PRC_DESTROY	0x01	/* process or lwp is being destroyed */
89 #define	PRC_LWP		0x02	/* structure refers to an lwp */
90 #define	PRC_SYS		0x04	/* process is a system process */
91 #define	PRC_POLL	0x08	/* poll() in progress on this process/lwp */
92 #define	PRC_EXCL	0x10	/* exclusive access granted (old /proc) */
93 
94 /*
95  * Macros for mapping between i-numbers and pids.
96  */
97 #define	pmkino(tslot, pslot, nodetype)		\
98 	(((((ino_t)(tslot) << nproc_highbit) |	\
99 	(ino_t)(pslot)) << 6) |			\
100 	(nodetype) + 2)
101 
102 /* for old /proc interface */
103 #define	PRBIAS	64
104 #define	ptoi(n) ((int)(((n) + PRBIAS)))		/* pid to i-number */
105 
106 /*
107  * Node types for /proc files (directories and files contained therein).
108  */
109 typedef enum prnodetype {
110 	PR_PROCDIR,		/* /proc				*/
111 	PR_SELF,		/* /proc/self				*/
112 	PR_PIDDIR,		/* /proc/<pid>				*/
113 	PR_AS,			/* /proc/<pid>/as			*/
114 	PR_CTL,			/* /proc/<pid>/ctl			*/
115 	PR_STATUS,		/* /proc/<pid>/status			*/
116 	PR_LSTATUS,		/* /proc/<pid>/lstatus			*/
117 	PR_PSINFO,		/* /proc/<pid>/psinfo			*/
118 	PR_LPSINFO,		/* /proc/<pid>/lpsinfo			*/
119 	PR_MAP,			/* /proc/<pid>/map			*/
120 	PR_RMAP,		/* /proc/<pid>/rmap			*/
121 	PR_XMAP,		/* /proc/<pid>/xmap			*/
122 	PR_CRED,		/* /proc/<pid>/cred			*/
123 	PR_SIGACT,		/* /proc/<pid>/sigact			*/
124 	PR_AUXV,		/* /proc/<pid>/auxv			*/
125 #if defined(__i386) || defined(__amd64)
126 	PR_LDT,			/* /proc/<pid>/ldt			*/
127 #endif
128 	PR_USAGE,		/* /proc/<pid>/usage			*/
129 	PR_LUSAGE,		/* /proc/<pid>/lusage			*/
130 	PR_PAGEDATA,		/* /proc/<pid>/pagedata			*/
131 	PR_WATCH,		/* /proc/<pid>/watch			*/
132 	PR_CURDIR,		/* /proc/<pid>/cwd			*/
133 	PR_ROOTDIR,		/* /proc/<pid>/root			*/
134 	PR_FDDIR,		/* /proc/<pid>/fd			*/
135 	PR_FD,			/* /proc/<pid>/fd/nn			*/
136 	PR_FDINFODIR,		/* /proc/<pid>/fdinfo			*/
137 	PR_FDINFO,		/* /proc/<pid>/fdinfo/nn		*/
138 	PR_OBJECTDIR,		/* /proc/<pid>/object			*/
139 	PR_OBJECT,		/* /proc/<pid>/object/xxx		*/
140 	PR_LWPDIR,		/* /proc/<pid>/lwp			*/
141 	PR_LWPIDDIR,		/* /proc/<pid>/lwp/<lwpid>		*/
142 	PR_LWPCTL,		/* /proc/<pid>/lwp/<lwpid>/lwpctl	*/
143 	PR_LWPNAME,		/* /proc/<pid>/lwp/<lwpid>/lwpname	*/
144 	PR_LWPSTATUS,		/* /proc/<pid>/lwp/<lwpid>/lwpstatus	*/
145 	PR_LWPSINFO,		/* /proc/<pid>/lwp/<lwpid>/lwpsinfo	*/
146 	PR_LWPUSAGE,		/* /proc/<pid>/lwp/<lwpid>/lwpusage	*/
147 	PR_XREGS,		/* /proc/<pid>/lwp/<lwpid>/xregs	*/
148 	PR_TMPLDIR,		/* /proc/<pid>/lwp/<lwpid>/templates	*/
149 	PR_TMPL,		/* /proc/<pid>/lwp/<lwpid>/templates/<id> */
150 	PR_SPYMASTER,		/* /proc/<pid>/lwp/<lwpid>/spymaster	*/
151 #if defined(__sparc)
152 	PR_GWINDOWS,		/* /proc/<pid>/lwp/<lwpid>/gwindows	*/
153 	PR_ASRS,		/* /proc/<pid>/lwp/<lwpid>/asrs		*/
154 #endif
155 	PR_PRIV,		/* /proc/<pid>/priv			*/
156 	PR_PATHDIR,		/* /proc/<pid>/path			*/
157 	PR_PATH,		/* /proc/<pid>/path/xxx			*/
158 	PR_CTDIR,		/* /proc/<pid>/contracts		*/
159 	PR_CT,			/* /proc/<pid>/contracts/<ctid>		*/
160 	PR_SECFLAGS,		/* /proc/<pid>/secflags			*/
161 	PR_PIDFILE,		/* old process file			*/
162 	PR_LWPIDFILE,		/* old lwp file				*/
163 	PR_OPAGEDATA,		/* old page data file			*/
164 	PR_NFILES		/* number of /proc node types		*/
165 } prnodetype_t;
166 
167 typedef struct prnode {
168 	vnode_t		*pr_next;	/* list of all vnodes for process */
169 	uint_t		pr_flags;	/* private flags */
170 	kmutex_t	pr_mutex;	/* locks pr_files and child pr_flags */
171 	prnodetype_t	pr_type;	/* node type */
172 	mode_t		pr_mode;	/* file mode */
173 	ino_t		pr_ino;		/* node id (for stat(2)) */
174 	uint_t		pr_hatid;	/* hat layer id for page data files */
175 	prcommon_t	*pr_common;	/* common data structure */
176 	prcommon_t	*pr_pcommon;	/* process common data structure */
177 	vnode_t		*pr_parent;	/* parent directory */
178 	vnode_t		**pr_files;	/* contained files array (directory) */
179 	uint_t		pr_index;	/* position within parent */
180 	vnode_t		*pr_pidfile;	/* substitute vnode for old /proc */
181 	vnode_t		*pr_realvp;	/* real vnode, file in object,fd dirs */
182 	proc_t		*pr_owner;	/* the process that created this node */
183 	vnode_t		*pr_vnode;	/* pointer to vnode */
184 	struct contract *pr_contract;	/* contract pointer */
185 	int		pr_cttype;	/* active template type */
186 } prnode_t;
187 
188 /*
189  * Values for pr_flags.
190  */
191 #define	PR_INVAL	0x01		/* vnode is invalidated */
192 #define	PR_ISSELF	0x02		/* vnode is a self-open */
193 #define	PR_AOUT		0x04		/* vnode is for an a.out path */
194 #define	PR_OFFMAX	0x08		/* vnode is a large file open */
195 
196 /*
197  * Conversion macros.
198  */
199 #define	VTOP(vp)	((struct prnode *)(vp)->v_data)
200 #define	PTOV(pnp)	((pnp)->pr_vnode)
201 
202 /*
203  * Flags to prlock().
204  */
205 #define	ZNO	0	/* Fail on encountering a zombie process. */
206 #define	ZYES	1	/* Allow zombies. */
207 
208 /*
209  * Assign one set to another (possible different sizes).
210  *
211  * Assigning to a smaller set causes members to be lost.
212  * Assigning to a larger set causes extra members to be cleared.
213  */
214 #define	prassignset(ap, sp)					\
215 {								\
216 	register int _i_ = sizeof (*(ap))/sizeof (uint32_t);	\
217 	while (--_i_ >= 0)					\
218 		((uint32_t *)(ap))[_i_] =			\
219 		    (_i_ >= sizeof (*(sp))/sizeof (uint32_t)) ?	\
220 		    0 : ((uint32_t *)(sp))[_i_];		\
221 }
222 
223 /*
224  * Determine whether or not a set (of arbitrary size) is empty.
225  */
226 #define	prisempty(sp) \
227 	setisempty((uint32_t *)(sp), \
228 		(uint_t)(sizeof (*(sp)) / sizeof (uint32_t)))
229 
230 /*
231  * Resource usage with times as hrtime_t rather than timestruc_t.
232  * Each member exactly matches the corresponding member in prusage_t.
233  * This is for convenience of internal computation.
234  */
235 typedef struct prhusage {
236 	id_t		pr_lwpid;	/* lwp id.  0: process or defunct */
237 	int		pr_count;	/* number of contributing lwps */
238 	hrtime_t	pr_tstamp;	/* current time stamp */
239 	hrtime_t	pr_create;	/* process/lwp creation time stamp */
240 	hrtime_t	pr_term;	/* process/lwp termination time stamp */
241 	hrtime_t	pr_rtime;	/* total lwp real (elapsed) time */
242 	hrtime_t	pr_utime;	/* user level CPU time */
243 	hrtime_t	pr_stime;	/* system call CPU time */
244 	hrtime_t	pr_ttime;	/* other system trap CPU time */
245 	hrtime_t	pr_tftime;	/* text page fault sleep time */
246 	hrtime_t	pr_dftime;	/* data page fault sleep time */
247 	hrtime_t	pr_kftime;	/* kernel page fault sleep time */
248 	hrtime_t	pr_ltime;	/* user lock wait sleep time */
249 	hrtime_t	pr_slptime;	/* all other sleep time */
250 	hrtime_t	pr_wtime;	/* wait-cpu (latency) time */
251 	hrtime_t	pr_stoptime;	/* stopped time */
252 	hrtime_t	filltime[6];	/* filler for future expansion */
253 	uint64_t	pr_minf;	/* minor page faults */
254 	uint64_t	pr_majf;	/* major page faults */
255 	uint64_t	pr_nswap;	/* swaps */
256 	uint64_t	pr_inblk;	/* input blocks */
257 	uint64_t	pr_oublk;	/* output blocks */
258 	uint64_t	pr_msnd;	/* messages sent */
259 	uint64_t	pr_mrcv;	/* messages received */
260 	uint64_t	pr_sigs;	/* signals received */
261 	uint64_t	pr_vctx;	/* voluntary context switches */
262 	uint64_t	pr_ictx;	/* involuntary context switches */
263 	uint64_t	pr_sysc;	/* system calls */
264 	uint64_t	pr_ioch;	/* chars read and written */
265 	uint64_t	filler[10];	/* filler for future expansion */
266 } prhusage_t;
267 
268 #if defined(_KERNEL)
269 
270 /* Exclude system processes from this test */
271 #define	PROCESS_NOT_32BIT(p)	\
272 	(!((p)->p_flag & SSYS) && (p)->p_as != &kas && \
273 	(p)->p_model != DATAMODEL_ILP32)
274 
275 extern	int	prnwatch;	/* number of supported watchpoints */
276 extern	int	nproc_highbit;	/* highbit(v.v_nproc) */
277 
278 extern	struct vnodeops	*prvnodeops;
279 
280 /*
281  * Generic chained copyout buffers for procfs use.
282  * In order to prevent procfs from making huge oversize kmem_alloc calls,
283  * a list of smaller buffers can be concatenated and copied to userspace in
284  * sequence.
285  *
286  * The implementation is opaque.
287  *
288  * A user of this will perform the following steps:
289  *
290  *	list_t	listhead;
291  *	struct my *mp;
292  *
293  *	pr_iol_initlist(&listhead, sizeof (*mp), n);
294  *	while (whatever) {
295  *		mp = pr_iol_newbuf(&listhead, sizeof (*mp));
296  *		...
297  *		error = ...
298  *	}
299  *
300  * When done, depending on whether copyout() or uiomove() is supposed to
301  * be used for transferring the buffered data to userspace, call either:
302  *
303  *	error = pr_iol_copyout_and_free(&listhead, &cmaddr, error);
304  *
305  * or else:
306  *
307  *	error = pr_iol_uiomove_and_free(&listhead, uiop, error);
308  *
309  * These two functions will in any case kmem_free() all list items, but
310  * if an error occurred before they will not perform the copyout/uiomove.
311  * If copyout/uiomove are done, the passed target address / uio_t
312  * are updated. The error returned will either be the one passed in, or
313  * the error that occurred during copyout/uiomove.
314  */
315 
316 extern	void	pr_iol_initlist(list_t *head, size_t itemsize, int nitems);
317 extern	void *	pr_iol_newbuf(list_t *head, size_t itemsize);
318 extern	int	pr_iol_copyout_and_free(list_t *head, caddr_t *tgt, int errin);
319 extern	int	pr_iol_uiomove_and_free(list_t *head, uio_t *uiop, int errin);
320 extern	void	pr_iol_freelist(list_t *);
321 
322 #if defined(_SYSCALL32_IMPL)
323 
324 extern	int	prwritectl32(vnode_t *, struct uio *, cred_t *);
325 extern	void	prgetaction32(proc_t *, user_t *, uint_t, struct sigaction32 *);
326 extern	void	prcvtusage32(struct prhusage *, prusage32_t *);
327 
328 #endif	/* _SYSCALL32_IMPL */
329 
330 /* kludge to support old /proc interface */
331 #if !defined(_SYS_OLD_PROCFS_H)
332 extern	int	prgetmap(proc_t *, int, list_t *);
333 extern	int	prgetxmap(proc_t *, list_t *);
334 #if defined(_SYSCALL32_IMPL)
335 extern	int	prgetmap32(proc_t *, int, list_t *);
336 extern	int	prgetxmap32(proc_t *, list_t *);
337 #endif	/* _SYSCALL32_IMPL */
338 #endif /* !_SYS_OLD_PROCFS_H */
339 
340 extern	proc_t	*pr_p_lock(prnode_t *);
341 extern	kthread_t *pr_thread(prnode_t *);
342 extern	void	pr_stop(prnode_t *);
343 extern	int	pr_wait_stop(prnode_t *, time_t);
344 extern	int	pr_setrun(prnode_t *, ulong_t);
345 extern	int	pr_wait(prcommon_t *, timestruc_t *, int);
346 extern	void	pr_wait_die(prnode_t *);
347 extern	int	pr_setsig(prnode_t *, siginfo_t *);
348 extern	int	pr_kill(prnode_t *, int, cred_t *);
349 extern	int	pr_unkill(prnode_t *, int);
350 extern	int	pr_nice(proc_t *, int, cred_t *);
351 extern	void	pr_setentryexit(proc_t *, sysset_t *, int);
352 extern	int	pr_set(proc_t *, long);
353 extern	int	pr_unset(proc_t *, long);
354 extern	void	pr_sethold(prnode_t *, sigset_t *);
355 extern	file_t	*pr_getf(proc_t *, uint_t, short *);
356 extern	void	pr_releasef(file_t *);
357 extern	void	pr_setfault(proc_t *, fltset_t *);
358 extern	int	prusrio(proc_t *, enum uio_rw, struct uio *, int);
359 extern	int	prwritectl(vnode_t *, struct uio *, cred_t *);
360 extern	int	prlock(prnode_t *, int);
361 extern	void	prunmark(proc_t *);
362 extern	void	prunlock(prnode_t *);
363 extern	size_t	prpdsize(struct as *);
364 extern	int	prpdread(proc_t *, uint_t, struct uio *);
365 extern	size_t	oprpdsize(struct as *);
366 extern	int	oprpdread(struct as *, uint_t, struct uio *);
367 extern	void	prgetaction(proc_t *, user_t *, uint_t, struct sigaction *);
368 extern	void	prgetusage(kthread_t *, struct prhusage *);
369 extern	void	praddusage(kthread_t *, struct prhusage *);
370 extern	void	prcvtusage(struct prhusage *, prusage_t *);
371 extern	void	prscaleusage(prhusage_t *);
372 extern	kthread_t *prchoose(proc_t *);
373 extern	void	allsetrun(proc_t *);
374 extern	int	setisempty(uint32_t *, uint_t);
375 extern	int	pr_u32tos(uint32_t, char *, int);
376 extern	vnode_t	*prlwpnode(prnode_t *, uint_t);
377 extern	prnode_t *prgetnode(vnode_t *, prnodetype_t);
378 extern	void	prfreenode(prnode_t *);
379 extern	void	pr_object_name(char *, vnode_t *, struct vattr *);
380 extern	int	set_watched_area(proc_t *, struct watched_area *);
381 extern	int	clear_watched_area(proc_t *, struct watched_area *);
382 extern	void	pr_free_watchpoints(proc_t *);
383 extern	proc_t	*pr_cancel_watch(prnode_t *);
384 extern	struct seg *break_seg(proc_t *);
385 extern	void	prgethold(kthread_t *, sigset_t *);
386 
387 /*
388  * Machine-dependent routines (defined in prmachdep.c).
389  */
390 extern	void	prgetprregs(klwp_t *, prgregset_t);
391 extern	void	prsetprregs(klwp_t *, prgregset_t, int);
392 
393 #if defined(_SYSCALL32_IMPL)
394 extern	void	prgetprregs32(klwp_t *, prgregset32_t);
395 extern	void	prgregset_32ton(klwp_t *, prgregset32_t, prgregset_t);
396 extern	void	prgetprfpregs32(klwp_t *, prfpregset32_t *);
397 extern	void	prsetprfpregs32(klwp_t *, prfpregset32_t *);
398 extern	size_t	prpdsize32(struct as *);
399 extern	int	prpdread32(proc_t *, uint_t, struct uio *);
400 extern	size_t	oprpdsize32(struct as *);
401 extern	int	oprpdread32(struct as *, uint_t, struct uio *);
402 #endif	/* _SYSCALL32_IMPL */
403 
404 extern	void	prpokethread(kthread_t *t);
405 extern	int	prgetrvals(klwp_t *, long *, long *);
406 extern	void	prgetprfpregs(klwp_t *, prfpregset_t *);
407 extern	void	prsetprfpregs(klwp_t *, prfpregset_t *);
408 extern	int	prhasfp(void);
409 extern	caddr_t	prgetstackbase(proc_t *);
410 extern	caddr_t	prgetpsaddr(proc_t *);
411 extern	int	prisstep(klwp_t *);
412 extern	void	prsvaddr(klwp_t *, caddr_t);
413 extern	int	prfetchinstr(klwp_t *, ulong_t *);
414 extern	ushort_t prgetpctcpu(uint64_t);
415 
416 /*
417  * This set of routines is used by platforms to implement support for the
418  * 'xregs' or extended registers in /proc. Unlike other registers which
419  * generally have a well-defined value determined by the ABI that never changes,
420  * we expect these to change.
421  *
422  * An important thing to note is that you'll see we have moved away from a
423  * traditional version of a fixed size, non-opaque definition of the
424  * prxregset_t. This is because the size varies and we don't want applications
425  * to incorrectly bake a real definition in and cause problems where extending
426  * it becomes very hard to do (ala the prgregset_t and prfregset_t). This is a
427  * little more work for everyone implementing it, but it does ensure that we are
428  * generally in better shape.
429  *
430  * Here are the semantics of what these are required to do and how the fit
431  * together:
432  *
433  *   o prhasx		Determine if the process in question supports the
434  *			extended register sets. Note, this is may be a
435  *			process-specific setting due to things like whether or
436  *			not the FPU is enabled or other things.
437  *
438  *   o prgetxregsize	This returns the size of the actual xregs file for a
439  *			given process. This may change between processes because
440  *			not every process may have the same set of extended
441  *			features enabled (e.g. AMX on x86). If xregs is not
442  *			supported then this should return 0. If xregs are
443  *			supported, then returning zero will lead other
444  *			operations to fail.
445  *
446  *   o prwriteminxreg	This is used by the prwritectl() and related worlds to
447  *			determine the minimum amount of data that much be
448  *			present to determine if the actual size of a write is
449  *			valid. If xregs is not supported, then this should
450  *			return B_FALSE. If xregs is supported, this may return 0
451  *			if no additional information is required to determine
452  *			the appropriate size to copy in. This would be the case
453  *			if the xregs structure is a fixed size.
454  *
455  *   o prwritesizexreg	This is meant to indicate how much data is required to
456  *			be copied in for a given xregs write. The base data will
457  *			already be present from having called prwriteminxreg
458  *			previously. If xregs are not supported this should
459  *			return B_FALSE.
460  *
461  *			There is a wrinkle in this which is not true of other
462  *			callers. The data that we are given is not guaranteed to
463  *			be aligned in the slightest due to the need to support
464  *			both ILP32 and LP64!
465  *
466  *   o prgetprxregs	This is a request to fill in the xregs data. Right now
467  *			the system guarantees that the buffer size is at least
468  *			the result of the prgetprxregs() call for this process.
469  *			Callers may assume that the process remains locked
470  *			between the two so that the size doesn't change. This
471  *			will not be called for processes where prhasx() return
472  *			false.
473  *
474  *   o prsetprxregs	This is a request to set the xregs data. The only
475  *			assumption that should be made is that the validation of
476  *			the size in prwritesizexreg() has been performed. Users
477  *			can and will potentially try to trick us with invalid
478  *			values. Do not blindly apply the supplied xregs.
479  *
480  *			If xregs are not supported this should return EINVAL.
481  *			While yes other errnos may make more sense, that is what
482  *			we have always returned in /proc for this case.
483  */
484 extern	int	prhasx(proc_t *);
485 extern	size_t	prgetprxregsize(proc_t *);
486 extern	void	prgetprxregs(klwp_t *, prxregset_t *);
487 extern	boolean_t prwriteminxreg(size_t *);
488 extern	boolean_t prwritesizexreg(const void *, size_t *);
489 extern	int	prsetprxregs(klwp_t *, prxregset_t *);
490 
491 #endif	/* _KERNEL */
492 
493 #ifdef	__cplusplus
494 }
495 #endif
496 
497 #endif	/* _SYS_PROC_PRDATA_H */
498