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 27*510e106fSFangrui Song enum class LinkFrom { Dst, Src }; 28*510e106fSFangrui Song 2918c89411SRafael Espindola /// This is an implementation class for the LinkModules function, which is the 3018c89411SRafael Espindola /// entrypoint for this file. 31b1ed91f3SChris Lattner class ModuleLinker { 32caabe228SRafael Espindola IRMover &Mover; 3340358fb8SRafael Espindola std::unique_ptr<Module> SrcM; 34b1ed91f3SChris Lattner 354b5ec263SRafael Espindola SetVector<GlobalValue *> ValuesToLink; 364160f5d3SRafael Espindola 37e868123dSDuncan P. N. Exon Smith /// For symbol clashes, prefer those from Src. 38020d4fb1SArtem Belevich unsigned Flags; 39e868123dSDuncan P. N. Exon Smith 405eb9c81dSJonas Devlieghere /// List of global value names that should be internalized. 415eb9c81dSJonas Devlieghere StringSet<> Internalize; 425eb9c81dSJonas Devlieghere 435eb9c81dSJonas Devlieghere /// Function that will perform the actual internalization. The reason for a 445eb9c81dSJonas Devlieghere /// callback is that the linker cannot call internalizeModule without 455eb9c81dSJonas Devlieghere /// creating a circular dependency between IPO and the linker. 465eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback; 475eb9c81dSJonas Devlieghere 48caabe228SRafael Espindola /// Used as the callback for lazy linking. 49caabe228SRafael Espindola /// The mover has just hit GV and we have to decide if it, and other members 50caabe228SRafael Espindola /// of the same comdat, should be linked. Every member to be linked is passed 51caabe228SRafael Espindola /// to Add. 52c321e534SBenjamin Kramer void addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add); 53baa3bf8fSRafael Espindola 54020d4fb1SArtem Belevich bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; } 55020d4fb1SArtem Belevich bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; } 56020d4fb1SArtem Belevich 57d12b4a33SRafael Espindola bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, 58d12b4a33SRafael Espindola const GlobalValue &Src); 59dbb0bd1aSRafael Espindola 60caabe228SRafael Espindola /// Should we have mover and linker error diag info? 61b1ed91f3SChris Lattner bool emitError(const Twine &Message) { 6240358fb8SRafael Espindola SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message)); 63b1ed91f3SChris Lattner return true; 64b1ed91f3SChris Lattner } 65b1ed91f3SChris Lattner 660e309fe8SRafael Espindola bool getComdatLeader(Module &M, StringRef ComdatName, 67dad0a645SDavid Majnemer const GlobalVariable *&GVar); 68dad0a645SDavid Majnemer bool computeResultingSelectionKind(StringRef ComdatName, 69dad0a645SDavid Majnemer Comdat::SelectionKind Src, 70dad0a645SDavid Majnemer Comdat::SelectionKind Dst, 71dad0a645SDavid Majnemer Comdat::SelectionKind &Result, 72*510e106fSFangrui Song LinkFrom &From); 73*510e106fSFangrui Song DenseMap<const Comdat *, std::pair<Comdat::SelectionKind, LinkFrom>> 74dad0a645SDavid Majnemer ComdatsChosen; 75dad0a645SDavid Majnemer bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, 76*510e106fSFangrui Song LinkFrom &From); 771ee9fbd8SRafael Espindola // Keep track of the lazy linked global members of each comdat in source. 781ee9fbd8SRafael Espindola DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers; 79dad0a645SDavid Majnemer 8018c89411SRafael Espindola /// Given a global in the source module, return the global in the 8118c89411SRafael Espindola /// destination module that is being linked to, if any. 823e8bc6a8SRafael Espindola GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) { 83caabe228SRafael Espindola Module &DstM = Mover.getModule(); 84b1ed91f3SChris Lattner // If the source has no name it can't link. If it has local linkage, 85b1ed91f3SChris Lattner // there is no name match-up going on. 864504c1bcSTeresa Johnson if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(SrcGV->getLinkage())) 872617dcceSCraig Topper return nullptr; 88b1ed91f3SChris Lattner 89b1ed91f3SChris Lattner // Otherwise see if we have a match in the destination module's symtab. 904504c1bcSTeresa Johnson GlobalValue *DGV = DstM.getNamedValue(SrcGV->getName()); 91c84f608bSRafael Espindola if (!DGV) 92c84f608bSRafael Espindola return nullptr; 93b1ed91f3SChris Lattner 94b1ed91f3SChris Lattner // If we found a global with the same name in the dest module, but it has 95b1ed91f3SChris Lattner // internal linkage, we are really not doing any linkage here. 96b1ed91f3SChris Lattner if (DGV->hasLocalLinkage()) 972617dcceSCraig Topper return nullptr; 98b1ed91f3SChris Lattner 99b1ed91f3SChris Lattner // Otherwise, we do in fact link to the destination global. 100b1ed91f3SChris Lattner return DGV; 101b1ed91f3SChris Lattner } 102b1ed91f3SChris Lattner 103370d528aSRafael Espindola /// Drop GV if it is a member of a comdat that we are dropping. 104370d528aSRafael Espindola /// This can happen with COFF's largest selection kind. 105370d528aSRafael Espindola void dropReplacedComdat(GlobalValue &GV, 106370d528aSRafael Espindola const DenseSet<const Comdat *> &ReplacedDstComdats); 107370d528aSRafael Espindola 108baa3bf8fSRafael Espindola bool linkIfNeeded(GlobalValue &GV); 109c7ed52f2STeresa Johnson 1104504c1bcSTeresa Johnson public: 1115eb9c81dSJonas Devlieghere ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags, 1125eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> 1135eb9c81dSJonas Devlieghere InternalizeCallback = {}) 1145eb9c81dSJonas Devlieghere : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags), 1155eb9c81dSJonas Devlieghere InternalizeCallback(std::move(InternalizeCallback)) {} 1164504c1bcSTeresa Johnson 1174504c1bcSTeresa Johnson bool run(); 1184504c1bcSTeresa Johnson }; 119*510e106fSFangrui Song } // namespace 1204504c1bcSTeresa Johnson 121eb5e0a77SRafael Espindola static GlobalValue::VisibilityTypes 122eb5e0a77SRafael Espindola getMinVisibility(GlobalValue::VisibilityTypes A, 123eb5e0a77SRafael Espindola GlobalValue::VisibilityTypes B) { 124eb5e0a77SRafael Espindola if (A == GlobalValue::HiddenVisibility || B == GlobalValue::HiddenVisibility) 125eb5e0a77SRafael Espindola return GlobalValue::HiddenVisibility; 126eb5e0a77SRafael Espindola if (A == GlobalValue::ProtectedVisibility || 127eb5e0a77SRafael Espindola B == GlobalValue::ProtectedVisibility) 128eb5e0a77SRafael Espindola return GlobalValue::ProtectedVisibility; 129eb5e0a77SRafael Espindola return GlobalValue::DefaultVisibility; 130eb5e0a77SRafael Espindola } 131eb5e0a77SRafael Espindola 1320e309fe8SRafael Espindola bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName, 133dad0a645SDavid Majnemer const GlobalVariable *&GVar) { 1340e309fe8SRafael Espindola const GlobalValue *GVal = M.getNamedValue(ComdatName); 135dad0a645SDavid Majnemer if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) { 136dad0a645SDavid Majnemer GVal = GA->getBaseObject(); 137dad0a645SDavid Majnemer if (!GVal) 138dad0a645SDavid Majnemer // We cannot resolve the size of the aliasee yet. 139dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 140dad0a645SDavid Majnemer "': COMDAT key involves incomputable alias size."); 141dad0a645SDavid Majnemer } 142dad0a645SDavid Majnemer 143dad0a645SDavid Majnemer GVar = dyn_cast_or_null<GlobalVariable>(GVal); 144dad0a645SDavid Majnemer if (!GVar) 145dad0a645SDavid Majnemer return emitError( 146dad0a645SDavid Majnemer "Linking COMDATs named '" + ComdatName + 147dad0a645SDavid Majnemer "': GlobalVariable required for data dependent selection!"); 148dad0a645SDavid Majnemer 149dad0a645SDavid Majnemer return false; 150dad0a645SDavid Majnemer } 151dad0a645SDavid Majnemer 152dad0a645SDavid Majnemer bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName, 153dad0a645SDavid Majnemer Comdat::SelectionKind Src, 154dad0a645SDavid Majnemer Comdat::SelectionKind Dst, 155dad0a645SDavid Majnemer Comdat::SelectionKind &Result, 156*510e106fSFangrui Song LinkFrom &From) { 157caabe228SRafael Espindola Module &DstM = Mover.getModule(); 158dad0a645SDavid Majnemer // The ability to mix Comdat::SelectionKind::Any with 159dad0a645SDavid Majnemer // Comdat::SelectionKind::Largest is a behavior that comes from COFF. 160dad0a645SDavid Majnemer bool DstAnyOrLargest = Dst == Comdat::SelectionKind::Any || 161dad0a645SDavid Majnemer Dst == Comdat::SelectionKind::Largest; 162dad0a645SDavid Majnemer bool SrcAnyOrLargest = Src == Comdat::SelectionKind::Any || 163dad0a645SDavid Majnemer Src == Comdat::SelectionKind::Largest; 164dad0a645SDavid Majnemer if (DstAnyOrLargest && SrcAnyOrLargest) { 165dad0a645SDavid Majnemer if (Dst == Comdat::SelectionKind::Largest || 166dad0a645SDavid Majnemer Src == Comdat::SelectionKind::Largest) 167dad0a645SDavid Majnemer Result = Comdat::SelectionKind::Largest; 168dad0a645SDavid Majnemer else 169dad0a645SDavid Majnemer Result = Comdat::SelectionKind::Any; 170dad0a645SDavid Majnemer } else if (Src == Dst) { 171dad0a645SDavid Majnemer Result = Dst; 172dad0a645SDavid Majnemer } else { 173dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 174dad0a645SDavid Majnemer "': invalid selection kinds!"); 175dad0a645SDavid Majnemer } 176dad0a645SDavid Majnemer 177dad0a645SDavid Majnemer switch (Result) { 178dad0a645SDavid Majnemer case Comdat::SelectionKind::Any: 179dad0a645SDavid Majnemer // Go with Dst. 180*510e106fSFangrui Song From = LinkFrom::Dst; 181dad0a645SDavid Majnemer break; 18239248779SFangrui Song case Comdat::SelectionKind::NoDeduplicate: 183dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 18439248779SFangrui Song "': nodeduplicate has been violated!"); 185dad0a645SDavid Majnemer case Comdat::SelectionKind::ExactMatch: 186dad0a645SDavid Majnemer case Comdat::SelectionKind::Largest: 187dad0a645SDavid Majnemer case Comdat::SelectionKind::SameSize: { 188dad0a645SDavid Majnemer const GlobalVariable *DstGV; 189dad0a645SDavid Majnemer const GlobalVariable *SrcGV; 190dad0a645SDavid Majnemer if (getComdatLeader(DstM, ComdatName, DstGV) || 19140358fb8SRafael Espindola getComdatLeader(*SrcM, ComdatName, SrcGV)) 192dad0a645SDavid Majnemer return true; 193dad0a645SDavid Majnemer 1940e309fe8SRafael Espindola const DataLayout &DstDL = DstM.getDataLayout(); 19540358fb8SRafael Espindola const DataLayout &SrcDL = SrcM->getDataLayout(); 1965f6eaac6SManuel Jacob uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType()); 1975f6eaac6SManuel Jacob uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType()); 198dad0a645SDavid Majnemer if (Result == Comdat::SelectionKind::ExactMatch) { 199dad0a645SDavid Majnemer if (SrcGV->getInitializer() != DstGV->getInitializer()) 200dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 201dad0a645SDavid Majnemer "': ExactMatch violated!"); 202*510e106fSFangrui Song From = LinkFrom::Dst; 203dad0a645SDavid Majnemer } else if (Result == Comdat::SelectionKind::Largest) { 204*510e106fSFangrui Song From = SrcSize > DstSize ? LinkFrom::Src : LinkFrom::Dst; 205dad0a645SDavid Majnemer } else if (Result == Comdat::SelectionKind::SameSize) { 206dad0a645SDavid Majnemer if (SrcSize != DstSize) 207dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 208dad0a645SDavid Majnemer "': SameSize violated!"); 209*510e106fSFangrui Song From = LinkFrom::Dst; 210dad0a645SDavid Majnemer } else { 211dad0a645SDavid Majnemer llvm_unreachable("unknown selection kind"); 212dad0a645SDavid Majnemer } 213dad0a645SDavid Majnemer break; 214dad0a645SDavid Majnemer } 215dad0a645SDavid Majnemer } 216dad0a645SDavid Majnemer 217dad0a645SDavid Majnemer return false; 218dad0a645SDavid Majnemer } 219dad0a645SDavid Majnemer 220dad0a645SDavid Majnemer bool ModuleLinker::getComdatResult(const Comdat *SrcC, 221dad0a645SDavid Majnemer Comdat::SelectionKind &Result, 222*510e106fSFangrui Song LinkFrom &From) { 223caabe228SRafael Espindola Module &DstM = Mover.getModule(); 224b16196a3SRafael Espindola Comdat::SelectionKind SSK = SrcC->getSelectionKind(); 225dad0a645SDavid Majnemer StringRef ComdatName = SrcC->getName(); 2260e309fe8SRafael Espindola Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); 227dad0a645SDavid Majnemer Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName); 2282ef3f299SRafael Espindola 229b16196a3SRafael Espindola if (DstCI == ComdatSymTab.end()) { 230b16196a3SRafael Espindola // Use the comdat if it is only available in one of the modules. 231*510e106fSFangrui Song From = LinkFrom::Src; 232b16196a3SRafael Espindola Result = SSK; 2332ef3f299SRafael Espindola return false; 234b16196a3SRafael Espindola } 2352ef3f299SRafael Espindola 236dad0a645SDavid Majnemer const Comdat *DstC = &DstCI->second; 237dad0a645SDavid Majnemer Comdat::SelectionKind DSK = DstC->getSelectionKind(); 238*510e106fSFangrui Song return computeResultingSelectionKind(ComdatName, SSK, DSK, Result, From); 239dad0a645SDavid Majnemer } 240f6f121e2SJames Molloy 241d12b4a33SRafael Espindola bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, 242d12b4a33SRafael Espindola const GlobalValue &Dest, 243dbb0bd1aSRafael Espindola const GlobalValue &Src) { 244e5a61917STeresa Johnson 245e868123dSDuncan P. N. Exon Smith // Should we unconditionally use the Src? 246020d4fb1SArtem Belevich if (shouldOverrideFromSrc()) { 247e868123dSDuncan P. N. Exon Smith LinkFromSrc = true; 248e868123dSDuncan P. N. Exon Smith return false; 249e868123dSDuncan P. N. Exon Smith } 250e868123dSDuncan P. N. Exon Smith 251778fcc77SRafael Espindola // We always have to add Src if it has appending linkage. 252267a57a6SSergey Dmitriev if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) { 253778fcc77SRafael Espindola LinkFromSrc = true; 254778fcc77SRafael Espindola return false; 255778fcc77SRafael Espindola } 256778fcc77SRafael Espindola 257d826bbbbSMehdi Amini bool SrcIsDeclaration = Src.isDeclarationForLinker(); 258d826bbbbSMehdi Amini bool DestIsDeclaration = Dest.isDeclarationForLinker(); 259c7ed52f2STeresa Johnson 260dbb0bd1aSRafael Espindola if (SrcIsDeclaration) { 261dbb0bd1aSRafael Espindola // If Src is external or if both Src & Dest are external.. Just link the 262dbb0bd1aSRafael Espindola // external globals, we aren't adding anything. 263d12b4a33SRafael Espindola if (Src.hasDLLImportStorageClass()) { 264dbb0bd1aSRafael Espindola // If one of GVs is marked as DLLImport, result should be dllimport'ed. 265d12b4a33SRafael Espindola LinkFromSrc = DestIsDeclaration; 266d12b4a33SRafael Espindola return false; 267d12b4a33SRafael Espindola } 268dbb0bd1aSRafael Espindola // If the Dest is weak, use the source linkage. 269ed11bd28SRafael Espindola if (Dest.hasExternalWeakLinkage()) { 270ed11bd28SRafael Espindola LinkFromSrc = true; 271ed11bd28SRafael Espindola return false; 272ed11bd28SRafael Espindola } 273ed11bd28SRafael Espindola // Link an available_externally over a declaration. 274ed11bd28SRafael Espindola LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); 275d12b4a33SRafael Espindola return false; 276dbb0bd1aSRafael Espindola } 277dbb0bd1aSRafael Espindola 278d12b4a33SRafael Espindola if (DestIsDeclaration) { 279dbb0bd1aSRafael Espindola // If Dest is external but Src is not: 280d12b4a33SRafael Espindola LinkFromSrc = true; 281d12b4a33SRafael Espindola return false; 282d12b4a33SRafael Espindola } 283dbb0bd1aSRafael Espindola 2840910605aSRafael Espindola if (Src.hasCommonLinkage()) { 285d12b4a33SRafael Espindola if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { 286d12b4a33SRafael Espindola LinkFromSrc = true; 2870910605aSRafael Espindola return false; 288d12b4a33SRafael Espindola } 289d12b4a33SRafael Espindola 290d12b4a33SRafael Espindola if (!Dest.hasCommonLinkage()) { 291d12b4a33SRafael Espindola LinkFromSrc = false; 292d12b4a33SRafael Espindola return false; 293d12b4a33SRafael Espindola } 2940910605aSRafael Espindola 295a28d91d8SMehdi Amini const DataLayout &DL = Dest.getParent()->getDataLayout(); 2965f6eaac6SManuel Jacob uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); 2975f6eaac6SManuel Jacob uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); 298d12b4a33SRafael Espindola LinkFromSrc = SrcSize > DestSize; 299d12b4a33SRafael Espindola return false; 3000910605aSRafael Espindola } 3010910605aSRafael Espindola 302dbb0bd1aSRafael Espindola if (Src.isWeakForLinker()) { 303dbb0bd1aSRafael Espindola assert(!Dest.hasExternalWeakLinkage()); 304dbb0bd1aSRafael Espindola assert(!Dest.hasAvailableExternallyLinkage()); 3050910605aSRafael Espindola 306d12b4a33SRafael Espindola if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { 307d12b4a33SRafael Espindola LinkFromSrc = true; 308d12b4a33SRafael Espindola return false; 309d12b4a33SRafael Espindola } 310dbb0bd1aSRafael Espindola 311d12b4a33SRafael Espindola LinkFromSrc = false; 3120910605aSRafael Espindola return false; 313dbb0bd1aSRafael Espindola } 314dbb0bd1aSRafael Espindola 315dbb0bd1aSRafael Espindola if (Dest.isWeakForLinker()) { 316dbb0bd1aSRafael Espindola assert(Src.hasExternalLinkage()); 317d12b4a33SRafael Espindola LinkFromSrc = true; 318d12b4a33SRafael Espindola return false; 319dbb0bd1aSRafael Espindola } 320dbb0bd1aSRafael Espindola 321dbb0bd1aSRafael Espindola assert(!Src.hasExternalWeakLinkage()); 322dbb0bd1aSRafael Espindola assert(!Dest.hasExternalWeakLinkage()); 323dbb0bd1aSRafael Espindola assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && 324dbb0bd1aSRafael Espindola "Unexpected linkage type!"); 325dbb0bd1aSRafael Espindola return emitError("Linking globals named '" + Src.getName() + 326dbb0bd1aSRafael Espindola "': symbol multiply defined!"); 327dbb0bd1aSRafael Espindola } 328dbb0bd1aSRafael Espindola 329baa3bf8fSRafael Espindola bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { 330baa3bf8fSRafael Espindola GlobalValue *DGV = getLinkedToGlobal(&GV); 331baa3bf8fSRafael Espindola 332b1a9ad81SBenoit Belley if (shouldLinkOnlyNeeded()) { 333b1a9ad81SBenoit Belley // Always import variables with appending linkage. 334b1a9ad81SBenoit Belley if (!GV.hasAppendingLinkage()) { 335b1a9ad81SBenoit Belley // Don't import globals unless they are referenced by the destination 336b1a9ad81SBenoit Belley // module. 337b1a9ad81SBenoit Belley if (!DGV) 338baa3bf8fSRafael Espindola return false; 339b1a9ad81SBenoit Belley // Don't import globals that are already defined in the destination module 340b1a9ad81SBenoit Belley if (!DGV->isDeclaration()) 341b1a9ad81SBenoit Belley return false; 342b1a9ad81SBenoit Belley } 343b1a9ad81SBenoit Belley } 344baa3bf8fSRafael Espindola 3454b5ec263SRafael Espindola if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { 3464b5ec263SRafael Espindola auto *DGVar = dyn_cast<GlobalVariable>(DGV); 3474b5ec263SRafael Espindola auto *SGVar = dyn_cast<GlobalVariable>(&GV); 3484b5ec263SRafael Espindola if (DGVar && SGVar) { 3494b5ec263SRafael Espindola if (DGVar->isDeclaration() && SGVar->isDeclaration() && 3504b5ec263SRafael Espindola (!DGVar->isConstant() || !SGVar->isConstant())) { 3514b5ec263SRafael Espindola DGVar->setConstant(false); 3524b5ec263SRafael Espindola SGVar->setConstant(false); 3534b5ec263SRafael Espindola } 3544b5ec263SRafael Espindola if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { 3550e62011dSGuillaume Chatelet MaybeAlign Align( 3560e62011dSGuillaume Chatelet std::max(DGVar->getAlignment(), SGVar->getAlignment())); 3574b5ec263SRafael Espindola SGVar->setAlignment(Align); 3584b5ec263SRafael Espindola DGVar->setAlignment(Align); 3594b5ec263SRafael Espindola } 3604b5ec263SRafael Espindola } 3614b5ec263SRafael Espindola 362baa3bf8fSRafael Espindola GlobalValue::VisibilityTypes Visibility = 363baa3bf8fSRafael Espindola getMinVisibility(DGV->getVisibility(), GV.getVisibility()); 364baa3bf8fSRafael Espindola DGV->setVisibility(Visibility); 365baa3bf8fSRafael Espindola GV.setVisibility(Visibility); 3664b5ec263SRafael Espindola 36796efdd61SPeter Collingbourne GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr( 36896efdd61SPeter Collingbourne DGV->getUnnamedAddr(), GV.getUnnamedAddr()); 36996efdd61SPeter Collingbourne DGV->setUnnamedAddr(UnnamedAddr); 37096efdd61SPeter Collingbourne GV.setUnnamedAddr(UnnamedAddr); 371baa3bf8fSRafael Espindola } 372baa3bf8fSRafael Espindola 3737c702116SPeter Collingbourne if (!DGV && !shouldOverrideFromSrc() && 3744b5ec263SRafael Espindola (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || 3754b5ec263SRafael Espindola GV.hasAvailableExternallyLinkage())) 3764b5ec263SRafael Espindola return false; 3774b5ec263SRafael Espindola 378bd03c503SRafael Espindola if (GV.isDeclaration()) 379bd03c503SRafael Espindola return false; 380bd03c503SRafael Espindola 381*510e106fSFangrui Song LinkFrom ComdatFrom = LinkFrom::Dst; 382baa3bf8fSRafael Espindola if (const Comdat *SC = GV.getComdat()) { 383*510e106fSFangrui Song std::tie(std::ignore, ComdatFrom) = ComdatsChosen[SC]; 384*510e106fSFangrui Song if (ComdatFrom == LinkFrom::Dst) 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 = 4464e601325SArthur 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; 465*510e106fSFangrui Song LinkFrom From; 466*510e106fSFangrui Song if (getComdatResult(&C, SK, From)) 467dad0a645SDavid Majnemer return true; 468*510e106fSFangrui Song ComdatsChosen[&C] = std::make_pair(SK, From); 469370d528aSRafael Espindola 470*510e106fSFangrui Song if (From != LinkFrom::Src) 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 529530aa7e4SItay Bookstein for (GlobalIFunc &GI : SrcM->ifuncs()) 530530aa7e4SItay Bookstein if (linkIfNeeded(GI)) 531530aa7e4SItay Bookstein return true; 532530aa7e4SItay Bookstein 533caabe228SRafael Espindola for (unsigned I = 0; I < ValuesToLink.size(); ++I) { 534caabe228SRafael Espindola GlobalValue *GV = ValuesToLink[I]; 535caabe228SRafael Espindola const Comdat *SC = GV->getComdat(); 536caabe228SRafael Espindola if (!SC) 537caabe228SRafael Espindola continue; 53842e03237SRafael Espindola for (GlobalValue *GV2 : LazyComdatMembers[SC]) { 53942e03237SRafael Espindola GlobalValue *DGV = getLinkedToGlobal(GV2); 54042e03237SRafael Espindola bool LinkFromSrc = true; 54142e03237SRafael Espindola if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) 54242e03237SRafael Espindola return true; 54342e03237SRafael Espindola if (LinkFromSrc) 544caabe228SRafael Espindola ValuesToLink.insert(GV2); 545caabe228SRafael Espindola } 54642e03237SRafael Espindola } 547caabe228SRafael Espindola 5485eb9c81dSJonas Devlieghere if (InternalizeCallback) { 549caabe228SRafael Espindola for (GlobalValue *GV : ValuesToLink) 550caabe228SRafael Espindola Internalize.insert(GV->getName()); 551caabe228SRafael Espindola } 552caabe228SRafael Espindola 5531eaa97f4SPeter Collingbourne // FIXME: Propagate Errors through to the caller instead of emitting 5541eaa97f4SPeter Collingbourne // diagnostics. 5551eaa97f4SPeter Collingbourne bool HasErrors = false; 5561eaa97f4SPeter Collingbourne if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(), 557caabe228SRafael Espindola [this](GlobalValue &GV, IRMover::ValueAdder Add) { 558caabe228SRafael Espindola addLazyFor(GV, Add); 5594b9b3791STeresa Johnson }, 5607c702116SPeter Collingbourne /* IsPerformingImport */ false)) { 5611eaa97f4SPeter Collingbourne handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { 5621eaa97f4SPeter Collingbourne DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message())); 5631eaa97f4SPeter Collingbourne HasErrors = true; 5641eaa97f4SPeter Collingbourne }); 5651eaa97f4SPeter Collingbourne } 5661eaa97f4SPeter Collingbourne if (HasErrors) 5674b5ec263SRafael Espindola return true; 5681eaa97f4SPeter Collingbourne 5695eb9c81dSJonas Devlieghere if (InternalizeCallback) 5705eb9c81dSJonas Devlieghere InternalizeCallback(DstM, Internalize); 571beadd56aSRafael Espindola 5722609888fSAnton Korobeynikov return false; 5732609888fSAnton Korobeynikov } 574361e513dSReid Spencer 5759d2bfc48SRafael Espindola Linker::Linker(Module &M) : Mover(M) {} 5763df61b7bSRafael Espindola 5775eb9c81dSJonas Devlieghere bool Linker::linkInModule( 5785eb9c81dSJonas Devlieghere std::unique_ptr<Module> Src, unsigned Flags, 5795eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { 5805eb9c81dSJonas Devlieghere ModuleLinker ModLinker(Mover, std::move(Src), Flags, 5815eb9c81dSJonas Devlieghere std::move(InternalizeCallback)); 582bef54363STeresa Johnson return ModLinker.run(); 583434e9561SRafael Espindola } 584434e9561SRafael Espindola 585b1ed91f3SChris Lattner //===----------------------------------------------------------------------===// 586b1ed91f3SChris Lattner // LinkModules entrypoint. 587b1ed91f3SChris Lattner //===----------------------------------------------------------------------===// 588b1ed91f3SChris Lattner 58918c89411SRafael Espindola /// This function links two modules together, with the resulting Dest module 59018c89411SRafael Espindola /// modified to be the composite of the two input modules. If an error occurs, 59118c89411SRafael Espindola /// true is returned and ErrorMsg (if not null) is set to indicate the problem. 59218c89411SRafael Espindola /// Upon failure, the Dest module could be in a modified state, and shouldn't be 59318c89411SRafael Espindola /// relied on to be consistent. 5945eb9c81dSJonas Devlieghere bool Linker::linkModules( 5955eb9c81dSJonas Devlieghere Module &Dest, std::unique_ptr<Module> Src, unsigned Flags, 5965eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { 5979d2bfc48SRafael Espindola Linker L(Dest); 5985eb9c81dSJonas Devlieghere return L.linkInModule(std::move(Src), Flags, std::move(InternalizeCallback)); 5994160f5d3SRafael Espindola } 6004160f5d3SRafael Espindola 601a3aeb980SBill Wendling //===----------------------------------------------------------------------===// 602a3aeb980SBill Wendling // C API. 603a3aeb980SBill Wendling //===----------------------------------------------------------------------===// 604a3aeb980SBill Wendling 605434e9561SRafael Espindola LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) { 606434e9561SRafael Espindola Module *D = unwrap(Dest); 607434e9561SRafael Espindola std::unique_ptr<Module> M(unwrap(Src)); 608434e9561SRafael Espindola return Linker::linkModules(*D, std::move(M)); 609434e9561SRafael Espindola } 610