objcopy: Improve wildcard matching for symbols with '!' prefix.
authorAndrew Burgess <andrew.burgess@embecosm.com>
Fri, 31 Jul 2015 12:48:22 +0000 (13:48 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Fri, 7 Aug 2015 09:41:40 +0000 (11:41 +0200)
When using options such as --localize-symbol, --globalize-symbol, etc,
along with the --wildcard option, prefixing a symbol name with '!'
should provide non-matching behaviour, as example the following example
is given in the manual:

    --wildcard --weaken-symbol !foo --weaken-symbol fo*

which should weaken all symbols matching the pattern 'fo*', but not the
symbol 'foo'.

However, this currently does not work, the current logic will waken all
symbols matching the pattern 'fo*' AND all symbols that are not 'foo'.
The symbol 'foo' is covered by the first condition, and so is weakened,
while, other symbols, for example 'bar' will match the second condition,
and so be weakened.

This patch adjusts the logic so that a pattern prefixed with '!'
specifically DOES NOT apply the relevant change to any matching symbols,
instead of applying the change to all non-matching symbols.  So this:

    --weaken-symbol !foo

will ensure that the symbol 'foo' is not weakened, but says nothing
about symbols that are not 'foo'.  As a result, a pattern prefixed with
'!' now only makes sense when used alongside a more wide ranging
wildcard pattern.

This change should make the wildcard matching feature more useful, with
no overall loss of functionality.  The example given in the manual,
weaken all symbols matching 'fo*' except 'foo' can now be achieved, but
so too can more complex examples, such as weaken all symbols matching
'fo*' except 'foo', 'foa', and 'fob', like this:

    --wildcard --weaken-symbol !foo \
               --weaken-symbol !foa \
               --weaken-symbol !fob \
               --weaken-symbol fo*

Under the previous scheme, something as symbols as, weaken all symbols
except 'foo' could have been achieved with this:

    --weaken-symbol !foo

however, this will no longer work.  To achieve the same result under the
new scheme this is now required:

    --weaken-symbol !foo --weaken-symbol *

binutils/ChangeLog:

* objcopy.c (is_specified_symbol_predicate): Don't stop at first
match.  Non-match rules set found to FALSE.

binutils/testsuite/ChangeLog:

* binutils-all/objcopy.exp: Run new symbol tests.
(objcopy_test_symbol_manipulation): New function.
* binutils-all/symbols-1.d: New file.
* binutils-all/symbols-2.d: New file.
* binutils-all/symbols-3.d: New file.
* binutils-all/symbols-4.d: New file.
* binutils-all/symbols.s: New file.

binutils/ChangeLog
binutils/objcopy.c
binutils/testsuite/ChangeLog
binutils/testsuite/binutils-all/objcopy.exp
binutils/testsuite/binutils-all/symbols-1.d [new file with mode: 0644]
binutils/testsuite/binutils-all/symbols-2.d [new file with mode: 0644]
binutils/testsuite/binutils-all/symbols-3.d [new file with mode: 0644]
binutils/testsuite/binutils-all/symbols-4.d [new file with mode: 0644]
binutils/testsuite/binutils-all/symbols.s [new file with mode: 0644]

index 2e1c211dee71cefef844d13d0118c93ccbf6139b..dde51c2e79a09dda040f5394588c097c2c123549 100644 (file)
@@ -1,3 +1,8 @@
+2015-08-07  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * objcopy.c (is_specified_symbol_predicate): Don't stop at first
+       match.  Non-match rules set found to FALSE.
+
 2015-08-06  Yaakov Selkowitz  <yselkowi@redhat.com>
 
        * configure: Regenerate.
index bb6ca4428d7feeda465004753b14be0f16ebd2ee..7ac8661ba105ef88713773bfdcdeb398550a5dbf 100644 (file)
@@ -985,15 +985,15 @@ is_specified_symbol_predicate (void **slot, void *data)
       if (! fnmatch (slot_name, d->name, 0))
        {
          d->found = TRUE;
-         /* Stop traversal.  */
-         return 0;
+         /* Continue traversal, there might be a non-match rule.  */
+         return 1;
        }
     }
   else
     {
-      if (fnmatch (slot_name + 1, d->name, 0))
+      if (fnmatch (slot_name + 1, d->name, 0))
        {
-         d->found = TRUE;
+         d->found = FALSE;
          /* Stop traversal.  */
          return 0;
        }
index 9255fb901e8438dad98d192316286956dd36bd1c..8f8f3c2276f8aad5706e7a039872b9f5c1e0da53 100644 (file)
@@ -1,3 +1,13 @@
+2015-08-07  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * binutils-all/objcopy.exp: Run new symbol tests.
+       (objcopy_test_symbol_manipulation): New function.
+       * binutils-all/symbols-1.d: New file.
+       * binutils-all/symbols-2.d: New file.
+       * binutils-all/symbols-3.d: New file.
+       * binutils-all/symbols-4.d: New file.
+       * binutils-all/symbols.s: New file.
+
 2015-08-05  Nick Clifton  <nickc@redhat.com>
 
        * binutils-all/objcopy.exp (keep_debug_symbols_and_check_links):
index 01d2e17bf230e0458141855f2a702d59cef2dce5..75514e42ce5dbfbf95f4ee3694daf252ef361b84 100644 (file)
@@ -987,6 +987,18 @@ proc objcopy_test_readelf {testname srcfile} {
     }
 }
 
+proc objcopy_test_symbol_manipulation {} {
+    global srcdir
+    global subdir
+
+    set test_list [lsort [glob -nocomplain $srcdir/$subdir/symbols-*.d]]
+    foreach t $test_list {
+        # We need to strip the ".d", but can leave the dirname.
+        verbose [file rootname $t]
+        run_dump_test [file rootname $t]
+    }
+}
+
 # ia64 specific tests
 if { ([istarget "ia64-*-elf*"]
        || [istarget "ia64-*-linux*"]) } {
@@ -995,6 +1007,7 @@ if { ([istarget "ia64-*-elf*"]
 
 # ELF specific tests
 if [is_elf_format] {
+    objcopy_test_symbol_manipulation
     objcopy_test "ELF unknown section type" unknown.s
     objcopy_test_readelf "ELF group" group.s
     objcopy_test_readelf "ELF group" group-2.s
diff --git a/binutils/testsuite/binutils-all/symbols-1.d b/binutils/testsuite/binutils-all/symbols-1.d
new file mode 100644 (file)
index 0000000..41314bd
--- /dev/null
@@ -0,0 +1,14 @@
+#name: localize 'fo*' but not 'foo'
+#PROG: objcopy
+#objcopy: -w -L !foo -L fo*
+#source: symbols.s
+#DUMPPROG: nm
+#nm: -n
+
+0+ D bar
+0+ d foa
+0+ d fob
+0+ D foo
+0+ d foo1
+0+ d foo2
+
diff --git a/binutils/testsuite/binutils-all/symbols-2.d b/binutils/testsuite/binutils-all/symbols-2.d
new file mode 100644 (file)
index 0000000..99950aa
--- /dev/null
@@ -0,0 +1,14 @@
+#name: weaken 'fo*' but not 'foo'
+#PROG: objcopy
+#objcopy: -w -W !foo -W fo*
+#source: symbols.s
+#DUMPPROG: nm
+#nm: -n
+
+0+ D bar
+0+ W foa
+0+ W fob
+0+ D foo
+0+ W foo1
+0+ W foo2
+
diff --git a/binutils/testsuite/binutils-all/symbols-3.d b/binutils/testsuite/binutils-all/symbols-3.d
new file mode 100644 (file)
index 0000000..9838e67
--- /dev/null
@@ -0,0 +1,14 @@
+#name: weaken 'fo*' but not 'foo', localize foo.
+#PROG: objcopy
+#objcopy: -w -W !foo -W fo* -L foo
+#source: symbols.s
+#DUMPPROG: nm
+#nm: -n
+
+0+ D bar
+0+ W foa
+0+ W fob
+0+ d foo
+0+ W foo1
+0+ W foo2
+
diff --git a/binutils/testsuite/binutils-all/symbols-4.d b/binutils/testsuite/binutils-all/symbols-4.d
new file mode 100644 (file)
index 0000000..bb984fd
--- /dev/null
@@ -0,0 +1,14 @@
+#name: weaken '*' but not 'foo' or 'bar'
+#PROG: objcopy
+#objcopy: -w -W !foo -W !bar -W *
+#source: symbols.s
+#DUMPPROG: nm
+#nm: -n
+
+0+ D bar
+0+ W foa
+0+ W fob
+0+ D foo
+0+ W foo1
+0+ W foo2
+
diff --git a/binutils/testsuite/binutils-all/symbols.s b/binutils/testsuite/binutils-all/symbols.s
new file mode 100644 (file)
index 0000000..0d2c62e
--- /dev/null
@@ -0,0 +1,14 @@
+        .section ".data", "aw"
+        .global foo
+        .global foo1
+        .global foo2
+        .global foa
+        .global fob
+        .global bar
+foo:
+foo1:
+foo2:
+foa:
+fob:
+bar:
+        .word 0x0