1 //===- Writer.cpp ---------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Writer.h" 11 #include "Config.h" 12 #include "InputChunks.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/StringMap.h" 24 #include "llvm/BinaryFormat/Wasm.h" 25 #include "llvm/Object/WasmTraits.h" 26 #include "llvm/Support/FileOutputBuffer.h" 27 #include "llvm/Support/Format.h" 28 #include "llvm/Support/FormatVariadic.h" 29 #include "llvm/Support/LEB128.h" 30 31 #include <cstdarg> 32 #include <map> 33 34 #define DEBUG_TYPE "lld" 35 36 using namespace llvm; 37 using namespace llvm::wasm; 38 using namespace lld; 39 using namespace lld::wasm; 40 41 static constexpr int kStackAlignment = 16; 42 static constexpr const char *kFunctionTableName = "__indirect_function_table"; 43 44 namespace { 45 46 // An init entry to be written to either the synthetic init func or the 47 // linking metadata. 48 struct WasmInitEntry { 49 const FunctionSymbol *Sym; 50 uint32_t Priority; 51 }; 52 53 // The writer writes a SymbolTable result to a file. 54 class Writer { 55 public: 56 void run(); 57 58 private: 59 void openFile(); 60 61 uint32_t lookupType(const WasmSignature &Sig); 62 uint32_t registerType(const WasmSignature &Sig); 63 64 void createCtorFunction(); 65 void calculateInitFunctions(); 66 void assignIndexes(); 67 void calculateImports(); 68 void calculateExports(); 69 void calculateCustomSections(); 70 void assignSymtab(); 71 void calculateTypes(); 72 void createOutputSegments(); 73 void layoutMemory(); 74 void createHeader(); 75 void createSections(); 76 SyntheticSection *createSyntheticSection(uint32_t Type, StringRef Name = ""); 77 78 // Builtin sections 79 void createTypeSection(); 80 void createFunctionSection(); 81 void createTableSection(); 82 void createGlobalSection(); 83 void createExportSection(); 84 void createImportSection(); 85 void createMemorySection(); 86 void createElemSection(); 87 void createCodeSection(); 88 void createDataSection(); 89 void createCustomSections(); 90 91 // Custom sections 92 void createDylinkSection(); 93 void createRelocSections(); 94 void createLinkingSection(); 95 void createNameSection(); 96 97 void writeHeader(); 98 void writeSections(); 99 100 uint64_t FileSize = 0; 101 uint32_t TableBase = 0; 102 uint32_t NumMemoryPages = 0; 103 uint32_t MaxMemoryPages = 0; 104 // Memory size and aligment. Written to the "dylink" section 105 // when build with -shared or -pie. 106 uint32_t MemAlign = 0; 107 uint32_t MemSize = 0; 108 109 std::vector<const WasmSignature *> Types; 110 DenseMap<WasmSignature, int32_t> TypeIndices; 111 std::vector<const Symbol *> ImportedSymbols; 112 unsigned NumImportedFunctions = 0; 113 unsigned NumImportedGlobals = 0; 114 std::vector<WasmExport> Exports; 115 std::vector<const DefinedData *> DefinedFakeGlobals; 116 std::vector<InputGlobal *> InputGlobals; 117 std::vector<InputFunction *> InputFunctions; 118 std::vector<const FunctionSymbol *> IndirectFunctions; 119 std::vector<const Symbol *> SymtabEntries; 120 std::vector<WasmInitEntry> InitFunctions; 121 122 llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping; 123 llvm::StringMap<SectionSymbol *> CustomSectionSymbols; 124 125 // Elements that are used to construct the final output 126 std::string Header; 127 std::vector<OutputSection *> OutputSections; 128 129 std::unique_ptr<FileOutputBuffer> Buffer; 130 131 std::vector<OutputSegment *> Segments; 132 llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap; 133 }; 134 135 } // anonymous namespace 136 137 void Writer::createImportSection() { 138 uint32_t NumImports = ImportedSymbols.size(); 139 if (Config->ImportMemory) 140 ++NumImports; 141 if (Config->ImportTable) 142 ++NumImports; 143 144 if (NumImports == 0) 145 return; 146 147 SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT); 148 raw_ostream &OS = Section->getStream(); 149 150 writeUleb128(OS, NumImports, "import count"); 151 152 if (Config->ImportMemory) { 153 WasmImport Import; 154 Import.Module = "env"; 155 Import.Field = "memory"; 156 Import.Kind = WASM_EXTERNAL_MEMORY; 157 Import.Memory.Flags = 0; 158 Import.Memory.Initial = NumMemoryPages; 159 if (MaxMemoryPages != 0) { 160 Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; 161 Import.Memory.Maximum = MaxMemoryPages; 162 } 163 if (Config->SharedMemory) 164 Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; 165 writeImport(OS, Import); 166 } 167 168 if (Config->ImportTable) { 169 uint32_t TableSize = TableBase + IndirectFunctions.size(); 170 WasmImport Import; 171 Import.Module = "env"; 172 Import.Field = kFunctionTableName; 173 Import.Kind = WASM_EXTERNAL_TABLE; 174 Import.Table.ElemType = WASM_TYPE_ANYFUNC; 175 Import.Table.Limits = {0, TableSize, 0}; 176 writeImport(OS, Import); 177 } 178 179 for (const Symbol *Sym : ImportedSymbols) { 180 WasmImport Import; 181 Import.Module = "env"; 182 Import.Field = Sym->getName(); 183 if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) { 184 Import.Kind = WASM_EXTERNAL_FUNCTION; 185 Import.SigIndex = lookupType(*FunctionSym->FunctionType); 186 } else { 187 auto *GlobalSym = cast<GlobalSymbol>(Sym); 188 Import.Kind = WASM_EXTERNAL_GLOBAL; 189 Import.Global = *GlobalSym->getGlobalType(); 190 } 191 writeImport(OS, Import); 192 } 193 } 194 195 void Writer::createTypeSection() { 196 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE); 197 raw_ostream &OS = Section->getStream(); 198 writeUleb128(OS, Types.size(), "type count"); 199 for (const WasmSignature *Sig : Types) 200 writeSig(OS, *Sig); 201 } 202 203 void Writer::createFunctionSection() { 204 if (InputFunctions.empty()) 205 return; 206 207 SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION); 208 raw_ostream &OS = Section->getStream(); 209 210 writeUleb128(OS, InputFunctions.size(), "function count"); 211 for (const InputFunction *Func : InputFunctions) 212 writeUleb128(OS, lookupType(Func->Signature), "sig index"); 213 } 214 215 void Writer::createMemorySection() { 216 if (Config->ImportMemory) 217 return; 218 219 SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY); 220 raw_ostream &OS = Section->getStream(); 221 222 bool HasMax = MaxMemoryPages != 0; 223 writeUleb128(OS, 1, "memory count"); 224 unsigned Flags = 0; 225 if (HasMax) 226 Flags |= WASM_LIMITS_FLAG_HAS_MAX; 227 if (Config->SharedMemory) 228 Flags |= WASM_LIMITS_FLAG_IS_SHARED; 229 writeUleb128(OS, Flags, "memory limits flags"); 230 writeUleb128(OS, NumMemoryPages, "initial pages"); 231 if (HasMax) 232 writeUleb128(OS, MaxMemoryPages, "max pages"); 233 } 234 235 void Writer::createGlobalSection() { 236 unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size(); 237 if (NumGlobals == 0) 238 return; 239 240 SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL); 241 raw_ostream &OS = Section->getStream(); 242 243 writeUleb128(OS, NumGlobals, "global count"); 244 for (const InputGlobal *G : InputGlobals) 245 writeGlobal(OS, G->Global); 246 for (const DefinedData *Sym : DefinedFakeGlobals) { 247 WasmGlobal Global; 248 Global.Type = {WASM_TYPE_I32, false}; 249 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; 250 Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); 251 writeGlobal(OS, Global); 252 } 253 } 254 255 void Writer::createTableSection() { 256 if (Config->ImportTable) 257 return; 258 259 // Always output a table section (or table import), even if there are no 260 // indirect calls. There are two reasons for this: 261 // 1. For executables it is useful to have an empty table slot at 0 262 // which can be filled with a null function call handler. 263 // 2. If we don't do this, any program that contains a call_indirect but 264 // no address-taken function will fail at validation time since it is 265 // a validation error to include a call_indirect instruction if there 266 // is not table. 267 uint32_t TableSize = TableBase + IndirectFunctions.size(); 268 269 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE); 270 raw_ostream &OS = Section->getStream(); 271 272 writeUleb128(OS, 1, "table count"); 273 WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize}; 274 writeTableType(OS, WasmTable{WASM_TYPE_ANYFUNC, Limits}); 275 } 276 277 void Writer::createExportSection() { 278 if (!Exports.size()) 279 return; 280 281 SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT); 282 raw_ostream &OS = Section->getStream(); 283 284 writeUleb128(OS, Exports.size(), "export count"); 285 for (const WasmExport &Export : Exports) 286 writeExport(OS, Export); 287 } 288 289 void Writer::calculateCustomSections() { 290 log("calculateCustomSections"); 291 bool StripDebug = Config->StripDebug || Config->StripAll; 292 for (ObjFile *File : Symtab->ObjectFiles) { 293 for (InputSection *Section : File->CustomSections) { 294 StringRef Name = Section->getName(); 295 // These custom sections are known the linker and synthesized rather than 296 // blindly copied 297 if (Name == "linking" || Name == "name" || Name.startswith("reloc.")) 298 continue; 299 // .. or it is a debug section 300 if (StripDebug && Name.startswith(".debug_")) 301 continue; 302 CustomSectionMapping[Name].push_back(Section); 303 } 304 } 305 } 306 307 void Writer::createCustomSections() { 308 log("createCustomSections"); 309 for (auto &Pair : CustomSectionMapping) { 310 StringRef Name = Pair.first(); 311 312 auto P = CustomSectionSymbols.find(Name); 313 if (P != CustomSectionSymbols.end()) { 314 uint32_t SectionIndex = OutputSections.size(); 315 P->second->setOutputSectionIndex(SectionIndex); 316 } 317 318 LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); 319 OutputSections.push_back(make<CustomSection>(Name, Pair.second)); 320 } 321 } 322 323 void Writer::createElemSection() { 324 if (IndirectFunctions.empty()) 325 return; 326 327 SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM); 328 raw_ostream &OS = Section->getStream(); 329 330 writeUleb128(OS, 1, "segment count"); 331 writeUleb128(OS, 0, "table index"); 332 WasmInitExpr InitExpr; 333 if (Config->Pic) { 334 InitExpr.Opcode = WASM_OPCODE_GET_GLOBAL; 335 InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex(); 336 } else { 337 InitExpr.Opcode = WASM_OPCODE_I32_CONST; 338 InitExpr.Value.Int32 = TableBase; 339 } 340 writeInitExpr(OS, InitExpr); 341 writeUleb128(OS, IndirectFunctions.size(), "elem count"); 342 343 uint32_t TableIndex = TableBase; 344 for (const FunctionSymbol *Sym : IndirectFunctions) { 345 assert(Sym->getTableIndex() == TableIndex); 346 writeUleb128(OS, Sym->getFunctionIndex(), "function index"); 347 ++TableIndex; 348 } 349 } 350 351 void Writer::createCodeSection() { 352 if (InputFunctions.empty()) 353 return; 354 355 log("createCodeSection"); 356 357 auto Section = make<CodeSection>(InputFunctions); 358 OutputSections.push_back(Section); 359 } 360 361 void Writer::createDataSection() { 362 if (!Segments.size()) 363 return; 364 365 log("createDataSection"); 366 auto Section = make<DataSection>(Segments); 367 OutputSections.push_back(Section); 368 } 369 370 // Create relocations sections in the final output. 371 // These are only created when relocatable output is requested. 372 void Writer::createRelocSections() { 373 log("createRelocSections"); 374 // Don't use iterator here since we are adding to OutputSection 375 size_t OrigSize = OutputSections.size(); 376 for (size_t I = 0; I < OrigSize; I++) { 377 OutputSection *OSec = OutputSections[I]; 378 uint32_t Count = OSec->numRelocations(); 379 if (!Count) 380 continue; 381 382 StringRef Name; 383 if (OSec->Type == WASM_SEC_DATA) 384 Name = "reloc.DATA"; 385 else if (OSec->Type == WASM_SEC_CODE) 386 Name = "reloc.CODE"; 387 else if (OSec->Type == WASM_SEC_CUSTOM) 388 Name = Saver.save("reloc." + OSec->Name); 389 else 390 llvm_unreachable( 391 "relocations only supported for code, data, or custom sections"); 392 393 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name); 394 raw_ostream &OS = Section->getStream(); 395 writeUleb128(OS, I, "reloc section"); 396 writeUleb128(OS, Count, "reloc count"); 397 OSec->writeRelocations(OS); 398 } 399 } 400 401 static uint32_t getWasmFlags(const Symbol *Sym) { 402 uint32_t Flags = 0; 403 if (Sym->isLocal()) 404 Flags |= WASM_SYMBOL_BINDING_LOCAL; 405 if (Sym->isWeak()) 406 Flags |= WASM_SYMBOL_BINDING_WEAK; 407 if (Sym->isHidden()) 408 Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; 409 if (Sym->isUndefined()) 410 Flags |= WASM_SYMBOL_UNDEFINED; 411 return Flags; 412 } 413 414 // Some synthetic sections (e.g. "name" and "linking") have subsections. 415 // Just like the synthetic sections themselves these need to be created before 416 // they can be written out (since they are preceded by their length). This 417 // class is used to create subsections and then write them into the stream 418 // of the parent section. 419 class SubSection { 420 public: 421 explicit SubSection(uint32_t Type) : Type(Type) {} 422 423 void writeTo(raw_ostream &To) { 424 OS.flush(); 425 writeUleb128(To, Type, "subsection type"); 426 writeUleb128(To, Body.size(), "subsection size"); 427 To.write(Body.data(), Body.size()); 428 } 429 430 private: 431 uint32_t Type; 432 std::string Body; 433 434 public: 435 raw_string_ostream OS{Body}; 436 }; 437 438 // Create the custom "dylink" section containing information for the dynamic 439 // linker. 440 // See 441 // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md 442 void Writer::createDylinkSection() { 443 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "dylink"); 444 raw_ostream &OS = Section->getStream(); 445 446 writeUleb128(OS, MemSize, "MemSize"); 447 writeUleb128(OS, int(log2(MemAlign)), "MemAlign"); 448 writeUleb128(OS, IndirectFunctions.size(), "TableSize"); 449 writeUleb128(OS, 0, "TableAlign"); 450 } 451 452 // Create the custom "linking" section containing linker metadata. 453 // This is only created when relocatable output is requested. 454 void Writer::createLinkingSection() { 455 SyntheticSection *Section = 456 createSyntheticSection(WASM_SEC_CUSTOM, "linking"); 457 raw_ostream &OS = Section->getStream(); 458 459 writeUleb128(OS, WasmMetadataVersion, "Version"); 460 461 if (!SymtabEntries.empty()) { 462 SubSection Sub(WASM_SYMBOL_TABLE); 463 writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols"); 464 465 for (const Symbol *Sym : SymtabEntries) { 466 assert(Sym->isDefined() || Sym->isUndefined()); 467 WasmSymbolType Kind = Sym->getWasmType(); 468 uint32_t Flags = getWasmFlags(Sym); 469 470 writeU8(Sub.OS, Kind, "sym kind"); 471 writeUleb128(Sub.OS, Flags, "sym flags"); 472 473 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) { 474 writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); 475 if (Sym->isDefined()) 476 writeStr(Sub.OS, Sym->getName(), "sym name"); 477 } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) { 478 writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); 479 if (Sym->isDefined()) 480 writeStr(Sub.OS, Sym->getName(), "sym name"); 481 } else if (isa<DataSymbol>(Sym)) { 482 writeStr(Sub.OS, Sym->getName(), "sym name"); 483 if (auto *DataSym = dyn_cast<DefinedData>(Sym)) { 484 writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index"); 485 writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(), 486 "data offset"); 487 writeUleb128(Sub.OS, DataSym->getSize(), "data size"); 488 } 489 } else { 490 auto *S = cast<SectionSymbol>(Sym); 491 writeUleb128(Sub.OS, S->getOutputSectionIndex(), "sym section index"); 492 } 493 } 494 495 Sub.writeTo(OS); 496 } 497 498 if (Segments.size()) { 499 SubSection Sub(WASM_SEGMENT_INFO); 500 writeUleb128(Sub.OS, Segments.size(), "num data segments"); 501 for (const OutputSegment *S : Segments) { 502 writeStr(Sub.OS, S->Name, "segment name"); 503 writeUleb128(Sub.OS, S->Alignment, "alignment"); 504 writeUleb128(Sub.OS, 0, "flags"); 505 } 506 Sub.writeTo(OS); 507 } 508 509 if (!InitFunctions.empty()) { 510 SubSection Sub(WASM_INIT_FUNCS); 511 writeUleb128(Sub.OS, InitFunctions.size(), "num init functions"); 512 for (const WasmInitEntry &F : InitFunctions) { 513 writeUleb128(Sub.OS, F.Priority, "priority"); 514 writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index"); 515 } 516 Sub.writeTo(OS); 517 } 518 519 struct ComdatEntry { 520 unsigned Kind; 521 uint32_t Index; 522 }; 523 std::map<StringRef, std::vector<ComdatEntry>> Comdats; 524 525 for (const InputFunction *F : InputFunctions) { 526 StringRef Comdat = F->getComdatName(); 527 if (!Comdat.empty()) 528 Comdats[Comdat].emplace_back( 529 ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()}); 530 } 531 for (uint32_t I = 0; I < Segments.size(); ++I) { 532 const auto &InputSegments = Segments[I]->InputSegments; 533 if (InputSegments.empty()) 534 continue; 535 StringRef Comdat = InputSegments[0]->getComdatName(); 536 #ifndef NDEBUG 537 for (const InputSegment *IS : InputSegments) 538 assert(IS->getComdatName() == Comdat); 539 #endif 540 if (!Comdat.empty()) 541 Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I}); 542 } 543 544 if (!Comdats.empty()) { 545 SubSection Sub(WASM_COMDAT_INFO); 546 writeUleb128(Sub.OS, Comdats.size(), "num comdats"); 547 for (const auto &C : Comdats) { 548 writeStr(Sub.OS, C.first, "comdat name"); 549 writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use 550 writeUleb128(Sub.OS, C.second.size(), "num entries"); 551 for (const ComdatEntry &Entry : C.second) { 552 writeU8(Sub.OS, Entry.Kind, "entry kind"); 553 writeUleb128(Sub.OS, Entry.Index, "entry index"); 554 } 555 } 556 Sub.writeTo(OS); 557 } 558 } 559 560 // Create the custom "name" section containing debug symbol names. 561 void Writer::createNameSection() { 562 unsigned NumNames = NumImportedFunctions; 563 for (const InputFunction *F : InputFunctions) 564 if (!F->getName().empty() || !F->getDebugName().empty()) 565 ++NumNames; 566 567 if (NumNames == 0) 568 return; 569 570 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name"); 571 572 SubSection Sub(WASM_NAMES_FUNCTION); 573 writeUleb128(Sub.OS, NumNames, "name count"); 574 575 // Names must appear in function index order. As it happens ImportedSymbols 576 // and InputFunctions are numbered in order with imported functions coming 577 // first. 578 for (const Symbol *S : ImportedSymbols) { 579 if (auto *F = dyn_cast<FunctionSymbol>(S)) { 580 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); 581 writeStr(Sub.OS, toString(*S), "symbol name"); 582 } 583 } 584 for (const InputFunction *F : InputFunctions) { 585 if (!F->getName().empty()) { 586 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); 587 if (!F->getDebugName().empty()) { 588 writeStr(Sub.OS, F->getDebugName(), "symbol name"); 589 } else { 590 writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name"); 591 } 592 } 593 } 594 595 Sub.writeTo(Section->getStream()); 596 } 597 598 void Writer::writeHeader() { 599 memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); 600 } 601 602 void Writer::writeSections() { 603 uint8_t *Buf = Buffer->getBufferStart(); 604 parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); }); 605 } 606 607 // Fix the memory layout of the output binary. This assigns memory offsets 608 // to each of the input data sections as well as the explicit stack region. 609 // The default memory layout is as follows, from low to high. 610 // 611 // - initialized data (starting at Config->GlobalBase) 612 // - BSS data (not currently implemented in llvm) 613 // - explicit stack (Config->ZStackSize) 614 // - heap start / unallocated 615 // 616 // The --stack-first option means that stack is placed before any static data. 617 // This can be useful since it means that stack overflow traps immediately 618 // rather than overwriting global data, but also increases code size since all 619 // static data loads and stores requires larger offsets. 620 void Writer::layoutMemory() { 621 createOutputSegments(); 622 623 uint32_t MemoryPtr = 0; 624 625 auto PlaceStack = [&]() { 626 if (Config->Relocatable || Config->Shared) 627 return; 628 MemoryPtr = alignTo(MemoryPtr, kStackAlignment); 629 if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) 630 error("stack size must be " + Twine(kStackAlignment) + "-byte aligned"); 631 log("mem: stack size = " + Twine(Config->ZStackSize)); 632 log("mem: stack base = " + Twine(MemoryPtr)); 633 MemoryPtr += Config->ZStackSize; 634 auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer); 635 SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr; 636 log("mem: stack top = " + Twine(MemoryPtr)); 637 }; 638 639 if (Config->StackFirst) { 640 PlaceStack(); 641 } else { 642 MemoryPtr = Config->GlobalBase; 643 log("mem: global base = " + Twine(Config->GlobalBase)); 644 } 645 646 uint32_t DataStart = MemoryPtr; 647 648 // Arbitrarily set __dso_handle handle to point to the start of the data 649 // segments. 650 if (WasmSym::DsoHandle) 651 WasmSym::DsoHandle->setVirtualAddress(DataStart); 652 653 MemAlign = 0; 654 for (OutputSegment *Seg : Segments) { 655 MemAlign = std::max(MemAlign, Seg->Alignment); 656 MemoryPtr = alignTo(MemoryPtr, Seg->Alignment); 657 Seg->StartVA = MemoryPtr; 658 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, 659 MemoryPtr, Seg->Size, Seg->Alignment)); 660 MemoryPtr += Seg->Size; 661 } 662 663 // TODO: Add .bss space here. 664 if (WasmSym::DataEnd) 665 WasmSym::DataEnd->setVirtualAddress(MemoryPtr); 666 667 log("mem: static data = " + Twine(MemoryPtr - DataStart)); 668 669 if (Config->Shared) { 670 MemSize = MemoryPtr; 671 return; 672 } 673 674 if (!Config->StackFirst) 675 PlaceStack(); 676 677 // Set `__heap_base` to directly follow the end of the stack or global data. 678 // The fact that this comes last means that a malloc/brk implementation 679 // can grow the heap at runtime. 680 if (!Config->Relocatable) { 681 WasmSym::HeapBase->setVirtualAddress(MemoryPtr); 682 log("mem: heap base = " + Twine(MemoryPtr)); 683 } 684 685 if (Config->InitialMemory != 0) { 686 if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) 687 error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); 688 if (MemoryPtr > Config->InitialMemory) 689 error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); 690 else 691 MemoryPtr = Config->InitialMemory; 692 } 693 MemSize = MemoryPtr; 694 NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize; 695 log("mem: total pages = " + Twine(NumMemoryPages)); 696 697 if (Config->MaxMemory != 0) { 698 if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) 699 error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); 700 if (MemoryPtr > Config->MaxMemory) 701 error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); 702 MaxMemoryPages = Config->MaxMemory / WasmPageSize; 703 log("mem: max pages = " + Twine(MaxMemoryPages)); 704 } 705 } 706 707 SyntheticSection *Writer::createSyntheticSection(uint32_t Type, 708 StringRef Name) { 709 auto Sec = make<SyntheticSection>(Type, Name); 710 log("createSection: " + toString(*Sec)); 711 OutputSections.push_back(Sec); 712 return Sec; 713 } 714 715 void Writer::createSections() { 716 // Known sections 717 if (Config->Pic) 718 createDylinkSection(); 719 createTypeSection(); 720 createImportSection(); 721 createFunctionSection(); 722 createTableSection(); 723 createMemorySection(); 724 createGlobalSection(); 725 createExportSection(); 726 createElemSection(); 727 createCodeSection(); 728 createDataSection(); 729 createCustomSections(); 730 731 // Custom sections 732 if (Config->Relocatable) { 733 createLinkingSection(); 734 createRelocSections(); 735 } 736 if (!Config->StripDebug && !Config->StripAll) 737 createNameSection(); 738 739 for (OutputSection *S : OutputSections) { 740 S->setOffset(FileSize); 741 S->finalizeContents(); 742 FileSize += S->getSize(); 743 } 744 } 745 746 void Writer::calculateImports() { 747 for (Symbol *Sym : Symtab->getSymbols()) { 748 if (!Sym->isUndefined()) 749 continue; 750 if (isa<DataSymbol>(Sym)) 751 continue; 752 if (Sym->isWeak() && !Config->Relocatable) 753 continue; 754 if (!Sym->isLive()) 755 continue; 756 if (!Sym->IsUsedInRegularObj) 757 continue; 758 759 LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); 760 ImportedSymbols.emplace_back(Sym); 761 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) 762 F->setFunctionIndex(NumImportedFunctions++); 763 else 764 cast<GlobalSymbol>(Sym)->setGlobalIndex(NumImportedGlobals++); 765 } 766 } 767 768 void Writer::calculateExports() { 769 if (Config->Relocatable) 770 return; 771 772 if (!Config->Relocatable && !Config->ImportMemory) 773 Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); 774 775 if (!Config->Relocatable && Config->ExportTable) 776 Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0}); 777 778 unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size(); 779 780 for (Symbol *Sym : Symtab->getSymbols()) { 781 if (!Sym->isExported()) 782 continue; 783 if (!Sym->isLive()) 784 continue; 785 786 StringRef Name = Sym->getName(); 787 WasmExport Export; 788 if (auto *F = dyn_cast<DefinedFunction>(Sym)) { 789 Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()}; 790 } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) { 791 // TODO(sbc): Remove this check once to mutable global proposal is 792 // implement in all major browsers. 793 // See: https://github.com/WebAssembly/mutable-global 794 if (G->getGlobalType()->Mutable) { 795 // Only the __stack_pointer should ever be create as mutable. 796 assert(G == WasmSym::StackPointer); 797 continue; 798 } 799 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()}; 800 } else { 801 auto *D = cast<DefinedData>(Sym); 802 DefinedFakeGlobals.emplace_back(D); 803 Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++}; 804 } 805 806 LLVM_DEBUG(dbgs() << "Export: " << Name << "\n"); 807 Exports.push_back(Export); 808 } 809 } 810 811 void Writer::assignSymtab() { 812 if (!Config->Relocatable) 813 return; 814 815 StringMap<uint32_t> SectionSymbolIndices; 816 817 unsigned SymbolIndex = SymtabEntries.size(); 818 for (ObjFile *File : Symtab->ObjectFiles) { 819 LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n"); 820 for (Symbol *Sym : File->getSymbols()) { 821 if (Sym->getFile() != File) 822 continue; 823 824 if (auto *S = dyn_cast<SectionSymbol>(Sym)) { 825 StringRef Name = S->getName(); 826 if (CustomSectionMapping.count(Name) == 0) 827 continue; 828 829 auto SSI = SectionSymbolIndices.find(Name); 830 if (SSI != SectionSymbolIndices.end()) { 831 Sym->setOutputSymbolIndex(SSI->second); 832 continue; 833 } 834 835 SectionSymbolIndices[Name] = SymbolIndex; 836 CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym); 837 838 Sym->markLive(); 839 } 840 841 // (Since this is relocatable output, GC is not performed so symbols must 842 // be live.) 843 assert(Sym->isLive()); 844 Sym->setOutputSymbolIndex(SymbolIndex++); 845 SymtabEntries.emplace_back(Sym); 846 } 847 } 848 849 // For the moment, relocatable output doesn't contain any synthetic functions, 850 // so no need to look through the Symtab for symbols not referenced by 851 // Symtab->ObjectFiles. 852 } 853 854 uint32_t Writer::lookupType(const WasmSignature &Sig) { 855 auto It = TypeIndices.find(Sig); 856 if (It == TypeIndices.end()) { 857 error("type not found: " + toString(Sig)); 858 return 0; 859 } 860 return It->second; 861 } 862 863 uint32_t Writer::registerType(const WasmSignature &Sig) { 864 auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); 865 if (Pair.second) { 866 LLVM_DEBUG(dbgs() << "type " << toString(Sig) << "\n"); 867 Types.push_back(&Sig); 868 } 869 return Pair.first->second; 870 } 871 872 void Writer::calculateTypes() { 873 // The output type section is the union of the following sets: 874 // 1. Any signature used in the TYPE relocation 875 // 2. The signatures of all imported functions 876 // 3. The signatures of all defined functions 877 878 for (ObjFile *File : Symtab->ObjectFiles) { 879 ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); 880 for (uint32_t I = 0; I < Types.size(); I++) 881 if (File->TypeIsUsed[I]) 882 File->TypeMap[I] = registerType(Types[I]); 883 } 884 885 for (const Symbol *Sym : ImportedSymbols) 886 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) 887 registerType(*F->FunctionType); 888 889 for (const InputFunction *F : InputFunctions) 890 registerType(F->Signature); 891 } 892 893 void Writer::assignIndexes() { 894 assert(InputFunctions.empty()); 895 uint32_t FunctionIndex = NumImportedFunctions; 896 auto AddDefinedFunction = [&](InputFunction *Func) { 897 if (!Func->Live) 898 return; 899 InputFunctions.emplace_back(Func); 900 Func->setFunctionIndex(FunctionIndex++); 901 }; 902 903 for (InputFunction *Func : Symtab->SyntheticFunctions) 904 AddDefinedFunction(Func); 905 906 for (ObjFile *File : Symtab->ObjectFiles) { 907 LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); 908 for (InputFunction *Func : File->Functions) 909 AddDefinedFunction(Func); 910 } 911 912 uint32_t TableIndex = TableBase; 913 auto HandleRelocs = [&](InputChunk *Chunk) { 914 if (!Chunk->Live) 915 return; 916 ObjFile *File = Chunk->File; 917 ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); 918 for (const WasmRelocation &Reloc : Chunk->getRelocations()) { 919 if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 || 920 Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) { 921 FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index); 922 if (Sym->hasTableIndex() || !Sym->hasFunctionIndex()) 923 continue; 924 Sym->setTableIndex(TableIndex++); 925 IndirectFunctions.emplace_back(Sym); 926 } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) { 927 // Mark target type as live 928 File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]); 929 File->TypeIsUsed[Reloc.Index] = true; 930 } 931 } 932 }; 933 934 for (ObjFile *File : Symtab->ObjectFiles) { 935 LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n"); 936 for (InputChunk *Chunk : File->Functions) 937 HandleRelocs(Chunk); 938 for (InputChunk *Chunk : File->Segments) 939 HandleRelocs(Chunk); 940 for (auto &P : File->CustomSections) 941 HandleRelocs(P); 942 } 943 944 assert(InputGlobals.empty()); 945 uint32_t GlobalIndex = NumImportedGlobals; 946 auto AddDefinedGlobal = [&](InputGlobal *Global) { 947 if (Global->Live) { 948 LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n"); 949 Global->setGlobalIndex(GlobalIndex++); 950 InputGlobals.push_back(Global); 951 } 952 }; 953 954 for (InputGlobal *Global : Symtab->SyntheticGlobals) 955 AddDefinedGlobal(Global); 956 957 for (ObjFile *File : Symtab->ObjectFiles) { 958 LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); 959 for (InputGlobal *Global : File->Globals) 960 AddDefinedGlobal(Global); 961 } 962 } 963 964 static StringRef getOutputDataSegmentName(StringRef Name) { 965 // With PIC code we currently only support a single data segment since 966 // we only have a single __memory_base to use as our base address. 967 if (Config->Pic) 968 return "data"; 969 if (!Config->MergeDataSegments) 970 return Name; 971 if (Name.startswith(".text.")) 972 return ".text"; 973 if (Name.startswith(".data.")) 974 return ".data"; 975 if (Name.startswith(".bss.")) 976 return ".bss"; 977 if (Name.startswith(".rodata.")) 978 return ".rodata"; 979 return Name; 980 } 981 982 void Writer::createOutputSegments() { 983 for (ObjFile *File : Symtab->ObjectFiles) { 984 for (InputSegment *Segment : File->Segments) { 985 if (!Segment->Live) 986 continue; 987 StringRef Name = getOutputDataSegmentName(Segment->getName()); 988 OutputSegment *&S = SegmentMap[Name]; 989 if (S == nullptr) { 990 LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n"); 991 S = make<OutputSegment>(Name, Segments.size()); 992 Segments.push_back(S); 993 } 994 S->addInputSegment(Segment); 995 LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); 996 } 997 } 998 } 999 1000 static const int OPCODE_CALL = 0x10; 1001 static const int OPCODE_END = 0xb; 1002 1003 // Create synthetic "__wasm_call_ctors" function based on ctor functions 1004 // in input object. 1005 void Writer::createCtorFunction() { 1006 // First write the body's contents to a string. 1007 std::string BodyContent; 1008 { 1009 raw_string_ostream OS(BodyContent); 1010 writeUleb128(OS, 0, "num locals"); 1011 for (const WasmInitEntry &F : InitFunctions) { 1012 writeU8(OS, OPCODE_CALL, "CALL"); 1013 writeUleb128(OS, F.Sym->getFunctionIndex(), "function index"); 1014 } 1015 writeU8(OS, OPCODE_END, "END"); 1016 } 1017 1018 // Once we know the size of the body we can create the final function body 1019 std::string FunctionBody; 1020 { 1021 raw_string_ostream OS(FunctionBody); 1022 writeUleb128(OS, BodyContent.size(), "function size"); 1023 OS << BodyContent; 1024 } 1025 1026 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody)); 1027 cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body); 1028 } 1029 1030 // Populate InitFunctions vector with init functions from all input objects. 1031 // This is then used either when creating the output linking section or to 1032 // synthesize the "__wasm_call_ctors" function. 1033 void Writer::calculateInitFunctions() { 1034 for (ObjFile *File : Symtab->ObjectFiles) { 1035 const WasmLinkingData &L = File->getWasmObj()->linkingData(); 1036 for (const WasmInitFunc &F : L.InitFunctions) { 1037 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); 1038 if (*Sym->FunctionType != WasmSignature{{}, {}}) 1039 error("invalid signature for init func: " + toString(*Sym)); 1040 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); 1041 } 1042 } 1043 1044 // Sort in order of priority (lowest first) so that they are called 1045 // in the correct order. 1046 std::stable_sort(InitFunctions.begin(), InitFunctions.end(), 1047 [](const WasmInitEntry &L, const WasmInitEntry &R) { 1048 return L.Priority < R.Priority; 1049 }); 1050 } 1051 1052 void Writer::run() { 1053 if (Config->Relocatable || Config->Pic) 1054 Config->GlobalBase = 0; 1055 1056 // For PIC code the table base is assigned dynamically by the loader. 1057 // For non-PIC, we start at 1 so that accessing table index 0 always traps. 1058 if (!Config->Pic) 1059 TableBase = 1; 1060 1061 log("-- calculateImports"); 1062 calculateImports(); 1063 log("-- assignIndexes"); 1064 assignIndexes(); 1065 log("-- calculateInitFunctions"); 1066 calculateInitFunctions(); 1067 if (!Config->Relocatable) 1068 createCtorFunction(); 1069 log("-- calculateTypes"); 1070 calculateTypes(); 1071 log("-- layoutMemory"); 1072 layoutMemory(); 1073 log("-- calculateExports"); 1074 calculateExports(); 1075 log("-- calculateCustomSections"); 1076 calculateCustomSections(); 1077 log("-- assignSymtab"); 1078 assignSymtab(); 1079 1080 if (errorHandler().Verbose) { 1081 log("Defined Functions: " + Twine(InputFunctions.size())); 1082 log("Defined Globals : " + Twine(InputGlobals.size())); 1083 log("Function Imports : " + Twine(NumImportedFunctions)); 1084 log("Global Imports : " + Twine(NumImportedGlobals)); 1085 for (ObjFile *File : Symtab->ObjectFiles) 1086 File->dumpInfo(); 1087 } 1088 1089 createHeader(); 1090 log("-- createSections"); 1091 createSections(); 1092 1093 log("-- openFile"); 1094 openFile(); 1095 if (errorCount()) 1096 return; 1097 1098 writeHeader(); 1099 1100 log("-- writeSections"); 1101 writeSections(); 1102 if (errorCount()) 1103 return; 1104 1105 if (Error E = Buffer->commit()) 1106 fatal("failed to write the output file: " + toString(std::move(E))); 1107 } 1108 1109 // Open a result file. 1110 void Writer::openFile() { 1111 log("writing: " + Config->OutputFile); 1112 1113 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 1114 FileOutputBuffer::create(Config->OutputFile, FileSize, 1115 FileOutputBuffer::F_executable); 1116 1117 if (!BufferOrErr) 1118 error("failed to open " + Config->OutputFile + ": " + 1119 toString(BufferOrErr.takeError())); 1120 else 1121 Buffer = std::move(*BufferOrErr); 1122 } 1123 1124 void Writer::createHeader() { 1125 raw_string_ostream OS(Header); 1126 writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); 1127 writeU32(OS, WasmVersion, "wasm version"); 1128 OS.flush(); 1129 FileSize += Header.size(); 1130 } 1131 1132 void lld::wasm::writeResult() { Writer().run(); } 1133