summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog27
-rw-r--r--binutils/NEWS5
-rw-r--r--binutils/doc/binutils.texi58
-rw-r--r--binutils/objcopy.c63
-rw-r--r--binutils/testsuite/binutils-all/objcopy.exp8
-rw-r--r--binutils/testsuite/binutils-all/remove-relocs-01.d16
-rw-r--r--binutils/testsuite/binutils-all/remove-relocs-01.s19
-rw-r--r--binutils/testsuite/binutils-all/remove-relocs-02.d6
-rw-r--r--binutils/testsuite/binutils-all/remove-relocs-03.d6
-rw-r--r--binutils/testsuite/binutils-all/remove-relocs-04.d11
-rw-r--r--binutils/testsuite/binutils-all/remove-relocs-05.d17
-rw-r--r--binutils/testsuite/binutils-all/remove-relocs-06.d11
12 files changed, 242 insertions, 5 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index f5b45d8c86..6b8f2260fd 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 9625cf49e2..56adfa2d9e 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 d77bc86b0f..5a564efd66 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 41ccc761d5..cf3f9832d3 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 be8a7d2b50..76d0b672f7 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 0000000000..9cd0bfeb63
--- /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 0000000000..642d54f004
--- /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 0000000000..c5fbacbbee
--- /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 0000000000..534d85e291
--- /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 0000000000..99f5a6146e
--- /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 0000000000..e2166c93d9
--- /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 0000000000..09fed58bb0
--- /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:
+.*
+.*
+.*
+.*
+