[v5,3/3] bfd: add load config size workaround for i386 XP and earlier.
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-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
Commit Message
Per the Microsoft PE documentation, XP and earlier on i686 require the
Size field to be 64, rather than the actual size as required on other
architectures. I have confirmed Windows 11 accepts either 64 or the
actual size for i386 images, but only the actual size for x86_64 images.
Signed-off-by: Jeremy Drake <sourceware-bugzilla@jdrake.com>
---
I decided to go ahead and send v5 of the patch series. I figure you can
take or leave patch 3, depending on how convincing LIU Hao's argument for
supporting XP is.
bfd/peXXigen.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
Comments
在 2025-4-3 06:56, Jeremy Drake 写道:
> Per the Microsoft PE documentation, XP and earlier on i686 require the
> Size field to be 64, rather than the actual size as required on other
> architectures. I have confirmed Windows 11 accepts either 64 or the
> actual size for i386 images, but only the actual size for x86_64 images.
>
> Signed-off-by: Jeremy Drake <sourceware-bugzilla@jdrake.com>
> ---
> I decided to go ahead and send v5 of the patch series. I figure you can
> take or leave patch 3, depending on how convincing LIU Hao's argument for
> supporting XP is.
>
> bfd/peXXigen.c | 26 +++++++++++++++++---------
> 1 file changed, 17 insertions(+), 9 deletions(-)
>
These changes look good to me.
```
MINGW32 ~/Desktop
$ gcc hello.c -Wl,--subsystem,windows:5.1 -Wl,--undefined,__load_config_used \
> && objdump -p a.exe | grep -Fi "load configuration directory"
Entry a 000042ec 00000040 Load Configuration Directory
MINGW32 ~/Desktop
$ gcc hello.c -Wl,--subsystem,windows:5.2 -Wl,--undefined,__load_config_used \
> && objdump -p a.exe | grep -Fi "load configuration directory"
Entry a 000042ec 000000bc Load Configuration Directory
MINGW64 ~/Desktop
$ gcc hello.c -Wl,--subsystem,windows:5.1 -Wl,--undefined,_load_config_used \
> && objdump -p a.exe | grep -Fi "load configuration directory"
Entry a 0000000000004348 00000138 Load Configuration Directory
MINGW64 ~/Desktop
$ gcc hello.c -Wl,--subsystem,windows:5.2 -Wl,--undefined,_load_config_used \
> && objdump -p a.exe | grep -Fi "load configuration directory"
Entry a 0000000000004348 00000138 Load Configuration Directory
```
--
Best regards,
LIU Hao
On 03.04.2025 00:56, Jeremy Drake wrote:
> Per the Microsoft PE documentation, XP and earlier on i686 require the
> Size field to be 64, rather than the actual size as required on other
> architectures. I have confirmed Windows 11 accepts either 64 or the
> actual size for i386 images, but only the actual size for x86_64 images.
>
> Signed-off-by: Jeremy Drake <sourceware-bugzilla@jdrake.com>
> ---
> I decided to go ahead and send v5 of the patch series. I figure you can
> take or leave patch 3, depending on how convincing LIU Hao's argument for
> supporting XP is.
Since you've taken the time to write it, I don't see a reason to not put
it in: Okay.
Jan
@@ -4601,21 +4601,29 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
result = false;
}
- /* The size is stored as the first 4 bytes at _load_config_used.
- The Microsoft PE format documentation says for compatibility with
- Windows XP and earlier, the size must be 64 for x86 images. If
- anyone cares about those versions, the size should be overridden
- for i386. */
+ /* The size is stored as the first 4 bytes at _load_config_used. */
if (bfd_get_section_contents (abfd,
h1->root.u.def.section->output_section, data,
h1->root.u.def.section->output_offset + h1->root.u.def.value,
4))
{
+ uint32_t size = bfd_get_32 (abfd, data);
+ /* The Microsoft PE format documentation says for compatibility
+ with Windows XP and earlier, the size must be 64 for x86
+ images. */
pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].Size =
- bfd_get_32 (abfd, data);
-
- if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].Size >
- h1->root.u.def.section->size - h1->root.u.def.value)
+ (bfd_get_arch (abfd) == bfd_arch_i386 &&
+ (bfd_get_mach (abfd) & ~bfd_mach_i386_intel_syntax) ==
+ bfd_mach_i386_i386 &&
+ (pe_data (abfd)->pe_opthdr.Subsystem ==
+ IMAGE_SUBSYSTEM_WINDOWS_GUI ||
+ pe_data (abfd)->pe_opthdr.Subsystem ==
+ IMAGE_SUBSYSTEM_WINDOWS_CUI) &&
+ pe_data (abfd)->pe_opthdr.MajorSubsystemVersion * 256 +
+ pe_data (abfd)->pe_opthdr.MinorSubsystemVersion <= 0x0501)
+ ? 64 : size;
+
+ if (size > h1->root.u.def.section->size - h1->root.u.def.value)
{
_bfd_error_handler
(_("%pB: unable to fill in DataDictionary[%d]: size too large for the containing section"),