Home | History | Annotate | Download | only in X64
      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.asm
     15 ;
     16 ; Abstract:
     17 ;
     18 ;   Debug interrupt handle functions.
     19 ;
     20 ;------------------------------------------------------------------------------
     21 
     22 #include "DebugException.h"
     23 
     24 
     25 externdef InterruptProcess:near
     26 
     27 data SEGMENT
     28 
     29 public          Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
     30 
     31 AGENT_HANDLER_SIGNATURE  MACRO
     32   db   41h, 47h, 54h, 48h       ; SIGNATURE_32('A','G','T','H')
     33 ENDM
     34 
     35 ExceptionStubHeaderSize        dd      Exception1Handle - Exception0Handle ;
     36 CommonEntryAddr                dq      CommonEntry ;
     37 
     38 .code
     39 
     40 AGENT_HANDLER_SIGNATURE
     41 Exception0Handle:
     42     cli
     43     push    rcx
     44     mov     rcx, 0
     45     jmp     qword ptr [CommonEntryAddr]
     46 AGENT_HANDLER_SIGNATURE	
     47 Exception1Handle:
     48     cli
     49     push    rcx
     50     mov     rcx, 1
     51     jmp     qword ptr [CommonEntryAddr]
     52 AGENT_HANDLER_SIGNATURE
     53 Exception2Handle:
     54     cli
     55     push    rcx
     56     mov     rcx, 2
     57     jmp     qword ptr [CommonEntryAddr]
     58 AGENT_HANDLER_SIGNATURE
     59 Exception3Handle:
     60     cli
     61     push    rcx
     62     mov     rcx, 3
     63     jmp     qword ptr [CommonEntryAddr]
     64 AGENT_HANDLER_SIGNATURE
     65 Exception4Handle:
     66     cli
     67     push    rcx
     68     mov     rcx, 4
     69     jmp     qword ptr [CommonEntryAddr]
     70 AGENT_HANDLER_SIGNATURE
     71 Exception5Handle:
     72     cli
     73     push    rcx
     74     mov     rcx, 5
     75     jmp     qword ptr [CommonEntryAddr]
     76 AGENT_HANDLER_SIGNATURE
     77 Exception6Handle:
     78     cli
     79     push    rcx
     80     mov     rcx, 6
     81     jmp     qword ptr [CommonEntryAddr]
     82 AGENT_HANDLER_SIGNATURE
     83 Exception7Handle:
     84     cli
     85     push    rcx
     86     mov     rcx, 7
     87     jmp     qword ptr [CommonEntryAddr]
     88 AGENT_HANDLER_SIGNATURE
     89 Exception8Handle:
     90     cli
     91     push    rcx
     92     mov     rcx, 8
     93     jmp     qword ptr [CommonEntryAddr]
     94 AGENT_HANDLER_SIGNATURE
     95 Exception9Handle:
     96     cli
     97     push    rcx
     98     mov     rcx, 9
     99     jmp     qword ptr [CommonEntryAddr]
    100 AGENT_HANDLER_SIGNATURE
    101 Exception10Handle:
    102     cli
    103     push    rcx
    104     mov     rcx, 10
    105     jmp     qword ptr [CommonEntryAddr]
    106 AGENT_HANDLER_SIGNATURE
    107 Exception11Handle:
    108     cli
    109     push    rcx
    110     mov     rcx, 11
    111     jmp     qword ptr [CommonEntryAddr]
    112 AGENT_HANDLER_SIGNATURE
    113 Exception12Handle:
    114     cli
    115     push    rcx
    116     mov     rcx, 12
    117     jmp     qword ptr [CommonEntryAddr]
    118 AGENT_HANDLER_SIGNATURE
    119 Exception13Handle:
    120     cli
    121     push    rcx
    122     mov     rcx, 13
    123     jmp     qword ptr [CommonEntryAddr]
    124 AGENT_HANDLER_SIGNATURE
    125 Exception14Handle:
    126     cli
    127     push    rcx
    128     mov     rcx, 14
    129     jmp     qword ptr [CommonEntryAddr]
    130 AGENT_HANDLER_SIGNATURE
    131 Exception15Handle:
    132     cli
    133     push    rcx
    134     mov     rcx, 15
    135     jmp     qword ptr [CommonEntryAddr]
    136 AGENT_HANDLER_SIGNATURE
    137 Exception16Handle:
    138     cli
    139     push    rcx
    140     mov     rcx, 16
    141     jmp     qword ptr [CommonEntryAddr]
    142 AGENT_HANDLER_SIGNATURE
    143 Exception17Handle:
    144     cli
    145     push    rcx
    146     mov     rcx, 17
    147     jmp     qword ptr [CommonEntryAddr]
    148 AGENT_HANDLER_SIGNATURE
    149 Exception18Handle:
    150     cli
    151     push    rcx
    152     mov     rcx, 18
    153     jmp     qword ptr [CommonEntryAddr]
    154 AGENT_HANDLER_SIGNATURE
    155 Exception19Handle:
    156     cli
    157     push    rcx
    158     mov     rcx, 19
    159     jmp     qword ptr [CommonEntryAddr]
    160 AGENT_HANDLER_SIGNATURE
    161 TimerInterruptHandle:
    162     cli
    163     push    rcx
    164     mov     rcx, 32
    165     jmp     qword ptr [CommonEntryAddr]
    166 
    167 CommonEntry:
    168     ; We need to determine if any extra data was pushed by the exception
    169     cmp     rcx, DEBUG_EXCEPT_DOUBLE_FAULT
    170     je      NoExtrPush
    171     cmp     rcx, DEBUG_EXCEPT_INVALID_TSS
    172     je      NoExtrPush
    173     cmp     rcx, DEBUG_EXCEPT_SEG_NOT_PRESENT
    174     je      NoExtrPush
    175     cmp     rcx, DEBUG_EXCEPT_STACK_FAULT
    176     je      NoExtrPush
    177     cmp     rcx, DEBUG_EXCEPT_GP_FAULT
    178     je      NoExtrPush
    179     cmp     rcx, DEBUG_EXCEPT_PAGE_FAULT
    180     je      NoExtrPush
    181     cmp     rcx, DEBUG_EXCEPT_ALIGNMENT_CHECK
    182     je      NoExtrPush
    183 
    184     push    [rsp]
    185     mov     qword ptr [rsp + 8], 0
    186 
    187 NoExtrPush:
    188     push    rbp
    189     mov     rbp, rsp
    190 
    191     ; store UINT64  r8, r9, r10, r11, r12, r13, r14, r15;
    192     push    r15
    193     push    r14
    194     push    r13
    195     push    r12
    196     push    r11
    197     push    r10
    198     push    r9
    199     push    r8
    200 
    201     mov     r8, cr8
    202     push    r8
    203 
    204     ; store UINT64  Rdi, Rsi, Rbp, Rsp, Rdx, Rcx, Rbx, Rax;
    205     push    rax
    206     push    rbx
    207     push    qword ptr [rbp + 8]       ; original rcx
    208     push    rdx
    209     push    qword ptr [rbp + 6 * 8]   ; original rsp
    210     push    qword ptr [rbp]           ; original rbp
    211     push    rsi
    212     push    rdi
    213 
    214     ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
    215     ;; insure FXSAVE/FXRSTOR is enabled in CR4...
    216     ;; ... while we're at it, make sure DE is also enabled...
    217     mov     rax, cr4
    218     or      rax, 208h
    219     mov     cr4, rax
    220     push    rax
    221     mov     rax, cr3
    222     push    rax
    223     mov     rax, cr2
    224     push    rax
    225     push    0
    226     mov     rax, cr0
    227     push    rax
    228 
    229     xor     rax, rax
    230     mov     rax, Ss
    231     push    rax
    232     mov     rax, Cs
    233     push    rax
    234     mov     rax, Ds
    235     push    rax
    236     mov     rax, Es
    237     push    rax
    238     mov     rax, Fs
    239     push    rax
    240     mov     rax, Gs
    241     push    rax
    242 
    243     ;; EIP
    244     mov     rax, [rbp + 8 * 3] ; EIP
    245     push    rax
    246 
    247     ;; UINT64  Gdtr[2], Idtr[2];
    248     sub  rsp, 16
    249     sidt fword ptr [rsp]
    250     sub  rsp, 16
    251     sgdt fword ptr [rsp]
    252 
    253     ;; UINT64  Ldtr, Tr;
    254     xor  rax, rax
    255     str  ax
    256     push rax
    257     sldt ax
    258     push rax
    259 
    260     ;; EFlags
    261     mov     rax, [rbp + 8 * 5]
    262     push    rax
    263 
    264     ;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    265     mov     rax, dr7
    266     push    rax
    267 
    268     ;; clear Dr7 while executing debugger itself
    269     xor     rax, rax
    270     mov     dr7, rax
    271 
    272     ;; Dr6
    273     mov     rax, dr6
    274     push    rax
    275 
    276     ;; insure all status bits in dr6 are clear...
    277     xor     rax, rax
    278     mov     dr6, rax
    279 
    280     mov     rax, dr3
    281     push    rax
    282     mov     rax, dr2
    283     push    rax
    284     mov     rax, dr1
    285     push    rax
    286     mov     rax, dr0
    287     push    rax
    288 
    289     ;; Clear Direction Flag
    290     cld
    291 
    292     sub     rsp, 512
    293     mov     rdi, rsp
    294     ;; Clear the buffer
    295     xor     rax, rax
    296     push    rcx
    297     mov     rcx, 64 ;= 512 / 8
    298     rep     stosq
    299     pop     rcx
    300     mov     rdi, rsp
    301     db 0fh, 0aeh, 00000111y ;fxsave [rdi]
    302 
    303     ;; save the exception data
    304     push    qword ptr [rbp + 16]
    305 
    306     ; call the C interrupt process function
    307     mov     rdx, rsp      ; Structure
    308     mov     r15, rcx      ; save vector in r15
    309     
    310     ;
    311     ; Per X64 calling convention, allocate maximum parameter stack space
    312     ; and make sure RSP is 16-byte aligned
    313     ;
    314     sub     rsp, 32 + 8
    315     call    InterruptProcess
    316     add     rsp, 32 + 8
    317 
    318     ;; skip the exception data
    319     add     rsp, 8
    320     
    321     mov     rsi, rsp
    322     db 0fh, 0aeh, 00001110y ; fxrstor [rsi]
    323     add     rsp, 512
    324 
    325     ;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    326     pop     rax
    327     mov     dr0, rax
    328     pop     rax
    329     mov     dr1, rax
    330     pop     rax
    331     mov     dr2, rax
    332     pop     rax
    333     mov     dr3, rax
    334     ;; skip restore of dr6.  We cleared dr6 during the context save.
    335     add     rsp, 8
    336     pop     rax
    337     mov     dr7, rax
    338 
    339     ;; set EFlags
    340     pop     qword ptr [rbp + 8 * 5]
    341 
    342     ;; UINT64  Ldtr, Tr;
    343     ;; UINT64  Gdtr[2], Idtr[2];
    344     ;; Best not let anyone mess with these particular registers...
    345     add     rsp, 24 * 2
    346 
    347     ;; UINT64  Eip;
    348     pop     qword ptr [rbp + 8 * 3]   ; set EIP in stack
    349 
    350     ;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;
    351     ;; NOTE - modified segment registers could hang the debugger...  We
    352     ;;        could attempt to insulate ourselves against this possibility,
    353     ;;        but that poses risks as well.
    354     ;;
    355     pop     rax
    356     pop     rax
    357     pop     rax
    358     mov     es, rax
    359     pop     rax
    360     mov     ds, rax
    361     pop     qword ptr [rbp + 8 * 4]    ; Set CS in stack
    362     pop     rax
    363     mov     ss, rax
    364 
    365     ;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4;
    366     pop     rax
    367     mov     cr0, rax
    368     add     rsp, 8    ; skip for Cr1
    369     pop     rax
    370     mov     cr2, rax
    371     pop     rax
    372     mov     cr3, rax
    373     pop     rax
    374     mov     cr4, rax
    375 
    376     ;; restore general register
    377     pop    rdi
    378     pop    rsi
    379     add    rsp, 8  ; skip rbp
    380     add    rsp, 8  ; skip rsp
    381     pop    rdx
    382     pop    rcx
    383     pop    rbx
    384     pop    rax
    385 
    386     pop    r8
    387     mov    cr8, r8
    388 
    389     ; store UINT64  r8, r9, r10, r11, r12, r13, r14, r15;
    390     pop     r8
    391     pop     r9
    392     pop     r10
    393     pop     r11
    394     pop     r12
    395     pop     r13
    396     pop     r14
    397     pop     r15
    398 
    399     mov     rsp, rbp
    400     pop     rbp
    401     add     rsp, 16      ; skip rcx and error code
    402 
    403     iretq
    404 
    405 END
    406