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