1 //===- Writer.cpp ---------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Writer.h" 10 #include "Config.h" 11 #include "InputChunks.h" 12 #include "InputEvent.h" 13 #include "InputGlobal.h" 14 #include "OutputSections.h" 15 #include "OutputSegment.h" 16 #include "SymbolTable.h" 17 #include "WriterUtils.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 "llvm/ADT/DenseSet.h" 23 #include "llvm/ADT/SmallSet.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/ADT/StringMap.h" 26 #include "llvm/BinaryFormat/Wasm.h" 27 #include "llvm/Object/WasmTraits.h" 28 #include "llvm/Support/FileOutputBuffer.h" 29 #include "llvm/Support/Format.h" 30 #include "llvm/Support/FormatVariadic.h" 31 #include "llvm/Support/LEB128.h" 32 #include "llvm/Support/Path.h" 33 34 #include <cstdarg> 35 #include <map> 36 37 #define DEBUG_TYPE "lld" 38 39 using namespace llvm; 40 using namespace llvm::wasm; 41 using namespace lld; 42 using namespace lld::wasm; 43 44 static constexpr int StackAlignment = 16; 45 static constexpr const char *FunctionTableName = "__indirect_function_table"; 46 const char *lld::wasm::DefaultModule = "env"; 47 48 namespace { 49 50 // An init entry to be written to either the synthetic init func or the 51 // linking metadata. 52 struct WasmInitEntry { 53 const FunctionSymbol *Sym; 54 uint32_t Priority; 55 }; 56 57 // The writer writes a SymbolTable result to a file. 58 class Writer { 59 public: 60 void run(); 61 62 private: 63 void openFile(); 64 65 uint32_t lookupType(const WasmSignature &Sig); 66 uint32_t registerType(const WasmSignature &Sig); 67 68 void createCtorFunction(); 69 void calculateInitFunctions(); 70 void processRelocations(InputChunk *Chunk); 71 void assignIndexes(); 72 void calculateTargetFeatures(); 73 void calculateImports(); 74 void calculateExports(); 75 void calculateCustomSections(); 76 void assignSymtab(); 77 void calculateTypes(); 78 void createOutputSegments(); 79 void layoutMemory(); 80 void createHeader(); 81 void createSections(); 82 SyntheticSection *createSyntheticSection(uint32_t Type, StringRef Name = ""); 83 84 // Builtin sections 85 void createTypeSection(); 86 void createFunctionSection(); 87 void createTableSection(); 88 void createGlobalSection(); 89 void createEventSection(); 90 void createExportSection(); 91 void createImportSection(); 92 void createMemorySection(); 93 void createElemSection(); 94 void createCodeSection(); 95 void createDataSection(); 96 void createCustomSections(); 97 98 // Custom sections 99 void createDylinkSection(); 100 void createRelocSections(); 101 void createLinkingSection(); 102 void createNameSection(); 103 void createProducersSection(); 104 void createTargetFeaturesSection(); 105 106 void writeHeader(); 107 void writeSections(); 108 109 uint64_t FileSize = 0; 110 uint32_t TableBase = 0; 111 uint32_t NumMemoryPages = 0; 112 uint32_t MaxMemoryPages = 0; 113 // Memory size and aligment. Written to the "dylink" section 114 // when build with -shared or -pie. 115 uint32_t MemAlign = 0; 116 uint32_t MemSize = 0; 117 118 std::vector<const WasmSignature *> Types; 119 DenseMap<WasmSignature, int32_t> TypeIndices; 120 std::vector<const Symbol *> ImportedSymbols; 121 std::vector<const Symbol *> GOTSymbols; 122 unsigned NumImportedFunctions = 0; 123 unsigned NumImportedGlobals = 0; 124 unsigned NumImportedEvents = 0; 125 std::vector<WasmExport> Exports; 126 std::vector<const DefinedData *> DefinedFakeGlobals; 127 std::vector<InputGlobal *> InputGlobals; 128 std::vector<InputFunction *> InputFunctions; 129 std::vector<InputEvent *> InputEvents; 130 std::vector<const FunctionSymbol *> IndirectFunctions; 131 std::vector<const Symbol *> SymtabEntries; 132 std::vector<WasmInitEntry> InitFunctions; 133 134 llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping; 135 llvm::StringMap<SectionSymbol *> CustomSectionSymbols; 136 llvm::SmallSet<std::string, 8> TargetFeatures; 137 138 // Elements that are used to construct the final output 139 std::string Header; 140 std::vector<OutputSection *> OutputSections; 141 142 std::unique_ptr<FileOutputBuffer> Buffer; 143 144 std::vector<OutputSegment *> Segments; 145 llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap; 146 }; 147 148 } // anonymous namespace 149 150 void Writer::createImportSection() { 151 uint32_t NumImports = ImportedSymbols.size() + GOTSymbols.size(); 152 if (Config->ImportMemory) 153 ++NumImports; 154 if (Config->ImportTable) 155 ++NumImports; 156 157 if (NumImports == 0) 158 return; 159 160 SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT); 161 raw_ostream &OS = Section->getStream(); 162 163 writeUleb128(OS, NumImports, "import count"); 164 165 if (Config->ImportMemory) { 166 WasmImport Import; 167 Import.Module = DefaultModule; 168 Import.Field = "memory"; 169 Import.Kind = WASM_EXTERNAL_MEMORY; 170 Import.Memory.Flags = 0; 171 Import.Memory.Initial = NumMemoryPages; 172 if (MaxMemoryPages != 0 || Config->SharedMemory) { 173 Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; 174 Import.Memory.Maximum = MaxMemoryPages; 175 } 176 if (Config->SharedMemory) 177 Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; 178 writeImport(OS, Import); 179 } 180 181 if (Config->ImportTable) { 182 uint32_t TableSize = TableBase + IndirectFunctions.size(); 183 WasmImport Import; 184 Import.Module = DefaultModule; 185 Import.Field = FunctionTableName; 186 Import.Kind = WASM_EXTERNAL_TABLE; 187 Import.Table.ElemType = WASM_TYPE_FUNCREF; 188 Import.Table.Limits = {0, TableSize, 0}; 189 writeImport(OS, Import); 190 } 191 192 for (const Symbol *Sym : ImportedSymbols) { 193 WasmImport Import; 194 if (auto *F = dyn_cast<UndefinedFunction>(Sym)) { 195 Import.Field = F->ImportName; 196 Import.Module = F->ImportModule; 197 } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) { 198 Import.Field = G->ImportName; 199 Import.Module = G->ImportModule; 200 } else { 201 Import.Field = Sym->getName(); 202 Import.Module = DefaultModule; 203 } 204 205 if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) { 206 Import.Kind = WASM_EXTERNAL_FUNCTION; 207 Import.SigIndex = lookupType(*FunctionSym->Signature); 208 } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) { 209 Import.Kind = WASM_EXTERNAL_GLOBAL; 210 Import.Global = *GlobalSym->getGlobalType(); 211 } else { 212 auto *EventSym = cast<EventSymbol>(Sym); 213 Import.Kind = WASM_EXTERNAL_EVENT; 214 Import.Event.Attribute = EventSym->getEventType()->Attribute; 215 Import.Event.SigIndex = lookupType(*EventSym->Signature); 216 } 217 writeImport(OS, Import); 218 } 219 220 for (const Symbol *Sym : GOTSymbols) { 221 WasmImport Import; 222 Import.Kind = WASM_EXTERNAL_GLOBAL; 223 Import.Global = {WASM_TYPE_I32, true}; 224 if (isa<DataSymbol>(Sym)) 225 Import.Module = "GOT.mem"; 226 else 227 Import.Module = "GOT.func"; 228 Import.Field = Sym->getName(); 229 writeImport(OS, Import); 230 } 231 } 232 233 void Writer::createTypeSection() { 234 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE); 235 raw_ostream &OS = Section->getStream(); 236 writeUleb128(OS, Types.size(), "type count"); 237 for (const WasmSignature *Sig : Types) 238 writeSig(OS, *Sig); 239 } 240 241 void Writer::createFunctionSection() { 242 if (InputFunctions.empty()) 243 return; 244 245 SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION); 246 raw_ostream &OS = Section->getStream(); 247 248 writeUleb128(OS, InputFunctions.size(), "function count"); 249 for (const InputFunction *Func : InputFunctions) 250 writeUleb128(OS, lookupType(Func->Signature), "sig index"); 251 } 252 253 void Writer::createMemorySection() { 254 if (Config->ImportMemory) 255 return; 256 257 SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY); 258 raw_ostream &OS = Section->getStream(); 259 260 bool HasMax = MaxMemoryPages != 0 || Config->SharedMemory; 261 writeUleb128(OS, 1, "memory count"); 262 unsigned Flags = 0; 263 if (HasMax) 264 Flags |= WASM_LIMITS_FLAG_HAS_MAX; 265 if (Config->SharedMemory) 266 Flags |= WASM_LIMITS_FLAG_IS_SHARED; 267 writeUleb128(OS, Flags, "memory limits flags"); 268 writeUleb128(OS, NumMemoryPages, "initial pages"); 269 if (HasMax) 270 writeUleb128(OS, MaxMemoryPages, "max pages"); 271 } 272 273 void Writer::createGlobalSection() { 274 unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size(); 275 if (NumGlobals == 0) 276 return; 277 278 SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL); 279 raw_ostream &OS = Section->getStream(); 280 281 writeUleb128(OS, NumGlobals, "global count"); 282 for (const InputGlobal *G : InputGlobals) 283 writeGlobal(OS, G->Global); 284 for (const DefinedData *Sym : DefinedFakeGlobals) { 285 WasmGlobal Global; 286 Global.Type = {WASM_TYPE_I32, false}; 287 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; 288 Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); 289 writeGlobal(OS, Global); 290 } 291 } 292 293 // The event section contains a list of declared wasm events associated with the 294 // module. Currently the only supported event kind is exceptions. A single event 295 // entry represents a single event with an event tag. All C++ exceptions are 296 // represented by a single event. An event entry in this section contains 297 // information on what kind of event it is (e.g. exception) and the type of 298 // values contained in a single event object. (In wasm, an event can contain 299 // multiple values of primitive types. But for C++ exceptions, we just throw a 300 // pointer which is an i32 value (for wasm32 architecture), so the signature of 301 // C++ exception is (i32)->(void), because all event types are assumed to have 302 // void return type to share WasmSignature with functions.) 303 void Writer::createEventSection() { 304 unsigned NumEvents = InputEvents.size(); 305 if (NumEvents == 0) 306 return; 307 308 SyntheticSection *Section = createSyntheticSection(WASM_SEC_EVENT); 309 raw_ostream &OS = Section->getStream(); 310 311 writeUleb128(OS, NumEvents, "event count"); 312 for (InputEvent *E : InputEvents) { 313 E->Event.Type.SigIndex = lookupType(E->Signature); 314 writeEvent(OS, E->Event); 315 } 316 } 317 318 void Writer::createTableSection() { 319 if (Config->ImportTable) 320 return; 321 322 // Always output a table section (or table import), even if there are no 323 // indirect calls. There are two reasons for this: 324 // 1. For executables it is useful to have an empty table slot at 0 325 // which can be filled with a null function call handler. 326 // 2. If we don't do this, any program that contains a call_indirect but 327 // no address-taken function will fail at validation time since it is 328 // a validation error to include a call_indirect instruction if there 329 // is not table. 330 uint32_t TableSize = TableBase + IndirectFunctions.size(); 331 332 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE); 333 raw_ostream &OS = Section->getStream(); 334 335 writeUleb128(OS, 1, "table count"); 336 WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize}; 337 writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits}); 338 } 339 340 void Writer::createExportSection() { 341 if (!Exports.size()) 342 return; 343 344 SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT); 345 raw_ostream &OS = Section->getStream(); 346 347 writeUleb128(OS, Exports.size(), "export count"); 348 for (const WasmExport &Export : Exports) 349 writeExport(OS, Export); 350 } 351 352 void Writer::calculateCustomSections() { 353 log("calculateCustomSections"); 354 bool StripDebug = Config->StripDebug || Config->StripAll; 355 for (ObjFile *File : Symtab->ObjectFiles) { 356 for (InputSection *Section : File->CustomSections) { 357 StringRef Name = Section->getName(); 358 // These custom sections are known the linker and synthesized rather than 359 // blindly copied 360 if (Name == "linking" || Name == "name" || Name == "producers" || 361 Name == "target_features" || Name.startswith("reloc.")) 362 continue; 363 // .. or it is a debug section 364 if (StripDebug && Name.startswith(".debug_")) 365 continue; 366 CustomSectionMapping[Name].push_back(Section); 367 } 368 } 369 } 370 371 void Writer::createCustomSections() { 372 log("createCustomSections"); 373 for (auto &Pair : CustomSectionMapping) { 374 StringRef Name = Pair.first(); 375 376 auto P = CustomSectionSymbols.find(Name); 377 if (P != CustomSectionSymbols.end()) { 378 uint32_t SectionIndex = OutputSections.size(); 379 P->second->setOutputSectionIndex(SectionIndex); 380 } 381 382 LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); 383 OutputSections.push_back(make<CustomSection>(Name, Pair.second)); 384 } 385 } 386 387 void Writer::createElemSection() { 388 if (IndirectFunctions.empty()) 389 return; 390 391 SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM); 392 raw_ostream &OS = Section->getStream(); 393 394 writeUleb128(OS, 1, "segment count"); 395 writeUleb128(OS, 0, "table index"); 396 WasmInitExpr InitExpr; 397 if (Config->Pic) { 398 InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET; 399 InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex(); 400 } else { 401 InitExpr.Opcode = WASM_OPCODE_I32_CONST; 402 InitExpr.Value.Int32 = TableBase; 403 } 404 writeInitExpr(OS, InitExpr); 405 writeUleb128(OS, IndirectFunctions.size(), "elem count"); 406 407 uint32_t TableIndex = TableBase; 408 for (const FunctionSymbol *Sym : IndirectFunctions) { 409 assert(Sym->getTableIndex() == TableIndex); 410 writeUleb128(OS, Sym->getFunctionIndex(), "function index"); 411 ++TableIndex; 412 } 413 } 414 415 void Writer::createCodeSection() { 416 if (InputFunctions.empty()) 417 return; 418 419 log("createCodeSection"); 420 421 auto Section = make<CodeSection>(InputFunctions); 422 OutputSections.push_back(Section); 423 } 424 425 void Writer::createDataSection() { 426 if (!Segments.size()) 427 return; 428 429 log("createDataSection"); 430 auto Section = make<DataSection>(Segments); 431 OutputSections.push_back(Section); 432 } 433 434 // Create relocations sections in the final output. 435 // These are only created when relocatable output is requested. 436 void Writer::createRelocSections() { 437 log("createRelocSections"); 438 // Don't use iterator here since we are adding to OutputSection 439 size_t OrigSize = OutputSections.size(); 440 for (size_t I = 0; I < OrigSize; I++) { 441 OutputSection *OSec = OutputSections[I]; 442 uint32_t Count = OSec->numRelocations(); 443 if (!Count) 444 continue; 445 446 StringRef Name; 447 if (OSec->Type == WASM_SEC_DATA) 448 Name = "reloc.DATA"; 449 else if (OSec->Type == WASM_SEC_CODE) 450 Name = "reloc.CODE"; 451 else if (OSec->Type == WASM_SEC_CUSTOM) 452 Name = Saver.save("reloc." + OSec->Name); 453 else 454 llvm_unreachable( 455 "relocations only supported for code, data, or custom sections"); 456 457 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name); 458 raw_ostream &OS = Section->getStream(); 459 writeUleb128(OS, I, "reloc section"); 460 writeUleb128(OS, Count, "reloc count"); 461 OSec->writeRelocations(OS); 462 } 463 } 464 465 static uint32_t getWasmFlags(const Symbol *Sym) { 466 uint32_t Flags = 0; 467 if (Sym->isLocal()) 468 Flags |= WASM_SYMBOL_BINDING_LOCAL; 469 if (Sym->isWeak()) 470 Flags |= WASM_SYMBOL_BINDING_WEAK; 471 if (Sym->isHidden()) 472 Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; 473 if (Sym->isUndefined()) 474 Flags |= WASM_SYMBOL_UNDEFINED; 475 if (auto *F = dyn_cast<UndefinedFunction>(Sym)) { 476 if (F->getName() != F->ImportName) 477 Flags |= WASM_SYMBOL_EXPLICIT_NAME; 478 } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) { 479 if (G->getName() != G->ImportName) 480 Flags |= WASM_SYMBOL_EXPLICIT_NAME; 481 } 482 return Flags; 483 } 484 485 // Some synthetic sections (e.g. "name" and "linking") have subsections. 486 // Just like the synthetic sections themselves these need to be created before 487 // they can be written out (since they are preceded by their length). This 488 // class is used to create subsections and then write them into the stream 489 // of the parent section. 490 class SubSection { 491 public: 492 explicit SubSection(uint32_t Type) : Type(Type) {} 493 494 void writeTo(raw_ostream &To) { 495 OS.flush(); 496 writeUleb128(To, Type, "subsection type"); 497 writeUleb128(To, Body.size(), "subsection size"); 498 To.write(Body.data(), Body.size()); 499 } 500 501 private: 502 uint32_t Type; 503 std::string Body; 504 505 public: 506 raw_string_ostream OS{Body}; 507 }; 508 509 // Create the custom "dylink" section containing information for the dynamic 510 // linker. 511 // See 512 // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md 513 void Writer::createDylinkSection() { 514 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "dylink"); 515 raw_ostream &OS = Section->getStream(); 516 517 writeUleb128(OS, MemSize, "MemSize"); 518 writeUleb128(OS, MemAlign, "MemAlign"); 519 writeUleb128(OS, IndirectFunctions.size(), "TableSize"); 520 writeUleb128(OS, 0, "TableAlign"); 521 writeUleb128(OS, Symtab->SharedFiles.size(), "Needed"); 522 for (auto *SO : Symtab->SharedFiles) 523 writeStr(OS, llvm::sys::path::filename(SO->getName()), "so name"); 524 } 525 526 // Create the custom "linking" section containing linker metadata. 527 // This is only created when relocatable output is requested. 528 void Writer::createLinkingSection() { 529 SyntheticSection *Section = 530 createSyntheticSection(WASM_SEC_CUSTOM, "linking"); 531 raw_ostream &OS = Section->getStream(); 532 533 writeUleb128(OS, WasmMetadataVersion, "Version"); 534 535 if (!SymtabEntries.empty()) { 536 SubSection Sub(WASM_SYMBOL_TABLE); 537 writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols"); 538 539 for (const Symbol *Sym : SymtabEntries) { 540 assert(Sym->isDefined() || Sym->isUndefined()); 541 WasmSymbolType Kind = Sym->getWasmType(); 542 uint32_t Flags = getWasmFlags(Sym); 543 544 writeU8(Sub.OS, Kind, "sym kind"); 545 writeUleb128(Sub.OS, Flags, "sym flags"); 546 547 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) { 548 writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); 549 if (Sym->isDefined() || 550 (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 551 writeStr(Sub.OS, Sym->getName(), "sym name"); 552 } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) { 553 writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); 554 if (Sym->isDefined() || 555 (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 556 writeStr(Sub.OS, Sym->getName(), "sym name"); 557 } else if (auto *E = dyn_cast<EventSymbol>(Sym)) { 558 writeUleb128(Sub.OS, E->getEventIndex(), "index"); 559 if (Sym->isDefined() || 560 (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 561 writeStr(Sub.OS, Sym->getName(), "sym name"); 562 } else if (isa<DataSymbol>(Sym)) { 563 writeStr(Sub.OS, Sym->getName(), "sym name"); 564 if (auto *DataSym = dyn_cast<DefinedData>(Sym)) { 565 writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index"); 566 writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(), 567 "data offset"); 568 writeUleb128(Sub.OS, DataSym->getSize(), "data size"); 569 } 570 } else { 571 auto *S = cast<SectionSymbol>(Sym); 572 writeUleb128(Sub.OS, S->getOutputSectionIndex(), "sym section index"); 573 } 574 } 575 576 Sub.writeTo(OS); 577 } 578 579 if (Segments.size()) { 580 SubSection Sub(WASM_SEGMENT_INFO); 581 writeUleb128(Sub.OS, Segments.size(), "num data segments"); 582 for (const OutputSegment *S : Segments) { 583 writeStr(Sub.OS, S->Name, "segment name"); 584 writeUleb128(Sub.OS, S->Alignment, "alignment"); 585 writeUleb128(Sub.OS, 0, "flags"); 586 } 587 Sub.writeTo(OS); 588 } 589 590 if (!InitFunctions.empty()) { 591 SubSection Sub(WASM_INIT_FUNCS); 592 writeUleb128(Sub.OS, InitFunctions.size(), "num init functions"); 593 for (const WasmInitEntry &F : InitFunctions) { 594 writeUleb128(Sub.OS, F.Priority, "priority"); 595 writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index"); 596 } 597 Sub.writeTo(OS); 598 } 599 600 struct ComdatEntry { 601 unsigned Kind; 602 uint32_t Index; 603 }; 604 std::map<StringRef, std::vector<ComdatEntry>> Comdats; 605 606 for (const InputFunction *F : InputFunctions) { 607 StringRef Comdat = F->getComdatName(); 608 if (!Comdat.empty()) 609 Comdats[Comdat].emplace_back( 610 ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()}); 611 } 612 for (uint32_t I = 0; I < Segments.size(); ++I) { 613 const auto &InputSegments = Segments[I]->InputSegments; 614 if (InputSegments.empty()) 615 continue; 616 StringRef Comdat = InputSegments[0]->getComdatName(); 617 #ifndef NDEBUG 618 for (const InputSegment *IS : InputSegments) 619 assert(IS->getComdatName() == Comdat); 620 #endif 621 if (!Comdat.empty()) 622 Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I}); 623 } 624 625 if (!Comdats.empty()) { 626 SubSection Sub(WASM_COMDAT_INFO); 627 writeUleb128(Sub.OS, Comdats.size(), "num comdats"); 628 for (const auto &C : Comdats) { 629 writeStr(Sub.OS, C.first, "comdat name"); 630 writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use 631 writeUleb128(Sub.OS, C.second.size(), "num entries"); 632 for (const ComdatEntry &Entry : C.second) { 633 writeU8(Sub.OS, Entry.Kind, "entry kind"); 634 writeUleb128(Sub.OS, Entry.Index, "entry index"); 635 } 636 } 637 Sub.writeTo(OS); 638 } 639 } 640 641 // Create the custom "name" section containing debug symbol names. 642 void Writer::createNameSection() { 643 unsigned NumNames = NumImportedFunctions; 644 for (const InputFunction *F : InputFunctions) 645 if (!F->getName().empty() || !F->getDebugName().empty()) 646 ++NumNames; 647 648 if (NumNames == 0) 649 return; 650 651 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name"); 652 653 SubSection Sub(WASM_NAMES_FUNCTION); 654 writeUleb128(Sub.OS, NumNames, "name count"); 655 656 // Names must appear in function index order. As it happens ImportedSymbols 657 // and InputFunctions are numbered in order with imported functions coming 658 // first. 659 for (const Symbol *S : ImportedSymbols) { 660 if (auto *F = dyn_cast<FunctionSymbol>(S)) { 661 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); 662 writeStr(Sub.OS, toString(*S), "symbol name"); 663 } 664 } 665 for (const InputFunction *F : InputFunctions) { 666 if (!F->getName().empty()) { 667 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); 668 if (!F->getDebugName().empty()) { 669 writeStr(Sub.OS, F->getDebugName(), "symbol name"); 670 } else { 671 writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name"); 672 } 673 } 674 } 675 676 Sub.writeTo(Section->getStream()); 677 } 678 679 void Writer::createProducersSection() { 680 SmallVector<std::pair<std::string, std::string>, 8> Languages; 681 SmallVector<std::pair<std::string, std::string>, 8> Tools; 682 SmallVector<std::pair<std::string, std::string>, 8> SDKs; 683 for (ObjFile *File : Symtab->ObjectFiles) { 684 const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo(); 685 for (auto &Producers : {std::make_pair(&Info.Languages, &Languages), 686 std::make_pair(&Info.Tools, &Tools), 687 std::make_pair(&Info.SDKs, &SDKs)}) 688 for (auto &Producer : *Producers.first) 689 if (Producers.second->end() == 690 llvm::find_if(*Producers.second, 691 [&](std::pair<std::string, std::string> Seen) { 692 return Seen.first == Producer.first; 693 })) 694 Producers.second->push_back(Producer); 695 } 696 int FieldCount = 697 int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty()); 698 if (FieldCount == 0) 699 return; 700 SyntheticSection *Section = 701 createSyntheticSection(WASM_SEC_CUSTOM, "producers"); 702 auto &OS = Section->getStream(); 703 writeUleb128(OS, FieldCount, "field count"); 704 for (auto &Field : 705 {std::make_pair("language", Languages), 706 std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) { 707 if (Field.second.empty()) 708 continue; 709 writeStr(OS, Field.first, "field name"); 710 writeUleb128(OS, Field.second.size(), "number of entries"); 711 for (auto &Entry : Field.second) { 712 writeStr(OS, Entry.first, "producer name"); 713 writeStr(OS, Entry.second, "producer version"); 714 } 715 } 716 } 717 718 void Writer::createTargetFeaturesSection() { 719 if (TargetFeatures.size() == 0) 720 return; 721 722 SmallVector<std::string, 8> Emitted(TargetFeatures.begin(), 723 TargetFeatures.end()); 724 std::sort(Emitted.begin(), Emitted.end()); 725 SyntheticSection *Section = 726 createSyntheticSection(WASM_SEC_CUSTOM, "target_features"); 727 auto &OS = Section->getStream(); 728 writeUleb128(OS, Emitted.size(), "feature count"); 729 for (auto &Feature : Emitted) { 730 writeU8(OS, WASM_FEATURE_PREFIX_USED, "feature used prefix"); 731 writeStr(OS, Feature, "feature name"); 732 } 733 } 734 735 void Writer::writeHeader() { 736 memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); 737 } 738 739 void Writer::writeSections() { 740 uint8_t *Buf = Buffer->getBufferStart(); 741 parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); }); 742 } 743 744 // Fix the memory layout of the output binary. This assigns memory offsets 745 // to each of the input data sections as well as the explicit stack region. 746 // The default memory layout is as follows, from low to high. 747 // 748 // - initialized data (starting at Config->GlobalBase) 749 // - BSS data (not currently implemented in llvm) 750 // - explicit stack (Config->ZStackSize) 751 // - heap start / unallocated 752 // 753 // The --stack-first option means that stack is placed before any static data. 754 // This can be useful since it means that stack overflow traps immediately 755 // rather than overwriting global data, but also increases code size since all 756 // static data loads and stores requires larger offsets. 757 void Writer::layoutMemory() { 758 createOutputSegments(); 759 760 uint32_t MemoryPtr = 0; 761 762 auto PlaceStack = [&]() { 763 if (Config->Relocatable || Config->Shared) 764 return; 765 MemoryPtr = alignTo(MemoryPtr, StackAlignment); 766 if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment)) 767 error("stack size must be " + Twine(StackAlignment) + "-byte aligned"); 768 log("mem: stack size = " + Twine(Config->ZStackSize)); 769 log("mem: stack base = " + Twine(MemoryPtr)); 770 MemoryPtr += Config->ZStackSize; 771 auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer); 772 SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr; 773 log("mem: stack top = " + Twine(MemoryPtr)); 774 }; 775 776 if (Config->StackFirst) { 777 PlaceStack(); 778 } else { 779 MemoryPtr = Config->GlobalBase; 780 log("mem: global base = " + Twine(Config->GlobalBase)); 781 } 782 783 uint32_t DataStart = MemoryPtr; 784 785 // Arbitrarily set __dso_handle handle to point to the start of the data 786 // segments. 787 if (WasmSym::DsoHandle) 788 WasmSym::DsoHandle->setVirtualAddress(DataStart); 789 790 MemAlign = 0; 791 for (OutputSegment *Seg : Segments) { 792 MemAlign = std::max(MemAlign, Seg->Alignment); 793 MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment); 794 Seg->StartVA = MemoryPtr; 795 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, 796 MemoryPtr, Seg->Size, Seg->Alignment)); 797 MemoryPtr += Seg->Size; 798 } 799 800 // TODO: Add .bss space here. 801 if (WasmSym::DataEnd) 802 WasmSym::DataEnd->setVirtualAddress(MemoryPtr); 803 804 log("mem: static data = " + Twine(MemoryPtr - DataStart)); 805 806 if (Config->Shared) { 807 MemSize = MemoryPtr; 808 return; 809 } 810 811 if (!Config->StackFirst) 812 PlaceStack(); 813 814 // Set `__heap_base` to directly follow the end of the stack or global data. 815 // The fact that this comes last means that a malloc/brk implementation 816 // can grow the heap at runtime. 817 if (!Config->Relocatable) { 818 WasmSym::HeapBase->setVirtualAddress(MemoryPtr); 819 log("mem: heap base = " + Twine(MemoryPtr)); 820 } 821 822 if (Config->InitialMemory != 0) { 823 if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) 824 error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); 825 if (MemoryPtr > Config->InitialMemory) 826 error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); 827 else 828 MemoryPtr = Config->InitialMemory; 829 } 830 MemSize = MemoryPtr; 831 NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize; 832 log("mem: total pages = " + Twine(NumMemoryPages)); 833 834 // Check max if explicitly supplied or required by shared memory 835 if (Config->MaxMemory != 0 || Config->SharedMemory) { 836 if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) 837 error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); 838 if (MemoryPtr > Config->MaxMemory) 839 error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); 840 MaxMemoryPages = Config->MaxMemory / WasmPageSize; 841 log("mem: max pages = " + Twine(MaxMemoryPages)); 842 } 843 } 844 845 SyntheticSection *Writer::createSyntheticSection(uint32_t Type, 846 StringRef Name) { 847 auto Sec = make<SyntheticSection>(Type, Name); 848 log("createSection: " + toString(*Sec)); 849 OutputSections.push_back(Sec); 850 return Sec; 851 } 852 853 void Writer::createSections() { 854 // Known sections 855 if (Config->Pic) 856 createDylinkSection(); 857 createTypeSection(); 858 createImportSection(); 859 createFunctionSection(); 860 createTableSection(); 861 createMemorySection(); 862 createGlobalSection(); 863 createEventSection(); 864 createExportSection(); 865 createElemSection(); 866 createCodeSection(); 867 createDataSection(); 868 createCustomSections(); 869 870 // Custom sections 871 if (Config->Relocatable) { 872 createLinkingSection(); 873 createRelocSections(); 874 } 875 876 if (!Config->StripDebug && !Config->StripAll) 877 createNameSection(); 878 879 if (!Config->StripAll) { 880 createProducersSection(); 881 createTargetFeaturesSection(); 882 } 883 884 for (OutputSection *S : OutputSections) { 885 S->setOffset(FileSize); 886 S->finalizeContents(); 887 FileSize += S->getSize(); 888 } 889 } 890 891 void Writer::calculateTargetFeatures() { 892 SmallSet<std::string, 8> Used; 893 SmallSet<std::string, 8> Required; 894 SmallSet<std::string, 8> Disallowed; 895 896 // Only infer used features if user did not specify features 897 bool InferFeatures = !Config->Features.hasValue(); 898 899 if (!InferFeatures) { 900 for (auto &Feature : Config->Features.getValue()) 901 TargetFeatures.insert(Feature); 902 // No need to read or check features 903 if (!Config->CheckFeatures) 904 return; 905 } 906 907 // Find the sets of used, required, and disallowed features 908 for (ObjFile *File : Symtab->ObjectFiles) { 909 for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { 910 switch (Feature.Prefix) { 911 case WASM_FEATURE_PREFIX_USED: 912 Used.insert(Feature.Name); 913 break; 914 case WASM_FEATURE_PREFIX_REQUIRED: 915 Used.insert(Feature.Name); 916 Required.insert(Feature.Name); 917 break; 918 case WASM_FEATURE_PREFIX_DISALLOWED: 919 Disallowed.insert(Feature.Name); 920 break; 921 default: 922 error("Unrecognized feature policy prefix " + 923 std::to_string(Feature.Prefix)); 924 } 925 } 926 } 927 928 if (InferFeatures) 929 TargetFeatures.insert(Used.begin(), Used.end()); 930 931 if (TargetFeatures.count("atomics") && !Config->SharedMemory) 932 error("'atomics' feature is used, so --shared-memory must be used"); 933 934 if (!Config->CheckFeatures) 935 return; 936 937 if (Disallowed.count("atomics") && Config->SharedMemory) 938 error( 939 "'atomics' feature is disallowed, so --shared-memory must not be used"); 940 941 // Validate that used features are allowed in output 942 if (!InferFeatures) { 943 for (auto &Feature : Used) { 944 if (!TargetFeatures.count(Feature)) 945 error(Twine("Target feature '") + Feature + "' is not allowed."); 946 } 947 } 948 949 // Validate the required and disallowed constraints for each file 950 for (ObjFile *File : Symtab->ObjectFiles) { 951 SmallSet<std::string, 8> ObjectFeatures; 952 for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { 953 if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED) 954 continue; 955 ObjectFeatures.insert(Feature.Name); 956 if (Disallowed.count(Feature.Name)) 957 error(Twine("Target feature '") + Feature.Name + 958 "' is disallowed. Use --no-check-features to suppress."); 959 } 960 for (auto &Feature : Required) { 961 if (!ObjectFeatures.count(Feature)) 962 error(Twine("Missing required target feature '") + Feature + 963 "'. Use --no-check-features to suppress."); 964 } 965 } 966 } 967 968 void Writer::calculateImports() { 969 for (Symbol *Sym : Symtab->getSymbols()) { 970 if (!Sym->isUndefined()) 971 continue; 972 if (Sym->isWeak() && !Config->Relocatable) 973 continue; 974 if (!Sym->isLive()) 975 continue; 976 if (!Sym->IsUsedInRegularObj) 977 continue; 978 // We don't generate imports for data symbols. They however can be imported 979 // as GOT entries. 980 if (isa<DataSymbol>(Sym)) 981 continue; 982 983 LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); 984 ImportedSymbols.emplace_back(Sym); 985 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) 986 F->setFunctionIndex(NumImportedFunctions++); 987 else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) 988 G->setGlobalIndex(NumImportedGlobals++); 989 else 990 cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++); 991 } 992 } 993 994 void Writer::calculateExports() { 995 if (Config->Relocatable) 996 return; 997 998 if (!Config->Relocatable && !Config->ImportMemory) 999 Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); 1000 1001 if (!Config->Relocatable && Config->ExportTable) 1002 Exports.push_back(WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0}); 1003 1004 unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size(); 1005 1006 for (Symbol *Sym : Symtab->getSymbols()) { 1007 if (!Sym->isExported()) 1008 continue; 1009 if (!Sym->isLive()) 1010 continue; 1011 1012 StringRef Name = Sym->getName(); 1013 WasmExport Export; 1014 if (auto *F = dyn_cast<DefinedFunction>(Sym)) { 1015 Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()}; 1016 } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) { 1017 // TODO(sbc): Remove this check once to mutable global proposal is 1018 // implement in all major browsers. 1019 // See: https://github.com/WebAssembly/mutable-global 1020 if (G->getGlobalType()->Mutable) { 1021 // Only the __stack_pointer should ever be create as mutable. 1022 assert(G == WasmSym::StackPointer); 1023 continue; 1024 } 1025 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()}; 1026 } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) { 1027 Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()}; 1028 } else { 1029 auto *D = cast<DefinedData>(Sym); 1030 DefinedFakeGlobals.emplace_back(D); 1031 Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++}; 1032 } 1033 1034 LLVM_DEBUG(dbgs() << "Export: " << Name << "\n"); 1035 Exports.push_back(Export); 1036 } 1037 } 1038 1039 void Writer::assignSymtab() { 1040 if (!Config->Relocatable) 1041 return; 1042 1043 StringMap<uint32_t> SectionSymbolIndices; 1044 1045 unsigned SymbolIndex = SymtabEntries.size(); 1046 1047 auto AddSymbol = [&](Symbol *Sym) { 1048 if (auto *S = dyn_cast<SectionSymbol>(Sym)) { 1049 StringRef Name = S->getName(); 1050 if (CustomSectionMapping.count(Name) == 0) 1051 return; 1052 1053 auto SSI = SectionSymbolIndices.find(Name); 1054 if (SSI != SectionSymbolIndices.end()) { 1055 Sym->setOutputSymbolIndex(SSI->second); 1056 return; 1057 } 1058 1059 SectionSymbolIndices[Name] = SymbolIndex; 1060 CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym); 1061 1062 Sym->markLive(); 1063 } 1064 1065 // (Since this is relocatable output, GC is not performed so symbols must 1066 // be live.) 1067 assert(Sym->isLive()); 1068 Sym->setOutputSymbolIndex(SymbolIndex++); 1069 SymtabEntries.emplace_back(Sym); 1070 }; 1071 1072 for (Symbol *Sym : Symtab->getSymbols()) 1073 if (Sym->IsUsedInRegularObj) 1074 AddSymbol(Sym); 1075 1076 for (ObjFile *File : Symtab->ObjectFiles) { 1077 LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); 1078 for (Symbol *Sym : File->getSymbols()) 1079 if (Sym->isLocal()) 1080 AddSymbol(Sym); 1081 } 1082 } 1083 1084 uint32_t Writer::lookupType(const WasmSignature &Sig) { 1085 auto It = TypeIndices.find(Sig); 1086 if (It == TypeIndices.end()) { 1087 error("type not found: " + toString(Sig)); 1088 return 0; 1089 } 1090 return It->second; 1091 } 1092 1093 uint32_t Writer::registerType(const WasmSignature &Sig) { 1094 auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); 1095 if (Pair.second) { 1096 LLVM_DEBUG(dbgs() << "type " << toString(Sig) << "\n"); 1097 Types.push_back(&Sig); 1098 } 1099 return Pair.first->second; 1100 } 1101 1102 void Writer::calculateTypes() { 1103 // The output type section is the union of the following sets: 1104 // 1. Any signature used in the TYPE relocation 1105 // 2. The signatures of all imported functions 1106 // 3. The signatures of all defined functions 1107 // 4. The signatures of all imported events 1108 // 5. The signatures of all defined events 1109 1110 for (ObjFile *File : Symtab->ObjectFiles) { 1111 ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); 1112 for (uint32_t I = 0; I < Types.size(); I++) 1113 if (File->TypeIsUsed[I]) 1114 File->TypeMap[I] = registerType(Types[I]); 1115 } 1116 1117 for (const Symbol *Sym : ImportedSymbols) { 1118 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) 1119 registerType(*F->Signature); 1120 else if (auto *E = dyn_cast<EventSymbol>(Sym)) 1121 registerType(*E->Signature); 1122 } 1123 1124 for (const InputFunction *F : InputFunctions) 1125 registerType(F->Signature); 1126 1127 for (const InputEvent *E : InputEvents) 1128 registerType(E->Signature); 1129 } 1130 1131 void Writer::processRelocations(InputChunk *Chunk) { 1132 if (!Chunk->Live) 1133 return; 1134 ObjFile *File = Chunk->File; 1135 ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); 1136 for (const WasmRelocation &Reloc : Chunk->getRelocations()) { 1137 switch (Reloc.Type) { 1138 case R_WASM_TABLE_INDEX_I32: 1139 case R_WASM_TABLE_INDEX_SLEB: { 1140 FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index); 1141 if (Sym->hasTableIndex() || !Sym->hasFunctionIndex()) 1142 continue; 1143 Sym->setTableIndex(TableBase + IndirectFunctions.size()); 1144 IndirectFunctions.emplace_back(Sym); 1145 break; 1146 } 1147 case R_WASM_TYPE_INDEX_LEB: 1148 // Mark target type as live 1149 File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]); 1150 File->TypeIsUsed[Reloc.Index] = true; 1151 break; 1152 case R_WASM_MEMORY_ADDR_SLEB: 1153 case R_WASM_MEMORY_ADDR_I32: 1154 case R_WASM_MEMORY_ADDR_LEB: { 1155 DataSymbol *Sym = File->getDataSymbol(Reloc.Index); 1156 if (!Config->Relocatable && !isa<DefinedData>(Sym) && !Sym->isWeak()) 1157 error(File->getName() + ": relocation " + 1158 relocTypeToString(Reloc.Type) + " cannot be used againt symbol " + 1159 Sym->getName() + "; recompile with -fPIC"); 1160 1161 break; 1162 } 1163 case R_WASM_GLOBAL_INDEX_LEB: { 1164 auto* Sym = File->getSymbols()[Reloc.Index]; 1165 if (!isa<GlobalSymbol>(Sym) && !Sym->isInGOT()) { 1166 Sym->setGOTIndex(NumImportedGlobals++); 1167 GOTSymbols.push_back(Sym); 1168 } 1169 } 1170 } 1171 } 1172 } 1173 1174 void Writer::assignIndexes() { 1175 assert(InputFunctions.empty()); 1176 uint32_t FunctionIndex = NumImportedFunctions; 1177 auto AddDefinedFunction = [&](InputFunction *Func) { 1178 if (!Func->Live) 1179 return; 1180 InputFunctions.emplace_back(Func); 1181 Func->setFunctionIndex(FunctionIndex++); 1182 }; 1183 1184 for (InputFunction *Func : Symtab->SyntheticFunctions) 1185 AddDefinedFunction(Func); 1186 1187 for (ObjFile *File : Symtab->ObjectFiles) { 1188 LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); 1189 for (InputFunction *Func : File->Functions) 1190 AddDefinedFunction(Func); 1191 } 1192 1193 for (ObjFile *File : Symtab->ObjectFiles) { 1194 LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n"); 1195 for (InputChunk *Chunk : File->Functions) 1196 processRelocations(Chunk); 1197 for (InputChunk *Chunk : File->Segments) 1198 processRelocations(Chunk); 1199 for (auto &P : File->CustomSections) 1200 processRelocations(P); 1201 } 1202 1203 assert(InputGlobals.empty()); 1204 uint32_t GlobalIndex = NumImportedGlobals; 1205 auto AddDefinedGlobal = [&](InputGlobal *Global) { 1206 if (Global->Live) { 1207 LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n"); 1208 Global->setGlobalIndex(GlobalIndex++); 1209 InputGlobals.push_back(Global); 1210 } 1211 }; 1212 1213 for (InputGlobal *Global : Symtab->SyntheticGlobals) 1214 AddDefinedGlobal(Global); 1215 1216 for (ObjFile *File : Symtab->ObjectFiles) { 1217 LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); 1218 for (InputGlobal *Global : File->Globals) 1219 AddDefinedGlobal(Global); 1220 } 1221 1222 assert(InputEvents.empty()); 1223 uint32_t EventIndex = NumImportedEvents; 1224 auto AddDefinedEvent = [&](InputEvent *Event) { 1225 if (Event->Live) { 1226 LLVM_DEBUG(dbgs() << "AddDefinedEvent: " << EventIndex << "\n"); 1227 Event->setEventIndex(EventIndex++); 1228 InputEvents.push_back(Event); 1229 } 1230 }; 1231 1232 for (ObjFile *File : Symtab->ObjectFiles) { 1233 LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n"); 1234 for (InputEvent *Event : File->Events) 1235 AddDefinedEvent(Event); 1236 } 1237 } 1238 1239 static StringRef getOutputDataSegmentName(StringRef Name) { 1240 // With PIC code we currently only support a single data segment since 1241 // we only have a single __memory_base to use as our base address. 1242 if (Config->Pic) 1243 return "data"; 1244 if (!Config->MergeDataSegments) 1245 return Name; 1246 if (Name.startswith(".text.")) 1247 return ".text"; 1248 if (Name.startswith(".data.")) 1249 return ".data"; 1250 if (Name.startswith(".bss.")) 1251 return ".bss"; 1252 if (Name.startswith(".rodata.")) 1253 return ".rodata"; 1254 return Name; 1255 } 1256 1257 void Writer::createOutputSegments() { 1258 for (ObjFile *File : Symtab->ObjectFiles) { 1259 for (InputSegment *Segment : File->Segments) { 1260 if (!Segment->Live) 1261 continue; 1262 StringRef Name = getOutputDataSegmentName(Segment->getName()); 1263 OutputSegment *&S = SegmentMap[Name]; 1264 if (S == nullptr) { 1265 LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n"); 1266 S = make<OutputSegment>(Name, Segments.size()); 1267 Segments.push_back(S); 1268 } 1269 S->addInputSegment(Segment); 1270 LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); 1271 } 1272 } 1273 } 1274 1275 static const int OPCODE_CALL = 0x10; 1276 static const int OPCODE_END = 0xb; 1277 1278 // Create synthetic "__wasm_call_ctors" function based on ctor functions 1279 // in input object. 1280 void Writer::createCtorFunction() { 1281 if (!WasmSym::CallCtors->isLive()) 1282 return; 1283 1284 // First write the body's contents to a string. 1285 std::string BodyContent; 1286 { 1287 raw_string_ostream OS(BodyContent); 1288 writeUleb128(OS, 0, "num locals"); 1289 for (const WasmInitEntry &F : InitFunctions) { 1290 writeU8(OS, OPCODE_CALL, "CALL"); 1291 writeUleb128(OS, F.Sym->getFunctionIndex(), "function index"); 1292 } 1293 writeU8(OS, OPCODE_END, "END"); 1294 } 1295 1296 // Once we know the size of the body we can create the final function body 1297 std::string FunctionBody; 1298 { 1299 raw_string_ostream OS(FunctionBody); 1300 writeUleb128(OS, BodyContent.size(), "function size"); 1301 OS << BodyContent; 1302 } 1303 1304 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody)); 1305 cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body); 1306 } 1307 1308 // Populate InitFunctions vector with init functions from all input objects. 1309 // This is then used either when creating the output linking section or to 1310 // synthesize the "__wasm_call_ctors" function. 1311 void Writer::calculateInitFunctions() { 1312 if (!Config->Relocatable && !WasmSym::CallCtors->isLive()) 1313 return; 1314 1315 for (ObjFile *File : Symtab->ObjectFiles) { 1316 const WasmLinkingData &L = File->getWasmObj()->linkingData(); 1317 for (const WasmInitFunc &F : L.InitFunctions) { 1318 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); 1319 assert(Sym->isLive()); 1320 if (*Sym->Signature != WasmSignature{{}, {}}) 1321 error("invalid signature for init func: " + toString(*Sym)); 1322 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); 1323 } 1324 } 1325 1326 // Sort in order of priority (lowest first) so that they are called 1327 // in the correct order. 1328 std::stable_sort(InitFunctions.begin(), InitFunctions.end(), 1329 [](const WasmInitEntry &L, const WasmInitEntry &R) { 1330 return L.Priority < R.Priority; 1331 }); 1332 } 1333 1334 void Writer::run() { 1335 if (Config->Relocatable || Config->Pic) 1336 Config->GlobalBase = 0; 1337 1338 // For PIC code the table base is assigned dynamically by the loader. 1339 // For non-PIC, we start at 1 so that accessing table index 0 always traps. 1340 if (!Config->Pic) 1341 TableBase = 1; 1342 1343 log("-- calculateTargetFeatures"); 1344 calculateTargetFeatures(); 1345 log("-- calculateImports"); 1346 calculateImports(); 1347 log("-- assignIndexes"); 1348 assignIndexes(); 1349 log("-- calculateInitFunctions"); 1350 calculateInitFunctions(); 1351 if (!Config->Relocatable) 1352 createCtorFunction(); 1353 log("-- calculateTypes"); 1354 calculateTypes(); 1355 log("-- layoutMemory"); 1356 layoutMemory(); 1357 log("-- calculateExports"); 1358 calculateExports(); 1359 log("-- calculateCustomSections"); 1360 calculateCustomSections(); 1361 log("-- assignSymtab"); 1362 assignSymtab(); 1363 1364 if (errorHandler().Verbose) { 1365 log("Defined Functions: " + Twine(InputFunctions.size())); 1366 log("Defined Globals : " + Twine(InputGlobals.size())); 1367 log("Defined Events : " + Twine(InputEvents.size())); 1368 log("Function Imports : " + Twine(NumImportedFunctions)); 1369 log("Global Imports : " + Twine(NumImportedGlobals)); 1370 log("Event Imports : " + Twine(NumImportedEvents)); 1371 for (ObjFile *File : Symtab->ObjectFiles) 1372 File->dumpInfo(); 1373 } 1374 1375 createHeader(); 1376 log("-- createSections"); 1377 createSections(); 1378 1379 log("-- openFile"); 1380 openFile(); 1381 if (errorCount()) 1382 return; 1383 1384 writeHeader(); 1385 1386 log("-- writeSections"); 1387 writeSections(); 1388 if (errorCount()) 1389 return; 1390 1391 if (Error E = Buffer->commit()) 1392 fatal("failed to write the output file: " + toString(std::move(E))); 1393 } 1394 1395 // Open a result file. 1396 void Writer::openFile() { 1397 log("writing: " + Config->OutputFile); 1398 1399 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 1400 FileOutputBuffer::create(Config->OutputFile, FileSize, 1401 FileOutputBuffer::F_executable); 1402 1403 if (!BufferOrErr) 1404 error("failed to open " + Config->OutputFile + ": " + 1405 toString(BufferOrErr.takeError())); 1406 else 1407 Buffer = std::move(*BufferOrErr); 1408 } 1409 1410 void Writer::createHeader() { 1411 raw_string_ostream OS(Header); 1412 writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); 1413 writeU32(OS, WasmVersion, "wasm version"); 1414 OS.flush(); 1415 FileSize += Header.size(); 1416 } 1417 1418 void lld::wasm::writeResult() { Writer().run(); } 1419