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 12 #include "llvm/ADT/DenseSet.h" 13 #include "Config.h" 14 #include "InputChunks.h" 15 #include "OutputSections.h" 16 #include "OutputSegment.h" 17 #include "SymbolTable.h" 18 #include "WriterUtils.h" 19 #include "lld/Common/ErrorHandler.h" 20 #include "lld/Common/Memory.h" 21 #include "lld/Common/Threads.h" 22 #include "llvm/Support/FileOutputBuffer.h" 23 #include "llvm/Support/Format.h" 24 #include "llvm/Support/FormatVariadic.h" 25 #include "llvm/Support/LEB128.h" 26 27 #include <cstdarg> 28 #include <map> 29 30 #define DEBUG_TYPE "lld" 31 32 using namespace llvm; 33 using namespace llvm::wasm; 34 using namespace lld; 35 using namespace lld::wasm; 36 37 static constexpr int kStackAlignment = 16; 38 39 namespace { 40 41 // Traits for using WasmSignature in a DenseMap. 42 struct WasmSignatureDenseMapInfo { 43 static WasmSignature getEmptyKey() { 44 WasmSignature Sig; 45 Sig.ReturnType = 1; 46 return Sig; 47 } 48 static WasmSignature getTombstoneKey() { 49 WasmSignature Sig; 50 Sig.ReturnType = 2; 51 return Sig; 52 } 53 static unsigned getHashValue(const WasmSignature &Sig) { 54 uintptr_t Value = 0; 55 Value += DenseMapInfo<int32_t>::getHashValue(Sig.ReturnType); 56 for (int32_t Param : Sig.ParamTypes) 57 Value += DenseMapInfo<int32_t>::getHashValue(Param); 58 return Value; 59 } 60 static bool isEqual(const WasmSignature &LHS, const WasmSignature &RHS) { 61 return LHS == RHS; 62 } 63 }; 64 65 // The writer writes a SymbolTable result to a file. 66 class Writer { 67 public: 68 void run(); 69 70 private: 71 void openFile(); 72 73 uint32_t lookupType(const WasmSignature &Sig); 74 uint32_t registerType(const WasmSignature &Sig); 75 void createCtorFunction(); 76 void calculateInitFunctions(); 77 void assignIndexes(); 78 void calculateImports(); 79 void calculateOffsets(); 80 void calculateTypes(); 81 void createOutputSegments(); 82 void layoutMemory(); 83 void createHeader(); 84 void createSections(); 85 SyntheticSection *createSyntheticSection(uint32_t Type, 86 StringRef Name = ""); 87 88 // Builtin sections 89 void createTypeSection(); 90 void createFunctionSection(); 91 void createTableSection(); 92 void createGlobalSection(); 93 void createExportSection(); 94 void createImportSection(); 95 void createMemorySection(); 96 void createElemSection(); 97 void createStartSection(); 98 void createCodeSection(); 99 void createDataSection(); 100 101 // Custom sections 102 void createRelocSections(); 103 void createLinkingSection(); 104 void createNameSection(); 105 106 void writeHeader(); 107 void writeSections(); 108 109 uint64_t FileSize = 0; 110 uint32_t DataSize = 0; 111 uint32_t NumMemoryPages = 0; 112 uint32_t InitialTableOffset = 0; 113 114 std::vector<const WasmSignature *> Types; 115 DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices; 116 std::vector<const Symbol *> ImportedFunctions; 117 std::vector<const Symbol *> ImportedGlobals; 118 std::vector<const Symbol *> DefinedGlobals; 119 std::vector<InputFunction *> DefinedFunctions; 120 std::vector<const Symbol *> IndirectFunctions; 121 std::vector<WasmInitFunc> InitFunctions; 122 123 // Elements that are used to construct the final output 124 std::string Header; 125 std::vector<OutputSection *> OutputSections; 126 127 std::unique_ptr<FileOutputBuffer> Buffer; 128 std::unique_ptr<SyntheticFunction> CtorFunction; 129 std::string CtorFunctionBody; 130 131 std::vector<OutputSegment *> Segments; 132 llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap; 133 }; 134 135 } // anonymous namespace 136 137 static void debugPrint(const char *fmt, ...) { 138 if (!errorHandler().Verbose) 139 return; 140 fprintf(stderr, "lld: "); 141 va_list ap; 142 va_start(ap, fmt); 143 vfprintf(stderr, fmt, ap); 144 va_end(ap); 145 } 146 147 void Writer::createImportSection() { 148 uint32_t NumImports = ImportedFunctions.size() + ImportedGlobals.size(); 149 if (Config->ImportMemory) 150 ++NumImports; 151 152 if (NumImports == 0) 153 return; 154 155 SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT); 156 raw_ostream &OS = Section->getStream(); 157 158 writeUleb128(OS, NumImports, "import count"); 159 160 for (const Symbol *Sym : ImportedFunctions) { 161 WasmImport Import; 162 Import.Module = "env"; 163 Import.Field = Sym->getName(); 164 Import.Kind = WASM_EXTERNAL_FUNCTION; 165 Import.SigIndex = lookupType(Sym->getFunctionType()); 166 writeImport(OS, Import); 167 } 168 169 if (Config->ImportMemory) { 170 WasmImport Import; 171 Import.Module = "env"; 172 Import.Field = "memory"; 173 Import.Kind = WASM_EXTERNAL_MEMORY; 174 Import.Memory.Flags = 0; 175 Import.Memory.Initial = NumMemoryPages; 176 writeImport(OS, Import); 177 } 178 179 for (const Symbol *Sym : ImportedGlobals) { 180 WasmImport Import; 181 Import.Module = "env"; 182 Import.Field = Sym->getName(); 183 Import.Kind = WASM_EXTERNAL_GLOBAL; 184 Import.Global.Mutable = false; 185 Import.Global.Type = WASM_TYPE_I32; 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 (DefinedFunctions.empty()) 200 return; 201 202 SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION); 203 raw_ostream &OS = Section->getStream(); 204 205 writeUleb128(OS, DefinedFunctions.size(), "function count"); 206 for (const InputFunction *Func : DefinedFunctions) 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 writeUleb128(OS, 1, "memory count"); 218 writeUleb128(OS, 0, "memory limits flags"); 219 writeUleb128(OS, NumMemoryPages, "initial pages"); 220 } 221 222 void Writer::createGlobalSection() { 223 if (DefinedGlobals.empty()) 224 return; 225 226 SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL); 227 raw_ostream &OS = Section->getStream(); 228 229 writeUleb128(OS, DefinedGlobals.size(), "global count"); 230 for (const Symbol *Sym : DefinedGlobals) { 231 WasmGlobal Global; 232 Global.Type = WASM_TYPE_I32; 233 Global.Mutable = Sym == Config->StackPointerSymbol; 234 Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; 235 Global.InitExpr.Value.Int32 = Sym->getVirtualAddress(); 236 writeGlobal(OS, Global); 237 } 238 } 239 240 void Writer::createTableSection() { 241 // Always output a table section, even if there are no indirect calls. 242 // There are two reasons for this: 243 // 1. For executables it is useful to have an empty table slot at 0 244 // which can be filled with a null function call handler. 245 // 2. If we don't do this, any program that contains a call_indirect but 246 // no address-taken function will fail at validation time since it is 247 // a validation error to include a call_indirect instruction if there 248 // is not table. 249 uint32_t TableSize = InitialTableOffset + IndirectFunctions.size(); 250 251 SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE); 252 raw_ostream &OS = Section->getStream(); 253 254 writeUleb128(OS, 1, "table count"); 255 writeSleb128(OS, WASM_TYPE_ANYFUNC, "table type"); 256 writeUleb128(OS, WASM_LIMITS_FLAG_HAS_MAX, "table flags"); 257 writeUleb128(OS, TableSize, "table initial size"); 258 writeUleb128(OS, TableSize, "table max size"); 259 } 260 261 void Writer::createExportSection() { 262 bool ExportMemory = !Config->Relocatable && !Config->ImportMemory; 263 Symbol *EntrySym = Symtab->find(Config->Entry); 264 bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined(); 265 bool ExportHidden = Config->EmitRelocs; 266 267 uint32_t NumExports = ExportMemory ? 1 : 0; 268 269 std::vector<const Symbol *> SymbolExports; 270 if (ExportEntry) 271 SymbolExports.emplace_back(EntrySym); 272 273 for (const Symbol *Sym : Symtab->getSymbols()) { 274 if (Sym->isUndefined() || Sym->isGlobal()) 275 continue; 276 if (Sym->isHidden() && !ExportHidden) 277 continue; 278 if (ExportEntry && Sym == EntrySym) 279 continue; 280 SymbolExports.emplace_back(Sym); 281 } 282 283 for (const Symbol *Sym : DefinedGlobals) { 284 // Can't export the SP right now because it mutable and mutable globals 285 // connot be exported. 286 if (Sym == Config->StackPointerSymbol) 287 continue; 288 SymbolExports.emplace_back(Sym); 289 } 290 291 NumExports += SymbolExports.size(); 292 if (!NumExports) 293 return; 294 295 SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT); 296 raw_ostream &OS = Section->getStream(); 297 298 writeUleb128(OS, NumExports, "export count"); 299 300 if (ExportMemory) { 301 WasmExport MemoryExport; 302 MemoryExport.Name = "memory"; 303 MemoryExport.Kind = WASM_EXTERNAL_MEMORY; 304 MemoryExport.Index = 0; 305 writeExport(OS, MemoryExport); 306 } 307 308 for (const Symbol *Sym : SymbolExports) { 309 DEBUG(dbgs() << "Export: " << Sym->getName() << "\n"); 310 WasmExport Export; 311 Export.Name = Sym->getName(); 312 Export.Index = Sym->getOutputIndex(); 313 if (Sym->isFunction()) 314 Export.Kind = WASM_EXTERNAL_FUNCTION; 315 else 316 Export.Kind = WASM_EXTERNAL_GLOBAL; 317 writeExport(OS, Export); 318 } 319 } 320 321 void Writer::createStartSection() {} 322 323 void Writer::createElemSection() { 324 if (IndirectFunctions.empty()) 325 return; 326 327 SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM); 328 raw_ostream &OS = Section->getStream(); 329 330 writeUleb128(OS, 1, "segment count"); 331 writeUleb128(OS, 0, "table index"); 332 WasmInitExpr InitExpr; 333 InitExpr.Opcode = WASM_OPCODE_I32_CONST; 334 InitExpr.Value.Int32 = InitialTableOffset; 335 writeInitExpr(OS, InitExpr); 336 writeUleb128(OS, IndirectFunctions.size(), "elem count"); 337 338 uint32_t TableIndex = InitialTableOffset; 339 for (const Symbol *Sym : IndirectFunctions) { 340 assert(Sym->getTableIndex() == TableIndex); 341 writeUleb128(OS, Sym->getOutputIndex(), "function index"); 342 ++TableIndex; 343 } 344 } 345 346 void Writer::createCodeSection() { 347 if (DefinedFunctions.empty()) 348 return; 349 350 log("createCodeSection"); 351 352 auto Section = make<CodeSection>(DefinedFunctions); 353 OutputSections.push_back(Section); 354 } 355 356 void Writer::createDataSection() { 357 if (!Segments.size()) 358 return; 359 360 log("createDataSection"); 361 auto Section = make<DataSection>(Segments); 362 OutputSections.push_back(Section); 363 } 364 365 // Create relocations sections in the final output. 366 // These are only created when relocatable output is requested. 367 void Writer::createRelocSections() { 368 log("createRelocSections"); 369 // Don't use iterator here since we are adding to OutputSection 370 size_t OrigSize = OutputSections.size(); 371 for (size_t i = 0; i < OrigSize; i++) { 372 OutputSection *S = OutputSections[i]; 373 const char *name; 374 uint32_t Count = S->numRelocations(); 375 if (!Count) 376 continue; 377 378 if (S->Type == WASM_SEC_DATA) 379 name = "reloc.DATA"; 380 else if (S->Type == WASM_SEC_CODE) 381 name = "reloc.CODE"; 382 else 383 llvm_unreachable("relocations only supported for code and data"); 384 385 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, name); 386 raw_ostream &OS = Section->getStream(); 387 writeUleb128(OS, S->Type, "reloc section"); 388 writeUleb128(OS, Count, "reloc count"); 389 S->writeRelocations(OS); 390 } 391 } 392 393 // Create the custom "linking" section containing linker metadata. 394 // This is only created when relocatable output is requested. 395 void Writer::createLinkingSection() { 396 SyntheticSection *Section = 397 createSyntheticSection(WASM_SEC_CUSTOM, "linking"); 398 raw_ostream &OS = Section->getStream(); 399 400 SubSection DataSizeSubSection(WASM_DATA_SIZE); 401 writeUleb128(DataSizeSubSection.getStream(), DataSize, "data size"); 402 DataSizeSubSection.finalizeContents(); 403 DataSizeSubSection.writeToStream(OS); 404 405 if (!Config->Relocatable) 406 return; 407 408 if (Segments.size()) { 409 SubSection SubSection(WASM_SEGMENT_INFO); 410 writeUleb128(SubSection.getStream(), Segments.size(), "num data segments"); 411 for (const OutputSegment *S : Segments) { 412 writeStr(SubSection.getStream(), S->Name, "segment name"); 413 writeUleb128(SubSection.getStream(), S->Alignment, "alignment"); 414 writeUleb128(SubSection.getStream(), 0, "flags"); 415 } 416 SubSection.finalizeContents(); 417 SubSection.writeToStream(OS); 418 } 419 420 if (!InitFunctions.empty()) { 421 SubSection SubSection(WASM_INIT_FUNCS); 422 writeUleb128(SubSection.getStream(), InitFunctions.size(), 423 "num init functionsw"); 424 for (const WasmInitFunc &F : InitFunctions) { 425 writeUleb128(SubSection.getStream(), F.Priority, "priority"); 426 writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index"); 427 } 428 SubSection.finalizeContents(); 429 SubSection.writeToStream(OS); 430 } 431 432 struct ComdatEntry { unsigned Kind; uint32_t Index; }; 433 std::map<StringRef,std::vector<ComdatEntry>> Comdats; 434 435 for (const InputFunction *F : DefinedFunctions) { 436 StringRef Comdat = F->getComdat(); 437 if (!Comdat.empty()) 438 Comdats[Comdat].emplace_back( 439 ComdatEntry{WASM_COMDAT_FUNCTION, F->getOutputIndex()}); 440 } 441 for (uint32_t I = 0; I < Segments.size(); ++I) { 442 const auto &InputSegments = Segments[I]->InputSegments; 443 if (InputSegments.empty()) 444 continue; 445 StringRef Comdat = InputSegments[0]->getComdat(); 446 #ifndef NDEBUG 447 for (const InputSegment *IS : InputSegments) 448 assert(IS->getComdat() == Comdat); 449 #endif 450 if (!Comdat.empty()) 451 Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I}); 452 } 453 454 if (!Comdats.empty()) { 455 SubSection SubSection(WASM_COMDAT_INFO); 456 writeUleb128(SubSection.getStream(), Comdats.size(), "num comdats"); 457 for (const auto &C : Comdats) { 458 writeStr(SubSection.getStream(), C.first, "comdat name"); 459 writeUleb128(SubSection.getStream(), 0, "comdat flags"); // flags for future use 460 writeUleb128(SubSection.getStream(), C.second.size(), "num entries"); 461 for (const ComdatEntry &Entry : C.second) { 462 writeUleb128(SubSection.getStream(), Entry.Kind, "entry kind"); 463 writeUleb128(SubSection.getStream(), Entry.Index, "entry index"); 464 } 465 } 466 SubSection.finalizeContents(); 467 SubSection.writeToStream(OS); 468 } 469 } 470 471 // Create the custom "name" section containing debug symbol names. 472 void Writer::createNameSection() { 473 // Create an array of all function sorted by function index space 474 std::vector<const Symbol *> Names; 475 476 auto AddToNames = [&](Symbol* S) { 477 if (!S->isFunction() || S->WrittenToNameSec) 478 return; 479 // We also need to guard against two different symbols (two different 480 // names) for the same wasm function. While this is possible (aliases) 481 // it is not legal in the "name" section. 482 InputFunction *Function = S->getFunction(); 483 if (Function) { 484 if (Function->WrittenToNameSec) 485 return; 486 Function->WrittenToNameSec = true; 487 } 488 S->WrittenToNameSec = true; 489 Names.emplace_back(S); 490 }; 491 492 for (ObjFile *File : Symtab->ObjectFiles) { 493 Names.reserve(Names.size() + File->getSymbols().size()); 494 DEBUG(dbgs() << "adding names from: " << File->getName() << "\n"); 495 for (Symbol *S : File->getSymbols()) { 496 if (S->isWeak()) 497 continue; 498 AddToNames(S); 499 } 500 } 501 502 DEBUG(dbgs() << "adding symtab names\n"); 503 for (Symbol *S : Symtab->getSymbols()) { 504 DEBUG(dbgs() << "sym: " << S->getName() << "\n"); 505 if (S->getFile()) 506 continue; 507 AddToNames(S); 508 } 509 510 SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name"); 511 512 std::sort(Names.begin(), Names.end(), [](const Symbol *A, const Symbol *B) { 513 return A->getOutputIndex() < B->getOutputIndex(); 514 }); 515 516 SubSection FunctionSubsection(WASM_NAMES_FUNCTION); 517 raw_ostream &OS = FunctionSubsection.getStream(); 518 writeUleb128(OS, Names.size(), "name count"); 519 520 // We have to iterate through the inputs twice so that all the imports 521 // appear first before any of the local function names. 522 for (const Symbol *S : Names) { 523 writeUleb128(OS, S->getOutputIndex(), "func index"); 524 writeStr(OS, S->getName(), "symbol name"); 525 } 526 527 FunctionSubsection.finalizeContents(); 528 FunctionSubsection.writeToStream(Section->getStream()); 529 } 530 531 void Writer::writeHeader() { 532 memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); 533 } 534 535 void Writer::writeSections() { 536 uint8_t *Buf = Buffer->getBufferStart(); 537 parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); }); 538 } 539 540 // Fix the memory layout of the output binary. This assigns memory offsets 541 // to each of the input data sections as well as the explicit stack region. 542 void Writer::layoutMemory() { 543 uint32_t MemoryPtr = 0; 544 if (!Config->Relocatable) { 545 MemoryPtr = Config->GlobalBase; 546 debugPrint("mem: global base = %d\n", Config->GlobalBase); 547 } 548 549 createOutputSegments(); 550 551 // Static data comes first 552 for (OutputSegment *Seg : Segments) { 553 MemoryPtr = alignTo(MemoryPtr, Seg->Alignment); 554 Seg->StartVA = MemoryPtr; 555 debugPrint("mem: %-15s offset=%-8d size=%-8d align=%d\n", 556 Seg->Name.str().c_str(), MemoryPtr, Seg->Size, Seg->Alignment); 557 MemoryPtr += Seg->Size; 558 } 559 560 DataSize = MemoryPtr; 561 if (!Config->Relocatable) 562 DataSize -= Config->GlobalBase; 563 debugPrint("mem: static data = %d\n", DataSize); 564 565 // Stack comes after static data 566 if (!Config->Relocatable) { 567 MemoryPtr = alignTo(MemoryPtr, kStackAlignment); 568 if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) 569 error("stack size must be " + Twine(kStackAlignment) + "-byte aligned"); 570 debugPrint("mem: stack size = %d\n", Config->ZStackSize); 571 debugPrint("mem: stack base = %d\n", MemoryPtr); 572 MemoryPtr += Config->ZStackSize; 573 Config->StackPointerSymbol->setVirtualAddress(MemoryPtr); 574 debugPrint("mem: stack top = %d\n", MemoryPtr); 575 // Set `__heap_base` to directly follow the end of the stack. We don't 576 // allocate any heap memory up front, but instead really on the malloc/brk 577 // implementation growing the memory at runtime. 578 Config->HeapBaseSymbol->setVirtualAddress(MemoryPtr); 579 debugPrint("mem: heap base = %d\n", MemoryPtr); 580 } 581 582 uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize); 583 NumMemoryPages = MemSize / WasmPageSize; 584 debugPrint("mem: total pages = %d\n", NumMemoryPages); 585 } 586 587 SyntheticSection *Writer::createSyntheticSection(uint32_t Type, 588 StringRef Name) { 589 auto Sec = make<SyntheticSection>(Type, Name); 590 log("createSection: " + toString(*Sec)); 591 OutputSections.push_back(Sec); 592 return Sec; 593 } 594 595 void Writer::createSections() { 596 // Known sections 597 createTypeSection(); 598 createImportSection(); 599 createFunctionSection(); 600 createTableSection(); 601 createMemorySection(); 602 createGlobalSection(); 603 createExportSection(); 604 createStartSection(); 605 createElemSection(); 606 createCodeSection(); 607 createDataSection(); 608 609 // Custom sections 610 if (Config->EmitRelocs) 611 createRelocSections(); 612 createLinkingSection(); 613 if (!Config->StripDebug && !Config->StripAll) 614 createNameSection(); 615 616 for (OutputSection *S : OutputSections) { 617 S->setOffset(FileSize); 618 S->finalizeContents(); 619 FileSize += S->getSize(); 620 } 621 } 622 623 void Writer::calculateImports() { 624 for (Symbol *Sym : Symtab->getSymbols()) { 625 if (!Sym->isUndefined() || Sym->isWeak()) 626 continue; 627 628 if (Sym->isFunction()) { 629 Sym->setOutputIndex(ImportedFunctions.size()); 630 ImportedFunctions.push_back(Sym); 631 } else { 632 Sym->setOutputIndex(ImportedGlobals.size()); 633 ImportedGlobals.push_back(Sym); 634 } 635 } 636 } 637 638 uint32_t Writer::lookupType(const WasmSignature &Sig) { 639 auto It = TypeIndices.find(Sig); 640 if (It == TypeIndices.end()) { 641 error("type not found: " + toString(Sig)); 642 return 0; 643 } 644 return It->second; 645 } 646 647 uint32_t Writer::registerType(const WasmSignature &Sig) { 648 auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size())); 649 if (Pair.second) { 650 DEBUG(dbgs() << "type " << toString(Sig) << "\n"); 651 Types.push_back(&Sig); 652 } 653 return Pair.first->second; 654 } 655 656 void Writer::calculateTypes() { 657 for (ObjFile *File : Symtab->ObjectFiles) { 658 File->TypeMap.reserve(File->getWasmObj()->types().size()); 659 for (const WasmSignature &Sig : File->getWasmObj()->types()) 660 File->TypeMap.push_back(registerType(Sig)); 661 } 662 663 for (Symbol *Sym : Symtab->getSymbols()) 664 if (Sym->isFunction()) 665 registerType(Sym->getFunctionType()); 666 } 667 668 void Writer::assignIndexes() { 669 uint32_t GlobalIndex = ImportedGlobals.size() + DefinedGlobals.size(); 670 uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size(); 671 672 if (Config->StackPointerSymbol) { 673 DefinedGlobals.emplace_back(Config->StackPointerSymbol); 674 Config->StackPointerSymbol->setOutputIndex(GlobalIndex++); 675 } 676 677 if (Config->HeapBaseSymbol) { 678 DefinedGlobals.emplace_back(Config->HeapBaseSymbol); 679 Config->HeapBaseSymbol->setOutputIndex(GlobalIndex++); 680 } 681 682 if (Config->EmitRelocs) 683 DefinedGlobals.reserve(Symtab->getSymbols().size()); 684 685 uint32_t TableIndex = InitialTableOffset; 686 687 for (ObjFile *File : Symtab->ObjectFiles) { 688 if (Config->EmitRelocs) { 689 DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); 690 for (Symbol *Sym : File->getSymbols()) { 691 // Create wasm globals for data symbols defined in this file 692 if (!Sym->isDefined() || File != Sym->getFile()) 693 continue; 694 if (Sym->isFunction()) 695 continue; 696 697 DefinedGlobals.emplace_back(Sym); 698 Sym->setOutputIndex(GlobalIndex++); 699 } 700 } 701 } 702 703 for (ObjFile *File : Symtab->ObjectFiles) { 704 DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); 705 for (InputFunction *Func : File->Functions) { 706 if (Func->Discarded) 707 continue; 708 DefinedFunctions.emplace_back(Func); 709 Func->setOutputIndex(FunctionIndex++); 710 } 711 } 712 713 for (ObjFile *File : Symtab->ObjectFiles) { 714 DEBUG(dbgs() << "Table Indexes: " << File->getName() << "\n"); 715 for (Symbol *Sym : File->getTableSymbols()) { 716 if (Sym->hasTableIndex() || !Sym->hasOutputIndex()) 717 continue; 718 Sym->setTableIndex(TableIndex++); 719 IndirectFunctions.emplace_back(Sym); 720 } 721 } 722 } 723 724 static StringRef getOutputDataSegmentName(StringRef Name) { 725 if (Config->Relocatable) 726 return Name; 727 728 for (StringRef V : 729 {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.", 730 ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.", 731 ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) { 732 StringRef Prefix = V.drop_back(); 733 if (Name.startswith(V) || Name == Prefix) 734 return Prefix; 735 } 736 737 return Name; 738 } 739 740 void Writer::createOutputSegments() { 741 for (ObjFile *File : Symtab->ObjectFiles) { 742 for (InputSegment *Segment : File->Segments) { 743 if (Segment->Discarded) 744 continue; 745 StringRef Name = getOutputDataSegmentName(Segment->getName()); 746 OutputSegment *&S = SegmentMap[Name]; 747 if (S == nullptr) { 748 DEBUG(dbgs() << "new segment: " << Name << "\n"); 749 S = make<OutputSegment>(Name); 750 Segments.push_back(S); 751 } 752 S->addInputSegment(Segment); 753 DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); 754 } 755 } 756 } 757 758 static const int OPCODE_CALL = 0x10; 759 static const int OPCODE_END = 0xb; 760 761 // Create synthetic "__wasm_call_ctors" function based on ctor functions 762 // in input object. 763 void Writer::createCtorFunction() { 764 uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size(); 765 Config->CtorSymbol->setOutputIndex(FunctionIndex); 766 767 // First write the body bytes to a string. 768 std::string FunctionBody; 769 static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; 770 { 771 raw_string_ostream OS(FunctionBody); 772 writeUleb128(OS, 0, "num locals"); 773 for (const WasmInitFunc &F : InitFunctions) { 774 writeU8(OS, OPCODE_CALL, "CALL"); 775 writeUleb128(OS, F.FunctionIndex, "function index"); 776 } 777 writeU8(OS, OPCODE_END, "END"); 778 } 779 780 // Once we know the size of the body we can create the final function body 781 raw_string_ostream OS(CtorFunctionBody); 782 writeUleb128(OS, FunctionBody.size(), "function size"); 783 OS.flush(); 784 CtorFunctionBody += FunctionBody; 785 ArrayRef<uint8_t> BodyArray( 786 reinterpret_cast<const uint8_t *>(CtorFunctionBody.data()), 787 CtorFunctionBody.size()); 788 CtorFunction = llvm::make_unique<SyntheticFunction>(Signature, BodyArray); 789 DefinedFunctions.emplace_back(CtorFunction.get()); 790 } 791 792 // Populate InitFunctions vector with init functions from all input objects. 793 // This is then used either when creating the output linking section or to 794 // synthesize the "__wasm_call_ctors" function. 795 void Writer::calculateInitFunctions() { 796 for (ObjFile *File : Symtab->ObjectFiles) { 797 const WasmLinkingData &L = File->getWasmObj()->linkingData(); 798 InitFunctions.reserve(InitFunctions.size() + L.InitFunctions.size()); 799 for (const WasmInitFunc &F : L.InitFunctions) 800 InitFunctions.emplace_back(WasmInitFunc{ 801 F.Priority, File->relocateFunctionIndex(F.FunctionIndex)}); 802 } 803 // Sort in order of priority (lowest first) so that they are called 804 // in the correct order. 805 std::sort(InitFunctions.begin(), InitFunctions.end(), 806 [](const WasmInitFunc &L, const WasmInitFunc &R) { 807 return L.Priority < R.Priority; 808 }); 809 } 810 811 void Writer::run() { 812 if (!Config->Relocatable) 813 InitialTableOffset = 1; 814 815 log("-- calculateTypes"); 816 calculateTypes(); 817 log("-- calculateImports"); 818 calculateImports(); 819 log("-- assignIndexes"); 820 assignIndexes(); 821 log("-- calculateInitFunctions"); 822 calculateInitFunctions(); 823 if (!Config->Relocatable) 824 createCtorFunction(); 825 826 if (errorHandler().Verbose) { 827 log("Defined Functions: " + Twine(DefinedFunctions.size())); 828 log("Defined Globals : " + Twine(DefinedGlobals.size())); 829 log("Function Imports : " + Twine(ImportedFunctions.size())); 830 log("Global Imports : " + Twine(ImportedGlobals.size())); 831 log("Total Imports : " + 832 Twine(ImportedFunctions.size() + ImportedGlobals.size())); 833 for (ObjFile *File : Symtab->ObjectFiles) 834 File->dumpInfo(); 835 } 836 837 log("-- layoutMemory"); 838 layoutMemory(); 839 840 createHeader(); 841 log("-- createSections"); 842 createSections(); 843 844 log("-- openFile"); 845 openFile(); 846 if (errorCount()) 847 return; 848 849 writeHeader(); 850 851 log("-- writeSections"); 852 writeSections(); 853 if (errorCount()) 854 return; 855 856 if (Error E = Buffer->commit()) 857 fatal("failed to write the output file: " + toString(std::move(E))); 858 } 859 860 // Open a result file. 861 void Writer::openFile() { 862 log("writing: " + Config->OutputFile); 863 ::remove(Config->OutputFile.str().c_str()); 864 865 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 866 FileOutputBuffer::create(Config->OutputFile, FileSize, 867 FileOutputBuffer::F_executable); 868 869 if (!BufferOrErr) 870 error("failed to open " + Config->OutputFile + ": " + 871 toString(BufferOrErr.takeError())); 872 else 873 Buffer = std::move(*BufferOrErr); 874 } 875 876 void Writer::createHeader() { 877 raw_string_ostream OS(Header); 878 writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); 879 writeU32(OS, WasmVersion, "wasm version"); 880 OS.flush(); 881 FileSize += Header.size(); 882 } 883 884 void lld::wasm::writeResult() { Writer().run(); } 885