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<ecx>); 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 mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx] 37 38.global __SEH3$_RegisterFrameWithStackLayout 39__SEH3$_RegisterFrameWithStackLayout: 40 41 /* Save the pointer to the alloca frame */ 42 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx 43 44.global __SEH3$_RegisterFrame 45__SEH3$_RegisterFrame: 46 47 /* Save the address of the static data table */ 48 mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx 49 50 /* Set the handler address */ 51 mov dword ptr [eax + SEH3_REGISTRATION_FRAME_Handler], offset __SEH3$_except_handler 52 53 /* Set this as the end of the internal chain */ 54 mov dword ptr [eax + SEH3_REGISTRATION_FRAME_EndOfChain], eax 55 56 /* Register the frame in the TEB */ 57 mov edx, dword ptr fs:[0] 58 mov [eax + SEH3_REGISTRATION_FRAME_Next], edx 59 mov dword ptr fs:[0], eax 60 61 /* Save the stack registers */ 62 mov [eax + SEH3_REGISTRATION_FRAME_Esp], esp 63 mov [eax + SEH3_REGISTRATION_FRAME_Ebp], ebp 64 65 /* Set eax to 0 to indicate 1st return */ 66 xor eax, eax 67 ret 68 69 70/* 71 * void 72 * __attribute__((regparm(3))) 73 * __attribute__((returns_twice)) 74 * _SEH3$_RegisterTryLevel[WithNonVolatiles]( 75 * PSEH3$_REGISTRATION_FRAME RegistrationFrame<eax>, 76 * PSEH3$_SCOPE_TABLE ScopeTable<edx>, 77 * PVOID AllocaFrame<ecx>); 78 */ 79.global __SEH3$_RegisterTryLevelWithNonVolatiles 80__SEH3$_RegisterTryLevelWithNonVolatiles: 81 82 /* Save non-volatiles in the registration frame */ 83 mov [eax + SEH3_REGISTRATION_FRAME_Ebx], ebx 84 mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi 85 mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi 86 87 /* Safe the return address */ 88 mov ebx, [esp] 89 mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx 90 mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx] 91 92.global __SEH3$_RegisterTryLevelWithStackLayout 93__SEH3$_RegisterTryLevelWithStackLayout: 94 95 /* Save the pointer to the alloca frame */ 96 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx 97 98.global __SEH3$_RegisterTryLevel 99__SEH3$_RegisterTryLevel: 100 101 /* Save the address of the static data table */ 102 mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx 103 104 /* Set the handler address to NULL as identification */ 105 and dword ptr [eax + SEH3_REGISTRATION_FRAME_Handler], 0 106 107 /* Get the current registered frame */ 108 mov edx, dword ptr fs:[0] 109 110 /* Get the current end of the chain and set this as Next */ 111 mov ecx, [edx + SEH3_REGISTRATION_FRAME_EndOfChain] 112 mov [eax + SEH3_REGISTRATION_FRAME_Next], ecx 113 114 /* Set this as the end of the internal chain */ 115 mov dword ptr [edx + SEH3_REGISTRATION_FRAME_EndOfChain], eax 116 117 /* Save the stack registers */ 118 mov [eax + SEH3_REGISTRATION_FRAME_Esp], esp 119 mov [eax + SEH3_REGISTRATION_FRAME_Ebp], ebp 120 121 /* Set eax to 0 to indicate 1st return */ 122 xor eax, eax 123 ret 124 125 126.global __SEH3$_InvokeEmbeddedFilterFromRegistration 127__SEH3$_InvokeEmbeddedFilterFromRegistration: 128 129 /* Safe the current non-volatiles */ 130 push ebp 131 push ebx 132 push esi 133 push edi 134 135 /* Save the registration frame pointer */ 136 push eax 137 138 /* Load the non-volatiles from the registration invocation */ 139 mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx] 140 mov esi, [eax + SEH3_REGISTRATION_FRAME_Esi] 141 mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi] 142 mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp] 143 144 /* Calculate the size of the temp stack frame region */ 145 mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame] 146 sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp] 147 148 /* Put the return address on the stack */ 149 push offset __SEH3$_InvokeEmbeddedFilterReturnClang 150 151 /* Save the current stack pointer in the AllocaFrame member */ 152 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], esp 153 154 /* Allocate enough temp stack space on the stack */ 155 sub esp, ecx 156 157 /* Get the return address that was saved when registering the frame */ 158 mov edx, [eax + SEH3_REGISTRATION_FRAME_ReturnAddress] 159 160 /* Jump into the filter or finally function */ 161 xor eax, eax 162 inc eax 163 jmp edx 164 165 /* We return to this label with a cleaned up stack */ 166__SEH3$_InvokeEmbeddedFilterReturnClang: 167 168 /* Restore the registration frame pointer */ 169 pop ecx 170 171 /* Save the non-volatiles back in the registration frame */ 172 mov [ecx + SEH3_REGISTRATION_FRAME_Ebx], ebx 173 mov [ecx + SEH3_REGISTRATION_FRAME_Esi], esi 174 mov [ecx + SEH3_REGISTRATION_FRAME_Edi], edi 175 mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp 176 177 /* Restore the current non-volatiles */ 178 pop edi 179 pop esi 180 pop ebx 181 pop ebp 182 183 ret 184 185 186.global __SEH3$_InvokeEmbeddedFilter 187__SEH3$_InvokeEmbeddedFilter: 188 189 /* Safe the current non-volatiles */ 190 push ebp 191 push ebx 192 push esi 193 push edi 194 195 /* Load ebp from the registration invocation */ 196 mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp] 197 198 /* Calculate the size of the temp stack frame region */ 199 mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame] 200 sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp] 201 202 /* Put the return address on the stack */ 203 push offset __SEH3$_InvokeEmbeddedFilterReturn 204 205 /* Save the current stack pointer in the AllocaFrame member */ 206 mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], esp 207 208 /* Allocate enough temp stack space on the stack */ 209 sub esp, ecx 210 211 /* Get the scope table */ 212 mov edx, [eax + SEH3_REGISTRATION_FRAME_ScopeTable] 213 214 /* Jump into the filter or finally function */ 215 jmp [edx + SEH3_SCOPE_TABLE_Filter] 216 217 /* We return to this label with a cleaned up stack */ 218__SEH3$_InvokeEmbeddedFilterReturn: 219 220 /* Restore the current non-volatiles */ 221 pop edi 222 pop esi 223 pop ebx 224 pop ebp 225 226 ret 227 228/* 229 * void 230 * __fastcall 231 * _SEH3$_CallRtlUnwind( 232 * PSEH3$_REGISTRATION_FRAME RegistrationFrame<ecx>) 233 */ 234.global @_SEH3$_CallRtlUnwind@4 235@_SEH3$_CallRtlUnwind@4: 236 237 push ebp 238 mov ebp, esp 239 240 push edi 241 push esi 242 push ebx 243 244 push 0 /* ReturnValue */ 245 push 0 /* ExceptionRecord */ 246 push 0 /* TargetIp */ 247 push ecx /* TargetFrame */ 248 call _RtlUnwind@16 249 250 pop ebx 251 pop esi 252 pop edi 253 pop ebp 254 ret 255 256