diff options
Diffstat (limited to 'COFF/Driver.cpp')
| -rw-r--r-- | COFF/Driver.cpp | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp index 4cacf0ff552a..bb6a60e4fc4c 100644 --- a/COFF/Driver.cpp +++ b/COFF/Driver.cpp @@ -14,6 +14,7 @@ #include "SymbolTable.h" #include "Symbols.h" #include "Writer.h" +#include "lld/Driver/Driver.h" #include "llvm/ADT/Optional.h" #include "llvm/LibDriver/LibDriver.h" #include "llvm/Option/Arg.h" @@ -40,27 +41,28 @@ namespace coff { Configuration *Config; LinkerDriver *Driver; -void link(llvm::ArrayRef<const char *> Args) { +bool link(llvm::ArrayRef<const char *> Args) { Configuration C; LinkerDriver D; Config = &C; Driver = &D; - return Driver->link(Args); + Driver->link(Args); + return true; } -// Drop directory components and replace extension with ".exe". +// Drop directory components and replace extension with ".exe" or ".dll". static std::string getOutputPath(StringRef Path) { auto P = Path.find_last_of("\\/"); StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1); - return (S.substr(0, S.rfind('.')) + ".exe").str(); + const char* E = Config->DLL ? ".dll" : ".exe"; + return (S.substr(0, S.rfind('.')) + E).str(); } // Opens a file. Path has to be resolved already. // Newly created memory buffers are owned by this driver. MemoryBufferRef LinkerDriver::openFile(StringRef Path) { - auto MBOrErr = MemoryBuffer::getFile(Path); - error(MBOrErr, Twine("Could not open ") + Path); - std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; + std::unique_ptr<MemoryBuffer> MB = + check(MemoryBuffer::getFile(Path), "could not open " + Path); MemoryBufferRef MBRef = MB->getMemBufferRef(); OwningMBs.push_back(std::move(MB)); // take ownership return MBRef; @@ -116,12 +118,16 @@ void LinkerDriver::parseDirectives(StringRef S) { case OPT_nodefaultlib: Config->NoDefaultLibs.insert(doFindLib(Arg->getValue())); break; + case OPT_section: + parseSection(Arg->getValue()); + break; case OPT_editandcontinue: + case OPT_fastfail: case OPT_guardsym: case OPT_throwingnew: break; default: - error(Twine(Arg->getSpelling()) + " is not allowed in .drectve"); + fatal(Arg->getSpelling() + " is not allowed in .drectve"); } } } @@ -246,7 +252,7 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { // We call our own implementation of lib.exe that understands bitcode files. if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib")) { if (llvm::libDriverMain(ArgsArr.slice(1)) != 0) - error("lib failed"); + fatal("lib failed"); return; } @@ -268,7 +274,7 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { } if (Args.filtered_begin(OPT_INPUT) == Args.filtered_end()) - error("no input files."); + fatal("no input files"); // Construct search path list. SearchPaths.push_back(""); @@ -295,7 +301,7 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { // Handle /noentry if (Args.hasArg(OPT_noentry)) { if (!Args.hasArg(OPT_dll)) - error("/noentry must be specified with /dll"); + fatal("/noentry must be specified with /dll"); Config->NoEntry = true; } @@ -308,7 +314,7 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { // Handle /fixed if (Args.hasArg(OPT_fixed)) { if (Args.hasArg(OPT_dynamicbase)) - error("/fixed must not be specified with /dynamicbase"); + fatal("/fixed must not be specified with /dynamicbase"); Config->Relocatable = false; Config->DynamicBase = false; } @@ -382,17 +388,17 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { StringRef OptLevel = StringRef(S).substr(7); if (OptLevel.getAsInteger(10, Config->LTOOptLevel) || Config->LTOOptLevel > 3) - error("/opt:lldlto: invalid optimization level: " + OptLevel); + fatal("/opt:lldlto: invalid optimization level: " + OptLevel); continue; } if (StringRef(S).startswith("lldltojobs=")) { StringRef Jobs = StringRef(S).substr(11); if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0) - error("/opt:lldltojobs: invalid job count: " + Jobs); + fatal("/opt:lldltojobs: invalid job count: " + Jobs); continue; } if (S != "ref" && S != "lbr" && S != "nolbr") - error(Twine("/opt: unknown option: ") + S); + fatal("/opt: unknown option: " + S); } } @@ -404,6 +410,10 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { for (auto *Arg : Args.filtered(OPT_merge)) parseMerge(Arg->getValue()); + // Handle /section + for (auto *Arg : Args.filtered(OPT_section)) + parseSection(Arg->getValue()); + // Handle /manifest if (auto *Arg = Args.getLastArg(OPT_manifest_colon)) parseManifest(Arg->getValue()); @@ -420,6 +430,10 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { if (auto *Arg = Args.getLastArg(OPT_manifestfile)) Config->ManifestFile = Arg->getValue(); + // Handle /manifestinput + for (auto *Arg : Args.filtered(OPT_manifestinput)) + Config->ManifestInput.push_back(Arg->getValue()); + // Handle miscellaneous boolean flags. if (Args.hasArg(OPT_allowbind_no)) Config->AllowBind = false; @@ -485,7 +499,7 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { continue; } if (Config->Machine != MT) - error(Twine(File->getShortName()) + ": machine type " + machineToStr(MT) + + fatal(File->getShortName() + ": machine type " + machineToStr(MT) + " conflicts with " + machineToStr(Config->Machine)); } if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { @@ -520,7 +534,7 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { // infer that from user-defined entry name. StringRef S = findDefaultEntry(); if (S.empty()) - error("entry point must be defined"); + fatal("entry point must be defined"); Config->Entry = addUndefined(S); if (Config->Verbose) llvm::outs() << "Entry name inferred: " << S << "\n"; @@ -627,14 +641,14 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) { Config->Subsystem = inferSubsystem(); if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) - error("subsystem must be defined"); + fatal("subsystem must be defined"); } // Handle /safeseh. if (Args.hasArg(OPT_safeseh)) for (ObjectFile *File : Symtab.ObjectFiles) if (!File->SEHCompat) - error("/safeseh: " + File->getName() + " is not compatible with SEH"); + fatal("/safeseh: " + File->getName() + " is not compatible with SEH"); // Windows specific -- when we are creating a .dll file, we also // need to create a .lib file. @@ -668,7 +682,8 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) { if (auto *Arg = Args.getLastArg(OPT_lldmap)) { std::error_code EC; llvm::raw_fd_ostream Out(Arg->getValue(), EC, OpenFlags::F_Text); - error(EC, "Could not create the symbol map"); + if (EC) + fatal(EC, "could not create the symbol map"); Symtab.printMap(Out); } // Call exit to avoid calling destructors. |
