1 //===- Driver.cpp ---------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lld/Common/Driver.h" 11 #include "Config.h" 12 #include "InputChunks.h" 13 #include "InputGlobal.h" 14 #include "MarkLive.h" 15 #include "SymbolTable.h" 16 #include "Writer.h" 17 #include "lld/Common/Args.h" 18 #include "lld/Common/ErrorHandler.h" 19 #include "lld/Common/Memory.h" 20 #include "lld/Common/Strings.h" 21 #include "lld/Common/Threads.h" 22 #include "lld/Common/Version.h" 23 #include "llvm/ADT/Twine.h" 24 #include "llvm/Object/Wasm.h" 25 #include "llvm/Option/ArgList.h" 26 #include "llvm/Support/CommandLine.h" 27 #include "llvm/Support/Path.h" 28 #include "llvm/Support/Process.h" 29 30 #define DEBUG_TYPE "lld" 31 32 using namespace llvm; 33 using namespace llvm::sys; 34 using namespace llvm::wasm; 35 36 using namespace lld; 37 using namespace lld::wasm; 38 39 Configuration *lld::wasm::Config; 40 41 namespace { 42 43 // Create enum with OPT_xxx values for each option in Options.td 44 enum { 45 OPT_INVALID = 0, 46 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID, 47 #include "Options.inc" 48 #undef OPTION 49 }; 50 51 class LinkerDriver { 52 public: 53 void link(ArrayRef<const char *> ArgsArr); 54 55 private: 56 void createFiles(opt::InputArgList &Args); 57 void addFile(StringRef Path); 58 void addLibrary(StringRef Name); 59 std::vector<InputFile *> Files; 60 }; 61 } // anonymous namespace 62 63 bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly, 64 raw_ostream &Error) { 65 errorHandler().LogName = Args[0]; 66 errorHandler().ErrorOS = &Error; 67 errorHandler().ColorDiagnostics = Error.has_colors(); 68 errorHandler().ErrorLimitExceededMsg = 69 "too many errors emitted, stopping now (use " 70 "-error-limit=0 to see all errors)"; 71 72 Config = make<Configuration>(); 73 Symtab = make<SymbolTable>(); 74 75 LinkerDriver().link(Args); 76 77 // Exit immediately if we don't need to return to the caller. 78 // This saves time because the overhead of calling destructors 79 // for all globally-allocated objects is not negligible. 80 if (CanExitEarly) 81 exitLld(errorCount() ? 1 : 0); 82 83 freeArena(); 84 return !errorCount(); 85 } 86 87 // Create prefix string literals used in Options.td 88 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; 89 #include "Options.inc" 90 #undef PREFIX 91 92 // Create table mapping all options defined in Options.td 93 static const opt::OptTable::Info OptInfo[] = { 94 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ 95 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ 96 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, 97 #include "Options.inc" 98 #undef OPTION 99 }; 100 101 class WasmOptTable : public llvm::opt::OptTable { 102 public: 103 WasmOptTable() : OptTable(OptInfo) {} 104 opt::InputArgList parse(ArrayRef<const char *> Argv); 105 }; 106 107 // Set color diagnostics according to -color-diagnostics={auto,always,never} 108 // or -no-color-diagnostics flags. 109 static void handleColorDiagnostics(opt::InputArgList &Args) { 110 auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, 111 OPT_no_color_diagnostics); 112 if (!Arg) 113 return; 114 if (Arg->getOption().getID() == OPT_color_diagnostics) { 115 errorHandler().ColorDiagnostics = true; 116 } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) { 117 errorHandler().ColorDiagnostics = false; 118 } else { 119 StringRef S = Arg->getValue(); 120 if (S == "always") 121 errorHandler().ColorDiagnostics = true; 122 else if (S == "never") 123 errorHandler().ColorDiagnostics = false; 124 else if (S != "auto") 125 error("unknown option: --color-diagnostics=" + S); 126 } 127 } 128 129 // Find a file by concatenating given paths. 130 static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) { 131 SmallString<128> S; 132 path::append(S, Path1, Path2); 133 if (fs::exists(S)) 134 return S.str().str(); 135 return None; 136 } 137 138 opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) { 139 SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size()); 140 141 unsigned MissingIndex; 142 unsigned MissingCount; 143 opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount); 144 145 handleColorDiagnostics(Args); 146 for (auto *Arg : Args.filtered(OPT_UNKNOWN)) 147 error("unknown argument: " + Arg->getSpelling()); 148 return Args; 149 } 150 151 // Currently we allow a ".imports" to live alongside a library. This can 152 // be used to specify a list of symbols which can be undefined at link 153 // time (imported from the environment. For example libc.a include an 154 // import file that lists the syscall functions it relies on at runtime. 155 // In the long run this information would be better stored as a symbol 156 // attribute/flag in the object file itself. 157 // See: https://github.com/WebAssembly/tool-conventions/issues/35 158 static void readImportFile(StringRef Filename) { 159 if (Optional<MemoryBufferRef> Buf = readFile(Filename)) 160 for (StringRef Sym : args::getLines(*Buf)) 161 Config->AllowUndefinedSymbols.insert(Sym); 162 } 163 164 void LinkerDriver::addFile(StringRef Path) { 165 Optional<MemoryBufferRef> Buffer = readFile(Path); 166 if (!Buffer.hasValue()) 167 return; 168 MemoryBufferRef MBRef = *Buffer; 169 170 if (identify_magic(MBRef.getBuffer()) == file_magic::archive) { 171 SmallString<128> ImportFile = Path; 172 path::replace_extension(ImportFile, ".imports"); 173 if (fs::exists(ImportFile)) 174 readImportFile(ImportFile.str()); 175 176 Files.push_back(make<ArchiveFile>(MBRef)); 177 return; 178 } 179 180 Files.push_back(make<ObjFile>(MBRef)); 181 } 182 183 // Add a given library by searching it from input search paths. 184 void LinkerDriver::addLibrary(StringRef Name) { 185 for (StringRef Dir : Config->SearchPaths) { 186 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) { 187 addFile(*S); 188 return; 189 } 190 } 191 192 error("unable to find library -l" + Name); 193 } 194 195 void LinkerDriver::createFiles(opt::InputArgList &Args) { 196 for (auto *Arg : Args) { 197 switch (Arg->getOption().getUnaliasedOption().getID()) { 198 case OPT_l: 199 addLibrary(Arg->getValue()); 200 break; 201 case OPT_INPUT: 202 addFile(Arg->getValue()); 203 break; 204 } 205 } 206 } 207 208 static StringRef getEntry(opt::InputArgList &Args, StringRef Default) { 209 auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry); 210 if (!Arg) 211 return Default; 212 if (Arg->getOption().getID() == OPT_no_entry) 213 return ""; 214 return Arg->getValue(); 215 } 216 217 static const uint8_t UnreachableFn[] = { 218 0x03 /* ULEB length */, 0x00 /* ULEB num locals */, 219 0x00 /* opcode unreachable */, 0x0b /* opcode end */ 220 }; 221 222 // For weak undefined functions, there may be "call" instructions that reference 223 // the symbol. In this case, we need to synthesise a dummy/stub function that 224 // will abort at runtime, so that relocations can still provided an operand to 225 // the call instruction that passes Wasm validation. 226 static void handleWeakUndefines() { 227 for (Symbol *Sym : Symtab->getSymbols()) { 228 if (!Sym->isUndefined() || !Sym->isWeak()) 229 continue; 230 auto *FuncSym = dyn_cast<FunctionSymbol>(Sym); 231 if (!FuncSym) 232 continue; 233 234 // It is possible for undefined functions not to have a signature (eg. if 235 // added via "--undefined"), but weak undefined ones do have a signature. 236 assert(FuncSym->getFunctionType()); 237 const WasmSignature &Sig = *FuncSym->getFunctionType(); 238 239 // Add a synthetic dummy for weak undefined functions. These dummies will 240 // be GC'd if not used as the target of any "call" instructions. 241 Optional<std::string> SymName = demangleItanium(Sym->getName()); 242 StringRef DebugName = 243 Saver.save("undefined function " + 244 (SymName ? StringRef(*SymName) : Sym->getName())); 245 SyntheticFunction *Func = 246 make<SyntheticFunction>(Sig, Sym->getName(), DebugName); 247 Func->setBody(UnreachableFn); 248 // Ensure it compares equal to the null pointer, and so that table relocs 249 // don't pull in the stub body (only call-operand relocs should do that). 250 Func->setTableIndex(0); 251 Symtab->SyntheticFunctions.emplace_back(Func); 252 // Hide our dummy to prevent export. 253 uint32_t Flags = WASM_SYMBOL_VISIBILITY_HIDDEN; 254 replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Flags, nullptr, Func); 255 } 256 } 257 258 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { 259 WasmOptTable Parser; 260 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); 261 262 // Handle --help 263 if (Args.hasArg(OPT_help)) { 264 Parser.PrintHelp(outs(), ArgsArr[0], "LLVM Linker", false); 265 return; 266 } 267 268 // Handle --version 269 if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) { 270 outs() << getLLDVersion() << "\n"; 271 return; 272 } 273 274 // Parse and evaluate -mllvm options. 275 std::vector<const char *> V; 276 V.push_back("wasm-ld (LLVM option parsing)"); 277 for (auto *Arg : Args.filtered(OPT_mllvm)) 278 V.push_back(Arg->getValue()); 279 cl::ParseCommandLineOptions(V.size(), V.data()); 280 281 errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20); 282 283 Config->AllowUndefined = Args.hasArg(OPT_allow_undefined); 284 Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true); 285 Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start"); 286 Config->ExportTable = Args.hasArg(OPT_export_table); 287 errorHandler().FatalWarnings = 288 Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); 289 Config->ImportMemory = Args.hasArg(OPT_import_memory); 290 Config->ImportTable = Args.hasArg(OPT_import_table); 291 Config->OutputFile = Args.getLastArgValue(OPT_o); 292 Config->Relocatable = Args.hasArg(OPT_relocatable); 293 Config->GcSections = 294 Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable); 295 Config->MergeDataSegments = 296 Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments, 297 !Config->Relocatable); 298 Config->PrintGcSections = 299 Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); 300 Config->SearchPaths = args::getStrings(Args, OPT_L); 301 Config->StripAll = Args.hasArg(OPT_strip_all); 302 Config->StripDebug = Args.hasArg(OPT_strip_debug); 303 Config->StackFirst = Args.hasArg(OPT_stack_first); 304 errorHandler().Verbose = Args.hasArg(OPT_verbose); 305 ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true); 306 307 Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0); 308 Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024); 309 Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0); 310 Config->ZStackSize = 311 args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize); 312 313 if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file)) 314 readImportFile(Arg->getValue()); 315 316 if (!Args.hasArg(OPT_INPUT)) { 317 error("no input files"); 318 return; 319 } 320 321 if (Config->OutputFile.empty()) 322 error("no output file specified"); 323 324 if (Config->ImportTable && Config->ExportTable) 325 error("--import-table and --export-table may not be used together"); 326 327 if (Config->Relocatable) { 328 if (!Config->Entry.empty()) 329 error("entry point specified for relocatable output file"); 330 if (Config->GcSections) 331 error("-r and --gc-sections may not be used together"); 332 if (Args.hasArg(OPT_undefined)) 333 error("-r -and --undefined may not be used together"); 334 } 335 336 Symbol *EntrySym = nullptr; 337 if (!Config->Relocatable) { 338 // Can't export the SP right now because it's mutable, and mutable 339 // globals aren't yet supported in the official binary format. 340 // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN if/when the 341 // "mutable global" proposal is accepted. 342 llvm::wasm::WasmGlobal Global; 343 Global.Type = {WASM_TYPE_I32, true}; 344 Global.InitExpr.Value.Int32 = 0; 345 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; 346 Global.SymbolName = "__stack_pointer"; 347 InputGlobal *StackPointer = make<InputGlobal>(Global, nullptr); 348 StackPointer->Live = true; 349 350 static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT}; 351 352 // Add synthetic symbols before any others 353 WasmSym::CallCtors = Symtab->addSyntheticFunction( 354 "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, 355 make<SyntheticFunction>(NullSignature, "__wasm_call_ctors")); 356 WasmSym::StackPointer = Symtab->addSyntheticGlobal( 357 "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer); 358 WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0); 359 WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol( 360 "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN); 361 WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0); 362 363 if (!Config->Entry.empty()) 364 EntrySym = Symtab->addUndefinedFunction(Config->Entry, 0, nullptr, 365 &NullSignature); 366 367 // Handle the `--undefined <sym>` options. 368 for (auto *Arg : Args.filtered(OPT_undefined)) 369 Symtab->addUndefinedFunction(Arg->getValue(), 0, nullptr, nullptr); 370 } 371 372 createFiles(Args); 373 if (errorCount()) 374 return; 375 376 // Add all files to the symbol table. This will add almost all 377 // symbols that we need to the symbol table. 378 for (InputFile *F : Files) 379 Symtab->addFile(F); 380 381 // Add synthetic dummies for weak undefined functions. 382 if (!Config->Relocatable) 383 handleWeakUndefines(); 384 385 // Make sure we have resolved all symbols. 386 if (!Config->Relocatable && !Config->AllowUndefined) { 387 Symtab->reportRemainingUndefines(); 388 } else { 389 // When we allow undefined symbols we cannot include those defined in 390 // -u/--undefined since these undefined symbols have only names and no 391 // function signature, which means they cannot be written to the final 392 // output. 393 for (auto *Arg : Args.filtered(OPT_undefined)) { 394 Symbol *Sym = Symtab->find(Arg->getValue()); 395 if (!Sym->isDefined()) 396 error("function forced with --undefined not found: " + Sym->getName()); 397 } 398 } 399 if (errorCount()) 400 return; 401 402 // Handle --export. 403 for (auto *Arg : Args.filtered(OPT_export)) { 404 StringRef Name = Arg->getValue(); 405 Symbol *Sym = Symtab->find(Name); 406 if (Sym && Sym->isDefined()) 407 Sym->setHidden(false); 408 else if (!Config->AllowUndefined) 409 error("symbol exported via --export not found: " + Name); 410 } 411 412 if (EntrySym) 413 EntrySym->setHidden(false); 414 415 if (errorCount()) 416 return; 417 418 // Do size optimizations: garbage collection 419 markLive(); 420 421 // Write the result to the file. 422 writeResult(); 423 } 424