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 - movabsq $Exception0Handle, %rax - movq %rax, (%rcx) - movq $(Exception1Handle - Exception0Handle), 0x08(%rcx) - movabsq $HookAfterStubHeaderBegin, %rax - movq %rax, 0x10(%rcx) - ret + 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) + + 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