diff options
| author | 2020-08-03 15:06:44 +0000 | |
|---|---|---|
| committer | 2020-08-03 15:06:44 +0000 | |
| commit | b64793999546ed8adebaeebd9d8345d18db8927d (patch) | |
| tree | 4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/lib/Linker/LinkModules.cpp | |
| parent | Add support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff) | |
| download | wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip | |
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/lib/Linker/LinkModules.cpp')
| -rw-r--r-- | gnu/llvm/lib/Linker/LinkModules.cpp | 606 |
1 files changed, 0 insertions, 606 deletions
diff --git a/gnu/llvm/lib/Linker/LinkModules.cpp b/gnu/llvm/lib/Linker/LinkModules.cpp deleted file mode 100644 index 25f31a3401a..00000000000 --- a/gnu/llvm/lib/Linker/LinkModules.cpp +++ /dev/null @@ -1,606 +0,0 @@ -//===- lib/Linker/LinkModules.cpp - Module Linker Implementation ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the LLVM module linker. -// -//===----------------------------------------------------------------------===// - -#include "LinkDiagnosticInfo.h" -#include "llvm-c/Linker.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/IR/Comdat.h" -#include "llvm/IR/DiagnosticPrinter.h" -#include "llvm/IR/GlobalValue.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/Linker/Linker.h" -#include "llvm/Support/Error.h" -using namespace llvm; - -namespace { - -/// This is an implementation class for the LinkModules function, which is the -/// entrypoint for this file. -class ModuleLinker { - IRMover &Mover; - std::unique_ptr<Module> SrcM; - - SetVector<GlobalValue *> ValuesToLink; - - /// For symbol clashes, prefer those from Src. - unsigned Flags; - - /// List of global value names that should be internalized. - StringSet<> Internalize; - - /// Function that will perform the actual internalization. The reason for a - /// callback is that the linker cannot call internalizeModule without - /// creating a circular dependency between IPO and the linker. - std::function<void(Module &, const StringSet<> &)> InternalizeCallback; - - /// Used as the callback for lazy linking. - /// The mover has just hit GV and we have to decide if it, and other members - /// of the same comdat, should be linked. Every member to be linked is passed - /// to Add. - void addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add); - - bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; } - bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; } - - bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, - const GlobalValue &Src); - - /// Should we have mover and linker error diag info? - bool emitError(const Twine &Message) { - SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message)); - return true; - } - - bool getComdatLeader(Module &M, StringRef ComdatName, - const GlobalVariable *&GVar); - bool computeResultingSelectionKind(StringRef ComdatName, - Comdat::SelectionKind Src, - Comdat::SelectionKind Dst, - Comdat::SelectionKind &Result, - bool &LinkFromSrc); - std::map<const Comdat *, std::pair<Comdat::SelectionKind, bool>> - ComdatsChosen; - bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, - bool &LinkFromSrc); - // Keep track of the lazy linked global members of each comdat in source. - DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers; - - /// Given a global in the source module, return the global in the - /// destination module that is being linked to, if any. - GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) { - Module &DstM = Mover.getModule(); - // If the source has no name it can't link. If it has local linkage, - // there is no name match-up going on. - if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(SrcGV->getLinkage())) - return nullptr; - - // Otherwise see if we have a match in the destination module's symtab. - GlobalValue *DGV = DstM.getNamedValue(SrcGV->getName()); - if (!DGV) - return nullptr; - - // If we found a global with the same name in the dest module, but it has - // internal linkage, we are really not doing any linkage here. - if (DGV->hasLocalLinkage()) - return nullptr; - - // Otherwise, we do in fact link to the destination global. - return DGV; - } - - /// Drop GV if it is a member of a comdat that we are dropping. - /// This can happen with COFF's largest selection kind. - void dropReplacedComdat(GlobalValue &GV, - const DenseSet<const Comdat *> &ReplacedDstComdats); - - bool linkIfNeeded(GlobalValue &GV); - -public: - ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags, - std::function<void(Module &, const StringSet<> &)> - InternalizeCallback = {}) - : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags), - InternalizeCallback(std::move(InternalizeCallback)) {} - - bool run(); -}; -} - -static GlobalValue::VisibilityTypes -getMinVisibility(GlobalValue::VisibilityTypes A, - GlobalValue::VisibilityTypes B) { - if (A == GlobalValue::HiddenVisibility || B == GlobalValue::HiddenVisibility) - return GlobalValue::HiddenVisibility; - if (A == GlobalValue::ProtectedVisibility || - B == GlobalValue::ProtectedVisibility) - return GlobalValue::ProtectedVisibility; - return GlobalValue::DefaultVisibility; -} - -bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName, - const GlobalVariable *&GVar) { - const GlobalValue *GVal = M.getNamedValue(ComdatName); - if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) { - GVal = GA->getBaseObject(); - if (!GVal) - // We cannot resolve the size of the aliasee yet. - return emitError("Linking COMDATs named '" + ComdatName + - "': COMDAT key involves incomputable alias size."); - } - - GVar = dyn_cast_or_null<GlobalVariable>(GVal); - if (!GVar) - return emitError( - "Linking COMDATs named '" + ComdatName + - "': GlobalVariable required for data dependent selection!"); - - return false; -} - -bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName, - Comdat::SelectionKind Src, - Comdat::SelectionKind Dst, - Comdat::SelectionKind &Result, - bool &LinkFromSrc) { - Module &DstM = Mover.getModule(); - // The ability to mix Comdat::SelectionKind::Any with - // Comdat::SelectionKind::Largest is a behavior that comes from COFF. - bool DstAnyOrLargest = Dst == Comdat::SelectionKind::Any || - Dst == Comdat::SelectionKind::Largest; - bool SrcAnyOrLargest = Src == Comdat::SelectionKind::Any || - Src == Comdat::SelectionKind::Largest; - if (DstAnyOrLargest && SrcAnyOrLargest) { - if (Dst == Comdat::SelectionKind::Largest || - Src == Comdat::SelectionKind::Largest) - Result = Comdat::SelectionKind::Largest; - else - Result = Comdat::SelectionKind::Any; - } else if (Src == Dst) { - Result = Dst; - } else { - return emitError("Linking COMDATs named '" + ComdatName + - "': invalid selection kinds!"); - } - - switch (Result) { - case Comdat::SelectionKind::Any: - // Go with Dst. - LinkFromSrc = false; - break; - case Comdat::SelectionKind::NoDuplicates: - return emitError("Linking COMDATs named '" + ComdatName + - "': noduplicates has been violated!"); - case Comdat::SelectionKind::ExactMatch: - case Comdat::SelectionKind::Largest: - case Comdat::SelectionKind::SameSize: { - const GlobalVariable *DstGV; - const GlobalVariable *SrcGV; - if (getComdatLeader(DstM, ComdatName, DstGV) || - getComdatLeader(*SrcM, ComdatName, SrcGV)) - return true; - - const DataLayout &DstDL = DstM.getDataLayout(); - const DataLayout &SrcDL = SrcM->getDataLayout(); - uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType()); - uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType()); - if (Result == Comdat::SelectionKind::ExactMatch) { - if (SrcGV->getInitializer() != DstGV->getInitializer()) - return emitError("Linking COMDATs named '" + ComdatName + - "': ExactMatch violated!"); - LinkFromSrc = false; - } else if (Result == Comdat::SelectionKind::Largest) { - LinkFromSrc = SrcSize > DstSize; - } else if (Result == Comdat::SelectionKind::SameSize) { - if (SrcSize != DstSize) - return emitError("Linking COMDATs named '" + ComdatName + - "': SameSize violated!"); - LinkFromSrc = false; - } else { - llvm_unreachable("unknown selection kind"); - } - break; - } - } - - return false; -} - -bool ModuleLinker::getComdatResult(const Comdat *SrcC, - Comdat::SelectionKind &Result, - bool &LinkFromSrc) { - Module &DstM = Mover.getModule(); - Comdat::SelectionKind SSK = SrcC->getSelectionKind(); - StringRef ComdatName = SrcC->getName(); - Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); - Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName); - - if (DstCI == ComdatSymTab.end()) { - // Use the comdat if it is only available in one of the modules. - LinkFromSrc = true; - Result = SSK; - return false; - } - - const Comdat *DstC = &DstCI->second; - Comdat::SelectionKind DSK = DstC->getSelectionKind(); - return computeResultingSelectionKind(ComdatName, SSK, DSK, Result, - LinkFromSrc); -} - -bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, - const GlobalValue &Dest, - const GlobalValue &Src) { - - // Should we unconditionally use the Src? - if (shouldOverrideFromSrc()) { - LinkFromSrc = true; - return false; - } - - // We always have to add Src if it has appending linkage. - if (Src.hasAppendingLinkage()) { - LinkFromSrc = true; - return false; - } - - bool SrcIsDeclaration = Src.isDeclarationForLinker(); - bool DestIsDeclaration = Dest.isDeclarationForLinker(); - - if (SrcIsDeclaration) { - // If Src is external or if both Src & Dest are external.. Just link the - // external globals, we aren't adding anything. - if (Src.hasDLLImportStorageClass()) { - // If one of GVs is marked as DLLImport, result should be dllimport'ed. - LinkFromSrc = DestIsDeclaration; - return false; - } - // If the Dest is weak, use the source linkage. - if (Dest.hasExternalWeakLinkage()) { - LinkFromSrc = true; - return false; - } - // Link an available_externally over a declaration. - LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); - return false; - } - - if (DestIsDeclaration) { - // If Dest is external but Src is not: - LinkFromSrc = true; - return false; - } - - if (Src.hasCommonLinkage()) { - if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { - LinkFromSrc = true; - return false; - } - - if (!Dest.hasCommonLinkage()) { - LinkFromSrc = false; - return false; - } - - const DataLayout &DL = Dest.getParent()->getDataLayout(); - uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); - uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); - LinkFromSrc = SrcSize > DestSize; - return false; - } - - if (Src.isWeakForLinker()) { - assert(!Dest.hasExternalWeakLinkage()); - assert(!Dest.hasAvailableExternallyLinkage()); - - if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { - LinkFromSrc = true; - return false; - } - - LinkFromSrc = false; - return false; - } - - if (Dest.isWeakForLinker()) { - assert(Src.hasExternalLinkage()); - LinkFromSrc = true; - return false; - } - - assert(!Src.hasExternalWeakLinkage()); - assert(!Dest.hasExternalWeakLinkage()); - assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && - "Unexpected linkage type!"); - return emitError("Linking globals named '" + Src.getName() + - "': symbol multiply defined!"); -} - -bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { - GlobalValue *DGV = getLinkedToGlobal(&GV); - - if (shouldLinkOnlyNeeded()) { - // Always import variables with appending linkage. - if (!GV.hasAppendingLinkage()) { - // Don't import globals unless they are referenced by the destination - // module. - if (!DGV) - return false; - // Don't import globals that are already defined in the destination module - if (!DGV->isDeclaration()) - return false; - } - } - - if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { - auto *DGVar = dyn_cast<GlobalVariable>(DGV); - auto *SGVar = dyn_cast<GlobalVariable>(&GV); - if (DGVar && SGVar) { - if (DGVar->isDeclaration() && SGVar->isDeclaration() && - (!DGVar->isConstant() || !SGVar->isConstant())) { - DGVar->setConstant(false); - SGVar->setConstant(false); - } - if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { - unsigned Align = std::max(DGVar->getAlignment(), SGVar->getAlignment()); - SGVar->setAlignment(Align); - DGVar->setAlignment(Align); - } - } - - GlobalValue::VisibilityTypes Visibility = - getMinVisibility(DGV->getVisibility(), GV.getVisibility()); - DGV->setVisibility(Visibility); - GV.setVisibility(Visibility); - - GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr( - DGV->getUnnamedAddr(), GV.getUnnamedAddr()); - DGV->setUnnamedAddr(UnnamedAddr); - GV.setUnnamedAddr(UnnamedAddr); - } - - if (!DGV && !shouldOverrideFromSrc() && - (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || - GV.hasAvailableExternallyLinkage())) - return false; - - if (GV.isDeclaration()) - return false; - - if (const Comdat *SC = GV.getComdat()) { - bool LinkFromSrc; - Comdat::SelectionKind SK; - std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; - if (!LinkFromSrc) - return false; - } - - bool LinkFromSrc = true; - if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV)) - return true; - if (LinkFromSrc) - ValuesToLink.insert(&GV); - return false; -} - -void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) { - // Add these to the internalize list - if (!GV.hasLinkOnceLinkage() && !GV.hasAvailableExternallyLinkage() && - !shouldLinkOnlyNeeded()) - return; - - if (InternalizeCallback) - Internalize.insert(GV.getName()); - Add(GV); - - const Comdat *SC = GV.getComdat(); - if (!SC) - return; - for (GlobalValue *GV2 : LazyComdatMembers[SC]) { - GlobalValue *DGV = getLinkedToGlobal(GV2); - bool LinkFromSrc = true; - if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) - return; - if (!LinkFromSrc) - continue; - if (InternalizeCallback) - Internalize.insert(GV2->getName()); - Add(*GV2); - } -} - -void ModuleLinker::dropReplacedComdat( - GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) { - Comdat *C = GV.getComdat(); - if (!C) - return; - if (!ReplacedDstComdats.count(C)) - return; - if (GV.use_empty()) { - GV.eraseFromParent(); - return; - } - - if (auto *F = dyn_cast<Function>(&GV)) { - F->deleteBody(); - } else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) { - Var->setInitializer(nullptr); - } else { - auto &Alias = cast<GlobalAlias>(GV); - Module &M = *Alias.getParent(); - PointerType &Ty = *cast<PointerType>(Alias.getType()); - GlobalValue *Declaration; - if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) { - Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M); - } else { - Declaration = - new GlobalVariable(M, Ty.getElementType(), /*isConstant*/ false, - GlobalValue::ExternalLinkage, - /*Initializer*/ nullptr); - } - Declaration->takeName(&Alias); - Alias.replaceAllUsesWith(Declaration); - Alias.eraseFromParent(); - } -} - -bool ModuleLinker::run() { - Module &DstM = Mover.getModule(); - DenseSet<const Comdat *> ReplacedDstComdats; - - for (const auto &SMEC : SrcM->getComdatSymbolTable()) { - const Comdat &C = SMEC.getValue(); - if (ComdatsChosen.count(&C)) - continue; - Comdat::SelectionKind SK; - bool LinkFromSrc; - if (getComdatResult(&C, SK, LinkFromSrc)) - return true; - ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc); - - if (!LinkFromSrc) - continue; - - Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); - Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName()); - if (DstCI == ComdatSymTab.end()) - continue; - - // The source comdat is replacing the dest one. - const Comdat *DstC = &DstCI->second; - ReplacedDstComdats.insert(DstC); - } - - // Alias have to go first, since we are not able to find their comdats - // otherwise. - for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) { - GlobalAlias &GV = *I++; - dropReplacedComdat(GV, ReplacedDstComdats); - } - - for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) { - GlobalVariable &GV = *I++; - dropReplacedComdat(GV, ReplacedDstComdats); - } - - for (auto I = DstM.begin(), E = DstM.end(); I != E;) { - Function &GV = *I++; - dropReplacedComdat(GV, ReplacedDstComdats); - } - - for (GlobalVariable &GV : SrcM->globals()) - if (GV.hasLinkOnceLinkage()) - if (const Comdat *SC = GV.getComdat()) - LazyComdatMembers[SC].push_back(&GV); - - for (Function &SF : *SrcM) - if (SF.hasLinkOnceLinkage()) - if (const Comdat *SC = SF.getComdat()) - LazyComdatMembers[SC].push_back(&SF); - - for (GlobalAlias &GA : SrcM->aliases()) - if (GA.hasLinkOnceLinkage()) - if (const Comdat *SC = GA.getComdat()) - LazyComdatMembers[SC].push_back(&GA); - - // Insert all of the globals in src into the DstM module... without linking - // initializers (which could refer to functions not yet mapped over). - for (GlobalVariable &GV : SrcM->globals()) - if (linkIfNeeded(GV)) - return true; - - for (Function &SF : *SrcM) - if (linkIfNeeded(SF)) - return true; - - for (GlobalAlias &GA : SrcM->aliases()) - if (linkIfNeeded(GA)) - return true; - - for (unsigned I = 0; I < ValuesToLink.size(); ++I) { - GlobalValue *GV = ValuesToLink[I]; - const Comdat *SC = GV->getComdat(); - if (!SC) - continue; - for (GlobalValue *GV2 : LazyComdatMembers[SC]) { - GlobalValue *DGV = getLinkedToGlobal(GV2); - bool LinkFromSrc = true; - if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) - return true; - if (LinkFromSrc) - ValuesToLink.insert(GV2); - } - } - - if (InternalizeCallback) { - for (GlobalValue *GV : ValuesToLink) - Internalize.insert(GV->getName()); - } - - // FIXME: Propagate Errors through to the caller instead of emitting - // diagnostics. - bool HasErrors = false; - if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(), - [this](GlobalValue &GV, IRMover::ValueAdder Add) { - addLazyFor(GV, Add); - }, - /* IsPerformingImport */ false)) { - handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { - DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message())); - HasErrors = true; - }); - } - if (HasErrors) - return true; - - if (InternalizeCallback) - InternalizeCallback(DstM, Internalize); - - return false; -} - -Linker::Linker(Module &M) : Mover(M) {} - -bool Linker::linkInModule( - std::unique_ptr<Module> Src, unsigned Flags, - std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { - ModuleLinker ModLinker(Mover, std::move(Src), Flags, - std::move(InternalizeCallback)); - return ModLinker.run(); -} - -//===----------------------------------------------------------------------===// -// LinkModules entrypoint. -//===----------------------------------------------------------------------===// - -/// This function links two modules together, with the resulting Dest module -/// modified to be the composite of the two input modules. If an error occurs, -/// true is returned and ErrorMsg (if not null) is set to indicate the problem. -/// Upon failure, the Dest module could be in a modified state, and shouldn't be -/// relied on to be consistent. -bool Linker::linkModules( - Module &Dest, std::unique_ptr<Module> Src, unsigned Flags, - std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { - Linker L(Dest); - return L.linkInModule(std::move(Src), Flags, std::move(InternalizeCallback)); -} - -//===----------------------------------------------------------------------===// -// C API. -//===----------------------------------------------------------------------===// - -LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) { - Module *D = unwrap(Dest); - std::unique_ptr<Module> M(unwrap(Src)); - return Linker::linkModules(*D, std::move(M)); -} |
