diff options
author | Fangrui Song <i@maskray.me> | 2020-10-29 09:03:13 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2020-10-29 09:03:56 -0700 |
commit | 8f8b5e5587c3e204f21db975a0a76d4462ce3c57 (patch) | |
tree | ebd883a3260459e69c00b00670eda14b0d1cd239 /llvm/lib/MC/MCELFStreamer.cpp | |
parent | 58de4b205310d18614eabdcbaa1772e9fc090df3 (diff) | |
download | llvm-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.cpp | 14 |
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; |