From: Jan Beulich Date: Mon, 13 Nov 2017 11:26:12 +0000 (+0100) Subject: PE: don't corrupt section flags when linking from ELF objects X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5be87c8fa74c9ae6684bea571b4157ad1966d008;p=binutils-gdb.git PE: don't corrupt section flags when linking from ELF objects Linking EFI executables from ELF object files can result in corrupted COFF section flags if the section's alignment is too high. Issue a diagnostic in that case, erroring out if this is not a final link, and make sure only in-range values get written to the output image. While doing this also make tic80 use the generic alignment macros instead of custom #ifdef-ary. No testsuite regressions for the range of COFF/PE targets that actually cross-build in the first place on x86-64-linux. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d1b995a67f3..70d4e56fedf 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2017-11-13 Jan Beulich + + * coff-tic80.c (COFF_ENCODE_ALIGNMENT, COFF_DECODE_ALIGNMENT): + Define. + * coffcode.h (coff_set_alignment_hook): Drop tic80 special case. + (coff_write_object_contents): Likewise. Issue diagnostic for too + large alignment. + 2017-11-12 H.J. Lu PR ld/22423 diff --git a/bfd/coff-tic80.c b/bfd/coff-tic80.c index 253ea94e878..d23a6f47edb 100644 --- a/bfd/coff-tic80.c +++ b/bfd/coff-tic80.c @@ -42,6 +42,8 @@ #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) #define COFF_ALIGN_IN_SECTION_HEADER 1 #define COFF_ALIGN_IN_SFLAGS 1 +#define COFF_ENCODE_ALIGNMENT(S,X) ((S).s_flags |= (((unsigned)(X) & 0xf) << 8)) +#define COFF_DECODE_ALIGNMENT(X) (((X) >> 8) & 0xf) #define GET_SCNHDR_FLAGS H_GET_16 #define PUT_SCNHDR_FLAGS H_PUT_16 diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 6da0afa26d2..604ba6d8d91 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1855,10 +1855,6 @@ coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED, if ((1 << i) >= hdr->s_align) break; #endif -#ifdef TIC80COFF - /* TI tools puts the alignment power in bits 8-11. */ - i = (hdr->s_flags >> 8) & 0xF ; -#endif #ifdef COFF_DECODE_ALIGNMENT i = COFF_DECODE_ALIGNMENT(hdr->s_flags); #endif @@ -3865,12 +3861,25 @@ coff_write_object_contents (bfd * abfd) ? 1 << current->alignment_power : 0); #endif -#ifdef TIC80COFF - /* TI COFF puts the alignment power in bits 8-11 of the flags. */ - section.s_flags |= (current->alignment_power & 0xF) << 8; -#endif #ifdef COFF_ENCODE_ALIGNMENT COFF_ENCODE_ALIGNMENT(section, current->alignment_power); + if ((unsigned int)COFF_DECODE_ALIGNMENT(section.s_flags) + != current->alignment_power) + { + bfd_boolean warn = coff_data (abfd)->link_info + && !bfd_link_relocatable (coff_data (abfd)->link_info); + + _bfd_error_handler + /* xgettext:c-format */ + (_("%B:%s section %s: alignment 2**%u not representable"), + abfd, warn ? " warning:" : "", current->name, + current->alignment_power); + if (!warn) + { + bfd_set_error (bfd_error_nonrepresentable_section); + return FALSE; + } + } #endif #ifdef COFF_IMAGE_WITH_PE diff --git a/include/ChangeLog b/include/ChangeLog index dc320cb019b..a6e3ebcb973 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2017-11-13 Jan Beulich + + * coff/pe.h (COFF_ENCODE_ALIGNMENT): Cap value to maximum one + representable. + (COFF_DECODE_ALIGNMENT): Define. + 2017-11-09 Tamar Christina * opcode/aarch64.h (AARCH64_ARCH_V8_4): Enable DOTPROD. diff --git a/include/coff/pe.h b/include/coff/pe.h index f51ceedca00..5239916e604 100644 --- a/include/coff/pe.h +++ b/include/coff/pe.h @@ -104,7 +104,10 @@ /* Encode alignment power into IMAGE_SCN_ALIGN bits of s_flags. */ #define COFF_ENCODE_ALIGNMENT(SECTION, ALIGNMENT_POWER) \ - ((SECTION).s_flags |= IMAGE_SCN_ALIGN_POWER_CONST ((ALIGNMENT_POWER))) + ((SECTION).s_flags |= IMAGE_SCN_ALIGN_POWER_CONST ((ALIGNMENT_POWER) <= 13 \ + ? (ALIGNMENT_POWER) : 13)) +#define COFF_DECODE_ALIGNMENT(X) \ + IMAGE_SCN_ALIGN_POWER_NUM ((X) & IMAGE_SCN_ALIGN_POWER_BIT_MASK) #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */ #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */