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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_STACK_H 28 #define _SYS_STACK_H 29 30 #if !defined(_ASM) 31 32 #include <sys/types.h> 33 34 #endif 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 /* 41 * In the x86 world, a stack frame looks like this: 42 * 43 * |--------------------------| 44 * 4n+8(%ebp) ->| argument word n | 45 * | ... | (Previous frame) 46 * 8(%ebp) ->| argument word 0 | 47 * |--------------------------|-------------------- 48 * 4(%ebp) ->| return address | 49 * |--------------------------| 50 * 0(%ebp) ->| previous %ebp (optional) | 51 * |--------------------------| 52 * -4(%ebp) ->| unspecified | (Current frame) 53 * | ... | 54 * 0(%esp) ->| variable size | 55 * |--------------------------| 56 */ 57 58 /* 59 * Stack alignment macros. 60 */ 61 62 #define STACK_ALIGN32 4 63 #define STACK_ENTRY_ALIGN32 4 64 #define STACK_BIAS32 0 65 #define SA32(x) (((x)+(STACK_ALIGN32-1)) & ~(STACK_ALIGN32-1)) 66 #define STACK_RESERVE32 0 67 #define MINFRAME32 0 68 69 #if defined(__amd64) 70 71 /* 72 * In the amd64 world, a stack frame looks like this: 73 * 74 * |--------------------------| 75 * 8n+16(%rbp)->| argument word n | 76 * | ... | (Previous frame) 77 * 16(%rbp) ->| argument word 0 | 78 * |--------------------------|-------------------- 79 * 8(%rbp) ->| return address | 80 * |--------------------------| 81 * 0(%rbp) ->| previous %rbp | 82 * |--------------------------| 83 * -8(%rbp) ->| unspecified | (Current frame) 84 * | ... | 85 * 0(%rsp) ->| variable size | 86 * |--------------------------| 87 * -128(%rsp) ->| reserved for function | 88 * |--------------------------| 89 * 90 * The end of the input argument area must be aligned on a 16-byte 91 * boundary; i.e. (%rsp - 8) % 16 == 0 at function entry. 92 * 93 * The 128-byte location beyond %rsp is considered to be reserved for 94 * functions and is NOT modified by signal handlers. It can be used 95 * to store temporary data that is not needed across function calls. 96 */ 97 98 /* 99 * Stack alignment macros. 100 */ 101 102 #define STACK_ALIGN64 16 103 #define STACK_ENTRY_ALIGN64 8 104 #define STACK_BIAS64 0 105 #define SA64(x) (((x)+(STACK_ALIGN64-1)) & ~(STACK_ALIGN64-1)) 106 #define STACK_RESERVE64 128 107 #define MINFRAME64 0 108 109 #define STACK_ALIGN STACK_ALIGN64 110 #define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN64 111 #define STACK_BIAS STACK_BIAS64 112 #define SA(x) SA64(x) 113 #define STACK_RESERVE STACK_RESERVE64 114 #define MINFRAME MINFRAME64 115 116 #elif defined(__i386) 117 118 #define STACK_ALIGN STACK_ALIGN32 119 #define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN32 120 #define STACK_BIAS STACK_BIAS32 121 #define SA(x) SA32(x) 122 #define STACK_RESERVE STACK_RESERVE32 123 #define MINFRAME MINFRAME32 124 125 #endif /* __i386 */ 126 127 #if defined(_KERNEL) && !defined(_ASM) 128 129 #if defined(DEBUG) 130 #if STACK_ALIGN == 4 131 #define ASSERT_STACK_ALIGNED() \ 132 { \ 133 uint32_t __tmp; \ 134 ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \ 135 } 136 #elif (STACK_ALIGN == 16) && (_LONG_DOUBLE_ALIGNMENT == 16) 137 #define ASSERT_STACK_ALIGNED() \ 138 { \ 139 long double __tmp; \ 140 ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \ 141 } 142 #endif 143 #else /* DEBUG */ 144 #define ASSERT_STACK_ALIGNED() 145 #endif /* DEBUG */ 146 147 struct regs; 148 149 void traceregs(struct regs *); 150 void traceback(caddr_t); 151 152 #endif /* defined(_KERNEL) && !defined(_ASM) */ 153 154 #define STACK_GROWTH_DOWN /* stacks grow from high to low addresses */ 155 156 #ifdef __cplusplus 157 } 158 #endif 159 160 #endif /* _SYS_STACK_H */ 161