llvm/lld/COFF/Driver.cpp

//===- Driver.cpp ---------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Driver.h"
#include "COFFLinkerContext.h"
#include "Config.h"
#include "DebugTypes.h"
#include "ICF.h"
#include "InputFiles.h"
#include "MarkLive.h"
#include "MinGW.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Writer.h"
#include "lld/Common/Args.h"
#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/Driver.h"
#include "lld/Common/Filesystem.h"
#include "lld/Common/Timer.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/COFFModuleDefinition.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TarWriter.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/ToolDrivers/llvm-lib/LibDriver.h"
#include <algorithm>
#include <future>
#include <memory>
#include <optional>
#include <tuple>

usingnamespacellvm;
usingnamespacellvm::object;
usingnamespacellvm::COFF;
usingnamespacellvm::sys;

namespace lld::coff {

bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
          llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {}

// Parse options of the form "old;new".
static std::pair<StringRef, StringRef> getOldNewOptions(opt::InputArgList &args,
                                                        unsigned id) {}

// Parse options of the form "old;new[;extra]".
static std::tuple<StringRef, StringRef, StringRef>
getOldNewOptionsExtra(opt::InputArgList &args, unsigned id) {}

// Drop directory components and replace extension with
// ".exe", ".dll" or ".sys".
static std::string getOutputPath(StringRef path, bool isDll, bool isDriver) {}

// Returns true if S matches /crtend.?\.o$/.
static bool isCrtend(StringRef s) {}

// ErrorOr is not default constructible, so it cannot be used as the type
// parameter of a future.
// FIXME: We could open the file in createFutureForFile and avoid needing to
// return an error here, but for the moment that would cost us a file descriptor
// (a limited resource on Windows) for the duration that the future is pending.
MBErrPair;

// Create a std::future that opens and maps a file using the best strategy for
// the host platform.
static std::future<MBErrPair> createFutureForFile(std::string path) {}

// Symbol names are mangled by prepending "_" on x86.
StringRef LinkerDriver::mangle(StringRef sym) {}

llvm::Triple::ArchType LinkerDriver::getArch() {}

bool LinkerDriver::findUnderscoreMangle(StringRef sym) {}

MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> mb) {}

void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
                             bool wholeArchive, bool lazy) {}

void LinkerDriver::enqueuePath(StringRef path, bool wholeArchive, bool lazy) {}

void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
                                    StringRef parentName,
                                    uint64_t offsetInArchive) {}

void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
                                        const Archive::Symbol &sym,
                                        StringRef parentName) {}

bool LinkerDriver::isDecorated(StringRef sym) {}

// Parses .drectve section contents and returns a list of files
// specified by /defaultlib.
void LinkerDriver::parseDirectives(InputFile *file) {}

// Find file from search paths. You can omit ".obj", this function takes
// care of that. Note that the returned path is not guaranteed to exist.
StringRef LinkerDriver::findFile(StringRef filename) {}

static std::optional<sys::fs::UniqueID> getUniqueID(StringRef path) {}

// Resolves a file path. This never returns the same path
// (in that case, it returns std::nullopt).
std::optional<StringRef> LinkerDriver::findFileIfNew(StringRef filename) {}

// MinGW specific. If an embedded directive specified to link to
// foo.lib, but it isn't found, try libfoo.a instead.
StringRef LinkerDriver::findLibMinGW(StringRef filename) {}

// Find library file from search path.
StringRef LinkerDriver::findLib(StringRef filename) {}

// Resolves a library path. /nodefaultlib options are taken into
// consideration. This never returns the same path (in that case,
// it returns std::nullopt).
std::optional<StringRef> LinkerDriver::findLibIfNew(StringRef filename) {}

void LinkerDriver::detectWinSysRoot(const opt::InputArgList &Args) {}

void LinkerDriver::addClangLibSearchPaths(const std::string &argv0) {}

void LinkerDriver::addWinSysRootLibSearchPaths() {}

// Parses LIB environment which contains a list of search paths.
void LinkerDriver::addLibSearchPaths() {}

Symbol *LinkerDriver::addUndefined(StringRef name) {}

StringRef LinkerDriver::mangleMaybe(Symbol *s) {}

// Windows specific -- find default entry point name.
//
// There are four different entry point functions for Windows executables,
// each of which corresponds to a user-defined "main" function. This function
// infers an entry point from a user-defined "main" function.
StringRef LinkerDriver::findDefaultEntry() {}

WindowsSubsystem LinkerDriver::inferSubsystem() {}

uint64_t LinkerDriver::getDefaultImageBase() {}

static std::string rewritePath(StringRef s) {}

// Reconstructs command line arguments so that so that you can re-run
// the same command with the same inputs. This is for --reproduce.
static std::string createResponseFile(const opt::InputArgList &args,
                                      ArrayRef<StringRef> filePaths,
                                      ArrayRef<StringRef> searchPaths) {}

static unsigned parseDebugTypes(const opt::InputArgList &args) {}

std::string LinkerDriver::getMapFile(const opt::InputArgList &args,
                                     opt::OptSpecifier os,
                                     opt::OptSpecifier osFile) {}

std::string LinkerDriver::getImplibPath() {}

// The import name is calculated as follows:
//
//        | LIBRARY w/ ext |   LIBRARY w/o ext   | no LIBRARY
//   -----+----------------+---------------------+------------------
//   LINK | {value}        | {value}.{.dll/.exe} | {output name}
//    LIB | {value}        | {value}.dll         | {output name}.dll
//
std::string LinkerDriver::getImportName(bool asLib) {}

void LinkerDriver::createImportLibrary(bool asLib) {}

void LinkerDriver::parseModuleDefs(StringRef path) {}

void LinkerDriver::enqueueTask(std::function<void()> task) {}

bool LinkerDriver::run() {}

// Parse an /order file. If an option is given, the linker places
// COMDAT sections in the same order as their names appear in the
// given file.
void LinkerDriver::parseOrderFile(StringRef arg) {}

void LinkerDriver::parseCallGraphFile(StringRef path) {}

static void readCallGraphsFromObjectFiles(COFFLinkerContext &ctx) {}

static void markAddrsig(Symbol *s) {}

static void findKeepUniqueSections(COFFLinkerContext &ctx) {}

// link.exe replaces each %foo% in altPath with the contents of environment
// variable foo, and adds the two magic env vars _PDB (expands to the basename
// of pdb's output path) and _EXT (expands to the extension of the output
// binary).
// lld only supports %_PDB% and %_EXT% and warns on references to all other env
// vars.
void LinkerDriver::parsePDBAltPath() {}

/// Convert resource files and potentially merge input resource object
/// trees into one resource tree.
/// Call after ObjFile::Instances is complete.
void LinkerDriver::convertResources() {}

void LinkerDriver::maybeCreateECExportThunk(StringRef name, Symbol *&sym) {}

void LinkerDriver::createECExportThunks() {}

void LinkerDriver::pullArm64ECIcallHelper() {}

// In MinGW, if no symbols are chosen to be exported, then all symbols are
// automatically exported by default. This behavior can be forced by the
// -export-all-symbols option, so that it happens even when exports are
// explicitly specified. The automatic behavior can be disabled using the
// -exclude-all-symbols option, so that lld-link behaves like link.exe rather
// than MinGW in the case that nothing is explicitly exported.
void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {}

// lld has a feature to create a tar file containing all input files as well as
// all command line options, so that other people can run lld again with exactly
// the same inputs. This feature is accessible via /linkrepro and /reproduce.
//
// /linkrepro and /reproduce are very similar, but /linkrepro takes a directory
// name while /reproduce takes a full path. We have /linkrepro for compatibility
// with Microsoft link.exe.
std::optional<std::string> getReproduceFile(const opt::InputArgList &args) {}

static std::unique_ptr<llvm::vfs::FileSystem>
getVFS(const opt::InputArgList &args) {}

void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {}

} // namespace lld::coff