From fa463e9fc644e7a3bad39aa73bf6be72ea865805 Mon Sep 17 00:00:00 2001 From: Niklas G?rtler Date: Wed, 28 Aug 2019 12:33:41 +0100 Subject: [PATCH] Add an option to objcopy to change the alignment of sections. PR 24942 * objcopy.c (SECTION_CONTEXT_SET_ALIGNMENT): New constant. (struct section_list): Add alignment field. (command_line_switch): Add OPTION_SET_SECTION_ALIGNMENT. (copy_options): Add --set-section-alignment. (copy_usage): Describe --set-section-alignment. (find_section_list): Initialise the alignment field. (setup_section): Handle the alignment field. (copy_main): Handle OPTION_SET_SECTION_ALIGNMENT. * doc/binutils.texi: Document the new feature. * NEWS: Mention the new feature. --- binutils/ChangeLog | 14 +++++++++++ binutils/NEWS | 3 +++ binutils/doc/binutils.texi | 11 +++++++-- binutils/objcopy.c | 50 +++++++++++++++++++++++++++++++++++--- 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 6ddf000c05b..1148e9d990b 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +2019-08-28 Niklas Gürtler + + PR 24942 + * objcopy.c (SECTION_CONTEXT_SET_ALIGNMENT): New constant. + (struct section_list): Add alignment field. + (command_line_switch): Add OPTION_SET_SECTION_ALIGNMENT. + (copy_options): Add --set-section-alignment. + (copy_usage): Describe --set-section-alignment. + (find_section_list): Initialise the alignment field. + (setup_section): Handle the alignment field. + (copy_main): Handle OPTION_SET_SECTION_ALIGNMENT. + * doc/binutils.texi: Document the new feature. + * NEWS: Mention the new feature. + 2019-08-28 Nick Clifton PR 24931 diff --git a/binutils/NEWS b/binutils/NEWS index c6c4e296029..349af31c36e 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -2,6 +2,9 @@ * Add --source-comment[=] option to objdump which if present, provides a prefix to source code lines displayed in a disassembly. +* Add --set-section-alignment = option to objcopy to allow + the changing of section alignments. + * Add --verilog-data-width option to objcopy for verilog targets to control width of data elements in verilog hex format. diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index f6cdbdb5a7f..bb37cb09884 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -1175,6 +1175,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{--change-section-vma} @var{sectionpattern}@{=,+,-@}@var{val}] [@option{--change-warnings}] [@option{--no-change-warnings}] [@option{--set-section-flags} @var{sectionpattern}=@var{flags}] + [@option{--set-section-alignment} @var{sectionpattern}=@var{align}] [@option{--add-section} @var{sectionname}=@var{filename}] [@option{--dump-section} @var{sectionname}=@var{filename}] [@option{--update-section} @var{sectionname}=@var{filename}] @@ -1620,6 +1621,11 @@ to clear the @samp{contents} flag of a section which does have contents--just remove the section instead. Not all flags are meaningful for all object file formats. +@item --set-section-alignment @var{sectionpattern}=@var{align} +Set the alignment for any sections matching @var{sectionpattern}. @var{align} +specifies the alignment as the exponent for the power of two, i.e. the +alignment in bytes will be 2^@var{align}. + @item --add-section @var{sectionname}=@var{filename} Add a new section named @var{sectionname} while copying the file. The contents of the new section are taken from the file @var{filename}. The @@ -1975,8 +1981,9 @@ for dlls. [This option is specific to PE targets.] @item --section-alignment @var{num} -Sets the section alignment. Sections in memory will always begin at -addresses which are a multiple of this number. Defaults to 0x1000. +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.] @item --stack @var{reserve} diff --git a/binutils/objcopy.c b/binutils/objcopy.c index eb25421c6ec..ebb99339aaa 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -143,10 +143,12 @@ struct section_list #define SECTION_CONTEXT_ALTER_LMA (1 << 5) /* Increment or decrement the section's LMA address. */ #define SECTION_CONTEXT_SET_FLAGS (1 << 6) /* Set the section's flags. */ #define SECTION_CONTEXT_REMOVE_RELOCS (1 << 7) /* Remove relocations for this section. */ +#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 8) /* Set alignment for section. */ bfd_vma vma_val; /* Amount to change by or set to. */ bfd_vma lma_val; /* Amount to change by or set to. */ flagword flags; /* What to set the section flags to. */ + unsigned int alignment; /* Alignment of output section. */ }; static struct section_list *change_sections; @@ -344,8 +346,9 @@ enum command_line_switch OPTION_REMOVE_RELOCS, OPTION_RENAME_SECTION, OPTION_REVERSE_BYTES, - OPTION_SECTION_ALIGNMENT, + OPTION_PE_SECTION_ALIGNMENT, OPTION_SET_SECTION_FLAGS, + OPTION_SET_SECTION_ALIGNMENT, OPTION_SET_START, OPTION_SREC_FORCES3, OPTION_SREC_LEN, @@ -476,8 +479,9 @@ static struct option copy_options[] = {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS}, {"rename-section", required_argument, 0, OPTION_RENAME_SECTION}, {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES}, - {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT}, + {"section-alignment", required_argument, 0, OPTION_PE_SECTION_ALIGNMENT}, {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS}, + {"set-section-alignment", required_argument, 0, OPTION_SET_SECTION_ALIGNMENT}, {"set-start", required_argument, 0, OPTION_SET_START}, {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3}, {"srec-len", required_argument, 0, OPTION_SREC_LEN}, @@ -610,6 +614,8 @@ copy_usage (FILE *stream, int exit_status) Warn if a named section does not exist\n\ --set-section-flags =\n\ Set section 's properties to \n\ + --set-section-alignment =\n\ + Set section 's alignment to 2^ bytes\n\ --add-section = Add section found in to output\n\ --update-section =\n\ Update contents of section with\n\ @@ -964,6 +970,7 @@ find_section_list (const char *name, bfd_boolean add, unsigned int context) p->vma_val = 0; p->lma_val = 0; p->flags = 0; + p->alignment = 0; p->next = change_sections; change_sections = p; @@ -3766,6 +3773,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg) const char * name; char *prefix = NULL; bfd_boolean make_nobits; + unsigned int alignment; if (is_strip_section (ibfd, isection)) return; @@ -3872,11 +3880,18 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg) osection->lma = lma; + p = find_section_list (bfd_section_name (ibfd, isection), FALSE, + SECTION_CONTEXT_SET_ALIGNMENT); + if (p != NULL) + alignment = p->alignment; + else + alignment = bfd_section_alignment (ibfd, isection); + /* FIXME: This is probably not enough. If we change the LMA we may have to recompute the header for the file as well. */ if (!bfd_set_section_alignment (obfd, osection, - bfd_section_alignment (ibfd, isection))) + alignment)) { err = _("failed to set alignment"); goto loser; @@ -5262,6 +5277,33 @@ copy_main (int argc, char *argv[]) } break; + case OPTION_SET_SECTION_ALIGNMENT: + { + struct section_list *p; + const char *s; + int len; + char *name; + int align; + + s = strchr (optarg, '='); + if (s == NULL) + fatal (_("bad format for %s"), "--set-section-alignment"); + + align = atoi(s+1); + if (align < 0) + fatal (_("bad format for %s"), "--set-section-alignment"); + + len = s - optarg; + name = (char *) xmalloc (len + 1); + strncpy (name, optarg, len); + name[len] = '\0'; + + p = find_section_list (name, TRUE, SECTION_CONTEXT_SET_ALIGNMENT); + + p->alignment = align; + } + break; + case OPTION_RENAME_SECTION: { flagword flags; @@ -5457,7 +5499,7 @@ copy_main (int argc, char *argv[]) pe_image_base = parse_vma (optarg, "--image-base"); break; - case OPTION_SECTION_ALIGNMENT: + case OPTION_PE_SECTION_ALIGNMENT: pe_section_alignment = parse_vma (optarg, "--section-alignment"); break;