Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com>
		
			
				
	
	
		
			668 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			668 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| #------------------------------------------------------------------------------
 | |
| #*
 | |
| #*   Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
 | |
| #*   This program and the accompanying materials
 | |
| #*   are licensed and made available under the terms and conditions of the BSD License
 | |
| #*   which accompanies this distribution.  The full text of the license may be found at
 | |
| #*   http://opensource.org/licenses/bsd-license.php
 | |
| #*
 | |
| #*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| #*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| #*
 | |
| #*    ExceptionHandlerAsm.S
 | |
| #*
 | |
| #*   Abstract:
 | |
| #*
 | |
| #*     IA32 CPU Exception Handler
 | |
| #
 | |
| #------------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| #.MMX
 | |
| #.XMM
 | |
| 
 | |
| 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):DWORD         # Do far return flag
 | |
| 
 | |
| .text
 | |
| 
 | |
| #
 | |
| # exception handler stub table
 | |
| #
 | |
| Exception0Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   0
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception1Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   1
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception2Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   2
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception3Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   3
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception4Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   4
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception5Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   5
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception6Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   6
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception7Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   7
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception8Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   8
 | |
|     pushl   %eax
 | |
|      .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception9Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   9
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception10Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   10
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception11Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   11
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception12Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   12
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception13Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   13
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception14Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   14
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception15Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   15
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception16Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   16
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception17Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   17
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception18Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   18
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception19Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   19
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception20Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   20
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception21Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   21
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception22Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   22
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception23Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   23
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception24Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   24
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception25Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   25
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception26Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   26
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception27Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   27
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception28Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   28
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception29Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   29
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception30Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   30
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| Exception31Handle:
 | |
|     .byte   0x6a    #  push #VectorNum
 | |
|     .byte   31
 | |
|     pushl   %eax
 | |
|     .byte   0xB8
 | |
|     .long   ASM_PFX(CommonInterruptEntry)
 | |
|     jmp     *%eax
 | |
| 
 | |
| HookAfterStubBegin:
 | |
|     .byte   0x6a       # push
 | |
| VectorNum:
 | |
|     .byte   0          # 0 will be fixed
 | |
|     pushl   %eax
 | |
|     .byte   0xB8       # movl    ASM_PFX(HookAfterStubHeaderEnd), %eax
 | |
|     .long   ASM_PFX(HookAfterStubHeaderEnd)
 | |
|     jmp     *%eax
 | |
| ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
 | |
| ASM_PFX(HookAfterStubHeaderEnd):
 | |
|     popl    %eax
 | |
|     subl    $8, %esp        # reserve room for filling exception data later
 | |
|     pushl   8(%esp)
 | |
|     xchgl   (%esp), %ecx    # get vector number
 | |
|     bt      %ecx, ASM_PFX(mErrorCodeFlag)
 | |
|     jnc     NoErrorData
 | |
|     pushl    (%esp)         # addition push if exception data needed
 | |
| NoErrorData:
 | |
|     xchg    (%esp), %ecx    # restore ecx
 | |
|     pushl   %eax
 | |
| 
 | |
| #---------------------------------------;
 | |
| # CommonInterruptEntry                  ;
 | |
| #---------------------------------------;
 | |
| # The follow algorithm is used for the common interrupt routine.
 | |
| 
 | |
| ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
 | |
| ASM_PFX(CommonInterruptEntry):
 | |
|     cli
 | |
|     popl    %eax
 | |
|     #
 | |
|     # All interrupt handlers are invoked through interrupt gates, so
 | |
|     # IF flag automatically cleared at the entry point
 | |
|     #
 | |
| 
 | |
|     #
 | |
|     # Get vector number from top of stack
 | |
|     #
 | |
|     xchgl   (%esp), %ecx
 | |
|     andl    $0x0FF, %ecx      # Vector number should be less than 256
 | |
|     cmpl    $32, %ecx         # Intel reserved vector for exceptions?
 | |
|     jae     NoErrorCode
 | |
|     bt      %ecx, ASM_PFX(mErrorCodeFlag)
 | |
|     jc      HasErrorCode
 | |
| 
 | |
| NoErrorCode:
 | |
| 
 | |
|     #
 | |
|     # Stack:
 | |
|     # +---------------------+
 | |
|     # +    EFlags           +
 | |
|     # +---------------------+
 | |
|     # +    CS               +
 | |
|     # +---------------------+
 | |
|     # +    EIP              +
 | |
|     # +---------------------+
 | |
|     # +    ECX              +
 | |
|     # +---------------------+ <-- ESP
 | |
|     #
 | |
|     # Registers:
 | |
|     #   ECX - Vector Number
 | |
|     #
 | |
| 
 | |
|     #
 | |
|     # Put Vector Number on stack
 | |
|     #
 | |
|     pushl   %ecx
 | |
| 
 | |
|     #
 | |
|     # Put 0 (dummy) error code on stack, and restore ECX
 | |
|     #
 | |
|     xorl    %ecx, %ecx  # ECX = 0
 | |
|     xchgl   4(%esp), %ecx
 | |
| 
 | |
|     jmp     ErrorCodeAndVectorOnStack
 | |
| 
 | |
| HasErrorCode:
 | |
| 
 | |
|     #
 | |
|     # Stack:
 | |
|     # +---------------------+
 | |
|     # +    EFlags           +
 | |
|     # +---------------------+
 | |
|     # +    CS               +
 | |
|     # +---------------------+
 | |
|     # +    EIP              +
 | |
|     # +---------------------+
 | |
|     # +    Error Code       +
 | |
|     # +---------------------+
 | |
|     # +    ECX              +
 | |
|     # +---------------------+ <-- ESP
 | |
|     #
 | |
|     # Registers:
 | |
|     #   ECX - Vector Number
 | |
|     #
 | |
| 
 | |
|     #
 | |
|     # Put Vector Number on stack and restore ECX
 | |
|     #
 | |
|     xchgl   (%esp), %ecx
 | |
| 
 | |
| ErrorCodeAndVectorOnStack:
 | |
|     pushl   %ebp
 | |
|     movl    %esp, %ebp
 | |
| 
 | |
|     #
 | |
|     # Stack:
 | |
|     # +---------------------+
 | |
|     # +    EFlags           +
 | |
|     # +---------------------+
 | |
|     # +    CS               +
 | |
|     # +---------------------+
 | |
|     # +    EIP              +
 | |
|     # +---------------------+
 | |
|     # +    Error Code       +
 | |
|     # +---------------------+
 | |
|     # +    Vector Number    +
 | |
|     # +---------------------+
 | |
|     # +    EBP              +
 | |
|     # +---------------------+ <-- EBP
 | |
|     #
 | |
| 
 | |
|     #
 | |
|     # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
 | |
|     # is 16-byte aligned
 | |
|     #
 | |
|     andl    $0x0fffffff0, %esp
 | |
|     subl    $12, %esp
 | |
| 
 | |
|     subl    $8, %esp
 | |
|     pushl   $0         # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
 | |
|     pushl   $0         # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
 | |
| 
 | |
| #; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
 | |
|     pushl   %eax
 | |
|     pushl   %ecx
 | |
|     pushl   %edx
 | |
|     pushl   %ebx
 | |
|     leal    24(%ebp), %ecx
 | |
|     pushl   %ecx                          # ESP
 | |
|     pushl   (%ebp)              # EBP
 | |
|     pushl   %esi
 | |
|     pushl   %edi
 | |
| 
 | |
| #; UINT32  Gs, Fs, Es, Ds, Cs, Ss;
 | |
|     movl    %ss, %eax
 | |
|     pushl   %eax
 | |
|     movzwl  16(%ebp), %eax
 | |
|     pushl   %eax
 | |
|     movl    %ds, %eax
 | |
|     pushl   %eax
 | |
|     movl    %es, %eax
 | |
|     pushl   %eax
 | |
|     movl    %fs, %eax
 | |
|     pushl   %eax
 | |
|     movl    %gs, %eax
 | |
|     pushl   %eax
 | |
| 
 | |
| #; UINT32  Eip;
 | |
|     movl    12(%ebp), %eax
 | |
|     pushl   %eax
 | |
| 
 | |
| #; UINT32  Gdtr[2], Idtr[2];
 | |
|     subl    $8, %esp
 | |
|     sidt    (%esp)
 | |
|     movl    2(%esp), %eax
 | |
|     xchgl   (%esp), %eax
 | |
|     andl    $0x0FFFF, %eax
 | |
|     movl    %eax, 4(%esp)
 | |
| 
 | |
|     subl    $8, %esp
 | |
|     sgdt    (%esp)
 | |
|     movl    2(%esp), %eax
 | |
|     xchgl   (%esp), %eax
 | |
|     andl    $0x0FFFF, %eax
 | |
|     movl    %eax, 4(%esp)
 | |
| 
 | |
| #; UINT32  Ldtr, Tr;
 | |
|     xorl    %eax, %eax
 | |
|     str     %ax
 | |
|     pushl   %eax
 | |
|     sldt    %ax
 | |
|     pushl   %eax
 | |
| 
 | |
| #; UINT32  EFlags;
 | |
|     movl    20(%ebp), %eax
 | |
|     pushl   %eax
 | |
| 
 | |
| #; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
 | |
| ## insure FXSAVE/FXRSTOR is enabled in CR4...
 | |
| ## ... while we're at it, make sure DE is also enabled...
 | |
|     mov     $1, %eax
 | |
|     pushl   %ebx                         # temporarily save value of ebx on stack
 | |
|     cpuid                                # use CPUID to determine if FXSAVE/FXRESTOR
 | |
|                                          # and DE are supported
 | |
|     popl    %ebx                         # retore value of ebx that was overwritten
 | |
|                                          # by CPUID
 | |
|     movl    %cr4, %eax
 | |
|     pushl   %eax                         # push cr4 firstly
 | |
|     testl   $BIT24, %edx                 # Test for FXSAVE/FXRESTOR support
 | |
|     jz      L1
 | |
|     orl     $BIT9, %eax                  # Set CR4.OSFXSR
 | |
| L1:
 | |
|     testl   $BIT2, %edx                  # Test for Debugging Extensions support
 | |
|     jz      L2
 | |
|     orl     $BIT3, %eax                  # Set CR4.DE
 | |
| L2:
 | |
|     movl    %eax, %cr4
 | |
|     movl    %cr3, %eax
 | |
|     pushl   %eax
 | |
|     movl    %cr2, %eax
 | |
|     pushl   %eax
 | |
|     xorl    %eax, %eax
 | |
|     pushl   %eax
 | |
|     movl    %cr0, %eax
 | |
|     pushl   %eax
 | |
| 
 | |
| #; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
 | |
|     movl    %dr7, %eax
 | |
|     pushl   %eax
 | |
|     movl    %dr6, %eax
 | |
|     pushl   %eax
 | |
|     movl    %dr3, %eax
 | |
|     pushl   %eax
 | |
|     movl    %dr2, %eax
 | |
|     pushl   %eax
 | |
|     movl    %dr1, %eax
 | |
|     pushl   %eax
 | |
|     movl    %dr0, %eax
 | |
|     pushl   %eax
 | |
| 
 | |
| #; FX_SAVE_STATE_IA32 FxSaveState;
 | |
|     subl    $512, %esp
 | |
|     movl    %esp, %edi
 | |
|     testl   $BIT24, %edx     # Test for FXSAVE/FXRESTOR support.
 | |
|                              # edx still contains result from CPUID above
 | |
|     jz      L3
 | |
|     .byte      0x0f, 0x0ae, 0x07 #fxsave [edi]
 | |
| L3:
 | |
| 
 | |
| #; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
 | |
|     cld
 | |
| 
 | |
| #; UINT32  ExceptionData;
 | |
|     pushl   8(%ebp)
 | |
| 
 | |
| #; Prepare parameter and call
 | |
|     movl    %esp, %edx
 | |
|     pushl   %edx
 | |
|     movl    4(%ebp), %edx
 | |
|     pushl   %edx
 | |
| 
 | |
|     #
 | |
|     # Call External Exception Handler
 | |
|     #
 | |
|     call    ASM_PFX(CommonExceptionHandler)
 | |
|     addl    $8, %esp
 | |
| 
 | |
|     cli
 | |
| #; UINT32  ExceptionData;
 | |
|     addl    $4, %esp
 | |
| 
 | |
| #; FX_SAVE_STATE_IA32 FxSaveState;
 | |
|     movl    %esp, %esi
 | |
|     movl    $1, %eax
 | |
|     cpuid                    # use CPUID to determine if FXSAVE/FXRESTOR
 | |
|                              # are supported
 | |
|     testl   $BIT24, %edx     # Test for FXSAVE/FXRESTOR support
 | |
|     jz      L4
 | |
|     .byte      0x0f, 0x0ae, 0x0e # fxrstor [esi]
 | |
| L4:
 | |
|     addl    $512, %esp
 | |
| 
 | |
| #; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
 | |
| #; Skip restoration of DRx registers to support in-circuit emualators
 | |
| #; or debuggers set breakpoint in interrupt/exception context
 | |
|     addl    $24, %esp
 | |
| 
 | |
| #; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
 | |
|     popl    %eax
 | |
|     movl    %eax, %cr0
 | |
|     addl    $4, %esp    # not for Cr1
 | |
|     popl    %eax
 | |
|     movl    %eax, %cr2
 | |
|     popl    %eax
 | |
|     movl    %eax, %cr3
 | |
|     popl    %eax
 | |
|     movl    %eax, %cr4
 | |
| 
 | |
| #; UINT32  EFlags;
 | |
|     popl    20(%ebp)
 | |
| 
 | |
| #; UINT32  Ldtr, Tr;
 | |
| #; UINT32  Gdtr[2], Idtr[2];
 | |
| #; Best not let anyone mess with these particular registers...
 | |
|     addl    $24, %esp
 | |
| 
 | |
| #; UINT32  Eip;
 | |
|     popl    12(%ebp)
 | |
| 
 | |
| #; UINT32  Gs, Fs, Es, Ds, Cs, Ss;
 | |
| #; NOTE - modified segment registers could hang the debugger...  We
 | |
| #;        could attempt to insulate ourselves against this possibility,
 | |
| #;        but that poses risks as well.
 | |
| #;
 | |
|     popl    %gs
 | |
|     popl    %fs
 | |
|     popl    %es
 | |
|     popl    %ds
 | |
|     popl    16(%ebp)
 | |
|     popl    %ss
 | |
| 
 | |
| #; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
 | |
|     popl    %edi
 | |
|     popl    %esi
 | |
|     addl    $4, %esp   # not for ebp
 | |
|     addl    $4, %esp   # not for esp
 | |
|     popl    %ebx
 | |
|     popl    %edx
 | |
|     popl    %ecx
 | |
|     popl    %eax
 | |
| 
 | |
|     popl    -8(%ebp)
 | |
|     popl    -4(%ebp)
 | |
|     movl    %ebp, %esp
 | |
|     popl    %ebp
 | |
|     addl    $8, %esp
 | |
|     cmpl    $0, -16(%esp)  # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
 | |
|     jz      DoReturn
 | |
|     cmpl    $1, -20(%esp)  # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
 | |
|     jz      ErrorCode
 | |
|     jmp     *-16(%esp)
 | |
| ErrorCode:
 | |
|     subl    $4, %esp
 | |
|     jmp     *-12(%esp)
 | |
| 
 | |
| DoReturn:
 | |
|     cmpl    $0, ASM_PFX(mDoFarReturnFlag)
 | |
|     jz      DoIret
 | |
|     pushl   8(%esp)       # save EFLAGS
 | |
|     addl    $16, %esp
 | |
|     pushl   -8(%esp)      # save CS in new location
 | |
|     pushl   -8(%esp)      # save EIP in new location
 | |
|     pushl   -8(%esp)      # save EFLAGS in new location
 | |
|     popfl                 # restore EFLAGS
 | |
|     lret                  # far return
 | |
| 
 | |
| DoIret:
 | |
|     iretl
 | |
| 
 | |
| 
 | |
| #---------------------------------------;
 | |
| # _AsmGetTemplateAddressMap             ;
 | |
| #---------------------------------------;
 | |
| #
 | |
| # Protocol prototype
 | |
| #   AsmGetTemplateAddressMap (
 | |
| #     EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
 | |
| #   );
 | |
| #
 | |
| # Routine Description:
 | |
| #
 | |
| #  Return address map of interrupt handler template so that C code can generate
 | |
| #  interrupt table.
 | |
| #
 | |
| # Arguments:
 | |
| #
 | |
| #
 | |
| # Returns:
 | |
| #
 | |
| #   Nothing
 | |
| #
 | |
| #
 | |
| # Input:  [ebp][0]  = Original ebp
 | |
| #         [ebp][4]  = Return address
 | |
| #
 | |
| # Output: Nothing
 | |
| #
 | |
| # Destroys: Nothing
 | |
| #-----------------------------------------------------------------------------;
 | |
| #-------------------------------------------------------------------------------------
 | |
| #  AsmGetAddressMap (&AddressMap);
 | |
| #-------------------------------------------------------------------------------------
 | |
| ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)
 | |
| ASM_PFX(AsmGetTemplateAddressMap):
 | |
| 
 | |
|         pushl       %ebp
 | |
|         movl        %esp,%ebp
 | |
|         pushal
 | |
| 
 | |
|         movl        0x8(%ebp), %ebx
 | |
|         movl        $Exception0Handle, (%ebx)
 | |
|         movl        $(Exception1Handle - Exception0Handle), 0x4(%ebx)
 | |
|         movl        $(HookAfterStubBegin), 0x8(%ebx)
 | |
| 
 | |
|         popal
 | |
|         popl        %ebp
 | |
|         ret
 | |
| #-------------------------------------------------------------------------------------
 | |
| #  AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);
 | |
| #-------------------------------------------------------------------------------------
 | |
| ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)
 | |
| ASM_PFX(AsmVectorNumFixup):
 | |
|         movl  8(%esp), %eax
 | |
|         movl  4(%esp), %ecx
 | |
|         movb  %al, (VectorNum - HookAfterStubBegin)(%ecx)
 | |
|         ret
 |