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