This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Implement objcopy/strip --keep-section=<sectionpattern>


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=64f52b3ec1853d14293d5a461d7abc8bde5e3f62

commit 64f52b3ec1853d14293d5a461d7abc8bde5e3f62
Author: FÄ?ng-ruì Sòng <maskray@google.com>
Date:   Fri Nov 1 14:47:55 2019 -0700

    Implement objcopy/strip --keep-section=<sectionpattern>
    
    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.

Diff:
---
 binutils/ChangeLog                               | 15 ++++++++++++
 binutils/NEWS                                    |  3 +++
 binutils/doc/binutils.texi                       | 10 ++++++++
 binutils/objcopy.c                               | 31 ++++++++++++++++++------
 binutils/testsuite/binutils-all/keep-section-1.d |  8 ++++++
 binutils/testsuite/binutils-all/keep-section-2.d | 10 ++++++++
 binutils/testsuite/binutils-all/objcopy.exp      |  3 +++
 7 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 36b75c1..0f5d06b 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/NEWS b/binutils/NEWS
index fd14d71..88b0489 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -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,
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 97abf98..2a86b92 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -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
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 7bdd447..5643970 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -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
index 0000000..b28e29c
--- /dev/null
+++ b/binutils/testsuite/binutils-all/keep-section-1.d
@@ -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
index 0000000..7fea62f
--- /dev/null
+++ b/binutils/testsuite/binutils-all/keep-section-2.d
@@ -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.*
+#...
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 6c4b019..6739ab7 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -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 {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]