[PATCH v3 4/4] bfd: populate delay import directory in PE header.

Jeremy Drake sourceware-bugzilla@jdrake.com
Tue May 6 06:53:27 GMT 2025
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>
---
 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);
-- 
2.49.0.windows.1



More information about the Binutils mailing list