📄 exdsptch.c
字号:
* address space information and return.
*/
UpdateASID(pth, pProc, pcstk->akyLast ? pcstk->akyLast : pth->aky);
}
ControlPc = ContextRecord1.IntRa - INST_SIZE;
DEBUGMSG(ZONE_SEH, (TEXT("NKDispatchException: PSL ret=%8.8lx\r\n"),
ContextRecord1.IntRa));
pcstk = pcstk->pcstkNext;
}
} while (ContextRecord1.IntSp < HighLimit && ContextRecord1.IntSp > PrevSp);
// Set final exception flags and return exception not handled.
DEBUGMSG(1, (TEXT("NKDispatchException: returning failure. Flags=%x\r\n"),
ExceptionFlags));
UpdateASID(pth, pprcSave, akySave);
ExceptionRecord->ExceptionFlags = ExceptionFlags;
memcpy(OriginalContext, ContextRecord, sizeof(CONTEXT));
return FALSE;
}
#if defined(COMPRESSED_PDATA)
PRUNTIME_FUNCTION
NKLookupFunctionEntry(
IN PPROCESS pProc,
IN ULONG ControlPc,
OUT PRUNTIME_FUNCTION prf)
/*++
Routine Description:
This function searches the currently active function tables for an entry
that corresponds to the specified PC value.
Arguments:
pProc - process context for ControlPC
ControlPc - Supplies the address of an instruction within the specified
function.
prf - ptr to RUNTIME_FUNCTION structure to be filled in & returned.
Return Value:
If there is no entry in the function table for the specified PC, then
NULL is returned. Otherwise, the address of the function table entry
that corresponds to the specified PC is returned.
--*/
{
PPDATA table;
PPDATA entry;
PPDATA_EH peh;
ULONG SizeOfExceptionTable;
ULONG InstSize;
LONG High;
LONG Low;
LONG Middle;
__try {
// Search for the image that includes the specified PC value and locate
// its function table.
table = PDataFromPC(ControlPc, pProc, &SizeOfExceptionTable);
// If a function table is located, then search the function table
// for a function table entry for the specified PC.
if (table != NULL) {
// Initialize search indicies.
Low = 0;
High = (SizeOfExceptionTable / sizeof(PDATA)) - 1;
// Perform binary search on the function table for a function table
// entry that subsumes the specified PC.
while (High >= Low) {
// Compute next probe index and test entry. If the specified PC
// is greater than of equal to the beginning address and less
// than the ending address of the function table entry, then
// return the address of the function table entry. Otherwise,
// continue the search.
Middle = (Low + High) >> 1;
entry = &table[Middle];
if (ControlPc < entry->pFuncStart) {
High = Middle - 1;
} else if (Middle != High && ControlPc >= (entry+1)->pFuncStart) {
Low = Middle + 1;
} else {
// The ControlPc is between the middle entry and the middle+1 entry
// or this is the last entry that will be examined. Check ControlPc
// against the function length.
InstSize = entry->ThirtyTwoBits ? 4 : 2;
prf->BeginAddress = entry->pFuncStart;
prf->EndAddress = entry->pFuncStart + entry->FuncLen*InstSize;
prf->PrologEndAddress = entry->pFuncStart + entry->PrologLen*InstSize;
if (ControlPc >= prf->EndAddress)
break; // Not a match, stop searching
// Fill in the remaining fields in the RUNTIME_FUNCTION structure.
if (entry->ExceptionFlag) {
peh = (PPDATA_EH)(entry->pFuncStart & ~(InstSize-1))-1;
prf->ExceptionHandler = peh->pHandler;
prf->HandlerData = peh->pHandlerData;
} else {
prf->ExceptionHandler = 0;
prf->HandlerData = 0;
}
#if 0 // This feature is not supported by compressed pdata at this time
// The capability exists for more than one function entry
// to map to the same function. This permits a function to
// have discontiguous code segments described by separate
// function table entries. If the ending prologue address
// is not within the limits of the begining and ending
// address of the function able entry, then the prologue
// ending address is the address of a function table entry
// that accurately describes the ending prologue address.
if ((FunctionEntry->PrologEndAddress < FunctionEntry->BeginAddress) ||
(FunctionEntry->PrologEndAddress >= FunctionEntry->EndAddress)) {
FunctionEntry = (PRUNTIME_FUNCTION)FunctionEntry->PrologEndAddress;
}
#endif
return prf;
}
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
// A function table entry for the specified PC was not found.
return NULL;
}
#endif // COMPRESSED_PDATA
#if defined(OLD_PDATA)
PRUNTIME_FUNCTION
NKLookupFunctionEntry(
IN PPROCESS pProc,
IN ULONG ControlPc,
OUT PRUNTIME_FUNCTION prf)
/*++
Routine Description:
This function searches the currently active function tables for an entry
that corresponds to the specified PC value.
Arguments:
pProc - process context for ControlPC
ControlPc - Supplies the address of an instruction within the specified
function.
Return Value:
If there is no entry in the function table for the specified PC, then
NULL is returned. Otherwise, the address of the function table entry
that corresponds to the specified PC is returned.
--*/
{
PRUNTIME_FUNCTION FunctionEntry;
PRUNTIME_FUNCTION FunctionTable;
ULONG SizeOfExceptionTable;
LONG High;
LONG Low;
LONG Middle;
__try {
// Search for the image that includes the specified PC value and locate
// its function table.
FunctionTable = PDataFromPC(ControlPc, pProc, &SizeOfExceptionTable);
// If a function table is located, then search the function table
// for a function table entry for the specified PC.
if (FunctionTable != NULL) {
// Initialize search indicies.
Low = 0;
High = (SizeOfExceptionTable / sizeof(RUNTIME_FUNCTION)) - 1;
// Perform binary search on the function table for a function table
// entry that subsumes the specified PC.
while (High >= Low) {
// Compute next probe index and test entry. If the specified PC
// is greater than of equal to the beginning address and less
// than the ending address of the function table entry, then
// return the address of the function table entry. Otherwise,
// continue the search.
Middle = (Low + High) >> 1;
FunctionEntry = &FunctionTable[Middle];
if (ControlPc < FunctionEntry->BeginAddress) {
High = Middle - 1;
} else if (ControlPc >= FunctionEntry->EndAddress) {
Low = Middle + 1;
} else {
// The capability exists for more than one function entry
// to map to the same function. This permits a function to
// have discontiguous code segments described by separate
// function table entries. If the ending prologue address
// is not within the limits of the begining and ending
// address of the function able entry, then the prologue
// ending address is the address of a function table entry
// that accurately describes the ending prologue address.
if ((FunctionEntry->PrologEndAddress < FunctionEntry->BeginAddress) ||
(FunctionEntry->PrologEndAddress >= FunctionEntry->EndAddress)) {
FunctionEntry = (PRUNTIME_FUNCTION)FunctionEntry->PrologEndAddress;
}
return FunctionEntry;
}
}
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
// A function table entry for the specified PC was not found.
return NULL;
}
#endif // OLD_PDATA
#if defined(COMBINED_PDATA)
PRUNTIME_FUNCTION
NKLookupFunctionEntry(
IN PPROCESS pProc,
IN ULONG ControlPc,
OUT PRUNTIME_FUNCTION prf)
/*++
Routine Description:
This function searches the currently active function tables for an entry
that corresponds to the specified PC value.
Arguments:
pProc - process context for ControlPC
ControlPc - Supplies the address of an instruction within the specified
function.
Return Value:
If there is no entry in the function table for the specified PC, then
NULL is returned. Otherwise, the address of the function table entry
that corresponds to the specified PC is returned.
--*/
{
PCOMBINED_HEADER Header;
PRUNTIME_FUNCTION OldEntry;
PRUNTIME_FUNCTION OldTable;
PPDATA NewEntry;
PPDATA NewTable;
PPDATA_EH NewEH;
ULONG TotalSize;
ULONG EndAddress;
LONG NewHigh;
LONG OldHigh;
LONG Low;
LONG Middle;
UINT InstrShift;
__try {
// Search for the image that includes the specified PC value and locate
// its function table.
Header = PDataFromPC(ControlPc, pProc, &TotalSize);
// If the exception table doesn't exist or the size is invalid, just return
if (Header == NULL || TotalSize < sizeof (COMBINED_HEADER)) {
return NULL;
}
// If the PDATA is all old style then the header will actually be the
// first uncompressed entry and the zero fields will be non-zero
if (Header->zero1 || Header->zero2) {
OldTable = (PRUNTIME_FUNCTION)Header;
OldHigh = (TotalSize / sizeof(RUNTIME_FUNCTION)) - 1;
NewTable = NULL;
} else {
OldTable = (PRUNTIME_FUNCTION)(Header+1);
OldHigh = Header->Uncompressed - 1;
NewTable = (PPDATA)(&OldTable[Header->Uncompressed]);
NewHigh = Header->Compressed - 1;
}
// Initialize search indicies.
Low = 0;
// Perform binary search on the function table for a function table
// entry that subsumes the specified PC.
while (OldHigh >= Low) {
// Compute next probe index and test entry. If the specified PC
// is greater than of equal to the beginning address and less
// than the ending address of the function table entry, then
// return the address of the function table entry. Otherwise,
// continue the search.
Middle = (Low + OldHigh) >> 1;
OldEntry = &OldTable[Middle];
if (ControlPc < OldEntry->BeginAddress) {
OldHigh = Middle - 1;
} else if (ControlPc >= OldEntry->EndAddress) {
Low = Middle + 1;
} else {
// The capability exists for more than one function entry
// to map to the same function. This permits a function to
// have discontiguous code segments described by separate
// function table entries. If the ending prologue address
// is not within the limits of the begining and ending
// address of the function able entry, then the prologue
// ending address is the address of a function table entry
// that accurately describes the ending prologue address.
if ((OldEntry->PrologEndAddress < OldEntry->BeginAddress) ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -