- Add 'simple' implementation of MmDbgCopyMemory to read/write virtual memory in a somewhat safe way (still no support for physical memory). Properly implement KdpCopyMemoryChunks as a wrapper around MmDbgCopyMemory and make most of the remaining unsafe copies use it instead of RtlCopyMemory. This fixes most of the remaining crashes during KD debugging as WinDbg/KD relies on the kernel support to handle bad addresses.

- Stub out the remaining missing global variables for the debugger data block -- fixes some cases of WinDbg failures and gives it a chance to handle errors instead of failing on a NULL read. Several of these variables are for functionality we don't yet implement, so I tried to put them where they are "least wrong". Everything besides the MmLoadedUserImageList variable is left unitialized -- KD should mostly be able to handle this properly.
- Define correctly sized KDDEBUGGER_DATA64 for our kernel (needs to be done in a better way).

svn path=/trunk/; revision=43863
This commit is contained in:
Stefan Ginsberg 2009-10-31 01:02:35 +00:00
parent c4d8068980
commit 82bd7858d1
21 changed files with 417 additions and 121 deletions

View file

@ -285,7 +285,11 @@ typedef struct _KDDEBUGGER_DATA64
USHORT Gdt64R3CmTeb;
GCC_ULONG64 IopNumTriageDumpDataBlocks;
GCC_ULONG64 IopTriageDumpDataBlocks;
#if 0 // Longhorn/Vista and later
GCC_ULONG64 VfCrashDataBlock;
GCC_ULONG64 MmBadPagesDetected;
GCC_ULONG64 MmZeroedPageSingleBitErrorsDetected;
#endif
} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
#endif

View file

@ -1057,6 +1057,8 @@ extern GENERIC_MAPPING IopFileMapping;
extern POBJECT_TYPE _IoFileObjectType;
extern HAL_DISPATCH _HalDispatchTable;
extern LIST_ENTRY IopErrorLogListHead;
extern ULONG IopNumTriageDumpDataBlocks;
extern PVOID IopTriageDumpDataBlocks[64];
//
// Inlined Functions

View file

@ -296,6 +296,20 @@ KdpSuspendAllBreakPoints(
VOID
);
//
// Safe memory read & write Support
//
NTSTATUS
NTAPI
KdpCopyMemoryChunks(
IN ULONG64 Address,
IN PVOID Buffer,
IN ULONG TotalSize,
IN ULONG ChunkSize,
IN ULONG Flags,
OUT PULONG ActualSize OPTIONAL
);
//
// Architecture dependent support routines
//

View file

@ -18,6 +18,7 @@ extern UCHAR MmDisablePagingExecutive;
extern ULONG MmLowestPhysicalPage;
extern ULONG MmHighestPhysicalPage;
extern ULONG MmAvailablePages;
extern ULONG MmResidentAvailablePages;
extern PVOID MmPagedPoolBase;
extern ULONG MmPagedPoolSize;
@ -25,6 +26,25 @@ extern ULONG MmPagedPoolSize;
extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg;
extern LIST_ENTRY MmLoadedUserImageList;
extern ULONG MmNumberOfPagingFiles;
extern PVOID MmUnloadedDrivers;
extern PVOID MmLastUnloadedDrivers;
extern PVOID MmTriageActionTaken;
extern PVOID KernelVerifier;
extern MM_DRIVER_VERIFIER_DATA MmVerifierData;
extern SIZE_T MmTotalCommitLimit;
extern SIZE_T MmTotalCommittedPages;
extern SIZE_T MmSharedCommit;
extern SIZE_T MmDriverCommit;
extern SIZE_T MmProcessCommit;
extern SIZE_T MmPagedPoolCommit;
extern SIZE_T MmPeakCommitment;
extern SIZE_T MmtotalCommitLimitMaximum;
struct _KTRAP_FRAME;
struct _EPROCESS;
struct _MM_RMAP_ENTRY;
@ -33,7 +53,7 @@ typedef ULONG SWAPENTRY;
typedef ULONG PFN_TYPE, *PPFN_TYPE;
//
//MmDbgCopyMemory Flags
// MmDbgCopyMemory Flags
//
#define MMDBG_COPY_WRITE 0x00000001
#define MMDBG_COPY_PHYSICAL 0x00000002
@ -369,6 +389,20 @@ typedef struct _MMPFN
extern PMMPFN MmPfnDatabase;
typedef struct _MMPFNLIST
{
PFN_NUMBER Total;
MMLISTS ListName;
PFN_NUMBER Flink;
PFN_NUMBER Blink;
} MMPFNLIST, *PMMPFNLIST;
extern MMPFNLIST MmZeroedPageListHead;
extern MMPFNLIST MmFreePageListHead;
extern MMPFNLIST MmStandbyPageListHead;
extern MMPFNLIST MmModifiedPageListHead;
extern MMPFNLIST MmModifiedNoWritePageListHead;
typedef struct _MM_PAGEOP
{
/* Type of operation. */

View file

@ -39,6 +39,8 @@ LARGE_INTEGER IoWriteTransferCount = {{0, 0}};
ULONG IoOtherOperationCount = 0;
LARGE_INTEGER IoOtherTransferCount = {{0, 0}};
KSPIN_LOCK IoStatisticsLock = 0;
ULONG IopNumTriageDumpDataBlocks;
PVOID IopTriageDumpDataBlocks[64];
GENERIC_MAPPING IopFileMapping = {
FILE_GENERIC_READ,

View file

@ -160,7 +160,7 @@ KdpSysReadBusData(IN ULONG BusDataType,
Length);
/* Return status */
return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
NTSTATUS
@ -182,7 +182,7 @@ KdpSysWriteBusData(IN ULONG BusDataType,
Length);
/* Return status */
return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
NTSTATUS
@ -209,12 +209,13 @@ KdpSysReadControlSpace(IN ULONG Processor,
(ULONG_PTR)&KiProcessorBlock[Processor]->
ProcessorState);
/* Copy the memory */
RtlCopyMemory(Buffer, ControlStart, Length);
/* Finish up */
*ActualLength = Length;
return STATUS_SUCCESS;
/* Read the control state safely */
return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
ControlStart,
Length,
0,
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
ActualLength);
}
else
{
@ -243,12 +244,13 @@ KdpSysWriteControlSpace(IN ULONG Processor,
(ULONG_PTR)&KiProcessorBlock[Processor]->
ProcessorState);
/* Copy the memory */
RtlCopyMemory(ControlStart, Buffer, Length);
/* Finish up */
*ActualLength = Length;
return STATUS_SUCCESS;
/* Write the control state safely */
return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
ControlStart,
Length,
0,
MMDBG_COPY_UNSAFE,
ActualLength);
}
else
{

View file

@ -24,65 +24,72 @@ KdpCopyMemoryChunks(IN ULONG64 Address,
IN ULONG Flags,
OUT PULONG ActualSize OPTIONAL)
{
ULONG Length;
NTSTATUS Status;
ULONG RemainingLength, CopyChunk;
/* Check if this is physical or virtual copy */
if (Flags & MMDBG_COPY_PHYSICAL)
/* Check if we didn't get a chunk size or if it is too big */
if (ChunkSize == 0)
{
/* Fail physical memory read/write for now */
if (Flags & MMDBG_COPY_WRITE)
{
KdpDprintf("KdpCopyMemoryChunks: Failing write for Physical Address 0x%I64x Length: %x\n",
Address,
TotalSize);
}
else
{
KdpDprintf("KdpCopyMemoryChunks: Failing read for Physical Address 0x%I64x Length: %x\n",
Address,
TotalSize);
}
/* Return an error */
Length = 0;
Status = STATUS_UNSUCCESSFUL;
/* Default to 4 byte chunks */
ChunkSize = 4;
}
else
else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
{
/* Protect against NULL */
if (!Address)
{
if (ActualSize) *ActualSize = 0;
return STATUS_UNSUCCESSFUL;
}
/* Check if this is read or write */
if (Flags & MMDBG_COPY_WRITE)
{
/* Do the write */
RtlCopyMemory((PVOID)(ULONG_PTR)Address,
Buffer,
TotalSize);
}
else
{
/* Do the read */
RtlCopyMemory(Buffer,
(PVOID)(ULONG_PTR)Address,
TotalSize);
}
/* Set size and status */
Length = TotalSize;
Status = STATUS_SUCCESS;
/* Normalize to maximum size */
ChunkSize = MMDBG_COPY_MAX_SIZE;
}
/* Return the actual length if requested */
if (ActualSize) *ActualSize = Length;
/* Copy the whole range in page aligned chunks */
RemainingLength = TotalSize;
CopyChunk = 1;
while (RemainingLength > 0)
{
/*
* Determine the best chunk size for this round.
* The ideal size is page aligned, isn't larger than the
* the remaining length and respects the chunk limit.
*/
while (((CopyChunk * 2) <= RemainingLength) &&
(CopyChunk < ChunkSize) &&
((Address & ((CopyChunk * 2) - 1)) == 0))
{
/* Increase it */
CopyChunk = CopyChunk * 2;
}
/* Return status */
return Status;
/*
* The chunk size can be larger than the remaining size if this isn't
* the first round, so check if we need to shrink it back
*/
while (CopyChunk > RemainingLength)
{
/* Shrink it */
CopyChunk /= 2;
}
/* Do the copy */
Status = MmDbgCopyMemory(Address,
Buffer,
CopyChunk,
Flags);
if (!NT_SUCCESS(Status))
{
/* Copy failed, break out */
break;
}
/* Update pointers and length for the next run */
Address = Address + CopyChunk;
Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk);
RemainingLength = RemainingLength - CopyChunk;
}
/*
* Return the size we managed to copy
* and return success if we could copy the whole range
*/
if (ActualSize) *ActualSize = TotalSize - RemainingLength;
return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
VOID
@ -269,7 +276,7 @@ KdpSetCommonState(IN ULONG NewState,
IN PCONTEXT Context,
IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange)
{
USHORT InstructionCount;
ULONG InstructionCount;
BOOLEAN HadBreakpoints;
/* Setup common stuff available for all CPU architectures */
@ -285,10 +292,12 @@ KdpSetCommonState(IN ULONG NewState,
sizeof(DBGKD_ANY_CONTROL_REPORT));
/* Now copy the instruction stream and set the count */
RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
(PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
DBGKD_MAXSTREAM);
InstructionCount = DBGKD_MAXSTREAM;
KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
&WaitStateChange->ControlReport.InstructionStream[0],
DBGKD_MAXSTREAM,
0,
MMDBG_COPY_UNSAFE,
&InstructionCount);
WaitStateChange->ControlReport.InstructionCount = InstructionCount;
/* Clear all the breakpoints in this region */
@ -299,9 +308,12 @@ KdpSetCommonState(IN ULONG NewState,
if (HadBreakpoints)
{
/* Copy the instruction stream again, this time without breakpoints */
RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
(PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
WaitStateChange->ControlReport.InstructionCount);
KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
&WaitStateChange->ControlReport.InstructionStream[0],
InstructionCount,
0,
MMDBG_COPY_UNSAFE,
NULL);
}
}
@ -1297,6 +1309,7 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
PSTRING ExtraData;
STRING Data, Header;
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
ULONG PathNameLength;
KCONTINUE_STATUS Status;
/* Start wait loop */
@ -1317,14 +1330,27 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
/* Check if we have a symbol name */
/* Check if we have a path name */
if (PathName)
{
/* Setup the information */
WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length;
RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length);
/* Copy it to the path buffer */
KdpCopyMemoryChunks((ULONG_PTR)PathName->Buffer,
KdpPathBuffer,
PathName->Length,
0,
MMDBG_COPY_UNSAFE,
&PathNameLength);
/* Null terminate */
KdpPathBuffer[PathNameLength] = ANSI_NULL;
PathNameLength++;
/* Set the path length */
WaitStateChange.u.LoadSymbols.PathNameLength = PathNameLength;
/* Set up the data */
Data.Buffer = KdpPathBuffer;
Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength;
Data.Length = PathNameLength;
ExtraData = &Data;
}
else

View file

@ -21,6 +21,7 @@ KdpAddBreakpoint(IN PVOID Address)
{
KD_BREAKPOINT_TYPE Content;
ULONG i;
NTSTATUS Status;
/* Loop current breakpoints */
for (i = 0; i < KD_BREAKPOINT_MAX; i++)
@ -51,15 +52,39 @@ KdpAddBreakpoint(IN PVOID Address)
if (i == KD_BREAKPOINT_MAX) return 0;
/* Save the old instruction */
RtlCopyMemory(&Content, Address, KD_BREAKPOINT_SIZE);
Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
&Content,
KD_BREAKPOINT_SIZE,
0,
MMDBG_COPY_UNSAFE,
NULL);
if (!NT_SUCCESS(Status))
{
/* TODO: Set it as a owed breakpoint */
KdpDprintf("Failed to set breakpoint at address 0x%p\n", Address);
return 0;
}
/* Write the entry */
KdpBreakpointTable[i].Address = Address;
KdpBreakpointTable[i].Content = Content;
KdpBreakpointTable[i].Flags = KdpBreakpointActive;
/* Write the breakpoint and return the handle */
RtlCopyMemory(Address, &KdpBreakpointInstruction, KD_BREAKPOINT_SIZE);
/* Write the breakpoint */
Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
&KdpBreakpointInstruction,
KD_BREAKPOINT_SIZE,
0,
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
NULL);
if (!NT_SUCCESS(Status))
{
/* This should never happen */
KdpDprintf("Unable to write breakpoint to address 0x%p\n", Address);
}
/* Return the breakpoint handle */
return i + 1;
}
@ -67,6 +92,8 @@ BOOLEAN
NTAPI
KdpLowWriteContent(IN ULONG BpIndex)
{
NTSTATUS Status;
/* Make sure that the breakpoint is actually active */
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending)
{
@ -83,9 +110,20 @@ KdpLowWriteContent(IN ULONG BpIndex)
}
/* We have an active breakpoint with an instruction to bring back. Do it. */
RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
&KdpBreakpointTable[BpIndex].Content,
KD_BREAKPOINT_SIZE);
Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
Address,
&KdpBreakpointTable[BpIndex].Content,
KD_BREAKPOINT_SIZE,
0,
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
NULL);
if (!NT_SUCCESS(Status))
{
/* TODO: Set it as a owed breakpoint */
KdpDprintf("Failed to delete breakpoint at address 0x%p\n",
KdpBreakpointTable[BpIndex].Address);
return FALSE;
}
/* Everything went fine, return */
return TRUE;
@ -95,6 +133,8 @@ BOOLEAN
NTAPI
KdpLowRestoreBreakpoint(IN ULONG BpIndex)
{
NTSTATUS Status;
/* Were we not able to remove it earlier? */
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)
{
@ -111,9 +151,20 @@ KdpLowRestoreBreakpoint(IN ULONG BpIndex)
}
/* Ok, we actually have to overwrite the instruction now */
RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
&KdpBreakpointInstruction,
KD_BREAKPOINT_SIZE);
Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
Address,
&KdpBreakpointInstruction,
KD_BREAKPOINT_SIZE,
0,
MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
NULL);
if (!NT_SUCCESS(Status))
{
/* FIXME: Set it as a owed breakpoint */
KdpDprintf("Failed to restore breakpoint at address 0x%p\n",
KdpBreakpointTable[BpIndex].Address);
return FALSE;
}
/* Clear any possible previous pending flag and return success */
KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;

View file

@ -391,22 +391,22 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
{(ULONG_PTR)&PsActiveProcessHead},
{(ULONG_PTR)&PspCidTable},
{(ULONG_PTR)&ExpSystemResourcesList},
{0}, // ExpPagedPoolDescriptor
{0}, // ExpNumberOfPagedPools
{(ULONG_PTR)ExpPagedPoolDescriptor},
{(ULONG_PTR)&ExpNumberOfPagedPools},
{(ULONG_PTR)&KeTimeIncrement},
{(ULONG_PTR)&KeBugcheckCallbackListHead},
{(ULONG_PTR)KiBugCheckData},
{(ULONG_PTR)&IopErrorLogListHead},
{(ULONG_PTR)&ObpRootDirectoryObject},
{(ULONG_PTR)&ObpTypeObjectType},
{0}, // MmSystemCacheStart
{0}, // MmSystemCacheEnd
{0}, // MmSystemCacheWs
{(ULONG_PTR)&MmSystemCacheStart},
{(ULONG_PTR)&MmSystemCacheEnd},
{(ULONG_PTR)&MmSystemCacheWs},
{(ULONG_PTR)&MmPfnDatabase},
{(ULONG_PTR)MmSystemPtesStart},
{(ULONG_PTR)MmSystemPtesEnd},
{0}, // MmSubsectionBase
{0}, // MmNumberOfPagingFiles
{(ULONG_PTR)&MmSubsectionBase},
{(ULONG_PTR)&MmNumberOfPagingFiles},
{(ULONG_PTR)&MmLowestPhysicalPage},
{(ULONG_PTR)&MmHighestPhysicalPage},
{(ULONG_PTR)&MmNumberOfPhysicalPages},
@ -419,21 +419,21 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
{(ULONG_PTR)&MmPagedPoolInfo},
PAGE_SIZE,
{(ULONG_PTR)&MmSizeOfPagedPoolInBytes},
{0}, // MmTotalCommitLimit
{0}, // MmTotalCommittedPages
{0}, // MmSharedCommit
{0}, // MmDriverCommit
{0}, // MmProcessCommit
{0}, // MmPagedPoolCommit
{(ULONG_PTR)&MmTotalCommitLimit},
{(ULONG_PTR)&MmTotalCommittedPages},
{(ULONG_PTR)&MmSharedCommit},
{(ULONG_PTR)&MmDriverCommit},
{(ULONG_PTR)&MmProcessCommit},
{(ULONG_PTR)&MmPagedPoolCommit},
{0},
{0}, // MmZeroedPageListHead
{0}, // MmFreePageListHead
{0}, // MmStandbyPageListHead
{0}, // MmModifiedPageListHead
{0}, // MmModifiedNoWritePageListHead
{0}, // MmAvailablePages
{0}, // MmResidentAvailablePages
{0}, // PoolTrackTable
{(ULONG_PTR)&MmZeroedPageListHead},
{(ULONG_PTR)&MmFreePageListHead},
{(ULONG_PTR)&MmStandbyPageListHead},
{(ULONG_PTR)&MmModifiedPageListHead},
{(ULONG_PTR)&MmModifiedNoWritePageListHead},
{(ULONG_PTR)&MmAvailablePages},
{(ULONG_PTR)&MmResidentAvailablePages},
{(ULONG_PTR)&PoolTrackTable},
{(ULONG_PTR)&NonPagedPoolDescriptor},
{(ULONG_PTR)&MmHighestUserAddress},
{(ULONG_PTR)&MmSystemRangeStart},
@ -442,19 +442,19 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
{(ULONG_PTR)KdPrintDefaultCircularBuffer + 1},
{(ULONG_PTR)&KdPrintWritePointer},
{(ULONG_PTR)&KdPrintRolloverCount},
{0}, // MmLoadedUserImageList
{(ULONG_PTR)&MmLoadedUserImageList},
{(ULONG_PTR)&NtBuildLab},
{0},
{(ULONG_PTR)KiProcessorBlock},
{0}, // MmUnloadedDrivers
{0}, // MmLastUnloadedDrivers
{0}, // MmTriageActionTaken
{0}, // MmSpecialPoolTag
{0}, // KernelVerifier
{0}, // MmVerifierData
{0}, // MmAllocatedNonPagedPool
{0}, // MmPeakCommitment
{0}, // MmtotalCommitLimitMaximum
{(ULONG_PTR)&MmUnloadedDrivers},
{(ULONG_PTR)&MmLastUnloadedDrivers},
{(ULONG_PTR)&MmTriageActionTaken},
{(ULONG_PTR)&MmSpecialPoolTag},
{(ULONG_PTR)&KernelVerifier},
{(ULONG_PTR)&MmVerifierData},
{(ULONG_PTR)&MmAllocatedNonPagedPool},
{(ULONG_PTR)&MmPeakCommitment},
{(ULONG_PTR)&MmtotalCommitLimitMaximum},
{(ULONG_PTR)&CmNtCSDVersion},
{(ULONG_PTR)&MmPhysicalMemoryBlock},
{(ULONG_PTR)&MmSessionBase},
@ -539,6 +539,6 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
0,
0,
#endif
{0}, // IopNumTriageDumpDataBlocks
{0}, // IopTriageDumpDataBlocks
{(ULONG_PTR)&IopNumTriageDumpDataBlocks},
{(ULONG_PTR)IopTriageDumpDataBlocks},
};

View file

@ -54,6 +54,9 @@ ULONG MmBootImageSize;
ULONG MmUserProbeAddress;
PVOID MmHighestUserAddress;
PVOID MmSystemRangeStart;
PVOID MmSystemCacheStart;
PVOID MmSystemCacheEnd;
MMSUPPORT MmSystemCacheWs;
/* PRIVATE FUNCTIONS **********************************************************/

View file

@ -21,8 +21,11 @@
/* GLOBALS ********************************************************************/
ULONG ExpNumberOfPagedPools;
POOL_DESCRIPTOR NonPagedPoolDescriptor;
PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
PPOOL_DESCRIPTOR PoolVector[2];
PVOID PoolTrackTable;
PKGUARDED_MUTEX ExpPagedPoolMutex;
/* PRIVATE FUNCTIONS **********************************************************/

View file

@ -217,6 +217,12 @@ ULONG MmUserProbeAddress;
PVOID MmHighestUserAddress;
PVOID MmSystemRangeStart;
PVOID MmSystemCacheStart;
PVOID MmSystemCacheEnd;
MMSUPPORT MmSystemCacheWs;
/* PRIVATE FUNCTIONS **********************************************************/
//

View file

@ -87,7 +87,10 @@ typedef struct _POOL_HEADER
C_ASSERT(sizeof(POOL_HEADER) == 8);
C_ASSERT(sizeof(POOL_HEADER) == sizeof(LIST_ENTRY));
extern ULONG ExpNumberOfPagedPools;
extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
extern PVOID PoolTrackTable;
//
// END FIXFIX
@ -156,6 +159,12 @@ extern PVOID MmSessionBase;
extern PVOID MiSessionSpaceEnd;
extern ULONG MmSizeOfPagedPoolInBytes;
extern PMMPTE MmSystemPagePtes;
extern PVOID MmSystemCacheStart;
extern PVOID MmSystemCacheEnd;
extern MMSUPPORT MmSystemCacheWs;
extern SIZE_T MmAllocatedNonPagedPool;
extern ULONG_PTR MmSubsectionBase;
extern ULONG MmSpecialPoolTag;
NTSTATUS
NTAPI

View file

@ -24,6 +24,8 @@ PVOID MmNonPagedPoolEnd0;
PFN_NUMBER MiStartOfInitialPoolFrame, MiEndOfInitialPoolFrame;
KGUARDED_MUTEX MmPagedPoolMutex;
MM_PAGED_POOL_INFO MmPagedPoolInfo;
SIZE_T MmAllocatedNonPagedPool;
ULONG MmSpecialPoolTag;
/* PRIVATE FUNCTIONS **********************************************************/

View file

@ -51,6 +51,22 @@
PPHYSICAL_PAGE MmPfnDatabase;
ULONG MmAvailablePages;
ULONG MmResidentAvailablePages;
SIZE_T MmTotalCommitLimit;
SIZE_T MmTotalCommittedPages;
SIZE_T MmSharedCommit;
SIZE_T MmDriverCommit;
SIZE_T MmProcessCommit;
SIZE_T MmPagedPoolCommit;
SIZE_T MmPeakCommitment;
SIZE_T MmtotalCommitLimitMaximum;
MMPFNLIST MmZeroedPageListHead;
MMPFNLIST MmFreePageListHead;
MMPFNLIST MmStandbyPageListHead;
MMPFNLIST MmModifiedPageListHead;
MMPFNLIST MmModifiedNoWritePageListHead;
/* List of pages allocated to the MC_USER Consumer */
static LIST_ENTRY UserPageListHead;

108
reactos/ntoskrnl/mm/mmdbg.c Normal file
View file

@ -0,0 +1,108 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/mm/mmdbg.c
* PURPOSE: Memory Manager support routines for the Kernel Debugger
* PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
MmDbgCopyMemory(IN ULONG64 Address,
IN PVOID Buffer,
IN ULONG Size,
IN ULONG Flags)
{
NTSTATUS Status;
/* For now, this must be a "unsafe" copy */
ASSERT(Flags & MMDBG_COPY_UNSAFE);
/* We only handle 1, 2, 4 and 8 byte requests */
if ((Size != 1) &&
(Size != 2) &&
(Size != 4) &&
(Size != MMDBG_COPY_MAX_SIZE))
{
/* Invalid size, fail */
return STATUS_INVALID_PARAMETER_3;
}
/* The copy must be aligned too */
if ((Address & (Size - 1)) != 0)
{
/* Fail */
return STATUS_INVALID_PARAMETER_3;
}
/* No physical memory support yet */
if (Flags & MMDBG_COPY_PHYSICAL)
{
/* Fail */
KdpDprintf("MmDbgCopyMemory: Failing %s for Physical Address 0x%I64x\n",
Flags & MMDBG_COPY_WRITE ? "write" : "read",
Address);
return STATUS_UNSUCCESSFUL;
}
/* Simple check for invalid address */
if ((MiAddressToPde((ULONG_PTR)Address)->u.Hard.Valid == 0) ||
(MiAddressToPte((ULONG_PTR)Address)->u.Hard.Valid == 0))
{
/* Fail */
KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Address 0x%p\n",
Flags & MMDBG_COPY_WRITE ? "write" : "read",
(PVOID)(ULONG_PTR)Address);
return STATUS_UNSUCCESSFUL;
}
/* If we are going to write to it then make sure it is writeable too */
if ((Flags & MMDBG_COPY_WRITE) &&
(!MI_IS_PAGE_WRITEABLE(MiAddressToPte((ULONG_PTR)Address))))
{
/* Fail */
KdpDprintf("MmDbgCopyMemory: Failing write for Address 0x%p\n",
(PVOID)(ULONG_PTR)Address);
return STATUS_UNSUCCESSFUL;
}
/* Use SEH to try to catch anything else somewhat cleanly */
_SEH2_TRY
{
/* Check if this is read or write */
if (Flags & MMDBG_COPY_WRITE)
{
/* Do the write */
RtlCopyMemory((PVOID)(ULONG_PTR)Address,
Buffer,
Size);
}
else
{
/* Do the read */
RtlCopyMemory(Buffer,
(PVOID)(ULONG_PTR)Address,
Size);
}
/* Copy succeeded */
Status = STATUS_SUCCESS;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get the exception code */
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
/* Return status */
return Status;
}

View file

@ -424,6 +424,9 @@ MmInitSystem(IN ULONG Phase,
/* Initialize working sets */
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
/* Initialize the user mode image list */
InitializeListHead(&MmLoadedUserImageList);
/* Initialize the Loader Lock */
KeInitializeMutant(&MmSystemLoadLock, FALSE);

View file

@ -78,6 +78,7 @@ static KSPIN_LOCK PagingFileListLock;
/* Number of paging files */
static ULONG MiPagingFileCount;
ULONG MmNumberOfPagingFiles;
/* Number of pages that are available for swapping */
ULONG MiFreeSwapPages;

View file

@ -71,6 +71,8 @@ MM_SECTION_PAGEOUT_CONTEXT;
POBJECT_TYPE MmSectionObjectType = NULL;
ULONG_PTR MmSubsectionBase;
static GENERIC_MAPPING MmpSectionMapping = {
STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY,
STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE,

View file

@ -28,11 +28,18 @@ sprintf_nt(IN PCHAR Buffer,
/* GLOBALS *******************************************************************/
LIST_ENTRY PsLoadedModuleList;
LIST_ENTRY MmLoadedUserImageList;
KSPIN_LOCK PsLoadedModuleSpinLock;
ULONG_PTR PsNtosImageBase;
KMUTANT MmSystemLoadLock;
extern ULONG NtGlobalFlag;
PVOID MmUnloadedDrivers;
PVOID MmLastUnloadedDrivers;
PVOID MmTriageActionTaken;
PVOID KernelVerifier;
MM_DRIVER_VERIFIER_DATA MmVerifierData;
/* FUNCTIONS *****************************************************************/
PVOID

View file

@ -405,6 +405,7 @@
<file>dbgpool.c</file>
<file>freelist.c</file>
<file>marea.c</file>
<file>mmdbg.c</file>
<file>mmfault.c</file>
<file>mminit.c</file>
<file>mpw.c</file>