diff options
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; |