brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · 14710d5 Raw
280 lines · c
1//===- Driver.h -------------------------------------------------*- C++ -*-===//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#ifndef LLD_COFF_DRIVER_H10#define LLD_COFF_DRIVER_H11 12#include "Config.h"13#include "SymbolTable.h"14#include "lld/Common/LLVM.h"15#include "lld/Common/Reproduce.h"16#include "llvm/ADT/StringRef.h"17#include "llvm/ADT/StringSet.h"18#include "llvm/Object/Archive.h"19#include "llvm/Object/COFF.h"20#include "llvm/Option/Arg.h"21#include "llvm/Option/ArgList.h"22#include "llvm/Support/FileSystem.h"23#include "llvm/Support/TarWriter.h"24#include "llvm/WindowsDriver/MSVCPaths.h"25#include <memory>26#include <optional>27#include <set>28#include <vector>29 30namespace lld::coff {31 32using llvm::COFF::MachineTypes;33using llvm::COFF::WindowsSubsystem;34using std::optional;35 36class COFFOptTable : public llvm::opt::GenericOptTable {37public:38  COFFOptTable();39};40 41// The result of parsing the .drective section. The /export: and /include:42// options are handled separately because they reference symbols, and the number43// of symbols can be quite large. The LLVM Option library will perform at least44// one memory allocation per argument, and that is prohibitively slow for45// parsing directives.46struct ParsedDirectives {47  std::vector<StringRef> exports;48  std::vector<StringRef> includes;49  std::vector<StringRef> excludes;50  llvm::opt::InputArgList args;51};52 53class ArgParser {54public:55  ArgParser(COFFLinkerContext &ctx);56 57  // Parses command line options.58  llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> args);59 60  // Tokenizes a given string and then parses as command line options.61  llvm::opt::InputArgList parse(StringRef s) { return parse(tokenize(s)); }62 63  // Tokenizes a given string and then parses as command line options in64  // .drectve section. /EXPORT options are returned in second element65  // to be processed in fastpath.66  ParsedDirectives parseDirectives(StringRef s);67 68private:69  // Concatenate LINK environment variable.70  void addLINK(SmallVector<const char *, 256> &argv);71 72  std::vector<const char *> tokenize(StringRef s);73 74  COFFLinkerContext &ctx;75};76 77class LinkerDriver {78public:79  LinkerDriver(COFFLinkerContext &ctx) : ctx(ctx) {}80 81  void linkerMain(llvm::ArrayRef<const char *> args);82 83  void addFile(InputFile *file);84 85  void addClangLibSearchPaths(const std::string &argv0);86 87  // Used by ArchiveFile to enqueue members.88  void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym,89                            StringRef parentName);90 91  void enqueuePDB(StringRef Path) { enqueuePath(Path, false, false); }92 93  MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> mb);94 95  void enqueuePath(StringRef path, bool wholeArchive, bool lazy);96 97  // Returns a list of chunks of selected symbols.98  std::vector<Chunk *> getChunks() const;99 100  std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro101 102  void pullArm64ECIcallHelper();103 104private:105  // Searches a file from search paths.106  std::optional<StringRef> findFileIfNew(StringRef filename);107  std::optional<StringRef> findLibIfNew(StringRef filename);108  StringRef findFile(StringRef filename);109  StringRef findLib(StringRef filename);110  StringRef findLibMinGW(StringRef filename);111 112  // Determines the location of the sysroot based on `args`, environment, etc.113  void detectWinSysRoot(const llvm::opt::InputArgList &args);114 115  // Adds various search paths based on the sysroot.  Must only be called once116  // config.machine has been set.117  void addWinSysRootLibSearchPaths();118 119  void setMachine(llvm::COFF::MachineTypes machine);120  llvm::Triple::ArchType getArch();121 122  uint64_t getDefaultImageBase();123 124  bool isDecorated(StringRef sym);125 126  std::string getMapFile(const llvm::opt::InputArgList &args,127                         llvm::opt::OptSpecifier os,128                         llvm::opt::OptSpecifier osFile);129 130  std::string getImplibPath();131 132  // The import name is calculated as follows:133  //134  //        | LIBRARY w/ ext |   LIBRARY w/o ext   | no LIBRARY135  //   -----+----------------+---------------------+------------------136  //   LINK | {value}        | {value}.{.dll/.exe} | {output name}137  //    LIB | {value}        | {value}.dll         | {output name}.dll138  //139  std::string getImportName(bool asLib);140 141  void createImportLibrary(bool asLib);142 143  // Used by the resolver to parse .drectve section contents.144  void parseDirectives(InputFile *file);145 146  // Parse an /order file. If an option is given, the linker places COMDAT147  // sections int he same order as their names appear in the given file.148  void parseOrderFile(StringRef arg);149 150  void parseCallGraphFile(StringRef path);151 152  void parsePDBAltPath();153 154  // Parses LIB environment which contains a list of search paths.155  void addLibSearchPaths();156 157  // Library search path. The first element is always "" (current directory).158  std::vector<StringRef> searchPaths;159 160  // Convert resource files and potentially merge input resource object161  // trees into one resource tree.162  void convertResources();163 164  void maybeExportMinGWSymbols(const llvm::opt::InputArgList &args);165 166  // We don't want to add the same file more than once.167  // Files are uniquified by their filesystem and file number.168  std::set<llvm::sys::fs::UniqueID> visitedFiles;169 170  std::set<std::string> visitedLibs;171 172  void addBuffer(std::unique_ptr<MemoryBuffer> mb, bool wholeArchive,173                 bool lazy);174  void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,175                        StringRef parentName, uint64_t offsetInArchive);176  void addThinArchiveBuffer(MemoryBufferRef mbref, StringRef symName);177 178  void enqueueTask(std::function<void()> task);179  bool run();180 181  std::list<std::function<void()>> taskQueue;182  std::vector<MemoryBufferRef> resources;183 184  llvm::DenseSet<StringRef> excludedSymbols;185 186  COFFLinkerContext &ctx;187 188  llvm::ToolsetLayout vsLayout = llvm::ToolsetLayout::OlderVS;189  std::string vcToolChainPath;190  llvm::SmallString<128> diaPath;191  bool useWinSysRootLibPath = false;192  llvm::SmallString<128> universalCRTLibPath;193  int sdkMajor = 0;194  llvm::SmallString<128> windowsSdkLibPath;195 196  // Functions below this line are defined in DriverUtils.cpp.197 198  void printHelp(const char *argv0);199 200  // Parses a string in the form of "<integer>[,<integer>]".201  void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size = nullptr);202 203  void parseGuard(StringRef arg);204 205  // Parses a string in the form of "<integer>[.<integer>]".206  // Minor's default value is 0.207  void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor);208 209  // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".210  void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major,211                      uint32_t *minor, bool *gotVersion = nullptr);212 213  void parseMerge(StringRef);214  void parsePDBPageSize(StringRef);215  void parseSection(StringRef);216  void parseSectionLayout(StringRef);217 218  void parseSameAddress(StringRef);219 220  // Parses a MS-DOS stub file221  void parseDosStub(StringRef path);222 223  // Parses a string in the form of "[:<integer>]"224  void parseFunctionPadMin(llvm::opt::Arg *a);225 226  // Parses a string in the form of "[:<integer>]"227  void parseDependentLoadFlags(llvm::opt::Arg *a);228 229  // Parses a string in the form of "EMBED[,=<integer>]|NO".230  void parseManifest(StringRef arg);231 232  // Parses a string in the form of "level=<string>|uiAccess=<string>"233  void parseManifestUAC(StringRef arg);234 235  // Parses a string in the form of "cd|net[,(cd|net)]*"236  void parseSwaprun(StringRef arg);237 238  // Create a resource file containing a manifest XML.239  std::unique_ptr<MemoryBuffer> createManifestRes();240  void createSideBySideManifest();241  std::string createDefaultXml();242  std::string createManifestXmlWithInternalMt(StringRef defaultXml);243  std::string createManifestXmlWithExternalMt(StringRef defaultXml);244  std::string createManifestXml();245 246  std::unique_ptr<llvm::WritableMemoryBuffer>247  createMemoryBufferForManifestRes(size_t manifestRes);248 249  // Used for dllexported symbols.250  Export parseExport(StringRef arg);251 252  // Parses a string in the form of "key=value" and check253  // if value matches previous values for the key.254  // This feature used in the directive section to reject255  // incompatible objects.256  void checkFailIfMismatch(StringRef arg, InputFile *source);257 258  // Convert Windows resource files (.res files) to a .obj file.259  MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,260                                   ArrayRef<ObjFile *> objs);261 262  // Create export thunks for exported and patchable Arm64EC function symbols.263  void createECExportThunks();264  void maybeCreateECExportThunk(StringRef name, Symbol *&sym);265 266  bool ltoCompilationDone = false;267};268 269// Create enum with OPT_xxx values for each option in Options.td270enum {271  OPT_INVALID = 0,272#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),273#include "Options.inc"274#undef OPTION275};276 277} // namespace lld::coff278 279#endif280