Implement objcopy/strip --keep-section=<sectionpattern>
authorFāng-ruì Sòng <maskray@google.com>
Fri, 1 Nov 2019 21:47:55 +0000 (14:47 -0700)
committerAlan Modra <amodra@gmail.com>
Mon, 4 Nov 2019 01:25:28 +0000 (11:55 +1030)
llvm-objcopy and llvm-strip support an option --keep-section that
keeps some sections from being removed.

* objcopy.c (enum option_values): Add OPTION_KEEP_SECTION.
(SECTION_CONTEXT_KEEP): Define.  Adjust other SECTION_CONTEXT macros.
(copy_usage): Describe --keep-section.
(strip_usage): Likewise.
(copy_main): Handle SECTION_CONTEXT_KEEP.
(strip_main): Likewise.
(is_strip_section_1): Likewise.
* testsuite/binutils-all/objcopy.exp: Add tests.
* testsuite/binutils-all/keep-section-1.d: New test driver file.
* testsuite/binutils-all/keep-section-2.d: Likewise.
* doc/binutils.texi: Document the new feature.
* NEWS: Mention the new feature.

binutils/ChangeLog
binutils/NEWS
binutils/doc/binutils.texi
binutils/objcopy.c
binutils/testsuite/binutils-all/keep-section-1.d [new file with mode: 0644]
binutils/testsuite/binutils-all/keep-section-2.d [new file with mode: 0644]
binutils/testsuite/binutils-all/objcopy.exp

index 36b75c1f3ce66218b350ccb54eed2bcd244f896b..0f5d06b5a699f4458e9f8a5351e4432fb8fc0d4e 100644 (file)
@@ -1,3 +1,18 @@
+2019-11-04  Fangrui Song  <maskray@google.com>
+
+       * objcopy.c (enum option_values): Add OPTION_KEEP_SECTION.
+       (SECTION_CONTEXT_KEEP): Define.  Adjust other SECTION_CONTEXT macros.
+       (copy_usage): Describe --keep-section.
+       (strip_usage): Likewise.
+       (copy_main): Handle SECTION_CONTEXT_KEEP.
+       (strip_main): Likewise.
+       (is_strip_section_1): Likewise.
+       * testsuite/binutils-all/objcopy.exp: Add tests.
+       * testsuite/binutils-all/keep-section-1.d: New test driver file.
+       * testsuite/binutils-all/keep-section-2.d: Likewise.
+       * doc/binutils.texi: Document the new feature.
+       * NEWS: Mention the new feature.
+
 2019-10-20  Palmer Dabbelt  <palmer@sifive.com>
 
         * MAINTAINERS: Change palmer@sifive.com to palmer@dabbelt.com.
index fd14d71ce92772928bb2963cb492222c3b360972..88b048995a8fe4fac320fd54cda4172c0c9a5450 100644 (file)
@@ -3,6 +3,9 @@
 * Add --output option to the "ar" program.  This option can be used to specify
   the output directory when extracting members from an archive.
 
+* Add --keep-section option to objcopy and strip.  This option keeps the
+  specified section from being removed.
+
 Changes in 2.33:
 
 * Add --source-comment[=<txt>] option to objdump which if present,
index 97abf980ba81302af07dca3aadfb47b699ee18ea..2a86b92033af83230f541c0a515111bb3623ed0f 100644 (file)
@@ -1186,6 +1186,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{--keep-section=}@var{sectionpattern}]
         [@option{--remove-relocations=}@var{sectionpattern}]
         [@option{-p}|@option{--preserve-dates}]
         [@option{-D}|@option{--enable-deterministic-archives}]
@@ -1369,6 +1370,10 @@ would otherwise remove it.  For example:
 will remove all sections matching the pattern '.text.*', but will not
 remove the section '.text.foo'.
 
+@item --keep-section=@var{sectionpattern}
+When removing sections from the output file, keep sections that match
+@var{sectionpattern}.
+
 @item --remove-relocations=@var{sectionpattern}
 Remove non-dynamic relocations from the output file for any section
 matching @var{sectionpattern}.  This option may be given more than
@@ -3242,6 +3247,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{--keep-section=}@var{sectionpattern}]
       [@option{--remove-relocations=}@var{sectionpattern}]
       [@option{-o} @var{file}] [@option{-p}|@option{--preserve-dates}]
       [@option{-D}|@option{--enable-deterministic-archives}]
@@ -3312,6 +3318,10 @@ would otherwise remove it.  For example:
 will remove all sections matching the pattern '.text.*', but will not
 remove the section '.text.foo'.
 
+@item --keep-section=@var{sectionpattern}
+When removing sections from the output file, keep sections that match
+@var{sectionpattern}.
+
 @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
index 7bdd4478931d68c2d925ae826e219da1596c90d9..56439700c229c4e501bb8b7f881bdb1cc6b1ceb8 100644 (file)
@@ -143,13 +143,14 @@ struct section_list
      COPY and REMOVE are mutually exlusive.  SET and ALTER are mutually exclusive.  */
 #define SECTION_CONTEXT_REMOVE    (1 << 0) /* Remove this section.  */
 #define SECTION_CONTEXT_COPY      (1 << 1) /* Copy this section, delete all non-copied section.  */
-#define SECTION_CONTEXT_SET_VMA   (1 << 2) /* Set the sections' VMA address.  */
-#define SECTION_CONTEXT_ALTER_VMA (1 << 3) /* Increment or decrement the section's VMA address.  */
-#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.  */
-#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 8) /* Set alignment for section.  */
+#define SECTION_CONTEXT_KEEP      (1 << 2) /* Keep this section.  */
+#define SECTION_CONTEXT_SET_VMA   (1 << 3) /* Set the sections' VMA address.  */
+#define SECTION_CONTEXT_ALTER_VMA (1 << 4) /* Increment or decrement the section's VMA address.  */
+#define SECTION_CONTEXT_SET_LMA   (1 << 5) /* Set the sections' LMA address.  */
+#define SECTION_CONTEXT_ALTER_LMA (1 << 6) /* Increment or decrement the section's LMA address.  */
+#define SECTION_CONTEXT_SET_FLAGS (1 << 7) /* Set the section's flags.  */
+#define SECTION_CONTEXT_REMOVE_RELOCS (1 << 8) /* Remove relocations for this section.  */
+#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 9) /* 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.  */
@@ -332,6 +333,7 @@ enum command_line_switch
   OPTION_INTERLEAVE_WIDTH,
   OPTION_KEEPGLOBAL_SYMBOLS,
   OPTION_KEEP_FILE_SYMBOLS,
+  OPTION_KEEP_SECTION,
   OPTION_KEEP_SYMBOLS,
   OPTION_LOCALIZE_HIDDEN,
   OPTION_LOCALIZE_SYMBOLS,
@@ -386,6 +388,7 @@ static struct option strip_options[] =
   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
   {"input-target", required_argument, 0, 'I'},
   {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
+  {"keep-section", required_argument, 0, OPTION_KEEP_SECTION},
   {"keep-symbol", required_argument, 0, 'K'},
   {"merge-notes", no_argument, 0, 'M'},
   {"no-merge-notes", no_argument, 0, OPTION_NO_MERGE_NOTES},
@@ -457,6 +460,7 @@ static struct option copy_options[] =
   {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
   {"keep-global-symbol", required_argument, 0, 'G'},
   {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
+  {"keep-section", required_argument, 0, OPTION_KEEP_SECTION},
   {"keep-symbol", required_argument, 0, 'K'},
   {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
   {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
@@ -589,6 +593,7 @@ copy_usage (FILE *stream, int exit_status)
      --only-keep-debug             Strip everything but the debug information\n\
      --extract-dwo                 Copy only DWO sections\n\
      --extract-symbol              Remove section contents but keep symbols\n\
+     --keep-section <name>         Do not strip section <name>\n\
   -K --keep-symbol <name>          Do not strip symbol <name>\n\
      --keep-file-symbols           Do not strip file symbol(s)\n\
      --localize-hidden             Turn all ELF hidden symbols into locals\n\
@@ -722,6 +727,7 @@ strip_usage (FILE *stream, int exit_status)
   -M  --merge-notes                Remove redundant entries in note sections (default)\n\
       --no-merge-notes             Do not attempt to remove redundant notes\n\
   -N --strip-symbol=<name>         Do not copy symbol <name>\n\
+     --keep-section=<name>         Do not strip section <name>\n\
   -K --keep-symbol=<name>          Do not strip symbol <name>\n\
      --keep-file-symbols           Do not strip file symbol(s)\n\
   -w --wildcard                    Permit wildcard in symbol comparison\n\
@@ -1311,6 +1317,10 @@ is_mergeable_note_section (bfd * abfd, asection * sec)
 static bfd_boolean
 is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
 {
+  if (find_section_list (bfd_section_name (sec), FALSE, SECTION_CONTEXT_KEEP)
+      != NULL)
+    return FALSE;
+
   if (sections_removed || sections_copied)
     {
       struct section_list *p;
@@ -4584,6 +4594,9 @@ strip_main (int argc, char *argv[])
        case 'R':
          handle_remove_section_option (optarg);
          break;
+       case OPTION_KEEP_SECTION:
+         find_section_list (optarg, TRUE, SECTION_CONTEXT_KEEP);
+         break;
        case OPTION_REMOVE_RELOCS:
          handle_remove_relocations_option (optarg);
          break;
@@ -5010,6 +5023,10 @@ copy_main (int argc, char *argv[])
          handle_remove_section_option (optarg);
          break;
 
+       case OPTION_KEEP_SECTION:
+         find_section_list (optarg, TRUE, SECTION_CONTEXT_KEEP);
+         break;
+
         case OPTION_REMOVE_RELOCS:
          handle_remove_relocations_option (optarg);
          break;
diff --git a/binutils/testsuite/binutils-all/keep-section-1.d b/binutils/testsuite/binutils-all/keep-section-1.d
new file mode 100644 (file)
index 0000000..b28e29c
--- /dev/null
@@ -0,0 +1,8 @@
+#PROG: objcopy
+#source: data-sections.s
+#objcopy: --remove-section=.data.aa.* --keep-section=.data.aa.02
+#readelf: -WS
+
+#...
+  \[ [0-9]+\] \.data\.aa\.02.*
+#...
diff --git a/binutils/testsuite/binutils-all/keep-section-2.d b/binutils/testsuite/binutils-all/keep-section-2.d
new file mode 100644 (file)
index 0000000..7fea62f
--- /dev/null
@@ -0,0 +1,10 @@
+#PROG: objcopy
+#source: data-sections.s
+#objcopy: --remove-section=.data.aa.* --keep-section=.data.aa.*
+#readelf: -WS
+
+#...
+  \[ [0-9]+\] \.data\.aa\.01.*
+  \[ [0-9]+\] \.data\.aa\.02.*
+  \[ [0-9]+\] \.data\.aa\.03.*
+#...
index 6c4b0196ab7d9f0c1fdd27d3a11b6bdf47bed3e0..6739ab7de842456cab1ab5506f2355c87b405b19 100644 (file)
@@ -1222,6 +1222,9 @@ if [is_elf_format] {
     run_dump_test "only-section-01"
     run_dump_test "remove-section-01"
 
+    run_dump_test "keep-section-1"
+    run_dump_test "keep-section-2"
+
     # Test the remove relocation functionality
     set test_list [lsort [glob -nocomplain $srcdir/$subdir/remove-relocs-*.d]]
     foreach t $test_list {