forked from OSchip/llvm-project
COFF: Create LinkerDriver class.
Previously the main linker routine is just a non-member function. We store some context information to the Config object. This patch makes it belong to Driver. llvm-svn: 238677
This commit is contained in:
parent
412c4dbbd9
commit
a9cbbf885f
|
@ -37,13 +37,6 @@ public:
|
|||
uint32_t MinorImageVersion = 0;
|
||||
uint32_t MajorOSVersion = 6;
|
||||
uint32_t MinorOSVersion = 0;
|
||||
|
||||
bool insertFile(llvm::StringRef Path) {
|
||||
return VisitedFiles.insert(Path.lower()).second;
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::string> VisitedFiles;
|
||||
};
|
||||
|
||||
extern Configuration *Config;
|
||||
|
|
|
@ -35,6 +35,15 @@ namespace lld {
|
|||
namespace coff {
|
||||
|
||||
Configuration *Config;
|
||||
LinkerDriver *Driver;
|
||||
|
||||
bool link(int Argc, const char *Argv[]) {
|
||||
auto C = make_unique<Configuration>();
|
||||
Config = C.get();
|
||||
auto D = make_unique<LinkerDriver>();
|
||||
Driver = D.get();
|
||||
return Driver->link(Argc, Argv);
|
||||
}
|
||||
|
||||
static std::string getOutputPath(llvm::opt::InputArgList *Args) {
|
||||
if (auto *Arg = Args->getLastArg(OPT_out))
|
||||
|
@ -68,12 +77,12 @@ public:
|
|||
|
||||
// Parses .drectve section contents and returns a list of files
|
||||
// specified by /defaultlib.
|
||||
std::error_code parseDirectives(StringRef S,
|
||||
std::vector<std::unique_ptr<InputFile>> *Res,
|
||||
StringAllocator *Alloc) {
|
||||
std::error_code
|
||||
LinkerDriver::parseDirectives(StringRef S,
|
||||
std::vector<std::unique_ptr<InputFile>> *Res) {
|
||||
SmallVector<const char *, 16> Tokens;
|
||||
Tokens.push_back("link"); // argv[0] value. Will be ignored.
|
||||
BumpPtrStringSaver Saver(Alloc);
|
||||
BumpPtrStringSaver Saver(&Alloc);
|
||||
llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
|
||||
Tokens.push_back(nullptr);
|
||||
int Argc = Tokens.size() - 1;
|
||||
|
@ -86,16 +95,15 @@ std::error_code parseDirectives(StringRef S,
|
|||
|
||||
for (auto *Arg : Args->filtered(OPT_defaultlib)) {
|
||||
std::string Path = findLib(Arg->getValue());
|
||||
if (!Config->insertFile(Path))
|
||||
if (!insertFile(Path))
|
||||
continue;
|
||||
Res->push_back(llvm::make_unique<ArchiveFile>(Path));
|
||||
}
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
bool link(int Argc, const char *Argv[]) {
|
||||
bool LinkerDriver::link(int Argc, const char *Argv[]) {
|
||||
// Parse command line options.
|
||||
Config = new Configuration();
|
||||
auto ArgsOrErr = parseArgs(Argc, Argv);
|
||||
if (auto EC = ArgsOrErr.getError()) {
|
||||
llvm::errs() << EC.message() << "\n";
|
||||
|
@ -180,7 +188,7 @@ bool link(int Argc, const char *Argv[]) {
|
|||
SymbolTable Symtab;
|
||||
for (auto *Arg : Args->filtered(OPT_INPUT)) {
|
||||
std::string Path = findFile(Arg->getValue());
|
||||
if (!Config->insertFile(Path))
|
||||
if (!insertFile(Path))
|
||||
continue;
|
||||
if (auto EC = Symtab.addFile(createFile(Path))) {
|
||||
llvm::errs() << Path << ": " << EC.message() << "\n";
|
||||
|
@ -229,5 +237,9 @@ bool link(int Argc, const char *Argv[]) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LinkerDriver::insertFile(StringRef Path) {
|
||||
return VisitedFiles.insert(Path.lower()).second;
|
||||
}
|
||||
|
||||
} // namespace coff
|
||||
} // namespace lld
|
||||
|
|
|
@ -16,23 +16,42 @@
|
|||
#include "llvm/Option/Arg.h"
|
||||
#include "llvm/Option/ArgList.h"
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <system_error>
|
||||
#include <vector>
|
||||
|
||||
namespace lld {
|
||||
namespace coff {
|
||||
|
||||
class LinkerDriver;
|
||||
extern LinkerDriver *Driver;
|
||||
|
||||
using llvm::COFF::MachineTypes;
|
||||
using llvm::COFF::WindowsSubsystem;
|
||||
class InputFile;
|
||||
|
||||
// Entry point of the COFF linker.
|
||||
bool link(int Argc, const char *Argv[]);
|
||||
|
||||
class LinkerDriver {
|
||||
public:
|
||||
bool link(int Argc, const char *Argv[]);
|
||||
|
||||
// Used by the resolver to parse .drectve section contents.
|
||||
std::error_code
|
||||
parseDirectives(StringRef S, std::vector<std::unique_ptr<InputFile>> *Res);
|
||||
|
||||
private:
|
||||
// Returns false if a given file has already been read.
|
||||
bool insertFile(StringRef Path);
|
||||
|
||||
std::set<std::string> VisitedFiles;
|
||||
StringAllocator Alloc;
|
||||
};
|
||||
|
||||
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
|
||||
parseArgs(int Argc, const char *Argv[]);
|
||||
|
||||
std::error_code parseDirectives(StringRef S,
|
||||
std::vector<std::unique_ptr<InputFile>> *Res,
|
||||
StringAllocator *Alloc);
|
||||
|
||||
// Functions below this line are defined in DriverUtils.cpp.
|
||||
|
||||
void printHelp(const char *Argv0);
|
||||
|
|
|
@ -49,7 +49,7 @@ std::error_code SymbolTable::addObject(ObjectFile *File) {
|
|||
StringRef Dir = File->getDirectives();
|
||||
if (!Dir.empty()) {
|
||||
std::vector<std::unique_ptr<InputFile>> Libs;
|
||||
if (auto EC = parseDirectives(Dir, &Libs, &StringAlloc))
|
||||
if (auto EC = Driver->parseDirectives(Dir, &Libs))
|
||||
return EC;
|
||||
for (std::unique_ptr<InputFile> &Lib : Libs)
|
||||
addFile(std::move(Lib));
|
||||
|
|
|
@ -78,7 +78,6 @@ private:
|
|||
std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
|
||||
std::vector<std::unique_ptr<SymbolBody>> OwningSymbols;
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
StringAllocator StringAlloc;
|
||||
};
|
||||
|
||||
} // namespace pecoff
|
||||
|
|
Loading…
Reference in New Issue