]> xenbits.xensource.com Git - ovmf.git/commitdiff
BaseTools/GenFw: Add DllCharacteristicsEx field to debug data
authorArd Biesheuvel <ardb@kernel.org>
Sat, 25 Mar 2023 14:50:54 +0000 (15:50 +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

The PE/COFF spec describes an additional DllCharacteristics field
implemented as a debug directory entry, which carries flags related to
which control flow integrity (CFI) features are supported by the binary.

So let's add this entry when doing ELF to PE/COFF conversion - we will
add support for setting the flags in a subsequent patch.

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>
BaseTools/Source/C/GenFw/Elf64Convert.c
BaseTools/Source/C/GenFw/GenFw.c
BaseTools/Source/C/Include/IndustryStandard/PeImage.h

index 2a810e835d4a4a6682523d5994d9e09ff1ff935e..9c17c90b166024214d729eb9a76eb6c0b274e400 100644 (file)
@@ -992,6 +992,16 @@ ScanSections64 (
                 sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +\r
                 strlen(mInImageName) + 1;\r
 \r
+  //\r
+  // Add more space in the .debug data region for the DllCharacteristicsEx\r
+  // field.\r
+  //\r
+  if (mDllCharacteristicsEx != 0) {\r
+    mCoffOffset = DebugRvaAlign(mCoffOffset) +\r
+                  sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +\r
+                  sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY);\r
+  }\r
+\r
   mCoffOffset = CoffAlign(mCoffOffset);\r
   if (SectionCount == 0) {\r
     mDataOffset = mCoffOffset;\r
@@ -2244,29 +2254,47 @@ WriteDebug64 (
   VOID\r
   )\r
 {\r
-  UINT32                              Len;\r
-  EFI_IMAGE_OPTIONAL_HEADER_UNION     *NtHdr;\r
-  EFI_IMAGE_DATA_DIRECTORY            *DataDir;\r
-  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY     *Dir;\r
-  EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\r
+  UINT32                                      Len;\r
+  EFI_IMAGE_OPTIONAL_HEADER_UNION             *NtHdr;\r
+  EFI_IMAGE_DATA_DIRECTORY                    *DataDir;\r
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY             *Dir;\r
+  EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY         *Nb10;\r
+  EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY *DllEntry;\r
 \r
   Len = strlen(mInImageName) + 1;\r
 \r
+  NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
+  DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
+  DataDir->VirtualAddress = mDebugOffset;\r
+  DataDir->Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+\r
   Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);\r
+\r
+  if (mDllCharacteristicsEx != 0) {\r
+    DataDir->Size  += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+\r
+    Dir->Type       = EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS;\r
+    Dir->SizeOfData = sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY);\r
+    Dir->FileOffset = mDebugOffset + DataDir->Size +\r
+                      sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +\r
+                      DebugRvaAlign(Len);\r
+    Dir->RVA        = Dir->FileOffset;\r
+\r
+    DllEntry = (VOID *)(mCoffFile + Dir->FileOffset);\r
+\r
+    DllEntry->DllCharacteristicsEx = mDllCharacteristicsEx;\r
+\r
+    Dir++;\r
+  }\r
+\r
   Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
   Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
-  Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
-  Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+  Dir->RVA = mDebugOffset + DataDir->Size;\r
+  Dir->FileOffset = mDebugOffset + DataDir->Size;\r
 \r
   Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
   Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
   strcpy ((char *)(Nb10 + 1), mInImageName);\r
-\r
-\r
-  NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
-  DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
-  DataDir->VirtualAddress = mDebugOffset;\r
-  DataDir->Size = sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
 }\r
 \r
 STATIC\r
index 6f61f16788cd2a0a5d66d17228431d8f2b06ad20..d0e52ccc26431380270ab47ef1e192ae98ca2570 100644 (file)
@@ -2932,7 +2932,8 @@ Returns:
       if (mIsConvertXip) {\r
         DebugEntry->FileOffset = DebugEntry->RVA;\r
       }\r
-      if (ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+      if ((ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) &&\r
+          (DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS)) {\r
         memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);\r
         memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
       }\r
index 77ded3f6113982780525cc9da00a1f013765931d..22161edf443d0e22d1f622b284006e281405d9d1 100644 (file)
@@ -615,7 +615,8 @@ typedef struct {
 ///\r
 /// Debug Format\r
 ///\r
-#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2\r
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW               2\r
+#define EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS  20\r
 \r
 typedef struct {\r
   UINT32  Characteristics;\r
@@ -664,6 +665,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
 // .pdata entries for X64\r
 //\r