255 lines
8.8 KiB
Diff
255 lines
8.8 KiB
Diff
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)
|
|
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:
|
|
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*"
|
|
--- /dev/null 2024-06-27 08:39:51.717818400 +0100
|
|
+++ binutils-2.35.2/binutils/testsuite/binutils-all/section-alignment.d 2024-06-27 15:43:00.626529058 +0100
|
|
@@ -0,0 +1,9 @@
|
|
+#source: pr23633.s
|
|
+#PROG: objcopy
|
|
+#objcopy: --section-alignment=512
|
|
+#objdump: -P sections
|
|
+#target: [is_pecoff_format]
|
|
+
|
|
+#...
|
|
+.* Align: 512.*
|
|
+#pass
|