Implement RtlLookupFunctionTable, RtlLookupFunctionEntry and a usermode/kernelmode version of RtlpLookupModuleBase helper function.

svn path=/branches/ros-amd64-bringup/; revision=37308
This commit is contained in:
Timo Kreuzer 2008-11-12 15:24:40 +00:00
parent 3005f566a0
commit f3668beb0c
7 changed files with 248 additions and 20 deletions

View file

@ -14,6 +14,8 @@
#include <debug.h>
SIZE_T RtlpAllocDeallocQueryBufferSize = PAGE_SIZE;
#define IMAGE_DOS_MAGIC 0x5a4d
#define IMAGE_PE_MAGIC 0x00004550
/* FUNCTIONS ***************************************************************/
@ -358,6 +360,62 @@ RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index)
return NULL;
}
PVOID
NTAPI
RtlpLookupModuleBase(
PVOID Address)
{
NTSTATUS Status;
MEMORY_BASIC_INFORMATION MemoryInformation;
ULONG_PTR Base, Limit;
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NtHeader;
Status = NtQueryVirtualMemory(NtCurrentProcess(),
Address,
MemoryBasicInformation,
&MemoryInformation,
sizeof(MEMORY_BASIC_INFORMATION),
NULL);
if (!NT_SUCCESS(Status))
{
return NULL;
}
/* FIXME: remove these checks? */
Base = (ULONG_PTR)MemoryInformation.BaseAddress;
Limit = Base + MemoryInformation.RegionSize;
if ( ((ULONG_PTR)Address < Base) ||
((ULONG_PTR)Address >= Limit) )
{
/* WTF? */
return NULL;
}
/* Check if we got the right kind of memory */
if ( (MemoryInformation.State != MEM_COMMIT) ||
(MemoryInformation.Type != MEM_IMAGE) )
{
return NULL;
}
/* Check DOS magic */
DosHeader = MemoryInformation.AllocationBase;
if (DosHeader->e_magic != IMAGE_DOS_MAGIC)
{
return NULL;
}
/* Check NT header */
NtHeader = (PVOID)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
if (NtHeader->Signature != IMAGE_PE_MAGIC)
{
return NULL;
}
return MemoryInformation.AllocationBase;
}
/*
* Ldr Resource support code

View file

@ -14,19 +14,6 @@
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @unimplemented
*/
PVOID
NTAPI
RtlLookupFunctionEntry(IN ULONGLONG ControlPC,
OUT PULONGLONG ImageBase,
OUT PULONGLONG TargetGp)
{
UNIMPLEMENTED;
return NULL;
}
/*
* @unimplemented
*/

View file

@ -0,0 +1,153 @@
/* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Exception related functions
* PROGRAMMER: Timo Kreuzer
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG
#include <debug.h>
#define UNWIND_HISTORY_TABLE_NONE 0
#define UNWIND_HISTORY_TABLE_GLOBAL 1
#define UNWIND_HISTORY_TABLE_LOCAL 2
PVOID
NTAPI
RtlpLookupModuleBase(
PVOID Address);
/* FUNCTIONS *****************************************************************/
PRUNTIME_FUNCTION
NTAPI
RtlLookupFunctionTable(
IN DWORD64 ControlPc,
OUT PDWORD64 ImageBase,
OUT PULONG Length)
{
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_DATA_DIRECTORY Directory;
/* Find ModuleBase */
DosHeader = RtlpLookupModuleBase((PVOID)ControlPc);
if (!DosHeader)
{
return NULL;
}
/* Locate NT header and check number of directories */
NtHeader = (PVOID)((ULONG64)DosHeader + DosHeader->e_lfanew);
if (NtHeader->OptionalHeader.NumberOfRvaAndSizes
< IMAGE_DIRECTORY_ENTRY_EXCEPTION)
{
return NULL;
}
/* Locate the exception directory */
Directory = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
*Length = Directory->Size / sizeof(RUNTIME_FUNCTION);
*ImageBase = (ULONG64)DosHeader;
if (!Directory->VirtualAddress)
{
return NULL;
}
return (PVOID)((ULONG64)DosHeader + Directory->VirtualAddress);
}
// http://msdn.microsoft.com/en-us/library/ms680597(VS.85).aspx
PRUNTIME_FUNCTION
NTAPI
RtlLookupFunctionEntry(
IN DWORD64 ControlPc,
OUT PDWORD64 ImageBase,
OUT PUNWIND_HISTORY_TABLE HistoryTable)
{
PRUNTIME_FUNCTION FunctionTable, FunctionEntry;
ULONG TableLength;
ULONG IndexLo, IndexHi, IndexMid;
/* Find the corresponding table */
FunctionTable = RtlLookupFunctionTable(ControlPc,
ImageBase,
&TableLength);
/* Fail, if no table is found */
if (!FunctionTable)
{
return (PVOID)1;
}
/* Use relative virtual address */
ControlPc -= *ImageBase;
/* Do a binary search */
IndexLo = 0;
IndexHi = TableLength;
while (IndexHi > IndexLo)
{
IndexMid = (IndexLo + IndexHi) / 2;
FunctionEntry = &FunctionTable[IndexMid];
if ( (ControlPc >= FunctionEntry->BeginAddress) &&
(ControlPc < FunctionEntry->EndAddress) )
{
/* ControlPc is within limits, return entry */
return FunctionEntry;
}
if (ControlPc < FunctionEntry->BeginAddress)
{
/* Continue search in lower half */
IndexHi = IndexMid;
}
else
{
/* Continue search in upper half */
IndexLo = IndexMid + 1;
}
}
/* Nothing found, return NULL */
return NULL;
}
PEXCEPTION_ROUTINE
NTAPI
RtlVirtualUnwind(
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
IN PRUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
{
UNIMPLEMENTED;
return 0;
}
VOID
NTAPI
RtlUnwindEx(
IN ULONG64 TargetFrame,
IN ULONG64 TargetIp,
IN PEXCEPTION_RECORD ExceptionRecord,
IN PVOID ReturnValue,
OUT PCONTEXT OriginalContext,
IN PUNWIND_HISTORY_TABLE HistoryTable)
{
UNIMPLEMENTED;
return;
}

View file

@ -39,6 +39,7 @@
<if property="ARCH" value="amd64">
<directory name="amd64">
<file>debug_asm.S</file>
<file>unwind.c</file>
<file>stubs.c</file>
</directory>
<file>mem.c</file>

View file

@ -68,14 +68,10 @@ STUB(KiSystemService)
STUB(KdpGdbStubInit)
STUB(KdbpSafeReadMemory)
STUB(RtlFillMemoryUlong)
STUB(RtlCaptureContext)
STUB(RtlpGetExceptionAddress)
STUB(RtlDispatchException)
STUB(DbgkDebugObjectType)
STUB(KdbEnterDebuggerException)
STUB(KdbpCliModuleLoaded)
STUB(RtlUnwind)
STUB(RtlInitializeContext)
STUB(DbgCommandString)
STUB(ExAcquireRundownProtection)
STUB(ExAcquireRundownProtectionCacheAware)
@ -180,7 +176,6 @@ STUB(RtlCompareMemoryUlong)
STUB(RtlCopyMemory)
STUB(RtlCopyMemoryNonTemporal)
STUB(RtlFillMemory)
STUB(RtlLookupFunctionEntry)
STUB(RtlMoveMemory)
STUB(RtlOemStringToUnicodeSize)
STUB(RtlPcToFileHeader)
@ -196,8 +191,6 @@ STUB(RtlTraceDatabaseUnlock)
STUB(RtlTraceDatabaseValidate)
STUB(RtlUnicodeStringToAnsiSize)
STUB(RtlUnicodeStringToOemSize)
STUB(RtlUnwindEx)
STUB(RtlVirtualUnwind)
STUB(RtlZeroMemory)
STUB(SeReportSecurityEvent)
STUB(SeSetAuditParameter)

View file

@ -1047,6 +1047,18 @@ KiIdleLoop(
VOID
);
PVOID
NTAPI
KiPcToFileHeader(IN PVOID Eip,
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry,
IN BOOLEAN DriversOnly,
OUT PBOOLEAN InKernel);
PVOID
NTAPI
KiRosPcToUserFileHeader(IN PVOID Eip,
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry);
#include "ke_x.h"
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */

View file

@ -28,6 +28,30 @@ SIZE_T RtlpAllocDeallocQueryBufferSize = 128;
/* FUNCTIONS *****************************************************************/
PVOID
NTAPI
RtlpLookupModuleBase(
PVOID Address)
{
PLDR_DATA_TABLE_ENTRY LdrEntry;
BOOLEAN InSystem;
PVOID p;
/* Get the base for this file */
if ((ULONG_PTR)Address > (ULONG_PTR)MmHighestUserAddress)
{
/* We are in kernel */
p = KiPcToFileHeader(Address, &LdrEntry, FALSE, &InSystem);
}
else
{
/* We are in user land */
p = KiRosPcToUserFileHeader(Address, &LdrEntry);
}
return p;
}
VOID
NTAPI
RtlInitializeRangeListPackage(VOID)