test: alpha/exceptn.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# exceptn.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Defines

#define | DEFAULT_NO_ALIGNMENT_FIXUPS FALSE

## Functions

VOID | KiMachineCheck (IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
VOID | KeContextFromKframes (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT ContextFrame)
VOID | KeContextToKframes (IN OUT PKTRAP_FRAME TrapFrame, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN PCONTEXT ContextFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
VOID | KiDispatchException (IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
ULONG | KiCopyInformation (IN OUT PEXCEPTION_RECORD ExceptionRecord1, IN PEXCEPTION_RECORD ExceptionRecord2)
NTSTATUS | KeRaiseUserException (IN NTSTATUS ExceptionCode)

## Variables

ULONG | KiEnableAlignmentFaultExceptions = DEFAULT_NO_ALIGNMENT_FIXUPS ? 1 : 0

## Define Documentation

#define DEFAULT_NO_ALIGNMENT_FIXUPS FALSE

| Definition at line 74 of file alpha/exceptn.c.

## Function Documentation

VOID KeContextFromKframes | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN OUT PCONTEXT | ContextFrame
| ) |

Definition at line 104 of file alpha/exceptn.c.

References CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, and CONTEXT_INTEGER.

    00112                    :
    00113
    00114     This routine moves the selected contents of the specified trap and exception
    00115     frames into the specified context frame according to the specified context
    00116     flags.
    00117
    00118 Arguments:
    00119
    00120     TrapFrame - Supplies a pointer to a trap frame from which volatile context
    00121         should be copied into the context record.
    00122
    00123     ExceptionFrame - Supplies a pointer to an exception frame from which context
    00124         should be copied into the context record.
    00125
    00126     ContextFrame - Supplies a pointer to the context frame that receives the
    00127         context copied from the trap and exception frames.
    00128
    00129 Return Value:
    00130
    00131     None.
    00132
    00133 --*/
    00134
    00135 {
    00136
    00137     //
    00138     // Set control information if specified.
    00139     //
    00140
    00141     if ((ContextFrame->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
    00142
    00143         //
    00144         // Set integer register gp, ra, sp, FIR, and PSR from trap frame.
    00145         //
    00146
    00147         ContextFrame->IntGp = TrapFrame->IntGp;
    00148         ContextFrame->IntSp = TrapFrame->IntSp;
    00149         ContextFrame->IntRa = TrapFrame->IntRa;
    00150         ContextFrame->Fir = TrapFrame->Fir;
    00151         ContextFrame->Psr = TrapFrame->Psr;
    00152     }
    00153
    00154     //
    00155     // Set integer register contents if specified.
    00156     //
    00157
    00158     if ((ContextFrame->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
    00159
    00160         //
    00161         // Set volatile integer registers v0 and t0 - t7 from trap frame.
    00162         //
    00163
    00164         ContextFrame->IntV0 = TrapFrame->IntV0;
    00165         ContextFrame->IntT0 = TrapFrame->IntT0;
    00166         ContextFrame->IntT1 = TrapFrame->IntT1;
    00167         ContextFrame->IntT2 = TrapFrame->IntT2;
    00168         ContextFrame->IntT3 = TrapFrame->IntT3;
    00169         ContextFrame->IntT4 = TrapFrame->IntT4;
    00170         ContextFrame->IntT5 = TrapFrame->IntT5;
    00171         ContextFrame->IntT6 = TrapFrame->IntT6;
    00172         ContextFrame->IntT7 = TrapFrame->IntT7;
    00173
    00174         //
    00175         // Set nonvolatile integer registers s0 - s5 from exception frame.
    00176         //
    00177
    00178         ContextFrame->IntS0 = ExceptionFrame->IntS0;
    00179         ContextFrame->IntS1 = ExceptionFrame->IntS1;
    00180         ContextFrame->IntS2 = ExceptionFrame->IntS2;
    00181         ContextFrame->IntS3 = ExceptionFrame->IntS3;
    00182         ContextFrame->IntS4 = ExceptionFrame->IntS4;
    00183         ContextFrame->IntS5 = ExceptionFrame->IntS5;
    00184
    00185         //
    00186         // Set volatile integer registers a0 - a5, and t8 - t11 from trap
    00187         // frame.
    00188         //
    00189
    00190         ContextFrame->IntA0 = TrapFrame->IntA0;
    00191         ContextFrame->IntA1 = TrapFrame->IntA1;
    00192         ContextFrame->IntA2 = TrapFrame->IntA2;
    00193         ContextFrame->IntA3 = TrapFrame->IntA3;
    00194         ContextFrame->IntA4 = TrapFrame->IntA4;
    00195         ContextFrame->IntA5 = TrapFrame->IntA5;
    00196
    00197         ContextFrame->IntT8 = TrapFrame->IntT8;
    00198         ContextFrame->IntT9 = TrapFrame->IntT9;
    00199         ContextFrame->IntT10 = TrapFrame->IntT10;
    00200         ContextFrame->IntT11 = TrapFrame->IntT11;
    00201
    00202         //
    00203         // Set volatile integer registers fp, t12 and at from trap frame.
    00204         // Set integer register zero.
    00205         //
    00206
    00207         ContextFrame->IntFp = TrapFrame->IntFp;
    00208         ContextFrame->IntT12 = TrapFrame->IntT12;
    00209         ContextFrame->IntAt = TrapFrame->IntAt;
    00210         ContextFrame->IntZero = 0;
    00211     }
    00212
    00213     //
    00214     // Set floating register contents if specified.
    00215     //
    00216
    00217     if ((ContextFrame->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
    00218
    00219         //
    00220         // Set volatile floating registers f0 - f1 from trap frame.
    00221         // Set volatile floating registers f10 - f30 from trap frame.
    00222         // Set floating zero register f31 to 0.
    00223         //
    00224
    00225         ContextFrame->FltF0 = TrapFrame->FltF0;
    00226         ContextFrame->FltF1 = TrapFrame->FltF1;
    00227         RtlMoveMemory(&ContextFrame->FltF10, &TrapFrame->FltF10,
    00228                       sizeof(ULONGLONG) * 21);
    00229         ContextFrame->FltF31 = 0;
    00230
    00231         //
    00232         // Set nonvolatile floating registers f2 - f9 from exception frame.
    00233         //
    00234
    00235         ContextFrame->FltF2 = ExceptionFrame->FltF2;
    00236         ContextFrame->FltF3 = ExceptionFrame->FltF3;
    00237         ContextFrame->FltF4 = ExceptionFrame->FltF4;
    00238         ContextFrame->FltF5 = ExceptionFrame->FltF5;
    00239         ContextFrame->FltF6 = ExceptionFrame->FltF6;
    00240         ContextFrame->FltF7 = ExceptionFrame->FltF7;
    00241         ContextFrame->FltF8 = ExceptionFrame->FltF8;
    00242         ContextFrame->FltF9 = ExceptionFrame->FltF9;
    00243
    00244         //
    00245         // Set floating point control register from trap frame.
    00246         // Clear software floating point control register in context frame
    00247         // (if necessary, it can be set to the proper value by the caller).
    00248         //
    00249
    00250         ContextFrame->Fpcr = TrapFrame->Fpcr;
    00251         ContextFrame->SoftFpcr = 0;
    00252     }
    00253
    00254     return;
    00255 }

VOID KeContextToKframes | ( | IN OUT PKTRAP_FRAME | TrapFrame,
|  | IN OUT PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PCONTEXT | ContextFrame,
|  | IN ULONG | ContextFlags,
|  | IN KPROCESSOR_MODE | PreviousMode
| ) |

Definition at line 258 of file alpha/exceptn.c.

References CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, and CONTEXT_INTEGER.

    00268                    :
    00269
    00270     This routine moves the selected contents of the specified context frame into
    00271     the specified trap and exception frames according to the specified context
    00272     flags.
    00273
    00274 Arguments:
    00275
    00276     TrapFrame - Supplies a pointer to a trap frame that receives the volatile
    00277         context from the context record.
    00278
    00279     ExceptionFrame - Supplies a pointer to an exception frame that receives
    00280         the nonvolatile context from the context record.
    00281
    00282     ContextFrame - Supplies a pointer to a context frame that contains the
    00283         context that is to be copied into the trap and exception frames.
    00284
    00285     ContextFlags - Supplies the set of flags that specify which parts of the
    00286         context frame are to be copied into the trap and exception frames.
    00287
    00288     PreviousMode - Supplies the processor mode for which the trap and exception
    00289         frames are being built.
    00290
    00291 Return Value:
    00292
    00293     None.
    00294
    00295 --*/
    00296
    00297 {
    00298
    00299     //
    00300     // Set control information if specified.
    00301     //
    00302
    00303     if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
    00304
    00305         //
    00306         // Set integer register gp, sp, ra, FIR, and PSR in trap frame.
    00307         //
    00308
    00309         TrapFrame->IntGp = ContextFrame->IntGp;
    00310         TrapFrame->IntSp = ContextFrame->IntSp;
    00311         TrapFrame->IntRa = ContextFrame->IntRa;
    00312         TrapFrame->Fir = ContextFrame->Fir;
    00313         TrapFrame->Psr = SANITIZE_PSR(ContextFrame->Psr, PreviousMode);
    00314     }
    00315
    00316     //
    00317     // Set integer register contents if specified.
    00318     //
    00319
    00320     if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
    00321
    00322         //
    00323         // Set volatile integer registers v0 and t0 - t7 in trap frame.
    00324         //
    00325
    00326         TrapFrame->IntV0 = ContextFrame->IntV0;
    00327         TrapFrame->IntT0 = ContextFrame->IntT0;
    00328         TrapFrame->IntT1 = ContextFrame->IntT1;
    00329         TrapFrame->IntT2 = ContextFrame->IntT2;
    00330         TrapFrame->IntT3 = ContextFrame->IntT3;
    00331         TrapFrame->IntT4 = ContextFrame->IntT4;
    00332         TrapFrame->IntT5 = ContextFrame->IntT5;
    00333         TrapFrame->IntT6 = ContextFrame->IntT6;
    00334         TrapFrame->IntT7 = ContextFrame->IntT7;
    00335
    00336         //
    00337         // Set nonvolatile integer registers s0 - s5 in exception frame.
    00338         //
    00339
    00340         ExceptionFrame->IntS0 = ContextFrame->IntS0;
    00341         ExceptionFrame->IntS1 = ContextFrame->IntS1;
    00342         ExceptionFrame->IntS2 = ContextFrame->IntS2;
    00343         ExceptionFrame->IntS3 = ContextFrame->IntS3;
    00344         ExceptionFrame->IntS4 = ContextFrame->IntS4;
    00345         ExceptionFrame->IntS5 = ContextFrame->IntS5;
    00346
    00347         //
    00348         // Set volatile integer registers a0 - a5, and t8 - t11 in trap frame.
    00349         //
    00350
    00351         TrapFrame->IntA0 = ContextFrame->IntA0;
    00352         TrapFrame->IntA1 = ContextFrame->IntA1;
    00353         TrapFrame->IntA2 = ContextFrame->IntA2;
    00354         TrapFrame->IntA3 = ContextFrame->IntA3;
    00355         TrapFrame->IntA4 = ContextFrame->IntA4;
    00356         TrapFrame->IntA5 = ContextFrame->IntA5;
    00357
    00358         TrapFrame->IntT8 = ContextFrame->IntT8;
    00359         TrapFrame->IntT9 = ContextFrame->IntT9;
    00360         TrapFrame->IntT10 = ContextFrame->IntT10;
    00361         TrapFrame->IntT11 = ContextFrame->IntT11;
    00362
    00363         //
    00364         // Set volatile integer registers fp, t12 and at in trap frame.
    00365         //
    00366
    00367         TrapFrame->IntFp = ContextFrame->IntFp;
    00368         TrapFrame->IntT12 = ContextFrame->IntT12;
    00369         TrapFrame->IntAt = ContextFrame->IntAt;
    00370     }
    00371
    00372     //
    00373     // Set floating register contents if specified.
    00374     //
    00375
    00376     if ((ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
    00377
    00378         //
    00379         // Set volatile floating registers f0 - f1 in trap frame.
    00380         // Set volatile floating registers f10 - f30 in trap frame.
    00381         //
    00382
    00383         TrapFrame->FltF0 = ContextFrame->FltF0;
    00384         TrapFrame->FltF1 = ContextFrame->FltF1;
    00385         RtlMoveMemory(&TrapFrame->FltF10, &ContextFrame->FltF10,
    00386                       sizeof(ULONGLONG) * 21);
    00387
    00388         //
    00389         // Set nonvolatile floating registers f2 - f9 in exception frame.
    00390         //
    00391
    00392         ExceptionFrame->FltF2 = ContextFrame->FltF2;
    00393         ExceptionFrame->FltF3 = ContextFrame->FltF3;
    00394         ExceptionFrame->FltF4 = ContextFrame->FltF4;
    00395         ExceptionFrame->FltF5 = ContextFrame->FltF5;
    00396         ExceptionFrame->FltF6 = ContextFrame->FltF6;
    00397         ExceptionFrame->FltF7 = ContextFrame->FltF7;
    00398         ExceptionFrame->FltF8 = ContextFrame->FltF8;
    00399         ExceptionFrame->FltF9 = ContextFrame->FltF9;
    00400
    00401         //
    00402         // Set floating point control register in trap frame.
    00403         //
    00404
    00405         TrapFrame->Fpcr = ContextFrame->Fpcr;
    00406     }
    00407
    00408     return;
    00409 }

NTSTATUS KeRaiseUserException | ( | IN NTSTATUS | ExceptionCode | ) |

Definition at line 1024 of file alpha/exceptn.c.

References ASSERT, KeGetCurrentThread, KeRaiseUserExceptionDispatcher, and UserMode.

    01030                    :
    01031
    01032     This function causes an exception to be raised in the calling thread's user-mode
    01033     context. It does this by editing the trap frame the kernel was entered with to
    01034     point to trampoline code that raises the requested exception.
    01035
    01036 Arguments:
    01037
    01038     ExceptionCode - Supplies the status value to be used as the exception
    01039         code for the exception that is to be raised.
    01040
    01041 Return Value:
    01042
    01043     The status value that should be returned by the caller.
    01044
    01045 --*/
    01046
    01047 {
    01048
    01049     PKTRAP_FRAME TrapFrame;
    01050
    01051     ASSERT(KeGetPreviousMode() == UserMode);
    01052
    01053     TrapFrame = KeGetCurrentThread()->TrapFrame;
    01054
    01055     TrapFrame->Fir = (ULONGLONG)(LONG_PTR)KeRaiseUserExceptionDispatcher;
    01056     return(ExceptionCode);
    01057 }

ULONG KiCopyInformation | ( | IN OUT PEXCEPTION_RECORD | ExceptionRecord1,
|  | IN PEXCEPTION_RECORD | ExceptionRecord2
| ) |

Definition at line 984 of file alpha/exceptn.c.

    00991                    :
    00992
    00993     This function is called from an exception filter to copy the exception
    00994     information from one exception record to another when an exception occurs.
    00995
    00996 Arguments:
    00997
    00998     ExceptionRecord1 - Supplies a pointer to the destination exception record.
    00999
    01000     ExceptionRecord2 - Supplies a pointer to the source exception record.
    01001
    01002 Return Value:
    01003
    01004     A value of EXCEPTION_EXECUTE_HANDLER is returned as the function value.
    01005
    01006 --*/
    01007
    01008 {
    01009
    01010     //
    01011     // Copy one exception record to another and return value that causes
    01012     // an exception handler to be executed.
    01013     //
    01014
    01015     RtlMoveMemory((PVOID)ExceptionRecord1,
    01016                   (PVOID)ExceptionRecord2,
    01017                   sizeof(EXCEPTION_RECORD));
    01018
    01019     return EXCEPTION_EXECUTE_HANDLER;
    01020 }

VOID KiDispatchException | ( | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PKTRAP_FRAME | TrapFrame,
|  | IN KPROCESSOR_MODE | PreviousMode,
|  | IN BOOLEAN | FirstChance
| ) |

Definition at line 412 of file alpha/exceptn.c.

    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     // If the exception is an illegal instruction exception, then check for
    00481     // a byte/word instruction that should be emulated.
    00482     //
    00483     // N.B. The exception code STATUS_ILLEGAL_INSTRUCTION may be converted
    00484     //      into STATUS_DATATYPE_MISALIGNMENT in the case of unaligned word
    00485     //      access.
    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     // If the exception is a data misalignment, the previous mode was user,
    00514     // this is the first chance for handling the exception, and the current
    00515     // thread has enabled automatic alignment fixup, then attempt to emulate
    00516     // the unaligned reference.
    00517     //
    00518
    00519     if ((ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) &&
    00520         (FirstChance != FALSE)) {
    00521
    00522 #if DBG
    00523
    00524         //
    00525         // Count alignment faults by mode and display them at intervals.
    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         // If alignment fault exceptions are not enabled, then no exception
    00553         // should be raised and the data reference should be emulated.
    00554         //
    00555         // We will emulate the reference if
    00556         //      KiEnableAlignmentFaultExceptions == 0 (always fix up all faults, the default)
    00557         // OR   The thread has explicitly enabled alignment fixups
    00558         // OR   KiEnableAlignmentFaultExceptions == 2 and the process is not being debugged
    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     // If the exception is a data bus error then a machine check has
    00581     // been trapped by the PALcode. The error will be forwarded to the
    00582     // HAL eventually for logging or handling. If the handler returns
    00583     // it is assumed that the HAL successfully handled the error and
    00584     // execution may resume.
    00585     //
    00586     // N.B. A special exception code is used to signal a data bus error.
    00587     //      This code is equivalent to the bug check code merged with a
    00588     //      reserved facility code and the reserved bit set.
    00589     //
    00590
    00591     if (ExceptionRecord->ExceptionCode == (DATA_BUS_ERROR | 0xdfff0000)) {
    00592         KiMachineCheck(ExceptionRecord, ExceptionFrame, TrapFrame);
    00593         goto Handled2;
    00594     }
    00595
    00596     //
    00597     // Initialize the copy of the software FPCR. The proper value is set
    00598     // if a floating emulation operation is performed. Case on arithmetic
    00599     // exception codes that require special handling by the kernel.
    00600     //
    00601
    00602     SoftFpcr = 0;
    00603     switch (ExceptionRecord->ExceptionCode) {
    00604
    00605         //
    00606         // If the exception is a gentrap, then attempt to translate the
    00607         // Alpha specific gentrap value to a status code value. This
    00608         // exception is a precise trap.
    00609         //
    00610         // N.B. STATUS_ALPHA_GENTRAP is a pseudo status code generated by
    00611         //      PALcode when a callpal gentrap is executed. The status is
    00612         //      visible in user mode only when the gentrap code value is
    00613         //      unrecognized.
    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         // If the exception is an unimplemented floating operation, then
    00650         // PALcode has detected a subsetted floating point operation. These
    00651         // include attempts to use round to plus or minus infinity rounding
    00652         // modes on EV4. This exception is a fault.
    00653         //
    00654         // If the previous mode was user, an attempt is made to emulate the
    00655         // operation. If the emulation is successful, the continuation
    00656         // address is incremented to the next instruction.
    00657         //
    00658         // N.B. STATUS_ALPHA_FLOATING_NOT_IMPLEMENTED is a pseudo status code
    00659         //      generated by PALcode. The status is never visible outside of
    00660         //      this handler because the floating emulation routine converts
    00661         //      the status code to the proper floating status value.
    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         // If the exception is an arithmetic exception, then one or more
    00683         // integer overflow or floating point traps has occurred. This
    00684         // exception is an imprecise (asynchronous) trap. Attempt to locate
    00685         // the original trapping instruction and emulate the instruction.
    00686         //
    00687         // N.B. STATUS_ALPHA_ARITHMETIC_EXCEPTION is a pseudo status code
    00688         //      generated by PALcode. The status is never visible outside of
    00689         //      this handler because the floating emulation routine converts
    00690         //      the status code to the proper floating status value.
    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     // Move machine state from trap and exception frames to a context frame,
    00706     // and increment the number of exceptions dispatched.
    00707     //
    00708     // Explicitly set the value of the software FPCR in the context frame
    00709     // (because it is not a hardware register and thus not present in the
    00710     // trap or exception frames).
    00711     //
    00712
    00713     ContextFrame.ContextFlags = CONTEXT_FULL;
    00714     KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame);
    00715     KeGetCurrentPrcb()->KeExceptionDispatchCount += 1;
    00716     ContextFrame.SoftFpcr = (ULONGLONG)SoftFpcr;
    00717
    00718     //
    00719     // Select the method of handling the exception based on the previous mode.
    00720     //
    00721
    00722     if (PreviousMode == KernelMode) {
    00723
    00724         //
    00725         // If the kernel debugger is active, the exception is a breakpoint,
    00726         // the breakpoint is handled by the kernel debugger, and this is the
    00727         // first chance, then give the kernel debugger a chance to handle
    00728         // the exception.
    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         // Previous mode was kernel.
    00750         //
    00751         // If this is the first chance, then attempt to dispatch the exception
    00752         // to a frame based handler. If the exception is handled, then continue
    00753         // execution.
    00754         //
    00755         // If this is the second chance or the exception is not handled,
    00756         // then if the kernel debugger is active, then give the kernel
    00757         // debugger a second chance to handle the exception. If the kernel
    00758         // debugger handles the exception, then continue execution. Otherwise
    00759         // bug check.
    00760         //
    00761
    00762         if (FirstChance != FALSE) {
    00763
    00764             //
    00765             // This is the first chance to handle the exception.
    00766             //
    00767
    00768             if (RtlDispatchException(ExceptionRecord, &ContextFrame) != FALSE) {
    00769                 goto Handled1;
    00770             }
    00771         }
    00772
    00773         //
    00774         // This is the second chance to handle the exception.
    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         // If the kernel debugger is active, the exception is a breakpoint,
    00798         // the breakpoint is handled by the kernel debugger, and this is the
    00799         // first chance, then give the kernel debugger a chance to handle
    00800         // the exception.
    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         // Previous mode was user.
    00828         //
    00829         // If this is the first chance and the current process has a debugger
    00830         // port, then send a message to the debugger port and wait for a reply.
    00831         // If the debugger handles the exception, then continue execution. Otherwise
    00832         // transfer the exception information to the user stack, transition to
    00833         // user mode, and attempt to dispatch the exception to a frame based
    00834         // handler. If a frame based handler handles the exception, then continue
    00835         // execution. Otherwise, execute the raise exception system service
    00836         // which will call this routine a second time to process the exception.
    00837         //
    00838         // If this is the second chance and the current process has a debugger
    00839         // port, then send a message to the debugger port and wait for a reply.
    00840         // If the debugger handles the exception, then continue execution. Otherwise
    00841         // if the current process has a subsystem port, then send a message to
    00842         // the subsystem port and wait for a reply. If the subsystem handles the
    00843         // exception, then continue execution. Otherwise terminate the thread.
    00844         //
    00845
    00846         if (FirstChance != FALSE) {
    00847
    00848             //
    00849             // This is the first chance to handle the exception.
    00850             //
    00851
    00852             if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) {
    00853                 goto Handled2;
    00854             }
    00855
    00856             //
    00857             // Transfer exception information to the user stack, transition
    00858             // to user mode, and attempt to dispatch the exception to a frame
    00859             // based handler.
    00860             //
    00861
    00862         repeat:
    00863             try {
    00864
    00865                 //
    00866                 // Compute length of exception record and new aligned stack
    00867                 // address.
    00868                 //
    00869
    00870                 Length = (sizeof(EXCEPTION_RECORD) + 15) & (~15);
    00871                 UserStack1 = (ContextFrame.IntSp & ~((ULONG_PTR)15)) - Length;
    00872
    00873                 //
    00874                 // Probe user stack area for writability and then transfer the
    00875                 // exception record to the user stack area.
    00876                 //
    00877
    00878                 ProbeForWrite((PCHAR)UserStack1, Length, sizeof(QUAD));
    00879                 RtlMoveMemory((PVOID)UserStack1, ExceptionRecord, Length);
    00880
    00881                 //
    00882                 // Compute length of context record and new aligned user stack
    00883                 // pointer.
    00884                 //
    00885
    00886                 Length = (sizeof(CONTEXT) + 15) & (~15);
    00887                 UserStack2 = UserStack1 - Length;
    00888
    00889                 //
    00890                 // Probe user stack area for writability and then transfer the
    00891                 // context record to the user stack.
    00892                 //
    00893
    00894                 ProbeForWrite((PCHAR)UserStack2, Length, sizeof(QUAD));
    00895                 RtlMoveMemory((PVOID)UserStack2, &ContextFrame, sizeof(CONTEXT));
    00896
    00897                 //
    00898                 // Set address of exception record, context record, and the
    00899                 // and the new stack pointer in the current trap frame.
    00900                 //
    00901
    00902                 TrapFrame->IntSp = UserStack2;
    00903                 TrapFrame->IntFp = UserStack2;
    00904                 ExceptionFrame->IntS0 = UserStack1;
    00905                 ExceptionFrame->IntS1 = UserStack2;
    00906
    00907                 //
    00908                 // Set the address of the exception routine that will call the
    00909                 // exception dispatcher and then return to the trap handler.
    00910                 // The trap handler will restore the exception and trap frame
    00911                 // context and continue execution in the routine that will
    00912                 // call the exception dispatcher.
    00913                 //
    00914
    00915                 TrapFrame->Fir = (ULONGLONG)(LONG_PTR)KeUserExceptionDispatcher;
    00916                 return;
    00917
    00918             //
    00919             // If an exception occurs, then copy the new exception information
    00920             // to an exception record and handle the exception.
    00921             //
    00922
    00923             } except (KiCopyInformation(&ExceptionRecord1,
    00924                                (GetExceptionInformation())->ExceptionRecord)) {
    00925
    00926                 //
    00927                 // If the exception is a stack overflow, then attempt
    00928                 // to raise the stack overflow exception. Otherwise,
    00929                 // the user's stack is not accessible, or is misaligned,
    00930                 // and second chance processing is performed.
    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         // This is the second chance to handle the exception.
    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     // Move machine state from context frame to trap and exception frames and
    00965     // then return to continue execution with the restored state.
    00966     //
    00967
    00968 Handled1:
    00969     KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame,
    00970                        ContextFrame.ContextFlags, PreviousMode);
    00971
    00972     //
    00973     // Exception was handled by the debugger or the associated subsystem
    00974     // and state was modified, if necessary, using the get state and set
    00975     // state capabilities. Therefore the context frame does not need to
    00976     // be transferred to the trap and exception frames.
    00977     //
    00978
    00979 Handled2:
    00980     return;
    00981 }

VOID KiMachineCheck | ( | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PKTRAP_FRAME | TrapFrame
| ) |

Definition at line 31 of file alpha/buserror.c.

References DATA_BUS_ERROR, DbgPrint, and KeBugCheck().

Referenced by KiDispatchException().

    00039                    :
    00040
    00041     This function is called to process a machine check.  If the vendor
    00042     has supplied a machine check handler with its HAL then the machine
    00043     check handler is called.  If the routine returns TRUE indicating
    00044     that the error has been handled then execution resumes, otherwise,
    00045     a bugcheck is raised.
    00046
    00047     If no machine check handler is registered or it does not indicate
    00048     that the error has been handled, then this routine will attempt
    00049     default handling.  Default handling consists of checking the
    00050     machine check status in the exception record.  If the status indicates
    00051     that the machine check is correctable or retryable then return and
    00052     resume execution, otherwise a bugcheck is raised.
    00053
    00054 Arguments:
    00055
    00056     ExceptionRecord - Supplies a pointer to an exception record.
    00057
    00058     ExceptionFrame - Supplies a pointer to an exception frame.
    00059
    00060     TrapFrame - Supplies a pointer to a trap frame.
    00061
    00062 Return Value:
    00063
    00064     None.
    00065
    00066 --*/
    00067
    00068 {
    00069
    00070     if( ((ULONG_PTR)PCR->MachineCheckError != 0) &&
    00071           (PCR->MachineCheckError)(ExceptionRecord,
    00072                                    ExceptionFrame,
    00073                                    TrapFrame) ) {
    00074
    00075         //
    00076         // The HAL has handled the error.
    00077         //
    00078
    00079         return;
    00080
    00081     } else {
    00082
    00083         //
    00084         // Either there is no HAL handler, or it did not handle the
    00085         // error.
    00086         //
    00087
    00088         if( ExceptionRecord->ExceptionInformation[0] != 0 ){
    00089
    00090             //
    00091             // The error is either correctable or retryable, resume
    00092             // execution.
    00093             //
    00094
    00095 #if DBG
    00096
    00097             DbgPrint( "MCHK: resuming correctable or retryable error\n" );
    00098
    00099 #endif //DBG
    00100
    00101             return;
    00102
    00103         }
    00104     }
    00105
    00106
    00107     //
    00108     // The error was not handled and is not correctable or retryable.
    00109     //
    00110
    00111     KeBugCheck(DATA_BUS_ERROR);
    00112 }

## Variable Documentation

ULONG KiEnableAlignmentFaultExceptions = DEFAULT_NO_ALIGNMENT_FIXUPS ? 1 : 0

| Definition at line 77 of file alpha/exceptn.c. Referenced by KiDisableAlignmentExceptions(), and KiDispatchException().