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