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