]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c
MdeModulePkg: remove PE/COFF header workaround for ELILO on IPF
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / PropertiesTable.c
index 6e5ad033198886c071b3bea4bde23f621d2be63f..05eb4f422b2fc39103351ed3ff9eee3b99fd04cf 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI PropertiesTable support\r
 \r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -36,26 +36,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
   ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))\r
 \r
-#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C')\r
-\r
-typedef struct {\r
-  UINT32                 Signature;\r
-  LIST_ENTRY             Link;\r
-  EFI_PHYSICAL_ADDRESS   CodeSegmentBase;\r
-  UINT64                 CodeSegmentSize;\r
-} IMAGE_PROPERTIES_RECORD_CODE_SECTION;\r
-\r
-#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D')\r
-\r
-typedef struct {\r
-  UINT32                 Signature;\r
-  LIST_ENTRY             Link;\r
-  EFI_PHYSICAL_ADDRESS   ImageBase;\r
-  UINT64                 ImageSize;\r
-  UINTN                  CodeSegmentCount;\r
-  LIST_ENTRY             CodeSegmentList;\r
-} IMAGE_PROPERTIES_RECORD;\r
-\r
 #define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')\r
 \r
 typedef struct {\r
@@ -80,14 +60,9 @@ EFI_PROPERTIES_TABLE  mPropertiesTable = {
 \r
 EFI_LOCK           mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);\r
 \r
-//\r
-// Temporary save for original memory map.\r
-// This is for MemoryAttributesTable only.\r
-//\r
-extern BOOLEAN         mIsConstructingMemoryAttributesTable;\r
-EFI_MEMORY_DESCRIPTOR  *mMemoryMapOrg;\r
-UINTN                  mMemoryMapOrgSize;\r
-UINTN                  mDescriptorSize;\r
+BOOLEAN            mPropertiesTableEnable;\r
+\r
+BOOLEAN            mPropertiesTableEndOfDxe = FALSE;\r
 \r
 //\r
 // Below functions are for MemoryMap\r
@@ -198,42 +173,6 @@ SortMemoryMap (
   return ;\r
 }\r
 \r
-/**\r
-  Check if this memory entry spans across original memory map boundary.\r
-\r
-  @param PhysicalStart   The PhysicalStart of memory\r
-  @param NumberOfPages   The NumberOfPages of memory\r
-\r
-  @retval TRUE  This memory entry spans across original memory map boundary.\r
-  @retval FALSE This memory entry does not span cross original memory map boundary.\r
-**/\r
-STATIC\r
-BOOLEAN\r
-DoesEntrySpanAcrossBoundary (\r
-  IN UINT64                      PhysicalStart,\r
-  IN UINT64                      NumberOfPages\r
-  )\r
-{\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEntry;\r
-  EFI_MEMORY_DESCRIPTOR       *MemoryMapEnd;\r
-  UINT64                      MemoryBlockLength;\r
-\r
-  MemoryMapEntry = mMemoryMapOrg;\r
-  MemoryMapEnd   = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) mMemoryMapOrg + mMemoryMapOrgSize);\r
-  while (MemoryMapEntry < MemoryMapEnd) {\r
-    MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages));\r
-\r
-    if ((MemoryMapEntry->PhysicalStart <= PhysicalStart) &&\r
-        (MemoryMapEntry->PhysicalStart + MemoryBlockLength > PhysicalStart) &&\r
-        (MemoryMapEntry->PhysicalStart + MemoryBlockLength < PhysicalStart + EfiPagesToSize (NumberOfPages))) {\r
-      return TRUE;\r
-    }\r
-\r
-    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, mDescriptorSize);\r
-  }\r
-  return FALSE;\r
-}\r
-\r
 /**\r
   Merge continous memory map entries whose have same attributes.\r
 \r
@@ -245,7 +184,6 @@ DoesEntrySpanAcrossBoundary (
                                  it is the size of new memory map after merge.\r
   @param  DescriptorSize         Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
 **/\r
-STATIC\r
 VOID\r
 MergeMemoryMap (\r
   IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
@@ -271,8 +209,7 @@ MergeMemoryMap (
       if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&\r
           (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&\r
           (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&\r
-          ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart) &&\r
-          (!DoesEntrySpanAcrossBoundary (MemoryMapEntry->PhysicalStart, MemoryMapEntry->NumberOfPages + NextMemoryMapEntry->NumberOfPages))) {\r
+          ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) {\r
         MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
         if (NewMemoryMapEntry != MemoryMapEntry) {\r
           NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
@@ -430,7 +367,11 @@ SetNewRecord (
       //\r
       // DATA\r
       //\r
-      NewRecord->Type = EfiRuntimeServicesData;\r
+      if (!mPropertiesTableEnable) {\r
+        NewRecord->Type = TempRecord.Type;\r
+      } else {\r
+        NewRecord->Type = EfiRuntimeServicesData;\r
+      }\r
       NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
       NewRecord->VirtualStart  = 0;\r
       NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);\r
@@ -443,7 +384,11 @@ SetNewRecord (
       //\r
       // CODE\r
       //\r
-      NewRecord->Type = EfiRuntimeServicesCode;\r
+      if (!mPropertiesTableEnable) {\r
+        NewRecord->Type = TempRecord.Type;\r
+      } else {\r
+        NewRecord->Type = EfiRuntimeServicesCode;\r
+      }\r
       NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;\r
       NewRecord->VirtualStart  = 0;\r
       NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize);\r
@@ -467,7 +412,11 @@ SetNewRecord (
   // Final DATA\r
   //\r
   if (TempRecord.PhysicalStart < ImageEnd) {\r
-    NewRecord->Type = EfiRuntimeServicesData;\r
+    if (!mPropertiesTableEnable) {\r
+      NewRecord->Type = TempRecord.Type;\r
+    } else {\r
+      NewRecord->Type = EfiRuntimeServicesData;\r
+    }\r
     NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
     NewRecord->VirtualStart  = 0;\r
     NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);\r
@@ -549,6 +498,7 @@ SplitRecord (
   UINT64                  PhysicalEnd;\r
   UINTN                   NewRecordCount;\r
   UINTN                   TotalNewRecordCount;\r
+  BOOLEAN                 IsLastRecordData;\r
 \r
   if (MaxSplitRecordCount == 0) {\r
     CopyMem (NewRecord, OldRecord, DescriptorSize);\r
@@ -576,7 +526,17 @@ SplitRecord (
         // If this is still address in this record, need record.\r
         //\r
         NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-        if (NewRecord->Type == EfiRuntimeServicesData) {\r
+        IsLastRecordData = FALSE;\r
+        if (!mPropertiesTableEnable) {\r
+          if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) {\r
+            IsLastRecordData = TRUE;\r
+          }\r
+        } else {\r
+          if (NewRecord->Type == EfiRuntimeServicesData) {\r
+            IsLastRecordData = TRUE;\r
+          }\r
+        }\r
+        if (IsLastRecordData) {\r
           //\r
           // Last record is DATA, just merge it.\r
           //\r
@@ -586,7 +546,11 @@ SplitRecord (
           // Last record is CODE, create a new DATA entry.\r
           //\r
           NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
-          NewRecord->Type = EfiRuntimeServicesData;\r
+          if (!mPropertiesTableEnable) {\r
+            NewRecord->Type = TempRecord.Type;\r
+          } else {\r
+            NewRecord->Type = EfiRuntimeServicesData;\r
+          }\r
           NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
           NewRecord->VirtualStart  = 0;\r
           NewRecord->NumberOfPages = TempRecord.NumberOfPages;\r
@@ -613,6 +577,11 @@ SplitRecord (
     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
@@ -775,7 +744,7 @@ SplitTable (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-CoreGetMemoryMapPropertiesTable (\r
+CoreGetMemoryMapWithSeparatedImageSection (\r
   IN OUT UINTN                  *MemoryMapSize,\r
   IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
   OUT UINTN                     *MapKey,\r
@@ -807,6 +776,7 @@ CoreGetMemoryMapPropertiesTable (
   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
@@ -814,38 +784,13 @@ CoreGetMemoryMapPropertiesTable (
       //\r
       Status = EFI_BUFFER_TOO_SMALL;\r
     } else {\r
-      if (mIsConstructingMemoryAttributesTable) {\r
-        //\r
-        // If the memory map is constructed for memory attributes table,\r
-        // save original memory map, because they will be checked later\r
-        // to make sure the memory attributes table entry does not cross\r
-        // the original memory map entry boundary.\r
-        // This work must NOT be done in normal GetMemoryMap() because\r
-        // allocating memory is not allowed due to MapKey update.\r
-        //\r
-        mDescriptorSize = *DescriptorSize;\r
-        mMemoryMapOrgSize = *MemoryMapSize;\r
-        mMemoryMapOrg = AllocateCopyPool (*MemoryMapSize, MemoryMap);\r
-        if (mMemoryMapOrg == NULL) {\r
-          Status = EFI_OUT_OF_RESOURCES;\r
-          goto Exit;\r
-        }\r
-      }\r
-\r
       //\r
       // Split PE code/data\r
       //\r
       SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);\r
-\r
-      if (mIsConstructingMemoryAttributesTable) {\r
-        FreePool (mMemoryMapOrg);\r
-        mMemoryMapOrg = NULL;\r
-        mMemoryMapOrgSize = 0;\r
-      }\r
     }\r
   }\r
 \r
-Exit:\r
   CoreReleasePropertiesTableLock ();\r
   return Status;\r
 }\r
@@ -865,7 +810,7 @@ SetPropertiesTableSectionAlignment (
   IN UINT32  SectionAlignment\r
   )\r
 {\r
-  if (((SectionAlignment & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) &&\r
+  if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&\r
       ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0)) {\r
     DEBUG ((EFI_D_VERBOSE, "SetPropertiesTableSectionAlignment - Clear\n"));\r
     mPropertiesTable.MemoryProtectionAttribute &= ~((UINT64)EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);\r
@@ -905,7 +850,6 @@ SwapImageRecordCodeSection (
 \r
   @param  ImageRecord    image record to be sorted\r
 **/\r
-STATIC\r
 VOID\r
 SortImageRecordCodeSection (\r
   IN IMAGE_PROPERTIES_RECORD              *ImageRecord\r
@@ -956,7 +900,6 @@ SortImageRecordCodeSection (
   @retval TRUE  image record is valid\r
   @retval FALSE image record is invalid\r
 **/\r
-STATIC\r
 BOOLEAN\r
 IsImageRecordCodeSectionValid (\r
   IN IMAGE_PROPERTIES_RECORD              *ImageRecord\r
@@ -1133,11 +1076,15 @@ InsertImageRecord (
   IMAGE_PROPERTIES_RECORD              *ImageRecord;\r
   CHAR8                                *PdbPointer;\r
   IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
-  UINT16                               Magic;\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
@@ -1178,30 +1125,16 @@ InsertImageRecord (
   //\r
   // Get SectionAlignment\r
   //\r
-  if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
-    //\r
-    // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value\r
-    //       in the PE/COFF Header. If the MachineType is Itanium(IA64) and the\r
-    //       Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
-    //       then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
-    //\r
-    Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
-  } else {\r
-    //\r
-    // Get the magic value from the PE/COFF Optional Header\r
-    //\r
-    Magic = Hdr.Pe32->OptionalHeader.Magic;\r
-  }\r
-  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\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 & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) {\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, EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT >> 10));\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
@@ -1288,12 +1221,12 @@ InsertImageRecord (
   InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);\r
   mImagePropertiesPrivateData.ImageRecordCount++;\r
 \r
-  SortImageRecord ();\r
-\r
   if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {\r
     mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;\r
   }\r
 \r
+  SortImageRecord ();\r
+\r
 Finish:\r
   return ;\r
 }\r
@@ -1355,6 +1288,11 @@ RemoveImageRecord (
   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
@@ -1392,6 +1330,7 @@ InstallPropertiesTable (
   VOID                                    *Context\r
   )\r
 {\r
+  mPropertiesTableEndOfDxe = TRUE;\r
   if (PcdGetBool (PcdPropertiesTableEnable)) {\r
     EFI_STATUS  Status;\r
 \r
@@ -1401,17 +1340,19 @@ InstallPropertiesTable (
     DEBUG ((EFI_D_INFO, "MemoryProtectionAttribute - 0x%016lx\n", mPropertiesTable.MemoryProtectionAttribute));\r
     if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {\r
       DEBUG ((EFI_D_ERROR, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, "));\r
-      DEBUG ((EFI_D_ERROR, "because Runtime Driver Section Alignment is not %dK.\n", EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT >> 10));\r
+      DEBUG ((EFI_D_ERROR, "because Runtime Driver Section Alignment is not %dK.\n", RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));\r
       return ;\r
     }\r
 \r
-    gBS->GetMemoryMap = CoreGetMemoryMapPropertiesTable;\r
+    gBS->GetMemoryMap = CoreGetMemoryMapWithSeparatedImageSection;\r
     gBS->Hdr.CRC32 = 0;\r
     gBS->CalculateCrc32 ((UINT8 *)gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);\r
 \r
     DEBUG ((EFI_D_VERBOSE, "Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));\r
     DEBUG ((EFI_D_VERBOSE, "Dump ImageRecord:\n"));\r
     DumpImageRecord ();\r
+\r
+    mPropertiesTableEnable = TRUE;\r
   }\r
 }\r
 \r