[if gte mso 9]>

Re: [edk2] [UefiCpuPkg][CpuExceptionHandlerLib] Make self modifying code work with Xcode

Subject: Re: [edk2] [UefiCpuPkg][CpuExceptionHandlerLib] Make self modifying code work with Xcode

From: "Fan, Jeff" <jeff.fan@intel.com>

To: "edk2-devel@lists.sourceforge.net" <edk2-devel@lists.sourceforge.net>

Date: 2014-09-05 23:07:52

Andrew,

 

Could you help to verify if attached patch could work for CLANG?

 

Thanks!

Jeff

 

From: Andrew Fish [mailto:afish@apple.com]
Sent: Friday, September 05, 2014 12:11 AM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] [UefiCpuPkg][CpuExceptionHandlerLib] Make self modifying code work with Xcode

 

 

On Sep 3, 2014, at 8:02 PM, Fan, Jeff <jeff.fan@intel.com> wrote:



Andrew,

 

To support CPU exception handler as early as possible even before temp RAM is ready, IDT table is required to be located at FALSH.  We have to define 32 entries in assembly code. The reason why not to define 256 entries is due to size consideration.

 

 

We played some games to only have exceptions in PEI and the full table in DXE. 



But on DXE phase, we need to support all 256 IDT entries including exception/Interrupt handlers, we need to allocate memory for 256 IDT entries and copy exception handle stub code for each and fixed up vectors.

Exception0Handle:

    .byte   0x6a    #  push #VectorNum

    .byte   1

    pushq   %rax

    .byte   0x48, 0xB8

    .quad   ASM_PFX(CommonInterruptEntry)

    jmp     *%rax

Exception1Handle:

 

Why using jmp *%rax is to avoid relative address reference and we needn’t do fixup this address more.:-)

 

For CLANG, if we have to use relative address instead of absolute address reference. We could use the following code as you proposed. But we need to fix up relative address for JMP instruction.

     push    29

     push   %rax

     jmp     ASM_PFX(CommonInterruptEntry)

 

%rax is not required, but I need to make it consistence for both IDT entries code and HOOK after stub code.

 

I may try this solution.

 

 

I can help test on clang.

 

Thanks,

 

Andrew Fish



Use MACRO is good idea to make code more clean.

 

Thanks!

Jeff

From: Andrew Fish [mailto:afish@apple.com] 
Sent: Thursday, September 04, 2014 12:32 AM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] [UefiCpuPkg][CpuExceptionHandlerLib] Make self modifying code work with Xcode

 

 

On Sep 3, 2014, at 1:50 AM, Fan, Jeff <jeff.fan@intel.com> wrote:




Andrew,

 

Drop .align 3 is ok.

 

I have one another comment on the following updating.

-    .quad   ASM_PFX(CommonInterruptEntry)

+    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)

 

It does not consider the cases that IDT entries is located at FLASH (SEC x64 case or CapsuleX64 case) to support <32 exceptions.

 

We could use the following code to avoid absolute address reference.

movq    ASM_PFX(CommonInterruptEntry)(%rip), %rax

(Binary format is  0x48, 0xB8, 0x05, 0xXX, 0xXX, 0xXX, 0xXX)

 

But it may be hard to do fix-up offset value (32bit value only, not 64bit) for 256 interrupt entries when IDT table is located at physical memory.

 

One possible solution is to use another Exception handler stub code for the case IDT entries located at physical memory.

ExceptionHandleStubBegin:

    .byte   0x6a    #  push #VectorNum

    .byte   29

    pushq   %rax

    .byte   0x48, 0xB8

    .quad   0       # patch with ASM_PFX(CommonInterruptEntry)

    jmp     *%rax

ExceptionHandleStubEnd:

 

Do you have some suggestion?

 

 

I don’t understand why the vector table is being copied in the 1st place? Why not use the table in the library? It is part of the image it is linked with? I tried to make the smallest change possible, not the best fix. Probably better to not burn temp RAM in X64 SEC case. 

 

If the copies are not done then it becomes this (push %rax, not needed):

     push            29

     push   %rax

     jmp     ASM_PFX(CommonInterruptEntry)

 

I guess the hook after case, as coded, requires an entry. If the full table existed you could just point to it. 

 

You could also use a macro on the .S side, but you still don’t have the repeat. 

 

.macro IDT_MACRO

  .byte    0x6a

  .set      $0,   (. - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32)

.byte $0

  pushq   %rax

  jmp      ASM_PFX(CommonInterruptEntry)

.endm

 

ASM_PFX(AsmIdtVectorBegin):

            IDT_MACRO vector0

            IDT_MACRO vector1

            IDT_MACRO vector2

            IDT_MACRO vector3

            IDT_MACRO vector4

            IDT_MACRO vector5

        ….

 

Thanks,

 

Andrew Fish




Thanks!

Jeff

From: Andrew Fish [mailto:afish@apple.com] 
Sent: Wednesday, September 03, 2014 1:46 AM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] [UefiCpuPkg][CpuExceptionHandlerLib] Make self modifying code work with Xcode

 

 

On Sep 2, 2014, at 1:29 AM, Fan, Jeff <jeff.fan@intel.com> wrote:





Andrew,

 

.align 3 cannot pass GCC 4.6 build.  Why do you add it? Is it typo?

 

/DEBUG_GCC46/X64/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib/OUTPUT/X64/ExceptionHandlerAsm.iii:30: Error: alignment not a power of 2

 

 

I was trying to align the IDT entries on an 8 byte boundary. It is not required by the processor, so maybe we can just drop that statement, or use .p2align. 

 

The Xcode assembler treats the the argument to .align as a power of 2, looks like gas does not?

 

GNU assembler:

...

The way the required alignment is specified varies from system to system. For the a29k, hppa, m68k, m88k, w65, sparc, Xtensa, and Renesas / SuperH SH, and i386 using ELF format, the first expression is the alignment request in bytes. For example .align 8 advances the location counter until it is a multiple of 8. If the location counter is already a multiple of 8, no change is needed. 

For other systems, including the i386 using a.out format, and the arm and strongarm, it is the number of low-order zero bits the location counter must have after advancement. For example 
.align 3 advances the location counter until it a multiple of 8. If the location counter is already a multiple of 8, no change is needed. 

This inconsistency is due to the different behaviors of the various native assemblers for these systems which 
as must emulate. as also provides .balign and.p2align directives, which have a consistent behavior across all architectures (but are specific to as).

 

Xcode assembler:

.align

SYNOPSIS

.align    align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]]
.p2align  align_expression [ , 1byte_fill_expression [,max_bytes_to_fill]]
.p2alignw align_expression [ , 2byte_fill_expression [,max_bytes_to_fill]]
.p2alignl align_expression [ , 4byte_fill_expression [,max_bytes_to_fill]]
.align32  align_expression [ , 4byte_fill_expression [,max_bytes_to_fill]]

The align directives advance the location counter to the next align_expression boundary, if it isn't currently on such a boundary. align_expression is a power of 2 between 0 and 15 (for example, the argument of .align 3 means 2 ^ 3 (8)–byte alignment). The fill expression, if specified, must be absolute. The space between the current value of the location counter and the desired value is filled with the fill expression (or with zeros, if fill_expression isn't specified). The space between the current value of the location counter to the alignment of the fill expression width is filled with zeros first. Then the fill expression is used until the desired alignment is reached. max_bytes_to_fill is the maximum number of bytes that are allowed to be filled for the align directive. If the align directive can't be done in max_bytes_to_fill or less, it has no effect. If there is no fill_expression and the section has the pure_instructions attribute, or contains some instructions, the nop opcode is used as the fill expression.





Thanks!

Jeff

From: Andrew Fish [mailto:afish@apple.com] 
Sent: Saturday, August 30, 2014 7:35 AM
To: edk2-devel@lists.sourceforge.net
Subject: [edk2] [UefiCpuPkg][CpuExceptionHandlerLib] Make self modifying code work with Xcode

 

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 <afish@apple.com>

 

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
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

 

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

 

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