UefiCpuPkg owner,

Please review.

UefiCpuPkg: CpuExceptionHandlerLib: Make self modifying code work with Xcode

CpuExceptionHandlerLib has code that contains absolute relocations, not 
supported by
Xcode for X64, and it then copies this code to an alternate location in memory. 
It is 
very hard to write IP relative self-modifiying code. I had to update 
AsmVectorNumFixup()
to also patch in the absolute addressess after the code was copied. 

I also increased the size of mReservedVectorsData to remove a buffer overflow.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anderw Fish <[email protected]>

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 1b899b3..e361586 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -208,13 +208,16 @@ ArchRestoreExceptionContext (
  
   @param[in] VectorBase   Base address of the vector handler.
   @param[in] VectorNum    Index of vector.
+  @param[in] HookStub     TRUE  HookAfterStubHeaderEnd.
+                          FALSE HookAfterStubHeaderEnd
 
 **/
 VOID
 EFIAPI
 AsmVectorNumFixup (
   IN VOID    *VectorBase,
-  IN UINT8   VectorNum
+  IN UINT8   VectorNum,
+  IN BOOLEAN HookStub
   );
 
 /**
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
index c38f0e1..f02355e 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
@@ -119,7 +119,7 @@ InitializeCpuInterruptHandlers (
       (VOID *) TemplateMap.ExceptionStart,
       TemplateMap.ExceptionStubHeaderSize
       );
-    AsmVectorNumFixup ((VOID *) InterruptEntry, (UINT8) Index);
+    AsmVectorNumFixup ((VOID *) InterruptEntry, (UINT8) Index, FALSE);
     InterruptEntry += TemplateMap.ExceptionStubHeaderSize;
   }
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
index daa6330..4829016 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
@@ -25,8 +25,8 @@ SPIN_LOCK        mDisplayMessageSpinLock;
 //
 CONST UINTN      mImageAlignSize = SIZE_4KB;
 
-RESERVED_VECTORS_DATA       mReservedVectorsData[CPU_EXCEPTION_NUM];
-EFI_CPU_INTERRUPT_HANDLER   mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];
+RESERVED_VECTORS_DATA       mReservedVectorsData[CPU_INTERRUPT_NUM];
+EFI_CPU_INTERRUPT_HANDLER   mExternalInterruptHandlerTable[CPU_INTERRUPT_NUM];
 EFI_CPU_INTERRUPT_HANDLER   *mExternalInterruptHandler = NULL;
 UINTN                       mEnabledInterruptNum = 0;
 
@@ -166,7 +166,7 @@ UpdateIdtTable (
         (VOID *) TemplateMap->HookAfterStubHeaderStart,
         TemplateMap->ExceptionStubHeaderSize
         );
-      AsmVectorNumFixup ((VOID *) 
mReservedVectors[Index].HookAfterStubHeaderCode, (UINT8) Index);
+      AsmVectorNumFixup ((VOID *) 
mReservedVectors[Index].HookAfterStubHeaderCode, (UINT8) Index, TRUE);
       //
       // Go on the following code
       //
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
index 387b4b2..086e896 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
@@ -632,7 +632,7 @@ ASM_PFX(AsmGetTemplateAddressMap):
         popl        %ebp
         ret
 
#-------------------------------------------------------------------------------------
-#  AsmVectorNumFixup (*VectorBase, VectorNum);
+#  AsmVectorNumFixup (*VectorBase, VectorNum, HookStub);
 
#-------------------------------------------------------------------------------------
 ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)
 ASM_PFX(AsmVectorNumFixup):
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
index 74d4e89..90da51b 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
@@ -434,7 +434,7 @@ AsmGetTemplateAddressMap  proc near public
 AsmGetTemplateAddressMap  ENDP
 
 
;-------------------------------------------------------------------------------------
-;  AsmVectorNumFixup (*VectorBase, VectorNum);
+;  AsmVectorNumFixup (*VectorBase, VectorNum, HookStub);
 
;-------------------------------------------------------------------------------------
 AsmVectorNumFixup   proc near public
     mov     eax, dword ptr [esp + 8]
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
index 233dbcb..96871f1 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
@@ -23,12 +23,11 @@
 
 
 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
-ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
 
 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
 #EXTRN ASM_PFX(mDoFarReturnFlag):QWORD  # Do far return flag
 .text
+.align 3
 
 #
 # exception handler stub table
@@ -38,233 +37,234 @@ Exception0Handle:
     .byte   0
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception1Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   1
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception2Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   2
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception3Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   3
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception4Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   4
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception5Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   5
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception6Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   6
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception7Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   7
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception8Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   8
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception9Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   9
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception10Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   10
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception11Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   11
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception12Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   12
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception13Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   13
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception14Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   14
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception15Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   15
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception16Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   16
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception17Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   17
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception18Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   18
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception19Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   19
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception20Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   20
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception21Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   21
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception22Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   22
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception23Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   23
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception24Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   24
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception25Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   25
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception26Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   26
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception27Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   27
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception28Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   28
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception29Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   29
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception30Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   30
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
 Exception31Handle:
     .byte   0x6a    #  push #VectorNum
     .byte   31
     pushq   %rax
     .byte   0x48, 0xB8
-    .quad   ASM_PFX(CommonInterruptEntry)
+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)
     jmp     *%rax
     
 HookAfterStubHeaderBegin:
     .byte   0x6a      # push
-VectorNum:
+PatchVectorNum:
     .byte   0         # 0 will be fixed 
     pushq   %rax
     .byte   0x48, 0xB8      # movq    ASM_PFX(HookAfterStubHeaderEnd), %rax
-    .quad   ASM_PFX(HookAfterStubHeaderEnd)
+PatchFuncAddress:
+    .quad   0               # patch with ASM_PFX(HookAfterStubHeaderEnd)
     jmp     *%rax
 ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
 ASM_PFX(HookAfterStubHeaderEnd):
@@ -273,10 +273,7 @@ ASM_PFX(HookAfterStubHeaderEnd):
     subq    $0x18, %rsp         # reserve room for filling exception data later
     pushq   %rcx
     movq    8(%rax), %rcx
-    pushq   %rax
-    movabsl ASM_PFX(mErrorCodeFlag), %eax
-    bt      %ecx, %eax
-    popq    %rax
+    bt      %ecx, ASM_PFX(mErrorCodeFlag)(%rip)
     jnc     NoErrorData
     pushq   (%rsp)            # push additional rcx to make stack alignment
 NoErrorData:
@@ -304,7 +301,7 @@ ASM_PFX(CommonInterruptEntry):
     cmp     $32, %ecx          # Intel reserved vector for exceptions?
     jae     NoErrorCode
     pushq   %rax
-    movabsl ASM_PFX(mErrorCodeFlag), %eax
+    movl    ASM_PFX(mErrorCodeFlag)(%rip), %eax
     bt      %ecx, %eax
     popq    %rax
     jc      CommonInterruptEntry_al_0000
@@ -553,7 +550,7 @@ ErrorCode:
 
 DoReturn:
     pushq   %rax
-    movabsq ASM_PFX(mDoFarReturnFlag), %rax
+    movq    ASM_PFX(mDoFarReturnFlag)(%rip), %rax
     cmpq    $0, %rax          # Check if need to do far return instead of IRET
     popq    %rax
     jz      DoIret
@@ -566,7 +563,11 @@ DoReturn:
     movq    (%rax), %rax      # restore rax
     popfq                     # restore EFLAGS
     .byte   0x48              # prefix to composite "retq" with next "retf"
+#ifdef __APPLE__
+    .byte   0xCB
+#else
     retf                      # far return
+#endif
 DoIret:
     iretq
 
@@ -578,21 +579,39 @@ DoIret:
 ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)
 ASM_PFX(AsmGetTemplateAddressMap):
 
-        movabsq      $Exception0Handle, %rax
-        movq         %rax, (%rcx)
-        movq         $(Exception1Handle - Exception0Handle), 0x08(%rcx)
-        movabsq      $HookAfterStubHeaderBegin, %rax
-        movq         %rax, 0x10(%rcx)
-        ret
+    leaq         Exception0Handle(%rip), %rax
+    movq         %rax, (%rcx)
+    movq         $(Exception1Handle - Exception0Handle), 0x08(%rcx)
+    leaq         HookAfterStubHeaderBegin(%rip), %rax
+    movq         %rax, 0x10(%rcx)
+    ret
 
 
#-------------------------------------------------------------------------------------
-#  AsmVectorNumFixup (*VectorBase, VectorNum);
+# VOID
+# EFIAPI
+# AsmVectorNumFixup (
+#   IN VOID    *VectorBase,  // RCX
+#   IN UINT8   VectorNum,    // RDX
+#   IN BOOLEAN HookStub      // R8
+#  );
 
#-------------------------------------------------------------------------------------
 ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)
 ASM_PFX(AsmVectorNumFixup):
-        movq  %rdx, %rax
-        movb  %al, (VectorNum - HookAfterStubHeaderBegin)(%rcx)
-        ret
+    pushq     %rbp
+    movq      %rsp, %rbp
+
+# Patch vector #
+    movb      %dl, (PatchVectorNum - HookAfterStubHeaderBegin)(%rcx)
+
+# Patch Function address
+    leaq      ASM_PFX(HookAfterStubHeaderEnd)(%rip), %rax
+    leaq      ASM_PFX(CommonInterruptEntry)(%rip), %r10
+    testb     %r8b, %r8b
+    cmovneq   %rax, %r10
+    movq       %r10, (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx)
+
+    popq      %rbp
+    ret
 
 #END
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
index 59bec59..dfb66e2 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
@@ -378,7 +378,7 @@ AsmGetTemplateAddressMap   PROC
 AsmGetTemplateAddressMap   ENDP
 
 
;-------------------------------------------------------------------------------------
-;  AsmVectorNumFixup (*VectorBase, VectorNum);
+;  AsmVectorNumFixup (*VectorBase, VectorNum, HookStub);
 
;-------------------------------------------------------------------------------------
 AsmVectorNumFixup   PROC
     mov     rax, rdx

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to