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 _IA32_SYS_STACK_H 28 #define _IA32_SYS_STACK_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #if !defined(_ASM) 33 34 #include <sys/types.h> 35 36 #endif 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /* 43 * In the x86 world, a stack frame looks like this: 44 * 45 * |--------------------------| 46 * 4n+8(%ebp) ->| argument word n | 47 * | ... | (Previous frame) 48 * 8(%ebp) ->| argument word 0 | 49 * |--------------------------|-------------------- 50 * 4(%ebp) ->| return address | 51 * |--------------------------| 52 * 0(%ebp) ->| previous %ebp (optional) | 53 * |--------------------------| 54 * -4(%ebp) ->| unspecified | (Current frame) 55 * | ... | 56 * 0(%esp) ->| variable size | 57 * |--------------------------| 58 */ 59 60 /* 61 * Stack alignment macros. 62 */ 63 64 #define STACK_ALIGN32 4 65 #define STACK_ENTRY_ALIGN32 4 66 #define STACK_BIAS32 0 67 #define SA32(x) (((x)+(STACK_ALIGN32-1)) & ~(STACK_ALIGN32-1)) 68 #define STACK_RESERVE32 0 69 #define MINFRAME32 0 70 71 #if defined(__amd64) 72 73 /* 74 * In the amd64 world, a stack frame looks like this: 75 * 76 * |--------------------------| 77 * 8n+16(%rbp)->| argument word n | 78 * | ... | (Previous frame) 79 * 16(%rbp) ->| argument word 0 | 80 * |--------------------------|-------------------- 81 * 8(%rbp) ->| return address | 82 * |--------------------------| 83 * 0(%rbp) ->| previous %rbp | 84 * |--------------------------| 85 * -8(%rbp) ->| unspecified | (Current frame) 86 * | ... | 87 * 0(%rsp) ->| variable size | 88 * |--------------------------| 89 * -128(%rsp) ->| reserved for function | 90 * |--------------------------| 91 * 92 * The end of the input argument area must be aligned on a 16-byte 93 * boundary; i.e. (%rsp - 8) % 16 == 0 at function entry. 94 * 95 * The 128-byte location beyond %rsp is considered to be reserved for 96 * functions and is NOT modified by signal handlers. It can be used 97 * to store temporary data that is not needed across function calls. 98 */ 99 100 /* 101 * Stack alignment macros. 102 */ 103 104 #define STACK_ALIGN64 16 105 #define STACK_ENTRY_ALIGN64 8 106 #define STACK_BIAS64 0 107 #define SA64(x) (((x)+(STACK_ALIGN64-1)) & ~(STACK_ALIGN64-1)) 108 #define STACK_RESERVE64 128 109 #define MINFRAME64 0 110 111 #define STACK_ALIGN STACK_ALIGN64 112 #define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN64 113 #define STACK_BIAS STACK_BIAS64 114 #define SA(x) SA64(x) 115 #define STACK_RESERVE STACK_RESERVE64 116 #define MINFRAME MINFRAME64 117 118 #elif defined(__i386) 119 120 #define STACK_ALIGN STACK_ALIGN32 121 #define STACK_ENTRY_ALIGN STACK_ENTRY_ALIGN32 122 #define STACK_BIAS STACK_BIAS32 123 #define SA(x) SA32(x) 124 #define STACK_RESERVE STACK_RESERVE32 125 #define MINFRAME MINFRAME32 126 127 #endif /* __i386 */ 128 129 #if defined(_KERNEL) && !defined(_ASM) 130 131 #if defined(DEBUG) 132 #if STACK_ALIGN == 4 133 #define ASSERT_STACK_ALIGNED() \ 134 { \ 135 uint32_t __tmp; \ 136 ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \ 137 } 138 #elif (STACK_ALIGN == 16) && (_LONG_DOUBLE_ALIGNMENT == 16) 139 #define ASSERT_STACK_ALIGNED() \ 140 { \ 141 long double __tmp; \ 142 ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0); \ 143 } 144 #endif 145 #else /* DEBUG */ 146 #define ASSERT_STACK_ALIGNED() 147 #endif /* DEBUG */ 148 149 struct regs; 150 151 void traceregs(struct regs *); 152 void traceback(caddr_t); 153 154 #endif /* defined(_KERNEL) && !defined(_ASM) */ 155 156 #define STACK_GROWTH_DOWN /* stacks grow from high to low addresses */ 157 158 #ifdef __cplusplus 159 } 160 #endif 161 162 #endif /* _IA32_SYS_STACK_H */ 163