objcopy/strip: Allow section patterns starting with '!'.
authorAndrew Burgess <andrew.burgess@embecosm.com>
Mon, 24 Aug 2015 12:02:39 +0000 (13:02 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Thu, 14 Jul 2016 10:32:48 +0000 (11:32 +0100)
For symbol matching, prefixing a pattern with '!' will indicate a
non-matching pattern, however, this is not the case for section
patterns.  As a result it is not possible to say "apply this action to
all sections except ...".

With this commit the objcopy and strip tools now support '!' prefix for
section patterns, so we can say:

  objcopy --remove-section="*" --remove-section="!.text*"

Which will remove all sections, except those matching the pattern
'.text*'.

binutils/ChangeLog:

* objcopy.c (find_section_list): Handle section patterns starting
with '!' being a non-matching pattern.
* doc/binutils.texi (objcopy): Give example of using '!' with
--remove-section and --only-section.
(strip): Give example of using '!' with --remove-section.
* testsuite/binutils-all/data-sections.s: New file.
* testsuite/binutils-all/only-section-01.d: New file.
* testsuite/binutils-all/remove-section-01.d: New file.
* testsuite/binutils-all/objcopy.exp: Run new tests.
* NEWS: Mention new feature.

binutils/ChangeLog
binutils/NEWS
binutils/doc/binutils.texi
binutils/objcopy.c
binutils/testsuite/binutils-all/data-sections.s [new file with mode: 0644]
binutils/testsuite/binutils-all/objcopy.exp
binutils/testsuite/binutils-all/only-section-01.d [new file with mode: 0644]
binutils/testsuite/binutils-all/remove-section-01.d [new file with mode: 0644]

index 3bf69726613147ee1f0beab5cce1cb74461e83a0..f5b45d8c86186c48db36c42d11d7c5d8c479942d 100644 (file)
@@ -1,3 +1,16 @@
+2016-07-14  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * objcopy.c (find_section_list): Handle section patterns starting
+       with '!' being a non-matching pattern.
+       * doc/binutils.texi (objcopy): Give example of using '!' with
+       --remove-section and --only-section.
+       (strip): Give example of using '!' with --remove-section.
+       * testsuite/binutils-all/data-sections.s: New file.
+       * testsuite/binutils-all/only-section-01.d: New file.
+       * testsuite/binutils-all/remove-section-01.d: New file.
+       * testsuite/binutils-all/objcopy.exp: Run new tests.
+       * NEWS: Mention new feature.
+
 2016-07-09  Alan Modra  <amodra@gmail.com>
 
        PR binutils/20337
index 5bc6888ab5001ce69716b42dd182ea5fdf19133e..9625cf49e28e0921ff0aa54dad0e943ee6c0e5b1 100644 (file)
@@ -1,5 +1,15 @@
 -*- text -*-
 
+* The --remove-section option for objcopy and strip now accepts section
+  patterns starting with an exclamation point to indicate a non-matching
+  section.  A non-matching section is removed from the set of sections
+  matched by an earlier --remove-section pattern.
+
+* The --only-section option for objcopy now accepts section patterns
+  starting with an exclamation point to indicate a non-matching section.
+  A non-matching section is removed from the set of sections matched by
+  an earlier --only-section pattern.
+
 Changes in 2.27:
 
 * Add a configure option, --enable-64-bit-archive, to force use of a
index 5a004a34ec9b82479e057ace995a0d7c1a1bb9da..d77bc86b0f431ea3524043457728e364138475ce 100644 (file)
@@ -1221,6 +1221,18 @@ This option may be given more than once.  Note that using this option
 inappropriately may make the output file unusable.  Wildcard
 characters are accepted in @var{sectionpattern}.
 
+If the first character of @var{sectionpattern} is the exclamation
+point (!) then matching sections will not be copied, even if earlier
+use of @option{--only-section} on the same command line would
+otherwise copy it.  For example:
+
+@smallexample
+  --only-section=.text.* --only-section=!.text.foo
+@end smallexample
+
+will copy all sectinos maching '.text.*' but not the section
+'.text.foo'.
+
 @item -R @var{sectionpattern}
 @itemx --remove-section=@var{sectionpattern}
 Remove any section matching @var{sectionpattern} from the output file.
@@ -1230,6 +1242,18 @@ characters are accepted in @var{sectionpattern}.  Using both the
 @option{-j} and @option{-R} options together results in undefined
 behaviour.
 
+If the first character of @var{sectionpattern} is the exclamation
+point (!) then matching sections will not be removed even if an
+earlier use of @option{--remove-section} on the same command line
+would otherwise remove it.  For example:
+
+@smallexample
+  --remove-section=.text.* --remove-section=!.text.foo
+@end smallexample
+
+will remove all sections matching the pattern '.text.*', but will not
+remove the section '.text.foo'.
+
 @item -S
 @itemx --strip-all
 Do not copy relocation and symbol information from the source file.
@@ -3021,6 +3045,18 @@ inappropriately may make the output file unusable.  The wildcard
 character @samp{*} may be given at the end of @var{sectionname}.  If
 so, then any section starting with @var{sectionname} will be removed.
 
+If the first character of @var{sectionpattern} is the exclamation
+point (!) then matching sections will not be removed even if an
+earlier use of @option{--remove-section} on the same command line
+would otherwise remove it.  For example:
+
+@smallexample
+  --remove-section=.text.* --remove-section=!.text.foo
+@end smallexample
+
+will remove all sections matching the pattern '.text.*', but will not
+remove the section '.text.foo'.
+
 @item -s
 @itemx --strip-all
 Remove all symbols.
index 4bb625a03959e2f92391ed421d979af0d7a51e8e..41ccc761d538751efe1d65cebf3dfea87e86fecf 100644 (file)
@@ -854,7 +854,7 @@ parse_symflags (const char *s, char **other)
 static struct section_list *
 find_section_list (const char *name, bfd_boolean add, unsigned int context)
 {
-  struct section_list *p;
+  struct section_list *p, *match = NULL;
 
   /* assert ((context & ((1 << 7) - 1)) != 0); */
 
@@ -890,19 +890,36 @@ find_section_list (const char *name, bfd_boolean add, unsigned int context)
        }
       /* If we are not adding a new name/pattern then
         only check for a match if the context applies.  */
-      else if ((p->context & context)
-              /* We could check for the presence of wildchar characters
-                 first and choose between calling strcmp and fnmatch,
-                 but is that really worth it ?  */
-              && fnmatch (p->pattern, name, 0) == 0)
-       {
-         p->used = TRUE;
-         return p;
-       }
+      else if (p->context & context)
+        {
+          /* We could check for the presence of wildchar characters
+             first and choose between calling strcmp and fnmatch,
+             but is that really worth it ?  */
+          if (p->pattern [0] == '!')
+            {
+              if (fnmatch (p->pattern + 1, name, 0) == 0)
+                {
+                  p->used = TRUE;
+                  return NULL;
+                }
+            }
+          else
+            {
+              if (fnmatch (p->pattern, name, 0) == 0)
+                {
+                  if (match == NULL)
+                    match = p;
+                }
+            }
+        }
     }
 
   if (! add)
-    return NULL;
+    {
+      if (match != NULL)
+        match->used = TRUE;
+      return match;
+    }
 
   p = (struct section_list *) xmalloc (sizeof (struct section_list));
   p->pattern = name;
diff --git a/binutils/testsuite/binutils-all/data-sections.s b/binutils/testsuite/binutils-all/data-sections.s
new file mode 100644 (file)
index 0000000..0d6284c
--- /dev/null
@@ -0,0 +1,17 @@
+        .section ".data.aa.01", "aw"
+        .word 0x1
+
+        .section ".data.aa.02", "aw"
+        .word 0x2
+
+        .section ".data.aa.03", "aw"
+        .word 0x3
+
+        .section ".data.bb.01", "aw"
+        .word 0x4
+
+        .section ".data.bb.02", "aw"
+        .word 0x5
+
+        .section ".data.bb.03", "aw"
+        .word 0x6
index ccd442210181f21f87473d7146f2786d40ed5d44..be8a7d2b5079c82008f7c18ace818ba337186756 100644 (file)
@@ -1118,6 +1118,9 @@ if [is_elf_format] {
 
     run_dump_test "exclude-1a"
     run_dump_test "exclude-1b"
+
+    run_dump_test "only-section-01"
+    run_dump_test "remove-section-01"
 }
 run_dump_test "localize-hidden-2"
 
diff --git a/binutils/testsuite/binutils-all/only-section-01.d b/binutils/testsuite/binutils-all/only-section-01.d
new file mode 100644 (file)
index 0000000..0e71430
--- /dev/null
@@ -0,0 +1,9 @@
+#PROG: objcopy
+#source: data-sections.s
+#objcopy: --only-section=.data.aa.* --only-section=!.data.aa.02
+#readelf: -WS
+
+#...
+  \[ [0-9]+\] .data.aa.01.*
+  \[ [0-9]+\] .data.aa.03.*
+#...
diff --git a/binutils/testsuite/binutils-all/remove-section-01.d b/binutils/testsuite/binutils-all/remove-section-01.d
new file mode 100644 (file)
index 0000000..b2837b2
--- /dev/null
@@ -0,0 +1,8 @@
+#PROG: objcopy
+#source: data-sections.s
+#objcopy: --remove-section=.data.aa.* --remove-section=!.data.aa.02
+#readelf: -WS
+
+#...
+  \[ [0-9]+\] \.data\.aa\.02.*
+#...