1 //===- Writer.cpp ---------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Writer.h" 10 #include "Config.h" 11 #include "InputChunks.h" 12 #include "InputEvent.h" 13 #include "InputGlobal.h" 14 #include "OutputSections.h" 15 #include "OutputSegment.h" 16 #include "Relocations.h" 17 #include "SymbolTable.h" 18 #include "SyntheticSections.h" 19 #include "WriterUtils.h" 20 #include "lld/Common/ErrorHandler.h" 21 #include "lld/Common/Memory.h" 22 #include "lld/Common/Strings.h" 23 #include "lld/Common/Threads.h" 24 #include "llvm/ADT/DenseSet.h" 25 #include "llvm/ADT/SmallSet.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/ADT/StringMap.h" 28 #include "llvm/BinaryFormat/Wasm.h" 29 #include "llvm/Object/WasmTraits.h" 30 #include "llvm/Support/FileOutputBuffer.h" 31 #include "llvm/Support/Format.h" 32 #include "llvm/Support/FormatVariadic.h" 33 #include "llvm/Support/LEB128.h" 34 35 #include <cstdarg> 36 #include <map> 37 38 #define DEBUG_TYPE "lld" 39 40 using namespace llvm; 41 using namespace llvm::wasm; 42 using namespace lld; 43 using namespace lld::wasm; 44 45 static constexpr int StackAlignment = 16; 46 47 namespace { 48 49 // The writer writes a SymbolTable result to a file. 50 class Writer { 51 public: 52 void run(); 53 54 private: 55 void openFile(); 56 57 void createApplyRelocationsFunction(); 58 void createCallCtorsFunction(); 59 60 void assignIndexes(); 61 void populateSymtab(); 62 void populateProducers(); 63 void populateTargetFeatures(); 64 void calculateInitFunctions(); 65 void calculateImports(); 66 void calculateExports(); 67 void calculateCustomSections(); 68 void calculateTypes(); 69 void createOutputSegments(); 70 void layoutMemory(); 71 void createHeader(); 72 73 void addSection(OutputSection *Sec); 74 75 void addSections(); 76 void addStartStopSymbols(const InputSegment *Seg); 77 78 void createCustomSections(); 79 void createSyntheticSections(); 80 void finalizeSections(); 81 82 // Custom sections 83 void createRelocSections(); 84 85 void writeHeader(); 86 void writeSections(); 87 88 uint64_t FileSize = 0; 89 uint32_t TableBase = 0; 90 91 std::vector<WasmInitEntry> InitFunctions; 92 llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping; 93 94 // Elements that are used to construct the final output 95 std::string Header; 96 std::vector<OutputSection *> OutputSections; 97 98 std::unique_ptr<FileOutputBuffer> Buffer; 99 100 std::vector<OutputSegment *> Segments; 101 llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap; 102 }; 103 104 } // anonymous namespace 105 106 void Writer::calculateCustomSections() { 107 log("calculateCustomSections"); 108 bool StripDebug = Config->StripDebug || Config->StripAll; 109 for (ObjFile *File : Symtab->ObjectFiles) { 110 for (InputSection *Section : File->CustomSections) { 111 StringRef Name = Section->getName(); 112 // These custom sections are known the linker and synthesized rather than 113 // blindly copied 114 if (Name == "linking" || Name == "name" || Name == "producers" || 115 Name == "target_features" || Name.startswith("reloc.")) 116 continue; 117 // .. or it is a debug section 118 if (StripDebug && Name.startswith(".debug_")) 119 continue; 120 CustomSectionMapping[Name].push_back(Section); 121 } 122 } 123 } 124 125 void Writer::createCustomSections() { 126 log("createCustomSections"); 127 for (auto &Pair : CustomSectionMapping) { 128 StringRef Name = Pair.first(); 129 LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); 130 131 OutputSection *Sec = make<CustomSection>(Name, Pair.second); 132 if (Config->Relocatable || Config->EmitRelocs) { 133 auto *Sym = make<OutputSectionSymbol>(Sec); 134 Out.LinkingSec->addToSymtab(Sym); 135 Sec->SectionSym = Sym; 136 } 137 addSection(Sec); 138 } 139 } 140 141 // Create relocations sections in the final output. 142 // These are only created when relocatable output is requested. 143 void Writer::createRelocSections() { 144 log("createRelocSections"); 145 // Don't use iterator here since we are adding to OutputSection 146 size_t OrigSize = OutputSections.size(); 147 for (size_t I = 0; I < OrigSize; I++) { 148 LLVM_DEBUG(dbgs() << "check section " << I << "\n"); 149 OutputSection *Sec = OutputSections[I]; 150 151 // Count the number of needed sections. 152 uint32_t Count = Sec->numRelocations(); 153 if (!Count) 154 continue; 155 156 StringRef Name; 157 if (Sec->Type == WASM_SEC_DATA) 158 Name = "reloc.DATA"; 159 else if (Sec->Type == WASM_SEC_CODE) 160 Name = "reloc.CODE"; 161 else if (Sec->Type == WASM_SEC_CUSTOM) 162 Name = Saver.save("reloc." + Sec->Name); 163 else 164 llvm_unreachable( 165 "relocations only supported for code, data, or custom sections"); 166 167 addSection(make<RelocSection>(Name, Sec)); 168 } 169 } 170 171 void Writer::populateProducers() { 172 for (ObjFile *File : Symtab->ObjectFiles) { 173 const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo(); 174 Out.ProducersSec->addInfo(Info); 175 } 176 } 177 178 void Writer::writeHeader() { 179 memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); 180 } 181 182 void Writer::writeSections() { 183 uint8_t *Buf = Buffer->getBufferStart(); 184 parallelForEach(OutputSections, [Buf](OutputSection *S) { 185 assert(S->isNeeded()); 186 S->writeTo(Buf); 187 }); 188 } 189 190 // Fix the memory layout of the output binary. This assigns memory offsets 191 // to each of the input data sections as well as the explicit stack region. 192 // The default memory layout is as follows, from low to high. 193 // 194 // - initialized data (starting at Config->GlobalBase) 195 // - BSS data (not currently implemented in llvm) 196 // - explicit stack (Config->ZStackSize) 197 // - heap start / unallocated 198 // 199 // The --stack-first option means that stack is placed before any static data. 200 // This can be useful since it means that stack overflow traps immediately 201 // rather than overwriting global data, but also increases code size since all 202 // static data loads and stores requires larger offsets. 203 void Writer::layoutMemory() { 204 uint32_t MemoryPtr = 0; 205 206 auto PlaceStack = [&]() { 207 if (Config->Relocatable || Config->Shared) 208 return; 209 MemoryPtr = alignTo(MemoryPtr, StackAlignment); 210 if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment)) 211 error("stack size must be " + Twine(StackAlignment) + "-byte aligned"); 212 log("mem: stack size = " + Twine(Config->ZStackSize)); 213 log("mem: stack base = " + Twine(MemoryPtr)); 214 MemoryPtr += Config->ZStackSize; 215 auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer); 216 SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr; 217 log("mem: stack top = " + Twine(MemoryPtr)); 218 }; 219 220 if (Config->StackFirst) { 221 PlaceStack(); 222 } else { 223 MemoryPtr = Config->GlobalBase; 224 log("mem: global base = " + Twine(Config->GlobalBase)); 225 } 226 227 uint32_t DataStart = MemoryPtr; 228 229 // Arbitrarily set __dso_handle handle to point to the start of the data 230 // segments. 231 if (WasmSym::DsoHandle) 232 WasmSym::DsoHandle->setVirtualAddress(DataStart); 233 234 Out.DylinkSec->MemAlign = 0; 235 for (OutputSegment *Seg : Segments) { 236 Out.DylinkSec->MemAlign = std::max(Out.DylinkSec->MemAlign, Seg->Alignment); 237 MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment); 238 Seg->StartVA = MemoryPtr; 239 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, 240 MemoryPtr, Seg->Size, Seg->Alignment)); 241 MemoryPtr += Seg->Size; 242 } 243 244 // TODO: Add .bss space here. 245 if (WasmSym::DataEnd) 246 WasmSym::DataEnd->setVirtualAddress(MemoryPtr); 247 248 log("mem: static data = " + Twine(MemoryPtr - DataStart)); 249 250 if (Config->Shared) { 251 Out.DylinkSec->MemSize = MemoryPtr; 252 return; 253 } 254 255 if (!Config->StackFirst) 256 PlaceStack(); 257 258 // Set `__heap_base` to directly follow the end of the stack or global data. 259 // The fact that this comes last means that a malloc/brk implementation 260 // can grow the heap at runtime. 261 if (!Config->Relocatable) { 262 WasmSym::HeapBase->setVirtualAddress(MemoryPtr); 263 log("mem: heap base = " + Twine(MemoryPtr)); 264 } 265 266 if (Config->InitialMemory != 0) { 267 if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) 268 error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); 269 if (MemoryPtr > Config->InitialMemory) 270 error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); 271 else 272 MemoryPtr = Config->InitialMemory; 273 } 274 Out.DylinkSec->MemSize = MemoryPtr; 275 Out.MemorySec->NumMemoryPages = 276 alignTo(MemoryPtr, WasmPageSize) / WasmPageSize; 277 log("mem: total pages = " + Twine(Out.MemorySec->NumMemoryPages)); 278 279 // Check max if explicitly supplied or required by shared memory 280 if (Config->MaxMemory != 0 || Config->SharedMemory) { 281 if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) 282 error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); 283 if (MemoryPtr > Config->MaxMemory) 284 error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); 285 Out.MemorySec->MaxMemoryPages = Config->MaxMemory / WasmPageSize; 286 log("mem: max pages = " + Twine(Out.MemorySec->MaxMemoryPages)); 287 } 288 } 289 290 void Writer::addSection(OutputSection *Sec) { 291 if (!Sec->isNeeded()) 292 return; 293 log("addSection: " + toString(*Sec)); 294 Sec->SectionIndex = OutputSections.size(); 295 OutputSections.push_back(Sec); 296 } 297 298 // If a section name is valid as a C identifier (which is rare because of 299 // the leading '.'), linkers are expected to define __start_<secname> and 300 // __stop_<secname> symbols. They are at beginning and end of the section, 301 // respectively. This is not requested by the ELF standard, but GNU ld and 302 // gold provide the feature, and used by many programs. 303 void Writer::addStartStopSymbols(const InputSegment *Seg) { 304 StringRef S = Seg->getName(); 305 LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n"); 306 if (!isValidCIdentifier(S)) 307 return; 308 uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset; 309 uint32_t Stop = Start + Seg->getSize(); 310 Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start, 0); 311 Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop, 0); 312 } 313 314 void Writer::addSections() { 315 addSection(Out.DylinkSec); 316 addSection(Out.TypeSec); 317 addSection(Out.ImportSec); 318 addSection(Out.FunctionSec); 319 addSection(Out.TableSec); 320 addSection(Out.MemorySec); 321 addSection(Out.GlobalSec); 322 addSection(Out.EventSec); 323 addSection(Out.ExportSec); 324 addSection(Out.ElemSec); 325 addSection(Out.DataCountSec); 326 327 addSection(make<CodeSection>(Out.FunctionSec->InputFunctions)); 328 addSection(make<DataSection>(Segments)); 329 330 createCustomSections(); 331 332 addSection(Out.LinkingSec); 333 if (Config->EmitRelocs || Config->Relocatable) { 334 createRelocSections(); 335 } 336 337 addSection(Out.NameSec); 338 addSection(Out.ProducersSec); 339 addSection(Out.TargetFeaturesSec); 340 } 341 342 void Writer::finalizeSections() { 343 for (OutputSection *S : OutputSections) { 344 S->setOffset(FileSize); 345 S->finalizeContents(); 346 FileSize += S->getSize(); 347 } 348 } 349 350 void Writer::populateTargetFeatures() { 351 SmallSet<std::string, 8> Used; 352 SmallSet<std::string, 8> Required; 353 SmallSet<std::string, 8> Disallowed; 354 355 // Only infer used features if user did not specify features 356 bool InferFeatures = !Config->Features.hasValue(); 357 358 if (!InferFeatures) { 359 for (auto &Feature : Config->Features.getValue()) 360 Out.TargetFeaturesSec->Features.insert(Feature); 361 // No need to read or check features 362 if (!Config->CheckFeatures) 363 return; 364 } 365 366 // Find the sets of used, required, and disallowed features 367 for (ObjFile *File : Symtab->ObjectFiles) { 368 for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { 369 switch (Feature.Prefix) { 370 case WASM_FEATURE_PREFIX_USED: 371 Used.insert(Feature.Name); 372 break; 373 case WASM_FEATURE_PREFIX_REQUIRED: 374 Used.insert(Feature.Name); 375 Required.insert(Feature.Name); 376 break; 377 case WASM_FEATURE_PREFIX_DISALLOWED: 378 Disallowed.insert(Feature.Name); 379 break; 380 default: 381 error("Unrecognized feature policy prefix " + 382 std::to_string(Feature.Prefix)); 383 } 384 } 385 } 386 387 if (InferFeatures) 388 Out.TargetFeaturesSec->Features.insert(Used.begin(), Used.end()); 389 390 if (Out.TargetFeaturesSec->Features.count("atomics") && !Config->SharedMemory) 391 error("'atomics' feature is used, so --shared-memory must be used"); 392 393 if (!Config->CheckFeatures) 394 return; 395 396 if (Disallowed.count("atomics") && Config->SharedMemory) 397 error( 398 "'atomics' feature is disallowed, so --shared-memory must not be used"); 399 400 // Validate that used features are allowed in output 401 if (!InferFeatures) { 402 for (auto &Feature : Used) { 403 if (!Out.TargetFeaturesSec->Features.count(Feature)) 404 error(Twine("Target feature '") + Feature + "' is not allowed."); 405 } 406 } 407 408 // Validate the required and disallowed constraints for each file 409 for (ObjFile *File : Symtab->ObjectFiles) { 410 SmallSet<std::string, 8> ObjectFeatures; 411 for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { 412 if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED) 413 continue; 414 ObjectFeatures.insert(Feature.Name); 415 if (Disallowed.count(Feature.Name)) 416 error(Twine("Target feature '") + Feature.Name + 417 "' is disallowed. Use --no-check-features to suppress."); 418 } 419 for (auto &Feature : Required) { 420 if (!ObjectFeatures.count(Feature)) 421 error(Twine("Missing required target feature '") + Feature + 422 "'. Use --no-check-features to suppress."); 423 } 424 } 425 } 426 427 void Writer::calculateImports() { 428 for (Symbol *Sym : Symtab->getSymbols()) { 429 if (!Sym->isUndefined()) 430 continue; 431 if (Sym->isWeak() && !Config->Relocatable) 432 continue; 433 if (!Sym->isLive()) 434 continue; 435 if (!Sym->IsUsedInRegularObj) 436 continue; 437 // We don't generate imports for data symbols. They however can be imported 438 // as GOT entries. 439 if (isa<DataSymbol>(Sym)) 440 continue; 441 442 LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); 443 Out.ImportSec->addImport(Sym); 444 } 445 } 446 447 void Writer::calculateExports() { 448 if (Config->Relocatable) 449 return; 450 451 if (!Config->Relocatable && !Config->ImportMemory) 452 Out.ExportSec->Exports.push_back( 453 WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); 454 455 if (!Config->Relocatable && Config->ExportTable) 456 Out.ExportSec->Exports.push_back( 457 WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0}); 458 459 unsigned FakeGlobalIndex = 460 Out.ImportSec->numImportedGlobals() + Out.GlobalSec->InputGlobals.size(); 461 462 for (Symbol *Sym : Symtab->getSymbols()) { 463 if (!Sym->isExported()) 464 continue; 465 if (!Sym->isLive()) 466 continue; 467 468 StringRef Name = Sym->getName(); 469 WasmExport Export; 470 if (auto *F = dyn_cast<DefinedFunction>(Sym)) { 471 Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()}; 472 } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) { 473 // TODO(sbc): Remove this check once to mutable global proposal is 474 // implement in all major browsers. 475 // See: https://github.com/WebAssembly/mutable-global 476 if (G->getGlobalType()->Mutable) { 477 // Only the __stack_pointer should ever be create as mutable. 478 assert(G == WasmSym::StackPointer); 479 continue; 480 } 481 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()}; 482 } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) { 483 Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()}; 484 } else { 485 auto *D = cast<DefinedData>(Sym); 486 Out.GlobalSec->DefinedFakeGlobals.emplace_back(D); 487 Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++}; 488 } 489 490 LLVM_DEBUG(dbgs() << "Export: " << Name << "\n"); 491 Out.ExportSec->Exports.push_back(Export); 492 } 493 } 494 495 void Writer::populateSymtab() { 496 if (!Config->Relocatable && !Config->EmitRelocs) 497 return; 498 499 for (Symbol *Sym : Symtab->getSymbols()) 500 if (Sym->IsUsedInRegularObj && Sym->isLive()) 501 Out.LinkingSec->addToSymtab(Sym); 502 503 for (ObjFile *File : Symtab->ObjectFiles) { 504 LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); 505 for (Symbol *Sym : File->getSymbols()) 506 if (Sym->isLocal() && !isa<SectionSymbol>(Sym) && Sym->isLive()) 507 Out.LinkingSec->addToSymtab(Sym); 508 } 509 } 510 511 void Writer::calculateTypes() { 512 // The output type section is the union of the following sets: 513 // 1. Any signature used in the TYPE relocation 514 // 2. The signatures of all imported functions 515 // 3. The signatures of all defined functions 516 // 4. The signatures of all imported events 517 // 5. The signatures of all defined events 518 519 for (ObjFile *File : Symtab->ObjectFiles) { 520 ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); 521 for (uint32_t I = 0; I < Types.size(); I++) 522 if (File->TypeIsUsed[I]) 523 File->TypeMap[I] = Out.TypeSec->registerType(Types[I]); 524 } 525 526 for (const Symbol *Sym : Out.ImportSec->ImportedSymbols) { 527 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) 528 Out.TypeSec->registerType(*F->Signature); 529 else if (auto *E = dyn_cast<EventSymbol>(Sym)) 530 Out.TypeSec->registerType(*E->Signature); 531 } 532 533 for (const InputFunction *F : Out.FunctionSec->InputFunctions) 534 Out.TypeSec->registerType(F->Signature); 535 536 for (const InputEvent *E : Out.EventSec->InputEvents) 537 Out.TypeSec->registerType(E->Signature); 538 } 539 540 static void scanRelocations() { 541 for (ObjFile *File : Symtab->ObjectFiles) { 542 LLVM_DEBUG(dbgs() << "scanRelocations: " << File->getName() << "\n"); 543 for (InputChunk *Chunk : File->Functions) 544 scanRelocations(Chunk); 545 for (InputChunk *Chunk : File->Segments) 546 scanRelocations(Chunk); 547 for (auto &P : File->CustomSections) 548 scanRelocations(P); 549 } 550 } 551 552 void Writer::assignIndexes() { 553 // Seal the import section, since other index spaces such as function and 554 // global are effected by the number of imports. 555 Out.ImportSec->seal(); 556 557 for (InputFunction *Func : Symtab->SyntheticFunctions) 558 Out.FunctionSec->addFunction(Func); 559 560 for (ObjFile *File : Symtab->ObjectFiles) { 561 LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); 562 for (InputFunction *Func : File->Functions) 563 Out.FunctionSec->addFunction(Func); 564 } 565 566 for (InputGlobal *Global : Symtab->SyntheticGlobals) 567 Out.GlobalSec->addGlobal(Global); 568 569 for (ObjFile *File : Symtab->ObjectFiles) { 570 LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); 571 for (InputGlobal *Global : File->Globals) 572 Out.GlobalSec->addGlobal(Global); 573 } 574 575 for (ObjFile *File : Symtab->ObjectFiles) { 576 LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n"); 577 for (InputEvent *Event : File->Events) 578 Out.EventSec->addEvent(Event); 579 } 580 } 581 582 static StringRef getOutputDataSegmentName(StringRef Name) { 583 // With PIC code we currently only support a single data segment since 584 // we only have a single __memory_base to use as our base address. 585 if (Config->Pic) 586 return "data"; 587 if (!Config->MergeDataSegments) 588 return Name; 589 if (Name.startswith(".text.")) 590 return ".text"; 591 if (Name.startswith(".data.")) 592 return ".data"; 593 if (Name.startswith(".bss.")) 594 return ".bss"; 595 if (Name.startswith(".rodata.")) 596 return ".rodata"; 597 return Name; 598 } 599 600 void Writer::createOutputSegments() { 601 for (ObjFile *File : Symtab->ObjectFiles) { 602 for (InputSegment *Segment : File->Segments) { 603 if (!Segment->Live) 604 continue; 605 StringRef Name = getOutputDataSegmentName(Segment->getName()); 606 OutputSegment *&S = SegmentMap[Name]; 607 if (S == nullptr) { 608 LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n"); 609 S = make<OutputSegment>(Name, Segments.size()); 610 Segments.push_back(S); 611 } 612 S->addInputSegment(Segment); 613 LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); 614 } 615 } 616 } 617 618 // For -shared (PIC) output, we create create a synthetic function which will 619 // apply any relocations to the data segments on startup. This function is 620 // called __wasm_apply_relocs and is added at the very beginning of 621 // __wasm_call_ctors before any of the constructors run. 622 void Writer::createApplyRelocationsFunction() { 623 LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n"); 624 // First write the body's contents to a string. 625 std::string BodyContent; 626 { 627 raw_string_ostream OS(BodyContent); 628 writeUleb128(OS, 0, "num locals"); 629 for (const OutputSegment *Seg : Segments) 630 for (const InputSegment *InSeg : Seg->InputSegments) 631 InSeg->generateRelocationCode(OS); 632 writeU8(OS, WASM_OPCODE_END, "END"); 633 } 634 635 // Once we know the size of the body we can create the final function body 636 std::string FunctionBody; 637 { 638 raw_string_ostream OS(FunctionBody); 639 writeUleb128(OS, BodyContent.size(), "function size"); 640 OS << BodyContent; 641 } 642 643 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody)); 644 cast<SyntheticFunction>(WasmSym::ApplyRelocs->Function)->setBody(Body); 645 } 646 647 // Create synthetic "__wasm_call_ctors" function based on ctor functions 648 // in input object. 649 void Writer::createCallCtorsFunction() { 650 if (!WasmSym::CallCtors->isLive()) 651 return; 652 653 // First write the body's contents to a string. 654 std::string BodyContent; 655 { 656 raw_string_ostream OS(BodyContent); 657 writeUleb128(OS, 0, "num locals"); 658 if (Config->Pic) { 659 writeU8(OS, WASM_OPCODE_CALL, "CALL"); 660 writeUleb128(OS, WasmSym::ApplyRelocs->getFunctionIndex(), 661 "function index"); 662 } 663 for (const WasmInitEntry &F : InitFunctions) { 664 writeU8(OS, WASM_OPCODE_CALL, "CALL"); 665 writeUleb128(OS, F.Sym->getFunctionIndex(), "function index"); 666 } 667 writeU8(OS, WASM_OPCODE_END, "END"); 668 } 669 670 // Once we know the size of the body we can create the final function body 671 std::string FunctionBody; 672 { 673 raw_string_ostream OS(FunctionBody); 674 writeUleb128(OS, BodyContent.size(), "function size"); 675 OS << BodyContent; 676 } 677 678 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody)); 679 cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body); 680 } 681 682 // Populate InitFunctions vector with init functions from all input objects. 683 // This is then used either when creating the output linking section or to 684 // synthesize the "__wasm_call_ctors" function. 685 void Writer::calculateInitFunctions() { 686 if (!Config->Relocatable && !WasmSym::CallCtors->isLive()) 687 return; 688 689 for (ObjFile *File : Symtab->ObjectFiles) { 690 const WasmLinkingData &L = File->getWasmObj()->linkingData(); 691 for (const WasmInitFunc &F : L.InitFunctions) { 692 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); 693 assert(Sym->isLive()); 694 if (*Sym->Signature != WasmSignature{{}, {}}) 695 error("invalid signature for init func: " + toString(*Sym)); 696 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); 697 } 698 } 699 700 // Sort in order of priority (lowest first) so that they are called 701 // in the correct order. 702 llvm::stable_sort(InitFunctions, 703 [](const WasmInitEntry &L, const WasmInitEntry &R) { 704 return L.Priority < R.Priority; 705 }); 706 } 707 708 void Writer::createSyntheticSections() { 709 Out.DylinkSec = make<DylinkSection>(); 710 Out.TypeSec = make<TypeSection>(); 711 Out.ImportSec = make<ImportSection>(); 712 Out.FunctionSec = make<FunctionSection>(); 713 Out.TableSec = make<TableSection>(); 714 Out.MemorySec = make<MemorySection>(); 715 Out.GlobalSec = make<GlobalSection>(); 716 Out.EventSec = make<EventSection>(); 717 Out.ExportSec = make<ExportSection>(); 718 Out.ElemSec = make<ElemSection>(TableBase); 719 Out.DataCountSec = make<DataCountSection>(Segments.size()); 720 Out.LinkingSec = make<LinkingSection>(InitFunctions, Segments); 721 Out.NameSec = make<NameSection>(); 722 Out.ProducersSec = make<ProducersSection>(); 723 Out.TargetFeaturesSec = make<TargetFeaturesSection>(); 724 } 725 726 void Writer::run() { 727 if (Config->Relocatable || Config->Pic) 728 Config->GlobalBase = 0; 729 730 // For PIC code the table base is assigned dynamically by the loader. 731 // For non-PIC, we start at 1 so that accessing table index 0 always traps. 732 if (!Config->Pic) 733 TableBase = 1; 734 735 log("-- createOutputSegments"); 736 createOutputSegments(); 737 log("-- createSyntheticSections"); 738 createSyntheticSections(); 739 log("-- populateProducers"); 740 populateProducers(); 741 log("-- populateTargetFeatures"); 742 populateTargetFeatures(); 743 log("-- calculateImports"); 744 calculateImports(); 745 log("-- layoutMemory"); 746 layoutMemory(); 747 748 if (!Config->Relocatable) { 749 // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols 750 // This has to be done after memory layout is performed. 751 for (const OutputSegment *Seg : Segments) 752 for (const InputSegment *S : Seg->InputSegments) 753 addStartStopSymbols(S); 754 } 755 756 log("-- scanRelocations"); 757 scanRelocations(); 758 log("-- assignIndexes"); 759 assignIndexes(); 760 log("-- calculateInitFunctions"); 761 calculateInitFunctions(); 762 763 if (!Config->Relocatable) { 764 // Create linker synthesized functions 765 if (Config->Pic) 766 createApplyRelocationsFunction(); 767 createCallCtorsFunction(); 768 769 // Make sure we have resolved all symbols. 770 if (!Config->AllowUndefined) 771 Symtab->reportRemainingUndefines(); 772 773 if (errorCount()) 774 return; 775 } 776 777 log("-- calculateTypes"); 778 calculateTypes(); 779 log("-- calculateExports"); 780 calculateExports(); 781 log("-- calculateCustomSections"); 782 calculateCustomSections(); 783 log("-- populateSymtab"); 784 populateSymtab(); 785 log("-- addSections"); 786 addSections(); 787 788 if (errorHandler().Verbose) { 789 log("Defined Functions: " + Twine(Out.FunctionSec->InputFunctions.size())); 790 log("Defined Globals : " + Twine(Out.GlobalSec->InputGlobals.size())); 791 log("Defined Events : " + Twine(Out.EventSec->InputEvents.size())); 792 log("Function Imports : " + Twine(Out.ImportSec->numImportedFunctions())); 793 log("Global Imports : " + Twine(Out.ImportSec->numImportedGlobals())); 794 log("Event Imports : " + Twine(Out.ImportSec->numImportedEvents())); 795 for (ObjFile *File : Symtab->ObjectFiles) 796 File->dumpInfo(); 797 } 798 799 createHeader(); 800 log("-- finalizeSections"); 801 finalizeSections(); 802 803 log("-- openFile"); 804 openFile(); 805 if (errorCount()) 806 return; 807 808 writeHeader(); 809 810 log("-- writeSections"); 811 writeSections(); 812 if (errorCount()) 813 return; 814 815 if (Error E = Buffer->commit()) 816 fatal("failed to write the output file: " + toString(std::move(E))); 817 } 818 819 // Open a result file. 820 void Writer::openFile() { 821 log("writing: " + Config->OutputFile); 822 823 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 824 FileOutputBuffer::create(Config->OutputFile, FileSize, 825 FileOutputBuffer::F_executable); 826 827 if (!BufferOrErr) 828 error("failed to open " + Config->OutputFile + ": " + 829 toString(BufferOrErr.takeError())); 830 else 831 Buffer = std::move(*BufferOrErr); 832 } 833 834 void Writer::createHeader() { 835 raw_string_ostream OS(Header); 836 writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); 837 writeU32(OS, WasmVersion, "wasm version"); 838 OS.flush(); 839 FileSize += Header.size(); 840 } 841 842 void lld::wasm::writeResult() { Writer().run(); } 843