summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp5
-rw-r--r--llvm/lib/LTO/LTOBackend.cpp2
-rw-r--r--llvm/lib/MC/MCParser/ELFAsmParser.cpp1
-rw-r--r--llvm/lib/MC/MCStreamer.cpp2
-rw-r--r--llvm/lib/Object/ModuleSymbolTable.cpp89
-rw-r--r--llvm/lib/Object/RecordStreamer.cpp5
-rw-r--r--llvm/lib/Object/RecordStreamer.h18
-rw-r--r--llvm/lib/Transforms/IPO/FunctionImport.cpp2
8 files changed, 113 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 9bc55034c14..87b6c0d18a0 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -410,9 +410,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
// be listed on the llvm.used or llvm.compiler.used global and marked as
// referenced from there.
ModuleSymbolTable::CollectAsmSymbols(
- Triple(M.getTargetTriple()), M.getModuleInlineAsm(),
- [&M, &Index, &CantBePromoted](StringRef Name,
- object::BasicSymbolRef::Flags Flags) {
+ M, [&M, &Index, &CantBePromoted](StringRef Name,
+ object::BasicSymbolRef::Flags Flags) {
// Symbols not marked as Weak or Global are local definitions.
if (Flags & (object::BasicSymbolRef::SF_Weak |
object::BasicSymbolRef::SF_Global))
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 25795b1332e..605a32d7331 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -354,7 +354,7 @@ static void handleAsmUndefinedRefs(Module &Mod, TargetMachine &TM) {
// llvm.compiler.used to prevent optimization to drop these from the output.
StringSet<> AsmUndefinedRefs;
ModuleSymbolTable::CollectAsmSymbols(
- Triple(Mod.getTargetTriple()), Mod.getModuleInlineAsm(),
+ Mod,
[&AsmUndefinedRefs](StringRef Name, object::BasicSymbolRef::Flags Flags) {
if (Flags & object::BasicSymbolRef::SF_Undefined)
AsmUndefinedRefs.insert(Name);
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index b9426566b5c..fff081f0445 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -743,6 +743,7 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext());
getStreamer().EmitAssignment(Alias, Value);
+ getStreamer().emitELFSymverDirective(Alias, Sym);
return false;
}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 860c1bd6d87..b9c01c66f31 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -821,6 +821,8 @@ void MCStreamer::EmitCOFFSymbolType(int Type) {
llvm_unreachable("this directive only supported on COFF targets");
}
void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
+void MCStreamer::emitELFSymverDirective(MCSymbol *Alias,
+ const MCSymbol *Aliasee) {}
void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index 90488007ff5..21709b5c223 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -50,20 +50,95 @@ void ModuleSymbolTable::addModule(Module *M) {
for (GlobalAlias &GA : M->aliases())
SymTab.push_back(&GA);
- CollectAsmSymbols(Triple(M->getTargetTriple()), M->getModuleInlineAsm(),
- [this](StringRef Name, BasicSymbolRef::Flags Flags) {
- SymTab.push_back(new (AsmSymbols.Allocate())
- AsmSymbol(Name, Flags));
- });
+ CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
+ SymTab.push_back(new (AsmSymbols.Allocate()) AsmSymbol(Name, Flags));
+ });
+}
+
+// Ensure ELF .symver aliases get the same binding as the defined symbol
+// they alias with.
+static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
+ if (Streamer.symverAliases().empty())
+ return;
+
+ // The name in the assembler will be mangled, but the name in the IR
+ // might not, so we first compute a mapping from mangled name to GV.
+ Mangler Mang;
+ SmallString<64> MangledName;
+ StringMap<const GlobalValue *> MangledNameMap;
+ auto GetMangledName = [&](const GlobalValue &GV) {
+ if (!GV.hasName())
+ return;
+
+ MangledName.clear();
+ MangledName.reserve(GV.getName().size() + 1);
+ Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
+ MangledNameMap[MangledName] = &GV;
+ };
+ for (const Function &F : M)
+ GetMangledName(F);
+ for (const GlobalVariable &GV : M.globals())
+ GetMangledName(GV);
+ for (const GlobalAlias &GA : M.aliases())
+ GetMangledName(GA);
+
+ // Walk all the recorded .symver aliases, and set up the binding
+ // for each alias.
+ for (auto &Symver : Streamer.symverAliases()) {
+ const MCSymbol *Aliasee = Symver.first;
+ MCSymbolAttr Attr = MCSA_Invalid;
+
+ // First check if the aliasee binding was recorded in the asm.
+ RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
+ switch (state) {
+ case RecordStreamer::Global:
+ case RecordStreamer::DefinedGlobal:
+ Attr = MCSA_Global;
+ break;
+ case RecordStreamer::UndefinedWeak:
+ case RecordStreamer::DefinedWeak:
+ Attr = MCSA_Weak;
+ break;
+ default:
+ break;
+ }
+
+ // If we don't have a symbol attribute from assembly, then check if
+ // the aliasee was defined in the IR.
+ if (Attr == MCSA_Invalid) {
+ const auto *GV = M.getNamedValue(Aliasee->getName());
+ if (!GV) {
+ auto MI = MangledNameMap.find(Aliasee->getName());
+ if (MI != MangledNameMap.end())
+ GV = MI->second;
+ else
+ continue;
+ }
+ if (GV->hasExternalLinkage())
+ Attr = MCSA_Global;
+ else if (GV->hasLocalLinkage())
+ Attr = MCSA_Local;
+ else if (GV->isWeakForLinker())
+ Attr = MCSA_Weak;
+ }
+ if (Attr == MCSA_Invalid)
+ continue;
+
+ // Set the detected binding on each alias with this aliasee.
+ for (auto &Alias : Symver.second)
+ Streamer.EmitSymbolAttribute(Alias, Attr);
+ }
}
void ModuleSymbolTable::CollectAsmSymbols(
- const Triple &TT, StringRef InlineAsm,
+ const Module &M,
function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
+ StringRef InlineAsm = M.getModuleInlineAsm();
if (InlineAsm.empty())
return;
std::string Err;
+ const Triple TT(M.getTargetTriple());
const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
assert(T && T->hasMCAsmParser());
@@ -106,6 +181,8 @@ void ModuleSymbolTable::CollectAsmSymbols(
if (Parser->Run(false))
return;
+ handleSymverAliases(M, Streamer);
+
for (auto &KV : Streamer) {
StringRef Key = KV.first();
RecordStreamer::State Value = KV.second;
diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp
index da99b3fea00..8be6d0b60cf 100644
--- a/llvm/lib/Object/RecordStreamer.cpp
+++ b/llvm/lib/Object/RecordStreamer.cpp
@@ -110,3 +110,8 @@ void RecordStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
markDefined(*Symbol);
}
+
+void RecordStreamer::emitELFSymverDirective(MCSymbol *Alias,
+ const MCSymbol *Aliasee) {
+ SymverAliasMap[Aliasee].push_back(Alias);
+}
diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h
index c795dbb2e43..c3bd5b09a9b 100644
--- a/llvm/lib/Object/RecordStreamer.h
+++ b/llvm/lib/Object/RecordStreamer.h
@@ -20,6 +20,10 @@ public:
private:
StringMap<State> Symbols;
+ // Map of aliases created by .symver directives, saved so we can update
+ // their symbol binding after parsing complete. This maps from each
+ // aliasee to its list of aliases.
+ DenseMap<const MCSymbol *, std::vector<MCSymbol *>> SymverAliasMap;
void markDefined(const MCSymbol &Symbol);
void markGlobal(const MCSymbol &Symbol, MCSymbolAttr Attribute);
void markUsed(const MCSymbol &Symbol);
@@ -38,6 +42,20 @@ public:
unsigned ByteAlignment) override;
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
+ /// Record .symver aliases for later processing.
+ void emitELFSymverDirective(MCSymbol *Alias,
+ const MCSymbol *Aliasee) override;
+ /// Return the map of .symver aliasee to associated aliases.
+ DenseMap<const MCSymbol *, std::vector<MCSymbol *>> &symverAliases() {
+ return SymverAliasMap;
+ }
+ /// Get the state recorded for the given symbol.
+ State getSymbolState(const MCSymbol *Sym) {
+ auto SI = Symbols.find(Sym->getName());
+ if (SI == Symbols.end())
+ return NeverSeen;
+ return SI->second;
+ }
};
}
#endif
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 76cfbf81bd1..2c6dbb2a4ee 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -598,7 +598,7 @@ void llvm::thinLTOInternalizeModule(Module &TheModule,
// the current module.
StringSet<> AsmUndefinedRefs;
ModuleSymbolTable::CollectAsmSymbols(
- Triple(TheModule.getTargetTriple()), TheModule.getModuleInlineAsm(),
+ TheModule,
[&AsmUndefinedRefs](StringRef Name, object::BasicSymbolRef::Flags Flags) {
if (Flags & object::BasicSymbolRef::SF_Undefined)
AsmUndefinedRefs.insert(Name);
OpenPOWER on IntegriCloud