summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/user.h
blob: 9061fa5a2396d2808ffe312ac5c07a9a64841e54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved	*/


#ifndef _SYS_USER_H
#define	_SYS_USER_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <sys/types.h>
#include <sys/signal.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * struct exdata is visible in and out of the kernel. This is because it
 * is referenced in <sys/core.h> which doesn't have this kind of magic.
 */
struct exdata {
	struct vnode	*vp;
	size_t	ux_tsize;	/* text size */
	size_t	ux_dsize;	/* data size */
	size_t	ux_bsize;	/* bss size */
	size_t	ux_lsize;	/* lib size */
	long	ux_nshlibs;	/* number of shared libs needed */
	short	ux_mach;	/* machine type */
	short	ux_mag;		/* magic number MUST be here */
	off_t	ux_toffset;	/* file offset to raw text */
	off_t	ux_doffset;	/* file offset to raw data */
	off_t	ux_loffset;	/* file offset to lib sctn */
	caddr_t	ux_txtorg;	/* start addr of text in mem */
	caddr_t	ux_datorg;	/* start addr of data in mem */
	caddr_t	ux_entloc;	/* entry location */
};

#ifdef	__cplusplus
}
#endif

#if defined(_KERNEL) || defined(_KMEMUSER)

#include <sys/param.h>
#include <sys/pcb.h>
#include <sys/siginfo.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/auxv.h>
#include <sys/errno.h>
#include <sys/t_lock.h>
#include <sys/refstr.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Entry in the per-process list of open files.
 * Note: only certain fields are copied in flist_grow() and flist_fork().
 * This is indicated in brackets in the structure member comments.
 */
typedef struct uf_entry {
	kmutex_t	uf_lock;	/* per-fd lock [never copied] */
	struct file	*uf_file;	/* file pointer [grow, fork] */
	struct fpollinfo *uf_fpollinfo;	/* poll state [grow] */
	int		uf_refcnt;	/* LWPs accessing this file [grow] */
	int		uf_alloc;	/* right subtree allocs [grow, fork] */
	short		uf_flag;	/* fcntl F_GETFD flags [grow, fork] */
	short		uf_busy;	/* file is allocated [grow, fork] */
	kcondvar_t	uf_wanted_cv;	/* waiting for setf() [never copied] */
	kcondvar_t	uf_closing_cv;	/* waiting for close() [never copied] */
	struct portfd 	*uf_portfd;	/* associated with port [grow] */
	/* Avoid false sharing - pad to coherency granularity (64 bytes) */
	char		uf_pad[64 - sizeof (kmutex_t) - 2 * sizeof (void*) -
		2 * sizeof (int) - 2 * sizeof (short) -
		2 * sizeof (kcondvar_t) - sizeof (struct portfd *)];
} uf_entry_t;

/*
 * Retired file lists -- see flist_grow() for details.
 */
typedef struct uf_rlist {
	struct uf_rlist	*ur_next;
	uf_entry_t	*ur_list;
	int		ur_nfiles;
} uf_rlist_t;

/*
 * Per-process file information.
 */
typedef struct uf_info {
	kmutex_t	fi_lock;	/* see below */
	int		fi_badfd;	/* bad file descriptor # */
	int		fi_action;	/* action to take on bad fd use */
	int		fi_nfiles;	/* number of entries in fi_list[] */
	uf_entry_t *volatile fi_list;	/* current file list */
	uf_rlist_t	*fi_rlist;	/* retired file lists */
} uf_info_t;

/*
 * File list locking.
 *
 * Each process has a list of open files, fi_list, indexed by fd.
 * fi_list is an array of uf_entry_t structures, each with its own lock.
 * One might think that the correct way to lock a file descriptor would be:
 *
 *	ufp = fip->fi_list[fd];
 *	mutex_enter(&ufp->uf_lock);
 *
 * However, that construct is only safe if fi_lock is already held.  If not,
 * fi_list can change in the window between loading ufp and entering uf_lock.
 * The UF_ENTER() macro deals with this possibility.  UF_ENTER(ufp, fip, fd)
 * locks fd and sets ufp to fd's uf_entry.  The locking rules are as follows:
 *
 * (1) fi_lock protects fi_list and fi_nfiles.  It also protects the
 *     uf_alloc and uf_busy fields of every fd's ufp; see fd_find() for
 *     details on file descriptor allocation.
 *
 * (2) UF_ENTER(ufp, fip, fd) locks descriptor fd and sets ufp to point
 *     to the uf_entry_t for fd.  UF_ENTER() protects all fields in ufp
 *     except uf_alloc and uf_busy.  UF_ENTER(ufp, fip, fd) also prevents
 *     ufp->uf_alloc, ufp->uf_busy, fip->fi_list and fip->fi_nfiles from
 *     changing.
 *
 * (3) The lock ordering is (1), (2).
 *
 * (4) Note that fip->fi_list and fip->fi_nfiles cannot change while *any*
 *     file list lock is held.  Thus flist_grow() must acquire all such
 *     locks -- fi_lock and every fd's uf_lock -- to install a new file list.
 */
#define	UF_ENTER(ufp, fip, fd)					\
	for (;;) {						\
		uf_entry_t *_flist = (fip)->fi_list;		\
		ufp = &_flist[fd];				\
		ASSERT((fd) < (fip)->fi_nfiles);		\
		mutex_enter(&ufp->uf_lock);			\
		if (_flist == (fip)->fi_list)			\
			break;					\
		mutex_exit(&ufp->uf_lock);			\
	}

#define	UF_EXIT(ufp)	mutex_exit(&ufp->uf_lock)

#define	PSARGSZ		80	/* Space for exec arguments (used by ps(1)) */
#define	MAXCOMLEN	16	/* <= MAXNAMLEN, >= sizeof (ac_comm) */

typedef struct {		/* kernel syscall set type */
	uint_t	word[9];	/* space for syscall numbers [1..288] */
} k_sysset_t;

/*
 * __KERN_NAUXV_IMPL is defined as a convenience sizing mechanism
 * for the portions of the kernel that care about aux vectors.
 *
 * Applications that need to know how many aux vectors the kernel
 * supplies should use the proc(4) interface to read /proc/PID/auxv.
 *
 * This value should not be changed in a patch.
 */
#if defined(__sparc)
#define	__KERN_NAUXV_IMPL 19
#elif defined(__i386) || defined(__amd64)
#define	__KERN_NAUXV_IMPL 21
#endif

struct execsw;

/*
 * The user structure; one allocated per process.  Contains all the
 * per-process data that doesn't need to be referenced while the
 * process is swapped.
 */
typedef	struct	user {
	/*
	 * These fields are initialized at process creation time and never
	 * modified.  They can be accessed without acquiring locks.
	 */
	struct execsw *u_execsw;	/* pointer to exec switch entry */
	auxv_t  u_auxv[__KERN_NAUXV_IMPL]; /* aux vector from exec */
	timestruc_t u_start;		/* hrestime at process start */
	clock_t	u_ticks;		/* lbolt at process start */
	char	u_comm[MAXCOMLEN + 1];	/* executable file name from exec */
	char	u_psargs[PSARGSZ];	/* arguments from exec */
	int	u_argc;			/* value of argc passed to main() */
	uintptr_t u_argv;		/* value of argv passed to main() */
	uintptr_t u_envp;		/* value of envp passed to main() */

	/*
	 * These fields are protected by p_lock:
	 */
	struct vnode *u_cdir;		/* current directory */
	struct vnode *u_rdir;		/* root directory */
	uint64_t u_mem;			/* accumulated memory usage */
	size_t	u_mem_max;		/* peak RSS (K) */
	mode_t	u_cmask;		/* mask for file creation */
	char	u_acflag;		/* accounting flag */
	char	u_systrap;		/* /proc: any syscall mask bits set? */
	refstr_t *u_cwd;		/* cached string for cwd */

	k_sysset_t u_entrymask;		/* /proc syscall stop-on-entry mask */
	k_sysset_t u_exitmask;		/* /proc syscall stop-on-exit mask */
	k_sigset_t u_signodefer;	/* signals defered when caught */
	k_sigset_t u_sigonstack;	/* signals taken on alternate stack */
	k_sigset_t u_sigresethand;	/* signals reset when caught */
	k_sigset_t u_sigrestart;	/* signals that restart system calls */
	k_sigset_t u_sigmask[MAXSIG];	/* signals held while in catcher */
	void	(*u_signal[MAXSIG])();	/* Disposition of signals */

	/*
	 * Resource controls provide the backend for process resource limits,
	 * the interfaces for which are maintained for compatibility.  To
	 * preserve the behaviour associated with the RLIM_SAVED_CUR and
	 * RLIM_SAVED_MAX tokens, we retain the "saved" rlimits.
	 */
	struct rlimit64	u_saved_rlimit[RLIM_NSAVED];

	uf_info_t	u_finfo;	/* open file information */
} user_t;

#include <sys/proc.h>			/* cannot include before user defined */

#ifdef	_KERNEL
#define	P_FINFO(p)	(&(p)->p_user.u_finfo)
#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#else	/* defined(_KERNEL) || defined(_KMEMUSER) */

/*
 * Here, we define a fake version of struct user for programs
 * (debuggers) that use ptrace() to read and modify the saved
 * registers directly in the u-area.  ptrace() has been removed
 * from the operating system and now exists as a library function
 * in libc, built on the /proc process filesystem.  The ptrace()
 * library function provides access only to the members of the
 * fake struct user defined here.
 *
 * User-level programs that must know the real contents of struct
 * user will have to define _KMEMUSER before including <sys/user.h>.
 * Such programs also become machine specific. Carefully consider
 * the consequences of your actions.
 */

#include <sys/regset.h>

#ifdef	__cplusplus
extern "C" {
#endif

#define	PSARGSZ		80	/* Space for exec arguments (used by ps(1)) */

typedef	struct	user {
	gregset_t	u_reg;		/* user's saved registers */
	greg_t		*u_ar0;		/* address of user's saved R0 */
	char	u_psargs[PSARGSZ];	/* arguments from exec */
	void	(*u_signal[MAXSIG])();	/* Disposition of signals */
	int		u_code;		/* fault code on trap */
	caddr_t		u_addr;		/* fault PC on trap */
} user_t;

#ifdef	__cplusplus
}
#endif

#endif	/* defined(_KERNEL) || defined(_KMEMUSER) */

#endif	/* _SYS_USER_H */