[ros-diffs] [tkreuzer] 37308: Implement RtlLookupFunctionTable, RtlLookupFunctionEntry and a usermode/kernelmode version of RtlpLookupModuleBase helper function.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Nov 12 16:24:41 CET 2008


Author: tkreuzer
Date: Wed Nov 12 09:24:40 2008
New Revision: 37308

URL: http://svn.reactos.org/svn/reactos?rev=37308&view=rev
Log:
Implement RtlLookupFunctionTable, RtlLookupFunctionEntry and a usermode/kernelmode version of RtlpLookupModuleBase helper function.

Added:
    branches/ros-amd64-bringup/reactos/lib/rtl/amd64/unwind.c   (with props)
Modified:
    branches/ros-amd64-bringup/reactos/dll/ntdll/rtl/libsupp.c
    branches/ros-amd64-bringup/reactos/lib/rtl/amd64/stubs.c
    branches/ros-amd64-bringup/reactos/lib/rtl/rtl.rbuild
    branches/ros-amd64-bringup/reactos/ntoskrnl/amd64stubs.c
    branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/ke.h
    branches/ros-amd64-bringup/reactos/ntoskrnl/rtl/libsupp.c

Modified: branches/ros-amd64-bringup/reactos/dll/ntdll/rtl/libsupp.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/dll/ntdll/rtl/libsupp.c?rev=37308&r1=37307&r2=37308&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/dll/ntdll/rtl/libsupp.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/dll/ntdll/rtl/libsupp.c [iso-8859-1] Wed Nov 12 09:24:40 2008
@@ -14,6 +14,8 @@
 #include <debug.h>
 
 SIZE_T RtlpAllocDeallocQueryBufferSize = PAGE_SIZE;
+#define IMAGE_DOS_MAGIC 0x5a4d
+#define IMAGE_PE_MAGIC 0x00004550
 
 /* FUNCTIONS ***************************************************************/
 
@@ -356,6 +358,62 @@
    }
 
    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;
 }
 
 

Modified: branches/ros-amd64-bringup/reactos/lib/rtl/amd64/stubs.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/lib/rtl/amd64/stubs.c?rev=37308&r1=37307&r2=37308&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/lib/rtl/amd64/stubs.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/lib/rtl/amd64/stubs.c [iso-8859-1] Wed Nov 12 09:24:40 2008
@@ -13,19 +13,6 @@
 #include <debug.h>
 
 /* PUBLIC FUNCTIONS **********************************************************/
-
-/*
- * @unimplemented
- */
-PVOID
-NTAPI
-RtlLookupFunctionEntry(IN ULONGLONG ControlPC,
-                       OUT PULONGLONG ImageBase,
-                       OUT PULONGLONG TargetGp)
-{
-    UNIMPLEMENTED;
-    return NULL;
-}
 
 /*
  * @unimplemented

Added: branches/ros-amd64-bringup/reactos/lib/rtl/amd64/unwind.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/lib/rtl/amd64/unwind.c?rev=37308&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/lib/rtl/amd64/unwind.c (added)
+++ branches/ros-amd64-bringup/reactos/lib/rtl/amd64/unwind.c [iso-8859-1] Wed Nov 12 09:24:40 2008
@@ -1,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;
+}
+
+

Propchange: branches/ros-amd64-bringup/reactos/lib/rtl/amd64/unwind.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: branches/ros-amd64-bringup/reactos/lib/rtl/amd64/unwind.c
------------------------------------------------------------------------------
    svn:mergeinfo = 

Modified: branches/ros-amd64-bringup/reactos/lib/rtl/rtl.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/lib/rtl/rtl.rbuild?rev=37308&r1=37307&r2=37308&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/lib/rtl/rtl.rbuild [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/lib/rtl/rtl.rbuild [iso-8859-1] Wed Nov 12 09:24:40 2008
@@ -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>

Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/amd64stubs.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskrnl/amd64stubs.c?rev=37308&r1=37307&r2=37308&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/ntoskrnl/amd64stubs.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/ntoskrnl/amd64stubs.c [iso-8859-1] Wed Nov 12 09:24:40 2008
@@ -68,14 +68,10 @@
 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(RtlCopyMemory)
 STUB(RtlCopyMemoryNonTemporal)
 STUB(RtlFillMemory)
-STUB(RtlLookupFunctionEntry)
 STUB(RtlMoveMemory)
 STUB(RtlOemStringToUnicodeSize)
 STUB(RtlPcToFileHeader)
@@ -196,8 +191,6 @@
 STUB(RtlTraceDatabaseValidate)
 STUB(RtlUnicodeStringToAnsiSize)
 STUB(RtlUnicodeStringToOemSize)
-STUB(RtlUnwindEx)
-STUB(RtlVirtualUnwind)
 STUB(RtlZeroMemory)
 STUB(SeReportSecurityEvent)
 STUB(SeSetAuditParameter)

Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/ke.h
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/ke.h?rev=37308&r1=37307&r2=37308&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Wed Nov 12 09:24:40 2008
@@ -1047,6 +1047,18 @@
     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 */

Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/rtl/libsupp.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskrnl/rtl/libsupp.c?rev=37308&r1=37307&r2=37308&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/ntoskrnl/rtl/libsupp.c [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/ntoskrnl/rtl/libsupp.c [iso-8859-1] Wed Nov 12 09:24:40 2008
@@ -27,6 +27,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



More information about the Ros-diffs mailing list