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 } }


Generated on Sat May 15 19:43:03 2004 for test by doxygen 1.3.7