1 //===- Main.cpp -----------------------------------------------------------===//
2 //
3 // The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include <mcld/Environment.h>
10 #include <mcld/IRBuilder.h>
11 #include <mcld/Linker.h>
12 #include <mcld/LinkerConfig.h>
13 #include <mcld/LinkerScript.h>
14 #include <mcld/Module.h>
15 #include <mcld/ADT/StringEntry.h>
16 #include <mcld/MC/InputAction.h>
17 #include <mcld/MC/CommandAction.h>
18 #include <mcld/MC/FileAction.h>
19 #include <mcld/MC/ZOption.h>
20 #include <mcld/Support/raw_ostream.h>
21 #include <mcld/Support/MsgHandling.h>
22 #include <mcld/Support/Path.h>
23 #include <mcld/Support/SystemUtils.h>
24 #include <mcld/Support/TargetRegistry.h>
25
26 #include <llvm/ADT/ArrayRef.h>
27 #include <llvm/ADT/SmallVector.h>
28 #include <llvm/ADT/STLExtras.h>
29 #include <llvm/ADT/StringRef.h>
30 #include <llvm/ADT/StringSwitch.h>
31 #include <llvm/Option/Arg.h>
32 #include <llvm/Option/ArgList.h>
33 #include <llvm/Option/OptTable.h>
34 #include <llvm/Option/Option.h>
35 #include <llvm/Support/ManagedStatic.h>
36 #include <llvm/Support/Process.h>
37 #include <llvm/Support/Signals.h>
38
39 #include <cassert>
40 #include <cstdlib>
41 #include <string>
42
43 #if defined(HAVE_UNISTD_H)
44 #include <unistd.h>
45 #endif
46
47 #if defined(_MSC_VER) || defined(__MINGW32__)
48 #include <io.h>
49 #ifndef STDIN_FILENO
50 #define STDIN_FILENO 0
51 #endif
52 #ifndef STDOUT_FILENO
53 #define STDOUT_FILENO 1
54 #endif
55 #ifndef STDERR_FILENO
56 #define STDERR_FILENO 2
57 #endif
58 #endif
59
60 namespace {
61
62 class Driver {
63 private:
64 enum Option {
65 // This is not an option.
66 kOpt_INVALID = 0,
67 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
68 HELPTEXT, METAVAR) \
69 kOpt_ ## ID,
70 #include "Options.inc" // NOLINT
71 #undef OPTION
72 kOpt_LastOption
73 };
74
75 class OptTable : public llvm::opt::OptTable {
76 private:
77 #define PREFIX(NAME, VALUE) \
78 static const char* const NAME[];
79 #include "Options.inc" // NOLINT
80 #undef PREFIX
81 static const llvm::opt::OptTable::Info InfoTable[];
82
83 public:
84 OptTable();
85 };
86
87 private:
Driver(const char * prog_name,std::unique_ptr<llvm::opt::InputArgList> args)88 Driver(const char* prog_name, std::unique_ptr<llvm::opt::InputArgList> args)
89 : prog_name_(prog_name),
90 args_(std::move(args)),
91 module_(script_),
92 ir_builder_(module_, config_) {
93 return;
94 }
95
96 public:
97 static std::unique_ptr<Driver> Create(llvm::ArrayRef<const char*> argv);
98
99 bool Run();
100
101 private:
102 bool TranslateArguments();
103
104 private:
105 const char* prog_name_;
106
107 std::unique_ptr<llvm::opt::InputArgList> args_;
108
109 mcld::LinkerScript script_;
110
111 mcld::LinkerConfig config_;
112
113 mcld::Module module_;
114
115 mcld::IRBuilder ir_builder_;
116
117 mcld::Linker linker_;
118
119 private:
120 DISALLOW_COPY_AND_ASSIGN(Driver);
121 };
122
123 #define PREFIX(NAME, VALUE) \
124 const char* const Driver::OptTable::NAME[] = VALUE;
125 #include "Options.inc" // NOLINT
126 #undef PREFIX
127
128 const llvm::opt::OptTable::Info Driver::OptTable::InfoTable[] = {
129 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
130 HELPTEXT, METAVAR) \
131 { PREFIX, NAME, HELPTEXT, METAVAR, kOpt_ ## ID, \
132 llvm::opt::Option::KIND ## Class, PARAM, FLAGS, kOpt_ ## GROUP, \
133 kOpt_ ## ALIAS, ALIASARGS },
134 #include "Options.inc"
135 #undef OPTION
136 };
137
OptTable()138 Driver::OptTable::OptTable()
139 : llvm::opt::OptTable(InfoTable, llvm::array_lengthof(InfoTable)) { }
140
ShouldColorize()141 inline bool ShouldColorize() {
142 const char* term = getenv("TERM");
143 return term && (0 != strcmp(term, "dumb"));
144 }
145
146 /// ParseProgName - Parse program name
147 /// This function simplifies cross-compiling by reading triple from the program
148 /// name. For example, if the program name is `arm-linux-eabi-ld.mcld', we can
149 /// get the triple is arm-linux-eabi by the program name.
ParseProgName(const char * prog_name)150 inline std::string ParseProgName(const char* prog_name) {
151 static const char* suffixes[] = {"ld", "ld.mcld"};
152
153 std::string name(mcld::sys::fs::Path(prog_name).stem().native());
154
155 for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
156 if (name == suffixes[i])
157 return std::string();
158 }
159
160 llvm::StringRef prog_name_ref(prog_name);
161 llvm::StringRef prefix;
162
163 for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); ++i) {
164 if (!prog_name_ref.endswith(suffixes[i]))
165 continue;
166
167 llvm::StringRef::size_type last_component =
168 prog_name_ref.rfind('-', prog_name_ref.size() - strlen(suffixes[i]));
169 if (last_component == llvm::StringRef::npos)
170 continue;
171 llvm::StringRef prefix = prog_name_ref.slice(0, last_component);
172 std::string ignored_error;
173 if (!mcld::TargetRegistry::lookupTarget(prefix, ignored_error))
174 continue;
175 return prefix.str();
176 }
177 return std::string();
178 }
179
ParseEmulation(llvm::Triple & triple,const char * emulation)180 inline void ParseEmulation(llvm::Triple& triple, const char* emulation) {
181 llvm::Triple emu_triple =
182 llvm::StringSwitch<llvm::Triple>(emulation)
183 .Case("aarch64linux", llvm::Triple("aarch64", "", "linux", "gnu"))
184 .Case("armelf_linux_eabi", llvm::Triple("arm", "", "linux", "gnu"))
185 .Case("elf_i386", llvm::Triple("i386", "", "", "gnu"))
186 .Case("elf_x86_64", llvm::Triple("x86_64", "", "", "gnu"))
187 .Case("elf32_x86_64", llvm::Triple("x86_64", "", "", "gnux32"))
188 .Case("elf_i386_fbsd", llvm::Triple("i386", "", "freebsd", "gnu"))
189 .Case("elf_x86_64_fbsd", llvm::Triple("x86_64", "", "freebsd", "gnu"))
190 .Case("elf32ltsmip", llvm::Triple("mipsel", "", "", "gnu"))
191 .Case("elf64ltsmip", llvm::Triple("mips64el", "", "", "gnu"))
192 .Default(llvm::Triple());
193
194 if (emu_triple.getArch() == llvm::Triple::UnknownArch &&
195 emu_triple.getOS() == llvm::Triple::UnknownOS &&
196 emu_triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
197 mcld::error(mcld::diag::err_invalid_emulation) << emulation << "\n";
198
199 if (emu_triple.getArch() != llvm::Triple::UnknownArch)
200 triple.setArch(emu_triple.getArch());
201
202 if (emu_triple.getOS() != llvm::Triple::UnknownOS)
203 triple.setOS(emu_triple.getOS());
204
205 if (emu_triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
206 triple.setEnvironment(emu_triple.getEnvironment());
207 }
208
209 /// Configure the output filename.
ConfigureOutputName(llvm::StringRef output_name,mcld::Module & module,mcld::LinkerConfig & config)210 inline bool ConfigureOutputName(llvm::StringRef output_name,
211 mcld::Module& module,
212 mcld::LinkerConfig& config) {
213 std::string output(output_name.str());
214 if (output.empty()) {
215 if (config.targets().triple().getOS() == llvm::Triple::Win32) {
216 output.assign("_out");
217 switch (config.codeGenType()) {
218 case mcld::LinkerConfig::Object: {
219 output += ".obj";
220 break;
221 }
222 case mcld::LinkerConfig::DynObj: {
223 output += ".dll";
224 break;
225 }
226 case mcld::LinkerConfig::Exec: {
227 output += ".exe";
228 break;
229 }
230 case mcld::LinkerConfig::External:
231 break;
232 default: {
233 return false;
234 break;
235 }
236 } // switch (config.codeGenType())
237 } else {
238 output.assign("a.out");
239 }
240 } // if (output.empty())
241
242 module.setName(output);
243 return true;
244 }
245
InitializeInputs(mcld::IRBuilder & ir_builder,std::vector<std::unique_ptr<mcld::InputAction>> & input_actions)246 bool InitializeInputs(mcld::IRBuilder& ir_builder,
247 std::vector<std::unique_ptr<mcld::InputAction>>& input_actions) {
248 for (auto& action : input_actions) {
249 assert(action != nullptr);
250 action->activate(ir_builder.getInputBuilder());
251 }
252
253 if (ir_builder.getInputBuilder().isInGroup()) {
254 mcld::fatal(mcld::diag::fatal_forbid_nest_group);
255 return false;
256 }
257
258 return true;
259 }
260
TranslateArguments()261 bool Driver::TranslateArguments() {
262 //===--------------------------------------------------------------------===//
263 // Preference
264 //===--------------------------------------------------------------------===//
265
266 // --color=mode
267 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Color)) {
268 bool res = llvm::StringSwitch<bool>(arg->getValue())
269 .Case("never", false)
270 .Case("always", true)
271 .Case("auto", ShouldColorize() &&
272 llvm::sys::Process::FileDescriptorIsDisplayed(
273 STDOUT_FILENO))
274 .Default(false);
275 config_.options().setColor(res);
276 mcld::outs().setColor(res);
277 mcld::errs().setColor(res);
278 }
279
280 // --trace
281 config_.options().setTrace(args_->hasArg(kOpt_Trace));
282
283 // --verbose=level
284 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Verbose)) {
285 llvm::StringRef value = arg->getValue();
286 int level;
287 if (value.getAsInteger(0, level)) {
288 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
289 << ": " << arg->getValue();
290 return false;
291 }
292 config_.options().setVerbose(level);
293 }
294
295 // --error-limit NUMBER
296 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ErrorLimit)) {
297 llvm::StringRef value = arg->getValue();
298 int num;
299 if (value.getAsInteger(0, num) || (num < 0)) {
300 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
301 << ": " << arg->getValue();
302 return false;
303 }
304 config_.options().setMaxErrorNum(num);
305 }
306
307 // --warning-limit NUMBER
308 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_WarningLimit)) {
309 llvm::StringRef value = arg->getValue();
310 int num;
311 if (value.getAsInteger(0, num) || (num < 0)) {
312 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
313 << ": " << arg->getValue();
314 return false;
315 }
316 config_.options().setMaxWarnNum(num);
317 }
318
319 // --warn-shared-textrel
320 config_.options().setWarnSharedTextrel(args_->hasArg(kOpt_WarnSharedTextrel));
321
322 //===--------------------------------------------------------------------===//
323 // Target
324 //===--------------------------------------------------------------------===//
325 llvm::Triple triple;
326 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Triple)) {
327 // 1. Use the triple from command.
328 // -mtriple=value
329 triple.setTriple(arg->getValue());
330 } else {
331 std::string prog_triple = ParseProgName(prog_name_);
332 if (!prog_triple.empty()) {
333 // 2. Use the triple from the program name prefix.
334 triple.setTriple(prog_triple);
335 } else {
336 // 3. Use the default target triple.
337 triple.setTriple(mcld::sys::getDefaultTargetTriple());
338 }
339 }
340
341 // If a specific emulation was requested, apply it now.
342 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Emulation)) {
343 // -m emulation
344 ParseEmulation(triple, arg->getValue());
345 } else if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Arch)) {
346 // -march=value
347 config_.targets().setArch(arg->getValue());
348 }
349
350 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_CPU)) {
351 config_.targets().setTargetCPU(arg->getValue());
352 }
353
354 config_.targets().setTriple(triple);
355
356 // --gpsize=value
357 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_GPSize)) {
358 llvm::StringRef value = arg->getValue();
359 int size;
360 if (value.getAsInteger(0, size) || (size< 0)) {
361 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
362 << ": " << arg->getValue() << "\n";
363 return false;
364 }
365 config_.options().setGPSize(size);
366 }
367
368 //===--------------------------------------------------------------------===//
369 // Dynamic
370 //===--------------------------------------------------------------------===//
371
372 // --entry=entry
373 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Entry)) {
374 script_.setEntry(arg->getValue());
375 }
376
377 // -Bsymbolic
378 config_.options().setBsymbolic(args_->hasArg(kOpt_Bsymbolic));
379
380 // -Bgroup
381 config_.options().setBgroup(args_->hasArg(kOpt_Bgroup));
382
383 // -soname=name
384 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_SOName)) {
385 config_.options().setSOName(arg->getValue());
386 }
387
388 // --no-undefined
389 if (args_->hasArg(kOpt_NoUndef)) {
390 config_.options().setNoUndefined(true);
391 }
392
393 // --allow-multiple-definition
394 if (args_->hasArg(kOpt_AllowMulDefs)) {
395 config_.options().setMulDefs(true);
396 }
397
398 // -z options
399 for (llvm::opt::Arg* arg : args_->filtered(kOpt_Z)) {
400 llvm::StringRef value = arg->getValue();
401 mcld::ZOption z_opt =
402 llvm::StringSwitch<mcld::ZOption>(value)
403 .Case("combreloc", mcld::ZOption(mcld::ZOption::CombReloc))
404 .Case("nocombreloc", mcld::ZOption(mcld::ZOption::NoCombReloc))
405 .Case("defs", mcld::ZOption(mcld::ZOption::Defs))
406 .Case("execstack", mcld::ZOption(mcld::ZOption::ExecStack))
407 .Case("noexecstack", mcld::ZOption(mcld::ZOption::NoExecStack))
408 .Case("initfirst", mcld::ZOption(mcld::ZOption::InitFirst))
409 .Case("interpose", mcld::ZOption(mcld::ZOption::InterPose))
410 .Case("loadfltr", mcld::ZOption(mcld::ZOption::LoadFltr))
411 .Case("muldefs", mcld::ZOption(mcld::ZOption::MulDefs))
412 .Case("nocopyreloc", mcld::ZOption(mcld::ZOption::NoCopyReloc))
413 .Case("nodefaultlib", mcld::ZOption(mcld::ZOption::NoDefaultLib))
414 .Case("nodelete", mcld::ZOption(mcld::ZOption::NoDelete))
415 .Case("nodlopen", mcld::ZOption(mcld::ZOption::NoDLOpen))
416 .Case("nodump", mcld::ZOption(mcld::ZOption::NoDump))
417 .Case("relro", mcld::ZOption(mcld::ZOption::Relro))
418 .Case("norelro", mcld::ZOption(mcld::ZOption::NoRelro))
419 .Case("lazy", mcld::ZOption(mcld::ZOption::Lazy))
420 .Case("now", mcld::ZOption(mcld::ZOption::Now))
421 .Case("origin", mcld::ZOption(mcld::ZOption::Origin))
422 .Default(mcld::ZOption());
423
424 if (z_opt.kind() == mcld::ZOption::Unknown) {
425 if (value.startswith("common-page-size=")) {
426 // -z common-page-size=value
427 z_opt.setKind(mcld::ZOption::CommPageSize);
428 long long unsigned size = 0;
429 value.drop_front(17).getAsInteger(0, size);
430 z_opt.setPageSize(static_cast<uint64_t>(size));
431 } else if (value.startswith("max-page-size=")) {
432 // -z max-page-size=value
433 z_opt.setKind(mcld::ZOption::MaxPageSize);
434 long long unsigned size = 0;
435 value.drop_front(14).getAsInteger(0, size);
436 z_opt.setPageSize(static_cast<uint64_t>(size));
437 }
438 }
439 config_.options().addZOption(z_opt);
440 }
441
442 // --dynamic-linker=file
443 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Dyld)) {
444 config_.options().setDyld(arg->getValue());
445 }
446
447 // --enable-new-dtags
448 config_.options().setNewDTags(args_->hasArg(kOpt_EnableNewDTags));
449
450 // --spare-dyanmic-tags COUNT
451 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_SpareDTags)) {
452 llvm::StringRef value = arg->getValue();
453 int num;
454 if (value.getAsInteger(0, num) || (num < 0)) {
455 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
456 << ": " << arg->getValue() << "\n";
457 return false;
458 }
459 config_.options().setNumSpareDTags(num);
460 }
461
462 //===--------------------------------------------------------------------===//
463 // Output
464 //===--------------------------------------------------------------------===//
465
466 // Setup the codegen type.
467 if (args_->hasArg(kOpt_Shared) || args_->hasArg(kOpt_PIE)) {
468 // -shared, -pie
469 config_.setCodeGenType(mcld::LinkerConfig::DynObj);
470 } else if (args_->hasArg(kOpt_Relocatable)) {
471 // -r
472 config_.setCodeGenType(mcld::LinkerConfig::Object);
473 } else if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_OutputFormat)) {
474 // --oformat=value
475 llvm::StringRef value = arg->getValue();
476 if (value.equals("binary")) {
477 config_.setCodeGenType(mcld::LinkerConfig::Binary);
478 }
479 } else {
480 config_.setCodeGenType(mcld::LinkerConfig::Exec);
481 }
482
483 // Setup the output filename.
484 llvm::StringRef output_name;
485 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Output)) {
486 output_name = arg->getValue();
487 }
488 if (!ConfigureOutputName(output_name, module_, config_)) {
489 mcld::unreachable(mcld::diag::unrecognized_output_file) << module_.name();
490 return false;
491 } else {
492 if (!args_->hasArg(kOpt_SOName)) {
493 config_.options().setSOName(module_.name());
494 }
495 }
496
497 // --format=value
498 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_InputFormat)) {
499 llvm::StringRef value = arg->getValue();
500 if (value.equals("binary")) {
501 config_.options().setBinaryInput();
502 }
503 }
504
505 // Setup debug info stripping.
506 config_.options().setStripDebug(args_->hasArg(kOpt_StripDebug) ||
507 args_->hasArg(kOpt_StripAll));
508
509 // Setup symbol stripping mode.
510 if (args_->hasArg(kOpt_StripAll)) {
511 config_.options().setStripSymbols(
512 mcld::GeneralOptions::StripSymbolMode::StripAllSymbols);
513 } else if (args_->hasArg(kOpt_DiscardAll)) {
514 config_.options().setStripSymbols(
515 mcld::GeneralOptions::StripSymbolMode::StripLocals);
516 } else if (args_->hasArg(kOpt_DiscardLocals)) {
517 config_.options().setStripSymbols(
518 mcld::GeneralOptions::StripSymbolMode::StripTemporaries);
519 } else {
520 config_.options().setStripSymbols(
521 mcld::GeneralOptions::StripSymbolMode::KeepAllSymbols);
522 }
523
524 // --eh-frame-hdr
525 config_.options().setEhFrameHdr(args_->hasArg(kOpt_EHFrameHdr));
526
527 // -pie
528 config_.options().setPIE(args_->hasArg(kOpt_PIE));
529
530 // --nmagic
531 config_.options().setNMagic(args_->hasArg(kOpt_NMagic));
532
533 // --omagic
534 config_.options().setOMagic(args_->hasArg(kOpt_OMagic));
535
536 // --hash-style=style
537 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_HashStyle)) {
538 mcld::GeneralOptions::HashStyle style =
539 llvm::StringSwitch<mcld::GeneralOptions::HashStyle>(arg->getValue())
540 .Case("sysv", mcld::GeneralOptions::HashStyle::SystemV)
541 .Case("gnu", mcld::GeneralOptions::HashStyle::GNU)
542 .Case("both", mcld::GeneralOptions::HashStyle::Both)
543 .Default(mcld::GeneralOptions::HashStyle::Unknown);
544 if (style != mcld::GeneralOptions::HashStyle::Unknown) {
545 config_.options().setHashStyle(style);
546 }
547 }
548
549 // --[no]-export-dynamic
550 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ExportDynamic,
551 kOpt_NoExportDynamic)) {
552 if (arg->getOption().matches(kOpt_ExportDynamic)) {
553 config_.options().setExportDynamic(true);
554 } else {
555 config_.options().setExportDynamic(false);
556 }
557 }
558
559 // --no-warn-mismatch
560 config_.options().setWarnMismatch(!args_->hasArg(kOpt_NoWarnMismatch));
561
562 // --exclude-libs
563 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ExcludeLibs)) {
564 llvm::StringRef value = arg->getValue();
565 do {
566 std::pair<llvm::StringRef, llvm::StringRef> res = value.split(',');
567 config_.options().excludeLIBS().insert(res.first.str());
568 value = res.second;
569 } while (!value.empty());
570 }
571
572 //===--------------------------------------------------------------------===//
573 // Search Path
574 //===--------------------------------------------------------------------===//
575
576 // --sysroot
577 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Sysroot)) {
578 mcld::sys::fs::Path path(arg->getValue());
579 if (mcld::sys::fs::exists(path) && mcld::sys::fs::is_directory(path)) {
580 script_.setSysroot(path);
581 }
582 }
583
584 // -L searchdir
585 for (llvm::opt::Arg* arg : args_->filtered(kOpt_LibraryPath)) {
586 if (!script_.directories().insert(arg->getValue())) {
587 // FIXME: need a warning function
588 mcld::errs() << "WARNING: can not open search directory `-L"
589 << arg->getValue() << "'.\n";
590 }
591 }
592
593 // -nostdlib
594 config_.options().setNoStdlib(args_->hasArg(kOpt_NoStdlib));
595
596 // -rpath=path
597 for (llvm::opt::Arg* arg : args_->filtered(kOpt_RPath)) {
598 config_.options().getRpathList().push_back(arg->getValue());
599 }
600
601 //===--------------------------------------------------------------------===//
602 // Symbol
603 //===--------------------------------------------------------------------===//
604
605 // -d/-dc/-dp
606 config_.options().setDefineCommon(args_->hasArg(kOpt_DefineCommon));
607
608 // -u symbol
609 for (llvm::opt::Arg* arg : args_->filtered(kOpt_Undefined)) {
610 config_.options().getUndefSymList().push_back(arg->getValue());
611 }
612
613 //===--------------------------------------------------------------------===//
614 // Script
615 //===--------------------------------------------------------------------===//
616
617 // --wrap=symbol
618 for (llvm::opt::Arg* arg : args_->filtered(kOpt_Wrap)) {
619 bool exist = false;
620 const char* symbol = arg->getValue();
621 // symbol -> __wrap_symbol
622 mcld::StringEntry<llvm::StringRef>* to_wrap =
623 script_.renameMap().insert(symbol, exist);
624
625 std::string to_wrap_str;
626 to_wrap_str.append("__wrap_")
627 .append(symbol);
628 to_wrap->setValue(to_wrap_str);
629
630 if (exist)
631 mcld::warning(mcld::diag::rewrap) << symbol << to_wrap_str;
632
633 // __real_symbol -> symbol
634 std::string from_real_str;
635 to_wrap_str.append("__real_")
636 .append(symbol);
637 mcld::StringEntry<llvm::StringRef>* from_real =
638 script_.renameMap().insert(from_real_str, exist);
639 from_real->setValue(symbol);
640
641 if (exist)
642 mcld::warning(mcld::diag::rewrap) << symbol << from_real_str;
643 }
644
645 // --portalbe=symbol
646 for (llvm::opt::Arg* arg : args_->filtered(kOpt_Wrap)) {
647 bool exist = false;
648 const char* symbol = arg->getValue();
649 // symbol -> symbol_portable
650 mcld::StringEntry<llvm::StringRef>* to_wrap =
651 script_.renameMap().insert(symbol, exist);
652
653 std::string to_wrap_str;
654 to_wrap_str.append(symbol)
655 .append("_portable");
656 to_wrap->setValue(to_wrap_str);
657
658 if (exist)
659 mcld::warning(mcld::diag::rewrap) << symbol << to_wrap_str;
660
661 // __real_symbol -> symbol
662 std::string from_real_str;
663 to_wrap_str.append("__real_")
664 .append(symbol);
665 mcld::StringEntry<llvm::StringRef>* from_real =
666 script_.renameMap().insert(from_real_str, exist);
667 from_real->setValue(symbol);
668
669 if (exist)
670 mcld::warning(mcld::diag::rewrap) << symbol << from_real_str;
671 }
672
673 // --section-start=section=addr
674 for (llvm::opt::Arg* arg : args_->filtered(kOpt_SectionStart)) {
675 llvm::StringRef value = arg->getValue();
676 const size_t pos = value.find('=');
677 uint64_t addr = 0;
678 value.substr(pos + 1).getAsInteger(0, addr);
679 bool exist = false;
680 mcld::StringEntry<uint64_t>* mapping =
681 script_.addressMap().insert(value.substr(0, pos), exist);
682 mapping->setValue(addr);
683 }
684
685 // -Tbss=value
686 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Tbss)) {
687 llvm::StringRef value = arg->getValue();
688 uint64_t addr = 0;
689 if (value.getAsInteger(0, addr)) {
690 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
691 << ": " << arg->getValue() << "\n";
692 return false;
693 }
694 bool exist = false;
695 mcld::StringEntry<uint64_t>* mapping =
696 script_.addressMap().insert(".bss", exist);
697 mapping->setValue(addr);
698 }
699
700 // -Tdata=value
701 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Tdata)) {
702 llvm::StringRef value = arg->getValue();
703 uint64_t addr = 0;
704 if (value.getAsInteger(0, addr)) {
705 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
706 << ": " << arg->getValue() << "\n";
707 return false;
708 }
709 bool exist = false;
710 mcld::StringEntry<uint64_t>* mapping =
711 script_.addressMap().insert(".data", exist);
712 mapping->setValue(addr);
713 }
714
715 // -Ttext=value
716 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_Ttext)) {
717 llvm::StringRef value = arg->getValue();
718 uint64_t addr = 0;
719 if (value.getAsInteger(0, addr)) {
720 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
721 << ": " << arg->getValue() << "\n";
722 return false;
723 }
724 bool exist = false;
725 mcld::StringEntry<uint64_t>* mapping =
726 script_.addressMap().insert(".text", exist);
727 mapping->setValue(addr);
728 }
729
730 //===--------------------------------------------------------------------===//
731 // Optimization
732 //===--------------------------------------------------------------------===//
733
734 // --[no-]gc-sections
735 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_GCSections,
736 kOpt_NoGCSections)) {
737 if (arg->getOption().matches(kOpt_GCSections)) {
738 config_.options().setGCSections(true);
739 } else {
740 config_.options().setGCSections(false);
741 }
742 }
743
744 // --[no-]print-gc-sections
745 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_PrintGCSections,
746 kOpt_NoPrintGCSections)) {
747 if (arg->getOption().matches(kOpt_PrintGCSections)) {
748 config_.options().setPrintGCSections(true);
749 } else {
750 config_.options().setPrintGCSections(false);
751 }
752 }
753
754 // --[no-]ld-generated-unwind-info
755 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_LDGeneratedUnwindInfo,
756 kOpt_NoLDGeneratedUnwindInfo)) {
757 if (arg->getOption().matches(kOpt_LDGeneratedUnwindInfo)) {
758 config_.options().setGenUnwindInfo(true);
759 } else {
760 config_.options().setGenUnwindInfo(false);
761 }
762 }
763
764 // --icf=mode
765 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ICF)) {
766 mcld::GeneralOptions::ICF mode =
767 llvm::StringSwitch<mcld::GeneralOptions::ICF>(arg->getValue())
768 .Case("none", mcld::GeneralOptions::ICF::None)
769 .Case("all", mcld::GeneralOptions::ICF::All)
770 .Case("safe", mcld::GeneralOptions::ICF::Safe)
771 .Default(mcld::GeneralOptions::ICF::Unknown);
772 if (mode == mcld::GeneralOptions::ICF::Unknown) {
773 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
774 << ": " << arg->getValue() << "\n";
775 return false;
776 }
777 config_.options().setICFMode(mode);
778 }
779
780 // --icf-iterations
781 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_ICFIters)) {
782 llvm::StringRef value = arg->getValue();
783 int num;
784 if (value.getAsInteger(0, num) || (num < 0)) {
785 mcld::errs() << "Invalid value for" << arg->getOption().getPrefixedName()
786 << ": " << arg->getValue() << "\n";
787 return false;
788 }
789 config_.options().setICFIterations(num);
790 }
791
792 // --[no-]print-icf-sections
793 if (llvm::opt::Arg* arg = args_->getLastArg(kOpt_PrintICFSections,
794 kOpt_NoPrintICFSections)) {
795 if (arg->getOption().matches(kOpt_PrintICFSections)) {
796 config_.options().setPrintICFSections(true);
797 } else {
798 config_.options().setPrintICFSections(false);
799 }
800 }
801
802 //===--------------------------------------------------------------------===//
803 // Positional
804 //===--------------------------------------------------------------------===//
805
806 // # of regular objects, script, and namespec.
807 size_t input_num = 0;
808 typedef std::unique_ptr<mcld::InputAction> Action;
809
810 std::vector<Action> actions;
811 Action action;
812 actions.reserve(32);
813
814 for (llvm::opt::Arg* arg : *args_) {
815 const unsigned index = arg->getIndex();
816
817 switch (arg->getOption().getID()) {
818 // -T script
819 case kOpt_Script: {
820 const char* value = arg->getValue();
821 config_.options().getScriptList().push_back(value);
822
823 // FIXME: Let index of script file be 0.
824 action.reset(new mcld::ScriptAction(
825 0x0, value, mcld::ScriptFile::LDScript, script_.directories()));
826 actions.push_back(std::move(action));
827
828 action.reset(new mcld::ContextAction(0x0));
829 actions.push_back(std::move(action));
830
831 action.reset(new mcld::MemoryAreaAction(0x0,
832 mcld::FileHandle::ReadOnly));
833 actions.push_back(std::move(action));
834
835 ++input_num;
836 break;
837 }
838
839 // --defsym=symbol=expr
840 case kOpt_DefSym: {
841 std::string expr;
842 expr.append(arg->getValue())
843 .append(";");
844 script_.defsyms().push_back(std::move(expr));
845 action.reset(new mcld::DefSymAction(index, script_.defsyms().back()));
846 actions.push_back(std::move(action));
847 break;
848 }
849
850 // -l namespec
851 case kOpt_Namespec: {
852 action.reset(new mcld::NamespecAction(
853 index, arg->getValue(), script_.directories()));
854 actions.push_back(std::move(action));
855
856 action.reset(new mcld::ContextAction(index));
857 actions.push_back(std::move(action));
858
859 action.reset(new mcld::MemoryAreaAction(index,
860 mcld::FileHandle::ReadOnly));
861 actions.push_back(std::move(action));
862
863 ++input_num;
864 break;
865 }
866
867 // --whole-archive
868 case kOpt_WholeArchive: {
869 action.reset(new mcld::WholeArchiveAction(index));
870 actions.push_back(std::move(action));
871 break;
872 }
873
874 // --no-whole-archive
875 case kOpt_NoWholeArchive: {
876 action.reset(new mcld::NoWholeArchiveAction(index));
877 actions.push_back(std::move(action));
878 break;
879 }
880
881 // --as-needed
882 case kOpt_AsNeeded: {
883 action.reset(new mcld::AsNeededAction(index));
884 actions.push_back(std::move(action));
885 break;
886 }
887
888 // --no-as-needed
889 case kOpt_NoAsNeeded: {
890 action.reset(new mcld::NoAsNeededAction(index));
891 actions.push_back(std::move(action));
892 break;
893 }
894
895 // --add-needed
896 // FIXME: This is deprecated. Should be --copy-dt-needed-entries.
897 case kOpt_AddNeeded:
898 case kOpt_CopyDTNeeded: {
899 action.reset(new mcld::AddNeededAction(index));
900 actions.push_back(std::move(action));
901 break;
902 }
903
904 // --no-add-needed
905 // FIXME: This is deprecated. Should be --no-copy-dt-needed-entries.
906 case kOpt_NoAddNeeded:
907 case kOpt_NoCopyDTNeeded: {
908 action.reset(new mcld::AddNeededAction(index));
909 actions.push_back(std::move(action));
910 break;
911 }
912
913 // -Bdynamic
914 case kOpt_Bdynamic: {
915 action.reset(new mcld::BDynamicAction(index));
916 actions.push_back(std::move(action));
917 break;
918 }
919
920 // -Bstatic
921 case kOpt_Bstatic: {
922 action.reset(new mcld::BStaticAction(index));
923 actions.push_back(std::move(action));
924 break;
925 }
926
927 // --start-group
928 case kOpt_StartGroup: {
929 action.reset(new mcld::StartGroupAction(index));
930 actions.push_back(std::move(action));
931 break;
932 }
933
934 // --end-group
935 case kOpt_EndGroup: {
936 action.reset(new mcld::EndGroupAction(index));
937 actions.push_back(std::move(action));
938 break;
939 }
940
941 case kOpt_INPUT: {
942 action.reset(new mcld::InputFileAction(index, arg->getValue()));
943 actions.push_back(std::move(action));
944
945 action.reset(new mcld::ContextAction(index));
946 actions.push_back(std::move(action));
947
948 action.reset(new mcld::MemoryAreaAction(index,
949 mcld::FileHandle::ReadOnly));
950 actions.push_back(std::move(action));
951
952 ++input_num;
953 break;
954 }
955
956 default:
957 break;
958 }
959 }
960
961 if (input_num == 0) {
962 mcld::fatal(mcld::diag::err_no_inputs);
963 return false;
964 }
965
966 // Stable sort
967 std::stable_sort(actions.begin(),
968 actions.end(),
969 [] (const Action& X, const Action& Y) {
970 return X->position() < Y->position();
971 });
972
973 if (!InitializeInputs(ir_builder_, actions)) {
974 mcld::errs() << "Failed to initialize input tree!\n";
975 return false;
976 }
977
978 return true;
979 }
980
981 std::unique_ptr<llvm::opt::InputArgList>
ParseArgs(const llvm::opt::OptTable & opt_table,llvm::ArrayRef<const char * > argv)982 ParseArgs(const llvm::opt::OptTable& opt_table,
983 llvm::ArrayRef<const char*> argv) {
984 unsigned missing_arg_idx;
985 unsigned missing_arg_count;
986
987 std::unique_ptr<llvm::opt::InputArgList> args(
988 opt_table.ParseArgs(argv.begin(), argv.end(), missing_arg_idx,
989 missing_arg_count));
990 if (missing_arg_count > 0) {
991 mcld::errs() << "Argument to '" << args->getArgString(missing_arg_idx)
992 << "' is missing (expected " << missing_arg_count
993 << ((missing_arg_count > 1) ? " values" : " value") << ")\n";
994 return nullptr;
995 }
996
997 return args;
998 }
999
Create(llvm::ArrayRef<const char * > argv)1000 std::unique_ptr<Driver> Driver::Create(llvm::ArrayRef<const char*> argv) {
1001 // Parse command line options.
1002 OptTable opt_table;
1003 std::unique_ptr<llvm::opt::InputArgList> args = ParseArgs(opt_table,
1004 argv.slice(1));
1005 if (args == nullptr) {
1006 return nullptr;
1007 }
1008
1009 std::unique_ptr<Driver> result(new Driver(argv[0], std::move(args)));
1010
1011 // Return quickly if -help is specified.
1012 if (result->args_->hasArg(kOpt_Help)) {
1013 opt_table.PrintHelp(mcld::outs(), argv[0], "MCLinker",
1014 /* FlagsToInclude */0, /* FlagsToExclude */0);
1015 return nullptr;
1016 }
1017
1018 // Print version information if requested.
1019 if (result->args_->hasArg(kOpt_Version)) {
1020 mcld::outs() << result->config_.options().getVersionString() << "\n";
1021 }
1022
1023 // Setup instance from arguments.
1024 if (!result->TranslateArguments()) {
1025 return nullptr;
1026 }
1027
1028 return result;
1029 }
1030
Run()1031 bool Driver::Run() {
1032 mcld::Initialize();
1033
1034 if (!linker_.emulate(script_, config_)) {
1035 mcld::errs() << "Failed to emulate target!\n";
1036 return false;
1037 }
1038
1039 if (!linker_.link(module_, ir_builder_)) {
1040 mcld::errs() << "Failed to link objects!\n";
1041 return false;
1042 }
1043
1044 if (!linker_.emit(module_, module_.name())) {
1045 mcld::errs() << "Failed to emit output!\n";
1046 return false;
1047 }
1048
1049 mcld::Finalize();
1050 return true;
1051 }
1052
1053 } // anonymous namespace
1054
main(int argc,char ** argv)1055 int main(int argc, char** argv) {
1056 std::unique_ptr<Driver> driver =
1057 Driver::Create(llvm::makeArrayRef(argv, argc));
1058
1059 if ((driver == nullptr) || !driver->Run()) {
1060 return EXIT_FAILURE;
1061 } else {
1062 return EXIT_SUCCESS;
1063 }
1064 }
1065