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