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