summaryrefslogtreecommitdiffstats
path: root/private/ntos/rtl/heappagi.h
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/rtl/heappagi.h
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/rtl/heappagi.h')
-rw-r--r--private/ntos/rtl/heappagi.h225
1 files changed, 225 insertions, 0 deletions
diff --git a/private/ntos/rtl/heappagi.h b/private/ntos/rtl/heappagi.h
new file mode 100644
index 000000000..f00b255ee
--- /dev/null
+++ b/private/ntos/rtl/heappagi.h
@@ -0,0 +1,225 @@
+
+//
+// heappagi.h
+//
+// The following definitions are internal to the debug heap manager,
+// but are placed in this include file so that debugger extensions
+// can reference the same structure definitions. The following
+// definitions are not intended to be referenced externally except
+// by debugger extensions.
+//
+
+#ifndef _HEAP_PAGE_I_
+#define _HEAP_PAGE_I_
+
+#ifdef DEBUG_PAGE_HEAP
+
+#include "heap.h"
+
+#define DPH_INTERNAL_DEBUG 0 // change to 0 or #undef for production code
+
+#define DPH_MAX_STACK_LENGTH 20
+
+#if defined(_X86_) // RtlCaptureStackBackTrace() only implemented on x86
+ #if DBG // RtlCaptureStackBackTrace() only consistent with no FPO
+ #define DPH_CAPTURE_STACK_TRACE 1
+ #endif // DBG
+#endif // _X86_
+
+
+#if DPH_CAPTURE_STACK_TRACE
+
+typedef struct _DPH_STACK_TRACE_NODE DPH_STACK_TRACE_NODE, *PDPH_STACK_TRACE_NODE;
+
+struct _DPH_STACK_TRACE_NODE {
+
+ PDPH_STACK_TRACE_NODE Left; // B-tree on Hash
+ PDPH_STACK_TRACE_NODE Right; // B-tree on Hash
+
+ ULONG Hash; // simple sum of PVOIDs in stack trace
+ ULONG Length; // number of PVOIDs in stack trace
+
+ ULONG BusyCount; // number of busy allocations
+ ULONG BusyBytes; // total user size of busy allocations
+
+ PVOID Address[ 0 ]; // variable length array of addresses
+ };
+
+#endif // DPH_CAPTURE_STACK_TRACE
+
+
+typedef struct _DPH_HEAP_ALLOCATION DPH_HEAP_ALLOCATION, *PDPH_HEAP_ALLOCATION;
+
+struct _DPH_HEAP_ALLOCATION {
+
+ //
+ // Singly linked list of allocations (pNextAlloc must be
+ // first member in structure).
+ //
+
+ PDPH_HEAP_ALLOCATION pNextAlloc;
+
+ //
+ // | PAGE_READWRITE | PAGE_NOACCESS |
+ // |____________________|___||_________________________|
+ //
+ // ^pVirtualBlock ^pUserAllocation
+ //
+ // |---------------- nVirtualBlockSize ----------------|
+ //
+ // |---nVirtualAccessSize----|
+ //
+ // |---| nUserRequestedSize
+ //
+ // |----| nUserActualSize
+ //
+
+ PUCHAR pVirtualBlock;
+ ULONG nVirtualBlockSize;
+
+ ULONG nVirtualAccessSize;
+ PUCHAR pUserAllocation;
+ ULONG nUserRequestedSize;
+ ULONG nUserActualSize;
+ PVOID UserValue;
+ ULONG UserFlags;
+
+#if DPH_CAPTURE_STACK_TRACE
+
+ PDPH_STACK_TRACE_NODE pStackTrace;
+
+#endif
+
+ };
+
+
+typedef struct _DPH_HEAP_ROOT DPH_HEAP_ROOT, *PDPH_HEAP_ROOT;
+
+struct _DPH_HEAP_ROOT {
+
+ //
+ // Maintain a signature (DPH_HEAP_ROOT_SIGNATURE) as the
+ // first value in the heap root structure.
+ //
+
+ ULONG Signature;
+ ULONG HeapFlags;
+
+ //
+ // Access to this heap is synchronized with a critical section.
+ //
+
+ PRTL_CRITICAL_SECTION HeapCritSect;
+ ULONG nRemoteLockAcquired;
+
+ //
+ // The "VirtualStorage" list only uses the pVirtualBlock,
+ // nVirtualBlockSize, and nVirtualAccessSize fields of the
+ // HEAP_ALLOCATION structure. This is the list of virtual
+ // allocation entries that all the heap allocations are
+ // taken from.
+ //
+
+ PDPH_HEAP_ALLOCATION pVirtualStorageListHead;
+ PDPH_HEAP_ALLOCATION pVirtualStorageListTail;
+ ULONG nVirtualStorageRanges;
+ ULONG nVirtualStorageBytes;
+
+ //
+ // The "Busy" list is the list of active heap allocations.
+ // It is stored in LIFO order to improve temporal locality
+ // for linear searches since most initial heap allocations
+ // tend to remain permanent throughout a process's lifetime.
+ //
+
+ PDPH_HEAP_ALLOCATION pBusyAllocationListHead;
+ PDPH_HEAP_ALLOCATION pBusyAllocationListTail;
+ ULONG nBusyAllocations;
+ ULONG nBusyAllocationBytesCommitted;
+
+ //
+ // The "Free" list is the list of freed heap allocations, stored
+ // in FIFO order to increase the length of time a freed block
+ // remains on the freed list without being used to satisfy an
+ // allocation request. This increases the odds of catching
+ // a reference-after-freed bug in an app.
+ //
+
+ PDPH_HEAP_ALLOCATION pFreeAllocationListHead;
+ PDPH_HEAP_ALLOCATION pFreeAllocationListTail;
+ ULONG nFreeAllocations;
+ ULONG nFreeAllocationBytesCommitted;
+
+ //
+ // The "Available" list is stored in address-sorted order to facilitate
+ // coalescing. When an allocation request cannot be satisfied from the
+ // "Available" list, it is attempted from the free list. If it cannot
+ // be satisfied from the free list, the free list is coalesced into the
+ // available list. If the request still cannot be satisfied from the
+ // coalesced available list, new VM is added to the available list.
+ //
+
+ PDPH_HEAP_ALLOCATION pAvailableAllocationListHead;
+ PDPH_HEAP_ALLOCATION pAvailableAllocationListTail;
+ ULONG nAvailableAllocations;
+ ULONG nAvailableAllocationBytesCommitted;
+
+ //
+ // The "UnusedNode" list is simply a list of available node
+ // entries to place "Busy", "Free", or "Virtual" entries.
+ // When freed nodes get coalesced into a single free node,
+ // the other "unused" node goes on this list. When a new
+ // node is needed (like an allocation not satisfied from the
+ // free list), the node comes from this list if it's not empty.
+ //
+
+ PDPH_HEAP_ALLOCATION pUnusedNodeListHead;
+ PDPH_HEAP_ALLOCATION pUnusedNodeListTail;
+ ULONG nUnusedNodes;
+
+ ULONG nBusyAllocationBytesAccessible;
+
+ //
+ // Node pools need to be tracked so they can be protected
+ // from app scribbling on them.
+ //
+
+ PDPH_HEAP_ALLOCATION pNodePoolListHead;
+ PDPH_HEAP_ALLOCATION pNodePoolListTail;
+ ULONG nNodePools;
+ ULONG nNodePoolBytes;
+
+ //
+ // Doubly linked list of DPH heaps in process is tracked through this.
+ //
+
+ PDPH_HEAP_ROOT pNextHeapRoot;
+ PDPH_HEAP_ROOT pPrevHeapRoot;
+
+ ULONG nUnProtectionReferenceCount;
+ ULONG InsideAllocateNode; // only for debugging
+
+#if DPH_CAPTURE_STACK_TRACE
+
+ PUCHAR pStackTraceStorage;
+ ULONG nStackTraceStorage;
+
+ PDPH_STACK_TRACE_NODE pStackTraceRoot; // B-tree root
+ PDPH_STACK_TRACE_NODE pStackTraceCreator;
+
+ ULONG nStackTraceBytesCommitted;
+ ULONG nStackTraceBytesWasted;
+
+ ULONG nStackTraceBNodes;
+ ULONG nStackTraceBDepth;
+ ULONG nStackTraceBHashCollisions;
+
+#endif // DPH_CAPTURE_STACK_TRACE
+
+ };
+
+
+#endif // DEBUG_PAGE_HEAP
+
+#endif // _HEAP_PAGE_I_
+