diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Object/ModuleSymbolTable.cpp | 81 | ||||
-rw-r--r-- | llvm/lib/Object/RecordStreamer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Object/RecordStreamer.h | 14 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp | 23 |
5 files changed, 103 insertions, 38 deletions
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp index f0d70aefd42..b353ef3c835 100644 --- a/llvm/lib/Object/ModuleSymbolTable.cpp +++ b/llvm/lib/Object/ModuleSymbolTable.cpp @@ -68,9 +68,9 @@ void ModuleSymbolTable::addModule(Module *M) { }); } -void ModuleSymbolTable::CollectAsmSymbols( - const Module &M, - function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { +static void +initializeRecordStreamer(const Module &M, + function_ref<void(RecordStreamer &)> Init) { StringRef InlineAsm = M.getModuleInlineAsm(); if (InlineAsm.empty()) return; @@ -119,36 +119,53 @@ void ModuleSymbolTable::CollectAsmSymbols( if (Parser->Run(false)) return; - Streamer.flushSymverDirectives(); - - for (auto &KV : Streamer) { - StringRef Key = KV.first(); - RecordStreamer::State Value = KV.second; - // FIXME: For now we just assume that all asm symbols are executable. - uint32_t Res = BasicSymbolRef::SF_Executable; - switch (Value) { - case RecordStreamer::NeverSeen: - llvm_unreachable("NeverSeen should have been replaced earlier"); - case RecordStreamer::DefinedGlobal: - Res |= BasicSymbolRef::SF_Global; - break; - case RecordStreamer::Defined: - break; - case RecordStreamer::Global: - case RecordStreamer::Used: - Res |= BasicSymbolRef::SF_Undefined; - Res |= BasicSymbolRef::SF_Global; - break; - case RecordStreamer::DefinedWeak: - Res |= BasicSymbolRef::SF_Weak; - Res |= BasicSymbolRef::SF_Global; - break; - case RecordStreamer::UndefinedWeak: - Res |= BasicSymbolRef::SF_Weak; - Res |= BasicSymbolRef::SF_Undefined; + Init(Streamer); +} + +void ModuleSymbolTable::CollectAsmSymbols( + const Module &M, + function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) { + initializeRecordStreamer(M, [&](RecordStreamer &Streamer) { + Streamer.flushSymverDirectives(); + + for (auto &KV : Streamer) { + StringRef Key = KV.first(); + RecordStreamer::State Value = KV.second; + // FIXME: For now we just assume that all asm symbols are executable. + uint32_t Res = BasicSymbolRef::SF_Executable; + switch (Value) { + case RecordStreamer::NeverSeen: + llvm_unreachable("NeverSeen should have been replaced earlier"); + case RecordStreamer::DefinedGlobal: + Res |= BasicSymbolRef::SF_Global; + break; + case RecordStreamer::Defined: + break; + case RecordStreamer::Global: + case RecordStreamer::Used: + Res |= BasicSymbolRef::SF_Undefined; + Res |= BasicSymbolRef::SF_Global; + break; + case RecordStreamer::DefinedWeak: + Res |= BasicSymbolRef::SF_Weak; + Res |= BasicSymbolRef::SF_Global; + break; + case RecordStreamer::UndefinedWeak: + Res |= BasicSymbolRef::SF_Weak; + Res |= BasicSymbolRef::SF_Undefined; + } + AsmSymbol(Key, BasicSymbolRef::Flags(Res)); } - AsmSymbol(Key, BasicSymbolRef::Flags(Res)); - } + }); +} + +void ModuleSymbolTable::CollectAsmSymvers( + const Module &M, function_ref<void(StringRef, StringRef)> AsmSymver) { + initializeRecordStreamer(M, [&](RecordStreamer &Streamer) { + for (auto &KV : Streamer.symverAliases()) + for (auto &Alias : KV.second) + AsmSymver(KV.first->getName(), Alias); + }); } void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const { diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp index 21577bb5696..f49c823c068 100644 --- a/llvm/lib/Object/RecordStreamer.cpp +++ b/llvm/lib/Object/RecordStreamer.cpp @@ -128,6 +128,11 @@ void RecordStreamer::emitELFSymverDirective(StringRef AliasName, SymverAliasMap[Aliasee].push_back(AliasName); } +iterator_range<RecordStreamer::const_symver_iterator> +RecordStreamer::symverAliases() { + return {SymverAliasMap.begin(), SymverAliasMap.end()}; +} + void RecordStreamer::flushSymverDirectives() { // Mapping from mangled name to GV. StringMap<const GlobalValue *> MangledNameMap; diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h index 60b2d3ec3e8..13eac028a28 100644 --- a/llvm/lib/Object/RecordStreamer.h +++ b/llvm/lib/Object/RecordStreamer.h @@ -47,10 +47,6 @@ private: public: RecordStreamer(MCContext &Context, const Module &M); - using const_iterator = StringMap<State>::const_iterator; - - const_iterator begin(); - const_iterator end(); void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; @@ -63,9 +59,19 @@ public: /// Record .symver aliases for later processing. void emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) override; + // Emit ELF .symver aliases and ensure they have the same binding as the // defined symbol they alias with. void flushSymverDirectives(); + + // Symbols iterators + using const_iterator = StringMap<State>::const_iterator; + const_iterator begin(); + const_iterator end(); + + // SymverAliasMap iterators + using const_symver_iterator = decltype(SymverAliasMap)::const_iterator; + iterator_range<const_symver_iterator> symverAliases(); }; } // end namespace llvm diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp index b568445b724..925d8f87b3f 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -1947,6 +1947,24 @@ bool LowerTypeTestsModule::lower() { } } + // Emit .symver directives for exported functions, if they exist. + if (ExportSummary) { + if (NamedMDNode *SymversMD = M.getNamedMetadata("symvers")) { + for (auto Symver : SymversMD->operands()) { + assert(Symver->getNumOperands() >= 2); + StringRef SymbolName = + cast<MDString>(Symver->getOperand(0))->getString(); + StringRef Alias = cast<MDString>(Symver->getOperand(1))->getString(); + + if (!ExportedFunctions.count(SymbolName)) + continue; + + M.appendModuleInlineAsm( + (llvm::Twine(".symver ") + SymbolName + ", " + Alias).str()); + } + } + } + return true; } diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp index 9bca88a54b3..2ba27af43a9 100644 --- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" +#include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Pass.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" @@ -301,13 +302,13 @@ void splitAndWriteThinLTOBitcode( promoteInternals(*MergedM, M, ModuleId, CfiFunctions); promoteInternals(M, *MergedM, ModuleId, CfiFunctions); + auto &Ctx = MergedM->getContext(); SmallVector<MDNode *, 8> CfiFunctionMDs; for (auto V : CfiFunctions) { Function &F = *cast<Function>(V); SmallVector<MDNode *, 2> Types; F.getMetadata(LLVMContext::MD_type, Types); - auto &Ctx = MergedM->getContext(); SmallVector<Metadata *, 4> Elts; Elts.push_back(MDString::get(Ctx, F.getName())); CfiFunctionLinkage Linkage; @@ -336,7 +337,6 @@ void splitAndWriteThinLTOBitcode( continue; auto *F = cast<Function>(A.getAliasee()); - auto &Ctx = MergedM->getContext(); SmallVector<Metadata *, 4> Elts; Elts.push_back(MDString::get(Ctx, A.getName())); @@ -355,6 +355,25 @@ void splitAndWriteThinLTOBitcode( NMD->addOperand(MD); } + SmallVector<MDNode *, 8> Symvers; + ModuleSymbolTable::CollectAsmSymvers(M, [&](StringRef Name, StringRef Alias) { + Function *F = M.getFunction(Name); + if (!F || F->use_empty()) + return; + + SmallVector<Metadata *, 2> Elts; + Elts.push_back(MDString::get(Ctx, Name)); + Elts.push_back(MDString::get(Ctx, Alias)); + + Symvers.push_back(MDTuple::get(Ctx, Elts)); + }); + + if (!Symvers.empty()) { + NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("symvers"); + for (auto MD : Symvers) + NMD->addOperand(MD); + } + simplifyExternals(*MergedM); // FIXME: Try to re-use BSI and PFI from the original module here. |