mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 14:53:40 +00:00
Somehow missed this in previous commit
svn path=/trunk/; revision=69540
This commit is contained in:
parent
8ea1ea856d
commit
415eda607f
1 changed files with 116 additions and 158 deletions
|
@ -21,6 +21,12 @@
|
||||||
#define KdpDprintf(...)
|
#define KdpDprintf(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
MmIsSessionAddress(
|
||||||
|
IN PVOID Address
|
||||||
|
);
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
PVOID MiDebugMapping = MI_DEBUG_MAPPING;
|
PVOID MiDebugMapping = MI_DEBUG_MAPPING;
|
||||||
|
@ -28,16 +34,6 @@ PMMPTE MmDebugPte = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
NTAPI
|
|
||||||
MmIsSessionAddress(IN PVOID Address)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// No session space support yet
|
|
||||||
//
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress,
|
MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress,
|
||||||
|
@ -47,78 +43,59 @@ MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress,
|
||||||
MMPTE TempPte;
|
MMPTE TempPte;
|
||||||
PVOID MappingBaseAddress;
|
PVOID MappingBaseAddress;
|
||||||
|
|
||||||
//
|
/* Check if we are called too early */
|
||||||
// Check if we are called too early
|
|
||||||
//
|
|
||||||
if (MmDebugPte == NULL)
|
if (MmDebugPte == NULL)
|
||||||
{
|
{
|
||||||
//
|
/* The structures we require aren't initialized yet, fail */
|
||||||
// The structures we require aren't initialized yet, fail
|
|
||||||
//
|
|
||||||
KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
|
KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
|
||||||
"Address: 0x%I64x\n", PhysicalAddress);
|
"Address: 0x%I64x\n",
|
||||||
|
PhysicalAddress);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* FIXME: No support for cache flags yet */
|
||||||
// FIXME: No support for cache flags yet
|
|
||||||
//
|
|
||||||
if ((Flags & (MMDBG_COPY_CACHED |
|
if ((Flags & (MMDBG_COPY_CACHED |
|
||||||
MMDBG_COPY_UNCACHED |
|
MMDBG_COPY_UNCACHED |
|
||||||
MMDBG_COPY_WRITE_COMBINED)) != 0)
|
MMDBG_COPY_WRITE_COMBINED)) != 0)
|
||||||
{
|
{
|
||||||
//
|
/* Fail */
|
||||||
// Fail
|
KdpDprintf("MiDbgTranslatePhysicalAddress: Cache flags not yet supported. "
|
||||||
//
|
"Flags: 0x%lx\n",
|
||||||
KdpDprintf("MiDbgTranslatePhysicalAddress: Cache Flags not yet supported. "
|
Flags & (MMDBG_COPY_CACHED |
|
||||||
"Flags: 0x%lx\n", Flags & (MMDBG_COPY_CACHED |
|
|
||||||
MMDBG_COPY_UNCACHED |
|
MMDBG_COPY_UNCACHED |
|
||||||
MMDBG_COPY_WRITE_COMBINED));
|
MMDBG_COPY_WRITE_COMBINED));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* Save the base address of our mapping page */
|
||||||
// Save the base address of our mapping page
|
|
||||||
//
|
|
||||||
MappingBaseAddress = MiPteToAddress(MmDebugPte);
|
MappingBaseAddress = MiPteToAddress(MmDebugPte);
|
||||||
|
|
||||||
//
|
/* Get the template */
|
||||||
// Get the template
|
|
||||||
//
|
|
||||||
TempPte = ValidKernelPte;
|
TempPte = ValidKernelPte;
|
||||||
|
|
||||||
//
|
/* Convert physical address to PFN */
|
||||||
// Convert physical address to PFN
|
|
||||||
//
|
|
||||||
Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT);
|
Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT);
|
||||||
|
|
||||||
/* Check if this could be an I/O mapping */
|
/* Check if this could be an I/O mapping */
|
||||||
if (!MiGetPfnEntry(Pfn))
|
if (!MiGetPfnEntry(Pfn))
|
||||||
{
|
{
|
||||||
//
|
/* FIXME: We don't support this yet */
|
||||||
// FIXME: We don't support this yet
|
|
||||||
//
|
|
||||||
KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
|
KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
|
||||||
"PFN: 0x%I64x\n", (ULONG64)Pfn);
|
"PFN: 0x%I64x\n",
|
||||||
|
(ULONG64)Pfn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//
|
/* Set the PFN in the PTE */
|
||||||
// Set the PFN in the PTE
|
|
||||||
//
|
|
||||||
TempPte.u.Hard.PageFrameNumber = Pfn;
|
TempPte.u.Hard.PageFrameNumber = Pfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* Map the PTE and invalidate its TLB entry */
|
||||||
// Map the PTE and invalidate its TLB entry
|
|
||||||
//
|
|
||||||
*MmDebugPte = TempPte;
|
*MmDebugPte = TempPte;
|
||||||
KeInvalidateTlbEntry(MappingBaseAddress);
|
KeInvalidateTlbEntry(MappingBaseAddress);
|
||||||
|
|
||||||
//
|
/* Calculate and return the virtual offset into our mapping page */
|
||||||
// Calculate and return the virtual offset into our mapping page
|
|
||||||
//
|
|
||||||
return (PVOID)((ULONG_PTR)MappingBaseAddress +
|
return (PVOID)((ULONG_PTR)MappingBaseAddress +
|
||||||
BYTE_OFFSET(PhysicalAddress));
|
BYTE_OFFSET(PhysicalAddress));
|
||||||
}
|
}
|
||||||
|
@ -127,20 +104,23 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MiDbgUnTranslatePhysicalAddress(VOID)
|
MiDbgUnTranslatePhysicalAddress(VOID)
|
||||||
{
|
{
|
||||||
PVOID MappingBaseAddress = MiPteToAddress(MmDebugPte);
|
PVOID MappingBaseAddress;
|
||||||
|
|
||||||
//
|
/* The address must still be valid at this point */
|
||||||
// The address must still be valid at this point
|
MappingBaseAddress = MiPteToAddress(MmDebugPte);
|
||||||
//
|
|
||||||
ASSERT(MmIsAddressValid(MappingBaseAddress));
|
ASSERT(MmIsAddressValid(MappingBaseAddress));
|
||||||
|
|
||||||
//
|
/* Clear the mapping PTE and invalidate its TLB entry */
|
||||||
// Clear the mapping PTE and invalidate its TLB entry
|
|
||||||
//
|
|
||||||
MmDebugPte->u.Long = 0;
|
MmDebugPte->u.Long = 0;
|
||||||
KeInvalidateTlbEntry(MappingBaseAddress);
|
KeInvalidateTlbEntry(MappingBaseAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// We handle 8-byte requests at most
|
||||||
|
//
|
||||||
|
C_ASSERT(MMDBG_COPY_MAX_SIZE == 8);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmDbgCopyMemory(IN ULONG64 Address,
|
MmDbgCopyMemory(IN ULONG64 Address,
|
||||||
|
@ -148,102 +128,80 @@ MmDbgCopyMemory(IN ULONG64 Address,
|
||||||
IN ULONG Size,
|
IN ULONG Size,
|
||||||
IN ULONG Flags)
|
IN ULONG Flags)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
|
||||||
PVOID TargetAddress;
|
PVOID TargetAddress;
|
||||||
ULONG64 PhysicalAddress;
|
ULONG64 PhysicalAddress;
|
||||||
PMMPTE PointerPte;
|
PMMPTE PointerPte;
|
||||||
|
PVOID CopyDestination, CopySource;
|
||||||
|
|
||||||
//
|
/* No local kernel debugging support yet, so don't worry about locking */
|
||||||
// No local kernel debugging support yet, so don't worry about locking
|
|
||||||
//
|
|
||||||
ASSERT(Flags & MMDBG_COPY_UNSAFE);
|
ASSERT(Flags & MMDBG_COPY_UNSAFE);
|
||||||
|
|
||||||
//
|
/* We only handle 1, 2, 4 and 8 byte requests */
|
||||||
// We only handle 1, 2, 4 and 8 byte requests
|
|
||||||
//
|
|
||||||
if ((Size != 1) &&
|
if ((Size != 1) &&
|
||||||
(Size != 2) &&
|
(Size != 2) &&
|
||||||
(Size != 4) &&
|
(Size != 4) &&
|
||||||
(Size != MMDBG_COPY_MAX_SIZE))
|
(Size != 8))
|
||||||
{
|
{
|
||||||
//
|
/* Invalid size, fail */
|
||||||
// Invalid size, fail
|
KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n",
|
||||||
//
|
Size);
|
||||||
KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n", Size);
|
|
||||||
return STATUS_INVALID_PARAMETER_3;
|
return STATUS_INVALID_PARAMETER_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* The copy must be aligned */
|
||||||
// The copy must be aligned
|
|
||||||
//
|
|
||||||
if ((Address & (Size - 1)) != 0)
|
if ((Address & (Size - 1)) != 0)
|
||||||
{
|
{
|
||||||
//
|
/* Not allowing unaligned access */
|
||||||
// Fail
|
|
||||||
//
|
|
||||||
KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
|
KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
|
||||||
Address, Size);
|
Address,
|
||||||
|
Size);
|
||||||
return STATUS_INVALID_PARAMETER_3;
|
return STATUS_INVALID_PARAMETER_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* Check for physical or virtual copy */
|
||||||
// Check if this is physical or virtual copy
|
|
||||||
//
|
|
||||||
if (Flags & MMDBG_COPY_PHYSICAL)
|
if (Flags & MMDBG_COPY_PHYSICAL)
|
||||||
{
|
{
|
||||||
//
|
/* Physical: translate and map it to our mapping space */
|
||||||
// Physical: translate and map it to our mapping space
|
TargetAddress = MiDbgTranslatePhysicalAddress(Address,
|
||||||
//
|
Flags);
|
||||||
TargetAddress = MiDbgTranslatePhysicalAddress(Address, Flags);
|
|
||||||
|
|
||||||
//
|
/* Check if translation failed */
|
||||||
// Check if translation failed
|
|
||||||
//
|
|
||||||
if (!TargetAddress)
|
if (!TargetAddress)
|
||||||
{
|
{
|
||||||
//
|
/* Fail */
|
||||||
// Fail
|
KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address %I64x\n",
|
||||||
//
|
Address);
|
||||||
KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address "
|
|
||||||
"%I64x\n", Address);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* The address we received must be valid! */
|
||||||
// The address we received must be valid!
|
|
||||||
//
|
|
||||||
ASSERT(MmIsAddressValid(TargetAddress));
|
ASSERT(MmIsAddressValid(TargetAddress));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//
|
/* Virtual; truncate it to avoid casts later down */
|
||||||
// Virtual; truncate it to avoid casts later down
|
|
||||||
//
|
|
||||||
TargetAddress = (PVOID)(ULONG_PTR)Address;
|
TargetAddress = (PVOID)(ULONG_PTR)Address;
|
||||||
|
|
||||||
//
|
/* Make sure address is valid */
|
||||||
// Check if the address is invalid
|
|
||||||
//
|
|
||||||
if (!MmIsAddressValid(TargetAddress))
|
if (!MmIsAddressValid(TargetAddress))
|
||||||
{
|
{
|
||||||
//
|
/* Fail */
|
||||||
// Fail
|
KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Virtual Address 0x%p\n",
|
||||||
//
|
|
||||||
KdpDprintf("MmDbgCopyMemory: Failing %s for invalid "
|
|
||||||
"Virtual Address 0x%p\n",
|
|
||||||
Flags & MMDBG_COPY_WRITE ? "write" : "read",
|
Flags & MMDBG_COPY_WRITE ? "write" : "read",
|
||||||
TargetAddress);
|
TargetAddress);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* Not handling session space correctly yet */
|
||||||
// No session space support yet
|
if (MmIsSessionAddress(TargetAddress))
|
||||||
//
|
{
|
||||||
ASSERT(MmIsSessionAddress(TargetAddress) == FALSE);
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
/* If we are going to write to the address, then check if its writable */
|
/* If we are going to write to the address, then check if its writable */
|
||||||
PointerPte = MiAddressToPte(TargetAddress);
|
PointerPte = MiAddressToPte(TargetAddress);
|
||||||
if ((Flags & MMDBG_COPY_WRITE) && !MI_IS_PAGE_WRITEABLE(PointerPte))
|
if ((Flags & MMDBG_COPY_WRITE) &&
|
||||||
|
(!MI_IS_PAGE_WRITEABLE(PointerPte)))
|
||||||
{
|
{
|
||||||
/* Not writable, we need to do a physical copy */
|
/* Not writable, we need to do a physical copy */
|
||||||
Flags |= MMDBG_COPY_PHYSICAL;
|
Flags |= MMDBG_COPY_PHYSICAL;
|
||||||
|
@ -253,73 +211,73 @@ MmDbgCopyMemory(IN ULONG64 Address,
|
||||||
PhysicalAddress += BYTE_OFFSET(Address);
|
PhysicalAddress += BYTE_OFFSET(Address);
|
||||||
|
|
||||||
/* Translate the physical address */
|
/* Translate the physical address */
|
||||||
TargetAddress = MiDbgTranslatePhysicalAddress(PhysicalAddress, Flags);
|
TargetAddress = MiDbgTranslatePhysicalAddress(PhysicalAddress,
|
||||||
|
Flags);
|
||||||
|
|
||||||
/* Check if translation failed */
|
/* Check if translation failed */
|
||||||
if (!TargetAddress)
|
if (!TargetAddress)
|
||||||
{
|
{
|
||||||
/* Fail */
|
/* Fail */
|
||||||
KdpDprintf("MmDbgCopyMemory: Failed to translate for write "
|
KdpDprintf("MmDbgCopyMemory: Failed to translate for write %I64x (%I64x)\n",
|
||||||
"%I64x (%I64x)\n", PhysicalAddress, Address);
|
PhysicalAddress,
|
||||||
|
Address);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* Check what kind of operation this is */
|
||||||
// Use SEH to try to catch anything else somewhat cleanly
|
|
||||||
//
|
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Check if this is read or write
|
|
||||||
//
|
|
||||||
if (Flags & MMDBG_COPY_WRITE)
|
if (Flags & MMDBG_COPY_WRITE)
|
||||||
{
|
{
|
||||||
//
|
/* Write */
|
||||||
// Do the write
|
CopyDestination = TargetAddress;
|
||||||
//
|
CopySource = Buffer;
|
||||||
RtlCopyMemory(TargetAddress,
|
|
||||||
Buffer,
|
|
||||||
Size);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//
|
/* Read */
|
||||||
// Do the read
|
CopyDestination = Buffer;
|
||||||
//
|
CopySource = TargetAddress;
|
||||||
RtlCopyMemory(Buffer,
|
|
||||||
TargetAddress,
|
|
||||||
Size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* Do the copy */
|
||||||
// Copy succeeded
|
switch (Size)
|
||||||
//
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
{
|
||||||
//
|
case 1:
|
||||||
// Get the exception code
|
|
||||||
//
|
|
||||||
Status = _SEH2_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
|
|
||||||
//
|
/* 1 byte */
|
||||||
// Get rid of the mapping if this was a physical copy
|
*(PUCHAR)CopyDestination = *(PUCHAR)CopySource;
|
||||||
//
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
|
||||||
|
/* 2 bytes */
|
||||||
|
*(PUSHORT)CopyDestination = *(PUSHORT)CopySource;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
|
||||||
|
/* 4 bytes */
|
||||||
|
*(PULONG)CopyDestination = *(PULONG)CopySource;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
|
||||||
|
/* 8 bytes */
|
||||||
|
*(PULONGLONG)CopyDestination = *(PULONGLONG)CopySource;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Size is sanitized above */
|
||||||
|
DEFAULT_UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of the mapping if this was a physical copy */
|
||||||
if (Flags & MMDBG_COPY_PHYSICAL)
|
if (Flags & MMDBG_COPY_PHYSICAL)
|
||||||
{
|
{
|
||||||
//
|
/* Unmap and flush it */
|
||||||
// Unmap and flush it
|
|
||||||
//
|
|
||||||
MiDbgUnTranslatePhysicalAddress();
|
MiDbgUnTranslatePhysicalAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* And we are done */
|
||||||
// Return status to caller
|
return STATUS_SUCCESS;
|
||||||
//
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue