This is the mail archive of the binutils@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]

Re: [PATCH] Implement objcopy/strip --keep-section=<sectionpattern>


On Thu, Oct 31, 2019 at 7:00 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Thu, Oct 31, 2019 at 05:06:58PM -0700, Fāng-ruì Sòng via binutils wrote:
> > +     * objcopy.c (enum option_values): Add OPTION_KEEP_SECTION.
> > +     (SECTION_CONTEXT_KEEP): New macro.
>
> This needs to be more detailed.  You haven't mentioned that you are
> changing the other macros, nor have you mentioned the functions you
> are changing in objcopy.c.  The NEWS, binutils.texi, and testsuite
> changes also need entries in the ChangeLog.
> For the macro changes,
>         (SECTION_CONTEXT_KEEP): Define.  Adjust other SECTION_CONTEXT macros.
> would be sufficient.

Thanks. Changed in the updated patch.

> > @@ -1367,6 +1373,10 @@ is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
> >  static bfd_boolean
> >  is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
> >  {
> > +  if (find_section_list (bfd_section_name (sec), FALSE, SECTION_CONTEXT_KEEP)
> > +      != NULL)
> > +    return FALSE;
> > +
> >    if (is_strip_section_1 (abfd, sec))
> >      return TRUE;
> >
>
> I believe this change should be made in is_strip_section_1 instead.
> Otherwise, with a proper ChangeLog entry the patch looks good to
> commit.

is_strip_section_1 returns either TRUE (strip the section) or FALSE
(fall through to other conditions). We cannot put the --keep-section
logic there.
From 14bc33dbaebc86dd7496d6356f561d4fa21aa1b6 Mon Sep 17 00:00:00 2001
From: Fangrui Song <maskray@google.com>
Date: Thu, 31 Oct 2019 16:51:54 -0700
Subject: [PATCH] Implement objcopy/strip --keep-section=<sectionpattern>

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

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 36b75c1f3c..530f1d925d 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,13 @@
+2019-10-31  Fangrui Song  <maskray@google.com>
+
+	* objcopy.c (enum option_values): Add OPTION_KEEP_SECTION.
+	(SECTION_CONTEXT_KEEP): Define.  Adjust other SECTION_CONTEXT macros.
+	* 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 fd14d71ce9..88b048995a 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 97abf980ba..2a86b92033 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 7bdd447893..9280e453bc 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\
@@ -1367,6 +1373,10 @@ is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
 static bfd_boolean
 is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
 {
+  if (find_section_list (bfd_section_name (sec), FALSE, SECTION_CONTEXT_KEEP)
+      != NULL)
+    return FALSE;
+
   if (is_strip_section_1 (abfd, sec))
     return TRUE;
 
@@ -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 0000000000..b28e29c170
--- /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 0000000000..7fea62f149
--- /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 6c4b0196ab..6739ab7de8 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 {
-- 
2.20.0


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