in UefiTestingPkg/AuditTests/PagingAudit/Windows/PagingReportGenerator.py [0:0]
def Parse(self):
#Get Info Files
InfoFileList = glob.glob(os.path.join(self.DatFolderPath, "*MemoryInfo*.dat"))
Pte1gbFileList = glob.glob(os.path.join(self.DatFolderPath, "*1G*.dat"))
Pte2mbFileList = glob.glob(os.path.join(self.DatFolderPath, "*2M*.dat"))
Pte4kbFileList = glob.glob(os.path.join(self.DatFolderPath, "*4K*.dat"))
MatFileList = glob.glob(os.path.join(self.DatFolderPath, "*MAT*.dat"))
GuardPageFileList = glob.glob(os.path.join(self.DatFolderPath, "*GuardPage*.dat"))
logging.debug("Found %d Info Files" % len(InfoFileList))
logging.debug("Found %d 1gb Page Files" % len(Pte1gbFileList))
logging.debug("Found %d 2mb Page Files" % len(Pte2mbFileList))
logging.debug("Found %d 4kb Page Files" % len(Pte4kbFileList))
logging.debug("Found %d MAT Files" % len(MatFileList))
logging.debug("Found %d GuardPage Files" % len(GuardPageFileList))
# Parse each file, keeping PTEs and "Memory Ranges" separate
# Memory ranges are either "memory descriptions" for memory map types and TSEG
# or "memory contents" for loaded image information or IDT/GDT
for info in InfoFileList:
self.MemoryRangeInfo.extend(ParseInfoFile(info))
for mr in self.MemoryRangeInfo:
if mr.AddressBitwidth is not None:
if self.AddressBits == 0:
self.AddressBits = (1 << mr.AddressBitwidth) - 1
self.MemoryRangeInfo.remove(mr)
elif self.AddressBits != (1 << mr.AddressBitwidth) - 1:
self.ErrorMsg.append("Bitwidth discrepancy, %d and %d. Should not proceed with mixed bitwidth files in the same folder", self.AddressBits, (1 << mr.AddressBitwidth) - 1)
logging.error("Bitwidth discrepancy, %d and %d. Should not proceed with mixed bitwidth files in the same folder", self.AddressBits, (1 << mr.AddressBitwidth) - 1)
else:
self.MemoryRangeInfo.remove(mr)
if self.AddressBits == 0:
self.ErrorMsg.append("Did not find bitwidth from memory information file. Assuming 39 here and the results may not be accurate")
self.AddressBits = (1 << 39) - 1
for pte1g in Pte1gbFileList:
self.PageDirectoryInfo.extend(Parse1gPages(pte1g, self.AddressBits))
for pte2m in Pte2mbFileList:
self.PageDirectoryInfo.extend(Parse2mPages(pte2m, self.AddressBits))
for pte4k in Pte4kbFileList:
self.PageDirectoryInfo.extend(Parse4kPages(pte4k, self.AddressBits))
for guardpage in GuardPageFileList:
self.PageDirectoryInfo.extend(ParseInfoFile(guardpage))
for mat in MatFileList:
self.MemoryAttributesTable.extend(ParseInfoFile(mat))
if len(self.PageDirectoryInfo) == 0:
self.ErrorMsg.append("No Memory Range info found in PTE files")
else:
# Sort in descending order
self.PageDirectoryInfo.sort(key=operator.attrgetter('PhysicalStart'))
#check for Page Table Overlap - this is an error
index =0
maxindex = len(self.PageDirectoryInfo) -1
while index < maxindex: #this will allow all comparisions to work
if(self.PageDirectoryInfo[index].overlap(self.PageDirectoryInfo[index+1])):
self.ErrorMsg.append("Page Table Entry Overlap. Index %d Overlapping %d at StartAddress 0x%X" %
(index, index+1, self.PageDirectoryInfo[index].PhysicalStart))
logging.error("PTE overlap index %d and %d. Base Address = 0x%x", index, index+1, self.PageDirectoryInfo[index].PhysicalStart)
index += 1
if len(self.MemoryRangeInfo) == 0:
self.ErrorMsg.append("No Memory Range info found in Info files")
# Matching memory ranges up to page table entries
# use index based iteration so that page splitting
# is supported.
index = 0
while index < len(self.PageDirectoryInfo):
pte = self.PageDirectoryInfo[index]
for mr in self.MemoryRangeInfo:
if pte.overlap(mr):
if mr.MemoryType is not None:
if (pte.PhysicalStart < mr.PhysicalStart):
next = pte.split(mr.PhysicalStart-1)
self.PageDirectoryInfo.insert(index+1, next)
#decrement the index so that we process this partial PTE again
# since we are breaking from the MemoryRange Loop
index -= 1
break
if (pte.PhysicalEnd > mr.PhysicalEnd):
next = pte.split(mr.PhysicalEnd)
self.PageDirectoryInfo.insert(index +1, next)
if pte.MemoryType is None:
pte.MemoryType = mr.MemoryType
else:
logging.error("Multiple memory types found for one region " + pte.pteDebugStr() +" " + mr.MemoryRangeToString())
self.ErrorMsg.append("Multiple memory types found for one region. Base: 0x%X. EFI Memory Type: %d and %d"% (pte.PhysicalStart, pte.MemoryType,mr.MemoryType))
if mr.ImageName is not None:
if pte.ImageName is None:
pte.ImageName = mr.ImageName
else:
self.ErrorMsg.append("Multiple memory contents found for one region. Base: 0x%X. Memory Contents: %s and %s" % (pte.PhysicalStart, pte.ImageName, mr.ImageName ))
logging.error("Multiple memory contents found for one region " +pte.pteDebugStr() + " " + mr.LoadedImageEntryToString())
if mr.SystemMemoryType is not None:
if pte.SystemMemoryType is None:
pte.SystemMemoryType = mr.SystemMemoryType
else:
self.ErrorMsg.append("Multiple System Memory types found for one region. Base: 0x%X. EFI Memory Type: %s and %s."% (pte.PhysicalStart,pte.SystemMemoryType, mr.SystemMemoryType))
logging.error("Multiple system memory types found for one region " +pte.pteDebugStr() + " " + mr.LoadedImageEntryToString())
for MatEntry in self.MemoryAttributesTable:
if pte.overlap(MatEntry):
pte.Attribute = MatEntry.Attribute
index += 1
# Combining adjacent PTEs that have the same attributes.
index = 0
while index < (len(self.PageDirectoryInfo) - 1):
currentPte = self.PageDirectoryInfo[index]
nextPte = self.PageDirectoryInfo[index + 1]
if currentPte.sameAttributes(nextPte):
currentPte.grow(nextPte)
del self.PageDirectoryInfo[index + 1]
else:
index += 1
return 0