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