]> xenbits.xensource.com Git - ovmf.git/commitdiff
MdePkg/PeCoffLib: Capture DLL characteristics fields in image context
authorArd Biesheuvel <ardb@kernel.org>
Mon, 13 Mar 2023 17:17:05 +0000 (18:17 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 7 Apr 2023 13:18:38 +0000 (13:18 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4405

When loading a PE/COFF image, capture the DLL characteristics fields of
the header into our image context structure so we can refer to them when
mapping the image.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
MdePkg/Include/IndustryStandard/PeImage.h
MdePkg/Include/Library/PeCoffLib.h
MdePkg/Library/BasePeCoffLib/BasePeCoff.c

index dd4cc25483bc4bcf7b9c2677526acd4f6e4492a0..8646ff22b55faff012f745cadba12e566d82b4ec 100644 (file)
@@ -625,7 +625,8 @@ typedef struct {
   UINT32    FileOffset;  ///< The file pointer to the debug data.\r
 } EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;\r
 \r
-#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW  2    ///< The Visual C++ debug information.\r
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW               2    ///< The Visual C++ debug information.\r
+#define EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS  20\r
 \r
 ///\r
 /// Debug Data Structure defined in Microsoft C++.\r
@@ -669,6 +670,16 @@ typedef struct {
   //\r
 } EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;\r
 \r
+///\r
+/// Extended DLL Characteristics\r
+///\r
+#define EFI_IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT          0x0001\r
+#define EFI_IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT  0x0040\r
+\r
+typedef struct {\r
+  UINT32    DllCharacteristicsEx;\r
+} EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY;\r
+\r
 ///\r
 /// Resource format.\r
 ///\r
index b45879453785c77dcf9f03e83daf07a9a48d98e3..74cceb37bf39ffc61fd888fd4234380f7ae32081 100644 (file)
@@ -171,6 +171,12 @@ typedef struct {
   ///\r
   UINT16                      ImageType;\r
   ///\r
+  /// Set by PeCoffLoaderGetImageInfo() to the DLL flags stored in the PE/COFF header and\r
+  /// in the DllCharacteristicsEx debug table.\r
+  ///\r
+  UINT16                      DllCharacteristics;\r
+  UINT32                      DllCharacteristicsEx;\r
+  ///\r
   /// Set by PeCoffLoaderGetImageInfo() to TRUE if the PE/COFF image does not contain\r
   /// relocation information.\r
   ///\r
index 97a8aaf8c73d3e3cdbb6276dbd8cdfdbbc591ece..4b71176a0c7c2ed06b3a5025b1541effbf87de0b 100644 (file)
@@ -308,10 +308,11 @@ PeCoffLoaderGetPeHeader (
       //\r
       // Use PE32 offset\r
       //\r
-      ImageContext->ImageType        = Hdr.Pe32->OptionalHeader.Subsystem;\r
-      ImageContext->ImageSize        = (UINT64)Hdr.Pe32->OptionalHeader.SizeOfImage;\r
-      ImageContext->SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
-      ImageContext->SizeOfHeaders    = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
+      ImageContext->ImageType          = Hdr.Pe32->OptionalHeader.Subsystem;\r
+      ImageContext->ImageSize          = (UINT64)Hdr.Pe32->OptionalHeader.SizeOfImage;\r
+      ImageContext->SectionAlignment   = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
+      ImageContext->SizeOfHeaders      = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
+      ImageContext->DllCharacteristics = Hdr.Pe32->OptionalHeader.DllCharacteristics;\r
     } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
       //\r
       // 1. Check FileHeader.NumberOfRvaAndSizes filed.\r
@@ -429,10 +430,11 @@ PeCoffLoaderGetPeHeader (
       //\r
       // Use PE32+ offset\r
       //\r
-      ImageContext->ImageType        = Hdr.Pe32Plus->OptionalHeader.Subsystem;\r
-      ImageContext->ImageSize        = (UINT64)Hdr.Pe32Plus->OptionalHeader.SizeOfImage;\r
-      ImageContext->SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;\r
-      ImageContext->SizeOfHeaders    = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
+      ImageContext->ImageType          = Hdr.Pe32Plus->OptionalHeader.Subsystem;\r
+      ImageContext->ImageSize          = (UINT64)Hdr.Pe32Plus->OptionalHeader.SizeOfImage;\r
+      ImageContext->SectionAlignment   = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;\r
+      ImageContext->SizeOfHeaders      = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
+      ImageContext->DllCharacteristics = Hdr.Pe32Plus->OptionalHeader.DllCharacteristics;\r
     } else {\r
       ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;\r
       return RETURN_UNSUPPORTED;\r
@@ -545,8 +547,9 @@ PeCoffLoaderGetPeHeader (
   Retrieves information about a PE/COFF image.\r
 \r
   Computes the PeCoffHeaderOffset, IsTeImage, ImageType, ImageAddress, ImageSize,\r
-  DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders, and\r
-  DebugDirectoryEntryRva fields of the ImageContext structure.\r
+  DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders,\r
+  DllCharacteristics, DllCharacteristicsEx and DebugDirectoryEntryRva fields of\r
+  the ImageContext structure.\r
   If ImageContext is NULL, then return RETURN_INVALID_PARAMETER.\r
   If the PE/COFF image accessed through the ImageRead service in the ImageContext\r
   structure is not a supported PE/COFF image type, then return RETURN_UNSUPPORTED.\r
@@ -752,7 +755,28 @@ PeCoffLoaderGetImageInfo (
               ImageContext->ImageSize += DebugEntry.SizeOfData;\r
             }\r
 \r
-            return RETURN_SUCCESS;\r
+            continue;\r
+          }\r
+\r
+          if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS) {\r
+            Size     = sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY);\r
+            ReadSize = sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY);\r
+            Status   = ImageContext->ImageRead (\r
+                                       ImageContext->Handle,\r
+                                       DebugEntry.FileOffset,\r
+                                       &Size,\r
+                                       &ImageContext->DllCharacteristicsEx\r
+                                       );\r
+            if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+              ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+              if (Size != ReadSize) {\r
+                Status = RETURN_UNSUPPORTED;\r
+              }\r
+\r
+              return Status;\r
+            }\r
+\r
+            continue;\r
           }\r
         }\r
       }\r