VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/compiler/vcc/except-x86-vcc-asm.asm@ 97862

Last change on this file since 97862 was 97862, checked in by vboxsync, 2 years ago

IPRT/nocrt: Added a simple structured exception handling (SEH) testcase and did a basic implementation of _except_handler4 for 32-bit x86. bugref:10261 ticketref:21303

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1; $Id: except-x86-vcc-asm.asm 97862 2022-12-23 16:55:57Z vboxsync $
2;; @file
3; IPRT - Visual C++ Compiler - x86 Exception Handler Support Code.
4;
5
6;
7; Copyright (C) 2022 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; The contents of this file may alternatively be used under the terms
26; of the Common Development and Distribution License Version 1.0
27; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28; in the VirtualBox distribution, in which case the provisions of the
29; CDDL are applicable instead of those of the GPL.
30;
31; You may elect to license modified versions of this file under the
32; terms and conditions of either the GPL or the CDDL or both.
33;
34; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35;
36
37
38
39;*********************************************************************************************************************************
40;* Header Files *
41;*********************************************************************************************************************************
42%include "iprt/asmdefs.mac"
43
44
45;*********************************************************************************************************************************
46;* Structures and Typedefs *
47;*********************************************************************************************************************************
48
49struc EH4_XCPT_REG_REC_T
50 .uSavedEsp resd 1 ; 0 / 0x00
51 .pXctpPtrs resd 1 ; 4 / 0x04
52 .XcptRec resd 2 ; 8 / 0x08
53 .uEncodedScopeTable resd 1 ; 16 / 0x10
54 .uTryLevel resd 1 ; 20 / 0x14
55endstruc ; 24 / 0x18
56
57
58;;
59; Scope table record describing __try / __except / __finally blocks (aka
60; EH4_SCOPETABLE_RECORD).
61;
62struc EH4_SCOPE_TAB_REC_T
63 .uEnclosingLevel resd 1
64 .pfnFilter resd 1
65 .pfnHandlerOrFinally resd 1
66endstruc
67
68;; Special EH4_SCOPE_TAB_REC_T::uEnclosingLevel used to terminate the chain.
69%define EH4_TOPMOST_TRY_LEVEL 0xfffffffe
70
71;;
72; Scope table used by _except_handler4 (aka EH4_SCOPETABLE).
73;
74struc EH4_SCOPE_TAB_T
75 .offGSCookie resd 1
76 .offGSCookieXor resd 1
77 .offEHCookie resd 1
78 .offEHCookieXor resd 1
79 .aScopeRecords resb 12
80endstruc
81
82
83;*********************************************************************************************************************************
84;* External Symbols *
85;*********************************************************************************************************************************
86BEGINCODE
87extern IMPNAME(RtlUnwind@16)
88
89
90
91;;
92; Calls the filter sub-function for a __finally statement.
93;
94; This sets all GRPs to zero, except for ESP, EBP and EAX.
95;
96; @param pfnFilter [ebp + 08h]
97; @param fAbend [ebp + 0ch]
98; @param pbFrame [ebp + 10h]
99;
100BEGINPROC rtVccEh4DoFinally
101 push ebp
102 mov ebp, esp
103 push ebx
104 push edi
105 push esi
106
107 ;; @todo we're not calling __NLG_Notify nor NLG_Call, which may perhaps confuse debuggers or something...
108
109 xor edi, edi
110 xor esi, esi
111 xor edx, edx
112 xor ebx, ebx
113
114 mov eax, [ebp + 08h] ; pfnFilter
115 movzx ecx, byte [ebp + 0ch] ; fAbend
116 mov ebp, [ebp + 10h] ; pbFrame
117
118 call eax
119
120 pop esi
121 pop edi
122 pop ebx
123 pop ebp
124 ret
125ENDPROC rtVccEh4DoFinally
126
127
128;;
129; Calls the filter sub-function for an __except statement.
130;
131; This sets all GRPs to zero, except for ESP, EBP and ECX.
132;
133; @param pfnFilter [ebp + 08h]
134; @param pbFrame [ebp + 0ch]
135;
136BEGINPROC rtVccEh4DoFiltering
137 push ebp
138 push ebx
139 push edi
140 push esi
141
142 mov ecx, [esp + 5 * 4 + 0] ; pfnFilter
143 mov ebp, [esp + 5 * 4 + 4] ; pbFrame
144
145 xor edi, edi
146 xor esi, esi
147 xor edx, edx
148 xor ebx, ebx
149 xor eax, eax
150
151 call ecx
152
153 pop esi
154 pop edi
155 pop ebx
156 pop ebp
157 ret
158ENDPROC rtVccEh4DoFiltering
159
160
161;;
162; Resumes executing in an __except block (never returns).
163;
164; @param pfnHandler [ebp + 08h]
165; @param pbFrame [ebp + 0ch]
166;
167BEGINPROC rtVccEh4JumpToHandler
168 ;
169 ; Since we're never returning there is no need to save anything here. So,
170 ; just start by loading parameters into registers.
171 ;
172 mov esi, [esp + 1 * 4 + 0] ; pfnFilter
173 mov ebp, [esp + 1 * 4 + 4] ; pbFrame
174
175%if 0
176 mov eax, esi
177 push 1
178 call NAME(_NLG_Notify)
179%endif
180
181 ;
182 ; Zero all GPRs except for ESP, EBP and ESI.
183 ;
184 xor edi, edi
185 xor edx, edx
186 xor ecx, ecx
187 xor ebx, ebx
188 xor eax, eax
189
190 jmp esi
191ENDPROC rtVccEh4JumpToHandler
192
193
194
195;;
196; This does global unwinding via RtlUnwind.
197;
198; The interface kind of requires us to do this from assembly.
199;
200; @param pXcptRec [ebp + 08h]
201; @param pXcptRegRec [ebp + 0ch]
202;
203BEGINPROC rtVccEh4DoGlobalUnwind
204 push ebp
205 mov ebp, esp
206
207 ; Save all non-volatile registers.
208 push edi
209 push esi
210 push ebx
211
212 ;
213 ; Call unwind function.
214 ;
215 push 0 ; ReturnValue
216 push dword [ebp + 08h] ; ExceptionRecord - pXcptRec
217 push .return ; TargetIp
218 push dword [ebp + 0ch] ; TargetFrame - pXcptRegRec
219 call IMP(RtlUnwind@16)
220
221 ;
222 ; The RtlUnwind code will place us here if it doesn't return the regular way.
223 ;
224.return:
225 ; Restore non-volatile registers.
226 pop ebx
227 pop esi
228 pop edi
229
230 leave
231 ret
232ENDPROC rtVccEh4DoGlobalUnwind
233
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette