blob: 55e3858002961a0bd48b0c95521331dbdfd1e3a5 [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;
80
81 return link(*options, diagnostics);
82}
83
84
85std::unique_ptr<ELFTargetInfo> GnuLdDriver::parse(int argc, const char *argv[],
86 raw_ostream &diagnostics) {
87 // Parse command line options using LDOptions.td
88 std::unique_ptr<llvm::opt::InputArgList> parsedArgs;
89 GnuLdOptTable table;
90 unsigned missingIndex;
91 unsigned missingCount;
92 parsedArgs.reset(table.ParseArgs(&argv[1], &argv[argc],
93 missingIndex, missingCount));
94 if (missingCount) {
95 diagnostics << "error: missing arg value for '"
96 << parsedArgs->getArgString(missingIndex)
97 << "' expected " << missingCount << " argument(s).\n";
98 return nullptr;
99 }
100
101 for (auto it = parsedArgs->filtered_begin(OPT_UNKNOWN),
102 ie = parsedArgs->filtered_end(); it != ie; ++it) {
103 diagnostics << "warning: ignoring unknown argument: "
104 << (*it)->getAsString(*parsedArgs) << "\n";
105 }
106
107 // 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;
115 if (llvm::opt::Arg *trip = parsedArgs->getLastArg(OPT_target))
116 triple = llvm::Triple(trip->getValue());
117 else
118 triple = getDefaultTarget(argv[0]);
119 std::unique_ptr<ELFTargetInfo> options(ELFTargetInfo::create(triple));
120
121 if (!options) {
122 diagnostics << "unknown target triple\n";
123 return nullptr;
124 }
125
126 // Handle -e xxx
127 if (llvm::opt::Arg *entry = parsedArgs->getLastArg(OPT_entry))
128 options->setEntrySymbolName(entry->getValue());
129
130 // Handle -emit-yaml
131 if (parsedArgs->getLastArg(OPT_emit_yaml))
132 options->setOutputYAML(true);
133
134 // Handle -o xxx
135 if (llvm::opt::Arg *output = parsedArgs->getLastArg(OPT_output))
136 options->setOutputPath(output->getValue());
137 else if (options->outputYAML())
138 options->setOutputPath("-"); // yaml writes to stdout by default
139 else
140 options->setOutputPath("a.out");
141
142 // Handle -r, -shared, or -static
143 if ( llvm::opt::Arg *kind = parsedArgs->getLastArg(OPT_relocatable,
144 OPT_shared,
145 OPT_static)) {
146 switch (kind->getOption().getID()) {
147 case OPT_relocatable:
148 options->setOutputFileType(llvm::ELF::ET_REL);
149 options->setPrintRemainingUndefines(false);
150 options->setAllowRemainingUndefines(true);
151 break;
152 case OPT_shared:
153 options->setOutputFileType(llvm::ELF::ET_DYN);
154 break;
155 case OPT_static:
156 options->setOutputFileType(llvm::ELF::ET_EXEC);
157 options->setIsStaticExecutable(true);
158 break;
159 }
160 }
161 else {
162 options->setOutputFileType(llvm::ELF::ET_EXEC);
163 options->setIsStaticExecutable(false);
164 }
165
166 // Handle --noinhibit-exec
167 if (parsedArgs->getLastArg(OPT_noinhibit_exec))
168 options->setAllowRemainingUndefines(true);
169
170 // Handle --force-load
171 if (parsedArgs->getLastArg(OPT_force_load))
172 options->setForceLoadAllArchives(true);
173
174 // Handle --merge-strings
175 if (parsedArgs->getLastArg(OPT_merge_strings))
176 options->setMergeCommonStrings(true);
177
178 // Handle -t
179 if (parsedArgs->getLastArg(OPT_t))
180 options->setLogInputFiles(true);
181
182 // Handle -Lxxx
183 for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_L),
184 ie = parsedArgs->filtered_end();
185 it != ie; ++it) {
186 options->appendSearchPath((*it)->getValue());
187 }
188
189 // Copy mllvm
190 for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_mllvm),
191 ie = parsedArgs->filtered_end();
192 it != ie; ++it) {
193 options->appendLLVMOption((*it)->getValue());
194 }
195
196 // Handle input files (full paths and -lxxx)
197 for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_INPUT,OPT_l),
198 ie = parsedArgs->filtered_end();
199 it != ie; ++it) {
200 switch ((*it)->getOption().getID()) {
201 case OPT_INPUT:
202 options->appendInputFile((*it)->getValue());
203 break;
204 case OPT_l:
205 if (options->appendLibrary((*it)->getValue())) {
206 diagnostics << "Failed to find library for "
207 << (*it)->getValue() << "\n";
208 return nullptr;
209 }
210 break;
211 default:
212 llvm_unreachable("input option type not handled");
213 }
214 }
215
216 // Validate the combination of options used.
217 if (options->validate(diagnostics))
218 return nullptr;
219
220 return options;
221}
222
223
224/// Get the default target triple based on either the program name
225/// (e.g. "x86-ibm-linux-lld") or the primary target llvm was configured for.
226llvm::Triple GnuLdDriver::getDefaultTarget(const char *progName) {
227 SmallVector<StringRef, 4> components;
228 llvm::SplitString(llvm::sys::path::stem(progName), components, "-");
229 // If has enough parts to be start with a triple.
230 if (components.size() >= 4) {
231 llvm::Triple triple(components[0], components[1], components[2],
232 components[3]);
233 // If first component looks like an arch.
234 if (triple.getArch() != llvm::Triple::UnknownArch)
235 return triple;
236 }
237
238 // Fallback to use whatever default triple llvm was configured for.
239 return llvm::Triple(llvm::sys::getDefaultTargetTriple());
240}
241