[llvm] 8f8b5e5 - [MC] Error for .globl/.local which change the symbol binding and warn for .weak

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 29 09:08:06 PDT 2020


Author: Fangrui Song
Date: 2020-10-29T09:03:56-07:00
New Revision: 8f8b5e5587c3e204f21db975a0a76d4462ce3c57

URL: https://github.com/llvm/llvm-project/commit/8f8b5e5587c3e204f21db975a0a76d4462ce3c57
DIFF: https://github.com/llvm/llvm-project/commit/8f8b5e5587c3e204f21db975a0a76d4462ce3c57.diff

LOG: [MC] Error for .globl/.local which change the symbol binding and warn for .weak

GNU as let .weak override .globl since binutils-gdb
5ca547dc2399a0a5d9f20626d4bf5547c3ccfddd (1996) while MC lets the last
directive win (PR38921).

This caused an issue to Linux's powerpc port which has been fixed by
http://git.kernel.org/linus/968339fad422a58312f67718691b717dac45c399

Binding overriding is error-prone. This patch disallows a changed binding.
(https://sourceware.org/pipermail/binutils/2020-March/000299.html )

Our behavior regarding `.globl x; .weak x` matches GNU as. Such usage is
still suspicious but we issue a warning for now. We may upgrade it to an
error in the future.

Reviewed By: jhenderson, nickdesaulniers

Differential Revision: https://reviews.llvm.org/D90108

Added: 
    llvm/test/MC/ELF/symbol-binding-changed.s

Modified: 
    llvm/lib/MC/MCELFStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 5296e2400765f..6b653144a8fbd 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -225,17 +225,31 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
     break;
 
   case MCSA_Global:
+    // For `.weak x; .global x`, GNU as sets the binding to STB_WEAK while we
+    // traditionally set the binding to STB_GLOBAL. This is error-prone, so we
+    // error on such cases. Note, we also disallow changed binding from .local.
+    if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL)
+      getContext().reportError(SMLoc(), Symbol->getName() +
+                                            " changed binding to STB_GLOBAL");
     Symbol->setBinding(ELF::STB_GLOBAL);
     Symbol->setExternal(true);
     break;
 
   case MCSA_WeakReference:
   case MCSA_Weak:
+    // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK.
+    // We emit a warning for now but may switch to an error in the future.
+    if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK)
+      getContext().reportWarning(SMLoc(), Symbol->getName() +
+                                              " changed binding to STB_WEAK");
     Symbol->setBinding(ELF::STB_WEAK);
     Symbol->setExternal(true);
     break;
 
   case MCSA_Local:
+    if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL)
+      getContext().reportError(SMLoc(), Symbol->getName() +
+                                            " changed binding to STB_LOCAL");
     Symbol->setBinding(ELF::STB_LOCAL);
     Symbol->setExternal(false);
     break;

diff  --git a/llvm/test/MC/ELF/symbol-binding-changed.s b/llvm/test/MC/ELF/symbol-binding-changed.s
new file mode 100644
index 0000000000000..f327fae2a1c43
--- /dev/null
+++ b/llvm/test/MC/ELF/symbol-binding-changed.s
@@ -0,0 +1,28 @@
+# RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
+
+# CHECK: error: local changed binding to STB_GLOBAL
+local:
+.local local
+.globl local
+
+## `.globl x; .weak x` matches the GNU as behavior. We issue a warning for now.
+# CHECK: warning: global changed binding to STB_WEAK
+global:
+.global global
+.weak global
+
+# CHECK: error: weak changed binding to STB_LOCAL
+weak:
+.weak weak
+.local weak
+
+# CHECK-NOT: error:
+multi_local:
+.local multi_local
+.local multi_local
+multi_global:
+.global multi_global
+.global multi_global
+multi_weak:
+.weak multi_weak
+.weak multi_weak


        


More information about the llvm-commits mailing list