summaryrefslogtreecommitdiff
path: root/lib/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver')
-rw-r--r--lib/Driver/CMakeLists.txt21
-rw-r--r--lib/Driver/CoreDriver.cpp173
-rw-r--r--lib/Driver/CoreOptions.td15
-rw-r--r--lib/Driver/DarwinLdDriver.cpp387
-rw-r--r--lib/Driver/DarwinLdOptions.td35
-rw-r--r--lib/Driver/Driver.cpp142
-rw-r--r--lib/Driver/GnuLdDriver.cpp782
-rw-r--r--lib/Driver/GnuLdOptions.td378
-rw-r--r--lib/Driver/TODO.rst99
-rw-r--r--lib/Driver/UniversalDriver.cpp225
-rw-r--r--lib/Driver/UniversalDriverOptions.td19
11 files changed, 380 insertions, 1896 deletions
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index 840ccce50ab3..1bd1f2125816 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -1,19 +1,9 @@
-set(LLVM_TARGET_DEFINITIONS UniversalDriverOptions.td)
-tablegen(LLVM UniversalDriverOptions.inc -gen-opt-parser-defs)
-set(LLVM_TARGET_DEFINITIONS GnuLdOptions.td)
-tablegen(LLVM GnuLdOptions.inc -gen-opt-parser-defs)
-set(LLVM_TARGET_DEFINITIONS CoreOptions.td)
-tablegen(LLVM CoreOptions.inc -gen-opt-parser-defs)
set(LLVM_TARGET_DEFINITIONS DarwinLdOptions.td)
tablegen(LLVM DarwinLdOptions.inc -gen-opt-parser-defs)
add_public_tablegen_target(DriverOptionsTableGen)
add_lld_library(lldDriver
- CoreDriver.cpp
DarwinLdDriver.cpp
- Driver.cpp
- GnuLdDriver.cpp
- UniversalDriver.cpp
ADDITIONAL_HEADER_DIRS
${LLD_INCLUDE_DIR}/lld/Driver
@@ -21,16 +11,6 @@ add_lld_library(lldDriver
LINK_LIBS
lldConfig
lldMachO
- lldCOFF
- lldELF
- lldELF2
- lldAArch64ELFTarget
- lldARMELFTarget
- lldHexagonELFTarget
- lldMipsELFTarget
- lldX86ELFTarget
- lldExampleSubTarget
- lldX86_64ELFTarget
lldCore
lldReaderWriter
lldYAML
@@ -40,4 +20,3 @@ add_lld_library(lldDriver
)
add_dependencies(lldDriver DriverOptionsTableGen)
-
diff --git a/lib/Driver/CoreDriver.cpp b/lib/Driver/CoreDriver.cpp
deleted file mode 100644
index ce8648595109..000000000000
--- a/lib/Driver/CoreDriver.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-//===- lib/Driver/CoreDriver.cpp ------------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/Core/Reader.h"
-#include "lld/Driver/Driver.h"
-#include "lld/ReaderWriter/CoreLinkingContext.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lld;
-
-namespace {
-
-// Create enum with OPT_xxx values for each option in CoreOptions.td
-enum {
- OPT_INVALID = 0,
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, META) \
- OPT_##ID,
-#include "CoreOptions.inc"
-#undef OPTION
-};
-
-// Create prefix string literals used in CoreOptions.td
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "CoreOptions.inc"
-#undef PREFIX
-
-// Create table mapping all options defined in CoreOptions.td
-static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
-#include "CoreOptions.inc"
-#undef OPTION
-};
-
-// Create OptTable class for parsing actual command line arguments
-class CoreOptTable : public llvm::opt::OptTable {
-public:
- CoreOptTable() : OptTable(infoTable) {}
-};
-
-} // namespace anonymous
-
-
-namespace lld {
-
-static const Registry::KindStrings coreKindStrings[] = {
- { CoreLinkingContext::TEST_RELOC_CALL32, "call32" },
- { CoreLinkingContext::TEST_RELOC_PCREL32, "pcrel32" },
- { CoreLinkingContext::TEST_RELOC_GOT_LOAD32, "gotLoad32" },
- { CoreLinkingContext::TEST_RELOC_GOT_USE32, "gotUse32" },
- { CoreLinkingContext::TEST_RELOC_LEA32_WAS_GOT, "lea32wasGot" },
- LLD_KIND_STRING_END
-};
-
-bool CoreDriver::link(llvm::ArrayRef<const char *> args,
- raw_ostream &diagnostics) {
- CoreLinkingContext ctx;
-
- // Register possible input file parsers.
- ctx.registry().addSupportYamlFiles();
- ctx.registry().addKindTable(Reference::KindNamespace::testing,
- Reference::KindArch::all, coreKindStrings);
-
- if (!parse(args, ctx))
- return false;
- return Driver::link(ctx);
-}
-
-bool CoreDriver::parse(llvm::ArrayRef<const char *> args,
- CoreLinkingContext &ctx, raw_ostream &diagnostics) {
- // Parse command line options using CoreOptions.td
- CoreOptTable table;
- unsigned missingIndex;
- unsigned missingCount;
- llvm::opt::InputArgList parsedArgs =
- table.ParseArgs(args.slice(1), missingIndex, missingCount);
- if (missingCount) {
- diagnostics << "error: missing arg value for '"
- << parsedArgs.getArgString(missingIndex) << "' expected "
- << missingCount << " argument(s).\n";
- return false;
- }
-
- // Set default options
- ctx.setOutputPath("-");
- ctx.setDeadStripping(false);
- ctx.setGlobalsAreDeadStripRoots(false);
- ctx.setPrintRemainingUndefines(false);
- ctx.setAllowRemainingUndefines(true);
- ctx.setSearchArchivesToOverrideTentativeDefinitions(false);
-
- // Process all the arguments and create input files.
- for (auto inputArg : parsedArgs) {
- switch (inputArg->getOption().getID()) {
- case OPT_mllvm:
- ctx.appendLLVMOption(inputArg->getValue());
- break;
-
- case OPT_entry:
- ctx.setEntrySymbolName(inputArg->getValue());
- break;
-
- case OPT_output:
- ctx.setOutputPath(inputArg->getValue());
- break;
-
- case OPT_dead_strip:
- ctx.setDeadStripping(true);
- break;
-
- case OPT_keep_globals:
- ctx.setGlobalsAreDeadStripRoots(true);
- break;
-
- case OPT_undefines_are_errors:
- ctx.setPrintRemainingUndefines(true);
- ctx.setAllowRemainingUndefines(false);
- break;
-
- case OPT_commons_search_archives:
- ctx.setSearchArchivesToOverrideTentativeDefinitions(true);
- break;
-
- case OPT_add_pass:
- ctx.addPassNamed(inputArg->getValue());
- break;
-
- case OPT_INPUT: {
- std::vector<std::unique_ptr<File>> files
- = loadFile(ctx, inputArg->getValue(), false);
- for (std::unique_ptr<File> &file : files)
- ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
- break;
- }
-
- default:
- break;
- }
- }
-
- parseLLVMOptions(ctx);
-
- if (ctx.getNodes().empty()) {
- diagnostics << "No input files\n";
- return false;
- }
-
- // Validate the combination of options used.
- return ctx.validate(diagnostics);
-}
-
-} // namespace lld
diff --git a/lib/Driver/CoreOptions.td b/lib/Driver/CoreOptions.td
deleted file mode 100644
index df7cb41737d2..000000000000
--- a/lib/Driver/CoreOptions.td
+++ /dev/null
@@ -1,15 +0,0 @@
-include "llvm/Option/OptParser.td"
-
-def output : Separate<["-"], "o">;
-def entry : Separate<["-"], "e">;
-
-def dead_strip : Flag<["--"], "dead-strip">;
-def undefines_are_errors : Flag<["--"], "undefines-are-errors">;
-def keep_globals : Flag<["--"], "keep-globals">;
-def commons_search_archives : Flag<["--"], "commons-search-archives">;
-
-def add_pass : Separate<["--"], "add-pass">;
-
-def target : Separate<["-"], "target">, HelpText<"Target triple to link for">;
-def mllvm : Separate<["-"], "mllvm">, HelpText<"Options to pass to LLVM">;
-
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index 40fad74c9529..496b651bab4f 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -13,8 +13,11 @@
///
//===----------------------------------------------------------------------===//
-#include "lld/Core/File.h"
#include "lld/Core/ArchiveLibraryFile.h"
+#include "lld/Core/File.h"
+#include "lld/Core/Instrumentation.h"
+#include "lld/Core/PassManager.h"
+#include "lld/Core/Resolver.h"
#include "lld/Core/SharedLibraryFile.h"
#include "lld/Driver/Driver.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
@@ -25,17 +28,10 @@
#include "llvm/Option/Arg.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MachO.h"
-#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
using namespace lld;
@@ -72,6 +68,25 @@ public:
DarwinLdOptTable() : OptTable(infoTable) {}
};
+static std::vector<std::unique_ptr<File>>
+makeErrorFile(StringRef path, std::error_code ec) {
+ std::vector<std::unique_ptr<File>> result;
+ result.push_back(llvm::make_unique<ErrorFile>(path, ec));
+ return result;
+}
+
+static std::vector<std::unique_ptr<File>>
+parseMemberFiles(std::unique_ptr<File> file) {
+ std::vector<std::unique_ptr<File>> members;
+ if (auto *archive = dyn_cast<ArchiveLibraryFile>(file.get())) {
+ if (std::error_code ec = archive->parseAllMembers(members))
+ return makeErrorFile(file->path(), ec);
+ } else {
+ members.push_back(std::move(file));
+ }
+ return members;
+}
+
std::vector<std::unique_ptr<File>>
loadFile(MachOLinkingContext &ctx, StringRef path,
raw_ostream &diag, bool wholeArchive, bool upwardDylib) {
@@ -215,9 +230,9 @@ static std::error_code parseOrderFile(StringRef orderFilePath,
// In this variant, the path is to a text file which contains a partial path
// per line. The <dir> prefix is prepended to each partial path.
//
-static std::error_code loadFileList(StringRef fileListPath,
- MachOLinkingContext &ctx, bool forceLoad,
- raw_ostream &diagnostics) {
+static llvm::Error loadFileList(StringRef fileListPath,
+ MachOLinkingContext &ctx, bool forceLoad,
+ raw_ostream &diagnostics) {
// If there is a comma, split off <dir>.
std::pair<StringRef, StringRef> opt = fileListPath.split(',');
StringRef filePath = opt.first;
@@ -227,7 +242,7 @@ static std::error_code loadFileList(StringRef fileListPath,
ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
MemoryBuffer::getFileOrSTDIN(filePath);
if (std::error_code ec = mb.getError())
- return ec;
+ return llvm::errorCodeToError(ec);
StringRef buffer = mb->get()->getBuffer();
while (!buffer.empty()) {
// Split off each line in the file.
@@ -245,9 +260,9 @@ static std::error_code loadFileList(StringRef fileListPath,
path = ctx.copy(line);
}
if (!ctx.pathExists(path)) {
- return make_dynamic_error_code(Twine("File not found '")
- + path
- + "'");
+ return llvm::make_error<GenericError>(Twine("File not found '")
+ + path
+ + "'");
}
if (ctx.testingFileUsage()) {
diagnostics << "Found filelist entry " << canonicalizePath(path) << '\n';
@@ -255,7 +270,7 @@ static std::error_code loadFileList(StringRef fileListPath,
addFile(path, ctx, forceLoad, false, diagnostics);
buffer = lineAndRest.second;
}
- return std::error_code();
+ return llvm::Error();
}
/// Parse number assuming it is base 16, but allow 0x prefix.
@@ -265,20 +280,24 @@ static bool parseNumberBase16(StringRef numStr, uint64_t &baseAddress) {
return numStr.getAsInteger(16, baseAddress);
}
-namespace lld {
-
-bool DarwinLdDriver::linkMachO(llvm::ArrayRef<const char *> args,
- raw_ostream &diagnostics) {
- MachOLinkingContext ctx;
- if (!parse(args, ctx, diagnostics))
- return false;
- if (ctx.doNothing())
- return true;
- return link(ctx, diagnostics);
+static void parseLLVMOptions(const LinkingContext &ctx) {
+ // Honor -mllvm
+ if (!ctx.llvmOptions().empty()) {
+ unsigned numArgs = ctx.llvmOptions().size();
+ auto **args = new const char *[numArgs + 2];
+ args[0] = "lld (LLVM option parsing)";
+ for (unsigned i = 0; i != numArgs; ++i)
+ args[i + 1] = ctx.llvmOptions()[i];
+ args[numArgs + 1] = nullptr;
+ llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
+ }
}
-bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
- MachOLinkingContext &ctx, raw_ostream &diagnostics) {
+namespace lld {
+namespace mach_o {
+
+bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx,
+ raw_ostream &diagnostics) {
// Parse command line options using DarwinLdOptions.td
DarwinLdOptTable table;
unsigned missingIndex;
@@ -299,6 +318,7 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
// Figure out output kind ( -dylib, -r, -bundle, -preload, or -static )
llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE;
+ bool isStaticExecutable = false;
if (llvm::opt::Arg *kind = parsedArgs.getLastArg(
OPT_dylib, OPT_relocatable, OPT_bundle, OPT_static, OPT_preload)) {
switch (kind->getOption().getID()) {
@@ -313,6 +333,7 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
break;
case OPT_static:
fileType = llvm::MachO::MH_EXECUTE;
+ isStaticExecutable = true;
break;
case OPT_preload:
fileType = llvm::MachO::MH_PRELOAD;
@@ -350,7 +371,7 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
}
// Handle -macosx_version_min or -ios_version_min
- MachOLinkingContext::OS os = MachOLinkingContext::OS::macOSX;
+ MachOLinkingContext::OS os = MachOLinkingContext::OS::unknown;
uint32_t minOSVersion = 0;
if (llvm::opt::Arg *minOS =
parsedArgs.getLastArg(OPT_macosx_version_min, OPT_ios_version_min,
@@ -385,9 +406,16 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
// No min-os version on command line, check environment variables
}
+ // Handle export_dynamic
+ // FIXME: Should we warn when this applies to something other than a static
+ // executable or dylib? Those are the only cases where this has an effect.
+ // Note, this has to come before ctx.configure() so that we get the correct
+ // value for _globalsAreDeadStripRoots.
+ bool exportDynamicSymbols = parsedArgs.hasArg(OPT_export_dynamic);
+
// Now that there's enough information parsed in, let the linking context
// set up default values.
- ctx.configure(fileType, arch, os, minOSVersion);
+ ctx.configure(fileType, arch, os, minOSVersion, exportDynamicSymbols);
// Handle -e xxx
if (llvm::opt::Arg *entry = parsedArgs.getLastArg(OPT_entry))
@@ -673,6 +701,22 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
}
}
+ // Handle obsolete ObjC options: -objc_gc_compaction, -objc_gc, -objc_gc_only
+ if (parsedArgs.getLastArg(OPT_objc_gc_compaction)) {
+ diagnostics << "error: -objc_gc_compaction is not supported\n";
+ return false;
+ }
+
+ if (parsedArgs.getLastArg(OPT_objc_gc)) {
+ diagnostics << "error: -objc_gc is not supported\n";
+ return false;
+ }
+
+ if (parsedArgs.getLastArg(OPT_objc_gc_only)) {
+ diagnostics << "error: -objc_gc_only is not supported\n";
+ return false;
+ }
+
// Handle -pie or -no_pie
if (llvm::opt::Arg *pie = parsedArgs.getLastArg(OPT_pie, OPT_no_pie)) {
switch (ctx.outputMachOType()) {
@@ -719,6 +763,182 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
}
}
+ // Handle -version_load_command or -no_version_load_command
+ {
+ bool flagOn = false;
+ bool flagOff = false;
+ if (auto *arg = parsedArgs.getLastArg(OPT_version_load_command,
+ OPT_no_version_load_command)) {
+ flagOn = arg->getOption().getID() == OPT_version_load_command;
+ flagOff = arg->getOption().getID() == OPT_no_version_load_command;
+ }
+
+ // default to adding version load command for dynamic code,
+ // static code must opt-in
+ switch (ctx.outputMachOType()) {
+ case llvm::MachO::MH_OBJECT:
+ ctx.setGenerateVersionLoadCommand(false);
+ break;
+ case llvm::MachO::MH_EXECUTE:
+ // dynamic executables default to generating a version load command,
+ // while static exectuables only generate it if required.
+ if (isStaticExecutable) {
+ if (flagOn)
+ ctx.setGenerateVersionLoadCommand(true);
+ } else {
+ if (!flagOff)
+ ctx.setGenerateVersionLoadCommand(true);
+ }
+ break;
+ case llvm::MachO::MH_PRELOAD:
+ case llvm::MachO::MH_KEXT_BUNDLE:
+ if (flagOn)
+ ctx.setGenerateVersionLoadCommand(true);
+ break;
+ case llvm::MachO::MH_DYLINKER:
+ case llvm::MachO::MH_DYLIB:
+ case llvm::MachO::MH_BUNDLE:
+ if (!flagOff)
+ ctx.setGenerateVersionLoadCommand(true);
+ break;
+ case llvm::MachO::MH_FVMLIB:
+ case llvm::MachO::MH_DYLDLINK:
+ case llvm::MachO::MH_DYLIB_STUB:
+ case llvm::MachO::MH_DSYM:
+ // We don't generate load commands for these file types, even if
+ // forced on.
+ break;
+ }
+ }
+
+ // Handle -function_starts or -no_function_starts
+ {
+ bool flagOn = false;
+ bool flagOff = false;
+ if (auto *arg = parsedArgs.getLastArg(OPT_function_starts,
+ OPT_no_function_starts)) {
+ flagOn = arg->getOption().getID() == OPT_function_starts;
+ flagOff = arg->getOption().getID() == OPT_no_function_starts;
+ }
+
+ // default to adding functions start for dynamic code, static code must
+ // opt-in
+ switch (ctx.outputMachOType()) {
+ case llvm::MachO::MH_OBJECT:
+ ctx.setGenerateFunctionStartsLoadCommand(false);
+ break;
+ case llvm::MachO::MH_EXECUTE:
+ // dynamic executables default to generating a version load command,
+ // while static exectuables only generate it if required.
+ if (isStaticExecutable) {
+ if (flagOn)
+ ctx.setGenerateFunctionStartsLoadCommand(true);
+ } else {
+ if (!flagOff)
+ ctx.setGenerateFunctionStartsLoadCommand(true);
+ }
+ break;
+ case llvm::MachO::MH_PRELOAD:
+ case llvm::MachO::MH_KEXT_BUNDLE:
+ if (flagOn)
+ ctx.setGenerateFunctionStartsLoadCommand(true);
+ break;
+ case llvm::MachO::MH_DYLINKER:
+ case llvm::MachO::MH_DYLIB:
+ case llvm::MachO::MH_BUNDLE:
+ if (!flagOff)
+ ctx.setGenerateFunctionStartsLoadCommand(true);
+ break;
+ case llvm::MachO::MH_FVMLIB:
+ case llvm::MachO::MH_DYLDLINK:
+ case llvm::MachO::MH_DYLIB_STUB:
+ case llvm::MachO::MH_DSYM:
+ // We don't generate load commands for these file types, even if
+ // forced on.
+ break;
+ }
+ }
+
+ // Handle -data_in_code_info or -no_data_in_code_info
+ {
+ bool flagOn = false;
+ bool flagOff = false;
+ if (auto *arg = parsedArgs.getLastArg(OPT_data_in_code_info,
+ OPT_no_data_in_code_info)) {
+ flagOn = arg->getOption().getID() == OPT_data_in_code_info;
+ flagOff = arg->getOption().getID() == OPT_no_data_in_code_info;
+ }
+
+ // default to adding data in code for dynamic code, static code must
+ // opt-in
+ switch (ctx.outputMachOType()) {
+ case llvm::MachO::MH_OBJECT:
+ if (!flagOff)
+ ctx.setGenerateDataInCodeLoadCommand(true);
+ break;
+ case llvm::MachO::MH_EXECUTE:
+ // dynamic executables default to generating a version load command,
+ // while static exectuables only generate it if required.
+ if (isStaticExecutable) {
+ if (flagOn)
+ ctx.setGenerateDataInCodeLoadCommand(true);
+ } else {
+ if (!flagOff)
+ ctx.setGenerateDataInCodeLoadCommand(true);
+ }
+ break;
+ case llvm::MachO::MH_PRELOAD:
+ case llvm::MachO::MH_KEXT_BUNDLE:
+ if (flagOn)
+ ctx.setGenerateDataInCodeLoadCommand(true);
+ break;
+ case llvm::MachO::MH_DYLINKER:
+ case llvm::MachO::MH_DYLIB:
+ case llvm::MachO::MH_BUNDLE:
+ if (!flagOff)
+ ctx.setGenerateDataInCodeLoadCommand(true);
+ break;
+ case llvm::MachO::MH_FVMLIB:
+ case llvm::MachO::MH_DYLDLINK:
+ case llvm::MachO::MH_DYLIB_STUB:
+ case llvm::MachO::MH_DSYM:
+ // We don't generate load commands for these file types, even if
+ // forced on.
+ break;
+ }
+ }
+
+ // Handle sdk_version
+ if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_sdk_version)) {
+ uint32_t sdkVersion = 0;
+ if (MachOLinkingContext::parsePackedVersion(arg->getValue(),
+ sdkVersion)) {
+ diagnostics << "error: malformed sdkVersion value\n";
+ return false;
+ }
+ ctx.setSdkVersion(sdkVersion);
+ } else if (ctx.generateVersionLoadCommand()) {
+ // If we don't have an sdk version, but were going to emit a load command
+ // with min_version, then we need to give an warning as we have no sdk
+ // version to put in that command.
+ // FIXME: We need to decide whether to make this an error.
+ diagnostics << "warning: -sdk_version is required when emitting "
+ "min version load command. "
+ "Setting sdk version to match provided min version\n";
+ ctx.setSdkVersion(ctx.osMinVersion());
+ }
+
+ // Handle source_version
+ if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_source_version)) {
+ uint64_t version = 0;
+ if (MachOLinkingContext::parsePackedVersion(arg->getValue(),
+ version)) {
+ diagnostics << "error: malformed source_version value\n";
+ return false;
+ }
+ ctx.setSourceVersion(version);
+ }
+
// Handle stack_size
if (llvm::opt::Arg *stackSize = parsedArgs.getLastArg(OPT_stack_size)) {
uint64_t stackSizeVal;
@@ -794,6 +1014,10 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
ctx.setUndefinedMode(UndefMode);
}
+ // Handle -no_objc_category_merging.
+ if (parsedArgs.getLastArg(OPT_no_objc_category_merging))
+ ctx.setMergeObjCCategories(false);
+
// Handle -rpath <path>
if (parsedArgs.hasArg(OPT_rpath)) {
switch (ctx.outputMachOType()) {
@@ -829,7 +1053,7 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
// Handle input files and sectcreate.
for (auto &arg : parsedArgs) {
bool upward;
- ErrorOr<StringRef> resolvedPath = StringRef();
+ llvm::Optional<StringRef> resolvedPath;
switch (arg->getOption().getID()) {
default:
continue;
@@ -852,9 +1076,10 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
return false;
} else if (ctx.testingFileUsage()) {
diagnostics << "Found " << (upward ? "upward " : " ") << "library "
- << canonicalizePath(resolvedPath.get()) << '\n';
+ << canonicalizePath(resolvedPath.getValue()) << '\n';
}
- addFile(resolvedPath.get(), ctx, globalWholeArchive, upward, diagnostics);
+ addFile(resolvedPath.getValue(), ctx, globalWholeArchive,
+ upward, diagnostics);
break;
case OPT_framework:
case OPT_upward_framework:
@@ -866,17 +1091,20 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
return false;
} else if (ctx.testingFileUsage()) {
diagnostics << "Found " << (upward ? "upward " : " ") << "framework "
- << canonicalizePath(resolvedPath.get()) << '\n';
+ << canonicalizePath(resolvedPath.getValue()) << '\n';
}
- addFile(resolvedPath.get(), ctx, globalWholeArchive, upward, diagnostics);
+ addFile(resolvedPath.getValue(), ctx, globalWholeArchive,
+ upward, diagnostics);
break;
case OPT_filelist:
- if (std::error_code ec = loadFileList(arg->getValue(),
- ctx, globalWholeArchive,
- diagnostics)) {
- diagnostics << "error: " << ec.message()
- << ", processing '-filelist " << arg->getValue()
- << "'\n";
+ if (auto ec = loadFileList(arg->getValue(),
+ ctx, globalWholeArchive,
+ diagnostics)) {
+ handleAllErrors(std::move(ec), [&](const llvm::ErrorInfoBase &EI) {
+ diagnostics << "error: ";
+ EI.log(diagnostics);
+ diagnostics << ", processing '-filelist " << arg->getValue() << "'\n";
+ });
return false;
}
break;
@@ -908,5 +1136,80 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
return ctx.validate(diagnostics);
}
+/// This is where the link is actually performed.
+bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) {
+ MachOLinkingContext ctx;
+ if (!parse(args, ctx, diagnostics))
+ return false;
+ if (ctx.doNothing())
+ return true;
+ if (ctx.getNodes().empty())
+ return false;
+
+ for (std::unique_ptr<Node> &ie : ctx.getNodes())
+ if (FileNode *node = dyn_cast<FileNode>(ie.get()))
+ node->getFile()->parse();
+
+ std::vector<std::unique_ptr<File>> internalFiles;
+ ctx.createInternalFiles(internalFiles);
+ for (auto i = internalFiles.rbegin(), e = internalFiles.rend(); i != e; ++i) {
+ auto &members = ctx.getNodes();
+ members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
+ }
+
+ // Give target a chance to add files.
+ std::vector<std::unique_ptr<File>> implicitFiles;
+ ctx.createImplicitFiles(implicitFiles);
+ for (auto i = implicitFiles.rbegin(), e = implicitFiles.rend(); i != e; ++i) {
+ auto &members = ctx.getNodes();
+ members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
+ }
+
+ // Give target a chance to postprocess input files.
+ // Mach-O uses this chance to move all object files before library files.
+ ctx.finalizeInputFiles();
+ // Do core linking.
+ ScopedTask resolveTask(getDefaultDomain(), "Resolve");
+ Resolver resolver(ctx);
+ if (!resolver.resolve())
+ return false;
+ SimpleFile *merged = nullptr;
+ {
+ std::unique_ptr<SimpleFile> mergedFile = resolver.resultFile();
+ merged = mergedFile.get();
+ auto &members = ctx.getNodes();
+ members.insert(members.begin(),
+ llvm::make_unique<FileNode>(std::move(mergedFile)));
+ }
+ resolveTask.end();
+
+ // Run passes on linked atoms.
+ ScopedTask passTask(getDefaultDomain(), "Passes");
+ PassManager pm;
+ ctx.addPasses(pm);
+ if (auto ec = pm.runOnFile(*merged)) {
+ // FIXME: This should be passed to logAllUnhandledErrors but it needs
+ // to be passed a Twine instead of a string.
+ diagnostics << "Failed to run passes on file '" << ctx.outputPath()
+ << "': ";
+ logAllUnhandledErrors(std::move(ec), diagnostics, std::string());
+ return false;
+ }
+
+ passTask.end();
+
+ // Give linked atoms to Writer to generate output file.
+ ScopedTask writeTask(getDefaultDomain(), "Write");
+ if (auto ec = ctx.writeFile(*merged)) {
+ // FIXME: This should be passed to logAllUnhandledErrors but it needs
+ // to be passed a Twine instead of a string.
+ diagnostics << "Failed to write file '" << ctx.outputPath() << "': ";
+ logAllUnhandledErrors(std::move(ec), diagnostics, std::string());
+ return false;
+ }
+
+ return true;
+}
+} // namespace mach_o
} // namespace lld
diff --git a/lib/Driver/DarwinLdOptions.td b/lib/Driver/DarwinLdOptions.td
index cbf6ac1d4a4b..fa07f33646e7 100644
--- a/lib/Driver/DarwinLdOptions.td
+++ b/lib/Driver/DarwinLdOptions.td
@@ -33,6 +33,28 @@ def iphoneos_version_min : Separate<["-"], "iphoneos_version_min">,
def ios_simulator_version_min : Separate<["-"], "ios_simulator_version_min">,
MetaVarName<"<version>">,
HelpText<"Minimum iOS simulator version">, Group<grp_opts>;
+def sdk_version : Separate<["-"], "sdk_version">,
+ MetaVarName<"<version>">,
+ HelpText<"SDK version">, Group<grp_opts>;
+def source_version : Separate<["-"], "source_version">,
+ MetaVarName<"<version>">,
+ HelpText<"Source version">, Group<grp_opts>;
+def version_load_command : Flag<["-"], "version_load_command">,
+ HelpText<"Force generation of a version load command">, Group<grp_opts>;
+def no_version_load_command : Flag<["-"], "no_version_load_command">,
+ HelpText<"Disable generation of a version load command">, Group<grp_opts>;
+def function_starts : Flag<["-"], "function_starts">,
+ HelpText<"Force generation of a function starts load command">,
+ Group<grp_opts>;
+def no_function_starts : Flag<["-"], "no_function_starts">,
+ HelpText<"Disable generation of a function starts load command">,
+ Group<grp_opts>;
+def data_in_code_info : Flag<["-"], "data_in_code_info">,
+ HelpText<"Force generation of a data in code load command">,
+ Group<grp_opts>;
+def no_data_in_code_info : Flag<["-"], "no_data_in_code_info">,
+ HelpText<"Disable generation of a data in code load command">,
+ Group<grp_opts>;
def mllvm : Separate<["-"], "mllvm">,
MetaVarName<"<option>">,
HelpText<"Options to pass to LLVM during LTO">, Group<grp_opts>;
@@ -68,6 +90,10 @@ def undefined : Separate<["-"], "undefined">,
MetaVarName<"<undefined>">,
HelpText<"Determines how undefined symbols are handled.">,
Group<grp_opts>;
+def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">,
+ HelpText<"Disables the optimisation which merges Objective-C categories "
+ "on a class in to the class itself.">,
+ Group<grp_opts>;
// main executable options
def grp_main : OptionGroup<"opts">, HelpText<"MAIN EXECUTABLE OPTIONS">;
@@ -84,6 +110,9 @@ def stack_size : Separate<["-"], "stack_size">,
HelpText<"Specifies the maximum stack size for the main thread in a program. "
"Must be a page-size multiple. (default=8Mb)">,
Group<grp_main>;
+def export_dynamic : Flag<["-"], "export_dynamic">,
+ HelpText<"Preserves all global symbols in main executables during LTO">,
+ Group<grp_main>;
// dylib executable options
def grp_dylib : OptionGroup<"opts">, HelpText<"DYLIB EXECUTABLE OPTIONS">;
@@ -205,3 +234,9 @@ def single_module : Flag<["-"], "single_module">,
HelpText<"Default for dylibs">, Group<grp_obsolete>;
def multi_module : Flag<["-"], "multi_module">,
HelpText<"Unsupported way to build dylibs">, Group<grp_obsolete>;
+def objc_gc_compaction : Flag<["-"], "objc_gc_compaction">,
+ HelpText<"Unsupported ObjC GC option">, Group<grp_obsolete>;
+def objc_gc : Flag<["-"], "objc_gc">,
+ HelpText<"Unsupported ObjC GC option">, Group<grp_obsolete>;
+def objc_gc_only : Flag<["-"], "objc_gc_only">,
+ HelpText<"Unsupported ObjC GC option">, Group<grp_obsolete>;
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
deleted file mode 100644
index 6a7a26b3b0f6..000000000000
--- a/lib/Driver/Driver.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-//===- lib/Driver/Driver.cpp - Linker Driver Emulator -----------*- C++ -*-===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/Core/ArchiveLibraryFile.h"
-#include "lld/Core/File.h"
-#include "lld/Core/Instrumentation.h"
-#include "lld/Core/LLVM.h"
-#include "lld/Core/Parallel.h"
-#include "lld/Core/PassManager.h"
-#include "lld/Core/Reader.h"
-#include "lld/Core/Resolver.h"
-#include "lld/Core/Writer.h"
-#include "lld/Driver/Driver.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/raw_ostream.h"
-#include <mutex>
-
-namespace lld {
-
-FileVector makeErrorFile(StringRef path, std::error_code ec) {
- std::vector<std::unique_ptr<File>> result;
- result.push_back(llvm::make_unique<ErrorFile>(path, ec));
- return result;
-}
-
-FileVector parseMemberFiles(std::unique_ptr<File> file) {
- std::vector<std::unique_ptr<File>> members;
- if (auto *archive = dyn_cast<ArchiveLibraryFile>(file.get())) {
- if (std::error_code ec = archive->parseAllMembers(members))
- return makeErrorFile(file->path(), ec);
- } else {
- members.push_back(std::move(file));
- }
- return members;
-}
-
-FileVector loadFile(LinkingContext &ctx, StringRef path, bool wholeArchive) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> mb
- = MemoryBuffer::getFileOrSTDIN(path);
- if (std::error_code ec = mb.getError())
- return makeErrorFile(path, ec);
- ErrorOr<std::unique_ptr<File>> fileOrErr =
- ctx.registry().loadFile(std::move(mb.get()));
- if (std::error_code ec = fileOrErr.getError())
- return makeErrorFile(path, ec);
- std::unique_ptr<File> &file = fileOrErr.get();
- if (wholeArchive)
- return parseMemberFiles(std::move(file));
- std::vector<std::unique_ptr<File>> files;
- files.push_back(std::move(file));
- return files;
-}
-
-void Driver::parseLLVMOptions(const LinkingContext &ctx) {
- // Honor -mllvm
- if (!ctx.llvmOptions().empty()) {
- unsigned numArgs = ctx.llvmOptions().size();
- auto **args = new const char *[numArgs + 2];
- args[0] = "lld (LLVM option parsing)";
- for (unsigned i = 0; i != numArgs; ++i)
- args[i + 1] = ctx.llvmOptions()[i];
- args[numArgs + 1] = nullptr;
- llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
- }
-}
-
-/// This is where the link is actually performed.
-bool Driver::link(LinkingContext &ctx, raw_ostream &diagnostics) {
- if (ctx.getNodes().empty())
- return false;
-
- for (std::unique_ptr<Node> &ie : ctx.getNodes())
- if (FileNode *node = dyn_cast<FileNode>(ie.get()))
- ctx.getTaskGroup().spawn([node] { node->getFile()->parse(); });
-
- std::vector<std::unique_ptr<File>> internalFiles;
- ctx.createInternalFiles(internalFiles);
- for (auto i = internalFiles.rbegin(), e = internalFiles.rend(); i != e; ++i) {
- auto &members = ctx.getNodes();
- members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
- }
-
- // Give target a chance to add files.
- std::vector<std::unique_ptr<File>> implicitFiles;
- ctx.createImplicitFiles(implicitFiles);
- for (auto i = implicitFiles.rbegin(), e = implicitFiles.rend(); i != e; ++i) {
- auto &members = ctx.getNodes();
- members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
- }
-
- // Give target a chance to postprocess input files.
- // Mach-O uses this chance to move all object files before library files.
- // ELF adds specific undefined symbols resolver.
- ctx.finalizeInputFiles();
-
- // Do core linking.
- ScopedTask resolveTask(getDefaultDomain(), "Resolve");
- Resolver resolver(ctx);
- if (!resolver.resolve()) {
- ctx.getTaskGroup().sync();
- return false;
- }
- std::unique_ptr<SimpleFile> merged = resolver.resultFile();
- resolveTask.end();
-
- // Run passes on linked atoms.
- ScopedTask passTask(getDefaultDomain(), "Passes");
- PassManager pm;
- ctx.addPasses(pm);
- if (std::error_code ec = pm.runOnFile(*merged)) {
- diagnostics << "Failed to write file '" << ctx.outputPath()
- << "': " << ec.message() << "\n";
- return false;
- }
-
- passTask.end();
-
- // Give linked atoms to Writer to generate output file.
- ScopedTask writeTask(getDefaultDomain(), "Write");
- if (std::error_code ec = ctx.writeFile(*merged)) {
- diagnostics << "Failed to write file '" << ctx.outputPath()
- << "': " << ec.message() << "\n";
- return false;
- }
-
- return true;
-}
-
-} // namespace lld
diff --git a/lib/Driver/GnuLdDriver.cpp b/lib/Driver/GnuLdDriver.cpp
deleted file mode 100644
index 1cff481dd8d7..000000000000
--- a/lib/Driver/GnuLdDriver.cpp
+++ /dev/null
@@ -1,782 +0,0 @@
-//===- lib/Driver/GnuLdDriver.cpp -----------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-///
-/// Concrete instance of the Driver for GNU's ld.
-///
-//===----------------------------------------------------------------------===//
-
-#include "lld/Driver/Driver.h"
-#include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "lld/ReaderWriter/LinkerScript.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
-#include "llvm/Support/StringSaver.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstring>
-#include <tuple>
-
-using namespace lld;
-
-using llvm::BumpPtrAllocator;
-
-namespace {
-
-// Create enum with OPT_xxx values for each option in GnuLdOptions.td
-enum {
- OPT_INVALID = 0,
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, META) \
- OPT_##ID,
-#include "GnuLdOptions.inc"
-#undef OPTION
-};
-
-// Create prefix string literals used in GnuLdOptions.td
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "GnuLdOptions.inc"
-#undef PREFIX
-
-// Create table mapping all options defined in GnuLdOptions.td
-static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
-#include "GnuLdOptions.inc"
-#undef OPTION
-};
-
-
-// Create OptTable class for parsing actual command line arguments
-class GnuLdOptTable : public llvm::opt::OptTable {
-public:
- GnuLdOptTable() : OptTable(infoTable){}
-};
-
-} // anonymous namespace
-
-// If a command line option starts with "@", the driver reads its suffix as a
-// file, parse its contents as a list of command line options, and insert them
-// at the original @file position. If file cannot be read, @file is not expanded
-// and left unmodified. @file can appear in a response file, so it's a recursive
-// process.
-static llvm::ArrayRef<const char *>
-maybeExpandResponseFiles(llvm::ArrayRef<const char *> args,
- BumpPtrAllocator &alloc) {
- // Expand response files.
- SmallVector<const char *, 256> smallvec;
- for (const char *arg : args)
- smallvec.push_back(arg);
- llvm::StringSaver saver(alloc);
- llvm::cl::ExpandResponseFiles(saver, llvm::cl::TokenizeGNUCommandLine, smallvec);
-
- // Pack the results to a C-array and return it.
- const char **copy = alloc.Allocate<const char *>(smallvec.size() + 1);
- std::copy(smallvec.begin(), smallvec.end(), copy);
- copy[smallvec.size()] = nullptr;
- return llvm::makeArrayRef(copy, smallvec.size() + 1);
-}
-
-// Parses an argument of --defsym=<sym>=<number>
-static bool parseDefsymAsAbsolute(StringRef opt, StringRef &sym,
- uint64_t &addr) {
- size_t equalPos = opt.find('=');
- if (equalPos == 0 || equalPos == StringRef::npos)
- return false;
- sym = opt.substr(0, equalPos);
- if (opt.substr(equalPos + 1).getAsInteger(0, addr))
- return false;
- return true;
-}
-
-// Parses an argument of --defsym=<sym>=<sym>
-static bool parseDefsymAsAlias(StringRef opt, StringRef &sym,
- StringRef &target) {
- size_t equalPos = opt.find('=');
- if (equalPos == 0 || equalPos == StringRef::npos)
- return false;
- sym = opt.substr(0, equalPos);
- target = opt.substr(equalPos + 1);
- return !target.empty();
-}
-
-// Parses -z max-page-size=<value>
-static bool parseMaxPageSize(StringRef opt, uint64_t &val) {
- size_t equalPos = opt.find('=');
- if (equalPos == 0 || equalPos == StringRef::npos)
- return false;
- StringRef value = opt.substr(equalPos + 1);
- val = 0;
- if (value.getAsInteger(0, val) || !val)
- return false;
- return true;
-}
-
-bool GnuLdDriver::linkELF(llvm::ArrayRef<const char *> args,
- raw_ostream &diag) {
- BumpPtrAllocator alloc;
- args = maybeExpandResponseFiles(args, alloc);
- std::unique_ptr<ELFLinkingContext> options;
- if (!parse(args, options, diag))
- return false;
- if (!options)
- return true;
- bool linked = link(*options, diag);
-
- // Handle --stats.
- if (options->collectStats()) {
- llvm::TimeRecord t = llvm::TimeRecord::getCurrentTime(true);
- diag << "total time in link " << t.getProcessTime() << "\n";
- diag << "data size " << t.getMemUsed() << "\n";
- }
- return linked;
-}
-
-static llvm::Optional<llvm::Triple::ArchType>
-getArchType(const llvm::Triple &triple, StringRef value) {
- switch (triple.getArch()) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- if (value == "elf_i386")
- return llvm::Triple::x86;
- if (value == "elf_x86_64")
- return llvm::Triple::x86_64;
- return llvm::None;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- return llvm::StringSwitch<llvm::Optional<llvm::Triple::ArchType>>(value)
- .Cases("elf32btsmip", "elf32btsmipn32", llvm::Triple::mips)
- .Cases("elf32ltsmip", "elf32ltsmipn32", llvm::Triple::mipsel)
- .Case("elf64btsmip", llvm::Triple::mips64)
- .Case("elf64ltsmip", llvm::Triple::mips64el)
- .Default(llvm::None);
- case llvm::Triple::aarch64:
- if (value == "aarch64linux")
- return llvm::Triple::aarch64;
- return llvm::None;
- case llvm::Triple::arm:
- if (value == "armelf_linux_eabi")
- return llvm::Triple::arm;
- return llvm::None;
- default:
- return llvm::None;
- }
-}
-
-static bool isLinkerScript(StringRef path, raw_ostream &diag) {
- llvm::sys::fs::file_magic magic = llvm::sys::fs::file_magic::unknown;
- if (std::error_code ec = llvm::sys::fs::identify_magic(path, magic)) {
- diag << "unknown input file format: " << path << ": "
- << ec.message() << "\n";
- return false;
- }
- return magic == llvm::sys::fs::file_magic::unknown;
-}
-
-static ErrorOr<StringRef>
-findFile(ELFLinkingContext &ctx, StringRef path, bool dashL) {
- // If the path was referred to by using a -l argument, let's search
- // for the file in the search path.
- if (dashL) {
- ErrorOr<StringRef> pathOrErr = ctx.searchLibrary(path);
- if (std::error_code ec = pathOrErr.getError())
- return make_dynamic_error_code(
- Twine("Unable to find library -l") + path + ": " + ec.message());
- path = pathOrErr.get();
- }
- if (!llvm::sys::fs::exists(path))
- return make_dynamic_error_code(
- Twine("lld: cannot find file ") + path);
- return path;
-}
-
-static bool isPathUnderSysroot(StringRef sysroot, StringRef path) {
- if (sysroot.empty())
- return false;
- while (!path.empty() && !llvm::sys::fs::equivalent(sysroot, path))
- path = llvm::sys::path::parent_path(path);
- return !path.empty();
-}
-
-static std::error_code
-addFilesFromLinkerScript(ELFLinkingContext &ctx, StringRef scriptPath,
- const std::vector<script::Path> &inputPaths,
- raw_ostream &diag) {
- bool sysroot = (!ctx.getSysroot().empty()
- && isPathUnderSysroot(ctx.getSysroot(), scriptPath));
- for (const script::Path &path : inputPaths) {
- ErrorOr<StringRef> pathOrErr = path._isDashlPrefix
- ? ctx.searchLibrary(path._path) : ctx.searchFile(path._path, sysroot);
- if (std::error_code ec = pathOrErr.getError()) {
- auto file = llvm::make_unique<ErrorFile>(path._path, ec);
- ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
- continue;
- }
-
- std::vector<std::unique_ptr<File>> files
- = loadFile(ctx, pathOrErr.get(), false);
- for (std::unique_ptr<File> &file : files) {
- if (ctx.logInputFiles())
- diag << file->path() << "\n";
- ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
- }
- }
- return std::error_code();
-}
-
-std::error_code GnuLdDriver::evalLinkerScript(ELFLinkingContext &ctx,
- std::unique_ptr<MemoryBuffer> mb,
- raw_ostream &diag,
- bool nostdlib) {
- // Read the script file from disk and parse.
- StringRef path = mb->getBufferIdentifier();
- auto parser = llvm::make_unique<script::Parser>(std::move(mb));
- if (std::error_code ec = parser->parse())
- return ec;
- script::LinkerScript *script = parser->get();
- if (!script)
- return LinkerScriptReaderError::parse_error;
- // Evaluate script commands.
- // Currently we only recognize this subset of linker script commands.
- for (const script::Command *c : script->_commands) {
- if (auto *input = dyn_cast<script::Input>(c))
- if (std::error_code ec = addFilesFromLinkerScript(
- ctx, path, input->getPaths(), diag))
- return ec;
- if (auto *group = dyn_cast<script::Group>(c)) {
- int origSize = ctx.getNodes().size();
- if (std::error_code ec = addFilesFromLinkerScript(
- ctx, path, group->getPaths(), diag))
- return ec;
- size_t groupSize = ctx.getNodes().size() - origSize;
- ctx.getNodes().push_back(llvm::make_unique<GroupEnd>(groupSize));
- }
- if (auto *searchDir = dyn_cast<script::SearchDir>(c))
- if (!nostdlib)
- ctx.addSearchPath(searchDir->getSearchPath());
- if (auto *entry = dyn_cast<script::Entry>(c))
- ctx.setEntrySymbolName(entry->getEntryName());
- if (auto *output = dyn_cast<script::Output>(c))
- ctx.setOutputPath(output->getOutputFileName());
- if (auto *externs = dyn_cast<script::Extern>(c)) {
- for (auto symbol : *externs) {
- ctx.addInitialUndefinedSymbol(symbol);
- }
- }
- }
- // Transfer ownership of the script to the linking context
- ctx.linkerScriptSema().addLinkerScript(std::move(parser));
- return std::error_code();
-}
-
-bool GnuLdDriver::applyEmulation(llvm::Triple &triple,
- llvm::opt::InputArgList &args,
- raw_ostream &diag) {
- llvm::opt::Arg *arg = args.getLastArg(OPT_m);
- if (!arg)
- return true;
- llvm::Optional<llvm::Triple::ArchType> arch =
- getArchType(triple, arg->getValue());
- if (!arch) {
- diag << "error: unsupported emulation '" << arg->getValue() << "'.\n";
- return false;
- }
- triple.setArch(*arch);
- return true;
-}
-
-void GnuLdDriver::addPlatformSearchDirs(ELFLinkingContext &ctx,
- llvm::Triple &triple,
- llvm::Triple &baseTriple) {
- if (triple.getOS() == llvm::Triple::NetBSD &&
- triple.getArch() == llvm::Triple::x86 &&
- baseTriple.getArch() == llvm::Triple::x86_64) {
- ctx.addSearchPath("=/usr/lib/i386");
- return;
- }
- ctx.addSearchPath("=/usr/lib");
-}
-
-std::unique_ptr<ELFLinkingContext>
-GnuLdDriver::createELFLinkingContext(llvm::Triple triple) {
- std::unique_ptr<ELFLinkingContext> p;
- if ((p = elf::createAArch64LinkingContext(triple))) return p;
- if ((p = elf::createARMLinkingContext(triple))) return p;
- if ((p = elf::createExampleLinkingContext(triple))) return p;
- if ((p = elf::createHexagonLinkingContext(triple))) return p;
- if ((p = elf::createMipsLinkingContext(triple))) return p;
- if ((p = elf::createX86LinkingContext(triple))) return p;
- if ((p = elf::createX86_64LinkingContext(triple))) return p;
- return nullptr;
-}
-
-static llvm::Optional<bool>
-getBool(const llvm::opt::InputArgList &parsedArgs,
- unsigned yesFlag, unsigned noFlag) {
- if (auto *arg = parsedArgs.getLastArg(yesFlag, noFlag))
- return arg->getOption().getID() == yesFlag;
- return llvm::None;
-}
-
-bool GnuLdDriver::parse(llvm::ArrayRef<const char *> args,
- std::unique_ptr<ELFLinkingContext> &context,
- raw_ostream &diag) {
- // Parse command line options using GnuLdOptions.td
- GnuLdOptTable table;
- unsigned missingIndex;
- unsigned missingCount;
-
- llvm::opt::InputArgList parsedArgs =
- table.ParseArgs(args.slice(1), missingIndex, missingCount);
- if (missingCount) {
- diag << "error: missing arg value for '"
- << parsedArgs.getArgString(missingIndex) << "' expected "
- << missingCount << " argument(s).\n";
- return false;
- }
-
- // Handle --help
- if (parsedArgs.hasArg(OPT_help)) {
- table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
- return true;
- }
-
- // Use -target or use default target triple to instantiate LinkingContext
- llvm::Triple baseTriple;
- if (auto *arg = parsedArgs.getLastArg(OPT_target)) {
- baseTriple = llvm::Triple(arg->getValue());
- } else {
- baseTriple = getDefaultTarget(args[0]);
- }
- llvm::Triple triple(baseTriple);
-
- if (!applyEmulation(triple, parsedArgs, diag))
- return false;
-
- std::unique_ptr<ELFLinkingContext> ctx(createELFLinkingContext(triple));
-
- if (!ctx) {
- diag << "unknown target triple\n";
- return false;
- }
-
- // Copy mllvm
- for (auto *arg : parsedArgs.filtered(OPT_mllvm))
- ctx->appendLLVMOption(arg->getValue());
-
- // Ignore unknown arguments.
- for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN))
- diag << "warning: ignoring unknown argument: "
- << unknownArg->getValue() << "\n";
-
- // Set sys root path.
- if (auto *arg = parsedArgs.getLastArg(OPT_sysroot))
- ctx->setSysroot(arg->getValue());
-
- // Handle --demangle option(For compatibility)
- if (parsedArgs.hasArg(OPT_demangle))
- ctx->setDemangleSymbols(true);
-
- // Handle --no-demangle option.
- if (parsedArgs.hasArg(OPT_no_demangle))
- ctx->setDemangleSymbols(false);
-
- // Figure out output kind (-r, -static, -shared)
- if (parsedArgs.hasArg(OPT_relocatable)) {
- ctx->setOutputELFType(llvm::ELF::ET_REL);
- ctx->setPrintRemainingUndefines(false);
- ctx->setAllowRemainingUndefines(true);
- }
-
- if (parsedArgs.hasArg(OPT_static)) {
- ctx->setOutputELFType(llvm::ELF::ET_EXEC);
- ctx->setIsStaticExecutable(true);
- }
-
- if (parsedArgs.hasArg(OPT_shared)) {
- ctx->setOutputELFType(llvm::ELF::ET_DYN);
- ctx->setAllowShlibUndefines(true);
- ctx->setUseShlibUndefines(false);
- ctx->setPrintRemainingUndefines(false);
- ctx->setAllowRemainingUndefines(true);
- }
-
- // Handle --stats.
- if (parsedArgs.hasArg(OPT_stats)) {
- ctx->setCollectStats(true);
- }
-
- // Figure out if the output type is nmagic/omagic
- if (auto *arg =
- parsedArgs.getLastArg(OPT_nmagic, OPT_omagic, OPT_no_omagic)) {
- switch (arg->getOption().getID()) {
- case OPT_nmagic:
- ctx->setOutputMagic(ELFLinkingContext::OutputMagic::NMAGIC);
- ctx->setIsStaticExecutable(true);
- break;
- case OPT_omagic:
- ctx->setOutputMagic(ELFLinkingContext::OutputMagic::OMAGIC);
- ctx->setIsStaticExecutable(true);
- break;
- case OPT_no_omagic:
- ctx->setOutputMagic(ELFLinkingContext::OutputMagic::DEFAULT);
- ctx->setNoAllowDynamicLibraries();
- break;
- }
- }
-
- if (parsedArgs.hasArg(OPT_discard_loc))
- ctx->setDiscardLocals(true);
-
- if (parsedArgs.hasArg(OPT_discard_temp_loc))
- ctx->setDiscardTempLocals(true);
-
- if (parsedArgs.hasArg(OPT_strip_all))
- ctx->setStripSymbols(true);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_soname))
- ctx->setSharedObjectName(arg->getValue());
-
- if (parsedArgs.hasArg(OPT_rosegment))
- ctx->setCreateSeparateROSegment();
-
- if (parsedArgs.hasArg(OPT_no_align_segments))
- ctx->setAlignSegments(false);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_image_base)) {
- uint64_t baseAddress = 0;
- StringRef inputValue = arg->getValue();
- if (inputValue.getAsInteger(0, baseAddress) || !baseAddress) {
- diag << "invalid value for image base " << inputValue << "\n";
- return false;
- }
- ctx->setBaseAddress(baseAddress);
- }
-
- if (parsedArgs.hasArg(OPT_merge_strings))
- ctx->setMergeCommonStrings(true);
-
- if (parsedArgs.hasArg(OPT_t))
- ctx->setLogInputFiles(true);
-
- if (parsedArgs.hasArg(OPT_use_shlib_undefs))
- ctx->setUseShlibUndefines(true);
-
- if (auto val = getBool(parsedArgs, OPT_allow_shlib_undefs,
- OPT_no_allow_shlib_undefs))
- ctx->setAllowShlibUndefines(*val);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_e))
- ctx->setEntrySymbolName(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_output))
- ctx->setOutputPath(arg->getValue());
-
- if (parsedArgs.hasArg(OPT_noinhibit_exec))
- ctx->setAllowRemainingUndefines(true);
-
- if (auto val = getBool(parsedArgs, OPT_export_dynamic, OPT_no_export_dynamic))
- ctx->setExportDynamic(*val);
-
- if (parsedArgs.hasArg(OPT_allow_multiple_definition))
- ctx->setAllowDuplicates(true);
-
- if (auto *arg = parsedArgs.getLastArg(OPT_dynamic_linker))
- ctx->setInterpreter(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_init))
- ctx->setInitFunction(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_fini))
- ctx->setFiniFunction(arg->getValue());
-
- if (auto *arg = parsedArgs.getLastArg(OPT_output_filetype))
- ctx->setOutputFileType(arg->getValue());
-
- // Process ELF/ARM specific options
- bool hasArmTarget1Rel = parsedArgs.hasArg(OPT_target1_rel);
- bool hasArmTarget1Abs = parsedArgs.hasArg(OPT_target1_abs);
- if (triple.getArch() == llvm::Triple::arm) {
- if (hasArmTarget1Rel && hasArmTarget1Abs) {
- diag << "error: options --target1-rel and --target1-abs"
- " can't be used together.\n";
- return false;
- } else if (hasArmTarget1Rel || hasArmTarget1Abs) {
- ctx->setArmTarget1Rel(hasArmTarget1Rel && !hasArmTarget1Abs);
- }
- } else {
- for (const auto *arg : parsedArgs.filtered(OPT_grp_arm_targetopts)) {
- diag << "warning: ignoring unsupported ARM/ELF specific argument: "
- << arg->getSpelling() << "\n";
- }
- }
-
- // Process MIPS specific options.
- if (triple.getArch() == llvm::Triple::mips ||
- triple.getArch() == llvm::Triple::mipsel ||
- triple.getArch() == llvm::Triple::mips64 ||
- triple.getArch() == llvm::Triple::mips64el) {
- ctx->setMipsPcRelEhRel(parsedArgs.hasArg(OPT_pcrel_eh_reloc));
- auto *hashArg = parsedArgs.getLastArg(OPT_hash_style);
- if (hashArg && hashArg->getValue() != StringRef("sysv")) {
- diag << "error: .gnu.hash is incompatible with the MIPS ABI\n";
- return false;
- }
- }
- else {
- for (const auto *arg : parsedArgs.filtered(OPT_grp_mips_targetopts)) {
- diag << "warning: ignoring unsupported MIPS specific argument: "
- << arg->getSpelling() << "\n";
- }
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_L))
- ctx->addSearchPath(arg->getValue());
-
- // Add the default search directory specific to the target.
- if (!parsedArgs.hasArg(OPT_nostdlib))
- addPlatformSearchDirs(*ctx, triple, baseTriple);
-
- for (auto *arg : parsedArgs.filtered(OPT_u))
- ctx->addInitialUndefinedSymbol(arg->getValue());
-
- for (auto *arg : parsedArgs.filtered(OPT_defsym)) {
- StringRef sym, target;
- uint64_t addr;
- if (parseDefsymAsAbsolute(arg->getValue(), sym, addr)) {
- ctx->addInitialAbsoluteSymbol(sym, addr);
- } else if (parseDefsymAsAlias(arg->getValue(), sym, target)) {
- ctx->addAlias(sym, target);
- } else {
- diag << "invalid --defsym: " << arg->getValue() << "\n";
- return false;
- }
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_z)) {
- StringRef opt = arg->getValue();
- if (opt == "muldefs")
- ctx->setAllowDuplicates(true);
- else if (opt == "now")
- ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_NOW);
- else if (opt == "origin")
- ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_ORIGIN);
- else if (opt.startswith("max-page-size")) {
- // Parse -z max-page-size option.
- // The default page size is considered the minimum page size the user
- // can set, check the user input if its atleast the minimum page size
- // and does not exceed the maximum page size allowed for the target.
- uint64_t maxPageSize = 0;
-
- // Error if the page size user set is less than the maximum page size
- // and greather than the default page size and the user page size is a
- // modulo of the default page size.
- if ((!parseMaxPageSize(opt, maxPageSize)) ||
- (maxPageSize < ctx->getPageSize()) ||
- (maxPageSize % ctx->getPageSize())) {
- diag << "invalid option: " << opt << "\n";
- return false;
- }
- ctx->setMaxPageSize(maxPageSize);
- } else {
- diag << "warning: ignoring unknown argument for -z: " << opt << "\n";
- }
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_rpath)) {
- SmallVector<StringRef, 2> rpaths;
- StringRef(arg->getValue()).split(rpaths, ":");
- for (auto path : rpaths)
- ctx->addRpath(path);
- }
-
- for (auto *arg : parsedArgs.filtered(OPT_rpath_link)) {
- SmallVector<StringRef, 2> rpaths;
- StringRef(arg->getValue()).split(rpaths, ":");
- for (auto path : rpaths)
- ctx->addRpathLink(path);
- }
-
- // Enable new dynamic tags.
- if (parsedArgs.hasArg(OPT_enable_newdtags))
- ctx->setEnableNewDtags(true);
-
- // Support --wrap option.
- for (auto *arg : parsedArgs.filtered(OPT_wrap))
- ctx->addWrapForSymbol(arg->getValue());
-
- // Register possible input file parsers.
- ctx->registry().addSupportELFObjects(*ctx);
- ctx->registry().addSupportArchives(ctx->logInputFiles());
- ctx->registry().addSupportYamlFiles();
- if (ctx->allowLinkWithDynamicLibraries())
- ctx->registry().addSupportELFDynamicSharedObjects(*ctx);
-
- // Parse the LLVM options before we process files in case the file handling
- // makes use of things like DEBUG().
- parseLLVMOptions(*ctx);
-
- std::stack<int> groupStack;
- int numfiles = 0;
- bool asNeeded = false;
- bool wholeArchive = false;
-
- // Process files
- for (auto arg : parsedArgs) {
- switch (arg->getOption().getID()) {
- case OPT_no_whole_archive:
- wholeArchive = false;
- break;
-
- case OPT_whole_archive:
- wholeArchive = true;
- break;
-
- case OPT_as_needed:
- asNeeded = true;
- break;
-
- case OPT_no_as_needed:
- asNeeded = false;
- break;
-
- case OPT_start_group:
- groupStack.push(numfiles);
- break;
-
- case OPT_end_group: {
- if (groupStack.empty()) {
- diag << "stray --end-group\n";
- return false;
- }
- int startGroupPos = groupStack.top();
- ctx->getNodes().push_back(
- llvm::make_unique<GroupEnd>(numfiles - startGroupPos));
- groupStack.pop();
- break;
- }
-
- case OPT_INPUT:
- case OPT_l:
- case OPT_T: {
- bool dashL = (arg->getOption().getID() == OPT_l);
- StringRef path = arg->getValue();
-
- ErrorOr<StringRef> pathOrErr = findFile(*ctx, path, dashL);
- if (std::error_code ec = pathOrErr.getError()) {
- auto file = llvm::make_unique<ErrorFile>(path, ec);
- auto node = llvm::make_unique<FileNode>(std::move(file));
- node->setAsNeeded(asNeeded);
- ctx->getNodes().push_back(std::move(node));
- break;
- }
- StringRef realpath = pathOrErr.get();
-
- bool isScript =
- (!path.endswith(".objtxt") && isLinkerScript(realpath, diag));
- if (isScript) {
- if (ctx->logInputFiles())
- diag << path << "\n";
- ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
- MemoryBuffer::getFileOrSTDIN(realpath);
- if (std::error_code ec = mb.getError()) {
- diag << "Cannot open " << path << ": " << ec.message() << "\n";
- return false;
- }
- bool nostdlib = parsedArgs.hasArg(OPT_nostdlib);
- std::error_code ec =
- evalLinkerScript(*ctx, std::move(mb.get()), diag, nostdlib);
- if (ec) {
- diag << path << ": Error parsing linker script: "
- << ec.message() << "\n";
- return false;
- }
- break;
- }
- std::vector<std::unique_ptr<File>> files
- = loadFile(*ctx, realpath, wholeArchive);
- for (std::unique_ptr<File> &file : files) {
- if (ctx->logInputFiles())
- diag << file->path() << "\n";
- auto node = llvm::make_unique<FileNode>(std::move(file));
- node->setAsNeeded(asNeeded);
- ctx->getNodes().push_back(std::move(node));
- }
- numfiles += files.size();
- break;
- }
- }
- }
-
- if (ctx->getNodes().empty()) {
- diag << "No input files\n";
- return false;
- }
-
- // Set default output file name if the output file was not specified.
- if (ctx->outputPath().empty()) {
- switch (ctx->outputFileType()) {
- case LinkingContext::OutputFileType::YAML:
- ctx->setOutputPath("-");
- break;
- default:
- ctx->setOutputPath("a.out");
- break;
- }
- }
-
- // Validate the combination of options used.
- if (!ctx->validate(diag))
- return false;
-
- // Perform linker script semantic actions
- if (auto ec = ctx->linkerScriptSema().perform()) {
- diag << "Error in the linker script's semantics: " << ec.message() << "\n";
- return false;
- }
-
- context.swap(ctx);
- return true;
-}
-
-/// Get the default target triple based on either the program name
-/// (e.g. "x86-ibm-linux-lld") or the primary target llvm was configured for.
-llvm::Triple GnuLdDriver::getDefaultTarget(const char *progName) {
- SmallVector<StringRef, 4> components;
- llvm::SplitString(llvm::sys::path::stem(progName), components, "-");
- // If has enough parts to be start with a triple.
- if (components.size() >= 4) {
- llvm::Triple triple(components[0], components[1], components[2],
- components[3]);
- // If first component looks like an arch.
- if (triple.getArch() != llvm::Triple::UnknownArch)
- return triple;
- }
-
- // Fallback to use whatever default triple llvm was configured for.
- return llvm::Triple(llvm::sys::getDefaultTargetTriple());
-}
diff --git a/lib/Driver/GnuLdOptions.td b/lib/Driver/GnuLdOptions.td
deleted file mode 100644
index 7d850d4d002e..000000000000
--- a/lib/Driver/GnuLdOptions.td
+++ /dev/null
@@ -1,378 +0,0 @@
-include "llvm/Option/OptParser.td"
-
-//===----------------------------------------------------------------------===//
-/// Utility Functions
-//===----------------------------------------------------------------------===//
-// Single and multiple dash options combined
-multiclass smDash<string opt1, string opt2, string help> {
- // Option
- def "" : Separate<["-"], opt1>, HelpText<help>;
- def opt1_eq : Joined<["-"], opt1#"=">,
- Alias<!cast<Option>(opt1)>;
- // Compatibility aliases
- def opt2_dashdash : Separate<["--"], opt2>,
- Alias<!cast<Option>(opt1)>;
- def opt2_dashdash_eq : Joined<["--"], opt2#"=">,
- Alias<!cast<Option>(opt1)>;
-}
-
-// Support -<option>,-<option>=
-multiclass dashEq<string opt1, string opt2, string help> {
- // Option
- def "" : Separate<["-"], opt1>, HelpText<help>;
- // Compatibility aliases
- def opt2_eq : Joined<["-"], opt2#"=">,
- Alias<!cast<Option>(opt1)>;
-}
-
-// Support --<option>,--<option>=
-multiclass mDashEq<string opt1, string help> {
- // Option
- def "" : Separate<["--"], opt1>, HelpText<help>;
- // Compatibility aliases
- def opt2_eq : Joined<["--"], opt1#"=">,
- Alias<!cast<Option>(opt1)>;
-}
-
-//===----------------------------------------------------------------------===//
-/// LLVM and Target options
-//===----------------------------------------------------------------------===//
-def grp_llvmtarget : OptionGroup<"opts">,
- HelpText<"LLVM and Target Options">;
-def mllvm : Separate<["-"], "mllvm">,
- HelpText<"Options to pass to LLVM">, Group<grp_llvmtarget>;
-def target : Separate<["-"], "target">, MetaVarName<"<triple>">,
- HelpText<"Target triple to link for">,
- Group<grp_llvmtarget>;
-
-//===----------------------------------------------------------------------===//
-/// Output Kinds
-//===----------------------------------------------------------------------===//
-def grp_kind : OptionGroup<"outs">,
- HelpText<"OUTPUT KIND">;
-def relocatable : Flag<["-"], "r">,
- HelpText<"Create relocatable object file">, Group<grp_kind>;
-def static : Flag<["-"], "static">,
- HelpText<"Create static executable">, Group<grp_kind>;
-def dynamic : Flag<["-"], "dynamic">,
- HelpText<"Create dynamic executable (default)">,Group<grp_kind>;
-def shared : Flag<["-"], "shared">,
- HelpText<"Create dynamic library">, Group<grp_kind>;
-
-// output kinds - compatibility aliases
-def Bstatic : Flag<["-"], "Bstatic">, Alias<static>;
-def Bshareable : Flag<["-"], "Bshareable">, Alias<shared>;
-
-//===----------------------------------------------------------------------===//
-/// General Options
-//===----------------------------------------------------------------------===//
-def grp_general : OptionGroup<"opts">,
- HelpText<"GENERAL OPTIONS">;
-def output : Separate<["-"], "o">, MetaVarName<"<path>">,
- HelpText<"Path to file to write output">,
- Group<grp_general>;
-def m : JoinedOrSeparate<["-"], "m">, MetaVarName<"<emulation>">,
- HelpText<"Select target emulation">,
- Group<grp_general>;
-def build_id : Flag<["--"], "build-id">,
- HelpText<"Request creation of \".note.gnu.build-id\" ELF note section">,
- Group<grp_general>;
-def sysroot : Joined<["--"], "sysroot=">,
- HelpText<"Set the system root">,
- Group<grp_general>;
-
-
-//===----------------------------------------------------------------------===//
-/// Executable Options
-//===----------------------------------------------------------------------===//
-def grp_main : OptionGroup<"opts">,
- HelpText<"EXECUTABLE OPTIONS">;
-def L : Joined<["-"], "L">, MetaVarName<"<dir>">,
- HelpText<"Directory to search for libraries">,
- Group<grp_main>;
-def l : Joined<["-"], "l">, MetaVarName<"<libName>">,
- HelpText<"Root name of library to use">,
- Group<grp_main>;
-def noinhibit_exec : Flag<["--"], "noinhibit-exec">,
- HelpText<"Retain the executable output file whenever"
- " it is still usable">,
- Group<grp_main>;
-defm e : smDash<"e", "entry",
- "Name of entry point symbol">,
- Group<grp_main>;
-defm init: dashEq<"init", "init",
- "Specify an initializer function">,
- Group<grp_main>;
-defm fini: dashEq<"fini", "fini",
- "Specify a finalizer function">,
- Group<grp_main>;
-def whole_archive: Flag<["--"], "whole-archive">,
- HelpText<"Force load of all members in a static library">,
- Group<grp_main>;
-def no_whole_archive: Flag<["--"], "no-whole-archive">,
- HelpText<"Restores the default behavior of loading archive members">,
- Group<grp_main>;
-def nostdlib : Flag<["-"], "nostdlib">,
- HelpText<"Disable default search path for libraries">,
- Group<grp_main>;
-def image_base : Separate<["--"], "image-base">,
- HelpText<"Set the base address">,
- Group<grp_main>;
-
-//===----------------------------------------------------------------------===//
-/// Static Executable Options
-//===----------------------------------------------------------------------===//
-def grp_staticexec : OptionGroup<"opts">,
- HelpText<"STATIC EXECUTABLE OPTIONS">;
-def nmagic : Flag<["--"], "nmagic">,
- HelpText<"Turn off page alignment of sections,"
- " and disable linking against shared libraries">,
- Group<grp_staticexec>;
-def omagic : Flag<["--"], "omagic">,
- HelpText<"Set the text and data sections to be readable and writable."
- " Also, do not page-align the data segment, and"
- " disable linking against shared libraries.">,
- Group<grp_staticexec>;
-def no_omagic : Flag<["--"], "no-omagic">,
- HelpText<"This option negates most of the effects of the -N option."
- "Disable linking with shared libraries">,
- Group<grp_staticexec>;
-// Compatible Aliases
-def nmagic_alias : Flag<["-"], "n">,
- Alias<nmagic>;
-def omagic_alias : Flag<["-"], "N">,
- Alias<omagic>;
-
-//===----------------------------------------------------------------------===//
-/// Dynamic Library/Executable Options
-//===----------------------------------------------------------------------===//
-def grp_dynlibexec : OptionGroup<"opts">,
- HelpText<"DYNAMIC LIBRARY/EXECUTABLE OPTIONS">;
-def dynamic_linker : Joined<["--"], "dynamic-linker=">,
- HelpText<"Set the path to the dynamic linker">, Group<grp_dynlibexec>;
-// Executable options - compatibility aliases
-def dynamic_linker_alias : Separate<["-", "--"], "dynamic-linker">,
- Alias<dynamic_linker>;
-defm rpath : dashEq<"rpath", "rpath",
- "Add a directory to the runtime library search path">,
- Group<grp_dynlibexec>;
-def rpath_link : Separate<["-"], "rpath-link">,
- HelpText<"Specifies the first set of directories to search">,
- Group<grp_dynlibexec>;
-def export_dynamic : Flag<["-", "--"], "export-dynamic">,
- HelpText<"Add all symbols to the dynamic symbol table"
- " when creating executables">,
- Group<grp_main>;
-def alias_export_dynamic: Flag<["-"], "E">,
- Alias<export_dynamic>;
-def no_export_dynamic : Flag<["--"], "no-export-dynamic">,
- Group<grp_main>;
-
-//===----------------------------------------------------------------------===//
-/// Dynamic Library Options
-//===----------------------------------------------------------------------===//
-def grp_dynlib : OptionGroup<"opts">,
- HelpText<"DYNAMIC LIBRARY OPTIONS">;
-def soname : Joined<["-", "--"], "soname=">,
- HelpText<"Set the internal DT_SONAME field to the specified name">,
- Group<grp_dynlib>;
-def soname_separate : Separate<["-", "--"], "soname">, Alias<soname>;
-def soname_h : Separate<["-"], "h">, Alias<soname>;
-
-//===----------------------------------------------------------------------===//
-/// Resolver Options
-//===----------------------------------------------------------------------===//
-def grp_resolveropt : OptionGroup<"opts">,
- HelpText<"SYMBOL RESOLUTION OPTIONS">;
-defm u : smDash<"u", "undefined",
- "Force symbol to be entered in the output file"
- " as an undefined symbol">,
- Group<grp_resolveropt>;
-def start_group : Flag<["--"], "start-group">,
- HelpText<"Start a group">,
- Group<grp_resolveropt>;
-def alias_start_group: Flag<["-"], "(">,
- Alias<start_group>;
-def end_group : Flag<["--"], "end-group">,
- HelpText<"End a group">,
- Group<grp_resolveropt>;
-def alias_end_group: Flag<["-"], ")">,
- Alias<end_group>;
-def as_needed : Flag<["--"], "as-needed">,
- HelpText<"This option affects ELF DT_NEEDED tags for "
- "dynamic libraries mentioned on the command line">,
- Group<grp_resolveropt>;
-def no_as_needed : Flag<["--"], "no-as-needed">,
- HelpText<"This option restores the default behavior"
- " of adding DT_NEEDED entries">,
- Group<grp_resolveropt>;
-def no_allow_shlib_undefs : Flag<["--"], "no-allow-shlib-undefined">,
- HelpText<"Do not allow undefined symbols from dynamic"
- " library when creating executables">,
- Group<grp_resolveropt>;
-def allow_shlib_undefs : Flag<["-", "--"], "allow-shlib-undefined">,
- HelpText<"Allow undefined symbols from dynamic"
- " library when creating executables">,
- Group<grp_resolveropt>;
-def use_shlib_undefs: Flag<["--"], "use-shlib-undefines">,
- HelpText<"Resolve undefined symbols from dynamic libraries">,
- Group<grp_resolveropt>;
-def allow_multiple_definition: Flag<["--"], "allow-multiple-definition">,
- HelpText<"Allow multiple definitions">,
- Group<grp_resolveropt>;
-defm defsym : mDashEq<"defsym",
- "Create a global symbol in the output file "
- "containing the absolute address given by expression">,
- MetaVarName<"symbol=<expression>">,
- Group<grp_resolveropt>;
-
-//===----------------------------------------------------------------------===//
-/// Custom Options
-//===----------------------------------------------------------------------===//
-def grp_customopts : OptionGroup<"opts">,
- HelpText<"CUSTOM OPTIONS">;
-def disable_newdtags: Flag<["--"], "disable-new-dtags">,
- HelpText<"Disable new dynamic tags">,
- Group<grp_customopts>;
-def enable_newdtags: Flag<["--"], "enable-new-dtags">,
- HelpText<"Enable new dynamic tags">,
- Group<grp_customopts>;
-def rosegment: Flag<["--"], "rosegment">,
- HelpText<"Put read-only non-executable sections in their own segment">,
- Group<grp_customopts>;
-def z : Separate<["-"], "z">,
- HelpText<"Linker Option extensions">,
- Group<grp_customopts>;
-def no_align_segments: Flag<["--"], "no-align-segments">,
- HelpText<"Don't align ELF segments(virtualaddress/fileoffset) to page boundaries">,
- Group<grp_customopts>;
-
-//===----------------------------------------------------------------------===//
-/// Symbol options
-//===----------------------------------------------------------------------===//
-def grp_symbolopts : OptionGroup<"opts">,
- HelpText<"SYMBOL OPTIONS">;
-def demangle : Flag<["--"], "demangle">,
- HelpText<"Demangle C++ symbols">,
- Group<grp_symbolopts>;
-def discard_loc : Flag<["--"], "discard-all">,
- HelpText<"Discard all local symbols">,
- Group<grp_symbolopts>;
-def alias_discard_loc: Flag<["-"], "x">,
- Alias<discard_loc>;
-def discard_temp_loc : Flag<["--"], "discard-locals">,
- HelpText<"Discard temporary local symbols">,
- Group<grp_symbolopts>;
-def alias_discard_temp_loc : Flag<["-"], "X">,
- Alias<discard_temp_loc>;
-def no_demangle : Flag<["--"], "no-demangle">,
- HelpText<"Dont demangle C++ symbols">,
- Group<grp_symbolopts>;
-def strip_all : Flag<["--"], "strip-all">,
- HelpText<"Omit all symbol informations from output">,
- Group<grp_symbolopts>;
-def alias_strip_all : Flag<["-"], "s">,
- Alias<strip_all>;
-defm wrap : smDash<"wrap", "wrap",
- "Use a wrapper function for symbol. Any "
- " undefined reference to symbol will be resolved to "
- "\"__wrap_symbol\". Any undefined reference to \"__real_symbol\""
- " will be resolved to symbol.">,
- MetaVarName<"<symbol>">,
- Group<grp_symbolopts>;
-
-//===----------------------------------------------------------------------===//
-/// Script Options
-//===----------------------------------------------------------------------===//
-def grp_scriptopts : OptionGroup<"opts">,
- HelpText<"SCRIPT OPTIONS">;
-defm T : smDash<"T", "script",
- "Use the given linker script in place of the default script.">,
- Group<grp_scriptopts>;
-
-//===----------------------------------------------------------------------===//
-/// Optimization Options
-//===----------------------------------------------------------------------===//
-def grp_opts : OptionGroup<"opts">,
- HelpText<"OPTIMIZATIONS">;
-def hash_style : Joined <["--"], "hash-style=">,
- HelpText<"Set the type of linker's hash table(s)">,
- Group<grp_opts>;
-def merge_strings : Flag<["--"], "merge-strings">,
- HelpText<"Merge common strings across mergeable sections">,
- Group<grp_opts>;
-def eh_frame_hdr : Flag<["--"], "eh-frame-hdr">,
- HelpText<"Request creation of .eh_frame_hdr section and ELF "
- " PT_GNU_EH_FRAME segment header">,
- Group<grp_opts>;
-
-//===----------------------------------------------------------------------===//
-/// Tracing Options
-//===----------------------------------------------------------------------===//
-def grp_tracingopts : OptionGroup<"opts">,
- HelpText<"TRACING OPTIONS">;
-def t : Flag<["-"], "t">,
- HelpText<"Print the names of the input files as ld processes them">,
- Group<grp_tracingopts>;
-def stats : Flag<["--"], "stats">,
- HelpText<"Print time and memory usage stats">, Group<grp_tracingopts>;
-
-//===----------------------------------------------------------------------===//
-/// Extensions
-//===----------------------------------------------------------------------===//
-def grp_extns : OptionGroup<"opts">,
- HelpText<"Extensions">;
-def output_filetype: Separate<["--"], "output-filetype">,
- HelpText<"Specify yaml to create an output in YAML format">,
- Group<grp_extns>;
-def alias_output_filetype: Joined<["--"], "output-filetype=">,
- Alias<output_filetype>;
-
-//===----------------------------------------------------------------------===//
-/// Target Specific Options
-//===----------------------------------------------------------------------===//
-def grp_targetopts : OptionGroup<"opts">,
- HelpText<"ARCH SPECIFIC OPTIONS">;
-
-//===----------------------------------------------------------------------===//
-/// ARM Target Specific Options
-//===----------------------------------------------------------------------===//
-def grp_arm_targetopts : OptionGroup<"ARM SPECIFIC OPTIONS">,
- Group<grp_targetopts>;
-def target1_rel : Flag<["--"], "target1-rel">,
- Group<grp_arm_targetopts>, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">;
-def target1_abs : Flag<["--"], "target1-abs">,
- Group<grp_arm_targetopts>, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">;
-
-//===----------------------------------------------------------------------===//
-/// MIPS Target Specific Options
-//===----------------------------------------------------------------------===//
-def grp_mips_targetopts : OptionGroup<"MIPS SPECIFIC OPTIONS">,
- Group<grp_targetopts>;
-def pcrel_eh_reloc : Flag<["-", "--"], "pcrel-eh-reloc">,
- Group<grp_mips_targetopts>,
- HelpText<"Interpret R_MIPS_EH as R_MIPS_PC32">;
-
-//===----------------------------------------------------------------------===//
-/// Ignored options
-//===----------------------------------------------------------------------===//
-def grp_ignored: OptionGroup<"ignored">,
- HelpText<"GNU Options ignored for Compatibility ">;
-def dashg : Flag<["-"], "g">,
- HelpText<"Ignored.">,
- Group<grp_ignored>;
-def Qy : Flag<["-"], "Qy">,
- HelpText<"Ignored for SVR4 Compatibility">,
- Group<grp_ignored>;
-def qmagic : Flag<["-"], "qmagic">,
- HelpText<"Ignored for Linux Compatibility">,
- Group<grp_ignored>;
-def G : Separate<["-"], "G">,
- HelpText<"Ignored for MIPS GNU Linker Compatibility">,
- Group<grp_ignored>;
-
-//===----------------------------------------------------------------------===//
-/// Help
-//===----------------------------------------------------------------------===//
-def help : Flag<["--"], "help">,
- HelpText<"Display this help message">;
diff --git a/lib/Driver/TODO.rst b/lib/Driver/TODO.rst
deleted file mode 100644
index 868eaf02290c..000000000000
--- a/lib/Driver/TODO.rst
+++ /dev/null
@@ -1,99 +0,0 @@
-GNU ld Driver
-~~~~~~~~~~~~~
-
-Missing Options
-###############
-
-* --audit
-* -A,--architecture
-* -b,--format
-* -d,-dc,-dp
-* -P,--depaudit
-* --exclude-libs
-* --exclude-modules-for-implib
-* -E,--export-dynamic,--no-export-dynamic
-* -EB (We probably shouldn't support this)
-* -EL (We probably shouldn't support this)
-* -f,--auxiliary
-* -F,--filter
-* -G,--gpsize
-* -h
-* -i
-* --library
-* -M
-* --print-map
-* -output
-* -O
-* -q,--emit-relocs
-* --force-dynamic
-* --relocatable
-* -R,--just-symbols
-* -s,--strip-all
-* -S,--strip-debug
-* --trace
-* -dT,--default-script
-* -Ur
-* --unique
-* -v,--version,-V
-* -y,--trace-symbol
-* -z (keywords need to be implemented)
-* --accept-unknown-input-arch,--no-accept-unknown-input-arch
-* -Bdynamic,-dy,-call_shared
-* -Bgroup
-* -dn,-non_shared
-* -Bsymbolic
-* -Bsymbolic-functions
-* --dynamic-list
-* --dynamic-list-data
-* --dynamic-list-cpp-new
-* --dynamic-list-cpp-typeinfo
-* --check-sections,--no-check-sections
-* --copy-dt-needed-entries,--no-copy-dt-needed-entires
-* --cref
-* --no-define-common
-* --defsym (only absolute value supported now)
-* --demangle,--no-demangle
-* -I
-* --fatal-warnings,--no-fatal-warnings
-* --force-exe-suffix
-* --gc-sections,--no-gc-sections
-* --print-gc-sections,--no-print-gc-sections
-* --print-output-format
-* --target-help
-* -Map
-* --no-keep-memory
-* --no-undefined,-z defs
-* --allow-shlib-undefined,--no-alow-shlib-undefined
-* --no-undefined-version
-* --default-symver
-* --default-imported-symver
-* --no-warn-mismatch
-* --no-warn-search-mismatch
-* --oformat
-* -pie,--pic-executable
-* --relax,--no-relax
-* --retain-symbols-file
-* --sort-common
-* --sort-section={name,alignment}
-* --split-by-file
-* --split-by-reloc
-* --stats
-* --section-start
-* -T{bss,data,text,{text,rodata,data}-segment}
-* --unresolved-symbols
-* -dll-verbose,--verbose
-* --version-script
-* --warn-common
-* --warn-constructors
-* --warn-multiple-gp
-* --warn-once
-* --warn-section-align
-* --warn-shared-textrel
-* --warn-alternate-em
-* --warn-unresolved-symbols
-* --error-unresolved-symbols
-* --wrap
-* --no-ld-generated-unwind-info
-* --hash-size
-* --reduce-memory-overheads
-* --build-id
diff --git a/lib/Driver/UniversalDriver.cpp b/lib/Driver/UniversalDriver.cpp
deleted file mode 100644
index 3dea7ebfae89..000000000000
--- a/lib/Driver/UniversalDriver.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//===- lib/Driver/UniversalDriver.cpp -------------------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-///
-/// Driver for "universal" lld tool which can mimic any linker command line
-/// parsing once it figures out which command line flavor to use.
-///
-//===----------------------------------------------------------------------===//
-
-#include "lld/Driver/Driver.h"
-#include "lld/Config/Version.h"
-#include "lld/Core/LLVM.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lld;
-
-namespace {
-
-// Create enum with OPT_xxx values for each option in GnuLdOptions.td
-enum {
- OPT_INVALID = 0,
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, META) \
- OPT_##ID,
-#include "UniversalDriverOptions.inc"
-#undef OPTION
-};
-
-// Create prefix string literals used in GnuLdOptions.td
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "UniversalDriverOptions.inc"
-#undef PREFIX
-
-// Create table mapping all options defined in GnuLdOptions.td
-static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { \
- PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS \
- } \
- ,
-#include "UniversalDriverOptions.inc"
-#undef OPTION
-};
-
-// Create OptTable class for parsing actual command line arguments
-class UniversalDriverOptTable : public llvm::opt::OptTable {
-public:
- UniversalDriverOptTable()
- : OptTable(infoTable) {}
-};
-
-enum class Flavor {
- invalid,
- old_gnu_ld, // -flavor old-gnu
- gnu_ld, // -flavor gnu
- win_link, // -flavor link
- darwin_ld, // -flavor darwin
- core // -flavor core OR -core
-};
-
-struct ProgramNameParts {
- StringRef _target;
- StringRef _flavor;
-};
-
-} // anonymous namespace
-
-static Flavor strToFlavor(StringRef str) {
- return llvm::StringSwitch<Flavor>(str)
- .Case("old-gnu", Flavor::old_gnu_ld)
- .Case("gnu", Flavor::gnu_ld)
- .Case("ld.lld", Flavor::gnu_ld)
- .Case("link", Flavor::win_link)
- .Case("lld-link", Flavor::win_link)
- .Case("darwin", Flavor::darwin_ld)
- .Case("core", Flavor::core)
- .Case("ld", Flavor::gnu_ld)
- .Default(Flavor::invalid);
-}
-
-static ProgramNameParts parseProgramName(StringRef programName) {
- SmallVector<StringRef, 3> components;
- llvm::SplitString(programName, components, "-");
- ProgramNameParts ret;
-
- using std::begin;
- using std::end;
-
- // Erase any lld components.
- components.erase(std::remove(components.begin(), components.end(), "lld"),
- components.end());
-
- // Find the flavor component.
- auto flIter = std::find_if(components.begin(), components.end(),
- [](StringRef str) -> bool {
- return strToFlavor(str) != Flavor::invalid;
- });
-
- if (flIter != components.end()) {
- ret._flavor = *flIter;
- components.erase(flIter);
- }
-
- // Any remaining component must be the target.
- if (components.size() == 1)
- ret._target = components[0];
-
- return ret;
-}
-
-// Removes the argument from argv along with its value, if exists, and updates
-// argc.
-static void removeArg(llvm::opt::Arg *arg,
- llvm::MutableArrayRef<const char *> &args) {
- unsigned int numToRemove = arg->getNumValues() + 1;
- auto sub = args.slice(arg->getIndex() + 1);
- std::rotate(sub.begin(), sub.begin() + numToRemove, sub.end());
- args = args.drop_back(numToRemove);
-}
-
-static Flavor getFlavor(llvm::MutableArrayRef<const char *> &args,
- const llvm::opt::InputArgList &parsedArgs) {
- if (llvm::opt::Arg *argCore = parsedArgs.getLastArg(OPT_core)) {
- removeArg(argCore, args);
- return Flavor::core;
- }
- if (llvm::opt::Arg *argFlavor = parsedArgs.getLastArg(OPT_flavor)) {
- removeArg(argFlavor, args);
- return strToFlavor(argFlavor->getValue());
- }
-
-#if LLVM_ON_UNIX
- if (llvm::sys::path::filename(args[0]).equals("ld")) {
-#if __APPLE__
- // On a Darwin systems, if linker binary is named "ld", use Darwin driver.
- return Flavor::darwin_ld;
-#endif
- // On a ELF based systems, if linker binary is named "ld", use gnu driver.
- return Flavor::gnu_ld;
- }
-#endif
-
- StringRef name = llvm::sys::path::filename(args[0]);
- if (name.endswith_lower(".exe"))
- name = llvm::sys::path::stem(name);
- return strToFlavor(parseProgramName(name)._flavor);
-}
-
-namespace lld {
-
-bool UniversalDriver::link(llvm::MutableArrayRef<const char *> args,
- raw_ostream &diagnostics) {
- // Parse command line options using GnuLdOptions.td
- UniversalDriverOptTable table;
- unsigned missingIndex;
- unsigned missingCount;
-
- // Program name
- StringRef programName = llvm::sys::path::stem(args[0]);
-
- llvm::opt::InputArgList parsedArgs =
- table.ParseArgs(args.slice(1), missingIndex, missingCount);
-
- if (missingCount) {
- diagnostics << "error: missing arg value for '"
- << parsedArgs.getArgString(missingIndex) << "' expected "
- << missingCount << " argument(s).\n";
- return false;
- }
-
- // Handle -help
- if (parsedArgs.getLastArg(OPT_help)) {
- table.PrintHelp(llvm::outs(), programName.data(), "LLVM Linker", false);
- return true;
- }
-
- // Handle -version
- if (parsedArgs.getLastArg(OPT_version)) {
- diagnostics << "LLVM Linker Version: " << getLLDVersion()
- << getLLDRepositoryVersion() << "\n";
- return true;
- }
-
- Flavor flavor = getFlavor(args, parsedArgs);
-
- // Switch to appropriate driver.
- switch (flavor) {
- case Flavor::old_gnu_ld:
- return GnuLdDriver::linkELF(args, diagnostics);
- case Flavor::gnu_ld:
- elf2::link(args);
- return true;
- case Flavor::darwin_ld:
- return DarwinLdDriver::linkMachO(args, diagnostics);
- case Flavor::win_link:
- coff::link(args);
- return true;
- case Flavor::core:
- return CoreDriver::link(args, diagnostics);
- case Flavor::invalid:
- diagnostics << "Select the appropriate flavor\n";
- table.PrintHelp(llvm::outs(), programName.data(), "LLVM Linker", false);
- return false;
- }
- llvm_unreachable("Unrecognised flavor");
-}
-
-} // end namespace lld
diff --git a/lib/Driver/UniversalDriverOptions.td b/lib/Driver/UniversalDriverOptions.td
deleted file mode 100644
index 14abc9ce9911..000000000000
--- a/lib/Driver/UniversalDriverOptions.td
+++ /dev/null
@@ -1,19 +0,0 @@
-include "llvm/Option/OptParser.td"
-
-// Select an optional flavor
-def flavor: Separate<["-"], "flavor">,
- HelpText<"Flavor for linking, options are gnu/darwin/link">;
-
-// Select the core flavor
-def core : Flag<["-"], "core">,
- HelpText<"CORE linking">;
-
-def target: Separate<["-"], "target">,
- HelpText<"Select the target">;
-
-def version: Flag<["-"], "version">,
- HelpText<"Display the version">;
-
-// Help message
-def help : Flag<["-"], "help">,
- HelpText<"Display this help message">;