Fix IAT (Import Address Table) alignment on AArch64
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Test passed
|
Commit Message
The IAT should be aligned to 8 bytes in aarch64-w64-mingw32, otherwise, it might
result in relocation issues.
binutils/ChangeLog:
* dlltool.c (make_head): Update.
---
binutils/dlltool.c | 5 +++++
1 file changed, 5 insertions(+)
Comments
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.
Jan
> --- a/binutils/dlltool.c
> +++ b/binutils/dlltool.c
> @@ -2735,6 +2735,11 @@ make_head (void)
> if (!no_idata5)
> {
> fprintf (f, "\t.section\t.idata$5\n");
> +
> + /* IAT (Import Address Table) should be aligned to 8 on AArch64. */
> + if (machine == MAARCH64)
> + fprintf (f, "\t.align 3\n");
> +
> if (use_nul_prefixed_import_tables)
> {
> if (create_for_pep)
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.
binutils/ChangeLog:
* dlltool.c (make_head): Add 8 byte alignment.
---
Regards,
Evgeny
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?
> 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.
Jan
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.
> > 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.".
Regards,
Evgeny
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).
>>> 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.
Jan
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");
and the description can be updated with:
"This patch fixes this issue by aligning IAT to 8 bytes for PE32+."
Regards,
Evgeny
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);
? (Note that you can't use .align when no longer targeting a specific arch;
it needs to be .balign or .p2align.)
Jan
> and the description can be updated with:
> "This patch fixes this issue by aligning IAT to 8 bytes for PE32+."
>
> Regards,
> Evgeny
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).
> ? (Note that you can't use .align when no longer targeting a specific arch;
> it needs to be .balign or .p2align.)
It will be changed to .p2align.
Regards,
Evgeny
On 08.04.2026 11: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).
Hmm, good point, yet then wouldn't we better correct things there? And then
also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
approach could be to edit those tables at runtime. (Preferably we'd solve
this differently though, e.g. by setting .align to -1 to indicate 2 or 3
want using depending on the target.)
Jan
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.
>> ? (Note that you can't use .align when no longer targeting a specific arch;
>> it needs to be .balign or .p2align.)
>
> It will be changed to .p2align.
>
> Regards,
> Evgeny
On 08.04.2026 11:38, 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.
Sure, but dlltool fully controls what is emitted into the various .idata$<n>.
Jan
On Wed, Apr 08, 2026, Jan Beulich wrote:
> On 08.04.2026 11: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).
>
> Hmm, good point, yet then wouldn't we better correct things there? And then
> also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
> approach could be to edit those tables at runtime. (Preferably we'd solve
> this differently though, e.g. by setting .align to -1 to indicate 2 or 3
> want using depending on the target.)
It might be better to keep default 4 byte alignment for readability.
It turns the change into following:
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) alignemnt to 8 bytes
+ for PE32+.
+ https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table. */
+ secdata[IDATA5].align = 3;
+ secdata_delay[IDATA5].align = 3;
+ }
+
Regards,
Evgeny
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
On 08.04.2026 12:30, Evgeny Karpov wrote:
> On Wed, Apr 08, 2026, Jan Beulich wrote:
>> On 08.04.2026 11: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).
>>
>> Hmm, good point, yet then wouldn't we better correct things there? And then
>> also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
>> approach could be to edit those tables at runtime. (Preferably we'd solve
>> this differently though, e.g. by setting .align to -1 to indicate 2 or 3
>> want using depending on the target.)
>
> It might be better to keep default 4 byte alignment for readability.
> It turns the change into following:
>
> 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) alignemnt to 8 bytes
> + for PE32+.
> + https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table. */
> + secdata[IDATA5].align = 3;
I guess you mean secdata_plain[] here? Other than that I think all that is
now needed is a clean v2 submission.
Jan
> + secdata_delay[IDATA5].align = 3;
> + }
> +
>
> Regards,
> Evgeny
>
On Wed, Apr 08, 2026, Jan Beulich wrote:
> On 08.04.2026 12:30, Evgeny Karpov wrote:
> > On Wed, Apr 08, 2026, Jan Beulich wrote:
> >> On 08.04.2026 11: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).
> >>
> >> Hmm, good point, yet then wouldn't we better correct things there? And then
> >> also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
> >> approach could be to edit those tables at runtime. (Preferably we'd solve
> >> this differently though, e.g. by setting .align to -1 to indicate 2 or 3
> >> want using depending on the target.)
> >
> > It might be better to keep default 4 byte alignment for readability.
> > It turns the change into following:
> >
> > 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) alignemnt to 8 bytes
> > + for PE32+.
> > + https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table. */
> > + secdata[IDATA5].align = 3;
>
> I guess you mean secdata_plain[] here? Other than that I think all that is
> now needed is a clean v2 submission.
Actually, applying alignment in secdata_plain is already too late, and it
should be done in the header for .idata$5 before the first chunk symbol,
as it was done initially. In most cases, the default alignment is 4, and
only alignment to PE32+ needs to be adjusted.
As discussed earlier, that can be done by making this change in make_head:
if (create_for_pep)
fprintf (f, "\t.p2align 3\n");
Regards,
Evgeny
On 09.04.2026 10:10, Evgeny Karpov wrote:
> On Wed, Apr 08, 2026, Jan Beulich wrote:
>> On 08.04.2026 12:30, Evgeny Karpov wrote:
>>> On Wed, Apr 08, 2026, Jan Beulich wrote:
>>>> On 08.04.2026 11: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).
>>>>
>>>> Hmm, good point, yet then wouldn't we better correct things there? And then
>>>> also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
>>>> approach could be to edit those tables at runtime. (Preferably we'd solve
>>>> this differently though, e.g. by setting .align to -1 to indicate 2 or 3
>>>> want using depending on the target.)
>>>
>>> It might be better to keep default 4 byte alignment for readability.
>>> It turns the change into following:
>>>
>>> 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) alignemnt to 8 bytes
>>> + for PE32+.
>>> + https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table. */
>>> + secdata[IDATA5].align = 3;
>>
>> I guess you mean secdata_plain[] here? Other than that I think all that is
>> now needed is a clean v2 submission.
>
> Actually, applying alignment in secdata_plain is already too late, and it
> should be done in the header for .idata$5 before the first chunk symbol,
> as it was done initially.
I fear I don't understand: When modifying secdata_{plain,delay}[] right
after setting create_for_pep, how can that be too late? gen_lib_file()
(and hence make_one_lib_file()) is only called later.
Jan
On Thu, Apr 09, 2026, Jan Beulich wrote:
> On 09.04.2026 10:10, Evgeny Karpov wrote:
> > On Wed, Apr 08, 2026, Jan Beulich wrote:
> >> On 08.04.2026 12:30, Evgeny Karpov wrote:
> >>> On Wed, Apr 08, 2026, Jan Beulich wrote:
> >>>> On 08.04.2026 11: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).
> >>>>
> >>>> Hmm, good point, yet then wouldn't we better correct things there? And then
> >>>> also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
> >>>> approach could be to edit those tables at runtime. (Preferably we'd solve
> >>>> this differently though, e.g. by setting .align to -1 to indicate 2 or 3
> >>>> want using depending on the target.)
> >>>
> >>> It might be better to keep default 4 byte alignment for readability.
> >>> It turns the change into following:
> >>>
> >>> 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) alignemnt to 8 bytes
> >>> + for PE32+.
> >>> + https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table. */
> >>> + secdata[IDATA5].align = 3;
> >>
> >> I guess you mean secdata_plain[] here? Other than that I think all that is
> >> now needed is a clean v2 submission.
> >
> > Actually, applying alignment in secdata_plain is already too late, and it
> > should be done in the header for .idata$5 before the first chunk symbol,
> > as it was done initially.
>
> I fear I don't understand: When modifying secdata_{plain,delay}[] right
> after setting create_for_pep, how can that be too late? gen_lib_file()
> (and hence make_one_lib_file()) is only called later.
There is a sequence of .idata$5 sections that starts with a section created
by using make_head.
Regards,
Evgeny
On 09.04.2026 13:21, Evgeny Karpov wrote:
> On Thu, Apr 09, 2026, Jan Beulich wrote:
>> On 09.04.2026 10:10, Evgeny Karpov wrote:
>>> On Wed, Apr 08, 2026, Jan Beulich wrote:
>>>> On 08.04.2026 12:30, Evgeny Karpov wrote:
>>>>> On Wed, Apr 08, 2026, Jan Beulich wrote:
>>>>>> On 08.04.2026 11: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).
>>>>>>
>>>>>> Hmm, good point, yet then wouldn't we better correct things there? And then
>>>>>> also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
>>>>>> approach could be to edit those tables at runtime. (Preferably we'd solve
>>>>>> this differently though, e.g. by setting .align to -1 to indicate 2 or 3
>>>>>> want using depending on the target.)
>>>>>
>>>>> It might be better to keep default 4 byte alignment for readability.
>>>>> It turns the change into following:
>>>>>
>>>>> 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) alignemnt to 8 bytes
>>>>> + for PE32+.
>>>>> + https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table. */
>>>>> + secdata[IDATA5].align = 3;
>>>>
>>>> I guess you mean secdata_plain[] here? Other than that I think all that is
>>>> now needed is a clean v2 submission.
>>>
>>> Actually, applying alignment in secdata_plain is already too late, and it
>>> should be done in the header for .idata$5 before the first chunk symbol,
>>> as it was done initially.
>>
>> I fear I don't understand: When modifying secdata_{plain,delay}[] right
>> after setting create_for_pep, how can that be too late? gen_lib_file()
>> (and hence make_one_lib_file()) is only called later.
>
> There is a sequence of .idata$5 sections that starts with a section created
> by using make_head.
Which means what exactly wrt me pointing out that gen_lib_file() (and hence
make_head()) run much later than the editing of the two tables (in main())?
Jan
On Thu, Apr 09, 2026, Jan Beulich wrote:
> On 09.04.2026 13:21, Evgeny Karpov wrote:
> > On Thu, Apr 09, 2026, Jan Beulich wrote:
> >> On 09.04.2026 10:10, Evgeny Karpov wrote:
> >>> On Wed, Apr 08, 2026, Jan Beulich wrote:
> >>>> On 08.04.2026 12:30, Evgeny Karpov wrote:
> >>>>> On Wed, Apr 08, 2026, Jan Beulich wrote:
> >>>>>> On 08.04.2026 11: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).
> >>>>>>
> >>>>>> Hmm, good point, yet then wouldn't we better correct things there? And then
> >>>>>> also for .didat? secdata_{plain,delay}[] aren't even const, so a "rude"
> >>>>>> approach could be to edit those tables at runtime. (Preferably we'd solve
> >>>>>> this differently though, e.g. by setting .align to -1 to indicate 2 or 3
> >>>>>> want using depending on the target.)
> >>>>>
> >>>>> It might be better to keep default 4 byte alignment for readability.
> >>>>> It turns the change into following:
> >>>>>
> >>>>> 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) alignemnt to 8 bytes
> >>>>> + for PE32+.
> >>>>> + https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table. */
> >>>>> + secdata[IDATA5].align = 3;
> >>>>
> >>>> I guess you mean secdata_plain[] here? Other than that I think all that is
> >>>> now needed is a clean v2 submission.
> >>>
> >>> Actually, applying alignment in secdata_plain is already too late, and it
> >>> should be done in the header for .idata$5 before the first chunk symbol,
> >>> as it was done initially.
> >>
> >> I fear I don't understand: When modifying secdata_{plain,delay}[] right
> >> after setting create_for_pep, how can that be too late? gen_lib_file()
> >> (and hence make_one_lib_file()) is only called later.
> >
> > There is a sequence of .idata$5 sections that starts with a section created
> > by using make_head.
>
> Which means what exactly wrt me pointing out that gen_lib_file() (and hence
> make_head()) run much later than the editing of the two tables (in main())?
It looks like make_one_lib_file uses the alignment from secdata_plain to create
.idata$5 section, which will be placed after .idata$5 head section created by
make_head. make_head does not have an alignment without the patch introduced earlier.
however it has a reference to the first chunk, that should be aligned.
And the order is defined later in gen_lib_file.
Regards,
Evgeny
On 09.04.2026 16:40, Evgeny Karpov wrote:
> It looks like make_one_lib_file uses the alignment from secdata_plain to create
> .idata$5 section, which will be placed after .idata$5 head section created by
> make_head. make_head does not have an alignment without the patch introduced earlier.
> however it has a reference to the first chunk, that should be aligned.
> And the order is defined later in gen_lib_file.
Hmm, isn't it then a/the problem that make_head() doesn't consult the secdata
variant in use at all? Shouldn't it emit an alignment directive in all cases
(for 32-bit targets 4-byte alignment ought to also be needed)? And aren't
other .idata$<N> (except .idata$7) having the same issue then? The 4-byte
alignment presently looks to merely be an effect of gas / libbfd (for COFF)
giving all sections at least that alignment (specifically
COFF_DEFAULT_SECTION_ALIGNMENT_POWER, which some targets also set to less
than 2).
Further .idata$4 looks to also want 8-byte alignment for PE32+, judging from
the data that is being put there.
Jan
On Fri, Apr 10, 2026, Jan Beulich wrote:
> Hmm, isn't it then a/the problem that make_head() doesn't consult the secdata
> variant in use at all? Shouldn't it emit an alignment directive in all cases
> (for 32-bit targets 4-byte alignment ought to also be needed)? And aren't
> other .idata$<N> (except .idata$7) having the same issue then? The 4-byte
> alignment presently looks to merely be an effect of gas / libbfd (for COFF)
> giving all sections at least that alignment (specifically
> COFF_DEFAULT_SECTION_ALIGNMENT_POWER, which some targets also set to less
> than 2).
>
> Further .idata$4 looks to also want 8-byte alignment for PE32+, judging from
> the data that is being put there.
The main point here is that the first chunk in IAT should be aligned on AArch64
because of the relocation requirement for ldr.
The alignment for other architectures and other sections is optional.
It means the alignment is only required for the first chunk in IAT for AArch64
to resolve the relocation issues, and the rest is optional.
The change in make_head is sufficient.
v2 might stay as it is only for AArch64, or wider for PE32+.
Regards,
Evgeny
@@ -2735,6 +2735,11 @@ make_head (void)
if (!no_idata5)
{
fprintf (f, "\t.section\t.idata$5\n");
+
+ /* IAT (Import Address Table) should be aligned to 8 on AArch64. */
+ if (machine == MAARCH64)
+ fprintf (f, "\t.align 3\n");
+
if (use_nul_prefixed_import_tables)
{
if (create_for_pep)