aboutsummaryrefslogtreecommitdiff
path: root/binutils/objcopy.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils/objcopy.c')
-rw-r--r--binutils/objcopy.c63
1 files changed, 58 insertions, 5 deletions
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':