From 55f9fca6a49220cd7e87ff350f38abc4a28ca589 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 3 Apr 2024 14:26:57 +0100 Subject: [PATCH] Make objcopy's --section-alignment option also affect sections. Resolves: RHEL-30268 --- binutils-objcopy-pe-section-align.patch | 245 ++++++++++++++++++++++++ binutils.spec | 9 +- 2 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 binutils-objcopy-pe-section-align.patch diff --git a/binutils-objcopy-pe-section-align.patch b/binutils-objcopy-pe-section-align.patch new file mode 100644 index 0000000..b758bd0 --- /dev/null +++ b/binutils-objcopy-pe-section-align.patch @@ -0,0 +1,245 @@ +diff -rup binutils.orig/binutils/doc/binutils.texi binutils-2.35.2/binutils/doc/binutils.texi +--- binutils.orig/binutils/doc/binutils.texi 2024-04-03 11:32:37.507595411 +0100 ++++ binutils-2.35.2/binutils/doc/binutils.texi 2024-04-03 11:32:53.188615675 +0100 +@@ -1643,6 +1643,10 @@ above. If @var{sectionpattern} does not + input file, a warning will be issued, unless + @option{--no-change-warnings} is used. + ++Note - changing the VMA of sections in a fully linked binary can be ++dangerous since there may be code that expects the sections to be ++located at their old address. ++ + @item --change-warnings + @itemx --adjust-warnings + If @option{--change-section-address} or @option{--change-section-lma} or +@@ -1671,7 +1675,14 @@ ELF format files. + @item --set-section-alignment @var{sectionpattern}=@var{align} + Set the alignment for any sections matching @var{sectionpattern}. + @var{align} specifies the alignment in bytes and must be a power of +-two, i.e. 1, 2, 4, 8@dots{}. ++two, i.e. 1, 2, 4, 8@dots{}. ++ ++Note - setting a section's alignment will not automatically align its ++LMA or VMA addresses. If those need to be changed as well then the ++@option{--change-section-lma} and/or @option{--change-section-vma} ++options should be used. Also note that changing VMAs can cause ++problems in fully linked binaries where there may be code that expects ++the contents of the sections to be located at their old address. + + @item --add-section @var{sectionname}=@var{filename} + Add a new section named @var{sectionname} while copying the file. The +@@ -2029,11 +2040,21 @@ for dlls. + [This option is specific to PE targets.] + + @item --section-alignment @var{num} +-Sets the section alignment field in the PE header. Sections in memory +-will always begin at addresses which are a multiple of this number. +-Defaults to 0x1000. + [This option is specific to PE targets.] + ++Sets the section alignment field in the PE header - if one is present ++in the binary. Sections in memory will always begin at addresses ++which are a multiple of this number. Defaults to 0x1000. ++ ++Note - this option will also set the alignment field in each section's ++flags. ++ ++Note - if a section's LMA or VMA addresses are no longer aligned, and ++those addresses have not been set via the @option{--set-section-lma} or ++@option{--set-section-vma} options, and the file has been fully ++relocated then a warning message will be issued. It will then be up ++to the user to decide if the LMA and VMA need updating. ++ + @item --stack @var{reserve} + @itemx --stack @var{reserve},@var{commit} + Specify the number of bytes of memory to reserve (and optionally commit) +Only in binutils-2.35.2/binutils/doc: binutils.texi.orig +diff -rup binutils.orig/binutils/objcopy.c binutils-2.35.2/binutils/objcopy.c +--- binutils.orig/binutils/objcopy.c 2024-04-03 11:32:37.862595870 +0100 ++++ binutils-2.35.2/binutils/objcopy.c 2024-04-03 11:32:53.189615676 +0100 +@@ -3954,6 +3954,50 @@ setup_bfd_headers (bfd *ibfd, bfd *obfd) + return; + } + ++static inline signed int ++power_of_two (bfd_vma val) ++{ ++ signed int result = 0; ++ ++ if (val == 0) ++ return 0; ++ ++ while ((val & 1) == 0) ++ { ++ val >>= 1; ++ ++result; ++ } ++ ++ if (val != 1) ++ /* Number has more than one 1, i.e. wasn't a power of 2. */ ++ return -1; ++ ++ return result; ++} ++ ++static unsigned int ++image_scn_align (unsigned int alignment) ++{ ++ switch (alignment) ++ { ++ case 8192: return IMAGE_SCN_ALIGN_8192BYTES; ++ case 4096: return IMAGE_SCN_ALIGN_4096BYTES; ++ case 2048: return IMAGE_SCN_ALIGN_2048BYTES; ++ case 1024: return IMAGE_SCN_ALIGN_1024BYTES; ++ case 512: return IMAGE_SCN_ALIGN_512BYTES; ++ case 256: return IMAGE_SCN_ALIGN_256BYTES; ++ case 128: return IMAGE_SCN_ALIGN_128BYTES; ++ case 64: return IMAGE_SCN_ALIGN_64BYTES; ++ case 32: return IMAGE_SCN_ALIGN_32BYTES; ++ case 16: return IMAGE_SCN_ALIGN_16BYTES; ++ case 8: return IMAGE_SCN_ALIGN_8BYTES; ++ case 4: return IMAGE_SCN_ALIGN_4BYTES; ++ case 2: return IMAGE_SCN_ALIGN_2BYTES; ++ case 1: return IMAGE_SCN_ALIGN_1BYTES; ++ default: return 0; ++ } ++} ++ + /* Create a section in OBFD with the same + name and attributes as ISECTION in IBFD. */ + +@@ -4058,6 +4102,8 @@ setup_section (bfd *ibfd, sec_ptr isecti + goto loser; + } + ++ bfd_boolean vma_set_by_user = FALSE; ++ + vma = bfd_section_vma (isection); + p = find_section_list (bfd_section_name (isection), FALSE, + SECTION_CONTEXT_ALTER_VMA | SECTION_CONTEXT_SET_VMA); +@@ -4067,6 +4113,7 @@ setup_section (bfd *ibfd, sec_ptr isecti + vma = p->vma_val; + else + vma += p->vma_val; ++ vma_set_by_user = TRUE; + } + else + vma += change_section_address; +@@ -4077,6 +4124,8 @@ setup_section (bfd *ibfd, sec_ptr isecti + goto loser; + } + ++ bfd_boolean lma_set_by_user = FALSE; ++ + lma = isection->lma; + p = find_section_list (bfd_section_name (isection), FALSE, + SECTION_CONTEXT_ALTER_LMA | SECTION_CONTEXT_SET_LMA); +@@ -4086,6 +4135,7 @@ setup_section (bfd *ibfd, sec_ptr isecti + lma += p->lma_val; + else + lma = p->lma_val; ++ lma_set_by_user = TRUE; + } + else + lma += change_section_address; +@@ -4096,6 +4146,24 @@ setup_section (bfd *ibfd, sec_ptr isecti + SECTION_CONTEXT_SET_ALIGNMENT); + if (p != NULL) + alignment = p->alignment; ++ else if (pe_section_alignment != (bfd_vma) -1 ++ && bfd_get_flavour (obfd) == bfd_target_coff_flavour) ++ { ++ alignment = power_of_two (pe_section_alignment); ++ ++ if (coff_section_data (ibfd, isection)) ++ { ++ struct pei_section_tdata * pei_data = pei_section_data (ibfd, isection); ++ ++ if (pei_data != NULL) ++ { ++ /* Set the alignment flag of the input section, which will ++ be copied to the output section later on. */ ++ pei_data->pe_flags &= ~IMAGE_SCN_ALIGN_POWER_BIT_MASK; ++ pei_data->pe_flags |= image_scn_align (pe_section_alignment); ++ } ++ } ++ } + else + alignment = bfd_section_alignment (isection); + +@@ -4107,6 +4175,32 @@ setup_section (bfd *ibfd, sec_ptr isecti + goto loser; + } + ++ /* If the output section's VMA is not aligned ++ and the alignment has changed ++ and the VMA was not set by the user ++ and the section does not have relocations associated with it ++ then warn the user. */ ++ if (osection->vma & ((1 << alignment) - 1) ++ && alignment != bfd_section_alignment (isection) ++ && change_section_address == 0 ++ && ! vma_set_by_user ++ && bfd_get_reloc_upper_bound (ibfd, isection) < 1) ++ { ++ non_fatal (_("output section %s's alignment does not match its VMA"), name); ++ } ++ ++ /* Similar check for a non-aligned LMA. ++ FIXME: Since this is only an LMA, maybe it does not matter if ++ it is not aligned ? */ ++ if (osection->lma & ((1 << alignment) - 1) ++ && alignment != bfd_section_alignment (isection) ++ && change_section_address == 0 ++ && ! lma_set_by_user ++ && bfd_get_reloc_upper_bound (ibfd, isection) < 1) ++ { ++ non_fatal (_("output section %s's alignment does not match its LMA"), name); ++ } ++ + /* Copy merge entity size. */ + osection->entsize = isection->entsize; + +@@ -5530,15 +5624,8 @@ copy_main (int argc, char *argv[]) + fatal (_("bad format for --set-section-alignment: numeric argument needed")); + + /* Convert integer alignment into a power-of-two alignment. */ +- palign = 0; +- while ((align & 1) == 0) +- { +- align >>= 1; +- ++palign; +- } +- +- if (align != 1) +- /* Number has more than on 1, i.e. wasn't a power of 2. */ ++ palign = power_of_two (align); ++ if (palign == -1) + fatal (_("bad format for --set-section-alignment: alignment is not a power of two")); + + /* Add the alignment setting to the section list. */ +@@ -5751,6 +5838,11 @@ copy_main (int argc, char *argv[]) + case OPTION_PE_SECTION_ALIGNMENT: + pe_section_alignment = parse_vma (optarg, + "--section-alignment"); ++ if (power_of_two (pe_section_alignment) == -1) ++ { ++ non_fatal (_("--section-alignment argument is not a power of two: %s - ignoring"), optarg); ++ pe_section_alignment = (bfd_vma) -1; ++ } + break; + + case OPTION_SUBSYSTEM: +Only in binutils-2.35.2/binutils/: objcopy.c.orig +diff -rup binutils.orig/binutils/testsuite/binutils-all/objcopy.exp binutils-2.35.2/binutils/testsuite/binutils-all/objcopy.exp +--- binutils.orig/binutils/testsuite/binutils-all/objcopy.exp 2024-04-03 11:32:37.781595765 +0100 ++++ binutils-2.35.2/binutils/testsuite/binutils-all/objcopy.exp 2024-04-03 11:33:00.878625614 +0100 +@@ -1342,6 +1342,7 @@ objcopy_remove_relocations_from_executab + run_dump_test "pr23633" + + run_dump_test "set-section-alignment" ++run_dump_test "section-alignment" + + setup_xfail "hppa*-*-*" + setup_xfail "sh-*-coff*" +Only in binutils-2.35.2/binutils/testsuite/binutils-all: objcopy.exp.orig diff --git a/binutils.spec b/binutils.spec index dc253bf..9d830c1 100644 --- a/binutils.spec +++ b/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: binutils%{?_with_debug:-debug} Version: 2.35.2 -Release: 43%{?dist} +Release: 44%{?dist} License: GPLv3+ URL: https://sourceware.org/binutils @@ -445,6 +445,10 @@ Patch66: binutils-aarch64-flagm.patch # Lifetime: Fixed in 2.38 Patch67: binutils-verdef.patch +# Purpose: Make objcopy's --section-alignment option also affect sections. +# Lifetime: Fixed in 2.43 +Patch68: binutils-objcopy-pe-section-align.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -1285,6 +1289,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Thu Jan 25 2024 Nick Clifton - 2.35.2-44 +- Make objcopy's --section-alignment option also affect sections. (RHEL-30268) + * Thu Jan 25 2024 Nick Clifton - 2.35.2-43 - Do not set version info on unversion symbols. (RHEL-22601)