• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
24SECTION .data
25
26extern ASM_PFX(InterruptProcess)
27global ASM_PFX(Exception0Handle)
28global ASM_PFX(TimerInterruptHandle)
29global 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
35ASM_PFX(ExceptionStubHeaderSize): dd Exception1Handle - ASM_PFX(Exception0Handle) ;
36CommonEntryAddr: dq CommonEntry ;
37
38DEFAULT REL
39SECTION .text
40
41AGENT_HANDLER_SIGNATURE
42ASM_PFX(Exception0Handle):
43    cli
44    push    rcx
45    mov     rcx, dword 0
46    jmp     qword [CommonEntryAddr]
47AGENT_HANDLER_SIGNATURE
48Exception1Handle:
49    cli
50    push    rcx
51    mov     rcx, dword 1
52    jmp     qword [CommonEntryAddr]
53AGENT_HANDLER_SIGNATURE
54Exception2Handle:
55    cli
56    push    rcx
57    mov     rcx, dword 2
58    jmp     qword [CommonEntryAddr]
59AGENT_HANDLER_SIGNATURE
60Exception3Handle:
61    cli
62    push    rcx
63    mov     rcx, dword 3
64    jmp     qword [CommonEntryAddr]
65AGENT_HANDLER_SIGNATURE
66Exception4Handle:
67    cli
68    push    rcx
69    mov     rcx, dword 4
70    jmp     qword [CommonEntryAddr]
71AGENT_HANDLER_SIGNATURE
72Exception5Handle:
73    cli
74    push    rcx
75    mov     rcx, dword 5
76    jmp     qword [CommonEntryAddr]
77AGENT_HANDLER_SIGNATURE
78Exception6Handle:
79    cli
80    push    rcx
81    mov     rcx, dword 6
82    jmp     qword [CommonEntryAddr]
83AGENT_HANDLER_SIGNATURE
84Exception7Handle:
85    cli
86    push    rcx
87    mov     rcx, dword 7
88    jmp     qword [CommonEntryAddr]
89AGENT_HANDLER_SIGNATURE
90Exception8Handle:
91    cli
92    push    rcx
93    mov     rcx, dword 8
94    jmp     qword [CommonEntryAddr]
95AGENT_HANDLER_SIGNATURE
96Exception9Handle:
97    cli
98    push    rcx
99    mov     rcx, dword 9
100    jmp     qword [CommonEntryAddr]
101AGENT_HANDLER_SIGNATURE
102Exception10Handle:
103    cli
104    push    rcx
105    mov     rcx, dword 10
106    jmp     qword [CommonEntryAddr]
107AGENT_HANDLER_SIGNATURE
108Exception11Handle:
109    cli
110    push    rcx
111    mov     rcx, dword 11
112    jmp     qword [CommonEntryAddr]
113AGENT_HANDLER_SIGNATURE
114Exception12Handle:
115    cli
116    push    rcx
117    mov     rcx, dword 12
118    jmp     qword [CommonEntryAddr]
119AGENT_HANDLER_SIGNATURE
120Exception13Handle:
121    cli
122    push    rcx
123    mov     rcx, dword 13
124    jmp     qword [CommonEntryAddr]
125AGENT_HANDLER_SIGNATURE
126Exception14Handle:
127    cli
128    push    rcx
129    mov     rcx, dword 14
130    jmp     qword [CommonEntryAddr]
131AGENT_HANDLER_SIGNATURE
132Exception15Handle:
133    cli
134    push    rcx
135    mov     rcx, dword 15
136    jmp     qword [CommonEntryAddr]
137AGENT_HANDLER_SIGNATURE
138Exception16Handle:
139    cli
140    push    rcx
141    mov     rcx, dword 16
142    jmp     qword [CommonEntryAddr]
143AGENT_HANDLER_SIGNATURE
144Exception17Handle:
145    cli
146    push    rcx
147    mov     rcx, dword 17
148    jmp     qword [CommonEntryAddr]
149AGENT_HANDLER_SIGNATURE
150Exception18Handle:
151    cli
152    push    rcx
153    mov     rcx, dword 18
154    jmp     qword [CommonEntryAddr]
155AGENT_HANDLER_SIGNATURE
156Exception19Handle:
157    cli
158    push    rcx
159    mov     rcx, dword 19
160    jmp     qword [CommonEntryAddr]
161AGENT_HANDLER_SIGNATURE
162ASM_PFX(TimerInterruptHandle):
163    cli
164    push    rcx
165    mov     rcx, dword 32
166    jmp     qword [CommonEntryAddr]
167
168CommonEntry:
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
188NoExtrPush:
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