aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCELFStreamer.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2020-10-29 09:03:13 -0700
committerFangrui Song <i@maskray.me>2020-10-29 09:03:56 -0700
commit8f8b5e5587c3e204f21db975a0a76d4462ce3c57 (patch)
treeebd883a3260459e69c00b00670eda14b0d1cd239 /llvm/lib/MC/MCELFStreamer.cpp
parent58de4b205310d18614eabdcbaa1772e9fc090df3 (diff)
downloadllvm-8f8b5e5587c3e204f21db975a0a76d4462ce3c57.zip
llvm-8f8b5e5587c3e204f21db975a0a76d4462ce3c57.tar.gz
llvm-8f8b5e5587c3e204f21db975a0a76d4462ce3c57.tar.bz2
[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
Diffstat (limited to 'llvm/lib/MC/MCELFStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 5296e24..6b65314 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;