1 //=== DWARFLinkerImpl.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 "DWARFLinkerImpl.h" 10 #include "DIEGenerator.h" 11 #include "DependencyTracker.h" 12 #include "llvm/DWARFLinker/Utils.h" 13 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 14 #include "llvm/Support/FormatVariadic.h" 15 #include "llvm/Support/Parallel.h" 16 #include "llvm/Support/ThreadPool.h" 17 18 using namespace llvm; 19 using namespace dwarf_linker; 20 using namespace dwarf_linker::parallel; 21 22 DWARFLinkerImpl::DWARFLinkerImpl(MessageHandlerTy ErrorHandler, 23 MessageHandlerTy WarningHandler, 24 TranslatorFuncTy StringsTranslator) 25 : UniqueUnitID(0), DebugStrStrings(GlobalData), 26 DebugLineStrStrings(GlobalData), CommonSections(GlobalData) { 27 GlobalData.setTranslator(StringsTranslator); 28 GlobalData.setErrorHandler(ErrorHandler); 29 GlobalData.setWarningHandler(WarningHandler); 30 } 31 32 DWARFLinkerImpl::LinkContext::LinkContext(LinkingGlobalData &GlobalData, 33 DWARFFile &File, 34 StringMap<uint64_t> &ClangModules, 35 std::atomic<size_t> &UniqueUnitID) 36 : OutputSections(GlobalData), InputDWARFFile(File), 37 ClangModules(ClangModules), UniqueUnitID(UniqueUnitID) { 38 39 if (File.Dwarf) { 40 if (!File.Dwarf->compile_units().empty()) 41 CompileUnits.reserve(File.Dwarf->getNumCompileUnits()); 42 43 // Set context format&endianness based on the input file. 44 Format.Version = File.Dwarf->getMaxVersion(); 45 Format.AddrSize = File.Dwarf->getCUAddrSize(); 46 Endianness = File.Dwarf->isLittleEndian() ? llvm::endianness::little 47 : llvm::endianness::big; 48 } 49 } 50 51 DWARFLinkerImpl::LinkContext::RefModuleUnit::RefModuleUnit( 52 DWARFFile &File, std::unique_ptr<CompileUnit> Unit) 53 : File(File), Unit(std::move(Unit)) {} 54 55 DWARFLinkerImpl::LinkContext::RefModuleUnit::RefModuleUnit( 56 LinkContext::RefModuleUnit &&Other) 57 : File(Other.File), Unit(std::move(Other.Unit)) {} 58 59 void DWARFLinkerImpl::LinkContext::addModulesCompileUnit( 60 LinkContext::RefModuleUnit &&Unit) { 61 ModulesCompileUnits.emplace_back(std::move(Unit)); 62 } 63 64 void DWARFLinkerImpl::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader, 65 CompileUnitHandlerTy OnCUDieLoaded) { 66 ObjectContexts.emplace_back(std::make_unique<LinkContext>( 67 GlobalData, File, ClangModules, UniqueUnitID)); 68 69 if (ObjectContexts.back()->InputDWARFFile.Dwarf) { 70 for (const std::unique_ptr<DWARFUnit> &CU : 71 ObjectContexts.back()->InputDWARFFile.Dwarf->compile_units()) { 72 DWARFDie CUDie = CU->getUnitDIE(); 73 OverallNumberOfCU++; 74 75 if (!CUDie) 76 continue; 77 78 OnCUDieLoaded(*CU); 79 80 // Register mofule reference. 81 if (!GlobalData.getOptions().UpdateIndexTablesOnly) 82 ObjectContexts.back()->registerModuleReference(CUDie, Loader, 83 OnCUDieLoaded); 84 } 85 } 86 } 87 88 void DWARFLinkerImpl::setEstimatedObjfilesAmount(unsigned ObjFilesNum) { 89 ObjectContexts.reserve(ObjFilesNum); 90 } 91 92 Error DWARFLinkerImpl::link() { 93 // reset compile unit unique ID counter. 94 UniqueUnitID = 0; 95 96 if (Error Err = validateAndUpdateOptions()) 97 return Err; 98 99 dwarf::FormParams GlobalFormat = {GlobalData.getOptions().TargetDWARFVersion, 100 0, dwarf::DwarfFormat::DWARF32}; 101 llvm::endianness GlobalEndianness = llvm::endianness::native; 102 103 if (std::optional<std::reference_wrapper<const Triple>> CurTriple = 104 GlobalData.getTargetTriple()) { 105 GlobalEndianness = (*CurTriple).get().isLittleEndian() 106 ? llvm::endianness::little 107 : llvm::endianness::big; 108 } 109 std::optional<uint16_t> Language; 110 111 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) { 112 if (Context->InputDWARFFile.Dwarf.get() == nullptr) { 113 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness); 114 continue; 115 } 116 117 if (GlobalData.getOptions().Verbose) { 118 outs() << "DEBUG MAP OBJECT: " << Context->InputDWARFFile.FileName 119 << "\n"; 120 121 for (const std::unique_ptr<DWARFUnit> &OrigCU : 122 Context->InputDWARFFile.Dwarf->compile_units()) { 123 outs() << "Input compilation unit:"; 124 DIDumpOptions DumpOpts; 125 DumpOpts.ChildRecurseDepth = 0; 126 DumpOpts.Verbose = GlobalData.getOptions().Verbose; 127 OrigCU->getUnitDIE().dump(outs(), 0, DumpOpts); 128 } 129 } 130 131 // Verify input DWARF if requested. 132 if (GlobalData.getOptions().VerifyInputDWARF) 133 verifyInput(Context->InputDWARFFile); 134 135 if (!GlobalData.getTargetTriple()) 136 GlobalEndianness = Context->getEndianness(); 137 GlobalFormat.AddrSize = 138 std::max(GlobalFormat.AddrSize, Context->getFormParams().AddrSize); 139 140 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness); 141 142 // FIXME: move creation of CompileUnits into the addObjectFile. 143 // This would allow to not scan for context Language and Modules state 144 // twice. And then following handling might be removed. 145 for (const std::unique_ptr<DWARFUnit> &OrigCU : 146 Context->InputDWARFFile.Dwarf->compile_units()) { 147 DWARFDie UnitDie = OrigCU.get()->getUnitDIE(); 148 149 if (!Language) { 150 if (std::optional<DWARFFormValue> Val = 151 UnitDie.find(dwarf::DW_AT_language)) { 152 uint16_t LangVal = dwarf::toUnsigned(Val, 0); 153 if (isODRLanguage(LangVal)) 154 Language = LangVal; 155 } 156 } 157 } 158 } 159 160 if (GlobalFormat.AddrSize == 0) { 161 if (std::optional<std::reference_wrapper<const Triple>> TargetTriple = 162 GlobalData.getTargetTriple()) 163 GlobalFormat.AddrSize = (*TargetTriple).get().isArch32Bit() ? 4 : 8; 164 else 165 GlobalFormat.AddrSize = 8; 166 } 167 168 CommonSections.setOutputFormat(GlobalFormat, GlobalEndianness); 169 170 if (!GlobalData.Options.NoODR && Language.has_value()) { 171 llvm::parallel::TaskGroup TGroup; 172 TGroup.spawn([&]() { 173 ArtificialTypeUnit = std::make_unique<TypeUnit>( 174 GlobalData, UniqueUnitID++, Language, GlobalFormat, GlobalEndianness); 175 }); 176 } 177 178 // Set parallel options. 179 if (GlobalData.getOptions().Threads == 0) 180 llvm::parallel::strategy = optimal_concurrency(OverallNumberOfCU); 181 else 182 llvm::parallel::strategy = 183 hardware_concurrency(GlobalData.getOptions().Threads); 184 185 // Link object files. 186 if (GlobalData.getOptions().Threads == 1) { 187 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) { 188 // Link object file. 189 if (Error Err = Context->link(ArtificialTypeUnit.get())) 190 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName); 191 192 Context->InputDWARFFile.unload(); 193 } 194 } else { 195 ThreadPool Pool(llvm::parallel::strategy); 196 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) 197 Pool.async([&]() { 198 // Link object file. 199 if (Error Err = Context->link(ArtificialTypeUnit.get())) 200 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName); 201 202 Context->InputDWARFFile.unload(); 203 }); 204 205 Pool.wait(); 206 } 207 208 if (ArtificialTypeUnit.get() != nullptr && !ArtificialTypeUnit->getTypePool() 209 .getRoot() 210 ->getValue() 211 .load() 212 ->Children.empty()) { 213 if (GlobalData.getTargetTriple().has_value()) 214 if (Error Err = ArtificialTypeUnit.get()->finishCloningAndEmit( 215 (*GlobalData.getTargetTriple()).get())) 216 return Err; 217 } 218 219 // At this stage each compile units are cloned to their own set of debug 220 // sections. Now, update patches, assign offsets and assemble final file 221 // glueing debug tables from each compile unit. 222 glueCompileUnitsAndWriteToTheOutput(); 223 224 return Error::success(); 225 } 226 227 void DWARFLinkerImpl::verifyInput(const DWARFFile &File) { 228 assert(File.Dwarf); 229 230 std::string Buffer; 231 raw_string_ostream OS(Buffer); 232 DIDumpOptions DumpOpts; 233 if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) { 234 if (GlobalData.getOptions().InputVerificationHandler) 235 GlobalData.getOptions().InputVerificationHandler(File, OS.str()); 236 } 237 } 238 239 Error DWARFLinkerImpl::validateAndUpdateOptions() { 240 if (GlobalData.getOptions().TargetDWARFVersion == 0) 241 return createStringError(std::errc::invalid_argument, 242 "target DWARF version is not set"); 243 244 if (GlobalData.getOptions().Verbose && GlobalData.getOptions().Threads != 1) { 245 GlobalData.Options.Threads = 1; 246 GlobalData.warn( 247 "set number of threads to 1 to make --verbose to work properly.", ""); 248 } 249 250 // Do not do types deduplication in case --update. 251 if (GlobalData.getOptions().UpdateIndexTablesOnly && 252 !GlobalData.Options.NoODR) 253 GlobalData.Options.NoODR = true; 254 255 return Error::success(); 256 } 257 258 /// Resolve the relative path to a build artifact referenced by DWARF by 259 /// applying DW_AT_comp_dir. 260 static void resolveRelativeObjectPath(SmallVectorImpl<char> &Buf, DWARFDie CU) { 261 sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), "")); 262 } 263 264 static uint64_t getDwoId(const DWARFDie &CUDie) { 265 auto DwoId = dwarf::toUnsigned( 266 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id})); 267 if (DwoId) 268 return *DwoId; 269 return 0; 270 } 271 272 static std::string 273 remapPath(StringRef Path, 274 const DWARFLinker::ObjectPrefixMapTy &ObjectPrefixMap) { 275 if (ObjectPrefixMap.empty()) 276 return Path.str(); 277 278 SmallString<256> p = Path; 279 for (const auto &Entry : ObjectPrefixMap) 280 if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second)) 281 break; 282 return p.str().str(); 283 } 284 285 static std::string getPCMFile(const DWARFDie &CUDie, 286 DWARFLinker::ObjectPrefixMapTy *ObjectPrefixMap) { 287 std::string PCMFile = dwarf::toString( 288 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), ""); 289 290 if (PCMFile.empty()) 291 return PCMFile; 292 293 if (ObjectPrefixMap) 294 PCMFile = remapPath(PCMFile, *ObjectPrefixMap); 295 296 return PCMFile; 297 } 298 299 std::pair<bool, bool> DWARFLinkerImpl::LinkContext::isClangModuleRef( 300 const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet) { 301 if (PCMFile.empty()) 302 return std::make_pair(false, false); 303 304 // Clang module DWARF skeleton CUs abuse this for the path to the module. 305 uint64_t DwoId = getDwoId(CUDie); 306 307 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), ""); 308 if (Name.empty()) { 309 if (!Quiet) 310 GlobalData.warn("anonymous module skeleton CU for " + PCMFile + ".", 311 InputDWARFFile.FileName); 312 return std::make_pair(true, true); 313 } 314 315 if (!Quiet && GlobalData.getOptions().Verbose) { 316 outs().indent(Indent); 317 outs() << "Found clang module reference " << PCMFile; 318 } 319 320 auto Cached = ClangModules.find(PCMFile); 321 if (Cached != ClangModules.end()) { 322 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is 323 // fixed in clang, only warn about DWO_id mismatches in verbose mode. 324 // ASTFileSignatures will change randomly when a module is rebuilt. 325 if (!Quiet && GlobalData.getOptions().Verbose && (Cached->second != DwoId)) 326 GlobalData.warn( 327 Twine("hash mismatch: this object file was built against a " 328 "different version of the module ") + 329 PCMFile + ".", 330 InputDWARFFile.FileName); 331 if (!Quiet && GlobalData.getOptions().Verbose) 332 outs() << " [cached].\n"; 333 return std::make_pair(true, true); 334 } 335 336 return std::make_pair(true, false); 337 } 338 339 /// If this compile unit is really a skeleton CU that points to a 340 /// clang module, register it in ClangModules and return true. 341 /// 342 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name 343 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module 344 /// hash. 345 bool DWARFLinkerImpl::LinkContext::registerModuleReference( 346 const DWARFDie &CUDie, ObjFileLoaderTy Loader, 347 CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) { 348 std::string PCMFile = 349 getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap); 350 std::pair<bool, bool> IsClangModuleRef = 351 isClangModuleRef(CUDie, PCMFile, Indent, false); 352 353 if (!IsClangModuleRef.first) 354 return false; 355 356 if (IsClangModuleRef.second) 357 return true; 358 359 if (GlobalData.getOptions().Verbose) 360 outs() << " ...\n"; 361 362 // Cyclic dependencies are disallowed by Clang, but we still 363 // shouldn't run into an infinite loop, so mark it as processed now. 364 ClangModules.insert({PCMFile, getDwoId(CUDie)}); 365 366 if (Error E = 367 loadClangModule(Loader, CUDie, PCMFile, OnCUDieLoaded, Indent + 2)) { 368 consumeError(std::move(E)); 369 return false; 370 } 371 return true; 372 } 373 374 Error DWARFLinkerImpl::LinkContext::loadClangModule( 375 ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile, 376 CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) { 377 378 uint64_t DwoId = getDwoId(CUDie); 379 std::string ModuleName = dwarf::toString(CUDie.find(dwarf::DW_AT_name), ""); 380 381 /// Using a SmallString<0> because loadClangModule() is recursive. 382 SmallString<0> Path(GlobalData.getOptions().PrependPath); 383 if (sys::path::is_relative(PCMFile)) 384 resolveRelativeObjectPath(Path, CUDie); 385 sys::path::append(Path, PCMFile); 386 // Don't use the cached binary holder because we have no thread-safety 387 // guarantee and the lifetime is limited. 388 389 if (Loader == nullptr) { 390 GlobalData.error("cann't load clang module: loader is not specified.", 391 InputDWARFFile.FileName); 392 return Error::success(); 393 } 394 395 auto ErrOrObj = Loader(InputDWARFFile.FileName, Path); 396 if (!ErrOrObj) 397 return Error::success(); 398 399 std::unique_ptr<CompileUnit> Unit; 400 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) { 401 OnCUDieLoaded(*CU); 402 // Recursively get all modules imported by this one. 403 auto ChildCUDie = CU->getUnitDIE(); 404 if (!ChildCUDie) 405 continue; 406 if (!registerModuleReference(ChildCUDie, Loader, OnCUDieLoaded, Indent)) { 407 if (Unit) { 408 std::string Err = 409 (PCMFile + 410 ": Clang modules are expected to have exactly 1 compile unit.\n"); 411 GlobalData.error(Err, InputDWARFFile.FileName); 412 return make_error<StringError>(Err, inconvertibleErrorCode()); 413 } 414 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is 415 // fixed in clang, only warn about DWO_id mismatches in verbose mode. 416 // ASTFileSignatures will change randomly when a module is rebuilt. 417 uint64_t PCMDwoId = getDwoId(ChildCUDie); 418 if (PCMDwoId != DwoId) { 419 if (GlobalData.getOptions().Verbose) 420 GlobalData.warn( 421 Twine("hash mismatch: this object file was built against a " 422 "different version of the module ") + 423 PCMFile + ".", 424 InputDWARFFile.FileName); 425 // Update the cache entry with the DwoId of the module loaded from disk. 426 ClangModules[PCMFile] = PCMDwoId; 427 } 428 429 // Empty modules units should not be cloned. 430 if (!ChildCUDie.hasChildren()) 431 continue; 432 433 // Add this module. 434 Unit = std::make_unique<CompileUnit>( 435 GlobalData, *CU, UniqueUnitID.fetch_add(1), ModuleName, *ErrOrObj, 436 getUnitForOffset, CU->getFormParams(), getEndianness()); 437 } 438 } 439 440 if (Unit) { 441 ModulesCompileUnits.emplace_back(RefModuleUnit{*ErrOrObj, std::move(Unit)}); 442 // Preload line table, as it can't be loaded asynchronously. 443 ModulesCompileUnits.back().Unit->loadLineTable(); 444 } 445 446 return Error::success(); 447 } 448 449 Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) { 450 InterCUProcessingStarted = false; 451 if (!InputDWARFFile.Dwarf) 452 return Error::success(); 453 454 // Preload macro tables, as they can't be loaded asynchronously. 455 InputDWARFFile.Dwarf->getDebugMacinfo(); 456 InputDWARFFile.Dwarf->getDebugMacro(); 457 458 // Link modules compile units first. 459 parallelForEach(ModulesCompileUnits, [&](RefModuleUnit &RefModule) { 460 linkSingleCompileUnit(*RefModule.Unit, ArtificialTypeUnit); 461 }); 462 463 // Check for live relocations. If there is no any live relocation then we 464 // can skip entire object file. 465 if (!GlobalData.getOptions().UpdateIndexTablesOnly && 466 !InputDWARFFile.Addresses->hasValidRelocs()) { 467 if (GlobalData.getOptions().Verbose) 468 outs() << "No valid relocations found. Skipping.\n"; 469 return Error::success(); 470 } 471 472 OriginalDebugInfoSize = getInputDebugInfoSize(); 473 474 // Create CompileUnit structures to keep information about source 475 // DWARFUnit`s, load line tables. 476 for (const auto &OrigCU : InputDWARFFile.Dwarf->compile_units()) { 477 // Load only unit DIE at this stage. 478 auto CUDie = OrigCU->getUnitDIE(); 479 std::string PCMFile = 480 getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap); 481 482 // The !isClangModuleRef condition effectively skips over fully resolved 483 // skeleton units. 484 if (!CUDie || GlobalData.getOptions().UpdateIndexTablesOnly || 485 !isClangModuleRef(CUDie, PCMFile, 0, true).first) { 486 CompileUnits.emplace_back(std::make_unique<CompileUnit>( 487 GlobalData, *OrigCU, UniqueUnitID.fetch_add(1), "", InputDWARFFile, 488 getUnitForOffset, OrigCU->getFormParams(), getEndianness())); 489 490 // Preload line table, as it can't be loaded asynchronously. 491 CompileUnits.back()->loadLineTable(); 492 } 493 }; 494 495 HasNewInterconnectedCUs = false; 496 497 // Link self-sufficient compile units and discover inter-connected compile 498 // units. 499 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 500 linkSingleCompileUnit(*CU, ArtificialTypeUnit); 501 }); 502 503 // Link all inter-connected units. 504 if (HasNewInterconnectedCUs) { 505 InterCUProcessingStarted = true; 506 507 if (Error Err = finiteLoop([&]() -> Expected<bool> { 508 HasNewInterconnectedCUs = false; 509 510 // Load inter-connected units. 511 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 512 if (CU->isInterconnectedCU()) { 513 CU->maybeResetToLoadedStage(); 514 linkSingleCompileUnit(*CU, ArtificialTypeUnit, 515 CompileUnit::Stage::Loaded); 516 } 517 }); 518 519 // Do liveness analysis for inter-connected units. 520 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 521 linkSingleCompileUnit(*CU, ArtificialTypeUnit, 522 CompileUnit::Stage::LivenessAnalysisDone); 523 }); 524 525 return HasNewInterconnectedCUs.load(); 526 })) 527 return Err; 528 529 // Update dependencies. 530 if (Error Err = finiteLoop([&]() -> Expected<bool> { 531 HasNewGlobalDependency = false; 532 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 533 linkSingleCompileUnit( 534 *CU, ArtificialTypeUnit, 535 CompileUnit::Stage::UpdateDependenciesCompleteness); 536 }); 537 return HasNewGlobalDependency.load(); 538 })) 539 return Err; 540 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 541 if (CU->isInterconnectedCU() && 542 CU->getStage() == CompileUnit::Stage::LivenessAnalysisDone) 543 CU->setStage(CompileUnit::Stage::UpdateDependenciesCompleteness); 544 }); 545 546 // Assign type names. 547 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 548 linkSingleCompileUnit(*CU, ArtificialTypeUnit, 549 CompileUnit::Stage::TypeNamesAssigned); 550 }); 551 552 // Clone inter-connected units. 553 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 554 linkSingleCompileUnit(*CU, ArtificialTypeUnit, 555 CompileUnit::Stage::Cloned); 556 }); 557 558 // Update patches for inter-connected units. 559 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 560 linkSingleCompileUnit(*CU, ArtificialTypeUnit, 561 CompileUnit::Stage::PatchesUpdated); 562 }); 563 564 // Release data. 565 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) { 566 linkSingleCompileUnit(*CU, ArtificialTypeUnit, 567 CompileUnit::Stage::Cleaned); 568 }); 569 } 570 571 if (GlobalData.getOptions().UpdateIndexTablesOnly) { 572 // Emit Invariant sections. 573 574 if (Error Err = emitInvariantSections()) 575 return Err; 576 } else if (!CompileUnits.empty()) { 577 // Emit .debug_frame section. 578 579 Error ResultErr = Error::success(); 580 llvm::parallel::TaskGroup TGroup; 581 // We use task group here as PerThreadBumpPtrAllocator should be called from 582 // the threads created by ThreadPoolExecutor. 583 TGroup.spawn([&]() { 584 if (Error Err = cloneAndEmitDebugFrame()) 585 ResultErr = std::move(Err); 586 }); 587 return ResultErr; 588 } 589 590 return Error::success(); 591 } 592 593 void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit( 594 CompileUnit &CU, TypeUnit *ArtificialTypeUnit, 595 enum CompileUnit::Stage DoUntilStage) { 596 if (InterCUProcessingStarted != CU.isInterconnectedCU()) 597 return; 598 599 if (Error Err = finiteLoop([&]() -> Expected<bool> { 600 if (CU.getStage() >= DoUntilStage) 601 return false; 602 603 switch (CU.getStage()) { 604 case CompileUnit::Stage::CreatedNotLoaded: { 605 // Load input compilation unit DIEs. 606 // Analyze properties of DIEs. 607 if (!CU.loadInputDIEs()) { 608 // We do not need to do liveness analysis for invalid compilation 609 // unit. 610 CU.setStage(CompileUnit::Stage::Skipped); 611 } else { 612 CU.analyzeDWARFStructure(); 613 614 // The registerModuleReference() condition effectively skips 615 // over fully resolved skeleton units. This second pass of 616 // registerModuleReferences doesn't do any new work, but it 617 // will collect top-level errors, which are suppressed. Module 618 // warnings were already displayed in the first iteration. 619 if (registerModuleReference( 620 CU.getOrigUnit().getUnitDIE(), nullptr, 621 [](const DWARFUnit &) {}, 0)) 622 CU.setStage(CompileUnit::Stage::PatchesUpdated); 623 else 624 CU.setStage(CompileUnit::Stage::Loaded); 625 } 626 } break; 627 628 case CompileUnit::Stage::Loaded: { 629 // Mark all the DIEs that need to be present in the generated output. 630 // If ODR requested, build type names. 631 if (!CU.resolveDependenciesAndMarkLiveness(InterCUProcessingStarted, 632 HasNewInterconnectedCUs)) { 633 assert(HasNewInterconnectedCUs && 634 "Flag indicating new inter-connections is not set"); 635 return false; 636 } 637 638 CU.setStage(CompileUnit::Stage::LivenessAnalysisDone); 639 } break; 640 641 case CompileUnit::Stage::LivenessAnalysisDone: { 642 if (InterCUProcessingStarted) { 643 if (CU.updateDependenciesCompleteness()) 644 HasNewGlobalDependency = true; 645 return false; 646 } else { 647 if (Error Err = finiteLoop([&]() -> Expected<bool> { 648 return CU.updateDependenciesCompleteness(); 649 })) 650 return std::move(Err); 651 652 CU.setStage(CompileUnit::Stage::UpdateDependenciesCompleteness); 653 } 654 } break; 655 656 case CompileUnit::Stage::UpdateDependenciesCompleteness: 657 #ifndef NDEBUG 658 CU.verifyDependencies(); 659 #endif 660 661 if (ArtificialTypeUnit) { 662 if (Error Err = 663 CU.assignTypeNames(ArtificialTypeUnit->getTypePool())) 664 return std::move(Err); 665 } 666 CU.setStage(CompileUnit::Stage::TypeNamesAssigned); 667 break; 668 669 case CompileUnit::Stage::TypeNamesAssigned: 670 // Clone input compile unit. 671 if (CU.isClangModule() || 672 GlobalData.getOptions().UpdateIndexTablesOnly || 673 CU.getContaingFile().Addresses->hasValidRelocs()) { 674 if (Error Err = CU.cloneAndEmit(GlobalData.getTargetTriple(), 675 ArtificialTypeUnit)) 676 return std::move(Err); 677 } 678 679 CU.setStage(CompileUnit::Stage::Cloned); 680 break; 681 682 case CompileUnit::Stage::Cloned: 683 // Update DIEs referencies. 684 CU.updateDieRefPatchesWithClonedOffsets(); 685 CU.setStage(CompileUnit::Stage::PatchesUpdated); 686 break; 687 688 case CompileUnit::Stage::PatchesUpdated: 689 // Cleanup resources. 690 CU.cleanupDataAfterClonning(); 691 CU.setStage(CompileUnit::Stage::Cleaned); 692 break; 693 694 case CompileUnit::Stage::Cleaned: 695 assert(false); 696 break; 697 698 case CompileUnit::Stage::Skipped: 699 // Nothing to do. 700 break; 701 } 702 703 return true; 704 })) { 705 CU.error(std::move(Err)); 706 CU.cleanupDataAfterClonning(); 707 CU.setStage(CompileUnit::Stage::Skipped); 708 } 709 } 710 711 Error DWARFLinkerImpl::LinkContext::emitInvariantSections() { 712 if (!GlobalData.getTargetTriple().has_value()) 713 return Error::success(); 714 715 getOrCreateSectionDescriptor(DebugSectionKind::DebugLoc).OS 716 << InputDWARFFile.Dwarf->getDWARFObj().getLocSection().Data; 717 getOrCreateSectionDescriptor(DebugSectionKind::DebugLocLists).OS 718 << InputDWARFFile.Dwarf->getDWARFObj().getLoclistsSection().Data; 719 getOrCreateSectionDescriptor(DebugSectionKind::DebugRange).OS 720 << InputDWARFFile.Dwarf->getDWARFObj().getRangesSection().Data; 721 getOrCreateSectionDescriptor(DebugSectionKind::DebugRngLists).OS 722 << InputDWARFFile.Dwarf->getDWARFObj().getRnglistsSection().Data; 723 getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges).OS 724 << InputDWARFFile.Dwarf->getDWARFObj().getArangesSection(); 725 getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame).OS 726 << InputDWARFFile.Dwarf->getDWARFObj().getFrameSection().Data; 727 getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr).OS 728 << InputDWARFFile.Dwarf->getDWARFObj().getAddrSection().Data; 729 730 return Error::success(); 731 } 732 733 Error DWARFLinkerImpl::LinkContext::cloneAndEmitDebugFrame() { 734 if (!GlobalData.getTargetTriple().has_value()) 735 return Error::success(); 736 737 if (InputDWARFFile.Dwarf.get() == nullptr) 738 return Error::success(); 739 740 const DWARFObject &InputDWARFObj = InputDWARFFile.Dwarf->getDWARFObj(); 741 742 StringRef OrigFrameData = InputDWARFObj.getFrameSection().Data; 743 if (OrigFrameData.empty()) 744 return Error::success(); 745 746 RangesTy AllUnitsRanges; 747 for (std::unique_ptr<CompileUnit> &Unit : CompileUnits) { 748 for (auto CurRange : Unit->getFunctionRanges()) 749 AllUnitsRanges.insert(CurRange.Range, CurRange.Value); 750 } 751 752 unsigned SrcAddrSize = InputDWARFObj.getAddressSize(); 753 754 SectionDescriptor &OutSection = 755 getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame); 756 757 DataExtractor Data(OrigFrameData, InputDWARFObj.isLittleEndian(), 0); 758 uint64_t InputOffset = 0; 759 760 // Store the data of the CIEs defined in this object, keyed by their 761 // offsets. 762 DenseMap<uint64_t, StringRef> LocalCIES; 763 764 /// The CIEs that have been emitted in the output section. The actual CIE 765 /// data serves a the key to this StringMap. 766 StringMap<uint32_t> EmittedCIEs; 767 768 while (Data.isValidOffset(InputOffset)) { 769 uint64_t EntryOffset = InputOffset; 770 uint32_t InitialLength = Data.getU32(&InputOffset); 771 if (InitialLength == 0xFFFFFFFF) 772 return createFileError(InputDWARFObj.getFileName(), 773 createStringError(std::errc::invalid_argument, 774 "Dwarf64 bits no supported")); 775 776 uint32_t CIEId = Data.getU32(&InputOffset); 777 if (CIEId == 0xFFFFFFFF) { 778 // This is a CIE, store it. 779 StringRef CIEData = OrigFrameData.substr(EntryOffset, InitialLength + 4); 780 LocalCIES[EntryOffset] = CIEData; 781 // The -4 is to account for the CIEId we just read. 782 InputOffset += InitialLength - 4; 783 continue; 784 } 785 786 uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize); 787 788 // Some compilers seem to emit frame info that doesn't start at 789 // the function entry point, thus we can't just lookup the address 790 // in the debug map. Use the AddressInfo's range map to see if the FDE 791 // describes something that we can relocate. 792 std::optional<AddressRangeValuePair> Range = 793 AllUnitsRanges.getRangeThatContains(Loc); 794 if (!Range) { 795 // The +4 is to account for the size of the InitialLength field itself. 796 InputOffset = EntryOffset + InitialLength + 4; 797 continue; 798 } 799 800 // This is an FDE, and we have a mapping. 801 // Have we already emitted a corresponding CIE? 802 StringRef CIEData = LocalCIES[CIEId]; 803 if (CIEData.empty()) 804 return createFileError( 805 InputDWARFObj.getFileName(), 806 createStringError(std::errc::invalid_argument, 807 "Inconsistent debug_frame content. Dropping.")); 808 809 uint64_t OffsetToCIERecord = OutSection.OS.tell(); 810 811 // Look if we already emitted a CIE that corresponds to the 812 // referenced one (the CIE data is the key of that lookup). 813 auto IteratorInserted = 814 EmittedCIEs.insert(std::make_pair(CIEData, OffsetToCIERecord)); 815 OffsetToCIERecord = IteratorInserted.first->getValue(); 816 817 // Emit CIE for this ID if it is not emitted yet. 818 if (IteratorInserted.second) 819 OutSection.OS << CIEData; 820 821 // Remember offset to the FDE record, so that we might update 822 // field referencing CIE record(containing OffsetToCIERecord), 823 // when final offsets are known. OffsetToCIERecord(which is written later) 824 // is local to the current .debug_frame section, it should be updated 825 // with final offset of the .debug_frame section. 826 OutSection.notePatch( 827 DebugOffsetPatch{OutSection.OS.tell() + 4, &OutSection, true}); 828 829 // Emit the FDE with updated address and CIE pointer. 830 // (4 + AddrSize) is the size of the CIEId + initial_location 831 // fields that will get reconstructed by emitFDE(). 832 unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize); 833 emitFDE(OffsetToCIERecord, SrcAddrSize, Loc + Range->Value, 834 OrigFrameData.substr(InputOffset, FDERemainingBytes), OutSection); 835 InputOffset += FDERemainingBytes; 836 } 837 838 return Error::success(); 839 } 840 841 /// Emit a FDE into the debug_frame section. \p FDEBytes 842 /// contains the FDE data without the length, CIE offset and address 843 /// which will be replaced with the parameter values. 844 void DWARFLinkerImpl::LinkContext::emitFDE(uint32_t CIEOffset, 845 uint32_t AddrSize, uint64_t Address, 846 StringRef FDEBytes, 847 SectionDescriptor &Section) { 848 Section.emitIntVal(FDEBytes.size() + 4 + AddrSize, 4); 849 Section.emitIntVal(CIEOffset, 4); 850 Section.emitIntVal(Address, AddrSize); 851 Section.OS.write(FDEBytes.data(), FDEBytes.size()); 852 } 853 854 void DWARFLinkerImpl::glueCompileUnitsAndWriteToTheOutput() { 855 if (!GlobalData.getTargetTriple().has_value()) 856 return; 857 assert(SectionHandler); 858 859 // Go through all object files, all compile units and assign 860 // offsets to them. 861 assignOffsets(); 862 863 // Patch size/offsets fields according to the assigned CU offsets. 864 patchOffsetsAndSizes(); 865 866 // Emit common sections and write debug tables from all object files/compile 867 // units into the resulting file. 868 emitCommonSectionsAndWriteCompileUnitsToTheOutput(); 869 870 if (ArtificialTypeUnit.get() != nullptr) 871 ArtificialTypeUnit.reset(); 872 873 // Write common debug sections into the resulting file. 874 writeCommonSectionsToTheOutput(); 875 876 // Cleanup data. 877 cleanupDataAfterDWARFOutputIsWritten(); 878 879 if (GlobalData.getOptions().Statistics) 880 printStatistic(); 881 } 882 883 void DWARFLinkerImpl::printStatistic() { 884 885 // For each object file map how many bytes were emitted. 886 StringMap<DebugInfoSize> SizeByObject; 887 888 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) { 889 uint64_t AllDebugInfoSectionsSize = 0; 890 891 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits) 892 if (std::optional<SectionDescriptor *> DebugInfo = 893 CU->tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) 894 AllDebugInfoSectionsSize += (*DebugInfo)->getContents().size(); 895 896 SizeByObject[Context->InputDWARFFile.FileName].Input = 897 Context->OriginalDebugInfoSize; 898 SizeByObject[Context->InputDWARFFile.FileName].Output = 899 AllDebugInfoSectionsSize; 900 } 901 902 // Create a vector sorted in descending order by output size. 903 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted; 904 for (auto &E : SizeByObject) 905 Sorted.emplace_back(E.first(), E.second); 906 llvm::sort(Sorted, [](auto &LHS, auto &RHS) { 907 return LHS.second.Output > RHS.second.Output; 908 }); 909 910 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float { 911 const float Difference = Output - Input; 912 const float Sum = Input + Output; 913 if (Sum == 0) 914 return 0; 915 return (Difference / (Sum / 2)); 916 }; 917 918 int64_t InputTotal = 0; 919 int64_t OutputTotal = 0; 920 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n"; 921 922 // Print header. 923 outs() << ".debug_info section size (in bytes)\n"; 924 outs() << "----------------------------------------------------------------" 925 "---------------\n"; 926 outs() << "Filename Object " 927 " dSYM Change\n"; 928 outs() << "----------------------------------------------------------------" 929 "---------------\n"; 930 931 // Print body. 932 for (auto &E : Sorted) { 933 InputTotal += E.second.Input; 934 OutputTotal += E.second.Output; 935 llvm::outs() << formatv( 936 FormatStr, sys::path::filename(E.first).take_back(45), E.second.Input, 937 E.second.Output, ComputePercentange(E.second.Input, E.second.Output)); 938 } 939 // Print total and footer. 940 outs() << "----------------------------------------------------------------" 941 "---------------\n"; 942 llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal, 943 ComputePercentange(InputTotal, OutputTotal)); 944 outs() << "----------------------------------------------------------------" 945 "---------------\n\n"; 946 } 947 948 void DWARFLinkerImpl::assignOffsets() { 949 llvm::parallel::TaskGroup TGroup; 950 TGroup.spawn([&]() { assignOffsetsToStrings(); }); 951 TGroup.spawn([&]() { assignOffsetsToSections(); }); 952 } 953 954 void DWARFLinkerImpl::assignOffsetsToStrings() { 955 size_t CurDebugStrIndex = 1; // start from 1 to take into account zero entry. 956 uint64_t CurDebugStrOffset = 957 1; // start from 1 to take into account zero entry. 958 size_t CurDebugLineStrIndex = 0; 959 uint64_t CurDebugLineStrOffset = 0; 960 961 // Enumerates all strings, add them into the DwarfStringPoolEntry map, 962 // assign offset and index to the string if it is not indexed yet. 963 forEachOutputString([&](StringDestinationKind Kind, 964 const StringEntry *String) { 965 switch (Kind) { 966 case StringDestinationKind::DebugStr: { 967 DwarfStringPoolEntryWithExtString *Entry = DebugStrStrings.add(String); 968 assert(Entry != nullptr); 969 970 if (!Entry->isIndexed()) { 971 Entry->Offset = CurDebugStrOffset; 972 CurDebugStrOffset += Entry->String.size() + 1; 973 Entry->Index = CurDebugStrIndex++; 974 } 975 } break; 976 case StringDestinationKind::DebugLineStr: { 977 DwarfStringPoolEntryWithExtString *Entry = 978 DebugLineStrStrings.add(String); 979 assert(Entry != nullptr); 980 981 if (!Entry->isIndexed()) { 982 Entry->Offset = CurDebugLineStrOffset; 983 CurDebugLineStrOffset += Entry->String.size() + 1; 984 Entry->Index = CurDebugLineStrIndex++; 985 } 986 } break; 987 } 988 }); 989 } 990 991 void DWARFLinkerImpl::assignOffsetsToSections() { 992 std::array<uint64_t, SectionKindsNum> SectionSizesAccumulator = {0}; 993 994 forEachObjectSectionsSet([&](OutputSections &UnitSections) { 995 UnitSections.assignSectionsOffsetAndAccumulateSize(SectionSizesAccumulator); 996 }); 997 } 998 999 void DWARFLinkerImpl::forEachOutputString( 1000 function_ref<void(StringDestinationKind Kind, const StringEntry *String)> 1001 StringHandler) { 1002 // To save space we do not create any separate string table. 1003 // We use already allocated string patches and accelerator entries: 1004 // enumerate them in natural order and assign offsets. 1005 // ASSUMPTION: strings should be stored into .debug_str/.debug_line_str 1006 // sections in the same order as they were assigned offsets. 1007 forEachCompileUnit([&](CompileUnit *CU) { 1008 CU->forEach([&](SectionDescriptor &OutSection) { 1009 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) { 1010 StringHandler(StringDestinationKind::DebugStr, Patch.String); 1011 }); 1012 1013 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) { 1014 StringHandler(StringDestinationKind::DebugLineStr, Patch.String); 1015 }); 1016 }); 1017 1018 CU->forEachAcceleratorRecord([&](DwarfUnit::AccelInfo &Info) { 1019 StringHandler(DebugStr, Info.String); 1020 }); 1021 }); 1022 1023 if (ArtificialTypeUnit.get() != nullptr) { 1024 ArtificialTypeUnit->forEach([&](SectionDescriptor &OutSection) { 1025 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) { 1026 StringHandler(StringDestinationKind::DebugStr, Patch.String); 1027 }); 1028 1029 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) { 1030 StringHandler(StringDestinationKind::DebugLineStr, Patch.String); 1031 }); 1032 1033 OutSection.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) { 1034 if (Patch.Die == nullptr) 1035 return; 1036 1037 StringHandler(StringDestinationKind::DebugStr, Patch.String); 1038 }); 1039 1040 OutSection.ListDebugTypeLineStrPatch.forEach( 1041 [&](DebugTypeLineStrPatch &Patch) { 1042 if (Patch.Die == nullptr) 1043 return; 1044 1045 StringHandler(StringDestinationKind::DebugStr, Patch.String); 1046 }); 1047 }); 1048 } 1049 } 1050 1051 void DWARFLinkerImpl::forEachObjectSectionsSet( 1052 function_ref<void(OutputSections &)> SectionsSetHandler) { 1053 // Handle artificial type unit first. 1054 if (ArtificialTypeUnit.get() != nullptr) 1055 SectionsSetHandler(*ArtificialTypeUnit); 1056 1057 // Then all modules(before regular compilation units). 1058 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) 1059 for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits) 1060 if (ModuleUnit.Unit->getStage() != CompileUnit::Stage::Skipped) 1061 SectionsSetHandler(*ModuleUnit.Unit); 1062 1063 // Finally all compilation units. 1064 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) { 1065 // Handle object file common sections. 1066 SectionsSetHandler(*Context); 1067 1068 // Handle compilation units. 1069 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits) 1070 if (CU->getStage() != CompileUnit::Stage::Skipped) 1071 SectionsSetHandler(*CU); 1072 } 1073 } 1074 1075 void DWARFLinkerImpl::forEachCompileAndTypeUnit( 1076 function_ref<void(DwarfUnit *CU)> UnitHandler) { 1077 if (ArtificialTypeUnit.get() != nullptr) 1078 UnitHandler(ArtificialTypeUnit.get()); 1079 1080 // Enumerate module units. 1081 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) 1082 for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits) 1083 if (ModuleUnit.Unit->getStage() != CompileUnit::Stage::Skipped) 1084 UnitHandler(ModuleUnit.Unit.get()); 1085 1086 // Enumerate compile units. 1087 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) 1088 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits) 1089 if (CU->getStage() != CompileUnit::Stage::Skipped) 1090 UnitHandler(CU.get()); 1091 } 1092 1093 void DWARFLinkerImpl::forEachCompileUnit( 1094 function_ref<void(CompileUnit *CU)> UnitHandler) { 1095 // Enumerate module units. 1096 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) 1097 for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits) 1098 if (ModuleUnit.Unit->getStage() != CompileUnit::Stage::Skipped) 1099 UnitHandler(ModuleUnit.Unit.get()); 1100 1101 // Enumerate compile units. 1102 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) 1103 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits) 1104 if (CU->getStage() != CompileUnit::Stage::Skipped) 1105 UnitHandler(CU.get()); 1106 } 1107 1108 void DWARFLinkerImpl::patchOffsetsAndSizes() { 1109 forEachObjectSectionsSet([&](OutputSections &SectionsSet) { 1110 SectionsSet.forEach([&](SectionDescriptor &OutSection) { 1111 SectionsSet.applyPatches(OutSection, DebugStrStrings, DebugLineStrStrings, 1112 ArtificialTypeUnit.get()); 1113 }); 1114 }); 1115 } 1116 1117 void DWARFLinkerImpl::emitCommonSectionsAndWriteCompileUnitsToTheOutput() { 1118 llvm::parallel::TaskGroup TG; 1119 1120 // Create section descriptors ahead if they are not exist at the moment. 1121 // SectionDescriptors container is not thread safe. Thus we should be sure 1122 // that descriptors would not be created in following parallel tasks. 1123 1124 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugStr); 1125 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugLineStr); 1126 1127 if (llvm::is_contained(GlobalData.Options.AccelTables, 1128 AccelTableKind::Apple)) { 1129 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleNames); 1130 CommonSections.getOrCreateSectionDescriptor( 1131 DebugSectionKind::AppleNamespaces); 1132 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleObjC); 1133 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleTypes); 1134 } 1135 1136 if (llvm::is_contained(GlobalData.Options.AccelTables, 1137 AccelTableKind::DebugNames)) 1138 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugNames); 1139 1140 // Emit .debug_str and .debug_line_str sections. 1141 TG.spawn([&]() { emitStringSections(); }); 1142 1143 if (llvm::is_contained(GlobalData.Options.AccelTables, 1144 AccelTableKind::Apple)) { 1145 // Emit apple accelerator sections. 1146 TG.spawn([&]() { 1147 emitAppleAcceleratorSections((*GlobalData.getTargetTriple()).get()); 1148 }); 1149 } 1150 1151 if (llvm::is_contained(GlobalData.Options.AccelTables, 1152 AccelTableKind::DebugNames)) { 1153 // Emit .debug_names section. 1154 TG.spawn([&]() { 1155 emitDWARFv5DebugNamesSection((*GlobalData.getTargetTriple()).get()); 1156 }); 1157 } 1158 1159 // Write compile units to the output file. 1160 TG.spawn([&]() { writeCompileUnitsToTheOutput(); }); 1161 } 1162 1163 void DWARFLinkerImpl::emitStringSections() { 1164 uint64_t DebugStrNextOffset = 0; 1165 uint64_t DebugLineStrNextOffset = 0; 1166 1167 // Emit zero length string. Accelerator tables does not work correctly 1168 // if the first string is not zero length string. 1169 CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr) 1170 .emitInplaceString(""); 1171 DebugStrNextOffset++; 1172 1173 forEachOutputString( 1174 [&](StringDestinationKind Kind, const StringEntry *String) { 1175 switch (Kind) { 1176 case StringDestinationKind::DebugStr: { 1177 DwarfStringPoolEntryWithExtString *StringToEmit = 1178 DebugStrStrings.getExistingEntry(String); 1179 assert(StringToEmit->isIndexed()); 1180 1181 // Strings may be repeated. Use accumulated DebugStrNextOffset 1182 // to understand whether corresponding string is already emitted. 1183 // Skip string if its offset less than accumulated offset. 1184 if (StringToEmit->Offset >= DebugStrNextOffset) { 1185 DebugStrNextOffset = 1186 StringToEmit->Offset + StringToEmit->String.size() + 1; 1187 // Emit the string itself. 1188 CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr) 1189 .emitInplaceString(StringToEmit->String); 1190 } 1191 } break; 1192 case StringDestinationKind::DebugLineStr: { 1193 DwarfStringPoolEntryWithExtString *StringToEmit = 1194 DebugLineStrStrings.getExistingEntry(String); 1195 assert(StringToEmit->isIndexed()); 1196 1197 // Strings may be repeated. Use accumulated DebugLineStrStrings 1198 // to understand whether corresponding string is already emitted. 1199 // Skip string if its offset less than accumulated offset. 1200 if (StringToEmit->Offset >= DebugLineStrNextOffset) { 1201 DebugLineStrNextOffset = 1202 StringToEmit->Offset + StringToEmit->String.size() + 1; 1203 // Emit the string itself. 1204 CommonSections.getSectionDescriptor(DebugSectionKind::DebugLineStr) 1205 .emitInplaceString(StringToEmit->String); 1206 } 1207 } break; 1208 } 1209 }); 1210 } 1211 1212 void DWARFLinkerImpl::emitAppleAcceleratorSections(const Triple &TargetTriple) { 1213 AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces; 1214 AccelTable<AppleAccelTableStaticOffsetData> AppleNames; 1215 AccelTable<AppleAccelTableStaticOffsetData> AppleObjC; 1216 AccelTable<AppleAccelTableStaticTypeData> AppleTypes; 1217 1218 forEachCompileAndTypeUnit([&](DwarfUnit *CU) { 1219 CU->forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) { 1220 uint64_t OutOffset = Info.OutOffset; 1221 switch (Info.Type) { 1222 case DwarfUnit::AccelType::None: { 1223 llvm_unreachable("Unknown accelerator record"); 1224 } break; 1225 case DwarfUnit::AccelType::Namespace: { 1226 AppleNamespaces.addName( 1227 *DebugStrStrings.getExistingEntry(Info.String), 1228 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + 1229 OutOffset); 1230 } break; 1231 case DwarfUnit::AccelType::Name: { 1232 AppleNames.addName( 1233 *DebugStrStrings.getExistingEntry(Info.String), 1234 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + 1235 OutOffset); 1236 } break; 1237 case DwarfUnit::AccelType::ObjC: { 1238 AppleObjC.addName( 1239 *DebugStrStrings.getExistingEntry(Info.String), 1240 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + 1241 OutOffset); 1242 } break; 1243 case DwarfUnit::AccelType::Type: { 1244 AppleTypes.addName( 1245 *DebugStrStrings.getExistingEntry(Info.String), 1246 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset + 1247 OutOffset, 1248 Info.Tag, 1249 Info.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation 1250 : 0, 1251 Info.QualifiedNameHash); 1252 } break; 1253 } 1254 }); 1255 }); 1256 1257 { 1258 // FIXME: we use AsmPrinter to emit accelerator sections. 1259 // It might be beneficial to directly emit accelerator data 1260 // to the raw_svector_ostream. 1261 SectionDescriptor &OutSection = 1262 CommonSections.getSectionDescriptor(DebugSectionKind::AppleNamespaces); 1263 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, 1264 OutSection.OS); 1265 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { 1266 consumeError(std::move(Err)); 1267 return; 1268 } 1269 1270 // Emit table. 1271 Emitter.emitAppleNamespaces(AppleNamespaces); 1272 Emitter.finish(); 1273 1274 // Set start offset and size for output section. 1275 OutSection.setSizesForSectionCreatedByAsmPrinter(); 1276 } 1277 1278 { 1279 // FIXME: we use AsmPrinter to emit accelerator sections. 1280 // It might be beneficial to directly emit accelerator data 1281 // to the raw_svector_ostream. 1282 SectionDescriptor &OutSection = 1283 CommonSections.getSectionDescriptor(DebugSectionKind::AppleNames); 1284 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, 1285 OutSection.OS); 1286 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { 1287 consumeError(std::move(Err)); 1288 return; 1289 } 1290 1291 // Emit table. 1292 Emitter.emitAppleNames(AppleNames); 1293 Emitter.finish(); 1294 1295 // Set start offset ans size for output section. 1296 OutSection.setSizesForSectionCreatedByAsmPrinter(); 1297 } 1298 1299 { 1300 // FIXME: we use AsmPrinter to emit accelerator sections. 1301 // It might be beneficial to directly emit accelerator data 1302 // to the raw_svector_ostream. 1303 SectionDescriptor &OutSection = 1304 CommonSections.getSectionDescriptor(DebugSectionKind::AppleObjC); 1305 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, 1306 OutSection.OS); 1307 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { 1308 consumeError(std::move(Err)); 1309 return; 1310 } 1311 1312 // Emit table. 1313 Emitter.emitAppleObjc(AppleObjC); 1314 Emitter.finish(); 1315 1316 // Set start offset ans size for output section. 1317 OutSection.setSizesForSectionCreatedByAsmPrinter(); 1318 } 1319 1320 { 1321 // FIXME: we use AsmPrinter to emit accelerator sections. 1322 // It might be beneficial to directly emit accelerator data 1323 // to the raw_svector_ostream. 1324 SectionDescriptor &OutSection = 1325 CommonSections.getSectionDescriptor(DebugSectionKind::AppleTypes); 1326 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, 1327 OutSection.OS); 1328 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { 1329 consumeError(std::move(Err)); 1330 return; 1331 } 1332 1333 // Emit table. 1334 Emitter.emitAppleTypes(AppleTypes); 1335 Emitter.finish(); 1336 1337 // Set start offset ans size for output section. 1338 OutSection.setSizesForSectionCreatedByAsmPrinter(); 1339 } 1340 } 1341 1342 void DWARFLinkerImpl::emitDWARFv5DebugNamesSection(const Triple &TargetTriple) { 1343 std::unique_ptr<DWARF5AccelTable> DebugNames; 1344 1345 DebugNamesUnitsOffsets CompUnits; 1346 CompUnitIDToIdx CUidToIdx; 1347 1348 unsigned Id = 0; 1349 1350 forEachCompileAndTypeUnit([&](DwarfUnit *CU) { 1351 bool HasRecords = false; 1352 CU->forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) { 1353 if (DebugNames.get() == nullptr) 1354 DebugNames = std::make_unique<DWARF5AccelTable>(); 1355 1356 HasRecords = true; 1357 switch (Info.Type) { 1358 case DwarfUnit::AccelType::Name: 1359 case DwarfUnit::AccelType::Namespace: 1360 case DwarfUnit::AccelType::Type: { 1361 DebugNames->addName(*DebugStrStrings.getExistingEntry(Info.String), 1362 Info.OutOffset, std::nullopt /*ParentDIEOffset*/, 1363 Info.Tag, CU->getUniqueID()); 1364 } break; 1365 1366 default: 1367 break; // Nothing to do. 1368 }; 1369 }); 1370 1371 if (HasRecords) { 1372 CompUnits.push_back( 1373 CU->getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo) 1374 .StartOffset); 1375 CUidToIdx[CU->getUniqueID()] = Id++; 1376 } 1377 }); 1378 1379 if (DebugNames.get() != nullptr) { 1380 // FIXME: we use AsmPrinter to emit accelerator sections. 1381 // It might be beneficial to directly emit accelerator data 1382 // to the raw_svector_ostream. 1383 SectionDescriptor &OutSection = 1384 CommonSections.getSectionDescriptor(DebugSectionKind::DebugNames); 1385 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, 1386 OutSection.OS); 1387 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) { 1388 consumeError(std::move(Err)); 1389 return; 1390 } 1391 1392 // Emit table. 1393 Emitter.emitDebugNames(*DebugNames, CompUnits, CUidToIdx); 1394 Emitter.finish(); 1395 1396 // Set start offset ans size for output section. 1397 OutSection.setSizesForSectionCreatedByAsmPrinter(); 1398 } 1399 } 1400 1401 void DWARFLinkerImpl::cleanupDataAfterDWARFOutputIsWritten() { 1402 GlobalData.getStringPool().clear(); 1403 DebugStrStrings.clear(); 1404 DebugLineStrStrings.clear(); 1405 } 1406 1407 void DWARFLinkerImpl::writeCompileUnitsToTheOutput() { 1408 // Enumerate all sections and store them into the final emitter. 1409 forEachObjectSectionsSet([&](OutputSections &Sections) { 1410 Sections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) { 1411 // Emit section content. 1412 SectionHandler(OutSection); 1413 }); 1414 }); 1415 } 1416 1417 void DWARFLinkerImpl::writeCommonSectionsToTheOutput() { 1418 CommonSections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) { 1419 SectionHandler(OutSection); 1420 }); 1421 } 1422