diff options
-rw-r--r-- | binutils/ChangeLog | 27 | ||||
-rw-r--r-- | binutils/NEWS | 5 | ||||
-rw-r--r-- | binutils/doc/binutils.texi | 58 | ||||
-rw-r--r-- | binutils/objcopy.c | 63 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/objcopy.exp | 8 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/remove-relocs-01.d | 16 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/remove-relocs-01.s | 19 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/remove-relocs-02.d | 6 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/remove-relocs-03.d | 6 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/remove-relocs-04.d | 11 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/remove-relocs-05.d | 17 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/remove-relocs-06.d | 11 |
12 files changed, 242 insertions, 5 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f5b45d8..6b8f226 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,5 +1,32 @@ 2016-07-14 Andrew Burgess <andrew.burgess@embecosm.com> + * doc/binutils.texi (objcopy): Document 'remove-relocations'. + (strip): Likewise. + * objcopy.c (SECTION_CONTEXT_REMOVE_RELOCS): Define. + (enum command_line_switch): Add 'OPTION_REMOVE_RELOCS'. + (struct option strip_options): Add 'remove-relocations'. + (struct option copy_options): Likewise. + (copy_usage): Likewise. + (strip_usage): Likewise. + (handle_remove_relocations_option): New function. + (discard_relocations): New function. + (handle_remove_section_option): New function. + (copy_relocations_in_section): Use discard_relocations. + (strip_main): Use handle_remove_section_option for + 'remove-section', and handle 'remove-relocations' option. + (copy_main): Likewise. + * testsuite/binutils-all/objcopy.exp: Run new tests. + * testsuite/binutils-all/remove-relocs-01.d: New file. + * testsuite/binutils-all/remove-relocs-01.s: New file. + * testsuite/binutils-all/remove-relocs-02.d: New file. + * testsuite/binutils-all/remove-relocs-03.d: New file. + * testsuite/binutils-all/remove-relocs-04.d: New file. + * testsuite/binutils-all/remove-relocs-05.d: New file. + * testsuite/binutils-all/remove-relocs-06.d: New file. + * NEWS: Mention new option. + +2016-07-14 Andrew Burgess <andrew.burgess@embecosm.com> + * objcopy.c (find_section_list): Handle section patterns starting with '!' being a non-matching pattern. * doc/binutils.texi (objcopy): Give example of using '!' with diff --git a/binutils/NEWS b/binutils/NEWS index 9625cf4..56adfa2 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -10,6 +10,11 @@ A non-matching section is removed from the set of sections matched by an earlier --only-section pattern. +* New --remove-relocations=SECTIONPATTERN option for objcopy and strip. + This option can be used to remove sections containing relocations. + The SECTIONPATTERN is the section to which the relocations apply, not + the relocation section itself. + Changes in 2.27: * Add a configure option, --enable-64-bit-archive, to force use of a diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index d77bc86..5a564ef 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -1075,6 +1075,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] [@option{--interleave-width=}@var{width}] [@option{-j} @var{sectionpattern}|@option{--only-section=}@var{sectionpattern}] [@option{-R} @var{sectionpattern}|@option{--remove-section=}@var{sectionpattern}] + [@option{--remove-relocations=}@var{sectionpattern}] [@option{-p}|@option{--preserve-dates}] [@option{-D}|@option{--enable-deterministic-archives}] [@option{-U}|@option{--disable-deterministic-archives}] @@ -1254,6 +1255,34 @@ would otherwise remove it. For example: will remove all sections matching the pattern '.text.*', but will not remove the section '.text.foo'. +@item --remove-relocations=@var{sectionpattern} +Remove relocations from the output file for any section matching +@var{sectionpattern}. This option may be given more than once. Note +that using this option inappropriately may make the output file +unusable. Wildcard characters are accepted in @var{sectionpattern}. +For example: + +@smallexample + --remove-relocations=.text.* +@end smallexample + +will remove the relocations for all sections matching the patter +'.text.*'. + +If the first character of @var{sectionpattern} is the exclamation +point (!) then matching sections will not have their relocation +removed even if an earlier use of @option{--remove-relocations} on the +same command line would otherwise cause the relocations to be removed. +For example: + +@smallexample + --remove-relocations=.text.* --remove-relocations=!.text.foo +@end smallexample + +will remove all relocations for sections matching the pattern +'.text.*', but will not remove relocations for the section +'.text.foo'. + @item -S @itemx --strip-all Do not copy relocation and symbol information from the source file. @@ -2988,6 +3017,7 @@ strip [@option{-F} @var{bfdname} |@option{--target=}@var{bfdname}] [@option{-w}|@option{--wildcard}] [@option{-x}|@option{--discard-all}] [@option{-X} |@option{--discard-locals}] [@option{-R} @var{sectionname} |@option{--remove-section=}@var{sectionname}] + [@option{--remove-relocations=}@var{sectionpattern}] [@option{-o} @var{file}] [@option{-p}|@option{--preserve-dates}] [@option{-D}|@option{--enable-deterministic-archives}] [@option{-U}|@option{--disable-deterministic-archives}] @@ -3057,6 +3087,34 @@ would otherwise remove it. For example: will remove all sections matching the pattern '.text.*', but will not remove the section '.text.foo'. +@item --remove-relocations=@var{sectionpattern} +Remove relocations from the output file for any section matching +@var{sectionpattern}. This option may be given more than once. Note +that using this option inappropriately may make the output file +unusable. Wildcard characters are accepted in @var{sectionpattern}. +For example: + +@smallexample + --remove-relocations=.text.* +@end smallexample + +will remove the relocations for all sections matching the patter +'.text.*'. + +If the first character of @var{sectionpattern} is the exclamation +point (!) then matching sections will not have their relocation +removed even if an earlier use of @option{--remove-relocations} on the +same command line would otherwise cause the relocations to be removed. +For example: + +@smallexample + --remove-relocations=.text.* --remove-relocations=!.text.foo +@end smallexample + +will remove all relocations for sections matching the pattern +'.text.*', but will not remove relocations for the section +'.text.foo'. + @item -s @itemx --strip-all Remove all symbols. diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 41ccc76..cf3f983 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -139,6 +139,7 @@ struct section_list #define SECTION_CONTEXT_SET_LMA (1 << 4) /* Set the sections' LMA address. */ #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. */ bfd_vma vma_val; /* Amount to change by or set to. */ bfd_vma lma_val; /* Amount to change by or set to. */ @@ -326,6 +327,7 @@ enum command_line_switch OPTION_REDEFINE_SYM, OPTION_REDEFINE_SYMS, OPTION_REMOVE_LEADING_CHAR, + OPTION_REMOVE_RELOCS, OPTION_RENAME_SECTION, OPTION_REVERSE_BYTES, OPTION_SECTION_ALIGNMENT, @@ -367,6 +369,7 @@ static struct option strip_options[] = {"output-target", required_argument, 0, 'O'}, {"preserve-dates", no_argument, 0, 'p'}, {"remove-section", required_argument, 0, 'R'}, + {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS}, {"strip-all", no_argument, 0, 's'}, {"strip-debug", no_argument, 0, 'S'}, {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO}, @@ -451,6 +454,7 @@ static struct option copy_options[] = {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS}, {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR}, {"remove-section", required_argument, 0, 'R'}, + {"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}, @@ -538,6 +542,7 @@ copy_usage (FILE *stream, int exit_status) -j --only-section <name> Only copy section <name> into the output\n\ --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\ -R --remove-section <name> Remove section <name> from the output\n\ + --remove-relocations <name> Remove relocations from section <name>\n\ -S --strip-all Remove all symbol and relocation information\n\ -g --strip-debug Remove all debugging symbols & sections\n\ --strip-dwo Remove all DWO sections\n\ @@ -668,6 +673,7 @@ strip_usage (FILE *stream, int exit_status) Disable -D behavior (default)\n")); fprintf (stream, _("\ -R --remove-section=<name> Also remove section <name> from the output\n\ + --remove-relocations <name> Remove relocations from section <name>\n\ -s --strip-all Remove all symbol and relocation information\n\ -g -S -d --strip-debug Remove all debugging symbols & sections\n\ --strip-dwo Remove all DWO sections\n\ @@ -3207,6 +3213,46 @@ skip_section (bfd *ibfd, sec_ptr isection) return FALSE; } +/* Add section SECTION_PATTERN to the list of sections that will have their + relocations removed. */ + +static void +handle_remove_relocations_option (const char *section_pattern) +{ + find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE_RELOCS); +} + +/* Return TRUE if ISECTION from IBFD should have its relocations removed, + otherwise return FALSE. If the user has requested that relocations be + removed from a section that does not have relocations then this + function will still return TRUE. */ + +static bfd_boolean +discard_relocations (bfd *ibfd ATTRIBUTE_UNUSED, asection *isection) +{ + return (find_section_list (bfd_section_name (ibfd, isection), FALSE, + SECTION_CONTEXT_REMOVE_RELOCS) != NULL); +} + +/* Wrapper for dealing with --remove-section (-R) command line arguments. + A special case is detected here, if the user asks to remove a relocation + section (one starting with ".rela." or ".rel.") then this removal must + be done using a different technique. */ + +static void +handle_remove_section_option (const char *section_pattern) +{ + if (strncmp (section_pattern, ".rela.", 6) == 0) + handle_remove_relocations_option (section_pattern + 5); + else if (strncmp (section_pattern, ".rel.", 5) == 0) + handle_remove_relocations_option (section_pattern + 4); + else + { + find_section_list (section_pattern, TRUE, SECTION_CONTEXT_REMOVE); + sections_removed = TRUE; + } +} + /* Copy relocations in input section ISECTION of IBFD to an output section with the same name in OBFDARG. If stripping then don't copy any relocation info. */ @@ -3226,7 +3272,9 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg) osection = isection->output_section; /* Core files and DWO files do not need to be relocated. */ - if (bfd_get_format (obfd) == bfd_core || strip_symbols == STRIP_NONDWO) + if (bfd_get_format (obfd) == bfd_core + || strip_symbols == STRIP_NONDWO + || discard_relocations (ibfd, isection)) relsize = 0; else { @@ -3606,8 +3654,10 @@ strip_main (int argc, char *argv[]) input_target = output_target = optarg; break; case 'R': - find_section_list (optarg, TRUE, SECTION_CONTEXT_REMOVE); - sections_removed = TRUE; + handle_remove_section_option (optarg); + break; + case OPTION_REMOVE_RELOCS: + handle_remove_relocations_option (optarg); break; case 's': strip_symbols = STRIP_ALL; @@ -4009,8 +4059,11 @@ copy_main (int argc, char *argv[]) break; case 'R': - find_section_list (optarg, TRUE, SECTION_CONTEXT_REMOVE); - sections_removed = TRUE; + handle_remove_section_option (optarg); + break; + + case OPTION_REMOVE_RELOCS: + handle_remove_relocations_option (optarg); break; case 'S': diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index be8a7d2..76d0b67 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -1121,6 +1121,14 @@ if [is_elf_format] { run_dump_test "only-section-01" run_dump_test "remove-section-01" + + # Test the remove relocation functionality + set test_list [lsort [glob -nocomplain $srcdir/$subdir/remove-relocs-*.d]] + foreach t $test_list { + # We need to strip the ".d", but can leave the dirname. + verbose [file rootname $t] + run_dump_test [file rootname $t] + } } run_dump_test "localize-hidden-2" diff --git a/binutils/testsuite/binutils-all/remove-relocs-01.d b/binutils/testsuite/binutils-all/remove-relocs-01.d new file mode 100644 index 0000000..9cd0bfe --- /dev/null +++ b/binutils/testsuite/binutils-all/remove-relocs-01.d @@ -0,0 +1,16 @@ +#PROG: objcopy +#source: remove-relocs-01.s +#objcopy: --remove-relocations=.data.relocs.01 +#readelf: -r + +Relocation section '\.rela?\.data\.relocs\.02' at offset 0x[0-9a-f]+ contains 3 entries: +.* +.* +.* +.* + +Relocation section '\.rela?\.data\.relocs\.03' at offset 0x[0-9a-f]+ contains 3 entries: +.* +.* +.* +.* diff --git a/binutils/testsuite/binutils-all/remove-relocs-01.s b/binutils/testsuite/binutils-all/remove-relocs-01.s new file mode 100644 index 0000000..642d54f --- /dev/null +++ b/binutils/testsuite/binutils-all/remove-relocs-01.s @@ -0,0 +1,19 @@ + .section ".data.relocs.01", "aw" + .word rel_01_01 + .word rel_01_02 + .word rel_01_03 + + .section ".data.relocs.02", "aw" + .word rel_02_01 + .word rel_02_02 + .word rel_02_03 + + .section ".data.relocs.03", "aw" + .word rel_03_01 + .word rel_03_02 + .word rel_03_03 + + .section ".data.01", "aw" + .word 0x1 + .word 0x2 + .word 0x3 diff --git a/binutils/testsuite/binutils-all/remove-relocs-02.d b/binutils/testsuite/binutils-all/remove-relocs-02.d new file mode 100644 index 0000000..c5fbacb --- /dev/null +++ b/binutils/testsuite/binutils-all/remove-relocs-02.d @@ -0,0 +1,6 @@ +#PROG: objcopy +#source: remove-relocs-01.s +#objcopy: --remove-relocations=*.relocs.* +#readelf: -r + +There are no relocations in this file\. diff --git a/binutils/testsuite/binutils-all/remove-relocs-03.d b/binutils/testsuite/binutils-all/remove-relocs-03.d new file mode 100644 index 0000000..534d85e --- /dev/null +++ b/binutils/testsuite/binutils-all/remove-relocs-03.d @@ -0,0 +1,6 @@ +#PROG: objcopy +#source: remove-relocs-01.s +#objcopy: --remove-relocations=* +#readelf: -r + +There are no relocations in this file\. diff --git a/binutils/testsuite/binutils-all/remove-relocs-04.d b/binutils/testsuite/binutils-all/remove-relocs-04.d new file mode 100644 index 0000000..99f5a61 --- /dev/null +++ b/binutils/testsuite/binutils-all/remove-relocs-04.d @@ -0,0 +1,11 @@ +#PROG: objcopy +#source: remove-relocs-01.s +#objcopy: --remove-relocations=.data.relocs.0\[12\] +#readelf: -r + +Relocation section '\.rela?\.data\.relocs\.03' at offset 0x[0-9a-f]+ contains 3 entries: +.* +.* +.* +.* + diff --git a/binutils/testsuite/binutils-all/remove-relocs-05.d b/binutils/testsuite/binutils-all/remove-relocs-05.d new file mode 100644 index 0000000..e2166c9 --- /dev/null +++ b/binutils/testsuite/binutils-all/remove-relocs-05.d @@ -0,0 +1,17 @@ +#PROG: objcopy +#source: remove-relocs-01.s +#objcopy: --remove-section=.rela.data.relocs.01 --remove-section=.rel.data.relocs.01 +#readelf: -r + +Relocation section '\.rela?\.data\.relocs\.02' at offset 0x[0-9a-f]+ contains 3 entries: +.* +.* +.* +.* + +Relocation section '\.rela?\.data\.relocs\.03' at offset 0x[0-9a-f]+ contains 3 entries: +.* +.* +.* +.* + diff --git a/binutils/testsuite/binutils-all/remove-relocs-06.d b/binutils/testsuite/binutils-all/remove-relocs-06.d new file mode 100644 index 0000000..09fed58 --- /dev/null +++ b/binutils/testsuite/binutils-all/remove-relocs-06.d @@ -0,0 +1,11 @@ +#PROG: objcopy +#source: remove-relocs-01.s +#objcopy: --remove-relocations=.data.relocs.* --remove-relocations=!.data.relocs.02 +#readelf: -r + +Relocation section '\.rela?\.data\.relocs\.02' at offset 0x[0-9a-f]+ contains 3 entries: +.* +.* +.* +.* + |