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