summaryrefslogtreecommitdiff
path: root/UefiCpuPkg/Library
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/Library
parent19ee4a904982cfacdcb8c578c5d421162fa9488d (diff)
downloadedk2-07da1ac8c46425cb401cc5f356ab77b9cc1c334d.zip
edk2-07da1ac8c46425cb401cc5f356ab77b9cc1c334d.tar.gz
edk2-07da1ac8c46425cb401cc5f356ab77b9cc1c334d.tar.bz2
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/Library')
-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 1b899b3..efe77eb 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 c38f0e1..6739a2c 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 daa6330..d1291aa 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 387b4b2..e19afbe 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 74d4e89..3ff01b2 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 233dbcb..f371fd3 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 59bec59..cd21ec4 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