test: ppc/chandler.c File Reference

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

# chandler.c File Reference

`#include "nt.h"`

Go to the source code of this file.

## Functions

LONG | __C_ExecuteExceptionFilter (PEXCEPTION_POINTERS ExceptionPointers, EXCEPTION_FILTER ExceptionFilter, ULONG EstablisherFrame)
VOID | __C_ExecuteTerminationHandler (BOOLEAN AbnormalTermination, TERMINATION_HANDLER TerminationHandler, ULONG EstablisherFrame)
EXCEPTION_DISPOSITION | __C_specific_handler (IN PEXCEPTION_RECORD ExceptionRecord, IN PVOID EstablisherFrame, IN OUT PCONTEXT ContextRecord, IN OUT PDISPATCHER_CONTEXT DispatcherContext)

## Function Documentation

LONG __C_ExecuteExceptionFilter | ( | PEXCEPTION_POINTERS | ExceptionPointers,
|  | EXCEPTION_FILTER | ExceptionFilter,
|  | ULONG | EstablisherFrame
| ) |

| Referenced by __C_specific_handler(), and _OtsCSpecificHandler().

VOID __C_ExecuteTerminationHandler | ( | BOOLEAN | AbnormalTermination,
|  | TERMINATION_HANDLER | TerminationHandler,
|  | ULONG | EstablisherFrame
| ) |

| Referenced by __C_specific_handler(), _OtsCSpecificHandler(), and _OtsLocalFinallyUnwind().

EXCEPTION_DISPOSITION __C_specific_handler | ( | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PVOID | EstablisherFrame,
|  | IN OUT PCONTEXT | ContextRecord,
|  | IN OUT PDISPATCHER_CONTEXT | DispatcherContext
| ) |

Definition at line 49 of file ppc/chandler.c.

References __C_ExecuteExceptionFilter(), __C_ExecuteTerminationHandler(), ExceptionContinueExecution, ExceptionContinueSearch, Index, RtlUnwind2(), and TRUE.

    00058                    :
    00059
    00060     This function scans the scope tables associated with the specified
    00061     procedure and calls exception and termination handlers as necessary.
    00062
    00063 Arguments:
    00064
    00065     ExceptionRecord - Supplies a pointer to an exception record.
    00066
    00067     EstablisherFrame - Supplies a pointer to frame of the establisher function.
    00068
    00069     ContextRecord - Supplies a pointer to a context record.
    00070
    00071     DispatcherContext - Supplies a pointer to the exception dispatcher or
    00072         unwind dispatcher context.
    00073
    00074 Return Value:
    00075
    00076     If the exception is handled by one of the exception filter routines, then
    00077     there is no return from this routine and RtlUnwind is called. Otherwise,
    00078     an exception disposition value of continue execution or continue search is
    00079     returned.
    00080
    00081 --*/
    00082
    00083 {
    00084
    00085     ULONG ControlPc;
    00086     EXCEPTION_FILTER ExceptionFilter;
    00087     EXCEPTION_POINTERS ExceptionPointers;
    00088     PRUNTIME_FUNCTION FunctionEntry;
    00089     ULONG Index;
    00090     PSCOPE_TABLE ScopeTable;
    00091     ULONG TargetPc;
    00092     TERMINATION_HANDLER TerminationHandler;
    00093     LONG Value;
    00094
    00095     //
    00096     // Get address of where control left the establisher, the address of the
    00097     // function table entry that describes the function, and the address of
    00098     // the scope table.
    00099     //
    00100
    00101     ControlPc = DispatcherContext->ControlPc;
    00102     FunctionEntry = DispatcherContext->FunctionEntry;
    00103     ScopeTable = (PSCOPE_TABLE)(FunctionEntry->HandlerData);
    00104
    00105     //
    00106     // If an unwind is not in progress, then scan the scope table and call
    00107     // the appropriate exception filter routines. Otherwise, scan the scope
    00108     // table and call the appropriate termination handlers using the target
    00109     // PC obtained from the context record.
    00110     // are called.
    00111     //
    00112
    00113     if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags)) {
    00114
    00115         //
    00116         // Scan the scope table and call the appropriate exception filter
    00117         // routines.
    00118         //
    00119
    00120         ExceptionPointers.ExceptionRecord = ExceptionRecord;
    00121         ExceptionPointers.ContextRecord = ContextRecord;
    00122         for (Index = 0; Index < ScopeTable->Count; Index += 1) {
    00123             if ((ControlPc >= ScopeTable->ScopeRecord[Index].BeginAddress) &&
    00124                 (ControlPc < ScopeTable->ScopeRecord[Index].EndAddress) &&
    00125                 (ScopeTable->ScopeRecord[Index].JumpTarget != 0)) {
    00126
    00127                 //
    00128                 // Call the exception filter routine.
    00129                 //
    00130
    00131                 ExceptionFilter =
    00132                     (EXCEPTION_FILTER)ScopeTable->ScopeRecord[Index].HandlerAddress;
    00133                 Value = __C_ExecuteExceptionFilter(&ExceptionPointers,
    00134                                                    ExceptionFilter,
    00135                                                    (ULONG)EstablisherFrame);
    00136
    00137                 //
    00138                 // If the return value is less than zero, then dismiss the
    00139                 // exception. Otherwise, if the value is greater than zero,
    00140                 // then unwind to the target exception handler. Otherwise,
    00141                 // continue the search for an exception filter.
    00142                 //
    00143
    00144                 if (Value < 0) {
    00145                     return ExceptionContinueExecution;
    00146
    00147                 } else if (Value > 0) {
    00148                     RtlUnwind2(EstablisherFrame,
    00149                                (PVOID)ScopeTable->ScopeRecord[Index].JumpTarget,
    00150                                ExceptionRecord,
    00151                                (PVOID)ExceptionRecord->ExceptionCode,
    00152                                ContextRecord);
    00153                 }
    00154             }
    00155         }
    00156
    00157     } else {
    00158
    00159         //
    00160         // Scan the scope table and call the appropriate termination handler
    00161         // routines.
    00162         //
    00163
    00164         TargetPc = ContextRecord->Iar;
    00165         for (Index = 0; Index < ScopeTable->Count; Index += 1) {
    00166             if ((ControlPc >= ScopeTable->ScopeRecord[Index].BeginAddress) &&
    00167                 (ControlPc < ScopeTable->ScopeRecord[Index].EndAddress)) {
    00168
    00169                 //
    00170                 // If the target PC is within the same scope the control PC
    00171                 // is within, then this is an uplevel goto out of an inner try
    00172                 // scope or a long jump back into a try scope. Terminate the
    00173                 // scan termination handlers.
    00174                 //
    00175                 // N.B. The target PC can be just beyond the end of the scope,
    00176                 //      in which case it is a leave from the scope.
    00177                 //
    00178
    00179
    00180                 if ((TargetPc >= ScopeTable->ScopeRecord[Index].BeginAddress) &&
    00181                    (TargetPc <= ScopeTable->ScopeRecord[Index].EndAddress)) {
    00182                     break;
    00183
    00184                 } else {
    00185
    00186                     //
    00187                     // If the scope table entry describes an exception filter
    00188                     // and the associated exception handler is the target of
    00189                     // the unwind, then terminate the scan for termination
    00190                     // handlers. Otherwise, if the scope table entry describes
    00191                     // a termination handler, then record the address of the
    00192                     // end of the scope as the new control PC address and call
    00193                     // the termination handler.
    00194                     //
    00195
    00196                     if (ScopeTable->ScopeRecord[Index].JumpTarget != 0) {
    00197                         if (TargetPc == ScopeTable->ScopeRecord[Index].JumpTarget) {
    00198                             break;
    00199                         }
    00200
    00201                     } else {
    00202                         DispatcherContext->ControlPc =
    00203                                 ScopeTable->ScopeRecord[Index].EndAddress + 4;
    00204                         TerminationHandler =
    00205                             (TERMINATION_HANDLER)ScopeTable->ScopeRecord[Index].HandlerAddress;
    00206                         __C_ExecuteTerminationHandler(TRUE,
    00207                                                       TerminationHandler,
    00208                                                       (ULONG)EstablisherFrame);
    00209                     }
    00210                 }
    00211             }
    00212         }
    00213     }
    00214
    00215     //
    00216     // Continue search for exception or termination handlers.
    00217     //
    00218
    00219     return ExceptionContinueSearch;
    00220 }
    }