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 27510e106fSFangrui Song enum class LinkFrom { Dst, Src }; 28510e106fSFangrui 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, 72510e106fSFangrui Song LinkFrom &From); 73510e106fSFangrui Song DenseMap<const Comdat *, std::pair<Comdat::SelectionKind, LinkFrom>> 74dad0a645SDavid Majnemer ComdatsChosen; 75dad0a645SDavid Majnemer bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, 76510e106fSFangrui 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 }; 119510e106fSFangrui 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, 156510e106fSFangrui 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. 180510e106fSFangrui Song From = LinkFrom::Dst; 181dad0a645SDavid Majnemer break; 182*92f54e1cSPetr Hosek case Comdat::SelectionKind::NoDeduplicate: { 183*92f54e1cSPetr Hosek const GlobalVariable *DstGV; 184*92f54e1cSPetr Hosek const GlobalVariable *SrcGV; 185*92f54e1cSPetr Hosek if (getComdatLeader(DstM, ComdatName, DstGV) || 186*92f54e1cSPetr Hosek getComdatLeader(*SrcM, ComdatName, SrcGV)) 187*92f54e1cSPetr Hosek return true; 188*92f54e1cSPetr Hosek 189*92f54e1cSPetr Hosek if (SrcGV->isWeakForLinker()) { 190*92f54e1cSPetr Hosek // Go with Dst. 191*92f54e1cSPetr Hosek From = LinkFrom::Dst; 192*92f54e1cSPetr Hosek } else if (DstGV->isWeakForLinker()) { 193*92f54e1cSPetr Hosek // Go with Src. 194*92f54e1cSPetr Hosek From = LinkFrom::Src; 195*92f54e1cSPetr Hosek } else { 196dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 19739248779SFangrui Song "': nodeduplicate has been violated!"); 198*92f54e1cSPetr Hosek } 199*92f54e1cSPetr Hosek break; 200*92f54e1cSPetr Hosek } 201dad0a645SDavid Majnemer case Comdat::SelectionKind::ExactMatch: 202dad0a645SDavid Majnemer case Comdat::SelectionKind::Largest: 203dad0a645SDavid Majnemer case Comdat::SelectionKind::SameSize: { 204dad0a645SDavid Majnemer const GlobalVariable *DstGV; 205dad0a645SDavid Majnemer const GlobalVariable *SrcGV; 206dad0a645SDavid Majnemer if (getComdatLeader(DstM, ComdatName, DstGV) || 20740358fb8SRafael Espindola getComdatLeader(*SrcM, ComdatName, SrcGV)) 208dad0a645SDavid Majnemer return true; 209dad0a645SDavid Majnemer 2100e309fe8SRafael Espindola const DataLayout &DstDL = DstM.getDataLayout(); 21140358fb8SRafael Espindola const DataLayout &SrcDL = SrcM->getDataLayout(); 2125f6eaac6SManuel Jacob uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType()); 2135f6eaac6SManuel Jacob uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType()); 214dad0a645SDavid Majnemer if (Result == Comdat::SelectionKind::ExactMatch) { 215dad0a645SDavid Majnemer if (SrcGV->getInitializer() != DstGV->getInitializer()) 216dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 217dad0a645SDavid Majnemer "': ExactMatch violated!"); 218510e106fSFangrui Song From = LinkFrom::Dst; 219dad0a645SDavid Majnemer } else if (Result == Comdat::SelectionKind::Largest) { 220510e106fSFangrui Song From = SrcSize > DstSize ? LinkFrom::Src : LinkFrom::Dst; 221dad0a645SDavid Majnemer } else if (Result == Comdat::SelectionKind::SameSize) { 222dad0a645SDavid Majnemer if (SrcSize != DstSize) 223dad0a645SDavid Majnemer return emitError("Linking COMDATs named '" + ComdatName + 224dad0a645SDavid Majnemer "': SameSize violated!"); 225510e106fSFangrui Song From = LinkFrom::Dst; 226dad0a645SDavid Majnemer } else { 227dad0a645SDavid Majnemer llvm_unreachable("unknown selection kind"); 228dad0a645SDavid Majnemer } 229dad0a645SDavid Majnemer break; 230dad0a645SDavid Majnemer } 231dad0a645SDavid Majnemer } 232dad0a645SDavid Majnemer 233dad0a645SDavid Majnemer return false; 234dad0a645SDavid Majnemer } 235dad0a645SDavid Majnemer 236dad0a645SDavid Majnemer bool ModuleLinker::getComdatResult(const Comdat *SrcC, 237dad0a645SDavid Majnemer Comdat::SelectionKind &Result, 238510e106fSFangrui Song LinkFrom &From) { 239caabe228SRafael Espindola Module &DstM = Mover.getModule(); 240b16196a3SRafael Espindola Comdat::SelectionKind SSK = SrcC->getSelectionKind(); 241dad0a645SDavid Majnemer StringRef ComdatName = SrcC->getName(); 2420e309fe8SRafael Espindola Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); 243dad0a645SDavid Majnemer Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName); 2442ef3f299SRafael Espindola 245b16196a3SRafael Espindola if (DstCI == ComdatSymTab.end()) { 246b16196a3SRafael Espindola // Use the comdat if it is only available in one of the modules. 247510e106fSFangrui Song From = LinkFrom::Src; 248b16196a3SRafael Espindola Result = SSK; 2492ef3f299SRafael Espindola return false; 250b16196a3SRafael Espindola } 2512ef3f299SRafael Espindola 252dad0a645SDavid Majnemer const Comdat *DstC = &DstCI->second; 253dad0a645SDavid Majnemer Comdat::SelectionKind DSK = DstC->getSelectionKind(); 254510e106fSFangrui Song return computeResultingSelectionKind(ComdatName, SSK, DSK, Result, From); 255dad0a645SDavid Majnemer } 256f6f121e2SJames Molloy 257d12b4a33SRafael Espindola bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, 258d12b4a33SRafael Espindola const GlobalValue &Dest, 259dbb0bd1aSRafael Espindola const GlobalValue &Src) { 260e5a61917STeresa Johnson 261e868123dSDuncan P. N. Exon Smith // Should we unconditionally use the Src? 262020d4fb1SArtem Belevich if (shouldOverrideFromSrc()) { 263e868123dSDuncan P. N. Exon Smith LinkFromSrc = true; 264e868123dSDuncan P. N. Exon Smith return false; 265e868123dSDuncan P. N. Exon Smith } 266e868123dSDuncan P. N. Exon Smith 267778fcc77SRafael Espindola // We always have to add Src if it has appending linkage. 268267a57a6SSergey Dmitriev if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) { 269778fcc77SRafael Espindola LinkFromSrc = true; 270778fcc77SRafael Espindola return false; 271778fcc77SRafael Espindola } 272778fcc77SRafael Espindola 273d826bbbbSMehdi Amini bool SrcIsDeclaration = Src.isDeclarationForLinker(); 274d826bbbbSMehdi Amini bool DestIsDeclaration = Dest.isDeclarationForLinker(); 275c7ed52f2STeresa Johnson 276dbb0bd1aSRafael Espindola if (SrcIsDeclaration) { 277dbb0bd1aSRafael Espindola // If Src is external or if both Src & Dest are external.. Just link the 278dbb0bd1aSRafael Espindola // external globals, we aren't adding anything. 279d12b4a33SRafael Espindola if (Src.hasDLLImportStorageClass()) { 280dbb0bd1aSRafael Espindola // If one of GVs is marked as DLLImport, result should be dllimport'ed. 281d12b4a33SRafael Espindola LinkFromSrc = DestIsDeclaration; 282d12b4a33SRafael Espindola return false; 283d12b4a33SRafael Espindola } 284dbb0bd1aSRafael Espindola // If the Dest is weak, use the source linkage. 285ed11bd28SRafael Espindola if (Dest.hasExternalWeakLinkage()) { 286ed11bd28SRafael Espindola LinkFromSrc = true; 287ed11bd28SRafael Espindola return false; 288ed11bd28SRafael Espindola } 289ed11bd28SRafael Espindola // Link an available_externally over a declaration. 290ed11bd28SRafael Espindola LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); 291d12b4a33SRafael Espindola return false; 292dbb0bd1aSRafael Espindola } 293dbb0bd1aSRafael Espindola 294d12b4a33SRafael Espindola if (DestIsDeclaration) { 295dbb0bd1aSRafael Espindola // If Dest is external but Src is not: 296d12b4a33SRafael Espindola LinkFromSrc = true; 297d12b4a33SRafael Espindola return false; 298d12b4a33SRafael Espindola } 299dbb0bd1aSRafael Espindola 3000910605aSRafael Espindola if (Src.hasCommonLinkage()) { 301d12b4a33SRafael Espindola if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { 302d12b4a33SRafael Espindola LinkFromSrc = true; 3030910605aSRafael Espindola return false; 304d12b4a33SRafael Espindola } 305d12b4a33SRafael Espindola 306d12b4a33SRafael Espindola if (!Dest.hasCommonLinkage()) { 307d12b4a33SRafael Espindola LinkFromSrc = false; 308d12b4a33SRafael Espindola return false; 309d12b4a33SRafael Espindola } 3100910605aSRafael Espindola 311a28d91d8SMehdi Amini const DataLayout &DL = Dest.getParent()->getDataLayout(); 3125f6eaac6SManuel Jacob uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType()); 3135f6eaac6SManuel Jacob uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType()); 314d12b4a33SRafael Espindola LinkFromSrc = SrcSize > DestSize; 315d12b4a33SRafael Espindola return false; 3160910605aSRafael Espindola } 3170910605aSRafael Espindola 318dbb0bd1aSRafael Espindola if (Src.isWeakForLinker()) { 319dbb0bd1aSRafael Espindola assert(!Dest.hasExternalWeakLinkage()); 320dbb0bd1aSRafael Espindola assert(!Dest.hasAvailableExternallyLinkage()); 3210910605aSRafael Espindola 322d12b4a33SRafael Espindola if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { 323d12b4a33SRafael Espindola LinkFromSrc = true; 324d12b4a33SRafael Espindola return false; 325d12b4a33SRafael Espindola } 326dbb0bd1aSRafael Espindola 327d12b4a33SRafael Espindola LinkFromSrc = false; 3280910605aSRafael Espindola return false; 329dbb0bd1aSRafael Espindola } 330dbb0bd1aSRafael Espindola 331dbb0bd1aSRafael Espindola if (Dest.isWeakForLinker()) { 332dbb0bd1aSRafael Espindola assert(Src.hasExternalLinkage()); 333d12b4a33SRafael Espindola LinkFromSrc = true; 334d12b4a33SRafael Espindola return false; 335dbb0bd1aSRafael Espindola } 336dbb0bd1aSRafael Espindola 337dbb0bd1aSRafael Espindola assert(!Src.hasExternalWeakLinkage()); 338dbb0bd1aSRafael Espindola assert(!Dest.hasExternalWeakLinkage()); 339dbb0bd1aSRafael Espindola assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && 340dbb0bd1aSRafael Espindola "Unexpected linkage type!"); 341dbb0bd1aSRafael Espindola return emitError("Linking globals named '" + Src.getName() + 342dbb0bd1aSRafael Espindola "': symbol multiply defined!"); 343dbb0bd1aSRafael Espindola } 344dbb0bd1aSRafael Espindola 345baa3bf8fSRafael Espindola bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { 346baa3bf8fSRafael Espindola GlobalValue *DGV = getLinkedToGlobal(&GV); 347baa3bf8fSRafael Espindola 348b1a9ad81SBenoit Belley if (shouldLinkOnlyNeeded()) { 349b1a9ad81SBenoit Belley // Always import variables with appending linkage. 350b1a9ad81SBenoit Belley if (!GV.hasAppendingLinkage()) { 351b1a9ad81SBenoit Belley // Don't import globals unless they are referenced by the destination 352b1a9ad81SBenoit Belley // module. 353b1a9ad81SBenoit Belley if (!DGV) 354baa3bf8fSRafael Espindola return false; 355b1a9ad81SBenoit Belley // Don't import globals that are already defined in the destination module 356b1a9ad81SBenoit Belley if (!DGV->isDeclaration()) 357b1a9ad81SBenoit Belley return false; 358b1a9ad81SBenoit Belley } 359b1a9ad81SBenoit Belley } 360baa3bf8fSRafael Espindola 3614b5ec263SRafael Espindola if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { 3624b5ec263SRafael Espindola auto *DGVar = dyn_cast<GlobalVariable>(DGV); 3634b5ec263SRafael Espindola auto *SGVar = dyn_cast<GlobalVariable>(&GV); 3644b5ec263SRafael Espindola if (DGVar && SGVar) { 3654b5ec263SRafael Espindola if (DGVar->isDeclaration() && SGVar->isDeclaration() && 3664b5ec263SRafael Espindola (!DGVar->isConstant() || !SGVar->isConstant())) { 3674b5ec263SRafael Espindola DGVar->setConstant(false); 3684b5ec263SRafael Espindola SGVar->setConstant(false); 3694b5ec263SRafael Espindola } 3704b5ec263SRafael Espindola if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { 3710e62011dSGuillaume Chatelet MaybeAlign Align( 3720e62011dSGuillaume Chatelet std::max(DGVar->getAlignment(), SGVar->getAlignment())); 3734b5ec263SRafael Espindola SGVar->setAlignment(Align); 3744b5ec263SRafael Espindola DGVar->setAlignment(Align); 3754b5ec263SRafael Espindola } 3764b5ec263SRafael Espindola } 3774b5ec263SRafael Espindola 378baa3bf8fSRafael Espindola GlobalValue::VisibilityTypes Visibility = 379baa3bf8fSRafael Espindola getMinVisibility(DGV->getVisibility(), GV.getVisibility()); 380baa3bf8fSRafael Espindola DGV->setVisibility(Visibility); 381baa3bf8fSRafael Espindola GV.setVisibility(Visibility); 3824b5ec263SRafael Espindola 38396efdd61SPeter Collingbourne GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr( 38496efdd61SPeter Collingbourne DGV->getUnnamedAddr(), GV.getUnnamedAddr()); 38596efdd61SPeter Collingbourne DGV->setUnnamedAddr(UnnamedAddr); 38696efdd61SPeter Collingbourne GV.setUnnamedAddr(UnnamedAddr); 387baa3bf8fSRafael Espindola } 388baa3bf8fSRafael Espindola 3897c702116SPeter Collingbourne if (!DGV && !shouldOverrideFromSrc() && 3904b5ec263SRafael Espindola (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || 3914b5ec263SRafael Espindola GV.hasAvailableExternallyLinkage())) 3924b5ec263SRafael Espindola return false; 3934b5ec263SRafael Espindola 394bd03c503SRafael Espindola if (GV.isDeclaration()) 395bd03c503SRafael Espindola return false; 396bd03c503SRafael Espindola 397510e106fSFangrui Song LinkFrom ComdatFrom = LinkFrom::Dst; 398baa3bf8fSRafael Espindola if (const Comdat *SC = GV.getComdat()) { 399510e106fSFangrui Song std::tie(std::ignore, ComdatFrom) = ComdatsChosen[SC]; 400510e106fSFangrui Song if (ComdatFrom == LinkFrom::Dst) 401baa3bf8fSRafael Espindola return false; 402baa3bf8fSRafael Espindola } 403baa3bf8fSRafael Espindola 4044b5ec263SRafael Espindola bool LinkFromSrc = true; 4054b5ec263SRafael Espindola if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV)) 4064b5ec263SRafael Espindola return true; 4074b5ec263SRafael Espindola if (LinkFromSrc) 4084b5ec263SRafael Espindola ValuesToLink.insert(&GV); 409baa3bf8fSRafael Espindola return false; 410baa3bf8fSRafael Espindola } 411baa3bf8fSRafael Espindola 412c321e534SBenjamin Kramer void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) { 413caabe228SRafael Espindola // Add these to the internalize list 414c387e70cSPeter Collingbourne if (!GV.hasLinkOnceLinkage() && !GV.hasAvailableExternallyLinkage() && 415c387e70cSPeter Collingbourne !shouldLinkOnlyNeeded()) 416caabe228SRafael Espindola return; 417caabe228SRafael Espindola 4185eb9c81dSJonas Devlieghere if (InternalizeCallback) 419caabe228SRafael Espindola Internalize.insert(GV.getName()); 420caabe228SRafael Espindola Add(GV); 421caabe228SRafael Espindola 422caabe228SRafael Espindola const Comdat *SC = GV.getComdat(); 423caabe228SRafael Espindola if (!SC) 424caabe228SRafael Espindola return; 4251ee9fbd8SRafael Espindola for (GlobalValue *GV2 : LazyComdatMembers[SC]) { 426e1c42ac1SRafael Espindola GlobalValue *DGV = getLinkedToGlobal(GV2); 427e1c42ac1SRafael Espindola bool LinkFromSrc = true; 428e1c42ac1SRafael Espindola if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) 429e1c42ac1SRafael Espindola return; 430e1c42ac1SRafael Espindola if (!LinkFromSrc) 431e1c42ac1SRafael Espindola continue; 4325eb9c81dSJonas Devlieghere if (InternalizeCallback) 433caabe228SRafael Espindola Internalize.insert(GV2->getName()); 434caabe228SRafael Espindola Add(*GV2); 435caabe228SRafael Espindola } 436caabe228SRafael Espindola } 437caabe228SRafael Espindola 438370d528aSRafael Espindola void ModuleLinker::dropReplacedComdat( 439370d528aSRafael Espindola GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) { 440370d528aSRafael Espindola Comdat *C = GV.getComdat(); 441370d528aSRafael Espindola if (!C) 442370d528aSRafael Espindola return; 443370d528aSRafael Espindola if (!ReplacedDstComdats.count(C)) 444370d528aSRafael Espindola return; 445370d528aSRafael Espindola if (GV.use_empty()) { 446370d528aSRafael Espindola GV.eraseFromParent(); 447370d528aSRafael Espindola return; 448370d528aSRafael Espindola } 449370d528aSRafael Espindola 450370d528aSRafael Espindola if (auto *F = dyn_cast<Function>(&GV)) { 451370d528aSRafael Espindola F->deleteBody(); 452370d528aSRafael Espindola } else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) { 453370d528aSRafael Espindola Var->setInitializer(nullptr); 454370d528aSRafael Espindola } else { 455370d528aSRafael Espindola auto &Alias = cast<GlobalAlias>(GV); 456370d528aSRafael Espindola Module &M = *Alias.getParent(); 457370d528aSRafael Espindola GlobalValue *Declaration; 458370d528aSRafael Espindola if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) { 459370d528aSRafael Espindola Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M); 460370d528aSRafael Espindola } else { 461370d528aSRafael Espindola Declaration = 4624e601325SArthur Eubanks new GlobalVariable(M, Alias.getValueType(), /*isConstant*/ false, 463370d528aSRafael Espindola GlobalValue::ExternalLinkage, 464370d528aSRafael Espindola /*Initializer*/ nullptr); 465370d528aSRafael Espindola } 466370d528aSRafael Espindola Declaration->takeName(&Alias); 467370d528aSRafael Espindola Alias.replaceAllUsesWith(Declaration); 468370d528aSRafael Espindola Alias.eraseFromParent(); 469370d528aSRafael Espindola } 470370d528aSRafael Espindola } 471370d528aSRafael Espindola 472b1ed91f3SChris Lattner bool ModuleLinker::run() { 473370d528aSRafael Espindola Module &DstM = Mover.getModule(); 474370d528aSRafael Espindola DenseSet<const Comdat *> ReplacedDstComdats; 475370d528aSRafael Espindola 47640358fb8SRafael Espindola for (const auto &SMEC : SrcM->getComdatSymbolTable()) { 477dad0a645SDavid Majnemer const Comdat &C = SMEC.getValue(); 478dad0a645SDavid Majnemer if (ComdatsChosen.count(&C)) 479dad0a645SDavid Majnemer continue; 480dad0a645SDavid Majnemer Comdat::SelectionKind SK; 481510e106fSFangrui Song LinkFrom From; 482510e106fSFangrui Song if (getComdatResult(&C, SK, From)) 483dad0a645SDavid Majnemer return true; 484510e106fSFangrui Song ComdatsChosen[&C] = std::make_pair(SK, From); 485370d528aSRafael Espindola 486510e106fSFangrui Song if (From != LinkFrom::Src) 487370d528aSRafael Espindola continue; 488370d528aSRafael Espindola 489370d528aSRafael Espindola Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); 490370d528aSRafael Espindola Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName()); 491370d528aSRafael Espindola if (DstCI == ComdatSymTab.end()) 492370d528aSRafael Espindola continue; 493370d528aSRafael Espindola 494370d528aSRafael Espindola // The source comdat is replacing the dest one. 495370d528aSRafael Espindola const Comdat *DstC = &DstCI->second; 496370d528aSRafael Espindola ReplacedDstComdats.insert(DstC); 497370d528aSRafael Espindola } 498370d528aSRafael Espindola 499370d528aSRafael Espindola // Alias have to go first, since we are not able to find their comdats 500370d528aSRafael Espindola // otherwise. 501370d528aSRafael Espindola for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) { 502370d528aSRafael Espindola GlobalAlias &GV = *I++; 503370d528aSRafael Espindola dropReplacedComdat(GV, ReplacedDstComdats); 504370d528aSRafael Espindola } 505370d528aSRafael Espindola 506370d528aSRafael Espindola for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) { 507370d528aSRafael Espindola GlobalVariable &GV = *I++; 508370d528aSRafael Espindola dropReplacedComdat(GV, ReplacedDstComdats); 509370d528aSRafael Espindola } 510370d528aSRafael Espindola 511370d528aSRafael Espindola for (auto I = DstM.begin(), E = DstM.end(); I != E;) { 512370d528aSRafael Espindola Function &GV = *I++; 513370d528aSRafael Espindola dropReplacedComdat(GV, ReplacedDstComdats); 514dad0a645SDavid Majnemer } 515dad0a645SDavid Majnemer 51640358fb8SRafael Espindola for (GlobalVariable &GV : SrcM->globals()) 5171ee9fbd8SRafael Espindola if (GV.hasLinkOnceLinkage()) 518baa3bf8fSRafael Espindola if (const Comdat *SC = GV.getComdat()) 5191ee9fbd8SRafael Espindola LazyComdatMembers[SC].push_back(&GV); 520baa3bf8fSRafael Espindola 52140358fb8SRafael Espindola for (Function &SF : *SrcM) 5221ee9fbd8SRafael Espindola if (SF.hasLinkOnceLinkage()) 523baa3bf8fSRafael Espindola if (const Comdat *SC = SF.getComdat()) 5241ee9fbd8SRafael Espindola LazyComdatMembers[SC].push_back(&SF); 525baa3bf8fSRafael Espindola 52640358fb8SRafael Espindola for (GlobalAlias &GA : SrcM->aliases()) 5271ee9fbd8SRafael Espindola if (GA.hasLinkOnceLinkage()) 528baa3bf8fSRafael Espindola if (const Comdat *SC = GA.getComdat()) 5291ee9fbd8SRafael Espindola LazyComdatMembers[SC].push_back(&GA); 530baa3bf8fSRafael Espindola 531b1ed91f3SChris Lattner // Insert all of the globals in src into the DstM module... without linking 532b1ed91f3SChris Lattner // initializers (which could refer to functions not yet mapped over). 53340358fb8SRafael Espindola for (GlobalVariable &GV : SrcM->globals()) 534baa3bf8fSRafael Espindola if (linkIfNeeded(GV)) 535b1ed91f3SChris Lattner return true; 536b1ed91f3SChris Lattner 53740358fb8SRafael Espindola for (Function &SF : *SrcM) 538baa3bf8fSRafael Espindola if (linkIfNeeded(SF)) 539b1ed91f3SChris Lattner return true; 540b1ed91f3SChris Lattner 54140358fb8SRafael Espindola for (GlobalAlias &GA : SrcM->aliases()) 542baa3bf8fSRafael Espindola if (linkIfNeeded(GA)) 543b1ed91f3SChris Lattner return true; 544b1ed91f3SChris Lattner 545530aa7e4SItay Bookstein for (GlobalIFunc &GI : SrcM->ifuncs()) 546530aa7e4SItay Bookstein if (linkIfNeeded(GI)) 547530aa7e4SItay Bookstein return true; 548530aa7e4SItay Bookstein 549caabe228SRafael Espindola for (unsigned I = 0; I < ValuesToLink.size(); ++I) { 550caabe228SRafael Espindola GlobalValue *GV = ValuesToLink[I]; 551caabe228SRafael Espindola const Comdat *SC = GV->getComdat(); 552caabe228SRafael Espindola if (!SC) 553caabe228SRafael Espindola continue; 55442e03237SRafael Espindola for (GlobalValue *GV2 : LazyComdatMembers[SC]) { 55542e03237SRafael Espindola GlobalValue *DGV = getLinkedToGlobal(GV2); 55642e03237SRafael Espindola bool LinkFromSrc = true; 55742e03237SRafael Espindola if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2)) 55842e03237SRafael Espindola return true; 55942e03237SRafael Espindola if (LinkFromSrc) 560caabe228SRafael Espindola ValuesToLink.insert(GV2); 561caabe228SRafael Espindola } 56242e03237SRafael Espindola } 563caabe228SRafael Espindola 5645eb9c81dSJonas Devlieghere if (InternalizeCallback) { 565caabe228SRafael Espindola for (GlobalValue *GV : ValuesToLink) 566caabe228SRafael Espindola Internalize.insert(GV->getName()); 567caabe228SRafael Espindola } 568caabe228SRafael Espindola 5691eaa97f4SPeter Collingbourne // FIXME: Propagate Errors through to the caller instead of emitting 5701eaa97f4SPeter Collingbourne // diagnostics. 5711eaa97f4SPeter Collingbourne bool HasErrors = false; 5721eaa97f4SPeter Collingbourne if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(), 573caabe228SRafael Espindola [this](GlobalValue &GV, IRMover::ValueAdder Add) { 574caabe228SRafael Espindola addLazyFor(GV, Add); 5754b9b3791STeresa Johnson }, 5767c702116SPeter Collingbourne /* IsPerformingImport */ false)) { 5771eaa97f4SPeter Collingbourne handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { 5781eaa97f4SPeter Collingbourne DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message())); 5791eaa97f4SPeter Collingbourne HasErrors = true; 5801eaa97f4SPeter Collingbourne }); 5811eaa97f4SPeter Collingbourne } 5821eaa97f4SPeter Collingbourne if (HasErrors) 5834b5ec263SRafael Espindola return true; 5841eaa97f4SPeter Collingbourne 5855eb9c81dSJonas Devlieghere if (InternalizeCallback) 5865eb9c81dSJonas Devlieghere InternalizeCallback(DstM, Internalize); 587beadd56aSRafael Espindola 5882609888fSAnton Korobeynikov return false; 5892609888fSAnton Korobeynikov } 590361e513dSReid Spencer 5919d2bfc48SRafael Espindola Linker::Linker(Module &M) : Mover(M) {} 5923df61b7bSRafael Espindola 5935eb9c81dSJonas Devlieghere bool Linker::linkInModule( 5945eb9c81dSJonas Devlieghere std::unique_ptr<Module> Src, unsigned Flags, 5955eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { 5965eb9c81dSJonas Devlieghere ModuleLinker ModLinker(Mover, std::move(Src), Flags, 5975eb9c81dSJonas Devlieghere std::move(InternalizeCallback)); 598bef54363STeresa Johnson return ModLinker.run(); 599434e9561SRafael Espindola } 600434e9561SRafael Espindola 601b1ed91f3SChris Lattner //===----------------------------------------------------------------------===// 602b1ed91f3SChris Lattner // LinkModules entrypoint. 603b1ed91f3SChris Lattner //===----------------------------------------------------------------------===// 604b1ed91f3SChris Lattner 60518c89411SRafael Espindola /// This function links two modules together, with the resulting Dest module 60618c89411SRafael Espindola /// modified to be the composite of the two input modules. If an error occurs, 60718c89411SRafael Espindola /// true is returned and ErrorMsg (if not null) is set to indicate the problem. 60818c89411SRafael Espindola /// Upon failure, the Dest module could be in a modified state, and shouldn't be 60918c89411SRafael Espindola /// relied on to be consistent. 6105eb9c81dSJonas Devlieghere bool Linker::linkModules( 6115eb9c81dSJonas Devlieghere Module &Dest, std::unique_ptr<Module> Src, unsigned Flags, 6125eb9c81dSJonas Devlieghere std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { 6139d2bfc48SRafael Espindola Linker L(Dest); 6145eb9c81dSJonas Devlieghere return L.linkInModule(std::move(Src), Flags, std::move(InternalizeCallback)); 6154160f5d3SRafael Espindola } 6164160f5d3SRafael Espindola 617a3aeb980SBill Wendling //===----------------------------------------------------------------------===// 618a3aeb980SBill Wendling // C API. 619a3aeb980SBill Wendling //===----------------------------------------------------------------------===// 620a3aeb980SBill Wendling 621434e9561SRafael Espindola LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) { 622434e9561SRafael Espindola Module *D = unwrap(Dest); 623434e9561SRafael Espindola std::unique_ptr<Module> M(unwrap(Src)); 624434e9561SRafael Espindola return Linker::linkModules(*D, std::move(M)); 625434e9561SRafael Espindola } 626