llvm-capstone/lld/COFF/Driver.h
Martin Storsjo 33d43ff851 [COFF] Look for libfoo.a if foo.lib is specified, for MinGW
This allows using #pragma comment(lib, "foo") in MinGW built code,
if built with -fms-extensions. (This works for system libraries and
static libraries only, as it doesn't try to look for .dll.a. As
ld.bfd doesn't support embedded defaultlib directives, this isn't
in widespread use among mingw users.)

Differential Revision: https://reviews.llvm.org/D53017

llvm-svn: 344124
2018-10-10 09:00:10 +00:00

198 lines
6.0 KiB
C++

//===- Driver.h -------------------------------------------------*- C++ -*-===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_COFF_DRIVER_H
#define LLD_COFF_DRIVER_H
#include "Config.h"
#include "SymbolTable.h"
#include "lld/Common/LLVM.h"
#include "lld/Common/Reproduce.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TarWriter.h"
#include <memory>
#include <set>
#include <vector>
namespace lld {
namespace coff {
class LinkerDriver;
extern LinkerDriver *Driver;
using llvm::COFF::MachineTypes;
using llvm::COFF::WindowsSubsystem;
using llvm::Optional;
class COFFOptTable : public llvm::opt::OptTable {
public:
COFFOptTable();
};
class ArgParser {
public:
// Concatenate LINK environment variable and given arguments and parse them.
llvm::opt::InputArgList parseLINK(std::vector<const char *> Args);
// Tokenizes a given string and then parses as command line options.
llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); }
// Tokenizes a given string and then parses as command line options in
// .drectve section. /EXPORT options are returned in second element
// to be processed in fastpath.
std::pair<llvm::opt::InputArgList, std::vector<StringRef>>
parseDirectives(StringRef S);
private:
// Parses command line options.
llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> Args);
std::vector<const char *> tokenize(StringRef S);
COFFOptTable Table;
};
class LinkerDriver {
public:
void link(llvm::ArrayRef<const char *> Args);
// Used by the resolver to parse .drectve section contents.
void parseDirectives(StringRef S);
// Used by ArchiveFile to enqueue members.
void enqueueArchiveMember(const Archive::Child &C, StringRef SymName,
StringRef ParentName);
MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
private:
std::unique_ptr<llvm::TarWriter> Tar; // for /linkrepro
// Opens a file. Path has to be resolved already.
MemoryBufferRef openFile(StringRef Path);
// Searches a file from search paths.
Optional<StringRef> findFile(StringRef Filename);
Optional<StringRef> findLib(StringRef Filename);
StringRef doFindFile(StringRef Filename);
StringRef doFindLib(StringRef Filename);
StringRef doFindLibMinGW(StringRef Filename);
// Parses LIB environment which contains a list of search paths.
void addLibSearchPaths();
// Library search path. The first element is always "" (current directory).
std::vector<StringRef> SearchPaths;
// We don't want to add the same file more than once.
// Files are uniquified by their filesystem and file number.
std::set<llvm::sys::fs::UniqueID> VisitedFiles;
std::set<std::string> VisitedLibs;
Symbol *addUndefined(StringRef Sym);
// Windows specific -- "main" is not the only main function in Windows.
// You can choose one from these four -- {w,}{WinMain,main}.
// There are four different entry point functions for them,
// {w,}{WinMain,main}CRTStartup, respectively. The linker needs to
// choose the right one depending on which "main" function is defined.
// This function looks up the symbol table and resolve corresponding
// entry point name.
StringRef findDefaultEntry();
WindowsSubsystem inferSubsystem();
void addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive);
void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
StringRef ParentName);
void enqueuePath(StringRef Path, bool WholeArchive);
void enqueueTask(std::function<void()> Task);
bool run();
std::list<std::function<void()>> TaskQueue;
std::vector<StringRef> FilePaths;
std::vector<MemoryBufferRef> Resources;
llvm::StringSet<> DirectivesExports;
};
// Functions below this line are defined in DriverUtils.cpp.
void printHelp(const char *Argv0);
// For /machine option.
MachineTypes getMachineType(StringRef Arg);
StringRef machineToStr(MachineTypes MT);
// Parses a string in the form of "<integer>[,<integer>]".
void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size = nullptr);
void parseGuard(StringRef Arg);
// Parses a string in the form of "<integer>[.<integer>]".
// Minor's default value is 0.
void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor);
// Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".
void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major,
uint32_t *Minor);
void parseAlternateName(StringRef);
void parseMerge(StringRef);
void parseSection(StringRef);
void parseAligncomm(StringRef);
// Parses a string in the form of "EMBED[,=<integer>]|NO".
void parseManifest(StringRef Arg);
// Parses a string in the form of "level=<string>|uiAccess=<string>"
void parseManifestUAC(StringRef Arg);
// Create a resource file containing a manifest XML.
std::unique_ptr<MemoryBuffer> createManifestRes();
void createSideBySideManifest();
// Used for dllexported symbols.
Export parseExport(StringRef Arg);
void fixupExports();
void assignExportOrdinals();
// Parses a string in the form of "key=value" and check
// if value matches previous values for the key.
// This feature used in the directive section to reject
// incompatible objects.
void checkFailIfMismatch(StringRef Arg);
// Convert Windows resource files (.res files) to a .obj file.
MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs);
void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
// Create enum with OPT_xxx values for each option in Options.td
enum {
OPT_INVALID = 0,
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
#include "Options.inc"
#undef OPTION
};
} // namespace coff
} // namespace lld
#endif