This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] Implement objcopy/strip --keep-section=<sectionpattern>
- From: "Fāng-ruì Sòng via binutils" <binutils at sourceware dot org>
- To: Alan Modra <amodra at gmail dot com>
- Cc: binutils at sourceware dot org, Nick Clifton <nickc at redhat dot com>
- Date: Thu, 31 Oct 2019 21:16:03 -0700
- Subject: Re: [PATCH] Implement objcopy/strip --keep-section=<sectionpattern>
- References: <CAFP8O3KYkhb=5qbsfh86Pd_8yd1J8fEuTQ-BGid6dnqQB4o5PQ@mail.gmail.com> <20191101020007.GA6708@bubble.grove.modra.org>
- Reply-to: Fāng-ruì Sòng <maskray at google dot com>
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