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 30 extern "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 */ 179 extern void s10_runexe(void *, ulong_t); 180 181 /* 182 * From s10_handler.s 183 */ 184 extern void s10_handler_table(void); 185 extern void s10_handler(void); 186 extern void s10_error(void); 187 extern void s10_success(void); 188 189 /* 190 * From s10_brand.c 191 */ 192 extern void _s10_abort(int, const char *, const char *, int); 193 extern int s10_uucopy(const void *, void *, size_t); 194 extern int s10_uucopystr(const void *, void *, size_t); 195 196 /* 197 * From s10_deleted.c 198 */ 199 extern int s10_stat(); 200 extern int s10_lstat(); 201 extern int s10_fstat(); 202 extern int s10_stat64(); 203 extern int s10_lstat64(); 204 extern int s10_fstat64(); 205 extern int s10_open(); 206 extern int s10_open64(); 207 extern int s10_chown(); 208 extern int s10_lchown(); 209 extern int s10_fchown(); 210 extern int s10_unlink(); 211 extern int s10_rmdir(); 212 extern int s10_rename(); 213 extern int s10_access(); 214 extern int s10_creat(); 215 extern int s10_creat64(); 216 extern int s10_fork1(); 217 extern int s10_forkall(); 218 extern int s10_dup(); 219 extern int s10_poll(); 220 extern int s10_lwp_mutex_lock(); 221 extern int s10_lwp_sema_wait(); 222 extern int s10_utime(); 223 extern int s10_utimes(); 224 extern int s10_xstat(); 225 extern int s10_lxstat(); 226 extern int s10_fxstat(); 227 extern int s10_xmknod(); 228 extern int s10_fsat(); 229 extern int s10_umount(); 230 231 /* 232 * From s10_signal.c 233 */ 234 extern int s10sigset_to_native(const sigset_t *, sigset_t *); 235 236 extern int s10_kill(); 237 extern int s10_lwp_create(); 238 extern int s10_lwp_kill(); 239 extern int s10_lwp_sigmask(); 240 extern int s10_sigaction(); 241 extern int s10_signotify(); 242 extern int s10_sigpending(); 243 extern int s10_sigprocmask(); 244 extern int s10_sigqueue(); 245 extern int s10_sigsendsys(); 246 extern int s10_sigsuspend(); 247 extern int s10_sigtimedwait(); 248 extern int s10_wait(); 249 extern int s10_waitid(); 250 251 #endif /* !_ASM */ 252 253 #ifdef __cplusplus 254 } 255 #endif 256 257 #endif /* _S10_MISC_H */ 258