summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-08-19 06:17:30 +0000
committerFangrui Song <maskray@google.com>2019-08-19 06:17:30 +0000
commit38426c114f6e50f8638bdd656f2f423151bc8eca (patch)
tree378fd850c1275e140d0662509282f3facf79b1dc /llvm/lib/MC/ELFObjectWriter.cpp
parentebb7ddc6330b28b8c7e53d4c68d3684c127a41c1 (diff)
downloadbcm5719-llvm-38426c114f6e50f8638bdd656f2f423151bc8eca.tar.gz
bcm5719-llvm-38426c114f6e50f8638bdd656f2f423151bc8eca.zip
[MC] Don't emit .symver redirected symbols to the symbol table
GNU as keeps the original symbol in the symbol table for defined @ and @@, but suppresses it in other cases (@@@ or undefined). The original symbol is usually undesired: In a shared object, the original symbol can be localized with a version script, but it is hard to remove/localize in an archive: 1) a post-processing step removes the undesired original symbol 2) consumers (executable) of the archive are built with the version script Moreover, it can cause linker issues like binutils PR/18703 if the original symbol name and the base name of the versioned symbol is the same (both ld.bfd and gold have some code to work around defined @ and @@). In lld, if it sees f and f@v1: --version-script =(printf 'v1 {};') => f and f@v1 --version-script =(printf 'v1 { f; };') => f@v1 and f@@v1 It can be argued that @@@ added on 2000-11-13 corrected the @ and @@ mistake. This patch catches some more multiple version errors (defined @ and @@), and consistently suppress the original symbol. This addresses all the problems listed above. If the user wants other aliases to the versioned symbol, they can copy the original symbol to other symbol names with .set directive, e.g. .symver f, f@v1 # emit f@v1 but not f into .symtab .set f_impl, f # emit f_impl into .symtab llvm-svn: 369233
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