529 lines · cpp
1//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This utility may be invoked in the following manner:10// llvm-link a.bc b.bc c.bc -o x.bc11//12//===----------------------------------------------------------------------===//13 14#include "llvm/ADT/STLExtras.h"15#include "llvm/BinaryFormat/Magic.h"16#include "llvm/Bitcode/BitcodeReader.h"17#include "llvm/Bitcode/BitcodeWriter.h"18#include "llvm/IR/AutoUpgrade.h"19#include "llvm/IR/DiagnosticInfo.h"20#include "llvm/IR/DiagnosticPrinter.h"21#include "llvm/IR/LLVMContext.h"22#include "llvm/IR/Module.h"23#include "llvm/IR/ModuleSummaryIndex.h"24#include "llvm/IR/Verifier.h"25#include "llvm/IRReader/IRReader.h"26#include "llvm/Linker/Linker.h"27#include "llvm/Object/Archive.h"28#include "llvm/Support/CommandLine.h"29#include "llvm/Support/FileSystem.h"30#include "llvm/Support/InitLLVM.h"31#include "llvm/Support/Path.h"32#include "llvm/Support/SourceMgr.h"33#include "llvm/Support/SystemUtils.h"34#include "llvm/Support/ToolOutputFile.h"35#include "llvm/Support/WithColor.h"36#include "llvm/Transforms/IPO/FunctionImport.h"37#include "llvm/Transforms/IPO/Internalize.h"38#include "llvm/Transforms/Utils/FunctionImportUtils.h"39 40#include <memory>41#include <utility>42using namespace llvm;43 44static cl::OptionCategory LinkCategory("Link Options");45 46static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,47 cl::desc("<input bitcode files>"),48 cl::cat(LinkCategory));49 50static cl::list<std::string> OverridingInputs(51 "override", cl::value_desc("filename"),52 cl::desc(53 "input bitcode file which can override previously defined symbol(s)"),54 cl::cat(LinkCategory));55 56// Option to simulate function importing for testing. This enables using57// llvm-link to simulate ThinLTO backend processes.58static cl::list<std::string> Imports(59 "import", cl::value_desc("function:filename"),60 cl::desc("Pair of function name and filename, where function should be "61 "imported from bitcode in filename"),62 cl::cat(LinkCategory));63 64// Option to support testing of function importing. The module summary65// must be specified in the case were we request imports via the -import66// option, as well as when compiling any module with functions that may be67// exported (imported by a different llvm-link -import invocation), to ensure68// consistent promotion and renaming of locals.69static cl::opt<std::string>70 SummaryIndex("summary-index", cl::desc("Module summary index filename"),71 cl::init(""), cl::value_desc("filename"),72 cl::cat(LinkCategory));73 74static cl::opt<std::string>75 OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),76 cl::value_desc("filename"), cl::cat(LinkCategory));77 78static cl::opt<bool> Internalize("internalize",79 cl::desc("Internalize linked symbols"),80 cl::cat(LinkCategory));81 82static cl::opt<bool>83 DisableDITypeMap("disable-debug-info-type-map",84 cl::desc("Don't use a uniquing type map for debug info"),85 cl::cat(LinkCategory));86 87static cl::opt<bool> OnlyNeeded("only-needed",88 cl::desc("Link only needed symbols"),89 cl::cat(LinkCategory));90 91static cl::opt<bool> Force("f", cl::desc("Enable binary output on terminals"),92 cl::cat(LinkCategory));93 94static cl::opt<bool> DisableLazyLoad("disable-lazy-loading",95 cl::desc("Disable lazy module loading"),96 cl::cat(LinkCategory));97 98static cl::opt<bool> OutputAssembly("S",99 cl::desc("Write output as LLVM assembly"),100 cl::Hidden, cl::cat(LinkCategory));101 102static cl::opt<bool> Verbose("v",103 cl::desc("Print information about actions taken"),104 cl::cat(LinkCategory));105 106static cl::opt<bool> DumpAsm("d", cl::desc("Print assembly as linked"),107 cl::Hidden, cl::cat(LinkCategory));108 109static cl::opt<bool> SuppressWarnings("suppress-warnings",110 cl::desc("Suppress all linking warnings"),111 cl::init(false), cl::cat(LinkCategory));112 113static cl::opt<bool> NoVerify("disable-verify",114 cl::desc("Do not run the verifier"), cl::Hidden,115 cl::cat(LinkCategory));116 117static cl::opt<bool> IgnoreNonBitcode(118 "ignore-non-bitcode",119 cl::desc("Do not report an error for non-bitcode files in archives"),120 cl::Hidden);121 122static ExitOnError ExitOnErr;123 124// Read the specified bitcode file in and return it. This routine searches the125// link path for the specified file to try to find it...126//127static std::unique_ptr<Module> loadFile(const char *argv0,128 std::unique_ptr<MemoryBuffer> Buffer,129 LLVMContext &Context,130 bool MaterializeMetadata = true) {131 SMDiagnostic Err;132 if (Verbose)133 errs() << "Loading '" << Buffer->getBufferIdentifier() << "'\n";134 std::unique_ptr<Module> Result;135 if (DisableLazyLoad)136 Result = parseIR(*Buffer, Err, Context);137 else138 Result =139 getLazyIRModule(std::move(Buffer), Err, Context, !MaterializeMetadata);140 141 if (!Result) {142 Err.print(argv0, errs());143 return nullptr;144 }145 146 if (MaterializeMetadata) {147 ExitOnErr(Result->materializeMetadata());148 UpgradeDebugInfo(*Result);149 }150 151 return Result;152}153 154static std::unique_ptr<Module> loadArFile(const char *Argv0,155 std::unique_ptr<MemoryBuffer> Buffer,156 LLVMContext &Context) {157 std::unique_ptr<Module> Result(new Module("ArchiveModule", Context));158 StringRef ArchiveName = Buffer->getBufferIdentifier();159 if (Verbose)160 errs() << "Reading library archive file '" << ArchiveName161 << "' to memory\n";162 Expected<std::unique_ptr<object::Archive>> ArchiveOrError =163 object::Archive::create(Buffer->getMemBufferRef());164 if (!ArchiveOrError)165 ExitOnErr(ArchiveOrError.takeError());166 167 std::unique_ptr<object::Archive> Archive = std::move(ArchiveOrError.get());168 169 Linker L(*Result);170 Error Err = Error::success();171 for (const object::Archive::Child &C : Archive->children(Err)) {172 Expected<StringRef> Ename = C.getName();173 if (Error E = Ename.takeError()) {174 errs() << Argv0 << ": ";175 WithColor::error() << " failed to read name of archive member"176 << ArchiveName << "'\n";177 return nullptr;178 }179 std::string ChildName = Ename.get().str();180 if (Verbose)181 errs() << "Parsing member '" << ChildName182 << "' of archive library to module.\n";183 SMDiagnostic ParseErr;184 Expected<MemoryBufferRef> MemBuf = C.getMemoryBufferRef();185 if (Error E = MemBuf.takeError()) {186 errs() << Argv0 << ": ";187 WithColor::error() << " loading memory for member '" << ChildName188 << "' of archive library failed'" << ArchiveName189 << "'\n";190 return nullptr;191 };192 193 if (!isBitcode(reinterpret_cast<const unsigned char *>(194 MemBuf.get().getBufferStart()),195 reinterpret_cast<const unsigned char *>(196 MemBuf.get().getBufferEnd()))) {197 if (IgnoreNonBitcode)198 continue;199 errs() << Argv0 << ": ";200 WithColor::error() << " member of archive is not a bitcode file: '"201 << ChildName << "'\n";202 return nullptr;203 }204 205 std::unique_ptr<Module> M;206 if (DisableLazyLoad)207 M = parseIR(MemBuf.get(), ParseErr, Context);208 else209 M = getLazyIRModule(MemoryBuffer::getMemBuffer(MemBuf.get(), false),210 ParseErr, Context);211 212 if (!M) {213 errs() << Argv0 << ": ";214 WithColor::error() << " parsing member '" << ChildName215 << "' of archive library failed'" << ArchiveName216 << "'\n";217 return nullptr;218 }219 if (Verbose)220 errs() << "Linking member '" << ChildName << "' of archive library.\n";221 if (L.linkInModule(std::move(M)))222 return nullptr;223 } // end for each child224 ExitOnErr(std::move(Err));225 return Result;226}227 228namespace {229 230/// Helper to load on demand a Module from file and cache it for subsequent231/// queries during function importing.232class ModuleLazyLoaderCache {233 /// Cache of lazily loaded module for import.234 StringMap<std::unique_ptr<Module>> ModuleMap;235 236 /// Retrieve a Module from the cache or lazily load it on demand.237 std::function<std::unique_ptr<Module>(const char *argv0,238 const std::string &FileName)>239 createLazyModule;240 241public:242 /// Create the loader, Module will be initialized in \p Context.243 ModuleLazyLoaderCache(std::function<std::unique_ptr<Module>(244 const char *argv0, const std::string &FileName)>245 createLazyModule)246 : createLazyModule(std::move(createLazyModule)) {}247 248 /// Retrieve a Module from the cache or lazily load it on demand.249 Module &operator()(const char *argv0, const std::string &FileName);250 251 std::unique_ptr<Module> takeModule(const std::string &FileName) {252 auto I = ModuleMap.find(FileName);253 assert(I != ModuleMap.end());254 std::unique_ptr<Module> Ret = std::move(I->second);255 ModuleMap.erase(I);256 return Ret;257 }258};259 260// Get a Module for \p FileName from the cache, or load it lazily.261Module &ModuleLazyLoaderCache::operator()(const char *argv0,262 const std::string &Identifier) {263 auto &Module = ModuleMap[Identifier];264 if (!Module) {265 Module = createLazyModule(argv0, Identifier);266 assert(Module && "Failed to create lazy module!");267 }268 return *Module;269}270} // anonymous namespace271 272namespace {273struct LLVMLinkDiagnosticHandler : public DiagnosticHandler {274 bool handleDiagnostics(const DiagnosticInfo &DI) override {275 unsigned Severity = DI.getSeverity();276 switch (Severity) {277 case DS_Error:278 WithColor::error();279 break;280 case DS_Warning:281 if (SuppressWarnings)282 return true;283 WithColor::warning();284 break;285 case DS_Remark:286 case DS_Note:287 llvm_unreachable("Only expecting warnings and errors");288 }289 290 DiagnosticPrinterRawOStream DP(errs());291 DI.print(DP);292 errs() << '\n';293 return true;294 }295};296} // namespace297 298/// Import any functions requested via the -import option.299static bool importFunctions(const char *argv0, Module &DestModule) {300 if (SummaryIndex.empty())301 return true;302 std::unique_ptr<ModuleSummaryIndex> Index =303 ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex));304 305 // Map of Module -> List of globals to import from the Module306 FunctionImporter::ImportIDTable ImportIDs;307 FunctionImporter::ImportMapTy ImportList(ImportIDs);308 309 auto ModuleLoader = [&DestModule](const char *argv0,310 const std::string &Identifier) {311 std::unique_ptr<MemoryBuffer> Buffer = ExitOnErr(errorOrToExpected(312 MemoryBuffer::getFileOrSTDIN(Identifier, /*IsText=*/true)));313 return loadFile(argv0, std::move(Buffer), DestModule.getContext(), false);314 };315 316 ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader);317 // Owns the filename strings used to key into the ImportList. Normally this is318 // constructed from the index and the strings are owned by the index, however,319 // since we are synthesizing this data structure from options we need a cache320 // to own those strings.321 StringSet<> FileNameStringCache;322 for (const auto &Import : Imports) {323 // Identify the requested function and its bitcode source file.324 size_t Idx = Import.find(':');325 if (Idx == std::string::npos) {326 errs() << "Import parameter bad format: " << Import << "\n";327 return false;328 }329 std::string FunctionName = Import.substr(0, Idx);330 std::string FileName = Import.substr(Idx + 1, std::string::npos);331 332 // Load the specified source module.333 auto &SrcModule = ModuleLoaderCache(argv0, FileName);334 335 if (!NoVerify && verifyModule(SrcModule, &errs())) {336 errs() << argv0 << ": " << FileName;337 WithColor::error() << "input module is broken!\n";338 return false;339 }340 341 Function *F = SrcModule.getFunction(FunctionName);342 if (!F) {343 errs() << "Ignoring import request for non-existent function "344 << FunctionName << " from " << FileName << "\n";345 continue;346 }347 // We cannot import weak_any functions without possibly affecting the348 // order they are seen and selected by the linker, changing program349 // semantics.350 if (F->hasWeakAnyLinkage()) {351 errs() << "Ignoring import request for weak-any function " << FunctionName352 << " from " << FileName << "\n";353 continue;354 }355 356 if (Verbose)357 errs() << "Importing " << FunctionName << " from " << FileName << "\n";358 359 // `-import` specifies the `<filename,function-name>` pairs to import as360 // definition, so make the import type definition directly.361 // FIXME: A follow-up patch should add test coverage for import declaration362 // in `llvm-link` CLI (e.g., by introducing a new command line option).363 ImportList.addDefinition(364 FileNameStringCache.insert(FileName).first->getKey(), F->getGUID());365 }366 auto CachedModuleLoader = [&](StringRef Identifier) {367 return ModuleLoaderCache.takeModule(std::string(Identifier));368 };369 FunctionImporter Importer(*Index, CachedModuleLoader,370 /*ClearDSOLocalOnDeclarations=*/false);371 ExitOnErr(Importer.importFunctions(DestModule, ImportList));372 373 return true;374}375 376static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,377 const cl::list<std::string> &Files, unsigned Flags) {378 // Filter out flags that don't apply to the first file we load.379 unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc;380 // Similar to some flags, internalization doesn't apply to the first file.381 bool InternalizeLinkedSymbols = false;382 for (const auto &File : Files) {383 auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(File, /*IsText=*/true);384 385 // When we encounter a missing file, make sure we expose its name.386 if (auto EC = BufferOrErr.getError())387 if (EC == std::errc::no_such_file_or_directory)388 ExitOnErr(createStringError(EC, "No such file or directory: '%s'",389 File.c_str()));390 391 std::unique_ptr<MemoryBuffer> Buffer =392 ExitOnErr(errorOrToExpected(std::move(BufferOrErr)));393 394 std::unique_ptr<Module> M =395 identify_magic(Buffer->getBuffer()) == file_magic::archive396 ? loadArFile(argv0, std::move(Buffer), Context)397 : loadFile(argv0, std::move(Buffer), Context);398 if (!M) {399 errs() << argv0 << ": ";400 WithColor::error() << " loading file '" << File << "'\n";401 return false;402 }403 404 // Note that when ODR merging types cannot verify input files in here When405 // doing that debug metadata in the src module might already be pointing to406 // the destination.407 if (DisableDITypeMap && !NoVerify && verifyModule(*M, &errs())) {408 errs() << argv0 << ": " << File << ": ";409 WithColor::error() << "input module is broken!\n";410 return false;411 }412 413 // If a module summary index is supplied, load it so linkInModule can treat414 // local functions/variables as exported and promote if necessary.415 if (!SummaryIndex.empty()) {416 std::unique_ptr<ModuleSummaryIndex> Index =417 ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex));418 419 // Conservatively mark all internal values as promoted, since this tool420 // does not do the ThinLink that would normally determine what values to421 // promote.422 for (auto &I : *Index) {423 for (auto &S : I.second.getSummaryList()) {424 if (GlobalValue::isLocalLinkage(S->linkage()))425 S->setLinkage(GlobalValue::ExternalLinkage);426 }427 }428 429 // Promotion430 renameModuleForThinLTO(*M, *Index,431 /*ClearDSOLocalOnDeclarations=*/false);432 }433 434 if (Verbose)435 errs() << "Linking in '" << File << "'\n";436 437 bool Err = false;438 if (InternalizeLinkedSymbols) {439 Err = L.linkInModule(440 std::move(M), ApplicableFlags, [](Module &M, const StringSet<> &GVS) {441 internalizeModule(M, [&GVS](const GlobalValue &GV) {442 return !GV.hasName() || (GVS.count(GV.getName()) == 0);443 });444 });445 } else {446 Err = L.linkInModule(std::move(M), ApplicableFlags);447 }448 449 if (Err)450 return false;451 452 // Internalization applies to linking of subsequent files.453 InternalizeLinkedSymbols = Internalize;454 455 // All linker flags apply to linking of subsequent files.456 ApplicableFlags = Flags;457 }458 459 return true;460}461 462int main(int argc, char **argv) {463 InitLLVM X(argc, argv);464 ExitOnErr.setBanner(std::string(argv[0]) + ": ");465 466 cl::HideUnrelatedOptions({&LinkCategory, &getColorCategory()});467 cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");468 469 LLVMContext Context;470 Context.setDiagnosticHandler(std::make_unique<LLVMLinkDiagnosticHandler>(),471 true);472 473 if (!DisableDITypeMap)474 Context.enableDebugTypeODRUniquing();475 476 auto Composite = std::make_unique<Module>("llvm-link", Context);477 Linker L(*Composite);478 479 unsigned Flags = Linker::Flags::None;480 if (OnlyNeeded)481 Flags |= Linker::Flags::LinkOnlyNeeded;482 483 // First add all the regular input files484 if (!linkFiles(argv[0], Context, L, InputFilenames, Flags))485 return 1;486 487 // Next the -override ones.488 if (!linkFiles(argv[0], Context, L, OverridingInputs,489 Flags | Linker::Flags::OverrideFromSrc))490 return 1;491 492 // Import any functions requested via -import493 if (!importFunctions(argv[0], *Composite))494 return 1;495 496 if (DumpAsm)497 errs() << "Here's the assembly:\n" << *Composite;498 499 std::error_code EC;500 ToolOutputFile Out(OutputFilename, EC,501 OutputAssembly ? sys::fs::OF_TextWithCRLF502 : sys::fs::OF_None);503 if (EC) {504 WithColor::error() << EC.message() << '\n';505 return 1;506 }507 508 if (!NoVerify && verifyModule(*Composite, &errs())) {509 errs() << argv[0] << ": ";510 WithColor::error() << "linked module is broken!\n";511 return 1;512 }513 514 if (Verbose)515 errs() << "Writing bitcode...\n";516 Composite->removeDebugIntrinsicDeclarations();517 if (OutputAssembly) {518 Composite->print(Out.os(), nullptr, /* ShouldPreserveUseListOrder */ false);519 } else if (Force || !CheckBitcodeOutputToConsole(Out.os())) {520 WriteBitcodeToFile(*Composite, Out.os(),521 /* ShouldPreserveUseListOrder */ true);522 }523 524 // Declare success.525 Out.keep();526 527 return 0;528}529