1628e3cbeSEdward Pilatowicz /* 2628e3cbeSEdward Pilatowicz * CDDL HEADER START 3628e3cbeSEdward Pilatowicz * 4628e3cbeSEdward Pilatowicz * The contents of this file are subject to the terms of the 5628e3cbeSEdward Pilatowicz * Common Development and Distribution License (the "License"). 6628e3cbeSEdward Pilatowicz * You may not use this file except in compliance with the License. 7628e3cbeSEdward Pilatowicz * 8628e3cbeSEdward Pilatowicz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9628e3cbeSEdward Pilatowicz * or http://www.opensolaris.org/os/licensing. 10628e3cbeSEdward Pilatowicz * See the License for the specific language governing permissions 11628e3cbeSEdward Pilatowicz * and limitations under the License. 12628e3cbeSEdward Pilatowicz * 13628e3cbeSEdward Pilatowicz * When distributing Covered Code, include this CDDL HEADER in each 14628e3cbeSEdward Pilatowicz * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15628e3cbeSEdward Pilatowicz * If applicable, add the following below this CDDL HEADER, with the 16628e3cbeSEdward Pilatowicz * fields enclosed by brackets "[]" replaced with your own identifying 17628e3cbeSEdward Pilatowicz * information: Portions Copyright [yyyy] [name of copyright owner] 18628e3cbeSEdward Pilatowicz * 19628e3cbeSEdward Pilatowicz * CDDL HEADER END 20628e3cbeSEdward Pilatowicz */ 21628e3cbeSEdward Pilatowicz /* 2280e2ca85S * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23628e3cbeSEdward Pilatowicz */ 24628e3cbeSEdward Pilatowicz 2580e2ca85S #ifndef _BRAND_MISC_H 2680e2ca85S #define _BRAND_MISC_H 27628e3cbeSEdward Pilatowicz 28628e3cbeSEdward Pilatowicz #ifdef __cplusplus 29628e3cbeSEdward Pilatowicz extern "C" { 30628e3cbeSEdward Pilatowicz #endif 31628e3cbeSEdward Pilatowicz 32628e3cbeSEdward Pilatowicz /* 33628e3cbeSEdward Pilatowicz * This header file must uses _ASM defines to allow it to be included 34628e3cbeSEdward Pilatowicz * in assmebly source files 35628e3cbeSEdward Pilatowicz */ 36628e3cbeSEdward Pilatowicz #include <sys/asm_linkage.h> 37628e3cbeSEdward Pilatowicz #include <sys/regset.h> 38628e3cbeSEdward Pilatowicz #include <sys/syscall.h> 3980e2ca85S #if !defined(_ASM) 4080e2ca85S #include <sys/brand.h> 4180e2ca85S #endif 42628e3cbeSEdward Pilatowicz #include "assym.h" 43628e3cbeSEdward Pilatowicz 44628e3cbeSEdward Pilatowicz /* 45628e3cbeSEdward Pilatowicz * Our syscall emulation callback handler adds one argument to each 46628e3cbeSEdward Pilatowicz * system call, so we'll need to allocate space for one more argument 47628e3cbeSEdward Pilatowicz * above the maximum number of arguments that a system call can normally 48628e3cbeSEdward Pilatowicz * take. Also, we assume that each syscall argument is a long, ie, we 49628e3cbeSEdward Pilatowicz * don't support long long syscall parameters. 50628e3cbeSEdward Pilatowicz */ 51628e3cbeSEdward Pilatowicz #if defined(__sparc) 52628e3cbeSEdward Pilatowicz /* 53628e3cbeSEdward Pilatowicz * 32-bit and 64-bit sparc syscalls can take up to 8 arguments. 54628e3cbeSEdward Pilatowicz * 32-bit sparc indirect syscalls can take up to 9 arguments. 55628e3cbeSEdward Pilatowicz * Arguments 1 - 6 are passed via %o0 - %o5. 56628e3cbeSEdward Pilatowicz * Additional arguments are passed on the stack. 57628e3cbeSEdward Pilatowicz * So make space for 4 arguments on the stack. 58628e3cbeSEdward Pilatowicz */ 59628e3cbeSEdward Pilatowicz #define EH_ARGS_COUNT 4 60628e3cbeSEdward Pilatowicz #elif defined(__amd64) 61628e3cbeSEdward Pilatowicz /* 62628e3cbeSEdward Pilatowicz * amd64 syscalls can take up to 8 arguments. 63628e3cbeSEdward Pilatowicz * Arguments 1 - 6 are passed via: %rdi, %rsi, %rdx, %r10, %r8, %r9 64628e3cbeSEdward Pilatowicz * Additional arguments are passed on the stack. 65628e3cbeSEdward Pilatowicz * So make space for 3 arguments on the stack. 66628e3cbeSEdward Pilatowicz */ 67628e3cbeSEdward Pilatowicz #define EH_ARGS_COUNT 3 68628e3cbeSEdward Pilatowicz #else /* !__sparc && !__amd64 */ 69628e3cbeSEdward Pilatowicz /* 70628e3cbeSEdward Pilatowicz * ia32 syscalls can take up to 8 arguments. 71628e3cbeSEdward Pilatowicz * All arguments are passed on the stack. 72628e3cbeSEdward Pilatowicz * So make space for 9 arguments on the stack. 73628e3cbeSEdward Pilatowicz */ 74628e3cbeSEdward Pilatowicz #define EH_ARGS_COUNT 9 75628e3cbeSEdward Pilatowicz #endif /* !__sparc && !__amd64 */ 76628e3cbeSEdward Pilatowicz 77628e3cbeSEdward Pilatowicz 78628e3cbeSEdward Pilatowicz #define EH_ARGS_SIZE (CPTRSIZE * EH_ARGS_COUNT) 79628e3cbeSEdward Pilatowicz #define EH_ARGS_OFFSET(x) (STACK_BIAS + MINFRAME + (CPTRSIZE * (x))) 80628e3cbeSEdward Pilatowicz #define EH_LOCALS_SIZE (EH_ARGS_SIZE + SIZEOF_GREGSET_T + \ 81628e3cbeSEdward Pilatowicz SIZEOF_SYSRET_T + CPTRSIZE) 82628e3cbeSEdward Pilatowicz 83628e3cbeSEdward Pilatowicz #if defined(__sparc) 84628e3cbeSEdward Pilatowicz /* 85628e3cbeSEdward Pilatowicz * On sparc, all emulation callback handler variable access is done 86628e3cbeSEdward Pilatowicz * relative to %sp, so access offsets are positive. 87628e3cbeSEdward Pilatowicz */ 88628e3cbeSEdward Pilatowicz #define EH_LOCALS_START (STACK_BIAS + MINFRAME + EH_ARGS_SIZE) 89628e3cbeSEdward Pilatowicz #define EH_LOCALS_END_TGT (STACK_BIAS + MINFRAME + EH_LOCALS_SIZE) 90628e3cbeSEdward Pilatowicz #else /* !__sparc */ 91628e3cbeSEdward Pilatowicz /* 92628e3cbeSEdward Pilatowicz * On x86, all emulation callback handler variable access is done 93628e3cbeSEdward Pilatowicz * relative to %ebp/%rbp, so access offsets are negative. 94628e3cbeSEdward Pilatowicz */ 95628e3cbeSEdward Pilatowicz #define EH_LOCALS_START (-(EH_LOCALS_SIZE - \ 96628e3cbeSEdward Pilatowicz (STACK_BIAS + MINFRAME + EH_ARGS_SIZE))) 97628e3cbeSEdward Pilatowicz #define EH_LOCALS_END_TGT 0 98628e3cbeSEdward Pilatowicz #endif /* !__sparc */ 99628e3cbeSEdward Pilatowicz 100628e3cbeSEdward Pilatowicz /* 101628e3cbeSEdward Pilatowicz * In our emulation callback handler, our stack will look like: 102628e3cbeSEdward Pilatowicz * ------------------------------------------------- 103628e3cbeSEdward Pilatowicz * %bp | long rvflag | 104628e3cbeSEdward Pilatowicz * | | sysret_t sysret | 105628e3cbeSEdward Pilatowicz * v | gregset_t gregs | 106628e3cbeSEdward Pilatowicz * %sp | long callback args[EH_ARGS_COUNT] | 107628e3cbeSEdward Pilatowicz * ------------------------------------------------- 108628e3cbeSEdward Pilatowicz * For ia32, use %ebp and %esp instead of %bp and %sp. 109628e3cbeSEdward Pilatowicz * For amd64, use %rbp and %rsp instead of %bp and %sp. 110628e3cbeSEdward Pilatowicz * 111628e3cbeSEdward Pilatowicz * Our emulation callback handler always saves enough space to hold the 112628e3cbeSEdward Pilatowicz * maximum number of stack arguments to a system call. This is architecture 113628e3cbeSEdward Pilatowicz * specific and is defined via EH_ARGS_COUNT. 114628e3cbeSEdward Pilatowicz */ 115628e3cbeSEdward Pilatowicz #define EH_LOCALS_GREGS (EH_LOCALS_START) 116628e3cbeSEdward Pilatowicz #define EH_LOCALS_GREG(x) (EH_LOCALS_GREGS + (SIZEOF_GREG_T * (x))) 117628e3cbeSEdward Pilatowicz #define EH_LOCALS_SYSRET (EH_LOCALS_GREGS + SIZEOF_GREGSET_T) 118628e3cbeSEdward Pilatowicz #define EH_LOCALS_SYSRET1 (EH_LOCALS_SYSRET) 119628e3cbeSEdward Pilatowicz #define EH_LOCALS_SYSRET2 (EH_LOCALS_SYSRET + CPTRSIZE) 120628e3cbeSEdward Pilatowicz #define EH_LOCALS_RVFLAG (EH_LOCALS_SYSRET + SIZEOF_SYSRET_T) 121628e3cbeSEdward Pilatowicz #define EH_LOCALS_END (EH_LOCALS_RVFLAG + CPTRSIZE) 122628e3cbeSEdward Pilatowicz 123628e3cbeSEdward Pilatowicz #if (EH_LOCALS_END != EH_LOCALS_END_TGT) 12480e2ca85S #error "brand_misc.h EH_LOCALS_* macros don't add up" 125628e3cbeSEdward Pilatowicz #endif /* (EH_LOCALS_END != EH_LOCALS_END_TGT) */ 126628e3cbeSEdward Pilatowicz 127628e3cbeSEdward Pilatowicz /* 12880e2ca85S * The second parameter of each entry in the {BRAND}_sysent_table 129628e3cbeSEdward Pilatowicz * contains the number of parameters and flags that describe the 13080e2ca85S * syscall return value encoding. 13180e2ca85S * 13280e2ca85S * When declaring new syscall emulation functions, it is very important 13380e2ca85S * to to set the proper RV_* flags in the brand_sysent_table. Upon failure, 13480e2ca85S * syscall emulation fuctions should return an errno value. Upon success 13580e2ca85S * syscall emulation functions should return 0 and set the sysret_t return 13680e2ca85S * value parameters accordingly. 13780e2ca85S * 13880e2ca85S * There are five possible syscall macro wrappers used in the kernel's system 13980e2ca85S * call sysent table. These turn into the following return values: 14080e2ca85S * SYSENT_CL -> SYSENT_C or SYSENT_CI 14180e2ca85S * SYSENT_C SE_64RVAL RV_DEFAULT 14280e2ca85S * SYSENT_CI SE_32RVAL1 RV_DEFAULT 14380e2ca85S * SYSENT_2CI SE_32RVAL1|SE_32RVAL2 RV_32RVAL2 14480e2ca85S * SYSENT_AP SE_64RVAL RV_64RVAL 14580e2ca85S * 146628e3cbeSEdward Pilatowicz */ 147628e3cbeSEdward Pilatowicz #define NARGS_MASK 0x000000FF /* Mask for syscalls argument count */ 148628e3cbeSEdward Pilatowicz #define RV_MASK 0x0000FF00 /* Mask for return value flags */ 149628e3cbeSEdward Pilatowicz #define RV_DEFAULT 0x00000100 /* syscall returns "default" values */ 150628e3cbeSEdward Pilatowicz #define RV_32RVAL2 0x00000200 /* syscall returns two 32-bit values */ 151628e3cbeSEdward Pilatowicz #define RV_64RVAL 0x00000400 /* syscall returns a 64-bit value */ 152628e3cbeSEdward Pilatowicz 153628e3cbeSEdward Pilatowicz #if !defined(_ASM) 154628e3cbeSEdward Pilatowicz 155628e3cbeSEdward Pilatowicz /* 156628e3cbeSEdward Pilatowicz * We define our own version of assert because the default one will 157628e3cbeSEdward Pilatowicz * try to emit a localized message. That is bad because first, we can't 158628e3cbeSEdward Pilatowicz * emit messages to random file descriptors, and second localizing a message 159628e3cbeSEdward Pilatowicz * requires allocating memory and we can't do that either. 160628e3cbeSEdward Pilatowicz */ 16180e2ca85S #define brand_assert(ex) (void)((ex) || \ 16280e2ca85S (_brand_abort(0, #ex, __FILE__, __LINE__), 0)) 16380e2ca85S #define brand_abort(err, msg) _brand_abort((err), (msg), __FILE__, __LINE__) 164*c3232c95SToomas Soome #define EMULATE(cb, args) { (sysent_cb_t)(uintptr_t)(cb), (args) } 16580e2ca85S #define NOSYS EMULATE(brand_unimpl, (0 | RV_DEFAULT)) 16680e2ca85S 16780e2ca85S typedef long (*sysent_cb_t)(); 16880e2ca85S typedef struct brand_sysent_table { 16980e2ca85S sysent_cb_t st_callc; 17080e2ca85S uintptr_t st_args; 17180e2ca85S } brand_sysent_table_t; 17280e2ca85S 17380e2ca85S /* 17480e2ca85S * These macros invoke a brandsys subcommand, B_TRUSS_POINT, used to expose 17580e2ca85S * a call to an interpositioned syscall that would have otherwise gone 17680e2ca85S * unnoticed by truss(1) because the interpositioned system call did not call 17780e2ca85S * any system calls before returning. 17880e2ca85S */ 17980e2ca85S #define B_TRUSS_POINT_5(rval, syscall_num, err, a0, a1, a2, a3, a4) \ 18080e2ca85S __systemcall(rval, SYS_brand + 1024, \ 18180e2ca85S B_TRUSS_POINT, (syscall_num), (err), (a0), (a1), (a2), (a3), \ 18280e2ca85S (a4)) 18380e2ca85S 18480e2ca85S #define B_TRUSS_POINT_4(rval, syscall_num, err, a0, a1, a2, a3) \ 18580e2ca85S B_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), (a3), 0) 18680e2ca85S 18780e2ca85S #define B_TRUSS_POINT_3(rval, syscall_num, err, a0, a1, a2) \ 18880e2ca85S B_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), (a2), 0, 0) 18980e2ca85S 19080e2ca85S #define B_TRUSS_POINT_2(rval, syscall_num, err, a0, a1) \ 19180e2ca85S B_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), (a1), 0, 0, 0) 19280e2ca85S 19380e2ca85S #define B_TRUSS_POINT_1(rval, syscall_num, err, a0) \ 19480e2ca85S B_TRUSS_POINT_5(rval, (syscall_num), (err), (a0), 0, 0, 0, 0) 19580e2ca85S 19680e2ca85S #define B_TRUSS_POINT_0(rval, syscall_num, err) \ 19780e2ca85S B_TRUSS_POINT_5(rval, (syscall_num), (err), 0, 0, 0, 0, 0) 198628e3cbeSEdward Pilatowicz 199628e3cbeSEdward Pilatowicz /* 20080e2ca85S * From runexe.s 201628e3cbeSEdward Pilatowicz */ 20280e2ca85S extern void brand_runexe(void *, ulong_t); 203628e3cbeSEdward Pilatowicz 204628e3cbeSEdward Pilatowicz /* 20580e2ca85S * From handler.s 206628e3cbeSEdward Pilatowicz */ 20780e2ca85S extern void brand_handler_table(void); 20880e2ca85S extern void brand_handler(void); 20980e2ca85S extern void brand_error(void); 21080e2ca85S extern void brand_success(void); 211628e3cbeSEdward Pilatowicz 212628e3cbeSEdward Pilatowicz /* 21380e2ca85S * From brand_util.c 214628e3cbeSEdward Pilatowicz */ 21580e2ca85S extern long brand_unimpl(sysret_t *rv, uintptr_t p1); 21680e2ca85S extern void _brand_abort(int, const char *, const char *, int); 21780e2ca85S extern int brand_uucopy(const void *, void *, size_t); 21880e2ca85S extern int brand_uucopystr(const void *, void *, size_t); 21980e2ca85S extern void brand_pre_init(); 22080e2ca85S extern ulong_t brand_post_init(int, int, char **, char **); 22180e2ca85S #if defined(__sparc) && !defined(__sparcv9) 22280e2ca85S extern long brand_indir(sysret_t *, int, uintptr_t, uintptr_t, uintptr_t, 22380e2ca85S uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); 22480e2ca85S #endif /* __sparc && !__sparcv9 */ 225628e3cbeSEdward Pilatowicz 226628e3cbeSEdward Pilatowicz #endif /* !_ASM */ 227628e3cbeSEdward Pilatowicz 228628e3cbeSEdward Pilatowicz #ifdef __cplusplus 229628e3cbeSEdward Pilatowicz } 230628e3cbeSEdward Pilatowicz #endif 231628e3cbeSEdward Pilatowicz 23280e2ca85S #endif /* _BRAND_MISC_H */ 233