summaryrefslogtreecommitdiff
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorAnderw Fish <afish@apple.com>2014-09-09 06:50:51 +0000
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2014-09-09 06:50:51 +0000
commit07da1ac8c46425cb401cc5f356ab77b9cc1c334d (patch)
treeebe576744f54efd059fd6b1bd2bafcc294f6c97a /UefiCpuPkg
parent19ee4a904982cfacdcb8c578c5d421162fa9488d (diff)
downloadedk2-platforms-07da1ac8c46425cb401cc5f356ab77b9cc1c334d.tar.xz
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. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Anderw Fish <afish@apple.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16068 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h12
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c2
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c6
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S2
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm2
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S347
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm2
7 files changed, 109 insertions, 264 deletions
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 1b899b3024..efe77eb09f 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -204,17 +204,19 @@ ArchRestoreExceptionContext (
);
/**
- Fix up the vector number in the vector code.
+ Fix up the vector number and function address in the vector code.
- @param[in] VectorBase Base address of the vector handler.
- @param[in] VectorNum Index of vector.
+ @param[in] NewVectorAddr New vector handler address.
+ @param[in] VectorNum Index of vector.
+ @param[in] OldVectorAddr Old vector handler address.
**/
VOID
EFIAPI
AsmVectorNumFixup (
- IN VOID *VectorBase,
- IN UINT8 VectorNum
+ IN VOID *NewVectorAddr,
+ IN UINT8 VectorNum,
+ IN VOID *OldVectorAddr
);
/**
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
index c38f0e10dd..6739a2cc3c 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, (VOID *) TemplateMap.ExceptionStart);
InterruptEntry += TemplateMap.ExceptionStubHeaderSize;
}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
index daa6330f5b..d1291aa0eb 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
@@ -166,7 +166,11 @@ UpdateIdtTable (
(VOID *) TemplateMap->HookAfterStubHeaderStart,
TemplateMap->ExceptionStubHeaderSize
);
- AsmVectorNumFixup ((VOID *) mReservedVectors[Index].HookAfterStubHeaderCode, (UINT8) Index);
+ AsmVectorNumFixup (
+ (VOID *) mReservedVectors[Index].HookAfterStubHeaderCode,
+ (UINT8) Index,
+ (VOID *) TemplateMap->HookAfterStubHeaderStart
+ );
//
// Go on the following code
//
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
index 387b4b26bf..e19afbe14d 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 (*NewVectorAddr, VectorNum, *OldVectorAddr);
#-------------------------------------------------------------------------------------
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 74d4e89047..3ff01b2a0c 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 (*NewVectorAddr, VectorNum, *OldVectorAddr);
;-------------------------------------------------------------------------------------
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 233dbcbcc5..f371fd350a 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
@@ -23,265 +23,79 @@
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(mErrorCodeFlag):DWORD # Error code flags for exceptions
#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD # Do far return flag
.text
-#
-# exception handler stub table
-#
-Exception0Handle:
- .byte 0x6a # push #VectorNum
- .byte 0
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception1Handle:
- .byte 0x6a # push #VectorNum
- .byte 1
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception2Handle:
- .byte 0x6a # push #VectorNum
- .byte 2
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception3Handle:
- .byte 0x6a # push #VectorNum
- .byte 3
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception4Handle:
- .byte 0x6a # push #VectorNum
- .byte 4
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception5Handle:
- .byte 0x6a # push #VectorNum
- .byte 5
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception6Handle:
- .byte 0x6a # push #VectorNum
- .byte 6
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception7Handle:
- .byte 0x6a # push #VectorNum
- .byte 7
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception8Handle:
- .byte 0x6a # push #VectorNum
- .byte 8
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception9Handle:
- .byte 0x6a # push #VectorNum
- .byte 9
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception10Handle:
- .byte 0x6a # push #VectorNum
- .byte 10
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception11Handle:
- .byte 0x6a # push #VectorNum
- .byte 11
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception12Handle:
- .byte 0x6a # push #VectorNum
- .byte 12
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception13Handle:
- .byte 0x6a # push #VectorNum
- .byte 13
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception14Handle:
- .byte 0x6a # push #VectorNum
- .byte 14
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception15Handle:
- .byte 0x6a # push #VectorNum
- .byte 15
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception16Handle:
- .byte 0x6a # push #VectorNum
- .byte 16
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception17Handle:
- .byte 0x6a # push #VectorNum
- .byte 17
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception18Handle:
- .byte 0x6a # push #VectorNum
- .byte 18
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception19Handle:
- .byte 0x6a # push #VectorNum
- .byte 19
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception20Handle:
- .byte 0x6a # push #VectorNum
- .byte 20
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception21Handle:
- .byte 0x6a # push #VectorNum
- .byte 21
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception22Handle:
- .byte 0x6a # push #VectorNum
- .byte 22
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception23Handle:
- .byte 0x6a # push #VectorNum
- .byte 23
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception24Handle:
- .byte 0x6a # push #VectorNum
- .byte 24
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception25Handle:
- .byte 0x6a # push #VectorNum
- .byte 25
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception26Handle:
- .byte 0x6a # push #VectorNum
- .byte 26
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception27Handle:
- .byte 0x6a # push #VectorNum
- .byte 27
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception28Handle:
- .byte 0x6a # push #VectorNum
- .byte 28
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception29Handle:
- .byte 0x6a # push #VectorNum
- .byte 29
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception30Handle:
- .byte 0x6a # push #VectorNum
- .byte 30
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-Exception31Handle:
- .byte 0x6a # push #VectorNum
- .byte 31
- pushq %rax
- .byte 0x48, 0xB8
- .quad ASM_PFX(CommonInterruptEntry)
- jmp *%rax
-
+#ifdef __APPLE__
+# macros are different between GNU and Xcode as.
+.macro IDT_MACRO
+ push $0
+#else
+.macro IDT_MACRO arg
+ push \arg
+#endif
+ jmp ASM_PFX(CommonInterruptEntry)
+.endm
+
+AsmIdtVectorBegin:
+ IDT_MACRO $0
+ IDT_MACRO $1
+ IDT_MACRO $2
+ IDT_MACRO $3
+ IDT_MACRO $4
+ IDT_MACRO $5
+ IDT_MACRO $6
+ IDT_MACRO $7
+ IDT_MACRO $8
+ IDT_MACRO $9
+ IDT_MACRO $10
+ IDT_MACRO $11
+ IDT_MACRO $12
+ IDT_MACRO $13
+ IDT_MACRO $14
+ IDT_MACRO $15
+ IDT_MACRO $16
+ IDT_MACRO $17
+ IDT_MACRO $18
+ IDT_MACRO $19
+ IDT_MACRO $20
+ IDT_MACRO $21
+ IDT_MACRO $22
+ IDT_MACRO $23
+ IDT_MACRO $24
+ IDT_MACRO $25
+ IDT_MACRO $26
+ IDT_MACRO $27
+ IDT_MACRO $28
+ IDT_MACRO $29
+ IDT_MACRO $30
+ IDT_MACRO $31
+AsmIdtVectorEnd:
+
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)
- jmp *%rax
+ .byte 0xe9 # jmp ASM_PFX(HookAfterStubHeaderEnd)
+PatchFuncAddress:
+ .set HOOK_ADDRESS, ASM_PFX(HookAfterStubHeaderEnd) - . - 4
+ .long HOOK_ADDRESS # will be fixed
ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
ASM_PFX(HookAfterStubHeaderEnd):
+ pushq %rax
movq %rsp, %rax
andl $0x0fffffff0, %esp # make sure 16-byte aligned for exception context
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:
xchgq (%rsp), %rcx # restore rcx, save Exception Number in stack
- pushq (%rax) # push rax into stack to keep code consistence
+ movq (%rax), %rax # restore rax
#---------------------------------------;
# CommonInterruptEntry ;
@@ -291,7 +105,6 @@ NoErrorData:
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
ASM_PFX(CommonInterruptEntry):
cli
- popq %rax
#
# All interrupt handlers are invoked through interrupt gates, so
# IF flag automatically cleared at the entry point
@@ -304,7 +117,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 +366,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 +379,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
@@ -577,22 +394,44 @@ DoIret:
# comments here for definition of address map
ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)
ASM_PFX(AsmGetTemplateAddressMap):
+ pushq %rbp
+ movq %rsp, %rbp
+
+ leaq AsmIdtVectorBegin(%rip), %rax
+ movq %rax, (%rcx)
+ .set ENTRY_SIZE, ASM_PFX(HookAfterStubHeaderEnd) - HookAfterStubHeaderBegin
+ movq $(ENTRY_SIZE), 0x08(%rcx)
+ leaq HookAfterStubHeaderBegin(%rip), %rax
+ movq %rax, 0x10(%rcx)
- movabsq $Exception0Handle, %rax
- movq %rax, (%rcx)
- movq $(Exception1Handle - Exception0Handle), 0x08(%rcx)
- movabsq $HookAfterStubHeaderBegin, %rax
- movq %rax, 0x10(%rcx)
- ret
+ popq %rbp
+ ret
#-------------------------------------------------------------------------------------
-# AsmVectorNumFixup (*VectorBase, VectorNum);
+# VOID
+# EFIAPI
+# AsmVectorNumFixup (
+# IN VOID *NewVectorAddr, // RCX
+# IN UINT8 VectorNum // RDX
+# IN VOID *OldVectorAddr, // 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
+ subq %rcx, %r8 # Calculate the offset value
+ movl (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx), %eax
+ addq %r8, %rax
+ movl %eax, (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx)
+
+ popq %rbp
+ ret
#END
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
index 59bec5985a..cd21ec4c90 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 (*NewVectorAddr, VectorNum, *OldVectorAddr);
;-------------------------------------------------------------------------------------
AsmVectorNumFixup PROC
mov rax, rdx