159a5afa9SMikhail Glushenkov //===- lib/Linker/LinkModules.cpp - Module Linker Implementation ----------===// 2361e513dSReid Spencer // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6361e513dSReid Spencer // 7361e513dSReid Spencer //===----------------------------------------------------------------------===// 8361e513dSReid Spencer // 9361e513dSReid Spencer // This file implements the LLVM module linker. 10361e513dSReid Spencer // 11361e513dSReid Spencer //===----------------------------------------------------------------------===// 12361e513dSReid Spencer 13caabe228SRafael Espindola #include "LinkDiagnosticInfo.h" 14ed0881b2SChandler Carruth #include "llvm-c/Linker.h" 1566f02413SBill Wendling #include "llvm/ADT/SetVector.h" 167c702116SPeter Collingbourne #include "llvm/IR/Comdat.h" 17d12b4a33SRafael Espindola #include "llvm/IR/DiagnosticPrinter.h" 187c702116SPeter Collingbourne #include "llvm/IR/GlobalValue.h" 199d2bfc48SRafael Espindola #include "llvm/IR/LLVMContext.h" 207c702116SPeter Collingbourne #include "llvm/IR/Module.h" 21488a800aSTeresa Johnson #include "llvm/Linker/Linker.h" 221eaa97f4SPeter Collingbourne #include "llvm/Support/Error.h" 23361e513dSReid Spencer using namespace llvm; 24361e513dSReid Spencer 25b1ed91f3SChris Lattner namespace { 26d12b4a33SRafael Espindola 2718c89411SRafael Espindola /// This is an implementation class for the LinkModules function, which is the 2818c89411SRafael Espindola /// entrypoint for this file. 29b1ed91f3SChris Lattner class ModuleLinker { 30caabe228SRafael Espindola IRMover &Mover; 3140358fb8SRafael Espindola std::unique_ptr<Module> SrcM; 32b1ed91f3SChris Lattner 334b5ec263SRafael Espindola SetVector<GlobalValue *> ValuesToLink; 344160f5d3SRafael Espindola 35e868123dSDuncan P. N. Exon Smith /// For symbol clashes, prefer those from Src. 36020d4fb1SArtem Belevich unsigned Flags; 37e868123dSDuncan P. N. Exon Smith 385eb9c81dSJonas Devlieghere /// List of global value names that should be internalized. 395eb9c81dSJonas Devlieghere StringSet<> Internalize; 405eb9c81dSJonas Devlieghere 415eb9c81dSJonas Devlieghere /// Function that will perform the actual internalization. The reason for a 425eb9c81dSJonas Devlieghere /// callback is that the linker cannot call internalizeModule without 435eb9c81dSJonas Devlieghere /// creating a circular dependency between IPO and the linker. 445eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback; 455eb9c81dSJonas Devlieghere 46caabe228SRafael Espindola /// Used as the callback for lazy linking. 47caabe228SRafael Espindola /// The mover has just hit GV and we have to decide if it, and other members 48caabe228SRafael Espindola /// of the same comdat, should be linked. Every member to be linked is passed 49caabe228SRafael Espindola /// to Add. 50c321e534SBenjamin Kramer void addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add); 51baa3bf8fSRafael Espindola 52020d4fb1SArtem Belevich bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; } 53020d4fb1SArtem Belevich bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; } 54020d4fb1SArtem Belevich 55d12b4a33SRafael Espindola bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, 56d12b4a33SRafael Espindola const GlobalValue &Src); 57dbb0bd1aSRafael Espindola 58caabe228SRafael Espindola /// Should we have mover and linker error diag info? 59b1ed91f3SChris Lattner bool emitError(const Twine &Message) { 6040358fb8SRafael Espindola SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message)); 61b1ed91f3SChris Lattner return true; 62b1ed91f3SChris Lattner } 63b1ed91f3SChris Lattner 640e309fe8SRafael Espindola bool getComdatLeader(Module &M, StringRef ComdatName, 65dad0a645SDavid Majnemer const GlobalVariable *&GVar); 66dad0a645SDavid Majnemer bool computeResultingSelectionKind(StringRef ComdatName, 67dad0a645SDavid Majnemer Comdat::SelectionKind Src, 68dad0a645SDavid Majnemer Comdat::SelectionKind Dst, 69dad0a645SDavid Majnemer Comdat::SelectionKind &Result, 70dad0a645SDavid Majnemer bool &LinkFromSrc); 71dad0a645SDavid Majnemer std::map<const Comdat *, std::pair<Comdat::SelectionKind, bool>> 72dad0a645SDavid Majnemer ComdatsChosen; 73dad0a645SDavid Majnemer bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, 74dad0a645SDavid Majnemer bool &LinkFromSrc); 751ee9fbd8SRafael Espindola // Keep track of the lazy linked global members of each comdat in source. 761ee9fbd8SRafael Espindola DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers; 77dad0a645SDavid Majnemer 7818c89411SRafael Espindola /// Given a global in the source module, return the global in the 7918c89411SRafael Espindola /// destination module that is being linked to, if any. 803e8bc6a8SRafael Espindola GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) { 81caabe228SRafael Espindola Module &DstM = Mover.getModule(); 82b1ed91f3SChris Lattner // If the source has no name it can't link. If it has local linkage, 83b1ed91f3SChris Lattner // there is no name match-up going on. 844504c1bcSTeresa Johnson if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(SrcGV->getLinkage())) 852617dcceSCraig Topper return nullptr; 86b1ed91f3SChris Lattner 87b1ed91f3SChris Lattner // Otherwise see if we have a match in the destination module's symtab. 884504c1bcSTeresa Johnson GlobalValue *DGV = DstM.getNamedValue(SrcGV->getName()); 89c84f608bSRafael Espindola if (!DGV) 90c84f608bSRafael Espindola return nullptr; 91b1ed91f3SChris Lattner 92b1ed91f3SChris Lattner // If we found a global with the same name in the dest module, but it has 93b1ed91f3SChris Lattner // internal linkage, we are really not doing any linkage here. 94b1ed91f3SChris Lattner if (DGV->hasLocalLinkage()) 952617dcceSCraig Topper return nullptr; 96b1ed91f3SChris Lattner 97b1ed91f3SChris Lattner // Otherwise, we do in fact link to the destination global. 98b1ed91f3SChris Lattner return DGV; 99b1ed91f3SChris Lattner } 100b1ed91f3SChris Lattner 101370d528aSRafael Espindola /// Drop GV if it is a member of a comdat that we are dropping. 102370d528aSRafael Espindola /// This can happen with COFF's largest selection kind. 103370d528aSRafael Espindola void dropReplacedComdat(GlobalValue &GV, 104370d528aSRafael Espindola const DenseSet<const Comdat *> &ReplacedDstComdats); 105370d528aSRafael Espindola 106baa3bf8fSRafael Espindola bool linkIfNeeded(GlobalValue &GV); 107c7ed52f2STeresa Johnson 1084504c1bcSTeresa Johnson public: 1095eb9c81dSJonas Devlieghere ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags, 1105eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> 1115eb9c81dSJonas Devlieghere InternalizeCallback = {}) 1125eb9c81dSJonas Devlieghere : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags), 1135eb9c81dSJonas Devlieghere InternalizeCallback(std::move(InternalizeCallback)) {} 1144504c1bcSTeresa Johnson 1154504c1bcSTeresa Johnson bool run(); 1164504c1bcSTeresa Johnson }; 1174504c1bcSTeresa Johnson } 1184504c1bcSTeresa Johnson 119eb5e0a77SRafael Espindola static GlobalValue::VisibilityTypes 120eb5e0a77SRafael Espindola getMinVisibility(GlobalValue::VisibilityTypes A, 121eb5e0a77SRafael Espindola GlobalValue::VisibilityTypes B) { 122eb5e0a77SRafael Espindola if (A == GlobalValue::HiddenVisibility || B == GlobalValue::HiddenVisibility) 123eb5e0a77SRafael Espindola return GlobalValue::HiddenVisibility; 124eb5e0a77SRafael Espindola if (A == GlobalValue::ProtectedVisibility || 125eb5e0a77SRafael Espindola B == GlobalValue::ProtectedVisibility) 126eb5e0a77SRafael Espindola return GlobalValue::ProtectedVisibility; 127eb5e0a77SRafael Espindola return GlobalValue::DefaultVisibility; 128eb5e0a77SRafael Espindola } 129eb5e0a77SRafael Espindola 1300e309fe8SRafael Espindola bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName, 131dad0a645SDavid Majnemer const GlobalVariable *&GVar) { 1320e309fe8SRafael Espindola const GlobalValue *GVal = M.getNamedValue(ComdatName); 133dad0a645SDavid Majnemer if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) { 134dad0a645SDavid Majnemer GVal = GA->getBaseObject(); 135dad0a645SDavid Majnemer if (!GVal) 136dad0a645SDavid Majnemer // We cannot resolve the size of the aliasee yet. 137dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 138dad0a645SDavid Majnemer "': COMDAT key involves incomputable alias size."); 139dad0a645SDavid Majnemer } 140dad0a645SDavid Majnemer 141dad0a645SDavid Majnemer GVar = dyn_cast_or_null<GlobalVariable>(GVal); 142dad0a645SDavid Majnemer if (!GVar) 143dad0a645SDavid Majnemer return emitError( 144dad0a645SDavid Majnemer "Linking COMDATs named '" + ComdatName + 145dad0a645SDavid Majnemer "': GlobalVariable required for data dependent selection!"); 146dad0a645SDavid Majnemer 147dad0a645SDavid Majnemer return false; 148dad0a645SDavid Majnemer } 149dad0a645SDavid Majnemer 150dad0a645SDavid Majnemer bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName, 151dad0a645SDavid Majnemer Comdat::SelectionKind Src, 152dad0a645SDavid Majnemer Comdat::SelectionKind Dst, 153dad0a645SDavid Majnemer Comdat::SelectionKind &Result, 154dad0a645SDavid Majnemer bool &LinkFromSrc) { 155caabe228SRafael Espindola Module &DstM = Mover.getModule(); 156dad0a645SDavid Majnemer // The ability to mix Comdat::SelectionKind::Any with 157dad0a645SDavid Majnemer // Comdat::SelectionKind::Largest is a behavior that comes from COFF. 158dad0a645SDavid Majnemer bool DstAnyOrLargest = Dst == Comdat::SelectionKind::Any || 159dad0a645SDavid Majnemer Dst == Comdat::SelectionKind::Largest; 160dad0a645SDavid Majnemer bool SrcAnyOrLargest = Src == Comdat::SelectionKind::Any || 161dad0a645SDavid Majnemer Src == Comdat::SelectionKind::Largest; 162dad0a645SDavid Majnemer if (DstAnyOrLargest && SrcAnyOrLargest) { 163dad0a645SDavid Majnemer if (Dst == Comdat::SelectionKind::Largest || 164dad0a645SDavid Majnemer Src == Comdat::SelectionKind::Largest) 165dad0a645SDavid Majnemer Result = Comdat::SelectionKind::Largest; 166dad0a645SDavid Majnemer else 167dad0a645SDavid Majnemer Result = Comdat::SelectionKind::Any; 168dad0a645SDavid Majnemer } else if (Src == Dst) { 169dad0a645SDavid Majnemer Result = Dst; 170dad0a645SDavid Majnemer } else { 171dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 172dad0a645SDavid Majnemer "': invalid selection kinds!"); 173dad0a645SDavid Majnemer } 174dad0a645SDavid Majnemer 175dad0a645SDavid Majnemer switch (Result) { 176dad0a645SDavid Majnemer case Comdat::SelectionKind::Any: 177dad0a645SDavid Majnemer // Go with Dst. 178dad0a645SDavid Majnemer LinkFromSrc = false; 179dad0a645SDavid Majnemer break; 180dad0a645SDavid Majnemer case Comdat::SelectionKind::NoDuplicates: 181dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 182dad0a645SDavid Majnemer "': noduplicates has been violated!"); 183dad0a645SDavid Majnemer case Comdat::SelectionKind::ExactMatch: 184dad0a645SDavid Majnemer case Comdat::SelectionKind::Largest: 185dad0a645SDavid Majnemer case Comdat::SelectionKind::SameSize: { 186dad0a645SDavid Majnemer const GlobalVariable *DstGV; 187dad0a645SDavid Majnemer const GlobalVariable *SrcGV; 188dad0a645SDavid Majnemer if (getComdatLeader(DstM, ComdatName, DstGV) || 18940358fb8SRafael Espindola getComdatLeader(*SrcM, ComdatName, SrcGV)) 190dad0a645SDavid Majnemer return true; 191dad0a645SDavid Majnemer 1920e309fe8SRafael Espindola const DataLayout &DstDL = DstM.getDataLayout(); 19340358fb8SRafael Espindola const DataLayout &SrcDL = SrcM->getDataLayout(); 1945f6eaac6SManuel Jacob uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType()); 1955f6eaac6SManuel Jacob uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType()); 196dad0a645SDavid Majnemer if (Result == Comdat::SelectionKind::ExactMatch) { 197dad0a645SDavid Majnemer if (SrcGV->getInitializer() != DstGV->getInitializer()) 198dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 199dad0a645SDavid Majnemer "': ExactMatch violated!"); 200dad0a645SDavid Majnemer LinkFromSrc = false; 201dad0a645SDavid Majnemer } else if (Result == Comdat::SelectionKind::Largest) { 202dad0a645SDavid Majnemer LinkFromSrc = SrcSize > DstSize; 203dad0a645SDavid Majnemer } else if (Result == Comdat::SelectionKind::SameSize) { 204dad0a645SDavid Majnemer if (SrcSize != DstSize) 205dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 206dad0a645SDavid Majnemer "': SameSize violated!"); 207dad0a645SDavid Majnemer LinkFromSrc = false; 208dad0a645SDavid Majnemer } else { 209dad0a645SDavid Majnemer llvm_unreachable("unknown selection kind"); 210dad0a645SDavid Majnemer } 211dad0a645SDavid Majnemer break; 212dad0a645SDavid Majnemer } 213dad0a645SDavid Majnemer } 214dad0a645SDavid Majnemer 215dad0a645SDavid Majnemer return false; 216dad0a645SDavid Majnemer } 217dad0a645SDavid Majnemer 218dad0a645SDavid Majnemer bool ModuleLinker::getComdatResult(const Comdat *SrcC, 219dad0a645SDavid Majnemer Comdat::SelectionKind &Result, 220dad0a645SDavid Majnemer bool &LinkFromSrc) { 221caabe228SRafael Espindola Module &DstM = Mover.getModule(); 222b16196a3SRafael Espindola Comdat::SelectionKind SSK = SrcC->getSelectionKind(); 223dad0a645SDavid Majnemer StringRef ComdatName = SrcC->getName(); 2240e309fe8SRafael Espindola Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); 225dad0a645SDavid Majnemer Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName); 2262ef3f299SRafael Espindola 227b16196a3SRafael Espindola if (DstCI == ComdatSymTab.end()) { 228b16196a3SRafael Espindola // Use the comdat if it is only available in one of the modules. 229b16196a3SRafael Espindola LinkFromSrc = true; 230b16196a3SRafael Espindola Result = SSK; 2312ef3f299SRafael Espindola return false; 232b16196a3SRafael Espindola } 2332ef3f299SRafael Espindola 234dad0a645SDavid Majnemer const Comdat *DstC = &DstCI->second; 235dad0a645SDavid Majnemer Comdat::SelectionKind DSK = DstC->getSelectionKind(); 2362ef3f299SRafael Espindola return computeResultingSelectionKind(ComdatName, SSK, DSK, Result, 2372ef3f299SRafael Espindola LinkFromSrc); 238dad0a645SDavid Majnemer } 239f6f121e2SJames Molloy 240d12b4a33SRafael Espindola bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, 241d12b4a33SRafael Espindola const GlobalValue &Dest, 242dbb0bd1aSRafael Espindola const GlobalValue &Src) { 243e5a61917STeresa Johnson 244e868123dSDuncan P. N. Exon Smith // Should we unconditionally use the Src? 245020d4fb1SArtem Belevich if (shouldOverrideFromSrc()) { 246e868123dSDuncan P. N. Exon Smith LinkFromSrc = true; 247e868123dSDuncan P. N. Exon Smith return false; 248e868123dSDuncan P. N. Exon Smith } 249e868123dSDuncan P. N. Exon Smith 250778fcc77SRafael Espindola // We always have to add Src if it has appending linkage. 251267a57a6SSergey Dmitriev if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) { 252778fcc77SRafael Espindola LinkFromSrc = true; 253778fcc77SRafael Espindola return false; 254778fcc77SRafael Espindola } 255778fcc77SRafael Espindola 256d826bbbbSMehdi Amini bool SrcIsDeclaration = Src.isDeclarationForLinker(); 257d826bbbbSMehdi Amini bool DestIsDeclaration = Dest.isDeclarationForLinker(); 258c7ed52f2STeresa Johnson 259dbb0bd1aSRafael Espindola if (SrcIsDeclaration) { 260dbb0bd1aSRafael Espindola // If Src is external or if both Src & Dest are external.. Just link the 261dbb0bd1aSRafael Espindola // external globals, we aren't adding anything. 262d12b4a33SRafael Espindola if (Src.hasDLLImportStorageClass()) { 263dbb0bd1aSRafael Espindola // If one of GVs is marked as DLLImport, result should be dllimport'ed. 264d12b4a33SRafael Espindola LinkFromSrc = DestIsDeclaration; 265d12b4a33SRafael Espindola return false; 266d12b4a33SRafael Espindola } 267dbb0bd1aSRafael Espindola // If the Dest is weak, use the source linkage. 268ed11bd28SRafael Espindola if (Dest.hasExternalWeakLinkage()) { 269ed11bd28SRafael Espindola LinkFromSrc = true; 270ed11bd28SRafael Espindola return false; 271ed11bd28SRafael Espindola } 272ed11bd28SRafael Espindola // Link an available_externally over a declaration. 273ed11bd28SRafael Espindola LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); 274d12b4a33SRafael Espindola return false; 275dbb0bd1aSRafael Espindola } 276dbb0bd1aSRafael Espindola 277d12b4a33SRafael Espindola if (DestIsDeclaration) { 278dbb0bd1aSRafael Espindola // If Dest is external but Src is not: 279d12b4a33SRafael Espindola LinkFromSrc = true; 280d12b4a33SRafael Espindola return false; 281d12b4a33SRafael Espindola } 282dbb0bd1aSRafael Espindola 2830910605aSRafael Espindola if (Src.hasCommonLinkage()) { 284d12b4a33SRafael Espindola if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { 285d12b4a33SRafael Espindola LinkFromSrc = true; 2860910605aSRafael Espindola return false; 287d12b4a33SRafael Espindola } 288d12b4a33SRafael Espindola 289d12b4a33SRafael Espindola if (!Dest.hasCommonLinkage()) { 290d12b4a33SRafael Espindola LinkFromSrc = false; 291d12b4a33SRafael Espindola return false; 292d12b4a33SRafael Espindola } 2930910605aSRafael Espindola 294a28d91d8SMehdi Amini const DataLayout &DL = Dest.getParent()->getDataLayout(); 2955f6eaac6SManuel Jacob uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); 2965f6eaac6SManuel Jacob uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); 297d12b4a33SRafael Espindola LinkFromSrc = SrcSize > DestSize; 298d12b4a33SRafael Espindola return false; 2990910605aSRafael Espindola } 3000910605aSRafael Espindola 301dbb0bd1aSRafael Espindola if (Src.isWeakForLinker()) { 302dbb0bd1aSRafael Espindola assert(!Dest.hasExternalWeakLinkage()); 303dbb0bd1aSRafael Espindola assert(!Dest.hasAvailableExternallyLinkage()); 3040910605aSRafael Espindola 305d12b4a33SRafael Espindola if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { 306d12b4a33SRafael Espindola LinkFromSrc = true; 307d12b4a33SRafael Espindola return false; 308d12b4a33SRafael Espindola } 309dbb0bd1aSRafael Espindola 310d12b4a33SRafael Espindola LinkFromSrc = false; 3110910605aSRafael Espindola return false; 312dbb0bd1aSRafael Espindola } 313dbb0bd1aSRafael Espindola 314dbb0bd1aSRafael Espindola if (Dest.isWeakForLinker()) { 315dbb0bd1aSRafael Espindola assert(Src.hasExternalLinkage()); 316d12b4a33SRafael Espindola LinkFromSrc = true; 317d12b4a33SRafael Espindola return false; 318dbb0bd1aSRafael Espindola } 319dbb0bd1aSRafael Espindola 320dbb0bd1aSRafael Espindola assert(!Src.hasExternalWeakLinkage()); 321dbb0bd1aSRafael Espindola assert(!Dest.hasExternalWeakLinkage()); 322dbb0bd1aSRafael Espindola assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && 323dbb0bd1aSRafael Espindola "Unexpected linkage type!"); 324dbb0bd1aSRafael Espindola return emitError("Linking globals named '" + Src.getName() + 325dbb0bd1aSRafael Espindola "': symbol multiply defined!"); 326dbb0bd1aSRafael Espindola } 327dbb0bd1aSRafael Espindola 328baa3bf8fSRafael Espindola bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { 329baa3bf8fSRafael Espindola GlobalValue *DGV = getLinkedToGlobal(&GV); 330baa3bf8fSRafael Espindola 331b1a9ad81SBenoit Belley if (shouldLinkOnlyNeeded()) { 332b1a9ad81SBenoit Belley // Always import variables with appending linkage. 333b1a9ad81SBenoit Belley if (!GV.hasAppendingLinkage()) { 334b1a9ad81SBenoit Belley // Don't import globals unless they are referenced by the destination 335b1a9ad81SBenoit Belley // module. 336b1a9ad81SBenoit Belley if (!DGV) 337baa3bf8fSRafael Espindola return false; 338b1a9ad81SBenoit Belley // Don't import globals that are already defined in the destination module 339b1a9ad81SBenoit Belley if (!DGV->isDeclaration()) 340b1a9ad81SBenoit Belley return false; 341b1a9ad81SBenoit Belley } 342b1a9ad81SBenoit Belley } 343baa3bf8fSRafael Espindola 3444b5ec263SRafael Espindola if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { 3454b5ec263SRafael Espindola auto *DGVar = dyn_cast<GlobalVariable>(DGV); 3464b5ec263SRafael Espindola auto *SGVar = dyn_cast<GlobalVariable>(&GV); 3474b5ec263SRafael Espindola if (DGVar && SGVar) { 3484b5ec263SRafael Espindola if (DGVar->isDeclaration() && SGVar->isDeclaration() && 3494b5ec263SRafael Espindola (!DGVar->isConstant() || !SGVar->isConstant())) { 3504b5ec263SRafael Espindola DGVar->setConstant(false); 3514b5ec263SRafael Espindola SGVar->setConstant(false); 3524b5ec263SRafael Espindola } 3534b5ec263SRafael Espindola if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { 3540e62011dSGuillaume Chatelet MaybeAlign Align( 3550e62011dSGuillaume Chatelet std::max(DGVar->getAlignment(), SGVar->getAlignment())); 3564b5ec263SRafael Espindola SGVar->setAlignment(Align); 3574b5ec263SRafael Espindola DGVar->setAlignment(Align); 3584b5ec263SRafael Espindola } 3594b5ec263SRafael Espindola } 3604b5ec263SRafael Espindola 361baa3bf8fSRafael Espindola GlobalValue::VisibilityTypes Visibility = 362baa3bf8fSRafael Espindola getMinVisibility(DGV->getVisibility(), GV.getVisibility()); 363baa3bf8fSRafael Espindola DGV->setVisibility(Visibility); 364baa3bf8fSRafael Espindola GV.setVisibility(Visibility); 3654b5ec263SRafael Espindola 36696efdd61SPeter Collingbourne GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr( 36796efdd61SPeter Collingbourne DGV->getUnnamedAddr(), GV.getUnnamedAddr()); 36896efdd61SPeter Collingbourne DGV->setUnnamedAddr(UnnamedAddr); 36996efdd61SPeter Collingbourne GV.setUnnamedAddr(UnnamedAddr); 370baa3bf8fSRafael Espindola } 371baa3bf8fSRafael Espindola 3727c702116SPeter Collingbourne if (!DGV && !shouldOverrideFromSrc() && 3734b5ec263SRafael Espindola (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || 3744b5ec263SRafael Espindola GV.hasAvailableExternallyLinkage())) 3754b5ec263SRafael Espindola return false; 3764b5ec263SRafael Espindola 377bd03c503SRafael Espindola if (GV.isDeclaration()) 378bd03c503SRafael Espindola return false; 379bd03c503SRafael Espindola 380baa3bf8fSRafael Espindola if (const Comdat *SC = GV.getComdat()) { 381baa3bf8fSRafael Espindola bool LinkFromSrc; 382baa3bf8fSRafael Espindola Comdat::SelectionKind SK; 383baa3bf8fSRafael Espindola std::tie(SK, LinkFromSrc) = ComdatsChosen[SC]; 384f2e71244SRafael Espindola if (!LinkFromSrc) 385baa3bf8fSRafael Espindola return false; 386baa3bf8fSRafael Espindola } 387baa3bf8fSRafael Espindola 3884b5ec263SRafael Espindola bool LinkFromSrc = true; 3894b5ec263SRafael Espindola if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV)) 3904b5ec263SRafael Espindola return true; 3914b5ec263SRafael Espindola if (LinkFromSrc) 3924b5ec263SRafael Espindola ValuesToLink.insert(&GV); 393baa3bf8fSRafael Espindola return false; 394baa3bf8fSRafael Espindola } 395baa3bf8fSRafael Espindola 396c321e534SBenjamin Kramer void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) { 397caabe228SRafael Espindola // Add these to the internalize list 398c387e70cSPeter Collingbourne if (!GV.hasLinkOnceLinkage() && !GV.hasAvailableExternallyLinkage() && 399c387e70cSPeter Collingbourne !shouldLinkOnlyNeeded()) 400caabe228SRafael Espindola return; 401caabe228SRafael Espindola 4025eb9c81dSJonas Devlieghere if (InternalizeCallback) 403caabe228SRafael Espindola Internalize.insert(GV.getName()); 404caabe228SRafael Espindola Add(GV); 405caabe228SRafael Espindola 406caabe228SRafael Espindola const Comdat *SC = GV.getComdat(); 407caabe228SRafael Espindola if (!SC) 408caabe228SRafael Espindola return; 4091ee9fbd8SRafael Espindola for (GlobalValue *GV2 : LazyComdatMembers[SC]) { 410e1c42ac1SRafael Espindola GlobalValue *DGV = getLinkedToGlobal(GV2); 411e1c42ac1SRafael Espindola bool LinkFromSrc = true; 412e1c42ac1SRafael Espindola if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) 413e1c42ac1SRafael Espindola return; 414e1c42ac1SRafael Espindola if (!LinkFromSrc) 415e1c42ac1SRafael Espindola continue; 4165eb9c81dSJonas Devlieghere if (InternalizeCallback) 417caabe228SRafael Espindola Internalize.insert(GV2->getName()); 418caabe228SRafael Espindola Add(*GV2); 419caabe228SRafael Espindola } 420caabe228SRafael Espindola } 421caabe228SRafael Espindola 422370d528aSRafael Espindola void ModuleLinker::dropReplacedComdat( 423370d528aSRafael Espindola GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) { 424370d528aSRafael Espindola Comdat *C = GV.getComdat(); 425370d528aSRafael Espindola if (!C) 426370d528aSRafael Espindola return; 427370d528aSRafael Espindola if (!ReplacedDstComdats.count(C)) 428370d528aSRafael Espindola return; 429370d528aSRafael Espindola if (GV.use_empty()) { 430370d528aSRafael Espindola GV.eraseFromParent(); 431370d528aSRafael Espindola return; 432370d528aSRafael Espindola } 433370d528aSRafael Espindola 434370d528aSRafael Espindola if (auto *F = dyn_cast<Function>(&GV)) { 435370d528aSRafael Espindola F->deleteBody(); 436370d528aSRafael Espindola } else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) { 437370d528aSRafael Espindola Var->setInitializer(nullptr); 438370d528aSRafael Espindola } else { 439370d528aSRafael Espindola auto &Alias = cast<GlobalAlias>(GV); 440370d528aSRafael Espindola Module &M = *Alias.getParent(); 441370d528aSRafael Espindola GlobalValue *Declaration; 442370d528aSRafael Espindola if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) { 443370d528aSRafael Espindola Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M); 444370d528aSRafael Espindola } else { 445370d528aSRafael Espindola Declaration = 446*4e601325SArthur Eubanks new GlobalVariable(M, Alias.getValueType(), /*isConstant*/ false, 447370d528aSRafael Espindola GlobalValue::ExternalLinkage, 448370d528aSRafael Espindola /*Initializer*/ nullptr); 449370d528aSRafael Espindola } 450370d528aSRafael Espindola Declaration->takeName(&Alias); 451370d528aSRafael Espindola Alias.replaceAllUsesWith(Declaration); 452370d528aSRafael Espindola Alias.eraseFromParent(); 453370d528aSRafael Espindola } 454370d528aSRafael Espindola } 455370d528aSRafael Espindola 456b1ed91f3SChris Lattner bool ModuleLinker::run() { 457370d528aSRafael Espindola Module &DstM = Mover.getModule(); 458370d528aSRafael Espindola DenseSet<const Comdat *> ReplacedDstComdats; 459370d528aSRafael Espindola 46040358fb8SRafael Espindola for (const auto &SMEC : SrcM->getComdatSymbolTable()) { 461dad0a645SDavid Majnemer const Comdat &C = SMEC.getValue(); 462dad0a645SDavid Majnemer if (ComdatsChosen.count(&C)) 463dad0a645SDavid Majnemer continue; 464dad0a645SDavid Majnemer Comdat::SelectionKind SK; 465dad0a645SDavid Majnemer bool LinkFromSrc; 466dad0a645SDavid Majnemer if (getComdatResult(&C, SK, LinkFromSrc)) 467dad0a645SDavid Majnemer return true; 468dad0a645SDavid Majnemer ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc); 469370d528aSRafael Espindola 470370d528aSRafael Espindola if (!LinkFromSrc) 471370d528aSRafael Espindola continue; 472370d528aSRafael Espindola 473370d528aSRafael Espindola Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); 474370d528aSRafael Espindola Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName()); 475370d528aSRafael Espindola if (DstCI == ComdatSymTab.end()) 476370d528aSRafael Espindola continue; 477370d528aSRafael Espindola 478370d528aSRafael Espindola // The source comdat is replacing the dest one. 479370d528aSRafael Espindola const Comdat *DstC = &DstCI->second; 480370d528aSRafael Espindola ReplacedDstComdats.insert(DstC); 481370d528aSRafael Espindola } 482370d528aSRafael Espindola 483370d528aSRafael Espindola // Alias have to go first, since we are not able to find their comdats 484370d528aSRafael Espindola // otherwise. 485370d528aSRafael Espindola for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) { 486370d528aSRafael Espindola GlobalAlias &GV = *I++; 487370d528aSRafael Espindola dropReplacedComdat(GV, ReplacedDstComdats); 488370d528aSRafael Espindola } 489370d528aSRafael Espindola 490370d528aSRafael Espindola for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) { 491370d528aSRafael Espindola GlobalVariable &GV = *I++; 492370d528aSRafael Espindola dropReplacedComdat(GV, ReplacedDstComdats); 493370d528aSRafael Espindola } 494370d528aSRafael Espindola 495370d528aSRafael Espindola for (auto I = DstM.begin(), E = DstM.end(); I != E;) { 496370d528aSRafael Espindola Function &GV = *I++; 497370d528aSRafael Espindola dropReplacedComdat(GV, ReplacedDstComdats); 498dad0a645SDavid Majnemer } 499dad0a645SDavid Majnemer 50040358fb8SRafael Espindola for (GlobalVariable &GV : SrcM->globals()) 5011ee9fbd8SRafael Espindola if (GV.hasLinkOnceLinkage()) 502baa3bf8fSRafael Espindola if (const Comdat *SC = GV.getComdat()) 5031ee9fbd8SRafael Espindola LazyComdatMembers[SC].push_back(&GV); 504baa3bf8fSRafael Espindola 50540358fb8SRafael Espindola for (Function &SF : *SrcM) 5061ee9fbd8SRafael Espindola if (SF.hasLinkOnceLinkage()) 507baa3bf8fSRafael Espindola if (const Comdat *SC = SF.getComdat()) 5081ee9fbd8SRafael Espindola LazyComdatMembers[SC].push_back(&SF); 509baa3bf8fSRafael Espindola 51040358fb8SRafael Espindola for (GlobalAlias &GA : SrcM->aliases()) 5111ee9fbd8SRafael Espindola if (GA.hasLinkOnceLinkage()) 512baa3bf8fSRafael Espindola if (const Comdat *SC = GA.getComdat()) 5131ee9fbd8SRafael Espindola LazyComdatMembers[SC].push_back(&GA); 514baa3bf8fSRafael Espindola 515b1ed91f3SChris Lattner // Insert all of the globals in src into the DstM module... without linking 516b1ed91f3SChris Lattner // initializers (which could refer to functions not yet mapped over). 51740358fb8SRafael Espindola for (GlobalVariable &GV : SrcM->globals()) 518baa3bf8fSRafael Espindola if (linkIfNeeded(GV)) 519b1ed91f3SChris Lattner return true; 520b1ed91f3SChris Lattner 52140358fb8SRafael Espindola for (Function &SF : *SrcM) 522baa3bf8fSRafael Espindola if (linkIfNeeded(SF)) 523b1ed91f3SChris Lattner return true; 524b1ed91f3SChris Lattner 52540358fb8SRafael Espindola for (GlobalAlias &GA : SrcM->aliases()) 526baa3bf8fSRafael Espindola if (linkIfNeeded(GA)) 527b1ed91f3SChris Lattner return true; 528b1ed91f3SChris Lattner 529caabe228SRafael Espindola for (unsigned I = 0; I < ValuesToLink.size(); ++I) { 530caabe228SRafael Espindola GlobalValue *GV = ValuesToLink[I]; 531caabe228SRafael Espindola const Comdat *SC = GV->getComdat(); 532caabe228SRafael Espindola if (!SC) 533caabe228SRafael Espindola continue; 53442e03237SRafael Espindola for (GlobalValue *GV2 : LazyComdatMembers[SC]) { 53542e03237SRafael Espindola GlobalValue *DGV = getLinkedToGlobal(GV2); 53642e03237SRafael Espindola bool LinkFromSrc = true; 53742e03237SRafael Espindola if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) 53842e03237SRafael Espindola return true; 53942e03237SRafael Espindola if (LinkFromSrc) 540caabe228SRafael Espindola ValuesToLink.insert(GV2); 541caabe228SRafael Espindola } 54242e03237SRafael Espindola } 543caabe228SRafael Espindola 5445eb9c81dSJonas Devlieghere if (InternalizeCallback) { 545caabe228SRafael Espindola for (GlobalValue *GV : ValuesToLink) 546caabe228SRafael Espindola Internalize.insert(GV->getName()); 547caabe228SRafael Espindola } 548caabe228SRafael Espindola 5491eaa97f4SPeter Collingbourne // FIXME: Propagate Errors through to the caller instead of emitting 5501eaa97f4SPeter Collingbourne // diagnostics. 5511eaa97f4SPeter Collingbourne bool HasErrors = false; 5521eaa97f4SPeter Collingbourne if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(), 553caabe228SRafael Espindola [this](GlobalValue &GV, IRMover::ValueAdder Add) { 554caabe228SRafael Espindola addLazyFor(GV, Add); 5554b9b3791STeresa Johnson }, 5567c702116SPeter Collingbourne /* IsPerformingImport */ false)) { 5571eaa97f4SPeter Collingbourne handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { 5581eaa97f4SPeter Collingbourne DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message())); 5591eaa97f4SPeter Collingbourne HasErrors = true; 5601eaa97f4SPeter Collingbourne }); 5611eaa97f4SPeter Collingbourne } 5621eaa97f4SPeter Collingbourne if (HasErrors) 5634b5ec263SRafael Espindola return true; 5641eaa97f4SPeter Collingbourne 5655eb9c81dSJonas Devlieghere if (InternalizeCallback) 5665eb9c81dSJonas Devlieghere InternalizeCallback(DstM, Internalize); 567beadd56aSRafael Espindola 5682609888fSAnton Korobeynikov return false; 5692609888fSAnton Korobeynikov } 570361e513dSReid Spencer 5719d2bfc48SRafael Espindola Linker::Linker(Module &M) : Mover(M) {} 5723df61b7bSRafael Espindola 5735eb9c81dSJonas Devlieghere bool Linker::linkInModule( 5745eb9c81dSJonas Devlieghere std::unique_ptr<Module> Src, unsigned Flags, 5755eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { 5765eb9c81dSJonas Devlieghere ModuleLinker ModLinker(Mover, std::move(Src), Flags, 5775eb9c81dSJonas Devlieghere std::move(InternalizeCallback)); 578bef54363STeresa Johnson return ModLinker.run(); 579434e9561SRafael Espindola } 580434e9561SRafael Espindola 581b1ed91f3SChris Lattner //===----------------------------------------------------------------------===// 582b1ed91f3SChris Lattner // LinkModules entrypoint. 583b1ed91f3SChris Lattner //===----------------------------------------------------------------------===// 584b1ed91f3SChris Lattner 58518c89411SRafael Espindola /// This function links two modules together, with the resulting Dest module 58618c89411SRafael Espindola /// modified to be the composite of the two input modules. If an error occurs, 58718c89411SRafael Espindola /// true is returned and ErrorMsg (if not null) is set to indicate the problem. 58818c89411SRafael Espindola /// Upon failure, the Dest module could be in a modified state, and shouldn't be 58918c89411SRafael Espindola /// relied on to be consistent. 5905eb9c81dSJonas Devlieghere bool Linker::linkModules( 5915eb9c81dSJonas Devlieghere Module &Dest, std::unique_ptr<Module> Src, unsigned Flags, 5925eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { 5939d2bfc48SRafael Espindola Linker L(Dest); 5945eb9c81dSJonas Devlieghere return L.linkInModule(std::move(Src), Flags, std::move(InternalizeCallback)); 5954160f5d3SRafael Espindola } 5964160f5d3SRafael Espindola 597a3aeb980SBill Wendling //===----------------------------------------------------------------------===// 598a3aeb980SBill Wendling // C API. 599a3aeb980SBill Wendling //===----------------------------------------------------------------------===// 600a3aeb980SBill Wendling 601434e9561SRafael Espindola LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) { 602434e9561SRafael Espindola Module *D = unwrap(Dest); 603434e9561SRafael Espindola std::unique_ptr<Module> M(unwrap(Src)); 604434e9561SRafael Espindola return Linker::linkModules(*D, std::move(M)); 605434e9561SRafael Espindola } 606