objcopy: Allow making symbol global and weak on same invocation

Message ID 20240629210156.1445989-1-brainbomb@gmail.com
State New
Headers
Series objcopy: Allow making symbol global and weak on same invocation |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Marcus Nilsson June 29, 2024, 9:01 p.m. UTC
  Previously objcopy had to be run twice in order to make a local symbol
weak, first once to globalize it, and once again to mark it as weak.

Add test case to verify that --globalize-symbol and --weaken-symbol
together will output a weak symbol.

        * objcopy.c: Check weaken_specific_htab when marking symbol
          as global to allow weakening it right away.

        * testsuite/binutils-all/symbols-5.d: Add test case for
        globalizing and weakening symbol.
        * testsuite/binutils-all/symbols-5.s: Likewise.
---
 binutils/objcopy.c                          | 3 +++
 binutils/testsuite/binutils-all/symbols-5.d | 8 ++++++++
 binutils/testsuite/binutils-all/symbols-5.s | 3 +++
 3 files changed, 14 insertions(+)
 create mode 100644 binutils/testsuite/binutils-all/symbols-5.d
 create mode 100644 binutils/testsuite/binutils-all/symbols-5.s
  

Comments

Alan Modra June 30, 2024, 10:16 p.m. UTC | #1
On Sat, Jun 29, 2024 at 11:01:56PM +0200, Marcus Nilsson wrote:
> Previously objcopy had to be run twice in order to make a local symbol
> weak, first once to globalize it, and once again to mark it as weak.

Thanks, your patch looks good, but I'm going to implement the change a
little differently, to avoid looking at weaken_specific_htab in two
places.  I believe this keeps the same behaviour for odd combinations
of the various globalize/localize optiosn.  eg. where the same symbol
is mention in both --localize-symbol and --globalize-symbol

	* objcopy.c (filter_symbols): Weaken symbols after making
	local/global changes.
	* testsuite/binutils-all/symbols-5.d,
	* testsuite/binutils-all/symbols-5.s: New test.

diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 26f9d4a0f26..f54ae734198 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -1730,14 +1730,6 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
 
       if (keep)
 	{
-	  if (((flags & (BSF_GLOBAL | BSF_GNU_UNIQUE))
-	       || undefined)
-	      && (weaken || is_specified_symbol (name, weaken_specific_htab)))
-	    {
-	      sym->flags &= ~ (BSF_GLOBAL | BSF_GNU_UNIQUE);
-	      sym->flags |= BSF_WEAK;
-	    }
-
 	  if (!undefined
 	      && (flags & (BSF_GLOBAL | BSF_WEAK))
 	      && (is_specified_symbol (name, localize_specific_htab)
@@ -1745,18 +1737,27 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
 		      && ! is_specified_symbol (name, keepglobal_specific_htab))
 		  || (localize_hidden && is_hidden_symbol (sym))))
 	    {
-	      sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
-	      sym->flags |= BSF_LOCAL;
+	      flags &= ~(BSF_GLOBAL | BSF_WEAK);
+	      flags |= BSF_LOCAL;
 	    }
 
-	  if (!undefined
-	      && (flags & BSF_LOCAL)
-	      && is_specified_symbol (name, globalize_specific_htab))
+	  else if (!undefined
+		   && (flags & BSF_LOCAL)
+		   && is_specified_symbol (name, globalize_specific_htab))
+	    {
+	      flags &= ~BSF_LOCAL;
+	      flags |= BSF_GLOBAL;
+	    }
+
+	  if (((flags & (BSF_GLOBAL | BSF_GNU_UNIQUE))
+	       || undefined)
+	      && (weaken || is_specified_symbol (name, weaken_specific_htab)))
 	    {
-	      sym->flags &= ~ BSF_LOCAL;
-	      sym->flags |= BSF_GLOBAL;
+	      flags &= ~(BSF_GLOBAL | BSF_GNU_UNIQUE);
+	      flags |= BSF_WEAK;
 	    }
 
+	  sym->flags = flags;
 	  to[dst_count++] = sym;
 	}
     }
diff --git a/binutils/testsuite/binutils-all/symbols-5.d b/binutils/testsuite/binutils-all/symbols-5.d
new file mode 100644
index 00000000000..ffaa950fc5b
--- /dev/null
+++ b/binutils/testsuite/binutils-all/symbols-5.d
@@ -0,0 +1,8 @@
+#name: globalize and weaken 'foo'
+#PROG: objcopy
+#objcopy: --globalize-symbol foo -W foo
+#source: symbols-5.s
+#nm: -n
+
+#...
+0+ [VW] foo
diff --git a/binutils/testsuite/binutils-all/symbols-5.s b/binutils/testsuite/binutils-all/symbols-5.s
new file mode 100644
index 00000000000..aa01b9e4a60
--- /dev/null
+++ b/binutils/testsuite/binutils-all/symbols-5.s
@@ -0,0 +1,3 @@
+ .text
+foo:
+ .word 0x0
  

Patch

diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 26f9d4a0f26..4d1e933236c 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -1755,6 +1755,9 @@  filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
 	    {
 	      sym->flags &= ~ BSF_LOCAL;
 	      sym->flags |= BSF_GLOBAL;
+
+	      if (is_specified_symbol (name, weaken_specific_htab))
+		sym->flags |= BSF_WEAK;
 	    }
 
 	  to[dst_count++] = sym;
diff --git a/binutils/testsuite/binutils-all/symbols-5.d b/binutils/testsuite/binutils-all/symbols-5.d
new file mode 100644
index 00000000000..ffaa950fc5b
--- /dev/null
+++ b/binutils/testsuite/binutils-all/symbols-5.d
@@ -0,0 +1,8 @@ 
+#name: globalize and weaken 'foo'
+#PROG: objcopy
+#objcopy: --globalize-symbol foo -W foo
+#source: symbols-5.s
+#nm: -n
+
+#...
+0+ [VW] foo
diff --git a/binutils/testsuite/binutils-all/symbols-5.s b/binutils/testsuite/binutils-all/symbols-5.s
new file mode 100644
index 00000000000..1e8a55c1b56
--- /dev/null
+++ b/binutils/testsuite/binutils-all/symbols-5.s
@@ -0,0 +1,3 @@ 
+        .text
+foo:
+        .word 0x0