📄 mm.c
字号:
// Make sure we didn't get a bogus pointer
if (MemoryPointer >= (PVOID)(TotalPagesInLookupTable * MM_PAGE_SIZE))
{
BugCheck((DPRINT_MEMORY, "Bogus memory pointer (0x%x) passed to MmFreeMemory()\n", MemoryPointer));
}
#endif // DBG
// Find out the page number of the first
// page of memory they allocated
PageNumber = MmGetPageNumberFromAddress(MemoryPointer);
PageCount = RealPageLookupTable[PageNumber].PageAllocationLength;
#ifdef DBG
// Make sure we didn't get a bogus pointer
if ((PageCount < 1) || (PageCount > (TotalPagesInLookupTable - PageNumber)))
{
BugCheck((DPRINT_MEMORY, "Invalid page count in lookup table. PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
}
// Loop through our array check all the pages
// to make sure they are allocated with a length of 0
for (Idx=PageNumber+1; Idx<(PageNumber + PageCount); Idx++)
{
if ((RealPageLookupTable[Idx].PageAllocated == LoaderFree) ||
(RealPageLookupTable[Idx].PageAllocationLength != 0))
{
BugCheck((DPRINT_MEMORY, "Invalid page entry in lookup table, PageAllocated should = 1 and PageAllocationLength should = 0 because this is not the first block in the run. PageLookupTable[%d].PageAllocated = %d PageLookupTable[%d].PageAllocationLength = %d\n", PageNumber, RealPageLookupTable[PageNumber].PageAllocated, PageNumber, RealPageLookupTable[PageNumber].PageAllocationLength));
}
}
#endif
/* If this allocation is only a single page, it could be a sub-allocated page.
* Just don't free it */
if (1 == PageCount)
{
return;
}
// Loop through our array and mark all the
// blocks as free
for (Idx=PageNumber; Idx<(PageNumber + PageCount); Idx++)
{
RealPageLookupTable[Idx].PageAllocated = LoaderFree;
RealPageLookupTable[Idx].PageAllocationLength = 0;
}
FreePagesInLookupTable += PageCount;
#ifdef DBG
DecrementAllocationCount();
DbgPrint((DPRINT_MEMORY, "Freed %d pages of memory starting at page %d. AllocationCount: %d\n", PageCount, PageNumber, AllocationCount));
//VerifyHeap();
#endif // DBG
}
#ifdef DBG
VOID VerifyHeap(VOID)
{
ULONG Idx;
ULONG Idx2;
ULONG Count;
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
if (DUMP_MEM_MAP_ON_VERIFY)
{
DumpMemoryAllocMap();
}
// Loop through the array and verify that
// everything is kosher
for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
{
// Check if this block is allocated
if (RealPageLookupTable[Idx].PageAllocated != LoaderFree)
{
// This is the first block in the run so it
// had better have a length that is within range
if ((RealPageLookupTable[Idx].PageAllocationLength < 1) || (RealPageLookupTable[Idx].PageAllocationLength > (TotalPagesInLookupTable - Idx)))
{
BugCheck((DPRINT_MEMORY, "Allocation length out of range in heap table. PageLookupTable[Idx].PageAllocationLength = %d\n", RealPageLookupTable[Idx].PageAllocationLength));
}
// Now go through and verify that the rest of
// this run has the blocks marked allocated
// with a length of zero but don't check the
// first one because we already did
Count = RealPageLookupTable[Idx].PageAllocationLength;
for (Idx2=1; Idx2<Count; Idx2++)
{
// Make sure it's allocated
if (RealPageLookupTable[Idx + Idx2].PageAllocated == LoaderFree)
{
BugCheck((DPRINT_MEMORY, "Lookup table indicates hole in memory allocation. RealPageLookupTable[Idx + Idx2].PageAllocated == 0\n"));
}
// Make sure the length is zero
if (RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0)
{
BugCheck((DPRINT_MEMORY, "Allocation chain has non-zero value in non-first block in lookup table. RealPageLookupTable[Idx + Idx2].PageAllocationLength != 0\n"));
}
}
// Move on to the next run
Idx += (Count - 1);
}
else
{
// Nope, not allocated so make sure the length is zero
if (RealPageLookupTable[Idx].PageAllocationLength != 0)
{
BugCheck((DPRINT_MEMORY, "Free block is start of memory allocation. RealPageLookupTable[Idx].PageAllocationLength != 0\n"));
}
}
}
}
VOID DumpMemoryAllocMap(VOID)
{
ULONG Idx;
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
DbgPrint((DPRINT_MEMORY, "----------- Memory Allocation Bitmap -----------\n"));
for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
{
if ((Idx % 32) == 0)
{
DbgPrint((DPRINT_MEMORY, "\n"));
DbgPrint((DPRINT_MEMORY, "%x:\t", (Idx * MM_PAGE_SIZE)));
}
else if ((Idx % 4) == 0)
{
DbgPrint((DPRINT_MEMORY, " "));
}
switch (RealPageLookupTable[Idx].PageAllocated)
{
case LoaderFree:
DbgPrint((DPRINT_MEMORY, "*"));
break;
case LoaderBad:
DbgPrint((DPRINT_MEMORY, "-"));
break;
case LoaderLoadedProgram:
DbgPrint((DPRINT_MEMORY, "O"));
break;
case LoaderFirmwareTemporary:
DbgPrint((DPRINT_MEMORY, "T"));
break;
case LoaderFirmwarePermanent:
DbgPrint((DPRINT_MEMORY, "P"));
break;
case LoaderOsloaderHeap:
DbgPrint((DPRINT_MEMORY, "H"));
break;
case LoaderOsloaderStack:
DbgPrint((DPRINT_MEMORY, "S"));
break;
case LoaderSystemCode:
DbgPrint((DPRINT_MEMORY, "K"));
break;
case LoaderHalCode:
DbgPrint((DPRINT_MEMORY, "L"));
break;
case LoaderBootDriver:
DbgPrint((DPRINT_MEMORY, "B"));
break;
case LoaderStartupPcrPage:
DbgPrint((DPRINT_MEMORY, "G"));
break;
case LoaderRegistryData:
DbgPrint((DPRINT_MEMORY, "R"));
break;
case LoaderMemoryData:
DbgPrint((DPRINT_MEMORY, "M"));
break;
case LoaderNlsData:
DbgPrint((DPRINT_MEMORY, "N"));
break;
case LoaderSpecialMemory:
DbgPrint((DPRINT_MEMORY, "C"));
break;
default:
DbgPrint((DPRINT_MEMORY, "?"));
break;
}
}
DbgPrint((DPRINT_MEMORY, "\n"));
}
VOID IncrementAllocationCount(VOID)
{
AllocationCount++;
}
VOID DecrementAllocationCount(VOID)
{
AllocationCount--;
}
VOID MemAllocTest(VOID)
{
PVOID MemPtr1;
PVOID MemPtr2;
PVOID MemPtr3;
PVOID MemPtr4;
PVOID MemPtr5;
MemPtr1 = MmAllocateMemory(4096);
printf("MemPtr1: 0x%x\n", (int)MemPtr1);
MachConsGetCh();
MemPtr2 = MmAllocateMemory(4096);
printf("MemPtr2: 0x%x\n", (int)MemPtr2);
MachConsGetCh();
MemPtr3 = MmAllocateMemory(4096);
printf("MemPtr3: 0x%x\n", (int)MemPtr3);
DumpMemoryAllocMap();
VerifyHeap();
MachConsGetCh();
MmFreeMemory(MemPtr2);
MachConsGetCh();
MemPtr4 = MmAllocateMemory(2048);
printf("MemPtr4: 0x%x\n", (int)MemPtr4);
MachConsGetCh();
MemPtr5 = MmAllocateMemory(4096);
printf("MemPtr5: 0x%x\n", (int)MemPtr5);
MachConsGetCh();
}
#endif // DBG
ULONG GetSystemMemorySize(VOID)
{
return (TotalPagesInLookupTable * MM_PAGE_SIZE);
}
PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTableAddress;
*NoEntries = TotalPagesInLookupTable;
return RealPageLookupTable;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -