From 27ffa568f54e05f3e5d4fa75aab855cb9b8075d9 Mon Sep 17 00:00:00 2001
From: Mikhail Krichanov <mikhailkrichanov@gmail.com>
Date: Mon, 26 Jun 2023 12:42:16 +0300
Subject: [PATCH] UefiCpuPkg/CpuExceptionHandlerLib: Creates unified
 ExceptionHandlerAsm

This change removes Xcode5ExceptionHandlerAsm and merge it's
functionality into ExceptionHandlerAsm.
Also decreases number of vectors to 32 for:
- 64-bit PeiCpuExceptionHandlerLib
- 32-bit PeiCpuExceptionHandlerLib, SecPeiCpuExceptionHandlerLib

Signed-off-by: Savva Mitrofanov <savvamtr@gmail.com>
---
 .../CpuExceptionCommon.h                      |   1 +
 .../DxeCpuExceptionHandlerLib.inf             |   3 -
 .../Ia32/ExceptionHandlerAsm.nasm             |  11 +-
 .../Ia32/ExceptionTssEntryAsm.nasm            |   1 +
 .../PeiCpuExceptionHandlerLib.inf             |   4 +-
 .../PeiDxeSmmCpuException.c                   |   4 +-
 .../SecPeiCpuExceptionHandlerLib.inf          |   4 +-
 .../SmmCpuExceptionHandlerLib.inf             |   6 +-
 .../X64/ExceptionHandlerAsm.nasm              |  44 +-
 .../X64/SecPeiExceptionHandlerAsm.nasm        | 406 ------------------
 10 files changed, 36 insertions(+), 448 deletions(-)
 delete mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 95877b8be0..6d3dc46b6e 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -57,6 +57,7 @@ typedef struct {
   UINTN    ExceptionStart;
   UINTN    ExceptionStubHeaderSize;
   UINTN    HookAfterStubHeaderStart;
+  UINTN    HookAfterStubHeaderSize;
 } EXCEPTION_HANDLER_TEMPLATE_MAP;
 
 typedef struct {
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
index e8b4deeddd..398c82d46f 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -74,8 +74,5 @@
 [LibraryClasses.LoongArch64]
   CpuLib
 
-[BuildOptions]
-  XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT
-
 [Guids]
   gEfiDebugImageInfoTableGuid  ## CONSUMES ## SystemTable
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm
index 31a00449a2..9a92c931dd 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm
@@ -14,6 +14,12 @@
 ;
 ;------------------------------------------------------------------------------
 
+%ifdef CEHL_MINIMAL_INTERRUPTS
+%define NUM_VECTORS 32
+%else
+%define NUM_VECTORS 256
+%endif
+
 ;
 ; CommonExceptionHandler()
 ;
@@ -33,7 +39,7 @@ ALIGN   8
 ;
 AsmIdtVectorBegin:
 %assign Vector 0
-%rep  256
+%rep  NUM_VECTORS
     push    strict dword %[Vector];
     push    eax
     mov     eax, ASM_PFX(CommonInterruptEntry)
@@ -438,8 +444,9 @@ ASM_PFX(AsmGetTemplateAddressMap):
 
     mov ebx, dword [ebp + 0x8]
     mov dword [ebx],      AsmIdtVectorBegin
-    mov dword [ebx + 0x4], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 256
+    mov dword [ebx + 0x4], (AsmIdtVectorEnd - AsmIdtVectorBegin) / NUM_VECTORS
     mov dword [ebx + 0x8], HookAfterStubBegin
+    mov dword [ebx + 0xC], HookAfterStubHeaderEnd - HookAfterStubBegin
 
     popad
     pop     ebp
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm
index b63cfeac6d..8d91b04b53 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm
@@ -382,6 +382,7 @@ ASM_PFX(AsmGetTssTemplateMap):
     mov dword [ebx],       ASM_PFX(ExceptionTaskSwtichEntry0)
     mov dword [ebx + 0x4], (AsmExceptionEntryEnd - AsmExceptionEntryBegin) / 32
     mov dword [ebx + 0x8], 0
+    mov dword [ebx + 0xC], 0
 
     popad
     pop     ebp
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
index 3db1ad47ab..3caff1beb6 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
@@ -30,7 +30,7 @@
 [Sources.X64]
   X64/ArchExceptionHandler.c
   X64/ArchInterruptDefs.h
-  X64/SecPeiExceptionHandlerAsm.nasm
+  X64/ExceptionHandlerAsm.nasm
 
 [Sources.common]
   CpuExceptionCommon.h
@@ -63,4 +63,4 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard                    ## CONSUMES
 
 [BuildOptions]
-  XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT
+  *_*_*_NASM_FLAGS  = -DCEHL_MINIMAL_INTERRUPTS
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
index 748cf8d3bf..c92e405b2c 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c
@@ -206,7 +206,7 @@ UpdateIdtTable (
         CopyMem (
           (VOID *)ReservedVectors[Index].HookAfterStubHeaderCode,
           (VOID *)TemplateMap->HookAfterStubHeaderStart,
-          TemplateMap->ExceptionStubHeaderSize
+          TemplateMap->HookAfterStubHeaderSize
           );
         AsmVectorNumFixup (
           (VOID *)ReservedVectors[Index].HookAfterStubHeaderCode,
@@ -279,7 +279,7 @@ InitializeCpuExceptionHandlersWorker (
 
   IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;
   AsmGetTemplateAddressMap (&TemplateMap);
-  ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);
+  ASSERT (TemplateMap.HookAfterStubHeaderSize <= HOOKAFTER_STUB_SIZE);
 
   UpdateIdtTable (IdtTable, &TemplateMap, ExceptionHandlerData);
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
index 55acb46ebe..827bcd0e36 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
@@ -32,7 +32,7 @@
 [Sources.X64]
   X64/ArchExceptionHandler.c
   X64/ArchInterruptDefs.h
-  X64/SecPeiExceptionHandlerAsm.nasm
+  X64/ExceptionHandlerAsm.nasm
 
 [Sources.Ia32, Sources.X64]
   CpuExceptionCommon.h
@@ -74,4 +74,4 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard                    ## CONSUMES
 
 [BuildOptions]
-  XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT
+  *_*_*_NASM_FLAGS  = -DCEHL_MINIMAL_INTERRUPTS
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
index ef835ee9dc..de88041442 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
@@ -60,8 +60,8 @@
 [FeaturePcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard                    ## CONSUMES
 
-[BuildOptions]
-  XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT
-
 [Guids]
   gEfiDebugImageInfoTableGuid  ## CONSUMES ## SystemTable
+
+[BuildOptions]
+  *_*_*_NASM_FLAGS = -DCEHL_SUPPORTS_CET
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
index 3d64ac9080..4863686f14 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
@@ -36,6 +36,12 @@ struc IA32_IDT_GATE_DESCRIPTOR
   .Reserved_1                    CTYPE_UINT32 1
 endstruc
 
+%ifdef CEHL_MINIMAL_INTERRUPTS
+%define NUM_VECTORS 32
+%else
+%define NUM_VECTORS 256
+%endif
+
 ;
 ; CommonExceptionHandler()
 ;
@@ -53,17 +59,14 @@ SECTION .text
 
 ALIGN   8
 
-; Generate 256 IDT vectors.
+; Generate NUM_VECTORS IDT vectors.
 AsmIdtVectorBegin:
 %assign Vector 0
-%rep  256
+%rep  NUM_VECTORS
     push    strict dword %[Vector] ; This instruction pushes sign-extended 8-byte value on stack
     push    rax
-%ifdef NO_ABSOLUTE_RELOCS_IN_TEXT
-    mov     rax, strict qword 0    ; mov     rax, ASM_PFX(CommonInterruptEntry)
-%else
-    mov     rax, ASM_PFX(CommonInterruptEntry)
-%endif
+    ; This code is not copied, thus relative addressing is safe.
+    lea     rax, [ASM_PFX(CommonInterruptEntry)]
     jmp     rax
 %assign Vector Vector+1
 %endrep
@@ -73,12 +76,9 @@ HookAfterStubHeaderBegin:
     push    strict dword 0      ; 0 will be fixed
 VectorNum:
     push    rax
-%ifdef NO_ABSOLUTE_RELOCS_IN_TEXT
-    mov     rax, strict qword 0 ;     mov     rax, HookAfterStubHeaderEnd
-JmpAbsoluteAddress:
-%else
+    ; This code is copied, thus relative addressing would not be safe and we
+    ; need to utilize the absolute address.
     mov     rax, HookAfterStubHeaderEnd
-%endif
     jmp     rax
 HookAfterStubHeaderEnd:
     mov     rax, rsp
@@ -308,6 +308,7 @@ DrFinish:
     call    ASM_PFX(CommonExceptionHandler)
     add     rsp, 4 * 8 + 8
 
+%ifdef CEHL_SUPPORTS_CET
     ; The follow algorithm is used for clear shadow stack token busy bit.
     ; The comment is based on the sample shadow stack.
     ; Shadow stack is 32 bytes aligned.
@@ -354,6 +355,7 @@ DrFinish:
     mov     rax, 0x01           ; Pop off the new save token created
     incsspq rax                 ; SSP should be 0xFC0 now
 CetDone:
+%endif
 
     cli
 ;; UINT64  ExceptionData;
@@ -461,23 +463,10 @@ global ASM_PFX(AsmGetTemplateAddressMap)
 ASM_PFX(AsmGetTemplateAddressMap):
     lea     rax, [AsmIdtVectorBegin]
     mov     qword [rcx], rax
-    mov     qword [rcx + 0x8],  (AsmIdtVectorEnd - AsmIdtVectorBegin) / 256
+    mov     qword [rcx + 0x8],  (AsmIdtVectorEnd - AsmIdtVectorBegin) / NUM_VECTORS
     lea     rax, [HookAfterStubHeaderBegin]
     mov     qword [rcx + 0x10], rax
-
-%ifdef NO_ABSOLUTE_RELOCS_IN_TEXT
-; Fix up CommonInterruptEntry address
-    lea    rax, [ASM_PFX(CommonInterruptEntry)]
-    lea    rcx, [AsmIdtVectorBegin]
-%rep  256
-    mov    qword [rcx + (JmpAbsoluteAddress - 8 - HookAfterStubHeaderBegin)], rax
-    add    rcx, (AsmIdtVectorEnd - AsmIdtVectorBegin) / 256
-%endrep
-; Fix up HookAfterStubHeaderEnd
-    lea    rax, [HookAfterStubHeaderEnd]
-    lea    rcx, [JmpAbsoluteAddress]
-    mov    qword [rcx - 8], rax
-%endif
+    mov     qword [rcx + 0x18], HookAfterStubHeaderEnd - HookAfterStubHeaderBegin
 
     ret
 
@@ -489,4 +478,3 @@ ASM_PFX(AsmVectorNumFixup):
     mov     rax, rdx
     mov     [rcx + (VectorNum - 4 - HookAfterStubHeaderBegin)], al
     ret
-
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm
deleted file mode 100644
index 5c7a59c99d..0000000000
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm
+++ /dev/null
@@ -1,406 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.<BR>
-; SPDX-License-Identifier: BSD-2-Clause-Patent
-;
-; Module Name:
-;
-;   ExceptionHandlerAsm.Asm
-;
-; Abstract:
-;
-;   x64 CPU Exception Handler
-;
-; Notes:
-;
-;------------------------------------------------------------------------------
-
-;
-; CommonExceptionHandler()
-;
-
-%define VC_EXCEPTION 29
-
-extern ASM_PFX(mErrorCodeFlag)    ; Error code flags for exceptions
-extern ASM_PFX(mDoFarReturnFlag)  ; Do far return flag
-extern ASM_PFX(CommonExceptionHandler)
-
-SECTION .data
-
-DEFAULT REL
-%ifndef NO_ABSOLUTE_RELOCS_IN_TEXT
-SECTION .text
-%endif
-
-ALIGN   8
-
-; Generate 32 IDT vectors.
-; 32 IDT vectors are enough because interrupts (32+) are not enabled in SEC and PEI phase.
-AsmIdtVectorBegin:
-%assign Vector 0
-%rep  32
-    push    byte %[Vector]
-    push    rax
-    mov     rax, ASM_PFX(CommonInterruptEntry)
-    jmp     rax
-%assign Vector Vector+1
-%endrep
-AsmIdtVectorEnd:
-
-HookAfterStubHeaderBegin:
-    db      0x6a        ; push
-@VectorNum:
-    db      0          ; 0 will be fixed
-    push    rax
-    mov     rax, HookAfterStubHeaderEnd
-    jmp     rax
-
-SECTION .text
-
-HookAfterStubHeaderEnd:
-    mov     rax, rsp
-    and     sp,  0xfff0        ; make sure 16-byte aligned for exception context
-    sub     rsp, 0x18           ; reserve room for filling exception data later
-    push    rcx
-    mov     rcx, [rax + 8]
-    bt      [ASM_PFX(mErrorCodeFlag)], ecx
-    jnc     .0
-    push    qword [rsp]             ; push additional rcx to make stack alignment
-.0:
-    xchg    rcx, [rsp]        ; restore rcx, save Exception Number in stack
-    push    qword [rax]             ; push rax into stack to keep code consistence
-
-;---------------------------------------;
-; CommonInterruptEntry                  ;
-;---------------------------------------;
-; The follow algorithm is used for the common interrupt routine.
-; Entry from each interrupt with a push eax and eax=interrupt number
-; Stack frame would be as follows as specified in IA32 manuals:
-;
-; +---------------------+ <-- 16-byte aligned ensured by processor
-; +    Old SS           +
-; +---------------------+
-; +    Old RSP          +
-; +---------------------+
-; +    RFlags           +
-; +---------------------+
-; +    CS               +
-; +---------------------+
-; +    RIP              +
-; +---------------------+
-; +    Error Code       +
-; +---------------------+
-; +   Vector Number     +
-; +---------------------+
-; +    RBP              +
-; +---------------------+ <-- RBP, 16-byte aligned
-; The follow algorithm is used for the common interrupt routine.
-global ASM_PFX(CommonInterruptEntry)
-ASM_PFX(CommonInterruptEntry):
-    cli
-    pop     rax
-    ;
-    ; All interrupt handlers are invoked through interrupt gates, so
-    ; IF flag automatically cleared at the entry point
-    ;
-    xchg    rcx, [rsp]      ; Save rcx into stack and save vector number into rcx
-    and     rcx, 0xFF
-    cmp     ecx, 32         ; Intel reserved vector for exceptions?
-    jae     NoErrorCode
-    bt      [ASM_PFX(mErrorCodeFlag)], ecx
-    jc      HasErrorCode
-
-NoErrorCode:
-
-    ;
-    ; Push a dummy error code on the stack
-    ; to maintain coherent stack map
-    ;
-    push    qword [rsp]
-    mov     qword [rsp + 8], 0
-HasErrorCode:
-    push    rbp
-    mov     rbp, rsp
-    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
-    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
-
-    ;
-    ; Stack:
-    ; +---------------------+ <-- 16-byte aligned ensured by processor
-    ; +    Old SS           +
-    ; +---------------------+
-    ; +    Old RSP          +
-    ; +---------------------+
-    ; +    RFlags           +
-    ; +---------------------+
-    ; +    CS               +
-    ; +---------------------+
-    ; +    RIP              +
-    ; +---------------------+
-    ; +    Error Code       +
-    ; +---------------------+
-    ; + RCX / Vector Number +
-    ; +---------------------+
-    ; +    RBP              +
-    ; +---------------------+ <-- RBP, 16-byte aligned
-    ;
-
-    ;
-    ; Since here the stack pointer is 16-byte aligned, so
-    ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
-    ; is 16-byte aligned
-    ;
-
-;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
-    push r15
-    push r14
-    push r13
-    push r12
-    push r11
-    push r10
-    push r9
-    push r8
-    push rax
-    push qword [rbp + 8]   ; RCX
-    push rdx
-    push rbx
-    push qword [rbp + 48]  ; RSP
-    push qword [rbp]       ; RBP
-    push rsi
-    push rdi
-
-;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero
-    movzx   rax, word [rbp + 56]
-    push    rax                      ; for ss
-    movzx   rax, word [rbp + 32]
-    push    rax                      ; for cs
-    mov     rax, ds
-    push    rax
-    mov     rax, es
-    push    rax
-    mov     rax, fs
-    push    rax
-    mov     rax, gs
-    push    rax
-
-    mov     [rbp + 8], rcx               ; save vector number
-
-;; UINT64  Rip;
-    push    qword [rbp + 24]
-
-;; UINT64  Gdtr[2], Idtr[2];
-    xor     rax, rax
-    push    rax
-    push    rax
-    sidt    [rsp]
-    mov     bx, word [rsp]
-    mov     rax, qword [rsp + 2]
-    mov     qword [rsp], rax
-    mov     word [rsp + 8], bx
-
-    xor     rax, rax
-    push    rax
-    push    rax
-    sgdt    [rsp]
-    mov     bx, word [rsp]
-    mov     rax, qword [rsp + 2]
-    mov     qword [rsp], rax
-    mov     word [rsp + 8], bx
-
-;; UINT64  Ldtr, Tr;
-    xor     rax, rax
-    str     ax
-    push    rax
-    sldt    ax
-    push    rax
-
-;; UINT64  RFlags;
-    push    qword [rbp + 40]
-
-;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
-    mov     rax, cr8
-    push    rax
-    mov     rax, cr4
-    or      rax, 0x208
-    mov     cr4, rax
-    push    rax
-    mov     rax, cr3
-    push    rax
-    mov     rax, cr2
-    push    rax
-    xor     rax, rax
-    push    rax
-    mov     rax, cr0
-    push    rax
-
-;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-    cmp     qword [rbp + 8], VC_EXCEPTION
-    je      VcDebugRegs          ; For SEV-ES (#VC) Debug registers ignored
-
-    mov     rax, dr7
-    push    rax
-    mov     rax, dr6
-    push    rax
-    mov     rax, dr3
-    push    rax
-    mov     rax, dr2
-    push    rax
-    mov     rax, dr1
-    push    rax
-    mov     rax, dr0
-    push    rax
-    jmp     DrFinish
-
-VcDebugRegs:
-;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception recursion
-    xor     rax, rax
-    push    rax
-    push    rax
-    push    rax
-    push    rax
-    push    rax
-    push    rax
-
-DrFinish:
-;; FX_SAVE_STATE_X64 FxSaveState;
-    sub rsp, 512
-    mov rdi, rsp
-    fxsave [rdi]
-
-;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
-    cld
-
-;; UINT32  ExceptionData;
-    push    qword [rbp + 16]
-
-;; Prepare parameter and call
-    mov     rcx, [rbp + 8]
-    mov     rdx, rsp
-    ;
-    ; Per X64 calling convention, allocate maximum parameter stack space
-    ; and make sure RSP is 16-byte aligned
-    ;
-    sub     rsp, 4 * 8 + 8
-    call    ASM_PFX(CommonExceptionHandler)
-    add     rsp, 4 * 8 + 8
-
-    cli
-;; UINT64  ExceptionData;
-    add     rsp, 8
-
-;; FX_SAVE_STATE_X64 FxSaveState;
-
-    mov rsi, rsp
-    fxrstor [rsi]
-    add rsp, 512
-
-;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-;; Skip restoration of DRx registers to support in-circuit emualators
-;; or debuggers set breakpoint in interrupt/exception context
-    add     rsp, 8 * 6
-
-;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
-    pop     rax
-    mov     cr0, rax
-    add     rsp, 8   ; not for Cr1
-    pop     rax
-    mov     cr2, rax
-    pop     rax
-    mov     cr3, rax
-    pop     rax
-    mov     cr4, rax
-    pop     rax
-    mov     cr8, rax
-
-;; UINT64  RFlags;
-    pop     qword [rbp + 40]
-
-;; UINT64  Ldtr, Tr;
-;; UINT64  Gdtr[2], Idtr[2];
-;; Best not let anyone mess with these particular registers...
-    add     rsp, 48
-
-;; UINT64  Rip;
-    pop     qword [rbp + 24]
-
-;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;
-    pop     rax
-    ; mov     gs, rax ; not for gs
-    pop     rax
-    ; mov     fs, rax ; not for fs
-    ; (X64 will not use fs and gs, so we do not restore it)
-    pop     rax
-    mov     es, rax
-    pop     rax
-    mov     ds, rax
-    pop     qword [rbp + 32]  ; for cs
-    pop     qword [rbp + 56]  ; for ss
-
-;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
-    pop     rdi
-    pop     rsi
-    add     rsp, 8               ; not for rbp
-    pop     qword [rbp + 48] ; for rsp
-    pop     rbx
-    pop     rdx
-    pop     rcx
-    pop     rax
-    pop     r8
-    pop     r9
-    pop     r10
-    pop     r11
-    pop     r12
-    pop     r13
-    pop     r14
-    pop     r15
-
-    mov     rsp, rbp
-    pop     rbp
-    add     rsp, 16
-    cmp     qword [rsp - 32], 0  ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
-    jz      DoReturn
-    cmp     qword [rsp - 40], 1  ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
-    jz      ErrorCode
-    jmp     qword [rsp - 32]
-ErrorCode:
-    sub     rsp, 8
-    jmp     qword [rsp - 24]
-
-DoReturn:
-    cmp     qword [ASM_PFX(mDoFarReturnFlag)], 0   ; Check if need to do far return instead of IRET
-    jz      DoIret
-    push    rax
-    mov     rax, rsp          ; save old RSP to rax
-    mov     rsp, [rsp + 0x20]
-    push    qword [rax + 0x10]       ; save CS in new location
-    push    qword [rax + 0x8]        ; save EIP in new location
-    push    qword [rax + 0x18]       ; save EFLAGS in new location
-    mov     rax, [rax]        ; restore rax
-    popfq                     ; restore EFLAGS
-    retfq
-DoIret:
-    iretq
-
-;-------------------------------------------------------------------------------------
-;  GetTemplateAddressMap (&AddressMap);
-;-------------------------------------------------------------------------------------
-; comments here for definition of address map
-global ASM_PFX(AsmGetTemplateAddressMap)
-ASM_PFX(AsmGetTemplateAddressMap):
-    lea     rax, [AsmIdtVectorBegin]
-    mov     qword [rcx], rax
-    mov     qword [rcx + 0x8],  (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32
-    lea     rax, [HookAfterStubHeaderBegin]
-    mov     qword [rcx + 0x10], rax
-    ret
-
-;-------------------------------------------------------------------------------------
-;  AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);
-;-------------------------------------------------------------------------------------
-global ASM_PFX(AsmVectorNumFixup)
-ASM_PFX(AsmVectorNumFixup):
-    mov     rax, rdx
-    mov     [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al
-    ret
-