mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- 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:
parent
c4d8068980
commit
82bd7858d1
21 changed files with 417 additions and 121 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
|
|
@ -54,6 +54,9 @@ ULONG MmBootImageSize;
|
|||
ULONG MmUserProbeAddress;
|
||||
PVOID MmHighestUserAddress;
|
||||
PVOID MmSystemRangeStart;
|
||||
PVOID MmSystemCacheStart;
|
||||
PVOID MmSystemCacheEnd;
|
||||
MMSUPPORT MmSystemCacheWs;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
|
|
|
@ -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 **********************************************************/
|
||||
|
|
|
@ -217,6 +217,12 @@ ULONG MmUserProbeAddress;
|
|||
PVOID MmHighestUserAddress;
|
||||
PVOID MmSystemRangeStart;
|
||||
|
||||
|
||||
|
||||
PVOID MmSystemCacheStart;
|
||||
PVOID MmSystemCacheEnd;
|
||||
MMSUPPORT MmSystemCacheWs;
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 **********************************************************/
|
||||
|
||||
|
|
|
@ -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
108
reactos/ntoskrnl/mm/mmdbg.c
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue