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