[v6,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 noticed and followed the convention of putting the operator at the
beginning rather than then end of the line when wrapping an expression.
bfd/peXXigen.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
@@ -4602,21 +4602,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 DataDirectory[%d]: size too large for the containing section"),