1 //===- lib/Driver/CoreDriver.cpp ------------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lld/Core/Reader.h"
11 #include "lld/Driver/Driver.h"
12 #include "lld/ReaderWriter/CoreLinkingContext.h"
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/Option/Arg.h"
17 #include "llvm/Option/Option.h"
18 #include "llvm/Support/CommandLine.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/Host.h"
21 #include "llvm/Support/ManagedStatic.h"
22 #include "llvm/Support/Path.h"
23 #include "llvm/Support/PrettyStackTrace.h"
24 #include "llvm/Support/Signals.h"
25 #include "llvm/Support/raw_ostream.h"
31 // Create enum with OPT_xxx values for each option in CoreOptions.td
34 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
37 #include "CoreOptions.inc"
41 // Create prefix string literals used in CoreOptions.td
42 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
43 #include "CoreOptions.inc"
46 // Create table mapping all options defined in CoreOptions.td
47 static const llvm::opt::OptTable::Info infoTable[] = {
48 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
50 { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
51 PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
52 #include "CoreOptions.inc"
56 // Create OptTable class for parsing actual command line arguments
57 class CoreOptTable : public llvm::opt::OptTable {
59 CoreOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){}
62 } // namespace anonymous
67 static const Registry::KindStrings coreKindStrings[] = {
68 { CoreLinkingContext::TEST_RELOC_CALL32, "call32" },
69 { CoreLinkingContext::TEST_RELOC_PCREL32, "pcrel32" },
70 { CoreLinkingContext::TEST_RELOC_GOT_LOAD32, "gotLoad32" },
71 { CoreLinkingContext::TEST_RELOC_GOT_USE32, "gotUse32" },
72 { CoreLinkingContext::TEST_RELOC_LEA32_WAS_GOT, "lea32wasGot" },
76 bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
77 CoreLinkingContext ctx;
79 // Register possible input file parsers.
80 ctx.registry().addSupportNativeObjects();
81 ctx.registry().addSupportYamlFiles();
82 ctx.registry().addKindTable(Reference::KindNamespace::testing,
83 Reference::KindArch::all, coreKindStrings);
85 if (!parse(argc, argv, ctx))
87 return Driver::link(ctx);
90 bool CoreDriver::parse(int argc, const char *argv[], CoreLinkingContext &ctx,
91 raw_ostream &diagnostics) {
92 // Parse command line options using CoreOptions.td
93 std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
95 unsigned missingIndex;
96 unsigned missingCount;
98 table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount));
100 diagnostics << "error: missing arg value for '"
101 << parsedArgs->getArgString(missingIndex) << "' expected "
102 << missingCount << " argument(s).\n";
106 // Set default options
107 ctx.setOutputPath("-");
108 ctx.setDeadStripping(false);
109 ctx.setGlobalsAreDeadStripRoots(false);
110 ctx.setPrintRemainingUndefines(false);
111 ctx.setAllowRemainingUndefines(true);
112 ctx.setSearchArchivesToOverrideTentativeDefinitions(false);
114 // Process all the arguments and create input files.
115 for (auto inputArg : *parsedArgs) {
116 switch (inputArg->getOption().getID()) {
118 ctx.appendLLVMOption(inputArg->getValue());
122 ctx.setEntrySymbolName(inputArg->getValue());
126 ctx.setOutputPath(inputArg->getValue());
130 ctx.setDeadStripping(true);
133 case OPT_keep_globals:
134 ctx.setGlobalsAreDeadStripRoots(true);
137 case OPT_undefines_are_errors:
138 ctx.setPrintRemainingUndefines(true);
139 ctx.setAllowRemainingUndefines(false);
142 case OPT_commons_search_archives:
143 ctx.setSearchArchivesToOverrideTentativeDefinitions(true);
147 ctx.addPassNamed(inputArg->getValue());
151 std::vector<std::unique_ptr<File>> files
152 = loadFile(ctx, inputArg->getValue(), false);
153 for (std::unique_ptr<File> &file : files)
154 ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
163 if (ctx.getNodes().empty()) {
164 diagnostics << "No input files\n";
168 // Validate the combination of options used.
169 return ctx.validate(diagnostics);