00422 :
00423
00424 This function
is called to dispatch an exception to
the proper mode and
00425 to cause
the exception dispatcher to be called.
00426
00427 If
the exception
is a data misalignment,
the previous mode
is user,
this
00428
is the first chance
for handling
the exception, and
the current thread
00429 has enabled automatic alignment fixup, then an attempt
is made to emulate
00430
the unaligned reference. Data misalignment exceptions are never emulated
00431
for kernel mode.
00432
00433 If
the exception
is a floating not implemented exception, then an attempt
00434
is made to emulate
the floating operation. If
the exception
is an
00435 arithmetic exception, then an attempt
is made to convert
the imprecise
00436 exception into a precise exception, and then emulate
the floating
00437 operation in order to obtain
the proper IEEE results and exceptions.
00438 Floating exceptions are never emulated
for kernel mode.
00439
00440 If
the exception
is neither a data misalignment nor a floating point
00441 exception and
the previous mode
is kernel, then
the exception
00442 dispatcher
is called directly to process
the exception. Otherwise
the
00443 exception record, exception frame, and trap frame contents are copied
00444 to
the user mode stack. The contents of
the exception frame and trap
00445 are then modified such that when
control is returned, execution will
00446 commence in user mode in a routine which will call
the exception
00447 dispatcher.
00448
00449 Arguments:
00450
00451 ExceptionRecord - Supplies a pointer to an exception record.
00452
00453 ExceptionFrame - Supplies a pointer to an exception frame.
00454
00455 TrapFrame - Supplies a pointer to a trap frame.
00456
00457 PreviousMode - Supplies
the previous processor mode.
00458
00459 FirstChance - Supplies a
boolean variable that specifies whether
this
00460
is the first (TRUE) or second (FALSE) time that this exception has
00461 been processed.
00462
00463 Return Value:
00464
00465 None.
00466
00467 --*/
00468
00469 {
00470
00471 CONTEXT ContextFrame;
00472 EXCEPTION_RECORD ExceptionRecord1;
00473 PEXC_SUM ExceptionSummary;
00474 LONG Length;
00475 ULONG SoftFpcr;
00476 ULONGLONG UserStack1;
00477 ULONGLONG UserStack2;
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
if (ExceptionRecord->ExceptionCode == STATUS_ILLEGAL_INSTRUCTION) {
00489
if (
KiEmulateByteWord(ExceptionRecord,
00490 ExceptionFrame,
00491 TrapFrame) !=
FALSE) {
00492
KeGetCurrentPrcb()->KeByteWordEmulationCount += 1;
00493
goto Handled2;
00494 }
00495 }
00496
00497
#if DBG
00498
if (KiBreakOnAlignmentFault !=
FALSE) {
00499
00500
if (ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) {
00501
00502
DbgPrint(
"KI: Alignment fault exr = %p Pc = %p Address = %p\n",
00503 ExceptionRecord,
00504 ExceptionRecord->ExceptionAddress,
00505 ExceptionRecord->ExceptionInformation[2]);
00506
00507 DbgBreakPoint();
00508 }
00509 }
00510
#endif
00511
00512
00513
00514
00515
00516
00517
00518
00519
if ((ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) &&
00520 (FirstChance !=
FALSE)) {
00521
00522
#if DBG
00523
00524
00525
00526
00527
00528
if (PreviousMode ==
KernelMode) {
00529 KiKernelFixupCount += 1;
00530
if ((KiKernelFixupCount & KiKernelFixupMask) == 0) {
00531
DbgPrint(
"KI: Kernel Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n",
00532
PsGetCurrentProcess()->UniqueProcessId,
00533 ExceptionRecord->ExceptionAddress,
00534 ExceptionRecord->ExceptionInformation[2],
00535 KiKernelFixupCount);
00536 }
00537
00538 }
else {
00539 KiUserFixupCount += 1;
00540
if ((KiUserFixupCount & KiUserFixupMask) == 0) {
00541
DbgPrint(
"KI: User Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n",
00542
PsGetCurrentProcess()->UniqueProcessId,
00543 ExceptionRecord->ExceptionAddress,
00544 ExceptionRecord->ExceptionInformation[2],
00545 KiUserFixupCount);
00546 }
00547 }
00548
00549
#endif
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
if ( (
KiEnableAlignmentFaultExceptions == 0) ||
00562
00563 ((
KeGetCurrentThread()->AutoAlignment !=
FALSE) ||
00564 (
KeGetCurrentThread()->ApcState.Process->AutoAlignment !=
FALSE)) ||
00565
00566 (((
PsGetCurrentProcess()->DebugPort ==
NULL) || (PreviousMode ==
KernelMode)) &&
00567 (
KiEnableAlignmentFaultExceptions == 2)) ) {
00568
00569
if (
KiEmulateReference(ExceptionRecord,
00570 ExceptionFrame,
00571 TrapFrame,
00572 FALSE) !=
FALSE) {
00573
KeGetCurrentPrcb()->KeAlignmentFixupCount += 1;
00574
goto Handled2;
00575 }
00576 }
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
if (ExceptionRecord->ExceptionCode == (
DATA_BUS_ERROR | 0xdfff0000)) {
00592
KiMachineCheck(ExceptionRecord, ExceptionFrame, TrapFrame);
00593
goto Handled2;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602 SoftFpcr = 0;
00603
switch (ExceptionRecord->ExceptionCode) {
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
case STATUS_ALPHA_GENTRAP :
00617
switch (ExceptionRecord->ExceptionInformation[0]) {
00618
case GENTRAP_INTEGER_OVERFLOW :
00619 ExceptionRecord->ExceptionCode = STATUS_INTEGER_OVERFLOW;
00620
break;
00621
00622
case GENTRAP_INTEGER_DIVIDE_BY_ZERO :
00623 ExceptionRecord->ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
00624
break;
00625
00626
case GENTRAP_FLOATING_OVERFLOW :
00627 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
00628
break;
00629
00630
case GENTRAP_FLOATING_DIVIDE_BY_ZERO :
00631 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
00632
break;
00633
00634
case GENTRAP_FLOATING_UNDERFLOW :
00635 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
00636
break;
00637
00638
case GENTRAP_FLOATING_INVALID_OPERAND :
00639 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
00640
break;
00641
00642
case GENTRAP_FLOATING_INEXACT_RESULT :
00643 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
00644
break;
00645 }
00646
break;
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
case STATUS_ALPHA_FLOATING_NOT_IMPLEMENTED :
00665
if (PreviousMode !=
KernelMode) {
00666
if (
KiFloatingException(ExceptionRecord,
00667 ExceptionFrame,
00668 TrapFrame,
00669 FALSE,
00670 &SoftFpcr) !=
FALSE) {
00671 TrapFrame->Fir += 4;
00672
goto Handled2;
00673 }
00674
00675 }
else {
00676 ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
00677 }
00678
00679
break;
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
case STATUS_ALPHA_ARITHMETIC_EXCEPTION :
00694
if (
KiFloatingException(ExceptionRecord,
00695 ExceptionFrame,
00696 TrapFrame,
00697 TRUE,
00698 &SoftFpcr) !=
FALSE) {
00699
goto Handled2;
00700 }
00701
break;
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 ContextFrame.ContextFlags =
CONTEXT_FULL;
00714
KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame);
00715
KeGetCurrentPrcb()->KeExceptionDispatchCount += 1;
00716 ContextFrame.SoftFpcr = (ULONGLONG)SoftFpcr;
00717
00718
00719
00720
00721
00722
if (PreviousMode ==
KernelMode) {
00723
00724
00725
00726
00727
00728
00729
00730
00731
if ((FirstChance !=
FALSE) && (
KiDebugRoutine !=
NULL) &&
00732 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00733 (
KdIsThisAKdTrap(ExceptionRecord,
00734 &ContextFrame,
00735 KernelMode) !=
FALSE) &&
00736
00737 (((
KiDebugRoutine) (TrapFrame,
00738 ExceptionFrame,
00739 ExceptionRecord,
00740 &ContextFrame,
00741
KernelMode,
00742
FALSE)) !=
FALSE)) {
00743
00744
goto Handled1;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
if (FirstChance !=
FALSE) {
00763
00764
00765
00766
00767
00768
if (
RtlDispatchException(ExceptionRecord, &ContextFrame) !=
FALSE) {
00769
goto Handled1;
00770 }
00771 }
00772
00773
00774
00775
00776
00777
if ((
KiDebugRoutine !=
NULL) &&
00778 (((
KiDebugRoutine) (TrapFrame,
00779 ExceptionFrame,
00780 ExceptionRecord,
00781 &ContextFrame,
00782 PreviousMode,
00783
TRUE)) !=
FALSE)) {
00784
00785
goto Handled1;
00786 }
00787
00788
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
00789 ExceptionRecord->ExceptionCode,
00790 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
00791 ExceptionRecord->ExceptionInformation[0],
00792 ExceptionRecord->ExceptionInformation[1]);
00793
00794 }
else {
00795
00796
00797
00798
00799
00800
00801
00802
00803
if ((FirstChance !=
FALSE) &&
00804 (
KiDebugRoutine !=
NULL) &&
00805 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00806 (
KdIsThisAKdTrap(ExceptionRecord,
00807 &ContextFrame,
00808 UserMode) !=
FALSE) &&
00809
00810 ((
PsGetCurrentProcess()->DebugPort ==
NULL) ||
00811 ((
PsGetCurrentProcess()->DebugPort !=
NULL) &&
00812 (ExceptionRecord->ExceptionInformation[0] !=
00813 DEBUG_STOP_BREAKPOINT)))) {
00814
00815
if (((
KiDebugRoutine) (TrapFrame,
00816 ExceptionFrame,
00817 ExceptionRecord,
00818 &ContextFrame,
00819
UserMode,
00820
FALSE)) !=
FALSE) {
00821
00822
goto Handled1;
00823 }
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
if (FirstChance !=
FALSE) {
00847
00848
00849
00850
00851
00852
if (
DbgkForwardException(ExceptionRecord, TRUE, FALSE)) {
00853
goto Handled2;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862 repeat:
00863
try {
00864
00865
00866
00867
00868
00869
00870 Length = (
sizeof(EXCEPTION_RECORD) + 15) & (~15);
00871 UserStack1 = (ContextFrame.IntSp & ~((ULONG_PTR)15)) - Length;
00872
00873
00874
00875
00876
00877
00878
ProbeForWrite((PCHAR)UserStack1, Length,
sizeof(QUAD));
00879 RtlMoveMemory((PVOID)UserStack1, ExceptionRecord, Length);
00880
00881
00882
00883
00884
00885
00886 Length = (
sizeof(CONTEXT) + 15) & (~15);
00887 UserStack2 = UserStack1 - Length;
00888
00889
00890
00891
00892
00893
00894
ProbeForWrite((PCHAR)UserStack2, Length,
sizeof(QUAD));
00895 RtlMoveMemory((PVOID)UserStack2, &ContextFrame,
sizeof(CONTEXT));
00896
00897
00898
00899
00900
00901
00902 TrapFrame->IntSp = UserStack2;
00903 TrapFrame->IntFp = UserStack2;
00904 ExceptionFrame->IntS0 = UserStack1;
00905 ExceptionFrame->IntS1 = UserStack2;
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915 TrapFrame->Fir = (ULONGLONG)(LONG_PTR)
KeUserExceptionDispatcher;
00916
return;
00917
00918
00919
00920
00921
00922
00923 } except (
KiCopyInformation(&ExceptionRecord1,
00924 (GetExceptionInformation())->ExceptionRecord)) {
00925
00926
00927
00928
00929
00930
00931
00932
00933
if (ExceptionRecord1.ExceptionCode == STATUS_STACK_OVERFLOW) {
00934 ExceptionRecord1.ExceptionAddress = ExceptionRecord->ExceptionAddress;
00935 RtlMoveMemory((PVOID)ExceptionRecord,
00936 &ExceptionRecord1,
sizeof(EXCEPTION_RECORD));
00937
goto repeat;
00938 }
00939 }
00940 }
00941
00942
00943
00944
00945
00946
if (
DbgkForwardException(ExceptionRecord, TRUE, TRUE)) {
00947
goto Handled2;
00948
00949 }
else if (
DbgkForwardException(ExceptionRecord, FALSE, TRUE)) {
00950
goto Handled2;
00951
00952 }
else {
00953 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
00954
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
00955 ExceptionRecord->ExceptionCode,
00956 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
00957 ExceptionRecord->ExceptionInformation[0],
00958 ExceptionRecord->ExceptionInformation[1]);
00959
00960 }
00961 }
00962
00963
00964
00965
00966
00967
00968 Handled1:
00969
KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame,
00970 ContextFrame.ContextFlags, PreviousMode);
00971
00972
00973
00974
00975
00976
00977
00978
00979 Handled2:
00980
return;
00981 }