[PATCH] Fix IAT (Import Address Table) alignment on AArch64

Evgeny Karpov evgeny.karpov@arm.com
Wed Apr 8 10:34:25 GMT 2026


On Wed, Apr 08, 2026, Richard Earnshaw (foss) wrote:
> On 08/04/2026 10:27, Evgeny Karpov wrote:
> > On Wed, Apr 08, 2026, Jan Beulich wrote:
> >> On 08.04.2026 11:05, Evgeny Karpov wrote:
> >>> On Wed, Apr 08, 2026, Jan Beulich wrote:
> >>>> On 07.04.2026 19:12, Evgeny Karpov wrote:
> >>>>> On Tue, Apr 07, 2026, Jan Beulich wrote:
> >>>>>> On 07.04.2026 16:47, Evgeny Karpov wrote:
> >>>>>>> On Tue, Apr 07, 2026, Jan Beulich wrote:
> >>>>>>>> On 07.04.2026 11:48, Evgeny Karpov wrote:
> >>>>>>>>> The IAT should be aligned to 8 bytes in aarch64-w64-mingw32, otherwise, it might
> >>>>>>>>> result in relocation issues.
> >>>>>>>>
> >>>>>>>> What is it that makes this different on aarch64? IOW I wonder if this is
> >>>>>>>> going too far or not far enough.
> >>>>>>>>
> >>>>>>>>> binutils/ChangeLog:
> >>>>>>>>>
> >>>>>>>>> 	* dlltool.c (make_head): Update.
> >>>>>>>>
> >>>>>>>> Please either omit the ChangeLog entry, or have it say something meaningful.
> >>>>>>>
> >>>>>>> The updated decription:
> >>>>>>> ---
> >>>>>>> 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.
> >>>>>>
> >>>>>> Much better, thanks. This addresses part of my earlier remark then as well,
> >>>>>> clarifying it's not "too much" that you do. The "too little" aspect remains,
> >>>>>> though: Looking at a random ia64 archive, I see .idata$5 to have 8-byte
> >>>>>> alignment there as well. Shouldn't .idata$5 always have machine-word
> >>>>>> alignment?
> >>>>>
> >>>>> Based on PE Format documentation
> >>>>> https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table
> >>>>>
> >>>>> 4 byte addresses are used for PE32 and 8 byte addresses are used for PE32+.
> >>>>> There is no definition about the alignment, however it might be optional.
> >>>>> 8 byte alignment appears as a requirement for an architecture.
> >>>>> For example, it requires 8 byte alignment for ldr relocation on AArch64.
> >>>>>
> >>>>> Potentially, 8 byte alignment might be applied to all architectures,
> >>>>> however this might not be necessary for other relocations and could
> >>>>> slightly unnecessarily increase the size.
> >>>>
> >>>> Applying 8-byte alignment uniformly might add padding between .idata$4 and
> >>>> .idata$5 for PE32, which likely is unwanted (and possibly is wrong).
> >>>
> >>> Most likely, it does not break the PE format as it has an RVA to IAT, however it is 
> >>> definitely might bring unwanted padding to PE32.
> >>>
> >>>>>>> binutils/ChangeLog:
> >>>>>>>
> >>>>>>>         * dlltool.c (make_head): Add 8 byte alignment.
> >>>>>>
> >>>>>> This sadly still gives the impression of wider a change (all targets) than
> >>>>>> there is.
> >>>>>
> >>>>> It will be changed to "Add 8 byte alignment on AArch64.".
> >>>>
> >>>> If you insist on enforcing the alignment only for Arm64, then the code
> >>>> comment itself also wants extending to clarify why that target is special.
> >>>> As said, I think we should follow what MS tools do and arrange for 4- / 8-
> >>>> byte alignment for all targets.
> >>>
> >>> Based on this suggestion, the patch can be changed to:
> >>>
> >>> +      /* Align IAT (Import Address Table) to 8 bytes for PE32+.
> >>> +        https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table.  */
> >>> +      if (create_for_pep)
> >>> +       fprintf (f, "\t.align 3\n");
> >>
> >> Any reason to then not also go the final small step and use
> >>
> >>        fprintf (f, "\t.p2align %d\n", create_for_pep ? 3 : 2);
> > 
> > It looks like the alignment to 4 is not necessary because it is already aligned to
> > 4 by INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2).
> >  
> 
> Unless this is guaranteed to be the first element in the section, it's dangerous to assume that nothing will appear before it that is not an exact multiple of the alignment.

It is guaranteed to be the first element in the section by PE format.

Regards,
Evgeny



More information about the Binutils mailing list