From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- .../common/compiler/vcc/except-x86-vcc-asm.asm | 358 +++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 src/VBox/Runtime/common/compiler/vcc/except-x86-vcc-asm.asm (limited to 'src/VBox/Runtime/common/compiler/vcc/except-x86-vcc-asm.asm') diff --git a/src/VBox/Runtime/common/compiler/vcc/except-x86-vcc-asm.asm b/src/VBox/Runtime/common/compiler/vcc/except-x86-vcc-asm.asm new file mode 100644 index 00000000..dfc47415 --- /dev/null +++ b/src/VBox/Runtime/common/compiler/vcc/except-x86-vcc-asm.asm @@ -0,0 +1,358 @@ +; $Id: except-x86-vcc-asm.asm $ +;; @file +; IPRT - Visual C++ Compiler - x86 Exception Handler Support Code. +; + +; +; Copyright (C) 2022-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see . +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + + +;********************************************************************************************************************************* +;* Header Files * +;********************************************************************************************************************************* +%include "iprt/asmdefs.mac" + + +;********************************************************************************************************************************* +;* Defined Constants And Macros * +;********************************************************************************************************************************* + +;; @def WITH_NLG_STUFF +; Enabled NLG debugger hooks/whatever - no idea how it's used. +; +; So far vsdebugeng.manimpl.dll in the VS2019 remote debugger directory is the +; only component with any _NLG_ strings in it. Could not find any references +; to _NLG_ in windbg. +%define WITH_NLG_STUFF 1 + + +;********************************************************************************************************************************* +;* Structures and Typedefs * +;********************************************************************************************************************************* + +struc EH4_XCPT_REG_REC_T + .uSavedEsp resd 1 ; 0 / 0x00 + .pXctpPtrs resd 1 ; 4 / 0x04 + .XcptRec resd 2 ; 8 / 0x08 + .uEncodedScopeTable resd 1 ; 16 / 0x10 + .uTryLevel resd 1 ; 20 / 0x14 +endstruc ; 24 / 0x18 + + +;; +; Scope table record describing __try / __except / __finally blocks (aka +; EH4_SCOPETABLE_RECORD). +; +struc EH4_SCOPE_TAB_REC_T + .uEnclosingLevel resd 1 + .pfnFilter resd 1 + .pfnHandlerOrFinally resd 1 +endstruc + +;; Special EH4_SCOPE_TAB_REC_T::uEnclosingLevel used to terminate the chain. +%define EH4_TOPMOST_TRY_LEVEL 0xfffffffe + +;; +; Scope table used by _except_handler4 (aka EH4_SCOPETABLE). +; +struc EH4_SCOPE_TAB_T + .offGSCookie resd 1 + .offGSCookieXor resd 1 + .offEHCookie resd 1 + .offEHCookieXor resd 1 + .aScopeRecords resb 12 +endstruc + + +;********************************************************************************************************************************* +;* External Symbols * +;********************************************************************************************************************************* +BEGINCODE +extern IMPNAME(RtlUnwind@16) +extern _rtVccEh4DoLocalUnwindHandler@16 + + +;********************************************************************************************************************************* +;* Global Variables * +;********************************************************************************************************************************* + +;; Delcare rtVccEh4DoLocalUnwindHandler() in except-x86.cpp as a save exception handler. +; This adds the symbol table number of the exception handler to the special .sxdata section. +safeseh _rtVccEh4DoLocalUnwindHandler@16 + +%ifdef WITH_NLG_STUFF +BEGINDATA +GLOBALNAME_RAW __NLG_Destination, data, hidden + dd 019930520h + dd 0 + dd 0 + dd 0 +%endif + + +BEGINCODE + +%ifdef WITH_NLG_STUFF + +;; +; Some VS debugger interface, I think. +; +; @param EDX Notification code. +; @uses EBP, EAX & ECX are preserved. This differs from other implementation, +; but simplifies the calling code. +; +ALIGNCODE(32) +GLOBALNAME_RAW __NLG_Notify, function, hidden + ; + ; Save registers. + ; + push eax + push ecx + push ebp + push ebx + + + ; + ; ECX = notification code. + ; EBX = __NLG_Destination + ; + mov ecx, edx ; Originally held in ECX, so moving it there for now. + mov ebx, __NLG_Destination + +__NLG_Go: + ; + ; Save info to __NLG_Destination and the stack (same layout). + ; + mov [ebx + 0ch], ebp + push ebp + mov [ebx + 08h], ecx + push ecx + mov [ebx + 04h], eax + push eax + + ; + ; This is presumably the symbol the debugger hooks on to as the string + ; "__NLG_Dispatch" was found in vsdebugeng.manimpl.dll in VS2019. + ; +global __NLG_Dispatch +__NLG_Dispatch: + + ; Drop the info structure from the stack. + add esp, 4*3 + + ; + ; Restore registers and drop the parameter as we return. + ; + ; Note! This may sabotage attempts by the debugger to modify the state... + ; But that can be fixed once we know this is a requirement. Just + ; keep things simple for the caller for now. + ; + pop ebx + pop ebp + pop ecx + pop eax + ret + +;; +; NLG call + return2. +; +; The "__NLG_Return2" symbol was observed in several vsdebugeng.manimpl.dll +; strings in VS2019. +; +ALIGNCODE(4) +GLOBALNAME_RAW __NLG_Call, function, hidden + call eax + +global __NLG_Return2 +__NLG_Return2: + ret + +%endif + + +;; +; Calls the filter sub-function for a __finally statement. +; +; This sets all GRPs to zero, except for ESP, EBP and EAX. +; +; @param pfnFilter [ebp + 08h] +; @param fAbend [ebp + 0ch] +; @param pbFrame [ebp + 10h] +; +ALIGNCODE(64) +BEGINPROC rtVccEh4DoFinally + push ebp + mov ebp, esp + push ebx + push edi + push esi + + xor edi, edi + xor esi, esi +%ifndef WITH_NLG_STUFF + xor edx, edx +%endif + xor ebx, ebx + + mov eax, [ebp + 08h] ; pfnFilter + movzx ecx, byte [ebp + 0ch] ; fAbend + mov ebp, [ebp + 10h] ; pbFrame + +%ifdef WITH_NLG_STUFF + mov edx, 101h + call __NLG_Notify + xor edx, edx + + call __NLG_Call +%else + call eax +%endif + + pop esi + pop edi + pop ebx + pop ebp + ret +ENDPROC rtVccEh4DoFinally + + +;; +; Calls the filter sub-function for an __except statement. +; +; This sets all GRPs to zero, except for ESP, EBP and ECX. +; +; @param pfnFilter [ebp + 08h] +; @param pbFrame [ebp + 0ch] +; +ALIGNCODE(32) +BEGINPROC rtVccEh4DoFiltering + push ebp + push ebx + push edi + push esi + + mov ecx, [esp + 5 * 4 + 0] ; pfnFilter + mov ebp, [esp + 5 * 4 + 4] ; pbFrame + + xor edi, edi + xor esi, esi + xor edx, edx + xor ebx, ebx + xor eax, eax + + call ecx + + pop esi + pop edi + pop ebx + pop ebp + ret +ENDPROC rtVccEh4DoFiltering + + +;; +; Resumes executing in an __except block (never returns). +; +; @param pfnHandler [ebp + 08h] +; @param pbFrame [ebp + 0ch] +; +ALIGNCODE(32) +BEGINPROC rtVccEh4JumpToHandler + ; + ; Since we're never returning there is no need to save anything here. So, + ; just start by loading parameters into registers. + ; + mov esi, [esp + 1 * 4 + 0] ; pfnFilter + mov ebp, [esp + 1 * 4 + 4] ; pbFrame + +%ifdef WITH_NLG_STUFF + ; + ; Notify VS debugger/whatever. + ; + mov eax, esi + mov edx, 1 + call __NLG_Notify +%endif + + ; + ; Zero all GPRs except for ESP, EBP and ESI. + ; + xor edi, edi + xor edx, edx + xor ecx, ecx + xor ebx, ebx + xor eax, eax + + jmp esi +ENDPROC rtVccEh4JumpToHandler + + +;; +; This does global unwinding via RtlUnwind. +; +; The interface kind of requires us to do this from assembly. +; +; @param pXcptRec [ebp + 08h] +; @param pXcptRegRec [ebp + 0ch] +; +ALIGNCODE(32) +BEGINPROC rtVccEh4DoGlobalUnwind + push ebp + mov ebp, esp + + ; Save all non-volatile registers. + push edi + push esi + push ebx + + ; + ; Call unwind function. + ; + push 0 ; ReturnValue + push dword [ebp + 08h] ; ExceptionRecord - pXcptRec + push .return ; TargetIp + push dword [ebp + 0ch] ; TargetFrame - pXcptRegRec + call IMP(RtlUnwind@16) + + ; + ; The RtlUnwind code will place us here if it doesn't return the regular way. + ; +.return: + ; Restore non-volatile registers. + pop ebx + pop esi + pop edi + + leave + ret +ENDPROC rtVccEh4DoGlobalUnwind + -- cgit v1.2.3