xref: /illumos-gate/usr/src/uts/intel/sys/stack.h (revision 9b664393d4fdda96221e6ea9ea95790d3c15be70)
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