Path: blob/main/contrib/llvm-project/llvm/tools/llvm-link/llvm-link.cpp
35231 views
//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This utility may be invoked in the following manner:9// llvm-link a.bc b.bc c.bc -o x.bc10//11//===----------------------------------------------------------------------===//1213#include "llvm/ADT/STLExtras.h"14#include "llvm/BinaryFormat/Magic.h"15#include "llvm/Bitcode/BitcodeReader.h"16#include "llvm/Bitcode/BitcodeWriter.h"17#include "llvm/IR/AutoUpgrade.h"18#include "llvm/IR/DiagnosticInfo.h"19#include "llvm/IR/DiagnosticPrinter.h"20#include "llvm/IR/LLVMContext.h"21#include "llvm/IR/Module.h"22#include "llvm/IR/ModuleSummaryIndex.h"23#include "llvm/IR/Verifier.h"24#include "llvm/IRReader/IRReader.h"25#include "llvm/Linker/Linker.h"26#include "llvm/Object/Archive.h"27#include "llvm/Support/CommandLine.h"28#include "llvm/Support/FileSystem.h"29#include "llvm/Support/InitLLVM.h"30#include "llvm/Support/Path.h"31#include "llvm/Support/SourceMgr.h"32#include "llvm/Support/SystemUtils.h"33#include "llvm/Support/ToolOutputFile.h"34#include "llvm/Support/WithColor.h"35#include "llvm/Transforms/IPO/FunctionImport.h"36#include "llvm/Transforms/IPO/Internalize.h"37#include "llvm/Transforms/Utils/FunctionImportUtils.h"3839#include <memory>40#include <utility>41using namespace llvm;4243static cl::OptionCategory LinkCategory("Link Options");4445static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,46cl::desc("<input bitcode files>"),47cl::cat(LinkCategory));4849static cl::list<std::string> OverridingInputs(50"override", cl::value_desc("filename"),51cl::desc(52"input bitcode file which can override previously defined symbol(s)"),53cl::cat(LinkCategory));5455// Option to simulate function importing for testing. This enables using56// llvm-link to simulate ThinLTO backend processes.57static cl::list<std::string> Imports(58"import", cl::value_desc("function:filename"),59cl::desc("Pair of function name and filename, where function should be "60"imported from bitcode in filename"),61cl::cat(LinkCategory));6263// Option to support testing of function importing. The module summary64// must be specified in the case were we request imports via the -import65// option, as well as when compiling any module with functions that may be66// exported (imported by a different llvm-link -import invocation), to ensure67// consistent promotion and renaming of locals.68static cl::opt<std::string>69SummaryIndex("summary-index", cl::desc("Module summary index filename"),70cl::init(""), cl::value_desc("filename"),71cl::cat(LinkCategory));7273static cl::opt<std::string>74OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),75cl::value_desc("filename"), cl::cat(LinkCategory));7677static cl::opt<bool> Internalize("internalize",78cl::desc("Internalize linked symbols"),79cl::cat(LinkCategory));8081static cl::opt<bool>82DisableDITypeMap("disable-debug-info-type-map",83cl::desc("Don't use a uniquing type map for debug info"),84cl::cat(LinkCategory));8586static cl::opt<bool> OnlyNeeded("only-needed",87cl::desc("Link only needed symbols"),88cl::cat(LinkCategory));8990static cl::opt<bool> Force("f", cl::desc("Enable binary output on terminals"),91cl::cat(LinkCategory));9293static cl::opt<bool> DisableLazyLoad("disable-lazy-loading",94cl::desc("Disable lazy module loading"),95cl::cat(LinkCategory));9697static cl::opt<bool> OutputAssembly("S",98cl::desc("Write output as LLVM assembly"),99cl::Hidden, cl::cat(LinkCategory));100101static cl::opt<bool> Verbose("v",102cl::desc("Print information about actions taken"),103cl::cat(LinkCategory));104105static cl::opt<bool> DumpAsm("d", cl::desc("Print assembly as linked"),106cl::Hidden, cl::cat(LinkCategory));107108static cl::opt<bool> SuppressWarnings("suppress-warnings",109cl::desc("Suppress all linking warnings"),110cl::init(false), cl::cat(LinkCategory));111112static cl::opt<bool> PreserveBitcodeUseListOrder(113"preserve-bc-uselistorder",114cl::desc("Preserve use-list order when writing LLVM bitcode."),115cl::init(true), cl::Hidden, cl::cat(LinkCategory));116117static cl::opt<bool> PreserveAssemblyUseListOrder(118"preserve-ll-uselistorder",119cl::desc("Preserve use-list order when writing LLVM assembly."),120cl::init(false), cl::Hidden, cl::cat(LinkCategory));121122static cl::opt<bool> NoVerify("disable-verify",123cl::desc("Do not run the verifier"), cl::Hidden,124cl::cat(LinkCategory));125126static cl::opt<bool> IgnoreNonBitcode(127"ignore-non-bitcode",128cl::desc("Do not report an error for non-bitcode files in archives"),129cl::Hidden);130131static cl::opt<bool> TryUseNewDbgInfoFormat(132"try-experimental-debuginfo-iterators",133cl::desc("Enable debuginfo iterator positions, if they're built in"),134cl::init(false));135136extern cl::opt<bool> UseNewDbgInfoFormat;137extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat;138extern cl::opt<bool> WriteNewDbgInfoFormat;139extern bool WriteNewDbgInfoFormatToBitcode;140141extern cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat;142143static ExitOnError ExitOnErr;144145// Read the specified bitcode file in and return it. This routine searches the146// link path for the specified file to try to find it...147//148static std::unique_ptr<Module> loadFile(const char *argv0,149std::unique_ptr<MemoryBuffer> Buffer,150LLVMContext &Context,151bool MaterializeMetadata = true) {152SMDiagnostic Err;153if (Verbose)154errs() << "Loading '" << Buffer->getBufferIdentifier() << "'\n";155std::unique_ptr<Module> Result;156if (DisableLazyLoad)157Result = parseIR(*Buffer, Err, Context);158else159Result =160getLazyIRModule(std::move(Buffer), Err, Context, !MaterializeMetadata);161162if (!Result) {163Err.print(argv0, errs());164return nullptr;165}166167if (MaterializeMetadata) {168ExitOnErr(Result->materializeMetadata());169UpgradeDebugInfo(*Result);170}171172return Result;173}174175static std::unique_ptr<Module> loadArFile(const char *Argv0,176std::unique_ptr<MemoryBuffer> Buffer,177LLVMContext &Context) {178std::unique_ptr<Module> Result(new Module("ArchiveModule", Context));179StringRef ArchiveName = Buffer->getBufferIdentifier();180if (Verbose)181errs() << "Reading library archive file '" << ArchiveName182<< "' to memory\n";183Expected<std::unique_ptr<object::Archive>> ArchiveOrError =184object::Archive::create(Buffer->getMemBufferRef());185if (!ArchiveOrError)186ExitOnErr(ArchiveOrError.takeError());187188std::unique_ptr<object::Archive> Archive = std::move(ArchiveOrError.get());189190Linker L(*Result);191Error Err = Error::success();192for (const object::Archive::Child &C : Archive->children(Err)) {193Expected<StringRef> Ename = C.getName();194if (Error E = Ename.takeError()) {195errs() << Argv0 << ": ";196WithColor::error() << " failed to read name of archive member"197<< ArchiveName << "'\n";198return nullptr;199}200std::string ChildName = Ename.get().str();201if (Verbose)202errs() << "Parsing member '" << ChildName203<< "' of archive library to module.\n";204SMDiagnostic ParseErr;205Expected<MemoryBufferRef> MemBuf = C.getMemoryBufferRef();206if (Error E = MemBuf.takeError()) {207errs() << Argv0 << ": ";208WithColor::error() << " loading memory for member '" << ChildName209<< "' of archive library failed'" << ArchiveName210<< "'\n";211return nullptr;212};213214if (!isBitcode(reinterpret_cast<const unsigned char *>(215MemBuf.get().getBufferStart()),216reinterpret_cast<const unsigned char *>(217MemBuf.get().getBufferEnd()))) {218if (IgnoreNonBitcode)219continue;220errs() << Argv0 << ": ";221WithColor::error() << " member of archive is not a bitcode file: '"222<< ChildName << "'\n";223return nullptr;224}225226std::unique_ptr<Module> M;227if (DisableLazyLoad)228M = parseIR(MemBuf.get(), ParseErr, Context);229else230M = getLazyIRModule(MemoryBuffer::getMemBuffer(MemBuf.get(), false),231ParseErr, Context);232233if (!M) {234errs() << Argv0 << ": ";235WithColor::error() << " parsing member '" << ChildName236<< "' of archive library failed'" << ArchiveName237<< "'\n";238return nullptr;239}240if (Verbose)241errs() << "Linking member '" << ChildName << "' of archive library.\n";242if (L.linkInModule(std::move(M)))243return nullptr;244} // end for each child245ExitOnErr(std::move(Err));246return Result;247}248249namespace {250251/// Helper to load on demand a Module from file and cache it for subsequent252/// queries during function importing.253class ModuleLazyLoaderCache {254/// Cache of lazily loaded module for import.255StringMap<std::unique_ptr<Module>> ModuleMap;256257/// Retrieve a Module from the cache or lazily load it on demand.258std::function<std::unique_ptr<Module>(const char *argv0,259const std::string &FileName)>260createLazyModule;261262public:263/// Create the loader, Module will be initialized in \p Context.264ModuleLazyLoaderCache(std::function<std::unique_ptr<Module>(265const char *argv0, const std::string &FileName)>266createLazyModule)267: createLazyModule(std::move(createLazyModule)) {}268269/// Retrieve a Module from the cache or lazily load it on demand.270Module &operator()(const char *argv0, const std::string &FileName);271272std::unique_ptr<Module> takeModule(const std::string &FileName) {273auto I = ModuleMap.find(FileName);274assert(I != ModuleMap.end());275std::unique_ptr<Module> Ret = std::move(I->second);276ModuleMap.erase(I);277return Ret;278}279};280281// Get a Module for \p FileName from the cache, or load it lazily.282Module &ModuleLazyLoaderCache::operator()(const char *argv0,283const std::string &Identifier) {284auto &Module = ModuleMap[Identifier];285if (!Module) {286Module = createLazyModule(argv0, Identifier);287assert(Module && "Failed to create lazy module!");288}289return *Module;290}291} // anonymous namespace292293namespace {294struct LLVMLinkDiagnosticHandler : public DiagnosticHandler {295bool handleDiagnostics(const DiagnosticInfo &DI) override {296unsigned Severity = DI.getSeverity();297switch (Severity) {298case DS_Error:299WithColor::error();300break;301case DS_Warning:302if (SuppressWarnings)303return true;304WithColor::warning();305break;306case DS_Remark:307case DS_Note:308llvm_unreachable("Only expecting warnings and errors");309}310311DiagnosticPrinterRawOStream DP(errs());312DI.print(DP);313errs() << '\n';314return true;315}316};317} // namespace318319/// Import any functions requested via the -import option.320static bool importFunctions(const char *argv0, Module &DestModule) {321if (SummaryIndex.empty())322return true;323std::unique_ptr<ModuleSummaryIndex> Index =324ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex));325326// Map of Module -> List of globals to import from the Module327FunctionImporter::ImportMapTy ImportList;328329auto ModuleLoader = [&DestModule](const char *argv0,330const std::string &Identifier) {331std::unique_ptr<MemoryBuffer> Buffer =332ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Identifier)));333return loadFile(argv0, std::move(Buffer), DestModule.getContext(), false);334};335336ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader);337// Owns the filename strings used to key into the ImportList. Normally this is338// constructed from the index and the strings are owned by the index, however,339// since we are synthesizing this data structure from options we need a cache340// to own those strings.341StringSet<> FileNameStringCache;342for (const auto &Import : Imports) {343// Identify the requested function and its bitcode source file.344size_t Idx = Import.find(':');345if (Idx == std::string::npos) {346errs() << "Import parameter bad format: " << Import << "\n";347return false;348}349std::string FunctionName = Import.substr(0, Idx);350std::string FileName = Import.substr(Idx + 1, std::string::npos);351352// Load the specified source module.353auto &SrcModule = ModuleLoaderCache(argv0, FileName);354355if (!NoVerify && verifyModule(SrcModule, &errs())) {356errs() << argv0 << ": " << FileName;357WithColor::error() << "input module is broken!\n";358return false;359}360361Function *F = SrcModule.getFunction(FunctionName);362if (!F) {363errs() << "Ignoring import request for non-existent function "364<< FunctionName << " from " << FileName << "\n";365continue;366}367// We cannot import weak_any functions without possibly affecting the368// order they are seen and selected by the linker, changing program369// semantics.370if (F->hasWeakAnyLinkage()) {371errs() << "Ignoring import request for weak-any function " << FunctionName372<< " from " << FileName << "\n";373continue;374}375376if (Verbose)377errs() << "Importing " << FunctionName << " from " << FileName << "\n";378379// `-import` specifies the `<filename,function-name>` pairs to import as380// definition, so make the import type definition directly.381// FIXME: A follow-up patch should add test coverage for import declaration382// in `llvm-link` CLI (e.g., by introducing a new command line option).383auto &Entry =384ImportList[FileNameStringCache.insert(FileName).first->getKey()];385Entry[F->getGUID()] = GlobalValueSummary::Definition;386}387auto CachedModuleLoader = [&](StringRef Identifier) {388return ModuleLoaderCache.takeModule(std::string(Identifier));389};390FunctionImporter Importer(*Index, CachedModuleLoader,391/*ClearDSOLocalOnDeclarations=*/false);392ExitOnErr(Importer.importFunctions(DestModule, ImportList));393394return true;395}396397static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,398const cl::list<std::string> &Files, unsigned Flags) {399// Filter out flags that don't apply to the first file we load.400unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc;401// Similar to some flags, internalization doesn't apply to the first file.402bool InternalizeLinkedSymbols = false;403for (const auto &File : Files) {404auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(File);405406// When we encounter a missing file, make sure we expose its name.407if (auto EC = BufferOrErr.getError())408if (EC == std::errc::no_such_file_or_directory)409ExitOnErr(createStringError(EC, "No such file or directory: '%s'",410File.c_str()));411412std::unique_ptr<MemoryBuffer> Buffer =413ExitOnErr(errorOrToExpected(std::move(BufferOrErr)));414415std::unique_ptr<Module> M =416identify_magic(Buffer->getBuffer()) == file_magic::archive417? loadArFile(argv0, std::move(Buffer), Context)418: loadFile(argv0, std::move(Buffer), Context);419if (!M) {420errs() << argv0 << ": ";421WithColor::error() << " loading file '" << File << "'\n";422return false;423}424425// Note that when ODR merging types cannot verify input files in here When426// doing that debug metadata in the src module might already be pointing to427// the destination.428if (DisableDITypeMap && !NoVerify && verifyModule(*M, &errs())) {429errs() << argv0 << ": " << File << ": ";430WithColor::error() << "input module is broken!\n";431return false;432}433434// If a module summary index is supplied, load it so linkInModule can treat435// local functions/variables as exported and promote if necessary.436if (!SummaryIndex.empty()) {437std::unique_ptr<ModuleSummaryIndex> Index =438ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex));439440// Conservatively mark all internal values as promoted, since this tool441// does not do the ThinLink that would normally determine what values to442// promote.443for (auto &I : *Index) {444for (auto &S : I.second.SummaryList) {445if (GlobalValue::isLocalLinkage(S->linkage()))446S->setLinkage(GlobalValue::ExternalLinkage);447}448}449450// Promotion451if (renameModuleForThinLTO(*M, *Index,452/*ClearDSOLocalOnDeclarations=*/false))453return true;454}455456if (Verbose)457errs() << "Linking in '" << File << "'\n";458459bool Err = false;460if (InternalizeLinkedSymbols) {461Err = L.linkInModule(462std::move(M), ApplicableFlags, [](Module &M, const StringSet<> &GVS) {463internalizeModule(M, [&GVS](const GlobalValue &GV) {464return !GV.hasName() || (GVS.count(GV.getName()) == 0);465});466});467} else {468Err = L.linkInModule(std::move(M), ApplicableFlags);469}470471if (Err)472return false;473474// Internalization applies to linking of subsequent files.475InternalizeLinkedSymbols = Internalize;476477// All linker flags apply to linking of subsequent files.478ApplicableFlags = Flags;479}480481return true;482}483484int main(int argc, char **argv) {485InitLLVM X(argc, argv);486ExitOnErr.setBanner(std::string(argv[0]) + ": ");487488cl::HideUnrelatedOptions({&LinkCategory, &getColorCategory()});489cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");490491// Load bitcode into the new debug info format by default.492if (LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_UNSET)493LoadBitcodeIntoNewDbgInfoFormat = cl::boolOrDefault::BOU_TRUE;494495// Since llvm-link collects multiple IR modules together, for simplicity's496// sake we disable the "PreserveInputDbgFormat" flag to enforce a single497// debug info format.498PreserveInputDbgFormat = cl::boolOrDefault::BOU_FALSE;499500LLVMContext Context;501Context.setDiagnosticHandler(std::make_unique<LLVMLinkDiagnosticHandler>(),502true);503504if (!DisableDITypeMap)505Context.enableDebugTypeODRUniquing();506507auto Composite = std::make_unique<Module>("llvm-link", Context);508Linker L(*Composite);509510unsigned Flags = Linker::Flags::None;511if (OnlyNeeded)512Flags |= Linker::Flags::LinkOnlyNeeded;513514// First add all the regular input files515if (!linkFiles(argv[0], Context, L, InputFilenames, Flags))516return 1;517518// Next the -override ones.519if (!linkFiles(argv[0], Context, L, OverridingInputs,520Flags | Linker::Flags::OverrideFromSrc))521return 1;522523// Import any functions requested via -import524if (!importFunctions(argv[0], *Composite))525return 1;526527if (DumpAsm)528errs() << "Here's the assembly:\n" << *Composite;529530std::error_code EC;531ToolOutputFile Out(OutputFilename, EC,532OutputAssembly ? sys::fs::OF_TextWithCRLF533: sys::fs::OF_None);534if (EC) {535WithColor::error() << EC.message() << '\n';536return 1;537}538539if (!NoVerify && verifyModule(*Composite, &errs())) {540errs() << argv[0] << ": ";541WithColor::error() << "linked module is broken!\n";542return 1;543}544545if (Verbose)546errs() << "Writing bitcode...\n";547auto SetFormat = [&](bool NewFormat) {548Composite->setIsNewDbgInfoFormat(NewFormat);549if (NewFormat)550Composite->removeDebugIntrinsicDeclarations();551};552if (OutputAssembly) {553SetFormat(WriteNewDbgInfoFormat);554Composite->print(Out.os(), nullptr, PreserveAssemblyUseListOrder);555} else if (Force || !CheckBitcodeOutputToConsole(Out.os())) {556SetFormat(UseNewDbgInfoFormat && WriteNewDbgInfoFormatToBitcode);557WriteBitcodeToFile(*Composite, Out.os(), PreserveBitcodeUseListOrder);558}559560// Declare success.561Out.keep();562563return 0;564}565566567