[binutils-gdb] Fix IAT (Import Address Table) alignment on PE32+

Jan Beulich via Binutils-cvs <[email protected]>
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f6f94d6af6b139f89e438bbf7552bc21adf55e42

commit f6f94d6af6b139f89e438bbf7552bc21adf55e42
Author: Evgeny Karpov <[email protected]>
Date:   Fri May 15 09:47:56 2026 +0200

    Fix IAT (Import Address Table) alignment on PE32+
    
    The IAT should be aligned to 8 bytes in aarch64-w64-mingw32, otherwise, it might
    result in relocation issues.
    
    When a function is imported from DLL, it generates the following code:
    
    adrp    x19, __imp_fn
    ldr     x19, [x19, #:lo12:__imp_fn]
    
    8 byte alignment is required for ldr relocation. Addresses are placed in IAT.
    The size of the chunk on AArch64 is 8 bytes.
    If IAT is not aligned to 8 bytes, the relocation issue appears.
    This patch fixes this issue by aligning IAT to 8 bytes for PE32+.
    
    binutils/ChangeLog:
    
            * dlltool.c (make_head): Apply alignment to IAT.
            (make_delay_head): Apply alignment to Delay IAT.
            (main): Adjust 8 byte alignment for PE32+.

Diff:
---
 binutils/dlltool.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/binutils/dlltool.c b/binutils/dlltool.c
index 94805fcd334..f4ee894de1b 100644
--- a/binutils/dlltool.c
+++ b/binutils/dlltool.c
@@ -2735,6 +2735,8 @@ make_head (void)
   if (!no_idata5)
     {
       fprintf (f, "\t.section\t.idata$5\n");
+      fprintf (f, "\t.p2align %d\n", secdata_plain[IDATA5].align);
+
       if (use_nul_prefixed_import_tables)
 	{
 	  if (create_for_pep)
@@ -2828,6 +2830,8 @@ make_delay_head (void)
   if (!no_idata5)
     {
       fprintf (f, "\t.section\t.didat$5\n");
+      fprintf (f, "\t.p2align %d\n", secdata_delay[IDATA5].align);
+
       if (use_nul_prefixed_import_tables)
 	{
 	  if (create_for_pep)
@@ -4013,6 +4017,14 @@ main (int ac, char **av)
   /* Check if we generated PE+.  */
   create_for_pep = (strcmp (mname, "i386:x86-64") == 0
 		    || strcmp (mname, "arm64") == 0);
+  if (create_for_pep)
+    {
+      /* Update default 4 byte IAT (Import Address Table) alignment to 8 bytes
+	 for PE32+.
+	 https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table.  */
+      secdata_plain[IDATA5].align = 3;
+      secdata_delay[IDATA5].align = 3;
+    }
 
   /* Check the default underscore */
   if (leading_underscore == NULL)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.