]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Driver/CoreDriver.cpp
Vendor import of lld trunk r233088:
[FreeBSD/FreeBSD.git] / lib / Driver / CoreDriver.cpp
1 //===- lib/Driver/CoreDriver.cpp ------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
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"
26
27 using namespace lld;
28
29 namespace {
30
31 // Create enum with OPT_xxx values for each option in CoreOptions.td
32 enum {
33   OPT_INVALID = 0,
34 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
35                HELP, META) \
36           OPT_##ID,
37 #include "CoreOptions.inc"
38 #undef OPTION
39 };
40
41 // Create prefix string literals used in CoreOptions.td
42 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
43 #include "CoreOptions.inc"
44 #undef PREFIX
45
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, \
49                HELPTEXT, METAVAR)   \
50   { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
51     PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
52 #include "CoreOptions.inc"
53 #undef OPTION
54 };
55
56 // Create OptTable class for parsing actual command line arguments
57 class CoreOptTable : public llvm::opt::OptTable {
58 public:
59   CoreOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){}
60 };
61
62 } // namespace anonymous
63
64
65 namespace lld {
66
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" },
73   LLD_KIND_STRING_END
74 };
75
76 bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
77   CoreLinkingContext ctx;
78
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);
84
85   if (!parse(argc, argv, ctx))
86     return false;
87   return Driver::link(ctx);
88 }
89
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;
94   CoreOptTable table;
95   unsigned missingIndex;
96   unsigned missingCount;
97   parsedArgs.reset(
98       table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount));
99   if (missingCount) {
100     diagnostics << "error: missing arg value for '"
101                 << parsedArgs->getArgString(missingIndex) << "' expected "
102                 << missingCount << " argument(s).\n";
103     return false;
104   }
105
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);
113
114   // Process all the arguments and create input files.
115   for (auto inputArg : *parsedArgs) {
116     switch (inputArg->getOption().getID()) {
117     case OPT_mllvm:
118       ctx.appendLLVMOption(inputArg->getValue());
119       break;
120
121     case OPT_entry:
122       ctx.setEntrySymbolName(inputArg->getValue());
123       break;
124
125     case OPT_output:
126       ctx.setOutputPath(inputArg->getValue());
127       break;
128
129     case OPT_dead_strip:
130       ctx.setDeadStripping(true);
131       break;
132
133     case OPT_keep_globals:
134       ctx.setGlobalsAreDeadStripRoots(true);
135       break;
136
137     case OPT_undefines_are_errors:
138       ctx.setPrintRemainingUndefines(true);
139       ctx.setAllowRemainingUndefines(false);
140       break;
141
142     case OPT_commons_search_archives:
143       ctx.setSearchArchivesToOverrideTentativeDefinitions(true);
144       break;
145
146     case OPT_add_pass:
147       ctx.addPassNamed(inputArg->getValue());
148       break;
149
150     case OPT_INPUT: {
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)));
155       break;
156     }
157
158     default:
159       break;
160     }
161   }
162
163   if (ctx.getNodes().empty()) {
164     diagnostics << "No input files\n";
165     return false;
166   }
167
168   // Validate the combination of options used.
169   return ctx.validate(diagnostics);
170 }
171
172 } // namespace lld