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