]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools/GenFw: move .debug contents to .data to save space
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Mon, 27 Jul 2015 13:49:54 +0000 (13:49 +0000)
committerabiesheuvel <abiesheuvel@Edk2>
Mon, 27 Jul 2015 13:49:54 +0000 (13:49 +0000)
In order to reduce the memory footprint of PE/COFF images when
using large values for the PE/COFF section alignment, move the
contents of the .debug section to data, and point the debug data
directory entry to it. This allows us to drop the .debug section
entirely, as well as any associated rounding. Since our .debug
section only contains the filename of the ELF input image, the
penalty of keeping this data in a non-discardable section is
negligible.

Note that the PE/COFF spec v6.3 explicitly mentions that this is
allowed.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Yingke Liu <yingke.d.liu@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18077 6f19259b-4bc3-4df7-8a09-765794883524

BaseTools/Source/C/GenFw/Elf32Convert.c
BaseTools/Source/C/GenFw/Elf64Convert.c

index 10d9892ba1e06839e1adcaf8e6284695573d589c..53bb14a47dbfbbb95881e8898ea8a4113ef36b38 100644 (file)
@@ -101,7 +101,7 @@ STATIC UINT32 mCoffAlignment = 0x20;
 //\r
 // PE section alignment.\r
 //\r
-STATIC const UINT16 mCoffNbrSections = 5;\r
+STATIC const UINT16 mCoffNbrSections = 4;\r
 \r
 //\r
 // ELF sections to offset in Coff file.\r
@@ -116,6 +116,7 @@ STATIC UINT32 mTextOffset;
 STATIC UINT32 mDataOffset;\r
 STATIC UINT32 mHiiRsrcOffset;\r
 STATIC UINT32 mRelocOffset;\r
+STATIC UINT32 mDebugOffset;\r
 \r
 //\r
 // Initialization Function\r
@@ -354,6 +355,8 @@ ScanSections32 (
     assert (FALSE);\r
   }\r
 \r
+  mDebugOffset = mCoffOffset;\r
+\r
   if (mEhdr->e_machine != EM_ARM) {\r
     mCoffOffset = CoffAlign(mCoffOffset);\r
   }\r
@@ -398,12 +401,29 @@ ScanSections32 (
       SectionCount ++;\r
     }\r
   }\r
-  mCoffOffset = CoffAlign(mCoffOffset);\r
 \r
   if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {\r
     Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName);\r
   }\r
 \r
+  //\r
+  // Make room for .debug data in .data (or .text if .data is empty) instead of\r
+  // putting it in a section of its own. This is explicitly allowed by the\r
+  // PE/COFF spec, and prevents bloat in the binary when using large values for\r
+  // section alignment.\r
+  //\r
+  if (SectionCount > 0) {\r
+    mDebugOffset = mCoffOffset;\r
+  }\r
+  mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +\r
+                sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +\r
+                strlen(mInImageName) + 1;\r
+\r
+  mCoffOffset = CoffAlign(mCoffOffset);\r
+  if (SectionCount == 0) {\r
+    mDataOffset = mCoffOffset;\r
+  }\r
+\r
   //\r
   //  The HII resource sections.\r
   //\r
@@ -998,28 +1018,18 @@ WriteDebug32 (
   )\r
 {\r
   UINT32                              Len;\r
-  UINT32                              DebugOffset;\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
 \r
   Len = strlen(mInImageName) + 1;\r
-  DebugOffset = mCoffOffset;\r
 \r
-  mCoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)\r
-    + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)\r
-    + Len;\r
-  mCoffOffset = CoffAlign(mCoffOffset);\r
-\r
-  mCoffFile = realloc(mCoffFile, mCoffOffset);\r
-  memset(mCoffFile + DebugOffset, 0, mCoffOffset - DebugOffset);\r
-\r
-  Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + DebugOffset);\r
+  Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);\r
   Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
   Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
-  Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
-  Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+  Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+  Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
 \r
   Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
   Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
@@ -1028,20 +1038,8 @@ WriteDebug32 (
 \r
   NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
   DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
-  DataDir->VirtualAddress = DebugOffset;\r
-  DataDir->Size = mCoffOffset - DebugOffset;\r
-  if (DataDir->Size == 0) {\r
-    // If no debug, null out the directory entry and don't add the .debug section\r
-    DataDir->VirtualAddress = 0;\r
-    NtHdr->Pe32.FileHeader.NumberOfSections--;\r
-  } else {\r
-    DataDir->VirtualAddress = DebugOffset;\r
-    CreateSectionHeader (".debug", DebugOffset, mCoffOffset - DebugOffset,\r
-            EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
-            | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
-            | EFI_IMAGE_SCN_MEM_READ);\r
-\r
-  }\r
+  DataDir->VirtualAddress = mDebugOffset;\r
+  DataDir->Size = Dir->SizeOfData + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
 }\r
 \r
 STATIC\r
index d2becf165f5501a331ef7e08ed91ec1ae239ac54..7650afe54cfc90fc17546463e38d654413b484b6 100644 (file)
@@ -102,7 +102,7 @@ STATIC UINT32 mCoffAlignment = 0x20;
 //\r
 // PE section alignment.\r
 //\r
-STATIC const UINT16 mCoffNbrSections = 5;\r
+STATIC const UINT16 mCoffNbrSections = 4;\r
 \r
 //\r
 // ELF sections to offset in Coff file.\r
@@ -117,6 +117,7 @@ STATIC UINT32 mTextOffset;
 STATIC UINT32 mDataOffset;\r
 STATIC UINT32 mHiiRsrcOffset;\r
 STATIC UINT32 mRelocOffset;\r
+STATIC UINT32 mDebugOffset;\r
 \r
 //\r
 // Initialization Function\r
@@ -348,6 +349,8 @@ ScanSections64 (
     assert (FALSE);\r
   }\r
 \r
+  mDebugOffset = mCoffOffset;\r
+\r
   if (mEhdr->e_machine != EM_ARM) {\r
     mCoffOffset = CoffAlign(mCoffOffset);\r
   }\r
@@ -391,7 +394,24 @@ ScanSections64 (
       SectionCount ++;\r
     }\r
   }\r
+\r
+  //\r
+  // Make room for .debug data in .data (or .text if .data is empty) instead of\r
+  // putting it in a section of its own. This is explicitly allowed by the\r
+  // PE/COFF spec, and prevents bloat in the binary when using large values for\r
+  // section alignment.\r
+  //\r
+  if (SectionCount > 0) {\r
+    mDebugOffset = mCoffOffset;\r
+  }\r
+  mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +\r
+                sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +\r
+                strlen(mInImageName) + 1;\r
+\r
   mCoffOffset = CoffAlign(mCoffOffset);\r
+  if (SectionCount == 0) {\r
+    mDataOffset = mCoffOffset;\r
+  }\r
 \r
   if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {\r
     Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName);\r
@@ -903,28 +923,18 @@ WriteDebug64 (
   )\r
 {\r
   UINT32                              Len;\r
-  UINT32                              DebugOffset;\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
 \r
   Len = strlen(mInImageName) + 1;\r
-  DebugOffset = mCoffOffset;\r
-\r
-  mCoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)\r
-    + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)\r
-    + Len;\r
-  mCoffOffset = CoffAlign(mCoffOffset);\r
 \r
-  mCoffFile = realloc(mCoffFile, mCoffOffset);\r
-  memset(mCoffFile + DebugOffset, 0, mCoffOffset - DebugOffset);\r
-\r
-  Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + DebugOffset);\r
+  Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);\r
   Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
   Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
-  Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
-  Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+  Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+  Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
 \r
   Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
   Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
@@ -933,20 +943,8 @@ WriteDebug64 (
 \r
   NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
   DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
-  DataDir->VirtualAddress = DebugOffset;\r
-  DataDir->Size = mCoffOffset - DebugOffset;\r
-  if (DataDir->Size == 0) {\r
-    // If no debug, null out the directory entry and don't add the .debug section\r
-    DataDir->VirtualAddress = 0;\r
-    NtHdr->Pe32Plus.FileHeader.NumberOfSections--;\r
-  } else {\r
-    DataDir->VirtualAddress = DebugOffset;\r
-    CreateSectionHeader (".debug", DebugOffset, mCoffOffset - DebugOffset,\r
-            EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
-            | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
-            | EFI_IMAGE_SCN_MEM_READ);\r
-\r
-  }\r
+  DataDir->VirtualAddress = mDebugOffset;\r
+  DataDir->Size = Dir->SizeOfData + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
 }\r
 \r
 STATIC\r