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