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.
This commit is contained in:
Fāng-ruì Sòng 2019-11-01 14:47:55 -07:00 committed by Alan Modra
parent 5e874de30b
commit 64f52b3ec1
7 changed files with 73 additions and 7 deletions

View 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.

View 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,

View 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

View 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;

View File

@ -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.*
#...

View File

@ -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.*
#...

View 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 {