def Parse()

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