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