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