diff options
Diffstat (limited to 'binutils/objcopy.c')
-rw-r--r-- | binutils/objcopy.c | 63 |
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': |