]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
UefiCpuPkg: CpuExceptionHandlerLib: Make self modifying code work with Xcode
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / X64 / ExceptionHandlerAsm.S
index 233dbcbcc536e0d6b990635dd8d517b56ee4acd5..f371fd350adef7a640c484d7f519d1fc06daa43e 100644 (file)
 \r
 \r
 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
-ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
 \r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD    # Error code flags for exceptions\r
 #EXTRN ASM_PFX(mDoFarReturnFlag):QWORD  # Do far return flag\r
 .text\r
 \r
-#\r
-# exception handler stub table\r
-#\r
-Exception0Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   0\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception1Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   1\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception2Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   2\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception3Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   3\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception4Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   4\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception5Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   5\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception6Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   6\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception7Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   7\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception8Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   8\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception9Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   9\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception10Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   10\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception11Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   11\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception12Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   12\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception13Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   13\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception14Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   14\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception15Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   15\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception16Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   16\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception17Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   17\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception18Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   18\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception19Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   19\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception20Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   20\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception21Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   21\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception22Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   22\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception23Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   23\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception24Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   24\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception25Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   25\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception26Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   26\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception27Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   27\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception28Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   28\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception29Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   29\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception30Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   30\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-Exception31Handle:\r
-    .byte   0x6a    #  push #VectorNum\r
-    .byte   31\r
-    pushq   %rax\r
-    .byte   0x48, 0xB8\r
-    .quad   ASM_PFX(CommonInterruptEntry)\r
-    jmp     *%rax\r
-    \r
+#ifdef __APPLE__\r
+# macros are different between GNU and Xcode as. \r
+.macro IDT_MACRO \r
+  push     $0\r
+#else\r
+.macro IDT_MACRO arg\r
+  push    \arg\r
+#endif\r
+  jmp    ASM_PFX(CommonInterruptEntry)\r
+.endm\r
+\r
+AsmIdtVectorBegin:\r
+  IDT_MACRO $0\r
+  IDT_MACRO $1\r
+  IDT_MACRO $2\r
+  IDT_MACRO $3\r
+  IDT_MACRO $4\r
+  IDT_MACRO $5\r
+  IDT_MACRO $6\r
+  IDT_MACRO $7\r
+  IDT_MACRO $8\r
+  IDT_MACRO $9\r
+  IDT_MACRO $10\r
+  IDT_MACRO $11\r
+  IDT_MACRO $12\r
+  IDT_MACRO $13\r
+  IDT_MACRO $14\r
+  IDT_MACRO $15\r
+  IDT_MACRO $16\r
+  IDT_MACRO $17\r
+  IDT_MACRO $18\r
+  IDT_MACRO $19\r
+  IDT_MACRO $20\r
+  IDT_MACRO $21\r
+  IDT_MACRO $22\r
+  IDT_MACRO $23\r
+  IDT_MACRO $24\r
+  IDT_MACRO $25\r
+  IDT_MACRO $26\r
+  IDT_MACRO $27\r
+  IDT_MACRO $28\r
+  IDT_MACRO $29\r
+  IDT_MACRO $30\r
+  IDT_MACRO $31\r
+AsmIdtVectorEnd:\r
+\r
 HookAfterStubHeaderBegin:\r
     .byte   0x6a      # push\r
-VectorNum:\r
+PatchVectorNum:\r
     .byte   0         # 0 will be fixed \r
-    pushq   %rax\r
-    .byte   0x48, 0xB8      # movq    ASM_PFX(HookAfterStubHeaderEnd), %rax\r
-    .quad   ASM_PFX(HookAfterStubHeaderEnd)\r
-    jmp     *%rax\r
+    .byte   0xe9      # jmp     ASM_PFX(HookAfterStubHeaderEnd)\r
+PatchFuncAddress:\r
+     .set   HOOK_ADDRESS, ASM_PFX(HookAfterStubHeaderEnd) - . - 4\r
+    .long   HOOK_ADDRESS  # will be fixed\r
 ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
 ASM_PFX(HookAfterStubHeaderEnd):\r
+    pushq   %rax\r
     movq    %rsp, %rax\r
     andl    $0x0fffffff0, %esp  # make sure 16-byte aligned for exception context\r
     subq    $0x18, %rsp         # reserve room for filling exception data later\r
     pushq   %rcx\r
     movq    8(%rax), %rcx\r
-    pushq   %rax\r
-    movabsl ASM_PFX(mErrorCodeFlag), %eax\r
-    bt      %ecx, %eax\r
-    popq    %rax\r
+    bt      %ecx, ASM_PFX(mErrorCodeFlag)(%rip)\r
     jnc     NoErrorData\r
     pushq   (%rsp)            # push additional rcx to make stack alignment\r
 NoErrorData:\r
     xchgq   (%rsp), %rcx      # restore rcx, save Exception Number in stack\r
-    pushq   (%rax)            # push rax into stack to keep code consistence\r
+    movq    (%rax), %rax      # restore rax\r
 \r
 #---------------------------------------;\r
 # CommonInterruptEntry                  ;\r
@@ -291,7 +105,6 @@ NoErrorData:
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
 ASM_PFX(CommonInterruptEntry):\r
     cli\r
-    popq    %rax\r
     #\r
     # All interrupt handlers are invoked through interrupt gates, so\r
     # IF flag automatically cleared at the entry point\r
@@ -304,7 +117,7 @@ ASM_PFX(CommonInterruptEntry):
     cmp     $32, %ecx          # Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     pushq   %rax\r
-    movabsl ASM_PFX(mErrorCodeFlag), %eax\r
+    movl    ASM_PFX(mErrorCodeFlag)(%rip), %eax\r
     bt      %ecx, %eax\r
     popq    %rax\r
     jc      CommonInterruptEntry_al_0000\r
@@ -553,7 +366,7 @@ ErrorCode:
 \r
 DoReturn:\r
     pushq   %rax\r
-    movabsq ASM_PFX(mDoFarReturnFlag), %rax\r
+    movq    ASM_PFX(mDoFarReturnFlag)(%rip), %rax\r
     cmpq    $0, %rax          # Check if need to do far return instead of IRET\r
     popq    %rax\r
     jz      DoIret\r
@@ -566,7 +379,11 @@ DoReturn:
     movq    (%rax), %rax      # restore rax\r
     popfq                     # restore EFLAGS\r
     .byte   0x48              # prefix to composite "retq" with next "retf"\r
+#ifdef __APPLE__\r
+    .byte   0xCB\r
+#else\r
     retf                      # far return\r
+#endif\r
 DoIret:\r
     iretq\r
 \r
@@ -577,22 +394,44 @@ DoIret:
 # comments here for definition of address map\r
 ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)\r
 ASM_PFX(AsmGetTemplateAddressMap):\r
+    pushq     %rbp\r
+    movq      %rsp, %rbp\r
+\r
+    leaq         AsmIdtVectorBegin(%rip), %rax\r
+    movq         %rax, (%rcx)\r
+    .set         ENTRY_SIZE, ASM_PFX(HookAfterStubHeaderEnd) - HookAfterStubHeaderBegin\r
+    movq         $(ENTRY_SIZE), 0x08(%rcx)\r
+    leaq         HookAfterStubHeaderBegin(%rip), %rax\r
+    movq         %rax, 0x10(%rcx)\r
 \r
-        movabsq      $Exception0Handle, %rax\r
-        movq         %rax, (%rcx)\r
-        movq         $(Exception1Handle - Exception0Handle), 0x08(%rcx)\r
-        movabsq      $HookAfterStubHeaderBegin, %rax\r
-        movq         %rax, 0x10(%rcx)\r
-        ret\r
+    popq      %rbp\r
+    ret\r
 \r
 #-------------------------------------------------------------------------------------\r
-#  AsmVectorNumFixup (*VectorBase, VectorNum);\r
+# VOID\r
+# EFIAPI\r
+# AsmVectorNumFixup (\r
+#   IN VOID    *NewVectorAddr,  // RCX\r
+#   IN UINT8   VectorNum        // RDX\r
+#   IN VOID    *OldVectorAddr,  // R8\r
+#  );\r
 #-------------------------------------------------------------------------------------\r
 ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)\r
 ASM_PFX(AsmVectorNumFixup):\r
-        movq  %rdx, %rax\r
-        movb  %al, (VectorNum - HookAfterStubHeaderBegin)(%rcx)\r
-        ret\r
+    pushq     %rbp\r
+    movq      %rsp, %rbp\r
+\r
+# Patch vector #\r
+    movb      %dl, (PatchVectorNum - HookAfterStubHeaderBegin)(%rcx)\r
+\r
+# Patch Function address\r
+    subq      %rcx, %r8     # Calculate the offset value\r
+    movl      (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx), %eax\r
+    addq      %r8, %rax\r
+    movl      %eax, (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx)\r
+\r
+    popq      %rbp\r
+    ret\r
 \r
 #END\r
 \r