- 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; USHORT Gdt64R3CmTeb;
GCC_ULONG64 IopNumTriageDumpDataBlocks; GCC_ULONG64 IopNumTriageDumpDataBlocks;
GCC_ULONG64 IopTriageDumpDataBlocks; GCC_ULONG64 IopTriageDumpDataBlocks;
#if 0 // Longhorn/Vista and later
GCC_ULONG64 VfCrashDataBlock; GCC_ULONG64 VfCrashDataBlock;
GCC_ULONG64 MmBadPagesDetected;
GCC_ULONG64 MmZeroedPageSingleBitErrorsDetected;
#endif
} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64; } KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
#endif #endif

View file

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

View file

@ -296,6 +296,20 @@ KdpSuspendAllBreakPoints(
VOID 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 // Architecture dependent support routines
// //

View file

@ -18,6 +18,7 @@ extern UCHAR MmDisablePagingExecutive;
extern ULONG MmLowestPhysicalPage; extern ULONG MmLowestPhysicalPage;
extern ULONG MmHighestPhysicalPage; extern ULONG MmHighestPhysicalPage;
extern ULONG MmAvailablePages; extern ULONG MmAvailablePages;
extern ULONG MmResidentAvailablePages;
extern PVOID MmPagedPoolBase; extern PVOID MmPagedPoolBase;
extern ULONG MmPagedPoolSize; extern ULONG MmPagedPoolSize;
@ -25,6 +26,25 @@ extern ULONG MmPagedPoolSize;
extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor; extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg; 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 _KTRAP_FRAME;
struct _EPROCESS; struct _EPROCESS;
struct _MM_RMAP_ENTRY; struct _MM_RMAP_ENTRY;
@ -33,7 +53,7 @@ typedef ULONG SWAPENTRY;
typedef ULONG PFN_TYPE, *PPFN_TYPE; typedef ULONG PFN_TYPE, *PPFN_TYPE;
// //
//MmDbgCopyMemory Flags // MmDbgCopyMemory Flags
// //
#define MMDBG_COPY_WRITE 0x00000001 #define MMDBG_COPY_WRITE 0x00000001
#define MMDBG_COPY_PHYSICAL 0x00000002 #define MMDBG_COPY_PHYSICAL 0x00000002
@ -369,6 +389,20 @@ typedef struct _MMPFN
extern PMMPFN MmPfnDatabase; 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 typedef struct _MM_PAGEOP
{ {
/* Type of operation. */ /* Type of operation. */

View file

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

View file

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

View file

@ -24,65 +24,72 @@ KdpCopyMemoryChunks(IN ULONG64 Address,
IN ULONG Flags, IN ULONG Flags,
OUT PULONG ActualSize OPTIONAL) OUT PULONG ActualSize OPTIONAL)
{ {
ULONG Length;
NTSTATUS Status; NTSTATUS Status;
ULONG RemainingLength, CopyChunk;
/* Check if this is physical or virtual copy */ /* Check if we didn't get a chunk size or if it is too big */
if (Flags & MMDBG_COPY_PHYSICAL) if (ChunkSize == 0)
{ {
/* Fail physical memory read/write for now */ /* Default to 4 byte chunks */
if (Flags & MMDBG_COPY_WRITE) ChunkSize = 4;
{
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;
} }
else else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
{ {
/* Protect against NULL */ /* Normalize to maximum size */
if (!Address) ChunkSize = MMDBG_COPY_MAX_SIZE;
{
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;
} }
/* Return the actual length if requested */ /* Copy the whole range in page aligned chunks */
if (ActualSize) *ActualSize = Length; 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 VOID
@ -269,7 +276,7 @@ KdpSetCommonState(IN ULONG NewState,
IN PCONTEXT Context, IN PCONTEXT Context,
IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange) IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange)
{ {
USHORT InstructionCount; ULONG InstructionCount;
BOOLEAN HadBreakpoints; BOOLEAN HadBreakpoints;
/* Setup common stuff available for all CPU architectures */ /* Setup common stuff available for all CPU architectures */
@ -285,10 +292,12 @@ KdpSetCommonState(IN ULONG NewState,
sizeof(DBGKD_ANY_CONTROL_REPORT)); sizeof(DBGKD_ANY_CONTROL_REPORT));
/* Now copy the instruction stream and set the count */ /* Now copy the instruction stream and set the count */
RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0], KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
(PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter, &WaitStateChange->ControlReport.InstructionStream[0],
DBGKD_MAXSTREAM); DBGKD_MAXSTREAM,
InstructionCount = DBGKD_MAXSTREAM; 0,
MMDBG_COPY_UNSAFE,
&InstructionCount);
WaitStateChange->ControlReport.InstructionCount = InstructionCount; WaitStateChange->ControlReport.InstructionCount = InstructionCount;
/* Clear all the breakpoints in this region */ /* Clear all the breakpoints in this region */
@ -299,9 +308,12 @@ KdpSetCommonState(IN ULONG NewState,
if (HadBreakpoints) if (HadBreakpoints)
{ {
/* Copy the instruction stream again, this time without breakpoints */ /* Copy the instruction stream again, this time without breakpoints */
RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0], KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
(PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter, &WaitStateChange->ControlReport.InstructionStream[0],
WaitStateChange->ControlReport.InstructionCount); InstructionCount,
0,
MMDBG_COPY_UNSAFE,
NULL);
} }
} }
@ -1297,6 +1309,7 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
PSTRING ExtraData; PSTRING ExtraData;
STRING Data, Header; STRING Data, Header;
DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange; DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
ULONG PathNameLength;
KCONTINUE_STATUS Status; KCONTINUE_STATUS Status;
/* Start wait loop */ /* Start wait loop */
@ -1317,14 +1330,27 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum; WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage; WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
/* Check if we have a symbol name */ /* Check if we have a path name */
if (PathName) if (PathName)
{ {
/* Setup the information */ /* Copy it to the path buffer */
WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length; KdpCopyMemoryChunks((ULONG_PTR)PathName->Buffer,
RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length); 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.Buffer = KdpPathBuffer;
Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength; Data.Length = PathNameLength;
ExtraData = &Data; ExtraData = &Data;
} }
else else

View file

@ -21,6 +21,7 @@ KdpAddBreakpoint(IN PVOID Address)
{ {
KD_BREAKPOINT_TYPE Content; KD_BREAKPOINT_TYPE Content;
ULONG i; ULONG i;
NTSTATUS Status;
/* Loop current breakpoints */ /* Loop current breakpoints */
for (i = 0; i < KD_BREAKPOINT_MAX; i++) for (i = 0; i < KD_BREAKPOINT_MAX; i++)
@ -51,15 +52,39 @@ KdpAddBreakpoint(IN PVOID Address)
if (i == KD_BREAKPOINT_MAX) return 0; if (i == KD_BREAKPOINT_MAX) return 0;
/* Save the old instruction */ /* 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 */ /* Write the entry */
KdpBreakpointTable[i].Address = Address; KdpBreakpointTable[i].Address = Address;
KdpBreakpointTable[i].Content = Content; KdpBreakpointTable[i].Content = Content;
KdpBreakpointTable[i].Flags = KdpBreakpointActive; KdpBreakpointTable[i].Flags = KdpBreakpointActive;
/* Write the breakpoint and return the handle */ /* Write the breakpoint */
RtlCopyMemory(Address, &KdpBreakpointInstruction, KD_BREAKPOINT_SIZE); 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; return i + 1;
} }
@ -67,6 +92,8 @@ BOOLEAN
NTAPI NTAPI
KdpLowWriteContent(IN ULONG BpIndex) KdpLowWriteContent(IN ULONG BpIndex)
{ {
NTSTATUS Status;
/* Make sure that the breakpoint is actually active */ /* Make sure that the breakpoint is actually active */
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending) 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. */ /* We have an active breakpoint with an instruction to bring back. Do it. */
RtlCopyMemory(KdpBreakpointTable[BpIndex].Address, Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
&KdpBreakpointTable[BpIndex].Content, Address,
KD_BREAKPOINT_SIZE); &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 */ /* Everything went fine, return */
return TRUE; return TRUE;
@ -95,6 +133,8 @@ BOOLEAN
NTAPI NTAPI
KdpLowRestoreBreakpoint(IN ULONG BpIndex) KdpLowRestoreBreakpoint(IN ULONG BpIndex)
{ {
NTSTATUS Status;
/* Were we not able to remove it earlier? */ /* Were we not able to remove it earlier? */
if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired) if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)
{ {
@ -111,9 +151,20 @@ KdpLowRestoreBreakpoint(IN ULONG BpIndex)
} }
/* Ok, we actually have to overwrite the instruction now */ /* Ok, we actually have to overwrite the instruction now */
RtlCopyMemory(KdpBreakpointTable[BpIndex].Address, Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
&KdpBreakpointInstruction, Address,
KD_BREAKPOINT_SIZE); &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 */ /* Clear any possible previous pending flag and return success */
KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending; KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -51,6 +51,22 @@
PPHYSICAL_PAGE MmPfnDatabase; PPHYSICAL_PAGE MmPfnDatabase;
ULONG MmAvailablePages; 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 */ /* List of pages allocated to the MC_USER Consumer */
static LIST_ENTRY UserPageListHead; 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 */ /* Initialize working sets */
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
/* Initialize the user mode image list */
InitializeListHead(&MmLoadedUserImageList);
/* Initialize the Loader Lock */ /* Initialize the Loader Lock */
KeInitializeMutant(&MmSystemLoadLock, FALSE); KeInitializeMutant(&MmSystemLoadLock, FALSE);

View file

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

View file

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

View file

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

View file

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