summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 10a9fe87aa2..111ba3fab39 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -1285,8 +1285,21 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
Alias->setBinding(Symbol.getBinding());
Alias->setOther(Symbol.getOther());
- if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
+ // Record the rename. This serves two purposes: 1) detect multiple symbol
+ // version definitions, 2) consistently suppress the original symbol in the
+ // symbol table. GNU as keeps the original symbol for defined @ and @@, but
+ // suppresses in for other cases (@@@ or undefined). The original symbol is
+ // usually undesired and difficult to remove in an archive. Moreoever, it
+ // can cause linker issues like binutils PR/18703. If the user wants other
+ // aliases to the versioned symbol, they can copy the original symbol to
+ // other symbol names with .set directive.
+ auto R = Renames.try_emplace(&Symbol, Alias);
+ if (!R.second && R.first->second != Alias) {
+ Asm.getContext().reportError(
+ SMLoc(), llvm::Twine("multiple symbol versions defined for ") +
+ Symbol.getName());
continue;
+ }
// FIXME: Get source locations for these errors or diagnose them earlier.
if (Symbol.isUndefined() && Rest.startswith("@@") &&
@@ -1295,15 +1308,6 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
" must be defined");
continue;
}
-
- if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
- Asm.getContext().reportError(
- SMLoc(), llvm::Twine("multiple symbol versions defined for ") +
- Symbol.getName());
- continue;
- }
-
- Renames.insert(std::make_pair(&Symbol, Alias));
}
for (const MCSymbol *&Sym : AddrsigSyms) {
OpenPOWER on IntegriCloud