blob: 25ac09343a2dee1bd13e2aa05c4f869b09f943b0 [file] [log] [blame]
Nick Kledzikc314b462013-04-04 18:59:24 +00001//===- lib/Driver/GnuLdDriver.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/// \file
11///
12/// Concrete instance of the Driver for GNU's ld.
13///
14//===----------------------------------------------------------------------===//
15
16#include "lld/Driver/Driver.h"
17#include "lld/ReaderWriter/ELFTargetInfo.h"
18
19#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/ADT/Triple.h"
23#include "llvm/Option/Arg.h"
24#include "llvm/Option/Option.h"
25#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/FileSystem.h"
27#include "llvm/Support/Host.h"
28#include "llvm/Support/ManagedStatic.h"
29#include "llvm/Support/Path.h"
30#include "llvm/Support/PrettyStackTrace.h"
31#include "llvm/Support/raw_ostream.h"
32#include "llvm/Support/Signals.h"
33
34using namespace lld;
35
36
37namespace {
38
39// Create enum with OPT_xxx values for each option in LDOptions.td
40enum LDOpt {
41 OPT_INVALID = 0,
42#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, HELP, META) \
43 OPT_##ID,
44#include "LDOptions.inc"
45 LastOption
46#undef OPTION
47};
48
49// Create prefix string literals used in LDOptions.td
50#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
51#include "LDOptions.inc"
52#undef PREFIX
53
54// Create table mapping all options defined in LDOptions.td
55static const llvm::opt::OptTable::Info infoTable[] = {
56#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
57 HELPTEXT, METAVAR) \
58 { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
59 PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS },
60#include "LDOptions.inc"
61#undef OPTION
62};
63
64
65// Create OptTable class for parsing actual command line arguments
66class GnuLdOptTable : public llvm::opt::OptTable {
67public:
68 GnuLdOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){}
69};
70
71} // namespace
72
73
74
75bool GnuLdDriver::linkELF(int argc, const char *argv[],
76 raw_ostream &diagnostics) {
77 std::unique_ptr<ELFTargetInfo> options(parse(argc, argv, diagnostics));
78 if (!options)
79 return true;
Shankar Easwaraneeee23e2013-04-11 02:56:30 +000080
Nick Kledzikc314b462013-04-04 18:59:24 +000081 return link(*options, diagnostics);
82}
83
Shankar Easwaraneeee23e2013-04-11 02:56:30 +000084std::unique_ptr<ELFTargetInfo>
85GnuLdDriver::parse(int argc, const char *argv[], raw_ostream &diagnostics) {
Nick Kledzikc314b462013-04-04 18:59:24 +000086 // Parse command line options using LDOptions.td
87 std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
88 GnuLdOptTable table;
89 unsigned missingIndex;
90 unsigned missingCount;
Shankar Easwaraneeee23e2013-04-11 02:56:30 +000091 parsedArgs.reset(
92 table.ParseArgs(&argv[1], &argv[argc], missingIndex, missingCount));
Nick Kledzikc314b462013-04-04 18:59:24 +000093 if (missingCount) {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +000094 diagnostics << "error: missing arg value for '"
95 << parsedArgs->getArgString(missingIndex) << "' expected "
96 << missingCount << " argument(s).\n";
Nick Kledzikc314b462013-04-04 18:59:24 +000097 return nullptr;
98 }
99
100 for (auto it = parsedArgs->filtered_begin(OPT_UNKNOWN),
101 ie = parsedArgs->filtered_end(); it != ie; ++it) {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000102 diagnostics << "warning: ignoring unknown argument: " << (*it)->getAsString(
103 *parsedArgs)
104 << "\n";
Nick Kledzikc314b462013-04-04 18:59:24 +0000105 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000106
Nick Kledzikc314b462013-04-04 18:59:24 +0000107 // Handle --help
108 if (parsedArgs->getLastArg(OPT_help)) {
109 table.PrintHelp(llvm::outs(), argv[0], "LLVM Linker", false);
110 return nullptr;
111 }
112
113 // Use -target or use default target triple to instantiate TargetInfo
114 llvm::Triple triple;
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000115 if (llvm::opt::Arg *trip = parsedArgs->getLastArg(OPT_target))
Nick Kledzikc314b462013-04-04 18:59:24 +0000116 triple = llvm::Triple(trip->getValue());
117 else
118 triple = getDefaultTarget(argv[0]);
119 std::unique_ptr<ELFTargetInfo> options(ELFTargetInfo::create(triple));
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000120
Nick Kledzikc314b462013-04-04 18:59:24 +0000121 if (!options) {
122 diagnostics << "unknown target triple\n";
123 return nullptr;
124 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000125
Nick Kledzikc314b462013-04-04 18:59:24 +0000126 // Handle -e xxx
127 if (llvm::opt::Arg *entry = parsedArgs->getLastArg(OPT_entry))
128 options->setEntrySymbolName(entry->getValue());
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000129
Nick Kledzikc314b462013-04-04 18:59:24 +0000130 // Handle -emit-yaml
131 if (parsedArgs->getLastArg(OPT_emit_yaml))
132 options->setOutputYAML(true);
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000133
Nick Kledzikc314b462013-04-04 18:59:24 +0000134 // Handle -o xxx
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000135 if (llvm::opt::Arg *output = parsedArgs->getLastArg(OPT_output))
Nick Kledzikc314b462013-04-04 18:59:24 +0000136 options->setOutputPath(output->getValue());
137 else if (options->outputYAML())
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000138 options->setOutputPath("-"); // yaml writes to stdout by default
Nick Kledzikc314b462013-04-04 18:59:24 +0000139 else
140 options->setOutputPath("a.out");
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000141
Nick Kledzikc314b462013-04-04 18:59:24 +0000142 // Handle -r, -shared, or -static
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000143 if (llvm::opt::Arg *kind =
144 parsedArgs->getLastArg(OPT_relocatable, OPT_shared, OPT_static)) {
Nick Kledzikc314b462013-04-04 18:59:24 +0000145 switch (kind->getOption().getID()) {
146 case OPT_relocatable:
147 options->setOutputFileType(llvm::ELF::ET_REL);
148 options->setPrintRemainingUndefines(false);
149 options->setAllowRemainingUndefines(true);
150 break;
151 case OPT_shared:
152 options->setOutputFileType(llvm::ELF::ET_DYN);
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000153 options->setAllowShlibUndefines(true);
154 options->setUseShlibUndefines(false);
Nick Kledzikc314b462013-04-04 18:59:24 +0000155 break;
156 case OPT_static:
157 options->setOutputFileType(llvm::ELF::ET_EXEC);
158 options->setIsStaticExecutable(true);
159 break;
160 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000161 } else {
162 options->setOutputFileType(llvm::ELF::ET_EXEC);
163 options->setIsStaticExecutable(false);
164 options->setAllowShlibUndefines(false);
165 options->setUseShlibUndefines(true);
Nick Kledzikc314b462013-04-04 18:59:24 +0000166 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000167
Nick Kledzikc314b462013-04-04 18:59:24 +0000168 // Handle --noinhibit-exec
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000169 if (parsedArgs->getLastArg(OPT_noinhibit_exec))
Nick Kledzikc314b462013-04-04 18:59:24 +0000170 options->setAllowRemainingUndefines(true);
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000171
Nick Kledzikc314b462013-04-04 18:59:24 +0000172 // Handle --force-load
173 if (parsedArgs->getLastArg(OPT_force_load))
174 options->setForceLoadAllArchives(true);
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000175
Nick Kledzikc314b462013-04-04 18:59:24 +0000176 // Handle --merge-strings
177 if (parsedArgs->getLastArg(OPT_merge_strings))
178 options->setMergeCommonStrings(true);
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000179
Nick Kledzikc314b462013-04-04 18:59:24 +0000180 // Handle -t
181 if (parsedArgs->getLastArg(OPT_t))
182 options->setLogInputFiles(true);
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000183
184 // Handle --no-allow-shlib-undefined
185 if (parsedArgs->getLastArg(OPT_no_allow_shlib_undefs))
186 options->setAllowShlibUndefines(false);
187
188 // Handle --allow-shlib-undefined
189 if (parsedArgs->getLastArg(OPT_allow_shlib_undefs))
190 options->setAllowShlibUndefines(true);
191
192 // Handle --use-shlib-undefs
193 if (parsedArgs->getLastArg(OPT_use_shlib_undefs))
194 options->setUseShlibUndefines(true);
195
Shankar Easwarana5008e32013-05-29 22:51:01 +0000196 // Handle --dynamic-linker
197 if (llvm::opt::Arg *dynamicLinker =
198 parsedArgs->getLastArg(OPT_dynamic_linker))
199 options->setInterpreter(dynamicLinker->getValue());
200
Nick Kledzikc314b462013-04-04 18:59:24 +0000201 // Handle -Lxxx
202 for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_L),
203 ie = parsedArgs->filtered_end();
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000204 it != ie; ++it) {
Nick Kledzikc314b462013-04-04 18:59:24 +0000205 options->appendSearchPath((*it)->getValue());
206 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000207
Nick Kledzikc314b462013-04-04 18:59:24 +0000208 // Copy mllvm
209 for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_mllvm),
210 ie = parsedArgs->filtered_end();
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000211 it != ie; ++it) {
212 options->appendLLVMOption((*it)->getValue());
Nick Kledzikc314b462013-04-04 18:59:24 +0000213 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000214
Nick Kledzikc314b462013-04-04 18:59:24 +0000215 // Handle input files (full paths and -lxxx)
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000216 for (llvm::opt::arg_iterator
217 it = parsedArgs->filtered_begin(OPT_INPUT, OPT_l),
218 ie = parsedArgs->filtered_end();
219 it != ie; ++it) {
Nick Kledzikc314b462013-04-04 18:59:24 +0000220 switch ((*it)->getOption().getID()) {
221 case OPT_INPUT:
222 options->appendInputFile((*it)->getValue());
223 break;
224 case OPT_l:
225 if (options->appendLibrary((*it)->getValue())) {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000226 diagnostics << "Failed to find library for " << (*it)->getValue()
227 << "\n";
Nick Kledzikc314b462013-04-04 18:59:24 +0000228 return nullptr;
229 }
230 break;
231 default:
232 llvm_unreachable("input option type not handled");
233 }
234 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000235
Nick Kledzikc314b462013-04-04 18:59:24 +0000236 // Validate the combination of options used.
237 if (options->validate(diagnostics))
238 return nullptr;
239
240 return options;
241}
242
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000243/// Get the default target triple based on either the program name
Nick Kledzikc314b462013-04-04 18:59:24 +0000244/// (e.g. "x86-ibm-linux-lld") or the primary target llvm was configured for.
245llvm::Triple GnuLdDriver::getDefaultTarget(const char *progName) {
246 SmallVector<StringRef, 4> components;
247 llvm::SplitString(llvm::sys::path::stem(progName), components, "-");
248 // If has enough parts to be start with a triple.
249 if (components.size() >= 4) {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000250 llvm::Triple triple(components[0], components[1], components[2],
251 components[3]);
Nick Kledzikc314b462013-04-04 18:59:24 +0000252 // If first component looks like an arch.
253 if (triple.getArch() != llvm::Triple::UnknownArch)
254 return triple;
255 }
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000256
Nick Kledzikc314b462013-04-04 18:59:24 +0000257 // Fallback to use whatever default triple llvm was configured for.
258 return llvm::Triple(llvm::sys::getDefaultTargetTriple());
259}