[binutils-gdb] bfd: populate delay import directory in PE header

Jan Beulich jbeulich@sourceware.org
Fri Jun 13 05:53:45 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=213062b466e5f6c4e7d4ef8bd4afad553ec72bab

commit 213062b466e5f6c4e7d4ef8bd4afad553ec72bab
Author: Jeremy Drake <sourceware-bugzilla@jdrake.com>
Date:   Fri Jun 13 07:53:24 2025 +0200

    bfd: populate delay import directory in PE header
    
    Previously, the delay import table was constructed but its rva and size
    were never put into the PE optional header.
    
    Signed-off-by: Jeremy Drake <sourceware-bugzilla@jdrake.com>

Diff:
---
 bfd/peXXigen.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 7dfa82ee43e..19f38a4ac1b 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -593,7 +593,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
   bfd_vma sa, fa, ib;
-  IMAGE_DATA_DIRECTORY idata2, idata5, tls, loadcfg;
+  IMAGE_DATA_DIRECTORY idata2, idata5, didat2, tls, loadcfg;
 
   sa = extra->SectionAlignment;
   fa = extra->FileAlignment;
@@ -601,6 +601,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
 
   idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
   idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
+  didat2 = pe->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR];
   tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
   loadcfg = pe->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE];
 
@@ -651,6 +652,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
      a final link is going to be performed, it can overwrite them.  */
   extra->DataDirectory[PE_IMPORT_TABLE]  = idata2;
   extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
+  extra->DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR] = didat2;
   extra->DataDirectory[PE_TLS_TABLE] = tls;
   extra->DataDirectory[PE_LOAD_CONFIG_TABLE] = loadcfg;
 
@@ -4544,6 +4546,52 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
 	}
     }
 
+  /* The delay import directory.  This is .didat$2 */
+  h1 = coff_link_hash_lookup (coff_hash_table (info),
+			      "__DELAY_IMPORT_DIRECTORY_start__", false, false,
+			      true);
+  if (h1 != NULL
+      && (h1->root.type == bfd_link_hash_defined
+       || h1->root.type == bfd_link_hash_defweak)
+      && h1->root.u.def.section != NULL
+      && h1->root.u.def.section->output_section != NULL)
+    {
+      bfd_vma delay_va;
+
+      delay_va =
+	(h1->root.u.def.value
+	 + h1->root.u.def.section->output_section->vma
+	 + h1->root.u.def.section->output_offset);
+
+      h1 = coff_link_hash_lookup (coff_hash_table (info),
+				  "__DELAY_IMPORT_DIRECTORY_end__", false,
+				  false, true);
+      if (h1 != NULL
+	  && (h1->root.type == bfd_link_hash_defined
+	   || h1->root.type == bfd_link_hash_defweak)
+	  && h1->root.u.def.section != NULL
+	  && h1->root.u.def.section->output_section != NULL)
+	{
+	  pe_data (abfd)->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR].Size =
+	    ((h1->root.u.def.value
+	      + h1->root.u.def.section->output_section->vma
+	      + h1->root.u.def.section->output_offset)
+	     - delay_va);
+	  if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR].Size
+	      != 0)
+	    pe_data (abfd)->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR].VirtualAddress =
+	      delay_va - pe_data (abfd)->pe_opthdr.ImageBase;
+	}
+      else
+	{
+	  _bfd_error_handler
+	    (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"),
+	     abfd, PE_DELAY_IMPORT_DESCRIPTOR,
+	     "__DELAY_IMPORT_DIRECTORY_end__");
+	  result = false;
+	}
+    }
+
   name[0] = bfd_get_symbol_leading_char (abfd);
   strcpy (name + !!name[0], "_tls_used");
   h1 = coff_link_hash_lookup (coff_hash_table (info), name, false, false, true);


More information about the Binutils-cvs mailing list