From: Jeremy Drake Date: Mon, 7 Apr 2025 11:19:28 +0000 (+0200) Subject: bfd: add load config size workaround for i386 XP and earlier X-Git-Tag: binutils-2_45~953 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcdce142519644cdc359b3a7bc6eca6985e44c88;p=thirdparty%2Fbinutils-gdb.git bfd: add load config size workaround for i386 XP and earlier 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 --- diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index f63a7b6f11a..9938108ce6b 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -4602,22 +4602,30 @@ _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 ((bfd_vma) 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 DataDirectory[%d]: size too large for the containing section"),