123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- ;------------------------------------------------------------------------------
- ;
- ; Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.<BR>
- ; SPDX-License-Identifier: BSD-2-Clause-Patent
- ;
- ; Module Name:
- ;
- ; AsmFuncs.nasm
- ;
- ; Abstract:
- ;
- ; Debug interrupt handle functions.
- ;
- ;------------------------------------------------------------------------------
- #include "DebugException.h"
- ;
- ; InterruptProcess()
- ;
- extern ASM_PFX(InterruptProcess)
- global ASM_PFX(Exception0Handle)
- global ASM_PFX(TimerInterruptHandle)
- global ASM_PFX(ExceptionStubHeaderSize)
- %macro AGENT_HANDLER_SIGNATURE 0
- db 0x41, 0x47, 0x54, 0x48 ; SIGNATURE_32('A','G','T','H')
- %endmacro
- SECTION .data
- ASM_PFX(ExceptionStubHeaderSize): DD Exception1Handle - ASM_PFX(Exception0Handle)
- CommonEntryAddr: DD CommonEntry
- SECTION .text
- AGENT_HANDLER_SIGNATURE
- ASM_PFX(Exception0Handle):
- cli
- push eax
- mov eax, 0
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception1Handle:
- cli
- push eax
- mov eax, 1
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception2Handle:
- cli
- push eax
- mov eax, 2
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception3Handle:
- cli
- push eax
- mov eax, 3
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception4Handle:
- cli
- push eax
- mov eax, 4
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception5Handle:
- cli
- push eax
- mov eax, 5
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception6Handle:
- cli
- push eax
- mov eax, 6
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception7Handle:
- cli
- push eax
- mov eax, 7
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception8Handle:
- cli
- push eax
- mov eax, 8
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception9Handle:
- cli
- push eax
- mov eax, 9
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception10Handle:
- cli
- push eax
- mov eax, 10
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception11Handle:
- cli
- push eax
- mov eax, 11
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception12Handle:
- cli
- push eax
- mov eax, 12
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception13Handle:
- cli
- push eax
- mov eax, 13
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception14Handle:
- cli
- push eax
- mov eax, 14
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception15Handle:
- cli
- push eax
- mov eax, 15
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception16Handle:
- cli
- push eax
- mov eax, 16
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception17Handle:
- cli
- push eax
- mov eax, 17
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception18Handle:
- cli
- push eax
- mov eax, 18
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- Exception19Handle:
- cli
- push eax
- mov eax, 19
- jmp dword [CommonEntryAddr]
- AGENT_HANDLER_SIGNATURE
- ASM_PFX(TimerInterruptHandle):
- cli
- push eax
- mov eax, 32
- jmp dword [CommonEntryAddr]
- CommonEntry:
- ;
- ; +---------------------+
- ; + EFlags +
- ; +---------------------+
- ; + CS +
- ; +---------------------+
- ; + EIP +
- ; +---------------------+
- ; + Error Code +
- ; +---------------------+
- ; + EAX / Vector Number +
- ; +---------------------+
- ; + EBP +
- ; +---------------------+ <-- EBP
- ;
- cmp eax, DEBUG_EXCEPT_DOUBLE_FAULT
- je NoExtrPush
- cmp eax, DEBUG_EXCEPT_INVALID_TSS
- je NoExtrPush
- cmp eax, DEBUG_EXCEPT_SEG_NOT_PRESENT
- je NoExtrPush
- cmp eax, DEBUG_EXCEPT_STACK_FAULT
- je NoExtrPush
- cmp eax, DEBUG_EXCEPT_GP_FAULT
- je NoExtrPush
- cmp eax, DEBUG_EXCEPT_PAGE_FAULT
- je NoExtrPush
- cmp eax, DEBUG_EXCEPT_ALIGNMENT_CHECK
- je NoExtrPush
- push dword [esp]
- mov dword [esp + 4], 0
- NoExtrPush:
- push ebp
- mov ebp, esp ; save esp in ebp
- ;
- ; Make stack 16-byte alignment to make sure save fxrstor later
- ;
- and esp, 0xfffffff0
- sub esp, 12
- ; store UINT32 Edi, Esi, Ebp, Ebx, Edx, Ecx, Eax;
- push dword [ebp + 4] ; original eax
- push ebx
- push ecx
- push edx
- mov ebx, eax ; save vector in ebx
- mov eax, ebp
- add eax, 4 * 6
- push eax ; original ESP
- push dword [ebp] ; EBP
- push esi
- push edi
- ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- ;; insure FXSAVE/FXRSTOR is enabled in CR4...
- ;; ... while we're at it, make sure DE is also enabled...
- mov eax, 1
- push ebx ; temporarily save value of ebx on stack
- cpuid ; use CPUID to determine if FXSAVE/FXRESTOR and
- ; DE are supported
- pop ebx ; restore value of ebx that was overwritten by CPUID
- mov eax, cr4
- push eax ; push cr4 firstly
- test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
- jz .0
- or eax, BIT9 ; Set CR4.OSFXSR
- .0:
- test edx, BIT2 ; Test for Debugging Extensions support
- jz .1
- or eax, BIT3 ; Set CR4.DE
- .1:
- mov cr4, eax
- mov eax, cr3
- push eax
- mov eax, cr2
- push eax
- push 0 ; cr0 will not saved???
- mov eax, cr0
- push eax
- xor ecx, ecx
- mov ecx, Ss
- push ecx
- mov ecx, Cs
- push ecx
- mov ecx, Ds
- push ecx
- mov ecx, Es
- push ecx
- mov ecx, Fs
- push ecx
- mov ecx, Gs
- push ecx
- ;; EIP
- mov ecx, [ebp + 4 * 3] ; EIP
- push ecx
- ;; UINT32 Gdtr[2], Idtr[2];
- sub esp, 8
- sidt [esp]
- sub esp, 8
- sgdt [esp]
- ;; UINT32 Ldtr, Tr;
- xor eax, eax
- str ax
- push eax
- sldt ax
- push eax
- ;; EFlags
- mov ecx, [ebp + 4 * 5]
- push ecx
- ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- mov eax, dr7
- push eax
- ;; clear Dr7 while executing debugger itself
- xor eax, eax
- mov dr7, eax
- ;; Dr6
- mov eax, dr6
- push eax
- ;; insure all status bits in dr6 are clear...
- xor eax, eax
- mov dr6, eax
- mov eax, dr3
- push eax
- mov eax, dr2
- push eax
- mov eax, dr1
- push eax
- mov eax, dr0
- push eax
- ;; Clear Direction Flag
- cld
- ;; FX_SAVE_STATE_IA32 FxSaveState;
- sub esp, 512
- mov edi, esp
- ;; Clear the buffer
- xor eax, eax
- mov ecx, 128 ;= 512 / 4
- rep stosd
- mov edi, esp
- test edx, BIT24 ; Test for FXSAVE/FXRESTOR support.
- ; edx still contains result from CPUID above
- jz .2
- fxsave [edi]
- .2:
- ;; save the exception data
- push dword [ebp + 8]
- ; call the C interrupt process function
- push esp ; Structure
- push ebx ; vector
- call ASM_PFX(InterruptProcess)
- add esp, 8
- ; skip the exception data
- add esp, 4
- ;; FX_SAVE_STATE_IA32 FxSaveState;
- mov esi, esp
- mov eax, 1
- cpuid ; use CPUID to determine if FXSAVE/FXRESTOR are supported
- test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
- jz .3
- fxrstor [esi]
- .3:
- add esp, 512
- ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- pop eax
- mov dr0, eax
- pop eax
- mov dr1, eax
- pop eax
- mov dr2, eax
- pop eax
- mov dr3, eax
- ;; skip restore of dr6. We cleared dr6 during the context save.
- add esp, 4
- pop eax
- mov dr7, eax
- ;; set EFlags
- pop dword [ebp + 4 * 5] ; set EFLAGS in stack
- ;; UINT32 Ldtr, Tr;
- ;; UINT32 Gdtr[2], Idtr[2];
- ;; Best not let anyone mess with these particular registers...
- add esp, 24
- ;; UINT32 Eip;
- pop dword [ebp + 4 * 3] ; set EIP in stack
- ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- ;; NOTE - modified segment registers could hang the debugger... We
- ;; could attempt to insulate ourselves against this possibility,
- ;; but that poses risks as well.
- ;;
- pop gs
- pop fs
- pop es
- pop ds
- pop dword [ebp + 4 * 4] ; set CS in stack
- pop ss
- ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- pop eax
- mov cr0, eax
- add esp, 4 ; skip for Cr1
- pop eax
- mov cr2, eax
- pop eax
- mov cr3, eax
- pop eax
- mov cr4, eax
- ;; restore general register
- pop edi
- pop esi
- pop dword [ebp] ; save updated ebp
- pop dword [ebp + 4] ; save updated esp
- pop edx
- pop ecx
- pop ebx
- pop eax
- mov esp, ebp
- pop ebp ; restore ebp maybe updated
- pop esp ; restore esp maybe updated
- sub esp, 4 * 3 ; restore interrupt pushced stack
- iretd
|