00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include "ki.h"
00025
#include "ntfpia64.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define DEFAULT_NO_ALIGNMENT_FIXUPS FALSE
00053
00054 ULONG
KiEnableAlignmentFaultExceptions =
DEFAULT_NO_ALIGNMENT_FIXUPS ? 1 : 2;
00055
00056
#if DBG
00057
00058
00059
00060
00061
00062
00063 BOOLEAN KiBreakOnAlignmentFault =
FALSE;
00064
00065
00066
00067
00068
00069
00070
00071
00072 ULONG KiKernelFixupCount = 0;
00073 ULONG KiKernelFixupMask =
DEFAULT_NO_ALIGNMENT_FIXUPS ? 0 : 0x7f;
00074
00075 ULONG KiUserFixupCount = 0;
00076 ULONG KiUserFixupMask =
DEFAULT_NO_ALIGNMENT_FIXUPS ? 0 : 0x3ff;
00077
00078
#endif
00079
00080
VOID
00081
KiRestoreHigherFPVolatile(
00082 VOID
00083 );
00084
00085 LONG
00086
fp_emulate (
00087 ULONG trap_type,
00088 PVOID pbundle,
00089 ULONGLONG *pipsr,
00090 ULONGLONG *pfpsr,
00091 ULONGLONG *pisr,
00092 ULONGLONG *ppreds,
00093 ULONGLONG *pifs,
00094 PVOID fp_state
00095 );
00096
00097 BOOLEAN
00098 KiEmulateFloat (
00099 PEXCEPTION_RECORD ExceptionRecord,
00100 PKEXCEPTION_FRAME ExceptionFrame,
00101 PKTRAP_FRAME TrapFrame
00102 )
00103 {
00104
00105
FLOATING_POINT_STATE FpState;
00106
USHORT ISRCode;
00107 ULONG TrapType;
00108 PVOID ExceptionAddress;
00109 LONG
Status = -1;
00110
00111 FpState.
ExceptionFrame = (PVOID)ExceptionFrame;
00112 FpState.
TrapFrame = (PVOID)TrapFrame;
00113
00114
if (ExceptionRecord->ExceptionCode == STATUS_FLOAT_MULTIPLE_FAULTS) {
00115 TrapType = 1;
00116 ExceptionAddress = (PVOID)TrapFrame->StIIP;
00117 }
else {
00118 TrapType = 0;
00119 ExceptionAddress = (PVOID)TrapFrame->StIIPA;
00120 }
00121
00122
if ((
Status =
fp_emulate(TrapType, ExceptionAddress,
00123 &TrapFrame->StIPSR, &TrapFrame->StFPSR, &TrapFrame->StISR,
00124 &TrapFrame->Preds, &TrapFrame->StIFS, (PVOID)&FpState)) == 0) {
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
if (TrapType == 1) {
00135
KiAdvanceInstPointer(TrapFrame);
00136 }
00137
00138
if (TrapFrame->StIPSR & (1 << PSR_MFH)) {
00139
00140
00141
00142
00143
00144
00145 __rsm ((1 << PSR_DFH) | (1 << PSR_I));
00146
KiRestoreHigherFPVolatile();
00147 __ssm ((1 << PSR_DFH) | (1 << PSR_I));
00148 __dsrlz();
00149 }
00150
00151
return TRUE;
00152 }
00153
00154
if (
Status == -1) {
00155
KeBugCheckEx(FP_EMULATION_ERROR,
00156 (ULONG_PTR)TrapFrame,
00157 (ULONG_PTR)ExceptionFrame, 0, 0);
00158 }
00159
00160
ISRCode = (
USHORT)TrapFrame->StISR;
00161
00162
if (
Status & 0x1) {
00163
00164 ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
00165
00166
if (!(
Status & 0x4)) {
00167
if (TrapType == 1) {
00168
00169
00170
00171
00172
00173
if (
ISRCode & 0x11) {
00174 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
00175 }
else if (
ISRCode & 0x22) {
00176 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DENORMAL_OPERAND;
00177 }
else if (
ISRCode & 0x44) {
00178 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
00179 }
00180
00181 }
else {
00182
00183
00184
00185
00186
00187
ISRCode =
ISRCode >> 7;
00188
if (
ISRCode & 0x11) {
00189 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
00190 }
else if (
ISRCode & 0x22) {
00191 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
00192 }
else if (
ISRCode & 0x44) {
00193 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
00194 }
00195
00196 }
00197 }
00198
00199
if (
Status & 0x2) {
00200
00201
00202
00203
00204
00205
KiAdvanceInstPointer(TrapFrame);
00206 ExceptionRecord->ExceptionAddress =
00207 (PVOID) RtlIa64InsertIPSlotNumber
00208 (TrapFrame->StIIP,
00209 ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI)
00210 );
00211
if (!(
Status & 0x4)) {
00212
ISRCode =
ISRCode >> 7;
00213
if (
ISRCode & 0x11) {
00214 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
00215 }
else if (
ISRCode & 0x22) {
00216 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
00217 }
else if (
ISRCode & 0x44) {
00218 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
00219 }
00220 }
else {
00221 ExceptionRecord->ExceptionCode = STATUS_FLOAT_MULTIPLE_TRAPS;
00222 }
00223 }
00224 }
00225
00226
return FALSE;
00227 }
00228
00229
VOID
00230 KiDispatchException (
00231 IN PEXCEPTION_RECORD ExceptionRecord,
00232 IN PKEXCEPTION_FRAME ExceptionFrame,
00233 IN PKTRAP_FRAME TrapFrame,
00234 IN KPROCESSOR_MODE PreviousMode,
00235 IN BOOLEAN FirstChance
00236 )
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 {
00285
00286 CONTEXT ContextFrame;
00287 EXCEPTION_RECORD ExceptionRecord1;
00288 PPLABEL_DESCRIPTOR Plabel;
00289 BOOLEAN UserApcPending;
00290
00291
00292
00293
00294
00295
00296
00297
00298
#if DBG
00299
if (KiBreakOnAlignmentFault !=
FALSE) {
00300
00301
if (ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) {
00302
00303
DbgPrint(
"KI: Alignment fault exr = %p Pc = %p Address = %p\n",
00304 ExceptionRecord,
00305 ExceptionRecord->ExceptionAddress,
00306 ExceptionRecord->ExceptionInformation[2]);
00307
00308 DbgBreakPoint();
00309 }
00310 }
00311
#endif
00312
00313
if ((ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) &&
00314 (FirstChance !=
FALSE)) {
00315
00316
#if DBG
00317
00318
00319
00320
00321
00322
if (PreviousMode ==
KernelMode) {
00323 KiKernelFixupCount += 1;
00324
if ((KiKernelFixupCount & KiKernelFixupMask) == 0) {
00325
DbgPrint(
"KI: Kernel Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n",
00326
PsGetCurrentProcess()->UniqueProcessId,
00327 ExceptionRecord->ExceptionAddress,
00328 ExceptionRecord->ExceptionInformation[1],
00329 KiKernelFixupCount);
00330 }
00331
00332 }
else {
00333 KiUserFixupCount += 1;
00334
if ((KiUserFixupCount & KiUserFixupMask) == 0) {
00335
DbgPrint(
"KI: User Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n",
00336
PsGetCurrentProcess()->UniqueProcessId,
00337 ExceptionRecord->ExceptionAddress,
00338 ExceptionRecord->ExceptionInformation[1],
00339 KiUserFixupCount);
00340 }
00341 }
00342
00343
#endif
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
if ( (
KiEnableAlignmentFaultExceptions == 0) ||
00356
00357 ((
KeGetCurrentThread()->AutoAlignment !=
FALSE) ||
00358 (
KeGetCurrentThread()->ApcState.Process->AutoAlignment !=
FALSE)) ||
00359
00360 (((
PsGetCurrentProcess()->DebugPort ==
NULL) || (PreviousMode ==
KernelMode)) &&
00361 (
KiEnableAlignmentFaultExceptions == 2)) ) {
00362
00363
if (
KiEmulateReference(ExceptionRecord,
00364 ExceptionFrame,
00365 TrapFrame) !=
FALSE)
00366 {
00367
KeGetCurrentPrcb()->KeAlignmentFixupCount += 1;
00368
goto Handled2;
00369 }
00370 }
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
if ((ExceptionRecord->ExceptionCode == STATUS_FLOAT_MULTIPLE_FAULTS) ||
00384 (ExceptionRecord->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS)) {
00385
00386
if (
KiEmulateFloat(ExceptionRecord, ExceptionFrame, TrapFrame)) {
00387
00388
00389
00390
00391
00392
return;
00393 }
00394 }
00395
00396
00397
00398
00399
00400
00401 ContextFrame.ContextFlags =
CONTEXT_FULL;
00402
KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame);
00403
KeGetCurrentPrcb()->KeExceptionDispatchCount += 1;
00404
00405
00406
00407
00408
00409
if (PreviousMode ==
KernelMode) {
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
if (FirstChance !=
FALSE) {
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
RtlpCaptureRnats(&ContextFrame);
00439 TrapFrame->RsRNAT = ContextFrame.RsRNAT;
00440
00441
00442
00443
00444
00445
00446
00447
if ((
KiDebugRoutine !=
NULL) &&
00448 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00449 (
KdIsThisAKdTrap(ExceptionRecord,
00450 &ContextFrame,
00451
KernelMode) !=
FALSE)) {
00452
00453
if (((
KiDebugRoutine) (TrapFrame,
00454 ExceptionFrame,
00455 ExceptionRecord,
00456 &ContextFrame,
00457
KernelMode,
00458
FALSE)) !=
FALSE) {
00459
00460
goto Handled1;
00461 }
00462 }
00463
00464
if (
RtlDispatchException(ExceptionRecord, &ContextFrame) !=
FALSE) {
00465
goto Handled1;
00466 }
00467 }
00468
00469
00470
00471
00472
00473
if (
KiDebugRoutine !=
NULL) {
00474
if (((
KiDebugRoutine) (TrapFrame,
00475 ExceptionFrame,
00476 ExceptionRecord,
00477 &ContextFrame,
00478 PreviousMode,
00479
TRUE)) !=
FALSE) {
00480
goto Handled1;
00481 }
00482 }
00483
00484
KeBugCheckEx(
KMODE_EXCEPTION_NOT_HANDLED,
00485 ExceptionRecord->ExceptionCode,
00486 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
00487 ExceptionRecord->ExceptionInformation[0],
00488 ExceptionRecord->ExceptionInformation[1]);
00489
00490 }
else {
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
if (FirstChance !=
FALSE) {
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
if ((
KiDebugRoutine !=
NULL) &&
00529 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00530 (
KdIsThisAKdTrap(ExceptionRecord,
00531 &ContextFrame,
00532
UserMode) !=
FALSE) &&
00533 ((
PsGetCurrentProcess()->DebugPort ==
NULL) ||
00534 ((
PsGetCurrentProcess()->DebugPort !=
NULL) &&
00535 (ExceptionRecord->ExceptionInformation[0] !=
00536 DEBUG_STOP_BREAKPOINT)))) {
00537
00538
if (((
KiDebugRoutine) (TrapFrame,
00539 ExceptionFrame,
00540 ExceptionRecord,
00541 &ContextFrame,
00542
UserMode,
00543
FALSE)) !=
FALSE) {
00544
00545
goto Handled1;
00546 }
00547 }
00548
00549
00550
00551
00552
00553
if (
DbgkForwardException(ExceptionRecord,
TRUE,
FALSE)) {
00554 TrapFrame->StFPSR = SANITIZE_FSR(TrapFrame->StFPSR,
UserMode);
00555
goto Handled2;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 repeat:
00594
try {
00595
00596
00597
00598
00599
00600
00601 ULONG Length = (STACK_SCRATCH_AREA + 15 +
00602
sizeof(EXCEPTION_REGISTRATION_RECORD) +
00603
sizeof(EXCEPTION_RECORD) +
sizeof(CONTEXT)) & ~(15);
00604 ULONGLONG UserStack = (ContextFrame.IntSp & (~15)) - Length;
00605 ULONGLONG ContextSlot = UserStack + STACK_SCRATCH_AREA;
00606 ULONGLONG ExceptSlot = ContextSlot +
sizeof(CONTEXT);
00607 PULONGLONG PUserStack = (PULONGLONG) UserStack;
00608
00609
00610
00611
00612
00613
00614
ProbeForWrite((PCHAR)UserStack, Length,
sizeof(QUAD));
00615 RtlMoveMemory((PVOID)ContextSlot, &ContextFrame,
00616
sizeof(CONTEXT));
00617 RtlMoveMemory((PVOID)ExceptSlot, ExceptionRecord,
00618
sizeof(EXCEPTION_RECORD));
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 TrapFrame->RsPFS = TrapFrame->StIFS;
00631 TrapFrame->StIFS &= 0xffffffc000000000;
00632 TrapFrame->StIPSR &= ~((0x3i64 << PSR_RI) | (0x1i64 << PSR_IS));
00633 TrapFrame->IntSp = UserStack;
00634 TrapFrame->IntNats = 0;
00635
00636 ExceptionFrame->IntS0 = ExceptSlot;
00637 ExceptionFrame->IntS1 = ContextSlot;
00638 ExceptionFrame->IntNats = 0;
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 Plabel = (PPLABEL_DESCRIPTOR)
KeUserExceptionDispatcher;
00649 TrapFrame->StIIP = Plabel->EntryPoint;
00650 TrapFrame->IntGp = Plabel->GlobalPointer;
00651
00652
return;
00653
00654
00655
00656
00657
00658
00659 } except (
KiCopyInformation(&ExceptionRecord1,
00660 (GetExceptionInformation())->ExceptionRecord)) {
00661
00662
00663
00664
00665
00666
00667
00668
00669
if (ExceptionRecord1.ExceptionCode == STATUS_STACK_OVERFLOW) {
00670 ExceptionRecord1.ExceptionAddress = ExceptionRecord->ExceptionAddress;
00671 RtlMoveMemory((PVOID)ExceptionRecord,
00672 &ExceptionRecord1,
sizeof(EXCEPTION_RECORD));
00673
goto repeat;
00674 }
00675 }
00676 }
00677
00678
00679
00680
00681
00682 UserApcPending =
KeGetCurrentThread()->ApcState.UserApcPending;
00683
if (
DbgkForwardException(ExceptionRecord,
TRUE,
TRUE)) {
00684 TrapFrame->StFPSR = SANITIZE_FSR(TrapFrame->StFPSR,
UserMode);
00685
goto Handled2;
00686
00687 }
else if (
DbgkForwardException(ExceptionRecord,
FALSE,
TRUE)) {
00688 TrapFrame->StFPSR = SANITIZE_FSR(TrapFrame->StFPSR,
UserMode);
00689
goto Handled2;
00690
00691 }
else {
00692 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
00693
KeBugCheckEx(
KMODE_EXCEPTION_NOT_HANDLED,
00694 ExceptionRecord->ExceptionCode,
00695 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
00696 ExceptionRecord->ExceptionInformation[0],
00697 ExceptionRecord->ExceptionInformation[1]);
00698 }
00699 }
00700
00701
00702
00703
00704
00705
00706 Handled1:
00707
KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame,
00708 ContextFrame.ContextFlags, PreviousMode);
00709
00710
00711
00712
00713
00714
00715
00716
00717 Handled2:
00718
return;
00719 }
00720
00721 ULONG
00722 KiCopyInformation (
00723 IN OUT PEXCEPTION_RECORD ExceptionRecord1,
00724 IN PEXCEPTION_RECORD ExceptionRecord2
00725 )
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 {
00747
00748
00749
00750
00751
00752 RtlMoveMemory((PVOID)ExceptionRecord1,
00753 (PVOID)ExceptionRecord2,
00754
sizeof(EXCEPTION_RECORD));
00755
00756
return EXCEPTION_EXECUTE_HANDLER;
00757 }
00758
00759
NTSTATUS
00760 KeRaiseUserException(
00761 IN NTSTATUS ExceptionCode
00762 )
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 {
00784 PKTRAP_FRAME TrapFrame;
00785
00786
ASSERT(KeGetPreviousMode() ==
UserMode);
00787
00788 TrapFrame =
KeGetCurrentThread()->TrapFrame;
00789
00790
try {
00791
ProbeForWrite ((PVOID)TrapFrame->IntSp, 16,
sizeof(QUAD));
00792 *(PULONGLONG)TrapFrame->IntSp = TrapFrame->BrRp;
00793 *(PULONGLONG)(TrapFrame->IntSp + 8) = TrapFrame->RsPFS;
00794 } except (
EXCEPTION_EXECUTE_HANDLER) {
00795
return (ExceptionCode);
00796 }
00797
00798 TrapFrame->StIIP = ((PPLABEL_DESCRIPTOR)
KeRaiseUserExceptionDispatcher)->EntryPoint;
00799 TrapFrame->StIFS &= (0x3i64 << 62);
00800
return(ExceptionCode);
00801 }