Home | History | Annotate | Download | only in Ia32
      1 ;------------------------------------------------------------------------------
      2 ;
      3 ; Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
      4 ; This program and the accompanying materials
      5 ; are licensed and made available under the terms and conditions of the BSD License
      6 ; which accompanies this distribution.  The full text of the license may be found at
      7 ; http://opensource.org/licenses/bsd-license.php.
      8 ;
      9 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 ;
     12 ; Module Name:
     13 ;
     14 ;   AsmFuncs.nasm
     15 ;
     16 ; Abstract:
     17 ;
     18 ;   Debug interrupt handle functions.
     19 ;
     20 ;------------------------------------------------------------------------------
     21 
     22 #include "DebugException.h"
     23 
     24 ;
     25 ; InterruptProcess()
     26 ;
     27 extern ASM_PFX(InterruptProcess)
     28 
     29 global ASM_PFX(Exception0Handle)
     30 global ASM_PFX(TimerInterruptHandle)
     31 global ASM_PFX(ExceptionStubHeaderSize)
     32 
     33 %macro AGENT_HANDLER_SIGNATURE 0
     34   db   0x41, 0x47, 0x54, 0x48       ; SIGNATURE_32('A','G','T','H')
     35 %endmacro
     36 
     37 SECTION .data
     38 
     39 ASM_PFX(ExceptionStubHeaderSize): DD Exception1Handle - ASM_PFX(Exception0Handle)
     40 CommonEntryAddr: DD CommonEntry
     41 
     42 SECTION .text
     43 
     44 AGENT_HANDLER_SIGNATURE
     45 ASM_PFX(Exception0Handle):
     46     cli
     47     push    eax
     48     mov     eax, 0
     49     jmp     dword [CommonEntryAddr]
     50 AGENT_HANDLER_SIGNATURE
     51 Exception1Handle:
     52     cli
     53     push    eax
     54     mov     eax, 1
     55     jmp     dword [CommonEntryAddr]
     56 AGENT_HANDLER_SIGNATURE
     57 Exception2Handle:
     58     cli
     59     push    eax
     60     mov     eax, 2
     61     jmp     dword [CommonEntryAddr]
     62 AGENT_HANDLER_SIGNATURE
     63 Exception3Handle:
     64     cli
     65     push    eax
     66     mov     eax, 3
     67     jmp     dword [CommonEntryAddr]
     68 AGENT_HANDLER_SIGNATURE
     69 Exception4Handle:
     70     cli
     71     push    eax
     72     mov     eax, 4
     73     jmp     dword [CommonEntryAddr]
     74 AGENT_HANDLER_SIGNATURE
     75 Exception5Handle:
     76     cli
     77     push    eax
     78     mov     eax, 5
     79     jmp     dword [CommonEntryAddr]
     80 AGENT_HANDLER_SIGNATURE
     81 Exception6Handle:
     82     cli
     83     push    eax
     84     mov     eax, 6
     85     jmp     dword [CommonEntryAddr]
     86 AGENT_HANDLER_SIGNATURE
     87 Exception7Handle:
     88     cli
     89     push    eax
     90     mov     eax, 7
     91     jmp     dword [CommonEntryAddr]
     92 AGENT_HANDLER_SIGNATURE
     93 Exception8Handle:
     94     cli
     95     push    eax
     96     mov     eax, 8
     97     jmp     dword [CommonEntryAddr]
     98 AGENT_HANDLER_SIGNATURE
     99 Exception9Handle:
    100     cli
    101     push    eax
    102     mov     eax, 9
    103     jmp     dword [CommonEntryAddr]
    104 AGENT_HANDLER_SIGNATURE
    105 Exception10Handle:
    106     cli
    107     push    eax
    108     mov     eax, 10
    109     jmp     dword [CommonEntryAddr]
    110 AGENT_HANDLER_SIGNATURE
    111 Exception11Handle:
    112     cli
    113     push    eax
    114     mov     eax, 11
    115     jmp     dword [CommonEntryAddr]
    116 AGENT_HANDLER_SIGNATURE
    117 Exception12Handle:
    118     cli
    119     push    eax
    120     mov     eax, 12
    121     jmp     dword [CommonEntryAddr]
    122 AGENT_HANDLER_SIGNATURE
    123 Exception13Handle:
    124     cli
    125     push    eax
    126     mov     eax, 13
    127     jmp     dword [CommonEntryAddr]
    128 AGENT_HANDLER_SIGNATURE
    129 Exception14Handle:
    130     cli
    131     push    eax
    132     mov     eax, 14
    133     jmp     dword [CommonEntryAddr]
    134 AGENT_HANDLER_SIGNATURE
    135 Exception15Handle:
    136     cli
    137     push    eax
    138     mov     eax, 15
    139     jmp     dword [CommonEntryAddr]
    140 AGENT_HANDLER_SIGNATURE
    141 Exception16Handle:
    142     cli
    143     push    eax
    144     mov     eax, 16
    145     jmp     dword [CommonEntryAddr]
    146 AGENT_HANDLER_SIGNATURE
    147 Exception17Handle:
    148     cli
    149     push    eax
    150     mov     eax, 17
    151     jmp     dword [CommonEntryAddr]
    152 AGENT_HANDLER_SIGNATURE
    153 Exception18Handle:
    154     cli
    155     push    eax
    156     mov     eax, 18
    157     jmp     dword [CommonEntryAddr]
    158 AGENT_HANDLER_SIGNATURE
    159 Exception19Handle:
    160     cli
    161     push    eax
    162     mov     eax, 19
    163     jmp     dword [CommonEntryAddr]
    164 AGENT_HANDLER_SIGNATURE
    165 ASM_PFX(TimerInterruptHandle):
    166     cli
    167     push    eax
    168     mov     eax, 32
    169     jmp     dword [CommonEntryAddr]
    170 
    171 CommonEntry:
    172 ;
    173 ; +---------------------+
    174 ; +    EFlags           +
    175 ; +---------------------+
    176 ; +    CS               +
    177 ; +---------------------+
    178 ; +    EIP              +
    179 ; +---------------------+
    180 ; +    Error Code       +
    181 ; +---------------------+
    182 ; + EAX / Vector Number +
    183 ; +---------------------+
    184 ; +    EBP              +
    185 ; +---------------------+ <-- EBP
    186 ;
    187     cmp     eax, DEBUG_EXCEPT_DOUBLE_FAULT
    188     je      NoExtrPush
    189     cmp     eax, DEBUG_EXCEPT_INVALID_TSS
    190     je      NoExtrPush
    191     cmp     eax, DEBUG_EXCEPT_SEG_NOT_PRESENT
    192     je      NoExtrPush
    193     cmp     eax, DEBUG_EXCEPT_STACK_FAULT
    194     je      NoExtrPush
    195     cmp     eax, DEBUG_EXCEPT_GP_FAULT
    196     je      NoExtrPush
    197     cmp     eax, DEBUG_EXCEPT_PAGE_FAULT
    198     je      NoExtrPush
    199     cmp     eax, DEBUG_EXCEPT_ALIGNMENT_CHECK
    200     je      NoExtrPush
    201 
    202     push    dword [esp]
    203     mov     dword [esp + 4], 0
    204 
    205 NoExtrPush:
    206 
    207     push    ebp
    208     mov     ebp, esp        ; save esp in ebp
    209     ;
    210     ; Make stack 16-byte alignment to make sure save fxrstor later
    211     ;
    212     and     esp, 0xfffffff0
    213     sub     esp, 12
    214 
    215     ; store UINT32  Edi, Esi, Ebp, Ebx, Edx, Ecx, Eax;
    216     push    dword [ebp + 4]  ; original eax
    217     push    ebx
    218     push    ecx
    219     push    edx
    220     mov     ebx, eax         ; save vector in ebx
    221     mov     eax, ebp
    222     add     eax, 4 * 6
    223     push    eax              ; original ESP
    224     push    dword [ebp]  ; EBP
    225     push    esi
    226     push    edi
    227 
    228     ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
    229     ;; insure FXSAVE/FXRSTOR is enabled in CR4...
    230     ;; ... while we're at it, make sure DE is also enabled...
    231     mov     eax, 1
    232     push    ebx         ; temporarily save value of ebx on stack
    233     cpuid               ; use CPUID to determine if FXSAVE/FXRESTOR and
    234                         ; DE are supported
    235     pop     ebx         ; retore value of ebx that was overwritten by CPUID
    236     mov     eax, cr4
    237     push    eax         ; push cr4 firstly
    238     test    edx, BIT24  ; Test for FXSAVE/FXRESTOR support
    239     jz      .0
    240     or      eax, BIT9   ; Set CR4.OSFXSR
    241 .0:
    242     test    edx, BIT2   ; Test for Debugging Extensions support
    243     jz      .1
    244     or      eax, BIT3   ; Set CR4.DE
    245 .1:
    246     mov     cr4, eax
    247     mov     eax, cr3
    248     push    eax
    249     mov     eax, cr2
    250     push    eax
    251     push    0         ; cr0 will not saved???
    252     mov     eax, cr0
    253     push    eax
    254 
    255     xor     ecx, ecx
    256     mov     ecx, Ss
    257     push    ecx
    258     mov     ecx, Cs
    259     push    ecx
    260     mov     ecx, Ds
    261     push    ecx
    262     mov     ecx, Es
    263     push    ecx
    264     mov     ecx, Fs
    265     push    ecx
    266     mov     ecx, Gs
    267     push    ecx
    268 
    269     ;; EIP
    270     mov     ecx, [ebp + 4 * 3] ; EIP
    271     push    ecx
    272 
    273     ;; UINT32  Gdtr[2], Idtr[2];
    274     sub  esp, 8
    275     sidt [esp]
    276     sub  esp, 8
    277     sgdt [esp]
    278 
    279     ;; UINT32  Ldtr, Tr;
    280     xor  eax, eax
    281     str  ax
    282     push eax
    283     sldt ax
    284     push eax
    285 
    286     ;; EFlags
    287     mov     ecx, [ebp + 4 * 5]
    288     push    ecx
    289 
    290     ;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    291     mov     eax, dr7
    292     push    eax
    293 
    294     ;; clear Dr7 while executing debugger itself
    295     xor     eax, eax
    296     mov     dr7, eax
    297 
    298     ;; Dr6
    299     mov     eax, dr6
    300     push    eax
    301 
    302     ;; insure all status bits in dr6 are clear...
    303     xor     eax, eax
    304     mov     dr6, eax
    305 
    306     mov     eax, dr3
    307     push    eax
    308     mov     eax, dr2
    309     push    eax
    310     mov     eax, dr1
    311     push    eax
    312     mov     eax, dr0
    313     push    eax
    314 
    315     ;; Clear Direction Flag
    316     cld
    317 
    318     ;; FX_SAVE_STATE_IA32 FxSaveState;
    319     sub     esp, 512
    320     mov     edi, esp
    321     ;; Clear the buffer
    322     xor     eax, eax
    323     mov     ecx, 128 ;= 512 / 4
    324     rep     stosd
    325     mov     edi, esp
    326 
    327     test    edx, BIT24  ; Test for FXSAVE/FXRESTOR support.
    328                         ; edx still contains result from CPUID above
    329     jz      .2
    330     db 0xf, 0xae, 00000111y ;fxsave [edi]
    331 .2:
    332 
    333     ;; save the exception data
    334     push    dword [ebp + 8]
    335 
    336     ; call the C interrupt process function
    337     push    esp     ; Structure
    338     push    ebx     ; vector
    339     call    ASM_PFX(InterruptProcess)
    340     add     esp, 8
    341 
    342     ; skip the exception data
    343     add     esp, 4
    344 
    345     ;; FX_SAVE_STATE_IA32 FxSaveState;
    346     mov     esi, esp
    347     mov     eax, 1
    348     cpuid               ; use CPUID to determine if FXSAVE/FXRESTOR are supported
    349     test    edx, BIT24  ; Test for FXSAVE/FXRESTOR support
    350     jz      .3
    351     db 0xf, 0xae, 00001110y ; fxrstor [esi]
    352 .3:
    353     add esp, 512
    354 
    355     ;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    356     pop     eax
    357     mov     dr0, eax
    358     pop     eax
    359     mov     dr1, eax
    360     pop     eax
    361     mov     dr2, eax
    362     pop     eax
    363     mov     dr3, eax
    364     ;; skip restore of dr6.  We cleared dr6 during the context save.
    365     add     esp, 4
    366     pop     eax
    367     mov     dr7, eax
    368 
    369     ;; set EFlags
    370     pop     dword [ebp + 4 * 5]  ; set EFLAGS in stack
    371 
    372     ;; UINT32  Ldtr, Tr;
    373     ;; UINT32  Gdtr[2], Idtr[2];
    374     ;; Best not let anyone mess with these particular registers...
    375     add     esp, 24
    376 
    377     ;; UINT32  Eip;
    378     pop     dword [ebp + 4 * 3]   ; set EIP in stack
    379 
    380     ;; UINT32  Gs, Fs, Es, Ds, Cs, Ss;
    381     ;; NOTE - modified segment registers could hang the debugger...  We
    382     ;;        could attempt to insulate ourselves against this possibility,
    383     ;;        but that poses risks as well.
    384     ;;
    385     pop     gs
    386     pop     fs
    387     pop     es
    388     pop     ds
    389     pop     dword [ebp + 4 * 4]    ; set CS in stack
    390     pop     ss
    391 
    392     ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
    393     pop     eax
    394     mov     cr0, eax
    395     add     esp, 4    ; skip for Cr1
    396     pop     eax
    397     mov     cr2, eax
    398     pop     eax
    399     mov     cr3, eax
    400     pop     eax
    401     mov     cr4, eax
    402 
    403     ;; restore general register
    404     pop     edi
    405     pop     esi
    406     pop     dword [ebp]         ; save updated ebp
    407     pop     dword [ebp + 4]     ; save updated esp
    408     pop     edx
    409     pop     ecx
    410     pop     ebx
    411     pop     eax
    412 
    413     mov     esp, ebp
    414     pop     ebp         ; restore ebp maybe updated
    415     pop     esp         ; restore esp maybe updated
    416     sub     esp, 4 * 3  ; restore interupt pushced stack
    417 
    418     iretd
    419 
    420