Path: blob/main/contrib/llvm-project/lld/COFF/Driver.h
34870 views
//===- Driver.h -------------------------------------------------*- C++ -*-===//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//===----------------------------------------------------------------------===//78#ifndef LLD_COFF_DRIVER_H9#define LLD_COFF_DRIVER_H1011#include "Config.h"12#include "SymbolTable.h"13#include "lld/Common/LLVM.h"14#include "lld/Common/Reproduce.h"15#include "llvm/ADT/StringRef.h"16#include "llvm/ADT/StringSet.h"17#include "llvm/Object/Archive.h"18#include "llvm/Object/COFF.h"19#include "llvm/Option/Arg.h"20#include "llvm/Option/ArgList.h"21#include "llvm/Support/FileSystem.h"22#include "llvm/Support/TarWriter.h"23#include "llvm/WindowsDriver/MSVCPaths.h"24#include <memory>25#include <optional>26#include <set>27#include <vector>2829namespace lld::coff {3031using llvm::COFF::MachineTypes;32using llvm::COFF::WindowsSubsystem;33using std::optional;3435class COFFOptTable : public llvm::opt::GenericOptTable {36public:37COFFOptTable();38};3940// The result of parsing the .drective section. The /export: and /include:41// options are handled separately because they reference symbols, and the number42// of symbols can be quite large. The LLVM Option library will perform at least43// one memory allocation per argument, and that is prohibitively slow for44// parsing directives.45struct ParsedDirectives {46std::vector<StringRef> exports;47std::vector<StringRef> includes;48std::vector<StringRef> excludes;49llvm::opt::InputArgList args;50};5152class ArgParser {53public:54ArgParser(COFFLinkerContext &ctx);5556// Parses command line options.57llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);5859// Tokenizes a given string and then parses as command line options.60llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); }6162// Tokenizes a given string and then parses as command line options in63// .drectve section. /EXPORT options are returned in second element64// to be processed in fastpath.65ParsedDirectives parseDirectives(StringRef s);6667private:68// Concatenate LINK environment variable.69void addLINK(SmallVector<const char *, 256> &argv);7071std::vector<const char *> tokenize(StringRef s);7273COFFLinkerContext &ctx;74};7576class LinkerDriver {77public:78LinkerDriver(COFFLinkerContext &ctx) : ctx(ctx) {}7980void linkerMain(llvm::ArrayRef<const char *> args);8182// Adds various search paths based on the sysroot. Must only be called once83// config->machine has been set.84void addWinSysRootLibSearchPaths();8586void addClangLibSearchPaths(const std::string &argv0);8788// Used by the resolver to parse .drectve section contents.89void parseDirectives(InputFile *file);9091// Used by ArchiveFile to enqueue members.92void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym,93StringRef parentName);9495void enqueuePDB(StringRef Path) { enqueuePath(Path, false, false); }9697MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);9899void enqueuePath(StringRef path, bool wholeArchive, bool lazy);100101std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro102103private:104// Searches a file from search paths.105std::optional<StringRef> findFileIfNew(StringRef filename);106std::optional<StringRef> findLibIfNew(StringRef filename);107StringRef findFile(StringRef filename);108StringRef findLib(StringRef filename);109StringRef findLibMinGW(StringRef filename);110111bool findUnderscoreMangle(StringRef sym);112113// Determines the location of the sysroot based on `args`, environment, etc.114void detectWinSysRoot(const llvm::opt::InputArgList &args);115116// Symbol names are mangled by prepending "_" on x86.117StringRef mangle(StringRef sym);118119llvm::Triple::ArchType getArch();120121uint64_t getDefaultImageBase();122123bool isDecorated(StringRef sym);124125std::string getMapFile(const llvm::opt::InputArgList &args,126llvm::opt::OptSpecifier os,127llvm::opt::OptSpecifier osFile);128129std::string getImplibPath();130131// The import name is calculated as follows:132//133// | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY134// -----+----------------+---------------------+------------------135// LINK | {value} | {value}.{.dll/.exe} | {output name}136// LIB | {value} | {value}.dll | {output name}.dll137//138std::string getImportName(bool asLib);139140void createImportLibrary(bool asLib);141142void parseModuleDefs(StringRef path);143144// Parse an /order file. If an option is given, the linker places COMDAT145// sections int he same order as their names appear in the given file.146void parseOrderFile(StringRef arg);147148void parseCallGraphFile(StringRef path);149150void parsePDBAltPath();151152// Parses LIB environment which contains a list of search paths.153void addLibSearchPaths();154155// Library search path. The first element is always "" (current directory).156std::vector<StringRef> searchPaths;157158// Convert resource files and potentially merge input resource object159// trees into one resource tree.160void convertResources();161162void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args);163164// We don't want to add the same file more than once.165// Files are uniquified by their filesystem and file number.166std::set<llvm::sys::fs::UniqueID> visitedFiles;167168std::set<std::string> visitedLibs;169170Symbol *addUndefined(StringRef sym);171172StringRef mangleMaybe(Symbol *s);173174// Windows specific -- "main" is not the only main function in Windows.175// You can choose one from these four -- {w,}{WinMain,main}.176// There are four different entry point functions for them,177// {w,}{WinMain,main}CRTStartup, respectively. The linker needs to178// choose the right one depending on which "main" function is defined.179// This function looks up the symbol table and resolve corresponding180// entry point name.181StringRef findDefaultEntry();182WindowsSubsystem inferSubsystem();183184void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive,185bool lazy);186void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,187StringRef parentName, uint64_t offsetInArchive);188189void enqueueTask(std::function<void()> task);190bool run();191192std::list<std::function<void()>> taskQueue;193std::vector<StringRef> filePaths;194std::vector<MemoryBufferRef> resources;195196llvm::DenseSet<StringRef> directivesExports;197llvm::DenseSet<StringRef> excludedSymbols;198199COFFLinkerContext &ctx;200201llvm::ToolsetLayout vsLayout = llvm::ToolsetLayout::OlderVS;202std::string vcToolChainPath;203llvm::SmallString<128> diaPath;204bool useWinSysRootLibPath = false;205llvm::SmallString<128> universalCRTLibPath;206int sdkMajor = 0;207llvm::SmallString<128> windowsSdkLibPath;208209// Functions below this line are defined in DriverUtils.cpp.210211void printHelp(const char *argv0);212213// Parses a string in the form of "<integer>[,<integer>]".214void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size = nullptr);215216void parseGuard(StringRef arg);217218// Parses a string in the form of "<integer>[.<integer>]".219// Minor's default value is 0.220void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor);221222// Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".223void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major,224uint32_t *minor, bool *gotVersion = nullptr);225226void parseAlternateName(StringRef);227void parseMerge(StringRef);228void parsePDBPageSize(StringRef);229void parseSection(StringRef);230void parseAligncomm(StringRef);231232// Parses a string in the form of "[:<integer>]"233void parseFunctionPadMin(llvm::opt::Arg *a);234235// Parses a string in the form of "[:<integer>]"236void parseDependentLoadFlags(llvm::opt::Arg *a);237238// Parses a string in the form of "EMBED[,=<integer>]|NO".239void parseManifest(StringRef arg);240241// Parses a string in the form of "level=<string>|uiAccess=<string>"242void parseManifestUAC(StringRef arg);243244// Parses a string in the form of "cd|net[,(cd|net)]*"245void parseSwaprun(StringRef arg);246247// Create a resource file containing a manifest XML.248std::unique_ptr<MemoryBuffer> createManifestRes();249void createSideBySideManifest();250std::string createDefaultXml();251std::string createManifestXmlWithInternalMt(StringRef defaultXml);252std::string createManifestXmlWithExternalMt(StringRef defaultXml);253std::string createManifestXml();254255std::unique_ptr<llvm::WritableMemoryBuffer>256createMemoryBufferForManifestRes(size_t manifestRes);257258// Used for dllexported symbols.259Export parseExport(StringRef arg);260void fixupExports();261void assignExportOrdinals();262263// Parses a string in the form of "key=value" and check264// if value matches previous values for the key.265// This feature used in the directive section to reject266// incompatible objects.267void checkFailIfMismatch(StringRef arg, InputFile *source);268269// Convert Windows resource files (.res files) to a .obj file.270MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,271ArrayRef<ObjFile *> objs);272};273274// Create enum with OPT_xxx values for each option in Options.td275enum {276OPT_INVALID = 0,277#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),278#include "Options.inc"279#undef OPTION280};281282} // namespace lld::coff283284#endif285286287