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

Jan Beulich jbeulich@sourceware.org
Fri May 15 07:49:43 GMT 2026


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

commit f6f94d6af6b139f89e438bbf7552bc21adf55e42
Author: Evgeny Karpov <evgeny.karpov@arm.com>
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)


More information about the Binutils-cvs mailing list