s10_misc.h revision 11913:283e725df792
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 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef _S10_MISC_H
27#define	_S10_MISC_H
28
29#ifdef	__cplusplus
30extern "C" {
31#endif
32
33/*
34 * This header file must uses _ASM defines to allow it to be included
35 * in assmebly source files
36 */
37#include <sys/asm_linkage.h>
38#include <sys/regset.h>
39#include <sys/syscall.h>
40#include "assym.h"
41
42/*
43 * Our syscall emulation callback handler adds one argument to each
44 * system call, so we'll need to allocate space for one more argument
45 * above the maximum number of arguments that a system call can normally
46 * take.  Also, we assume that each syscall argument is a long, ie, we
47 * don't support long long syscall parameters.
48 */
49#if defined(__sparc)
50/*
51 * 32-bit and 64-bit sparc syscalls can take up to 8 arguments.
52 * 32-bit sparc indirect syscalls can take up to 9 arguments.
53 * Arguments 1 - 6 are passed via %o0 - %o5.
54 * Additional arguments are passed on the stack.
55 * So make space for 4 arguments on the stack.
56 */
57#define	EH_ARGS_COUNT		4
58#elif defined(__amd64)
59/*
60 * amd64 syscalls can take up to 8 arguments.
61 * Arguments 1 - 6 are passed via: %rdi, %rsi, %rdx, %r10, %r8, %r9
62 * Additional arguments are passed on the stack.
63 * So make space for 3 arguments on the stack.
64 */
65#define	EH_ARGS_COUNT		3
66#else /* !__sparc && !__amd64 */
67/*
68 * ia32 syscalls can take up to 8 arguments.
69 * All arguments are passed on the stack.
70 * So make space for 9 arguments on the stack.
71 */
72#define	EH_ARGS_COUNT		9
73#endif /* !__sparc && !__amd64 */
74
75
76#define	EH_ARGS_SIZE		(CPTRSIZE * EH_ARGS_COUNT)
77#define	EH_ARGS_OFFSET(x)	(STACK_BIAS + MINFRAME + (CPTRSIZE * (x)))
78#define	EH_LOCALS_SIZE		(EH_ARGS_SIZE + SIZEOF_GREGSET_T + \
79				    SIZEOF_SYSRET_T + CPTRSIZE)
80
81#if defined(__sparc)
82/*
83 * On sparc, all emulation callback handler variable access is done
84 * relative to %sp, so access offsets are positive.
85 */
86#define	EH_LOCALS_START		(STACK_BIAS + MINFRAME + EH_ARGS_SIZE)
87#define	EH_LOCALS_END_TGT	(STACK_BIAS + MINFRAME + EH_LOCALS_SIZE)
88#else /* !__sparc */
89/*
90 * On x86, all emulation callback handler variable access is done
91 * relative to %ebp/%rbp, so access offsets are negative.
92 */
93#define	EH_LOCALS_START		(-(EH_LOCALS_SIZE - \
94				    (STACK_BIAS + MINFRAME + EH_ARGS_SIZE)))
95#define	EH_LOCALS_END_TGT	0
96#endif /* !__sparc */
97
98/*
99 * In our emulation callback handler, our stack will look like:
100 *		-------------------------------------------------
101 *	  %bp   | long		rvflag				|
102 *	   |    | sysret_t	sysret				|
103 *	   v    | gregset_t	gregs				|
104 *	  %sp   | long		callback args[EH_ARGS_COUNT]	|
105 *		-------------------------------------------------
106 * For ia32, use %ebp and %esp instead of %bp and %sp.
107 * For amd64, use %rbp and %rsp instead of %bp and %sp.
108 *
109 * Our emulation callback handler always saves enough space to hold the
110 * maximum number of stack arguments to a system call.  This is architecture
111 * specific and is defined via EH_ARGS_COUNT.
112 */
113#define	EH_LOCALS_GREGS		(EH_LOCALS_START)
114#define	EH_LOCALS_GREG(x)	(EH_LOCALS_GREGS + (SIZEOF_GREG_T * (x)))
115#define	EH_LOCALS_SYSRET	(EH_LOCALS_GREGS + SIZEOF_GREGSET_T)
116#define	EH_LOCALS_SYSRET1	(EH_LOCALS_SYSRET)
117#define	EH_LOCALS_SYSRET2	(EH_LOCALS_SYSRET + CPTRSIZE)
118#define	EH_LOCALS_RVFLAG	(EH_LOCALS_SYSRET + SIZEOF_SYSRET_T)
119#define	EH_LOCALS_END		(EH_LOCALS_RVFLAG + CPTRSIZE)
120
121#if (EH_LOCALS_END != EH_LOCALS_END_TGT)
122#error "s10_misc.h EH_LOCALS_* macros don't add up"
123#endif /* (EH_LOCALS_END != EH_LOCALS_END_TGT) */
124
125/*
126 * The second parameter of each entry in the s10_sysent_table
127 * contains the number of parameters and flags that describe the
128 * syscall return value encoding.  See the block comments at the
129 * top of ../common/s10_brand.c for more information about the
130 * syscall return value flags and when they should be used.
131 */
132#define	NARGS_MASK	0x000000FF	/* Mask for syscalls argument count */
133#define	RV_MASK		0x0000FF00	/* Mask for return value flags */
134#define	RV_DEFAULT	0x00000100	/* syscall returns "default" values */
135#define	RV_32RVAL2	0x00000200	/* syscall returns two 32-bit values */
136#define	RV_64RVAL	0x00000400	/* syscall returns a 64-bit value */
137
138#if !defined(_ASM)
139
140/*
141 * We define our own version of assert because the default one will
142 * try to emit a localized message.  That is bad because first, we can't
143 * emit messages to random file descriptors, and second localizing a message
144 * requires allocating memory and we can't do that either.
145 */
146#define	s10_assert(ex)	(void)((ex) || \
147				(_s10_abort(0, #ex, __FILE__, __LINE__), 0))
148#define	s10_abort(err, msg)	_s10_abort((err), (msg), __FILE__, __LINE__)
149
150/*
151 * These macros invoke a brandsys subcommand, B_S10_TRUSS_POINT, used to expose
152 * a call to an interpositioned syscall that would have otherwise gone
153 * unnoticed by truss(1) because the interpositioned system call did not call
154 * any system calls before returning.
155 */
156#define	S10_TRUSS_POINT_5(rval, syscall_num, err, a0, a1, a2, a3, a4) \
157	__systemcall(rval, SYS_brand + 1024, \
158	    B_S10_TRUSS_POINT, (syscall_num), (err), (a0), (a1), (a2), (a3), \
159	    (a4))
160
161#define	S10_TRUSS_POINT_4(rval, syscall_num, err, a0, a1, a2, a3) \
162	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), (a3), 0)
163
164#define	S10_TRUSS_POINT_3(rval, syscall_num, err, a0, a1, a2) \
165	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), 0, 0)
166
167#define	S10_TRUSS_POINT_2(rval, syscall_num, err, a0, a1) \
168	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), 0, 0, 0)
169
170#define	S10_TRUSS_POINT_1(rval, syscall_num, err, a0) \
171	S10_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), 0, 0, 0, 0)
172
173#define	S10_TRUSS_POINT_0(rval, syscall_num, err) \
174	S10_TRUSS_POINT_5(rval, (syscall_num), (err), 0, 0, 0, 0, 0)
175
176/*
177 * From s10_runexe.s
178 */
179extern void s10_runexe(void *, ulong_t);
180
181/*
182 * From s10_handler.s
183 */
184extern void s10_handler_table(void);
185extern void s10_handler(void);
186extern void s10_error(void);
187extern void s10_success(void);
188
189/*
190 * From s10_brand.c
191 */
192extern void _s10_abort(int, const char *, const char *, int);
193extern int s10_uucopy(const void *, void *, size_t);
194extern int s10_uucopystr(const void *, void *, size_t);
195
196/*
197 * From s10_deleted.c
198 */
199extern int s10_stat();
200extern int s10_lstat();
201extern int s10_fstat();
202extern int s10_stat64();
203extern int s10_lstat64();
204extern int s10_fstat64();
205extern int s10_open();
206extern int s10_open64();
207extern int s10_chown();
208extern int s10_lchown();
209extern int s10_fchown();
210extern int s10_unlink();
211extern int s10_rmdir();
212extern int s10_rename();
213extern int s10_access();
214extern int s10_creat();
215extern int s10_creat64();
216extern int s10_fork1();
217extern int s10_forkall();
218extern int s10_dup();
219extern int s10_poll();
220extern int s10_lwp_mutex_lock();
221extern int s10_lwp_sema_wait();
222extern int s10_utime();
223extern int s10_utimes();
224extern int s10_xstat();
225extern int s10_lxstat();
226extern int s10_fxstat();
227extern int s10_xmknod();
228extern int s10_fsat();
229extern int s10_umount();
230
231/*
232 * From s10_signal.c
233 */
234extern int s10sigset_to_native(const sigset_t *, sigset_t *);
235
236extern int s10_context();
237extern int s10_kill();
238extern int s10_lwp_create();
239extern int s10_lwp_kill();
240extern int s10_lwp_sigmask();
241extern int s10_sigaction();
242extern int s10_signotify();
243extern int s10_sigpending();
244extern int s10_sigprocmask();
245extern int s10_sigqueue();
246extern int s10_sigsendsys();
247extern int s10_sigsuspend();
248extern int s10_sigtimedwait();
249extern int s10_wait();
250extern int s10_waitid();
251
252#endif	/* !_ASM */
253
254#ifdef	__cplusplus
255}
256#endif
257
258#endif	/* _S10_MISC_H */
259