[SHELL-EXPERIMENTS]
[reactos.git] / lib / pseh / i386 / pseh3_i386.S
1 /*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GNU GPL - See COPYING in the top level directory
4 * PURPOSE: Support library for PSEH3
5 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
6 */
7
8 #include "pseh3_asmdef.h"
9
10 .intel_syntax noprefix
11
12 .text
13
14 .extern __SEH3$_except_handler
15
16 /*
17 * void
18 * __attribute__((regparm(3)))
19 * __attribute__((returns_twice))
20 * _SEH3$_RegisterFrame[WithNonVolatiles](
21 * PSEH3$_REGISTRATION_FRAME RegistrationFrame<eax>,
22 * PSEH3$_SCOPE_TABLE ScopeTable<edx>,
23 * PVOID AllocaFrame);
24 */
25 .global __SEH3$_RegisterFrameWithNonVolatiles
26 __SEH3$_RegisterFrameWithNonVolatiles:
27
28 /* Save non-volatiles in the registration frame */
29 mov [eax + SEH3_REGISTRATION_FRAME_Ebx], ebx
30 mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
31 mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
32
33 /* Safe the return address */
34 mov ebx, [esp]
35 mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx
36
37 .global __SEH3$_RegisterFrameWithStackLayout
38 __SEH3$_RegisterFrameWithStackLayout:
39
40 /* Save the pointer to the alloca frame */
41 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx
42
43 .global __SEH3$_RegisterFrame
44 __SEH3$_RegisterFrame:
45
46 /* Save the address of the static data table */
47 mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx
48
49 /* Set the handler address */
50 mov dword ptr [eax + SEH3_REGISTRATION_FRAME_Handler], offset __SEH3$_except_handler
51
52 /* Set this as the end of the internal chain */
53 mov dword ptr [eax + SEH3_REGISTRATION_FRAME_EndOfChain], eax
54
55 /* Register the frame in the TEB */
56 mov edx, dword ptr fs:[0]
57 mov [eax + SEH3_REGISTRATION_FRAME_Next], edx
58 mov dword ptr fs:[0], eax
59
60 /* Save the stack registers */
61 mov [eax + SEH3_REGISTRATION_FRAME_Esp], esp
62 mov [eax + SEH3_REGISTRATION_FRAME_Ebp], ebp
63
64 /* Set eax to 0 to indicate 1st return */
65 xor eax, eax
66 ret
67
68
69 /*
70 * void
71 * __attribute__((regparm(3)))
72 * __attribute__((returns_twice))
73 * _SEH3$_RegisterTryLevel[WithNonVolatiles](
74 * PSEH3$_REGISTRATION_FRAME RegistrationFrame<edx>,
75 * PSEH3$_SCOPE_TABLE ScopeTable<eax>,
76 * PVOID AllocaFrame);
77 */
78 .global __SEH3$_RegisterTryLevelWithNonVolatiles
79 __SEH3$_RegisterTryLevelWithNonVolatiles:
80
81 /* Save non-volatiles in the registration frame */
82 mov [eax + SEH3_REGISTRATION_FRAME_Ebx], ebx
83 mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
84 mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
85
86 /* Safe the return address */
87 mov ebx, [esp]
88 mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx
89
90 .global __SEH3$_RegisterTryLevelWithStackLayout
91 __SEH3$_RegisterTryLevelWithStackLayout:
92
93 /* Save the pointer to the alloca frame */
94 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx
95
96 .global __SEH3$_RegisterTryLevel
97 __SEH3$_RegisterTryLevel:
98
99 /* Save the address of the static data table */
100 mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx
101
102 /* Set the handler address to NULL as identification */
103 and dword ptr [eax + SEH3_REGISTRATION_FRAME_Handler], 0
104
105 /* Get the current registered frame */
106 mov edx, dword ptr fs:[0]
107
108 /* Get the current end of the chain and set this as Next */
109 mov ecx, [edx + SEH3_REGISTRATION_FRAME_EndOfChain]
110 mov [eax + SEH3_REGISTRATION_FRAME_Next], ecx
111
112 /* Set this as the end of the internal chain */
113 mov dword ptr [edx + SEH3_REGISTRATION_FRAME_EndOfChain], eax
114
115 /* Save the stack registers */
116 mov [eax + SEH3_REGISTRATION_FRAME_Esp], esp
117 mov [eax + SEH3_REGISTRATION_FRAME_Ebp], ebp
118
119 /* Set eax to 0 to indicate 1st return */
120 xor eax, eax
121 ret
122
123
124 .global __SEH3$_InvokeEmbeddedFilterFromRegistration
125 __SEH3$_InvokeEmbeddedFilterFromRegistration:
126
127 /* Safe the current non-volatiles */
128 push ebp
129 push ebx
130 push esi
131 push edi
132
133 /* Load the non-volatiles from the registration invocation */
134 mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx]
135 mov esi, [eax + SEH3_REGISTRATION_FRAME_Esi]
136 mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi]
137 mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
138
139 /* Calculate the size of the temp stack frame region */
140 mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame]
141 sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp]
142
143 /* Put the return address on the stack */
144 push offset __SEH3$_InvokeEmbeddedFilterReturn
145
146 /* Save the current stack pointer in the AllocaFrame member */
147 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], esp
148
149 /* Allocate enough temp stack space on the stack */
150 sub esp, ecx
151
152 /* Get the return address that was saved when registering the frame */
153 mov edx, [eax + SEH3_REGISTRATION_FRAME_ReturnAddress]
154
155 /* Jump into the filter or finally function */
156 xor eax, eax
157 inc eax
158 jmp edx
159
160
161 .global __SEH3$_InvokeEmbeddedFilter
162 __SEH3$_InvokeEmbeddedFilter:
163
164 /* Safe the current non-volatiles */
165 push ebp
166 push ebx
167 push esi
168 push edi
169
170 /* Load ebp from the registration invocation */
171 mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
172
173 /* Calculate the size of the temp stack frame region */
174 mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame]
175 sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp]
176
177 /* Put the return address on the stack */
178 push offset __SEH3$_InvokeEmbeddedFilterReturn
179
180 /* Save the current stack pointer in the AllocaFrame member */
181 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], esp
182
183 /* Allocate enough temp stack space on the stack */
184 sub esp, ecx
185
186 /* Get the scope table */
187 mov edx, [eax + SEH3_REGISTRATION_FRAME_ScopeTable]
188
189 /* Jump into the filter or finally function */
190 jmp [edx + SEH3_SCOPE_TABLE_Filter]
191
192 /* We return to this label with a cleaned up stack */
193 __SEH3$_InvokeEmbeddedFilterReturn:
194
195 /* Restore the current non-volatiles */
196 pop edi
197 pop esi
198 pop ebx
199 pop ebp
200
201 ret
202
203 /*
204 * void
205 * __fastcall
206 * _SEH3$_CallRtlUnwind(
207 * PSEH3$_REGISTRATION_FRAME RegistrationFrame<ecx>)
208 */
209 .global @_SEH3$_CallRtlUnwind@4
210 @_SEH3$_CallRtlUnwind@4:
211
212 push ebp
213 mov ebp, esp
214
215 push edi
216 push esi
217 push ebx
218
219 push 0 /* ReturnValue */
220 push 0 /* ExceptionRecord */
221 push 0 /* TargetIp */
222 push ecx /* TargetFrame */
223 call _RtlUnwind@16
224
225 pop ebx
226 pop esi
227 pop edi
228 pop ebp
229 ret
230