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: 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 135 Driver::OptTable::OptTable() 136 : llvm::opt::OptTable(InfoTable) { } 137 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. 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 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. 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 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 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 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 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 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