Make objcopy's --section-alignment option also affect sections. Resolves: RHEL-30268

This commit is contained in:
Nick Clifton 2024-04-03 14:26:57 +01:00 committed by root
parent 240a18b49e
commit 04948b0a21
3 changed files with 255 additions and 1 deletions

2
.binutils.metadata Normal file
View File

@ -0,0 +1,2 @@
2dd8d1ce34dc7b1cb2073123e30c4901221835b0 binutils-2.35.2.tar.xz
713b4e570b46156c1d5172c8eba1bec6ac92d8fe binutils-2.19.50.0.1-output-format.sed

View File

@ -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

View File

@ -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 <nickc@redhat.com> - 2.35.2-44
- Make objcopy's --section-alignment option also affect sections. (RHEL-30268)
* Thu Jan 25 2024 Nick Clifton <nickc@redhat.com> - 2.35.2-43
- Do not set version info on unversion symbols. (RHEL-22601)