]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c
MdeModulePkg/DxeCore: merge properties table routines into MAT handling
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / PropertiesTable.c
diff --git a/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c b/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c
deleted file mode 100644 (file)
index 6ee8a8a..0000000
+++ /dev/null
@@ -1,1288 +0,0 @@
-/** @file\r
-  UEFI PropertiesTable support\r
-\r
-Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <PiDxe.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/DxeServicesTableLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/PcdLib.h>\r
-\r
-#include <Guid/EventGroup.h>\r
-#include <Protocol/DxeSmmReadyToLock.h>\r
-\r
-#include <Library/PeCoffLib.h>\r
-#include <Library/PeCoffGetEntryPointLib.h>\r
-#include <Protocol/Runtime.h>\r
-\r
-#include "DxeMain.h"\r
-#include "HeapGuard.h"\r
-\r
-#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
-  ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))\r
-\r
-#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')\r
-\r
-typedef struct {\r
-  UINT32                 Signature;\r
-  UINTN                  ImageRecordCount;\r
-  UINTN                  CodeSegmentCountMax;\r
-  LIST_ENTRY             ImageRecordList;\r
-} IMAGE_PROPERTIES_PRIVATE_DATA;\r
-\r
-IMAGE_PROPERTIES_PRIVATE_DATA  mImagePropertiesPrivateData = {\r
-  IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE,\r
-  0,\r
-  0,\r
-  INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData.ImageRecordList)\r
-};\r
-\r
-EFI_LOCK           mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);\r
-\r
-BOOLEAN            mPropertiesTableEndOfDxe = FALSE;\r
-\r
-extern BOOLEAN     mMemoryAttributesTableEnable;\r
-\r
-//\r
-// Below functions are for MemoryMap\r
-//\r
-\r
-/**\r
-  Converts a number of EFI_PAGEs to a size in bytes.\r
-\r
-  NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.\r
-\r
-  @param  Pages     The number of EFI_PAGES.\r
-\r
-  @return  The number of bytes associated with the number of EFI_PAGEs specified\r
-           by Pages.\r
-**/\r
-STATIC\r
-UINT64\r
-EfiPagesToSize (\r
-  IN UINT64 Pages\r
-  )\r
-{\r
-  return LShiftU64 (Pages, EFI_PAGE_SHIFT);\r
-}\r
-\r
-/**\r
-  Converts a size, in bytes, to a number of EFI_PAGESs.\r
-\r
-  NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.\r
-\r
-  @param  Size      A size in bytes.\r
-\r
-  @return  The number of EFI_PAGESs associated with the number of bytes specified\r
-           by Size.\r
-\r
-**/\r
-STATIC\r
-UINT64\r
-EfiSizeToPages (\r
-  IN UINT64 Size\r
-  )\r
-{\r
-  return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);\r
-}\r
-\r
-/**\r
-  Acquire memory lock on mPropertiesTableLock.\r
-**/\r
-STATIC\r
-VOID\r
-CoreAcquirePropertiesTableLock (\r
-  VOID\r
-  )\r
-{\r
-  CoreAcquireLock (&mPropertiesTableLock);\r
-}\r
-\r
-/**\r
-  Release memory lock on mPropertiesTableLock.\r
-**/\r
-STATIC\r
-VOID\r
-CoreReleasePropertiesTableLock (\r
-  VOID\r
-  )\r
-{\r
-  CoreReleaseLock (&mPropertiesTableLock);\r
-}\r
-\r
-/**\r
-  Sort memory map entries based upon PhysicalStart, from low to high.\r
-\r
-  @param  MemoryMap              A pointer to the buffer in which firmware places\r
-                                 the current memory map.\r
-  @param  MemoryMapSize          Size, in bytes, of the MemoryMap buffer.\r
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
-**/\r
-STATIC\r
-VOID\r
-SortMemoryMap (\r
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
-  IN UINTN                      MemoryMapSize,\r
-  IN UINTN                      DescriptorSize\r
-  )\r
-{\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEntry;\r
-  EFI_MEMORY_DESCRIPTOR       *NextMemoryMapEntry;\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEnd;\r
-  EFI_MEMORY_DESCRIPTOR       TempMemoryMap;\r
-\r
-  MemoryMapEntry = MemoryMap;\r
-  NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
-  MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);\r
-  while (MemoryMapEntry < MemoryMapEnd) {\r
-    while (NextMemoryMapEntry < MemoryMapEnd) {\r
-      if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {\r
-        CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR));\r
-        CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR));\r
-        CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof(EFI_MEMORY_DESCRIPTOR));\r
-      }\r
-\r
-      NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
-    }\r
-\r
-    MemoryMapEntry      = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
-    NextMemoryMapEntry  = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  Merge continous memory map entries whose have same attributes.\r
-\r
-  @param  MemoryMap              A pointer to the buffer in which firmware places\r
-                                 the current memory map.\r
-  @param  MemoryMapSize          A pointer to the size, in bytes, of the\r
-                                 MemoryMap buffer. On input, this is the size of\r
-                                 the current memory map.  On output,\r
-                                 it is the size of new memory map after merge.\r
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
-**/\r
-VOID\r
-MergeMemoryMap (\r
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
-  IN OUT UINTN                  *MemoryMapSize,\r
-  IN UINTN                      DescriptorSize\r
-  )\r
-{\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEntry;\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEnd;\r
-  UINT64                      MemoryBlockLength;\r
-  EFI_MEMORY_DESCRIPTOR       *NewMemoryMapEntry;\r
-  EFI_MEMORY_DESCRIPTOR       *NextMemoryMapEntry;\r
-\r
-  MemoryMapEntry = MemoryMap;\r
-  NewMemoryMapEntry = MemoryMap;\r
-  MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + *MemoryMapSize);\r
-  while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {\r
-    CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR));\r
-    NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
-\r
-    do {\r
-      MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStart);\r
-      MemoryBlockLength = (UINT64) (EfiPagesToSize (NewMemoryMapEntry->NumberOfPages));\r
-      if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&\r
-          (NewMemoryMapEntry->Type == NextMemoryMapEntry->Type) &&\r
-          (NewMemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&\r
-          ((NewMemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) {\r
-        NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
-        NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
-        continue;\r
-      } else {\r
-        MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
-        break;\r
-      }\r
-    } while (TRUE);\r
-\r
-    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
-    NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);\r
-  }\r
-\r
-  *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap;\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  Enforce memory map attributes.\r
-  This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP.\r
-\r
-  @param  MemoryMap              A pointer to the buffer in which firmware places\r
-                                 the current memory map.\r
-  @param  MemoryMapSize          Size, in bytes, of the MemoryMap buffer.\r
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
-**/\r
-STATIC\r
-VOID\r
-EnforceMemoryMapAttribute (\r
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
-  IN UINTN                      MemoryMapSize,\r
-  IN UINTN                      DescriptorSize\r
-  )\r
-{\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEntry;\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEnd;\r
-\r
-  MemoryMapEntry = MemoryMap;\r
-  MemoryMapEnd   = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);\r
-  while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {\r
-    switch (MemoryMapEntry->Type) {\r
-    case EfiRuntimeServicesCode:\r
-      // do nothing\r
-      break;\r
-    case EfiRuntimeServicesData:\r
-    case EfiMemoryMappedIO:\r
-    case EfiMemoryMappedIOPortSpace:\r
-      MemoryMapEntry->Attribute |= EFI_MEMORY_XP;\r
-      break;\r
-    case EfiReservedMemoryType:\r
-    case EfiACPIMemoryNVS:\r
-      break;\r
-    }\r
-\r
-    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].\r
-\r
-  @param Buffer  Start Address\r
-  @param Length  Address length\r
-\r
-  @return first image record covered by [buffer, length]\r
-**/\r
-STATIC\r
-IMAGE_PROPERTIES_RECORD *\r
-GetImageRecordByAddress (\r
-  IN EFI_PHYSICAL_ADDRESS  Buffer,\r
-  IN UINT64                Length\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD    *ImageRecord;\r
-  LIST_ENTRY                 *ImageRecordLink;\r
-  LIST_ENTRY                 *ImageRecordList;\r
-\r
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;\r
-\r
-  for (ImageRecordLink = ImageRecordList->ForwardLink;\r
-       ImageRecordLink != ImageRecordList;\r
-       ImageRecordLink = ImageRecordLink->ForwardLink) {\r
-    ImageRecord = CR (\r
-                    ImageRecordLink,\r
-                    IMAGE_PROPERTIES_RECORD,\r
-                    Link,\r
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE\r
-                    );\r
-\r
-    if ((Buffer <= ImageRecord->ImageBase) &&\r
-        (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize)) {\r
-      return ImageRecord;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Set the memory map to new entries, according to one old entry,\r
-  based upon PE code section and data section in image record\r
-\r
-  @param  ImageRecord            An image record whose [ImageBase, ImageSize] covered\r
-                                 by old memory map entry.\r
-  @param  NewRecord              A pointer to several new memory map entries.\r
-                                 The caller gurantee the buffer size be 1 +\r
-                                 (SplitRecordCount * DescriptorSize) calculated\r
-                                 below.\r
-  @param  OldRecord              A pointer to one old memory map entry.\r
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
-**/\r
-STATIC\r
-UINTN\r
-SetNewRecord (\r
-  IN IMAGE_PROPERTIES_RECORD       *ImageRecord,\r
-  IN OUT EFI_MEMORY_DESCRIPTOR     *NewRecord,\r
-  IN EFI_MEMORY_DESCRIPTOR         *OldRecord,\r
-  IN UINTN                         DescriptorSize\r
-  )\r
-{\r
-  EFI_MEMORY_DESCRIPTOR                     TempRecord;\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION      *ImageRecordCodeSection;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionLink;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionEndLink;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionList;\r
-  UINTN                                     NewRecordCount;\r
-  UINT64                                    PhysicalEnd;\r
-  UINT64                                    ImageEnd;\r
-\r
-  CopyMem (&TempRecord, OldRecord, sizeof(EFI_MEMORY_DESCRIPTOR));\r
-  PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages);\r
-  NewRecordCount = 0;\r
-\r
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;\r
-\r
-  ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;\r
-  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;\r
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
-    ImageRecordCodeSection = CR (\r
-                               ImageRecordCodeSectionLink,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
-                               Link,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
-                               );\r
-    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
-\r
-    if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {\r
-      //\r
-      // DATA\r
-      //\r
-      NewRecord->Type          = TempRecord.Type;\r
-      NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
-      NewRecord->VirtualStart  = 0;\r
-      NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);\r
-      NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;\r
-      if (NewRecord->NumberOfPages != 0) {\r
-        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-        NewRecordCount ++;\r
-      }\r
-\r
-      //\r
-      // CODE\r
-      //\r
-      NewRecord->Type          = TempRecord.Type;\r
-      NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;\r
-      NewRecord->VirtualStart  = 0;\r
-      NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize);\r
-      NewRecord->Attribute     = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;\r
-      if (NewRecord->NumberOfPages != 0) {\r
-        NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-        NewRecordCount ++;\r
-      }\r
-\r
-      TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize));\r
-      TempRecord.NumberOfPages = EfiSizeToPages(PhysicalEnd - TempRecord.PhysicalStart);\r
-      if (TempRecord.NumberOfPages == 0) {\r
-        break;\r
-      }\r
-    }\r
-  }\r
-\r
-  ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;\r
-\r
-  //\r
-  // Final DATA\r
-  //\r
-  if (TempRecord.PhysicalStart < ImageEnd) {\r
-    NewRecord->Type          = TempRecord.Type;\r
-    NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
-    NewRecord->VirtualStart  = 0;\r
-    NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);\r
-    NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;\r
-    NewRecordCount ++;\r
-  }\r
-\r
-  return NewRecordCount;\r
-}\r
-\r
-/**\r
-  Return the max number of new splitted entries, according to one old entry,\r
-  based upon PE code section and data section.\r
-\r
-  @param  OldRecord              A pointer to one old memory map entry.\r
-\r
-  @retval  0 no entry need to be splitted.\r
-  @return  the max number of new splitted entries\r
-**/\r
-STATIC\r
-UINTN\r
-GetMaxSplitRecordCount (\r
-  IN EFI_MEMORY_DESCRIPTOR *OldRecord\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD *ImageRecord;\r
-  UINTN                   SplitRecordCount;\r
-  UINT64                  PhysicalStart;\r
-  UINT64                  PhysicalEnd;\r
-\r
-  SplitRecordCount = 0;\r
-  PhysicalStart = OldRecord->PhysicalStart;\r
-  PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize(OldRecord->NumberOfPages);\r
-\r
-  do {\r
-    ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);\r
-    if (ImageRecord == NULL) {\r
-      break;\r
-    }\r
-    SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1);\r
-    PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;\r
-  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));\r
-\r
-  if (SplitRecordCount != 0) {\r
-    SplitRecordCount--;\r
-  }\r
-\r
-  return SplitRecordCount;\r
-}\r
-\r
-/**\r
-  Split the memory map to new entries, according to one old entry,\r
-  based upon PE code section and data section.\r
-\r
-  @param  OldRecord              A pointer to one old memory map entry.\r
-  @param  NewRecord              A pointer to several new memory map entries.\r
-                                 The caller gurantee the buffer size be 1 +\r
-                                 (SplitRecordCount * DescriptorSize) calculated\r
-                                 below.\r
-  @param  MaxSplitRecordCount    The max number of splitted entries\r
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
-\r
-  @retval  0 no entry is splitted.\r
-  @return  the real number of splitted record.\r
-**/\r
-STATIC\r
-UINTN\r
-SplitRecord (\r
-  IN EFI_MEMORY_DESCRIPTOR     *OldRecord,\r
-  IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord,\r
-  IN UINTN                     MaxSplitRecordCount,\r
-  IN UINTN                     DescriptorSize\r
-  )\r
-{\r
-  EFI_MEMORY_DESCRIPTOR   TempRecord;\r
-  IMAGE_PROPERTIES_RECORD *ImageRecord;\r
-  IMAGE_PROPERTIES_RECORD *NewImageRecord;\r
-  UINT64                  PhysicalStart;\r
-  UINT64                  PhysicalEnd;\r
-  UINTN                   NewRecordCount;\r
-  UINTN                   TotalNewRecordCount;\r
-  BOOLEAN                 IsLastRecordData;\r
-\r
-  if (MaxSplitRecordCount == 0) {\r
-    CopyMem (NewRecord, OldRecord, DescriptorSize);\r
-    return 0;\r
-  }\r
-\r
-  TotalNewRecordCount = 0;\r
-\r
-  //\r
-  // Override previous record\r
-  //\r
-  CopyMem (&TempRecord, OldRecord, sizeof(EFI_MEMORY_DESCRIPTOR));\r
-  PhysicalStart = TempRecord.PhysicalStart;\r
-  PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages);\r
-\r
-  ImageRecord = NULL;\r
-  do {\r
-    NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);\r
-    if (NewImageRecord == NULL) {\r
-      //\r
-      // No more image covered by this range, stop\r
-      //\r
-      if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {\r
-        //\r
-        // If this is still address in this record, need record.\r
-        //\r
-        NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-        IsLastRecordData = FALSE;\r
-        if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {\r
-          IsLastRecordData = TRUE;\r
-        }\r
-        if (IsLastRecordData) {\r
-          //\r
-          // Last record is DATA, just merge it.\r
-          //\r
-          NewRecord->NumberOfPages = EfiSizeToPages(PhysicalEnd - NewRecord->PhysicalStart);\r
-        } else {\r
-          //\r
-          // Last record is CODE, create a new DATA entry.\r
-          //\r
-          NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-          NewRecord->Type          = TempRecord.Type;\r
-          NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
-          NewRecord->VirtualStart  = 0;\r
-          NewRecord->NumberOfPages = TempRecord.NumberOfPages;\r
-          NewRecord->Attribute     = TempRecord.Attribute | EFI_MEMORY_XP;\r
-          TotalNewRecordCount ++;\r
-        }\r
-      }\r
-      break;\r
-    }\r
-    ImageRecord = NewImageRecord;\r
-\r
-    //\r
-    // Set new record\r
-    //\r
-    NewRecordCount = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);\r
-    TotalNewRecordCount += NewRecordCount;\r
-    NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);\r
-\r
-    //\r
-    // Update PhysicalStart, in order to exclude the image buffer already splitted.\r
-    //\r
-    PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;\r
-    TempRecord.PhysicalStart = PhysicalStart;\r
-    TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);\r
-  } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));\r
-\r
-  //\r
-  // The logic in function SplitTable() ensures that TotalNewRecordCount will not be zero if the\r
-  // code reaches here.\r
-  //\r
-  ASSERT (TotalNewRecordCount != 0);\r
-  return TotalNewRecordCount - 1;\r
-}\r
-\r
-/**\r
-  Split the original memory map, and add more entries to describe PE code section and data section.\r
-  This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.\r
-  This function will merge entries with same attributes finally.\r
-\r
-  NOTE: It assumes PE code/data section are page aligned.\r
-  NOTE: It assumes enough entry is prepared for new memory map.\r
-\r
-  Split table:\r
-   +---------------+\r
-   | Record X      |\r
-   +---------------+\r
-   | Record RtCode |\r
-   +---------------+\r
-   | Record Y      |\r
-   +---------------+\r
-   ==>\r
-   +---------------+\r
-   | Record X      |\r
-   +---------------+ ----\r
-   | Record RtData |     |\r
-   +---------------+     |\r
-   | Record RtCode |     |-> PE/COFF1\r
-   +---------------+     |\r
-   | Record RtData |     |\r
-   +---------------+ ----\r
-   | Record RtData |     |\r
-   +---------------+     |\r
-   | Record RtCode |     |-> PE/COFF2\r
-   +---------------+     |\r
-   | Record RtData |     |\r
-   +---------------+ ----\r
-   | Record Y      |\r
-   +---------------+\r
-\r
-  @param  MemoryMapSize          A pointer to the size, in bytes, of the\r
-                                 MemoryMap buffer. On input, this is the size of\r
-                                 old MemoryMap before split. The actual buffer\r
-                                 size of MemoryMap is MemoryMapSize +\r
-                                 (AdditionalRecordCount * DescriptorSize) calculated\r
-                                 below. On output, it is the size of new MemoryMap\r
-                                 after split.\r
-  @param  MemoryMap              A pointer to the buffer in which firmware places\r
-                                 the current memory map.\r
-  @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
-**/\r
-STATIC\r
-VOID\r
-SplitTable (\r
-  IN OUT UINTN                  *MemoryMapSize,\r
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
-  IN UINTN                      DescriptorSize\r
-  )\r
-{\r
-  INTN        IndexOld;\r
-  INTN        IndexNew;\r
-  UINTN       MaxSplitRecordCount;\r
-  UINTN       RealSplitRecordCount;\r
-  UINTN       TotalSplitRecordCount;\r
-  UINTN       AdditionalRecordCount;\r
-\r
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;\r
-\r
-  TotalSplitRecordCount = 0;\r
-  //\r
-  // Let old record point to end of valid MemoryMap buffer.\r
-  //\r
-  IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;\r
-  //\r
-  // Let new record point to end of full MemoryMap buffer.\r
-  //\r
-  IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount;\r
-  for (; IndexOld >= 0; IndexOld--) {\r
-    MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize));\r
-    //\r
-    // Split this MemoryMap record\r
-    //\r
-    IndexNew -= MaxSplitRecordCount;\r
-    RealSplitRecordCount = SplitRecord (\r
-                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize),\r
-                             (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize),\r
-                             MaxSplitRecordCount,\r
-                             DescriptorSize\r
-                             );\r
-    //\r
-    // Adjust IndexNew according to real split.\r
-    //\r
-    CopyMem (\r
-      ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),\r
-      ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),\r
-      RealSplitRecordCount * DescriptorSize\r
-      );\r
-    IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;\r
-    TotalSplitRecordCount += RealSplitRecordCount;\r
-    IndexNew --;\r
-  }\r
-  //\r
-  // Move all records to the beginning.\r
-  //\r
-  CopyMem (\r
-    MemoryMap,\r
-    (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize,\r
-    (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize\r
-    );\r
-\r
-  *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;\r
-\r
-  //\r
-  // Sort from low to high (Just in case)\r
-  //\r
-  SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize);\r
-\r
-  //\r
-  // Set RuntimeData to XP\r
-  //\r
-  EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, DescriptorSize);\r
-\r
-  //\r
-  // Merge same type to save entry size\r
-  //\r
-  MergeMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize);\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  This function for GetMemoryMap() with properties table capability.\r
-\r
-  It calls original GetMemoryMap() to get the original memory map information. Then\r
-  plus the additional memory map entries for PE Code/Data seperation.\r
-\r
-  @param  MemoryMapSize          A pointer to the size, in bytes, of the\r
-                                 MemoryMap buffer. On input, this is the size of\r
-                                 the buffer allocated by the caller.  On output,\r
-                                 it is the size of the buffer returned by the\r
-                                 firmware  if the buffer was large enough, or the\r
-                                 size of the buffer needed  to contain the map if\r
-                                 the buffer was too small.\r
-  @param  MemoryMap              A pointer to the buffer in which firmware places\r
-                                 the current memory map.\r
-  @param  MapKey                 A pointer to the location in which firmware\r
-                                 returns the key for the current memory map.\r
-  @param  DescriptorSize         A pointer to the location in which firmware\r
-                                 returns the size, in bytes, of an individual\r
-                                 EFI_MEMORY_DESCRIPTOR.\r
-  @param  DescriptorVersion      A pointer to the location in which firmware\r
-                                 returns the version number associated with the\r
-                                 EFI_MEMORY_DESCRIPTOR.\r
-\r
-  @retval EFI_SUCCESS            The memory map was returned in the MemoryMap\r
-                                 buffer.\r
-  @retval EFI_BUFFER_TOO_SMALL   The MemoryMap buffer was too small. The current\r
-                                 buffer size needed to hold the memory map is\r
-                                 returned in MemoryMapSize.\r
-  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreGetMemoryMapWithSeparatedImageSection (\r
-  IN OUT UINTN                  *MemoryMapSize,\r
-  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
-  OUT UINTN                     *MapKey,\r
-  OUT UINTN                     *DescriptorSize,\r
-  OUT UINT32                    *DescriptorVersion\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINTN       OldMemoryMapSize;\r
-  UINTN       AdditionalRecordCount;\r
-\r
-  //\r
-  // If PE code/data is not aligned, just return.\r
-  //\r
-  if (!mMemoryAttributesTableEnable) {\r
-    return CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);\r
-  }\r
-\r
-  if (MemoryMapSize == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  CoreAcquirePropertiesTableLock ();\r
-\r
-  AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;\r
-\r
-  OldMemoryMapSize = *MemoryMapSize;\r
-  Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;\r
-  } else if (Status == EFI_SUCCESS) {\r
-    ASSERT (MemoryMap != NULL);\r
-    if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) {\r
-      *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;\r
-      //\r
-      // Need update status to buffer too small\r
-      //\r
-      Status = EFI_BUFFER_TOO_SMALL;\r
-    } else {\r
-      //\r
-      // Split PE code/data\r
-      //\r
-      SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);\r
-    }\r
-  }\r
-\r
-  CoreReleasePropertiesTableLock ();\r
-  return Status;\r
-}\r
-\r
-//\r
-// Below functions are for ImageRecord\r
-//\r
-\r
-/**\r
-  Set PropertiesTable according to PE/COFF image section alignment.\r
-\r
-  @param  SectionAlignment    PE/COFF section alignment\r
-**/\r
-STATIC\r
-VOID\r
-SetPropertiesTableSectionAlignment (\r
-  IN UINT32  SectionAlignment\r
-  )\r
-{\r
-  if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&\r
-      mMemoryAttributesTableEnable) {\r
-    DEBUG ((EFI_D_VERBOSE, "SetPropertiesTableSectionAlignment - Clear\n"));\r
-    mMemoryAttributesTableEnable = FALSE;\r
-  }\r
-}\r
-\r
-/**\r
-  Swap two code sections in image record.\r
-\r
-  @param  FirstImageRecordCodeSection    first code section in image record\r
-  @param  SecondImageRecordCodeSection   second code section in image record\r
-**/\r
-STATIC\r
-VOID\r
-SwapImageRecordCodeSection (\r
-  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION      *FirstImageRecordCodeSection,\r
-  IN IMAGE_PROPERTIES_RECORD_CODE_SECTION      *SecondImageRecordCodeSection\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION      TempImageRecordCodeSection;\r
-\r
-  TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase;\r
-  TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;\r
-\r
-  FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;\r
-  FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;\r
-\r
-  SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;\r
-  SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;\r
-}\r
-\r
-/**\r
-  Sort code section in image record, based upon CodeSegmentBase from low to high.\r
-\r
-  @param  ImageRecord    image record to be sorted\r
-**/\r
-VOID\r
-SortImageRecordCodeSection (\r
-  IN IMAGE_PROPERTIES_RECORD              *ImageRecord\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION      *ImageRecordCodeSection;\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION      *NextImageRecordCodeSection;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionLink;\r
-  LIST_ENTRY                                *NextImageRecordCodeSectionLink;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionEndLink;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionList;\r
-\r
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;\r
-\r
-  ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;\r
-  NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
-  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;\r
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
-    ImageRecordCodeSection = CR (\r
-                               ImageRecordCodeSectionLink,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
-                               Link,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
-                               );\r
-    while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
-      NextImageRecordCodeSection = CR (\r
-                                     NextImageRecordCodeSectionLink,\r
-                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
-                                     Link,\r
-                                     IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
-                                     );\r
-      if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {\r
-        SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);\r
-      }\r
-      NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;\r
-    }\r
-\r
-    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
-    NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
-  }\r
-}\r
-\r
-/**\r
-  Check if code section in image record is valid.\r
-\r
-  @param  ImageRecord    image record to be checked\r
-\r
-  @retval TRUE  image record is valid\r
-  @retval FALSE image record is invalid\r
-**/\r
-BOOLEAN\r
-IsImageRecordCodeSectionValid (\r
-  IN IMAGE_PROPERTIES_RECORD              *ImageRecord\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION      *ImageRecordCodeSection;\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION      *LastImageRecordCodeSection;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionLink;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionEndLink;\r
-  LIST_ENTRY                                *ImageRecordCodeSectionList;\r
-\r
-  DEBUG ((EFI_D_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));\r
-\r
-  ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;\r
-\r
-  ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;\r
-  ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;\r
-  LastImageRecordCodeSection = NULL;\r
-  while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
-    ImageRecordCodeSection = CR (\r
-                               ImageRecordCodeSectionLink,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
-                               Link,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
-                               );\r
-    if (ImageRecordCodeSection->CodeSegmentSize == 0) {\r
-      return FALSE;\r
-    }\r
-    if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {\r
-      return FALSE;\r
-    }\r
-    if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {\r
-      return FALSE;\r
-    }\r
-    if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {\r
-      return FALSE;\r
-    }\r
-    if (LastImageRecordCodeSection != NULL) {\r
-      if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {\r
-        return FALSE;\r
-      }\r
-    }\r
-\r
-    LastImageRecordCodeSection = ImageRecordCodeSection;\r
-    ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Swap two image records.\r
-\r
-  @param  FirstImageRecord   first image record.\r
-  @param  SecondImageRecord  second image record.\r
-**/\r
-STATIC\r
-VOID\r
-SwapImageRecord (\r
-  IN IMAGE_PROPERTIES_RECORD      *FirstImageRecord,\r
-  IN IMAGE_PROPERTIES_RECORD      *SecondImageRecord\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD      TempImageRecord;\r
-\r
-  TempImageRecord.ImageBase = FirstImageRecord->ImageBase;\r
-  TempImageRecord.ImageSize = FirstImageRecord->ImageSize;\r
-  TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;\r
-\r
-  FirstImageRecord->ImageBase = SecondImageRecord->ImageBase;\r
-  FirstImageRecord->ImageSize = SecondImageRecord->ImageSize;\r
-  FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;\r
-\r
-  SecondImageRecord->ImageBase = TempImageRecord.ImageBase;\r
-  SecondImageRecord->ImageSize = TempImageRecord.ImageSize;\r
-  SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;\r
-\r
-  SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);\r
-}\r
-\r
-/**\r
-  Sort image record based upon the ImageBase from low to high.\r
-**/\r
-STATIC\r
-VOID\r
-SortImageRecord (\r
-  VOID\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD      *ImageRecord;\r
-  IMAGE_PROPERTIES_RECORD      *NextImageRecord;\r
-  LIST_ENTRY                   *ImageRecordLink;\r
-  LIST_ENTRY                   *NextImageRecordLink;\r
-  LIST_ENTRY                   *ImageRecordEndLink;\r
-  LIST_ENTRY                   *ImageRecordList;\r
-\r
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;\r
-\r
-  ImageRecordLink = ImageRecordList->ForwardLink;\r
-  NextImageRecordLink = ImageRecordLink->ForwardLink;\r
-  ImageRecordEndLink = ImageRecordList;\r
-  while (ImageRecordLink != ImageRecordEndLink) {\r
-    ImageRecord = CR (\r
-                    ImageRecordLink,\r
-                    IMAGE_PROPERTIES_RECORD,\r
-                    Link,\r
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE\r
-                    );\r
-    while (NextImageRecordLink != ImageRecordEndLink) {\r
-      NextImageRecord = CR (\r
-                          NextImageRecordLink,\r
-                          IMAGE_PROPERTIES_RECORD,\r
-                          Link,\r
-                          IMAGE_PROPERTIES_RECORD_SIGNATURE\r
-                          );\r
-      if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {\r
-        SwapImageRecord (ImageRecord, NextImageRecord);\r
-      }\r
-      NextImageRecordLink = NextImageRecordLink->ForwardLink;\r
-    }\r
-\r
-    ImageRecordLink = ImageRecordLink->ForwardLink;\r
-    NextImageRecordLink = ImageRecordLink->ForwardLink;\r
-  }\r
-}\r
-\r
-/**\r
-  Insert image record.\r
-\r
-  @param  RuntimeImage    Runtime image information\r
-**/\r
-VOID\r
-InsertImageRecord (\r
-  IN EFI_RUNTIME_IMAGE_ENTRY  *RuntimeImage\r
-  )\r
-{\r
-  VOID                                 *ImageAddress;\r
-  EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
-  UINT32                               PeCoffHeaderOffset;\r
-  UINT32                               SectionAlignment;\r
-  EFI_IMAGE_SECTION_HEADER             *Section;\r
-  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;\r
-  UINT8                                *Name;\r
-  UINTN                                Index;\r
-  IMAGE_PROPERTIES_RECORD              *ImageRecord;\r
-  CHAR8                                *PdbPointer;\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
-\r
-  DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));\r
-  DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));\r
-\r
-  if (mPropertiesTableEndOfDxe) {\r
-    DEBUG ((DEBUG_INFO, "Do not insert runtime image record after EndOfDxe\n"));\r
-    return ;\r
-  }\r
-\r
-  ImageRecord = AllocatePool (sizeof(*ImageRecord));\r
-  if (ImageRecord == NULL) {\r
-    return ;\r
-  }\r
-  ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;\r
-\r
-  DEBUG ((EFI_D_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));\r
-\r
-  //\r
-  // Step 1: record whole region\r
-  //\r
-  ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase;\r
-  ImageRecord->ImageSize = RuntimeImage->ImageSize;\r
-\r
-  ImageAddress = RuntimeImage->ImageBase;\r
-\r
-  PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress);\r
-  if (PdbPointer != NULL) {\r
-    DEBUG ((EFI_D_VERBOSE, "  Image - %a\n", PdbPointer));\r
-  }\r
-\r
-  //\r
-  // Check PE/COFF image\r
-  //\r
-  DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress;\r
-  PeCoffHeaderOffset = 0;\r
-  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
-    PeCoffHeaderOffset = DosHdr->e_lfanew;\r
-  }\r
-\r
-  Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset);\r
-  if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
-    DEBUG ((EFI_D_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature));\r
-    // It might be image in SMM.\r
-    goto Finish;\r
-  }\r
-\r
-  //\r
-  // Get SectionAlignment\r
-  //\r
-  if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
-    SectionAlignment  = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
-  } else {\r
-    SectionAlignment  = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;\r
-  }\r
-\r
-  SetPropertiesTableSectionAlignment (SectionAlignment);\r
-  if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {\r
-    DEBUG ((EFI_D_WARN, "!!!!!!!!  InsertImageRecord - Section Alignment(0x%x) is not %dK  !!!!!!!!\n",\r
-      SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));\r
-    PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress);\r
-    if (PdbPointer != NULL) {\r
-      DEBUG ((EFI_D_WARN, "!!!!!!!!  Image - %a  !!!!!!!!\n", PdbPointer));\r
-    }\r
-    goto Finish;\r
-  }\r
-\r
-  Section = (EFI_IMAGE_SECTION_HEADER *) (\r
-               (UINT8 *) (UINTN) ImageAddress +\r
-               PeCoffHeaderOffset +\r
-               sizeof(UINT32) +\r
-               sizeof(EFI_IMAGE_FILE_HEADER) +\r
-               Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
-               );\r
-  ImageRecord->CodeSegmentCount = 0;\r
-  InitializeListHead (&ImageRecord->CodeSegmentList);\r
-  for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
-    Name = Section[Index].Name;\r
-    DEBUG ((\r
-      EFI_D_VERBOSE,\r
-      "  Section - '%c%c%c%c%c%c%c%c'\n",\r
-      Name[0],\r
-      Name[1],\r
-      Name[2],\r
-      Name[3],\r
-      Name[4],\r
-      Name[5],\r
-      Name[6],\r
-      Name[7]\r
-      ));\r
-\r
-    if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) {\r
-      DEBUG ((EFI_D_VERBOSE, "  VirtualSize          - 0x%08x\n", Section[Index].Misc.VirtualSize));\r
-      DEBUG ((EFI_D_VERBOSE, "  VirtualAddress       - 0x%08x\n", Section[Index].VirtualAddress));\r
-      DEBUG ((EFI_D_VERBOSE, "  SizeOfRawData        - 0x%08x\n", Section[Index].SizeOfRawData));\r
-      DEBUG ((EFI_D_VERBOSE, "  PointerToRawData     - 0x%08x\n", Section[Index].PointerToRawData));\r
-      DEBUG ((EFI_D_VERBOSE, "  PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations));\r
-      DEBUG ((EFI_D_VERBOSE, "  PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers));\r
-      DEBUG ((EFI_D_VERBOSE, "  NumberOfRelocations  - 0x%08x\n", Section[Index].NumberOfRelocations));\r
-      DEBUG ((EFI_D_VERBOSE, "  NumberOfLinenumbers  - 0x%08x\n", Section[Index].NumberOfLinenumbers));\r
-      DEBUG ((EFI_D_VERBOSE, "  Characteristics      - 0x%08x\n", Section[Index].Characteristics));\r
-\r
-      //\r
-      // Step 2: record code section\r
-      //\r
-      ImageRecordCodeSection = AllocatePool (sizeof(*ImageRecordCodeSection));\r
-      if (ImageRecordCodeSection == NULL) {\r
-        return ;\r
-      }\r
-      ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;\r
-\r
-      ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress;\r
-      ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData;\r
-\r
-      DEBUG ((EFI_D_VERBOSE, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize));\r
-\r
-      InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link);\r
-      ImageRecord->CodeSegmentCount++;\r
-    }\r
-  }\r
-\r
-  if (ImageRecord->CodeSegmentCount == 0) {\r
-    SetPropertiesTableSectionAlignment (1);\r
-    DEBUG ((EFI_D_ERROR, "!!!!!!!!  InsertImageRecord - CodeSegmentCount is 0  !!!!!!!!\n"));\r
-    PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress);\r
-    if (PdbPointer != NULL) {\r
-      DEBUG ((EFI_D_ERROR, "!!!!!!!!  Image - %a  !!!!!!!!\n", PdbPointer));\r
-    }\r
-    goto Finish;\r
-  }\r
-\r
-  //\r
-  // Final\r
-  //\r
-  SortImageRecordCodeSection (ImageRecord);\r
-  //\r
-  // Check overlap all section in ImageBase/Size\r
-  //\r
-  if (!IsImageRecordCodeSectionValid (ImageRecord)) {\r
-    DEBUG ((EFI_D_ERROR, "IsImageRecordCodeSectionValid - FAIL\n"));\r
-    goto Finish;\r
-  }\r
-\r
-  InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);\r
-  mImagePropertiesPrivateData.ImageRecordCount++;\r
-\r
-  if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {\r
-    mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;\r
-  }\r
-\r
-  SortImageRecord ();\r
-\r
-Finish:\r
-  return ;\r
-}\r
-\r
-/**\r
-  Find image record according to image base and size.\r
-\r
-  @param  ImageBase    Base of PE image\r
-  @param  ImageSize    Size of PE image\r
-\r
-  @return image record\r
-**/\r
-STATIC\r
-IMAGE_PROPERTIES_RECORD *\r
-FindImageRecord (\r
-  IN EFI_PHYSICAL_ADDRESS  ImageBase,\r
-  IN UINT64                ImageSize\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD    *ImageRecord;\r
-  LIST_ENTRY                 *ImageRecordLink;\r
-  LIST_ENTRY                 *ImageRecordList;\r
-\r
-  ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;\r
-\r
-  for (ImageRecordLink = ImageRecordList->ForwardLink;\r
-       ImageRecordLink != ImageRecordList;\r
-       ImageRecordLink = ImageRecordLink->ForwardLink) {\r
-    ImageRecord = CR (\r
-                    ImageRecordLink,\r
-                    IMAGE_PROPERTIES_RECORD,\r
-                    Link,\r
-                    IMAGE_PROPERTIES_RECORD_SIGNATURE\r
-                    );\r
-\r
-    if ((ImageBase == ImageRecord->ImageBase) &&\r
-        (ImageSize == ImageRecord->ImageSize)) {\r
-      return ImageRecord;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Remove Image record.\r
-\r
-  @param  RuntimeImage    Runtime image information\r
-**/\r
-VOID\r
-RemoveImageRecord (\r
-  IN EFI_RUNTIME_IMAGE_ENTRY  *RuntimeImage\r
-  )\r
-{\r
-  IMAGE_PROPERTIES_RECORD              *ImageRecord;\r
-  LIST_ENTRY                           *CodeSegmentListHead;\r
-  IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
-\r
-  DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage));\r
-  DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));\r
-\r
-  if (mPropertiesTableEndOfDxe) {\r
-    DEBUG ((DEBUG_INFO, "Do not remove runtime image record after EndOfDxe\n"));\r
-    return ;\r
-  }\r
-\r
-  ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize);\r
-  if (ImageRecord == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));\r
-    return ;\r
-  }\r
-\r
-  CodeSegmentListHead = &ImageRecord->CodeSegmentList;\r
-  while (!IsListEmpty (CodeSegmentListHead)) {\r
-    ImageRecordCodeSection = CR (\r
-                               CodeSegmentListHead->ForwardLink,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
-                               Link,\r
-                               IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
-                               );\r
-    RemoveEntryList (&ImageRecordCodeSection->Link);\r
-    FreePool (ImageRecordCodeSection);\r
-  }\r
-\r
-  RemoveEntryList (&ImageRecord->Link);\r
-  FreePool (ImageRecord);\r
-  mImagePropertiesPrivateData.ImageRecordCount--;\r
-}\r
-\r
-\r
-/**\r
-  Install PropertiesTable.\r
-\r
-  @param[in]  Event     The Event this notify function registered to.\r
-  @param[in]  Context   Pointer to the context data registered to the Event.\r
-**/\r
-VOID\r
-EFIAPI\r
-InstallPropertiesTable (\r
-  EFI_EVENT                               Event,\r
-  VOID                                    *Context\r
-  )\r
-{\r
-  mPropertiesTableEndOfDxe = TRUE;\r
-}\r
-\r
-/**\r
-  Initialize PropertiesTable support.\r
-**/\r
-VOID\r
-EFIAPI\r
-CoreInitializePropertiesTable (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_EVENT   EndOfDxeEvent;\r
-\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  InstallPropertiesTable,\r
-                  NULL,\r
-                  &gEfiEndOfDxeEventGroupGuid,\r
-                  &EndOfDxeEvent\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-  return ;\r
-}\r