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