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