|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
vad.c
Abstract:
WinDbg Extension Api
Author:
Lou Perazzoli (loup) 12-Jun-1992
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
CHAR *ProtectString[] = { "NO_ACCESS", "READONLY", "EXECUTE", "EXECUTE_READ", "READWRITE", "WRITECOPY", "EXECUTE_READWRITE", "EXECUTE_WRITECOPY" };
DECLARE_API( vad )
/*++
Routine Description:
Dumps all vads for process.
Arguments:
args - Address Flags
Return Value:
None
--*/
{ ULONG64 Next; ULONG64 VadToDump; ULONG64 ParentStored; ULONG64 First; ULONG64 Left; ULONG64 Prev; ULONG Flags; ULONG Done; ULONG Level = 0; ULONG Count = 0; ULONG AverageLevel = 0; ULONG MaxLevel = 0; ULONG VadFlagsPrivateMemory=0, VadFlagsNoChange=0; ULONG PhysicalMapping=0,ImageMap=0,NoChange=0,LargePages=0,MemCommit=0,PrivateMemory=0,Protection=0; ULONG64 StartingVpn=0, EndingVpn=0, Parent=0, LeftChild=0, RightChild=0; ULONG64 ControlArea=0, FirstPrototypePte=0, LastContiguousPte=0, CommitCharge=0;
VadToDump = 0; Flags = 0;
if (GetExpressionEx(args, &VadToDump, &args)) { Flags = (ULONG) GetExpression(args); }
if (VadToDump == 0) { dprintf("Specify the address of a VAD within the VAD tree\n"); return E_INVALIDARG; }
First = VadToDump; if (First == 0) { return E_INVALIDARG; }
#define ReadFirstVad(fld, var) GetFieldValue(First, (PUCHAR) "nt!_MMVAD", #fld, var)
#define ReadFirstVadShort(fld, var) GetFieldValue(First, (PUCHAR) "nt!_MMVAD_SHORT", #fld, var)
if ( ReadFirstVadShort(u.VadFlags.PrivateMemory, VadFlagsPrivateMemory) ) { dprintf("%08p: Unable to get contents of VAD1\n",First ); return E_INVALIDARG; }
ReadFirstVadShort(u.VadFlags.NoChange, VadFlagsNoChange); ReadFirstVadShort(StartingVpn, StartingVpn); ReadFirstVadShort(EndingVpn, EndingVpn);
if (ReadFirstVadShort(Parent, Parent)) { ReadFirstVadShort(u1.Parent, Parent); }
ReadFirstVadShort(LeftChild, LeftChild); ReadFirstVadShort(RightChild, RightChild); ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge);
if (Flags == 1) { ULONG FileOffset=0; ULONG64 ListFlink=0, ListBlink=0, Banked=0; ULONG CopyOnWrite=0,Inherit=0,ExtendableFile=0,SecNoChange=0; ULONG OneSecured=0,MultipleSecured=0,ReadOnly=0,StoredInVad=0;
//
// Dump only this vad.
//
if ((VadFlagsPrivateMemory == 0) || (VadFlagsNoChange == 1)) { if ( ReadFirstVad(ControlArea, ControlArea) ) { dprintf("%08p: Unable to get contents of VAD2\n",First ); return E_INVALIDARG; } ReadFirstVad(FirstPrototypePte, FirstPrototypePte); ReadFirstVad(LastContiguousPte, LastContiguousPte); ReadFirstVad(u2.VadFlags2.CopyOnWrite, CopyOnWrite); ReadFirstVad(u2.VadFlags2.Inherit, Inherit); ReadFirstVad(u2.VadFlags2.ExtendableFile, ExtendableFile); ReadFirstVad(u2.VadFlags2.SecNoChange, SecNoChange); ReadFirstVad(u2.VadFlags2.OneSecured, OneSecured); ReadFirstVad(u2.VadFlags2.MultipleSecured, MultipleSecured); ReadFirstVad(u2.VadFlags2.ReadOnly, ReadOnly); ReadFirstVad(u2.VadFlags2.StoredInVad, StoredInVad); ReadFirstVad(u2.VadFlags2.FileOffset, FileOffset); ReadFirstVad(u3.List.Flink, ListFlink); ReadFirstVad(u3.List.Blink, ListBlink); ReadFirstVad(u4.Banked, Banked); } ReadFirstVad(u.VadFlags.CommitCharge, CommitCharge); ReadFirstVad(u.VadFlags.PhysicalMapping, PhysicalMapping); ReadFirstVad(u.VadFlags.ImageMap, ImageMap); ReadFirstVad(u.VadFlags.Protection, Protection); ReadFirstVad(u.VadFlags.NoChange, NoChange); ReadFirstVad(u.VadFlags.LargePages, LargePages); ReadFirstVad(u.VadFlags.MemCommit, MemCommit); ReadFirstVad(u.VadFlags.PrivateMemory, PrivateMemory);
dprintf("\nVAD @ %8p\n",VadToDump); dprintf(" Start VPN: %8p End VPN: %8p Control Area: %8p\n", StartingVpn, EndingVpn, ControlArea); dprintf(" First ProtoPte: %8p Last PTE %8p Commit Charge %8lx (%ld.)\n", FirstPrototypePte, LastContiguousPte, (ULONG)CommitCharge, (ULONG)CommitCharge ); dprintf(" Secured.Flink %8p Blink %8p Banked/Extend: %8p Offset %lx\n", ListFlink, ListBlink, Banked, FileOffset);
dprintf(" ");
if (PhysicalMapping) { dprintf("PhysicalMapping "); } if (ImageMap) { dprintf("ImageMap "); } Inherit ? dprintf("ViewShare ") : dprintf("ViewUnmap "); if (NoChange) { dprintf("NoChange "); } if (CopyOnWrite) { dprintf("CopyOnWrite "); } if (LargePages) { dprintf("LargePages "); } if (MemCommit) { dprintf("MemCommit "); } if (PrivateMemory) { dprintf("PrivateMemory "); } dprintf ("%s\n\n",ProtectString[Protection & 7]);
if (ExtendableFile) { dprintf("ExtendableFile "); } if (SecNoChange) { dprintf("SecNoChange "); } if (OneSecured) { dprintf("OneSecured "); } if (MultipleSecured) { dprintf("MultipleSecured "); } if (ReadOnly) { dprintf("ReadOnly "); } if (StoredInVad) { dprintf("StoredInVad "); } dprintf ("\n\n");
return E_INVALIDARG; }
Prev = First;
while (LeftChild != 0) { if ( CheckControlC() ) { return E_INVALIDARG; } Prev = First; First = LeftChild; Level += 1; if (Level > MaxLevel) { MaxLevel = Level; }
if (Flags & 2) { dprintf("Reading LeftChild VAD %08p\n",First ); }
if ( ReadFirstVadShort(LeftChild, LeftChild) ) { dprintf("%08p %08p: Unable to get contents of VAD3\n", First, Prev); return E_INVALIDARG; } }
ReadFirstVadShort(StartingVpn, StartingVpn); ReadFirstVadShort(EndingVpn, EndingVpn);
if (ReadFirstVadShort(Parent, Parent)) { ReadFirstVadShort(u1.Parent, Parent); Parent &= ~0x3; }
ReadFirstVadShort(RightChild, RightChild); ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge); ReadFirstVadShort(u.VadFlags.PrivateMemory, PrivateMemory); ReadFirstVadShort(u.VadFlags.PhysicalMapping, PhysicalMapping); ReadFirstVadShort(u.VadFlags.ImageMap, ImageMap); ReadFirstVadShort(u.VadFlags.Protection, Protection);
dprintf("VAD level start end commit\n"); dprintf("%p (%2ld) %8p %8p %4ld %s %s %s\n", First, Level, StartingVpn, EndingVpn, (ULONG)CommitCharge, PrivateMemory ? "Private" : "Mapped ", ImageMap ? "Exe " : PhysicalMapping ? "Phys" : " ", ProtectString[Protection & 7] ); Count += 1; AverageLevel += Level;
Next = First; while (Next != 0) {
if ( CheckControlC() ) { return E_INVALIDARG; }
if (RightChild == 0) {
Done = TRUE;
//
// Pre-AVL vad trees were delimited by a parent pointer of NULL.
//
while ((ParentStored = Parent) != 0) {
if ( CheckControlC() ) { return E_INVALIDARG; }
Level -= 1;
//
// Locate the first ancestor of this node of which this
// node is the left child of and return that node as the
// next element.
//
First = ParentStored & ~0x3; if ( ReadFirstVadShort( LeftChild, LeftChild) || (ReadFirstVadShort(Parent, Parent) && ReadFirstVadShort(u1.Parent, Parent)) ) { dprintf("%08p %08p: Unable to get contents of VAD4\n",Parent, Prev); return E_INVALIDARG; } Parent &= ~0x3;
//
// AVL vad trees are delimited by a parent pointer that equals
// the current vad so check for that explicitly here so that
// this same extension can work on both types of kernels.
//
if (Parent == First) { break; }
Prev = First; ReadFirstVadShort(StartingVpn, StartingVpn); ReadFirstVadShort(EndingVpn, EndingVpn); ReadFirstVadShort(RightChild, RightChild); ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge); ReadFirstVadShort(u.VadFlags.PrivateMemory, PrivateMemory); ReadFirstVadShort(u.VadFlags.PhysicalMapping, PhysicalMapping); ReadFirstVadShort(u.VadFlags.ImageMap, ImageMap); ReadFirstVadShort(u.VadFlags.Protection, Protection);
if (LeftChild == Next) { Next = ParentStored; dprintf("%p (%2ld) %8p %8p %4ld %s %s %s\n", Next, Level, StartingVpn, EndingVpn, (ULONG)CommitCharge, PrivateMemory ? "Private" : "Mapped ", ImageMap ? "Exe " : PhysicalMapping ? "Phys" : " ", ProtectString[Protection & 7] ); Done = FALSE; Count += 1; AverageLevel += Level; break; } Next = ParentStored; } if (Done) { Next = 0; break; } } else {
//
// A right child exists, locate the left most child of that right child.
//
Next = RightChild; Level += 1; if (Level > MaxLevel) { MaxLevel = Level; }
First = Next;
if ( ReadFirstVadShort(LeftChild, LeftChild) ) { dprintf("%08p %08p: Unable to get contents of VAD5\n",Next, Prev); return E_INVALIDARG; }
while ((Left = LeftChild) != 0) { if ( CheckControlC() ) { return E_INVALIDARG; } Level += 1; if (Level > MaxLevel) { MaxLevel = Level; } Next = Left; First = Next; if ( ReadFirstVadShort(LeftChild, LeftChild) ) { dprintf("%08p %08p: Unable to get contents of VAD6\n",Next, Prev); return E_INVALIDARG; } Prev = First; }
ReadFirstVadShort(StartingVpn, StartingVpn); ReadFirstVadShort(EndingVpn, EndingVpn); if (ReadFirstVadShort(Parent, Parent)) { ReadFirstVadShort(u1.Parent, Parent); Parent &= ~0x3; } ReadFirstVadShort(RightChild, RightChild); ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge); ReadFirstVadShort(u.VadFlags.PrivateMemory, PrivateMemory); ReadFirstVadShort(u.VadFlags.PhysicalMapping, PhysicalMapping); ReadFirstVadShort(u.VadFlags.ImageMap, ImageMap); ReadFirstVadShort(u.VadFlags.Protection, Protection);
dprintf("%p (%2ld) %8p %8p %4ld %s %s %s\n", Next, Level, StartingVpn, EndingVpn, (ULONG)CommitCharge, PrivateMemory ? "Private" : "Mapped ", ImageMap ? "Exe " : PhysicalMapping ? "Phys" : " ", ProtectString[Protection & 7] ); Count += 1; AverageLevel += Level; } } dprintf("\nTotal VADs: %5ld average level: %4ld maximum depth: %ld\n", Count, 1+(AverageLevel/Count),MaxLevel);
#undef ReadFirstVad
return S_OK; }
|