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