LLVM 24.0.0git
DWARFLinkerImpl.cpp
Go to the documentation of this file.
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 "DependencyTracker.h"
16
17using namespace llvm;
18using namespace dwarf_linker;
19using namespace dwarf_linker::parallel;
20
28
30 DWARFFile &File, uint64_t ObjFileIdx,
32 uint64_t &ModuleUnitIdx,
33 std::atomic<size_t> &UniqueUnitID)
37
38 if (File.Dwarf) {
39 if (!File.Dwarf->compile_units().empty())
40 CompileUnits.reserve(File.Dwarf->getNumCompileUnits());
41
42 // Set context format&endianness based on the input file.
43 Format.Version = File.Dwarf->getMaxVersion();
44 Format.AddrSize = File.Dwarf->getCUAddrSize();
45 Endianness = File.Dwarf->isLittleEndian() ? llvm::endianness::little
46 : llvm::endianness::big;
47 }
48}
49
51 CompileUnitHandlerTy OnCUDieLoaded) {
52 ObjectContexts.emplace_back(std::make_unique<LinkContext>(
55
56 if (ObjectContexts.back()->InputDWARFFile.Dwarf) {
57 for (const std::unique_ptr<DWARFUnit> &CU :
58 ObjectContexts.back()->InputDWARFFile.Dwarf->compile_units()) {
59 DWARFDie CUDie = CU->getUnitDIE();
60
61 if (!CUDie)
62 continue;
63
64 OnCUDieLoaded(*CU);
65
66 // Register mofule reference.
67 if (!GlobalData.getOptions().UpdateIndexTablesOnly)
68 ObjectContexts.back()->registerModuleReference(CUDie, Loader,
69 OnCUDieLoaded);
70 }
71 }
72}
73
75 ObjectContexts.reserve(ObjFilesNum);
76}
77
79 // UniqueUnitID is initialized by the constructor and must not be reset
80 // here. addObjectFile() may have already handed out IDs to clang module
81 // CUs loaded from .pcm files, and the IDs handed out below must stay
82 // disjoint from those.
83
85 return Err;
86
87 dwarf::FormParams GlobalFormat = {GlobalData.getOptions().TargetDWARFVersion,
90
91 if (std::optional<std::reference_wrapper<const Triple>> CurTriple =
92 GlobalData.getTargetTriple()) {
93 GlobalEndianness = (*CurTriple).get().isLittleEndian()
96 }
97 std::optional<uint16_t> Language;
98
99 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) {
100 if (Context->InputDWARFFile.Dwarf == nullptr) {
101 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness);
102 continue;
103 }
104
105 if (GlobalData.getOptions().Verbose) {
106 outs() << "DEBUG MAP OBJECT: " << Context->InputDWARFFile.FileName
107 << "\n";
108
109 for (const std::unique_ptr<DWARFUnit> &OrigCU :
110 Context->InputDWARFFile.Dwarf->compile_units()) {
111 outs() << "Input compilation unit:";
112 DIDumpOptions DumpOpts;
113 DumpOpts.ChildRecurseDepth = 0;
114 DumpOpts.Verbose = GlobalData.getOptions().Verbose;
115 OrigCU->getUnitDIE().dump(outs(), 0, DumpOpts);
116 }
117 }
118
119 // Verify input DWARF if requested.
120 if (GlobalData.getOptions().VerifyInputDWARF)
121 verifyInput(Context->InputDWARFFile);
122
123 if (!GlobalData.getTargetTriple())
124 GlobalEndianness = Context->getEndianness();
125 GlobalFormat.AddrSize =
126 std::max(GlobalFormat.AddrSize, Context->getFormParams().AddrSize);
127
128 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness);
129
130 // FIXME: move creation of CompileUnits into the addObjectFile.
131 // This would allow to not scan for context Language and Modules state
132 // twice. And then following handling might be removed.
133 for (const std::unique_ptr<DWARFUnit> &OrigCU :
134 Context->InputDWARFFile.Dwarf->compile_units()) {
135 DWARFDie UnitDie = OrigCU->getUnitDIE();
136
137 if (!Language) {
138 if (std::optional<uint64_t> LangVal = UnitDie.getLanguage())
139 if (isODRLanguage(*LangVal))
140 Language = static_cast<uint16_t>(*LangVal);
141 }
142 }
143
144 // Clang module units decide their ODR availability from their own
145 // language, so they have to be part of this scan as well. A module unit
146 // can be the only ODR unit of a link, and any unit which deduplicates
147 // types requires the artificial type unit to exist.
148 for (const std::unique_ptr<CompileUnit> &Module :
149 Context->ModulesCompileUnits) {
150 if (!Language) {
151 if (std::optional<uint16_t> LangVal = Module->getLanguage())
152 if (isODRLanguage(*LangVal))
153 Language = *LangVal;
154 }
155 }
156 }
157
158 if (GlobalFormat.AddrSize == 0) {
159 if (std::optional<std::reference_wrapper<const Triple>> TargetTriple =
160 GlobalData.getTargetTriple())
161 GlobalFormat.AddrSize = (*TargetTriple).get().isArch32Bit() ? 4 : 8;
162 else
163 GlobalFormat.AddrSize = 8;
164 }
165
166 CommonSections.setOutputFormat(GlobalFormat, GlobalEndianness);
167
168 if (!GlobalData.Options.NoODR && Language.has_value()) {
170 TGroup.spawn([&]() {
171 ArtificialTypeUnit = std::make_unique<TypeUnit>(
172 GlobalData, UniqueUnitID++, Language, GlobalFormat, GlobalEndianness);
173 });
174 }
175
176 // Set this process-global once. link() runs per architecture and dsymutil
177 // may run those links concurrently, so assigning it from each would be a
178 // data race; the thread count is the same for every architecture, so the
179 // first assignment suffices. Size the executor from that thread count rather
180 // than the per-architecture CU count, which is moot once it is shared.
181 static llvm::once_flag ParallelStrategyFlag;
182 llvm::call_once(ParallelStrategyFlag, [&] {
184 hardware_concurrency(GlobalData.getOptions().Threads);
185 });
186
187 // Link object files.
188 if (GlobalData.getOptions().Threads == 1) {
189 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) {
190 // Link object file.
191 if (Error Err = Context->link(ArtificialTypeUnit.get()))
192 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
193 if (Error Err = Context->unloadInput())
194 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
195 }
196 } else {
197 assert(ThreadPool && "setThreadPool() must be called before link()");
199 for (std::unique_ptr<LinkContext> &Context : ObjectContexts)
200 Group.async([&]() {
201 // Link object file.
202 if (Error Err = Context->link(ArtificialTypeUnit.get()))
203 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
204 if (Error Err = Context->unloadInput())
205 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
206 });
207 }
208
209 // Merge staged parseable Swift interface entries into the shared map. Done
210 // serially so that the final map contents and any conflict warnings are
211 // deterministic.
212 if (DWARFLinkerBase::SwiftInterfacesMapTy *SwiftInterfaces =
213 GlobalData.Options.ParseableSwiftInterfaces) {
214 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) {
215 for (std::unique_ptr<CompileUnit> &ModuleUnit :
216 Context->ModulesCompileUnits)
217 ModuleUnit->mergeSwiftInterfaces(*SwiftInterfaces);
218 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
219 CU->mergeSwiftInterfaces(*SwiftInterfaces);
220 }
221 }
222
223 // Build the linker-wide CIE registry, then emit each context's
224 // .debug_frame in parallel. See CIERegistry for the ownership rules.
225 if (!GlobalData.getOptions().UpdateIndexTablesOnly) {
227 for (std::unique_ptr<LinkContext> &Context : ObjectContexts)
228 if (Context->FrameScan)
229 Context->registerCIEs(CIEs);
230
232 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) {
233 if (!Context->FrameScan)
234 continue;
235 TGroup.spawn([&]() {
236 if (Error Err = Context->emitDebugFrame(CIEs))
237 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
238 });
239 }
240 }
241
242 if (ArtificialTypeUnit != nullptr && !ArtificialTypeUnit->getTypePool()
243 .getRoot()
244 ->getValue()
245 .load()
246 ->Children.empty()) {
247 if (GlobalData.getTargetTriple().has_value())
248 if (Error Err = ArtificialTypeUnit->finishCloningAndEmit(
249 (*GlobalData.getTargetTriple()).get()))
250 return Err;
251 }
252
253 // At this stage each compile units are cloned to their own set of debug
254 // sections. Now, update patches, assign offsets and assemble final file
255 // glueing debug tables from each compile unit.
257
258 return Error::success();
259}
260
262 assert(File.Dwarf);
263
264 std::string Buffer;
265 raw_string_ostream OS(Buffer);
266 DIDumpOptions DumpOpts;
267 if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) {
268 if (GlobalData.getOptions().InputVerificationHandler)
269 GlobalData.getOptions().InputVerificationHandler(File, OS.str());
270 }
271}
272
274 if (GlobalData.getOptions().TargetDWARFVersion == 0)
275 return createStringError(std::errc::invalid_argument,
276 "target DWARF version is not set");
277
278 if (GlobalData.getOptions().Verbose && GlobalData.getOptions().Threads != 1) {
279 GlobalData.Options.Threads = 1;
280 GlobalData.warn(
281 "set number of threads to 1 to make --verbose to work properly.", "");
282 }
283
284 // Do not do types deduplication in case --update.
285 if (GlobalData.getOptions().UpdateIndexTablesOnly &&
286 !GlobalData.Options.NoODR)
287 GlobalData.Options.NoODR = true;
288
289 return Error::success();
290}
291
292/// Resolve the relative path to a build artifact referenced by DWARF by
293/// applying DW_AT_comp_dir.
295 sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), ""));
296}
297
298static uint64_t getDwoId(const DWARFDie &CUDie) {
299 auto DwoId = dwarf::toUnsigned(
300 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id}));
301 if (DwoId)
302 return *DwoId;
303 return 0;
304}
305
306static std::string
308 const DWARFLinker::ObjectPrefixMapTy &ObjectPrefixMap) {
309 if (ObjectPrefixMap.empty())
310 return Path.str();
311
312 SmallString<256> p = Path;
313 for (const auto &Entry : ObjectPrefixMap)
314 if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second))
315 break;
316 return p.str().str();
317}
318
319static std::string getPCMFile(const DWARFDie &CUDie,
320 DWARFLinker::ObjectPrefixMapTy *ObjectPrefixMap) {
321 std::string PCMFile = dwarf::toString(
322 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
323
324 if (PCMFile.empty())
325 return PCMFile;
326
327 if (ObjectPrefixMap)
328 PCMFile = remapPath(PCMFile, *ObjectPrefixMap);
329
330 return PCMFile;
331}
332
334 const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet) {
335 if (PCMFile.empty())
336 return std::make_pair(false, false);
337
338 // Clang module DWARF skeleton CUs abuse this for the path to the module.
339 uint64_t DwoId = getDwoId(CUDie);
340
341 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
342 if (Name.empty()) {
343 if (!Quiet)
344 GlobalData.warn("anonymous module skeleton CU for " + PCMFile + ".",
345 InputDWARFFile.FileName);
346 return std::make_pair(true, true);
347 }
348
349 if (!Quiet && GlobalData.getOptions().Verbose) {
350 outs().indent(Indent);
351 outs() << "Found clang module reference " << PCMFile;
352 }
353
354 auto Cached = ClangModules.find(PCMFile);
355 if (Cached != ClangModules.end()) {
356 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
357 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
358 // ASTFileSignatures will change randomly when a module is rebuilt.
359 if (!Quiet && GlobalData.getOptions().Verbose && (Cached->second != DwoId))
360 GlobalData.warn(
361 Twine("hash mismatch: this object file was built against a "
362 "different version of the module ") +
363 PCMFile + ".",
364 InputDWARFFile.FileName);
365 if (!Quiet && GlobalData.getOptions().Verbose)
366 outs() << " [cached].\n";
367 return std::make_pair(true, true);
368 }
369
370 return std::make_pair(true, false);
371}
372
373/// If this compile unit is really a skeleton CU that points to a
374/// clang module, register it in ClangModules and return true.
375///
376/// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
377/// pointing to the module, and a DW_AT_gnu_dwo_id with the module
378/// hash.
380 const DWARFDie &CUDie, ObjFileLoaderTy Loader,
381 CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) {
382 std::string PCMFile =
383 getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap);
384 std::pair<bool, bool> IsClangModuleRef =
385 isClangModuleRef(CUDie, PCMFile, Indent, false);
386
387 if (!IsClangModuleRef.first)
388 return false;
389
390 if (IsClangModuleRef.second)
391 return true;
392
393 if (GlobalData.getOptions().Verbose)
394 outs() << " ...\n";
395
396 // Cyclic dependencies are disallowed by Clang, but we still
397 // shouldn't run into an infinite loop, so mark it as processed now.
398 ClangModules.insert({PCMFile, getDwoId(CUDie)});
399
400 if (Error E =
401 loadClangModule(Loader, CUDie, PCMFile, OnCUDieLoaded, Indent + 2)) {
402 consumeError(std::move(E));
403 return false;
404 }
405 return true;
406}
407
409 ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile,
410 CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) {
411
412 uint64_t DwoId = getDwoId(CUDie);
413 std::string ModuleName = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
414
415 /// Using a SmallString<0> because loadClangModule() is recursive.
416 SmallString<0> Path(GlobalData.getOptions().PrependPath);
417 if (sys::path::is_relative(PCMFile))
418 resolveRelativeObjectPath(Path, CUDie);
419 sys::path::append(Path, PCMFile);
420 // Don't use the cached binary holder because we have no thread-safety
421 // guarantee and the lifetime is limited.
422
423 if (Loader == nullptr) {
424 GlobalData.error("cann't load clang module: loader is not specified.",
425 InputDWARFFile.FileName);
426 return Error::success();
427 }
428
429 auto ErrOrObj = Loader(InputDWARFFile.FileName, Path);
430 if (!ErrOrObj)
431 return Error::success();
432
433 std::unique_ptr<CompileUnit> Unit;
434 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) {
435 OnCUDieLoaded(*CU);
436 // Recursively get all modules imported by this one.
437 auto ChildCUDie = CU->getUnitDIE();
438 if (!ChildCUDie)
439 continue;
440 if (!registerModuleReference(ChildCUDie, Loader, OnCUDieLoaded, Indent)) {
441 if (Unit) {
442 std::string Err =
443 (PCMFile +
444 ": Clang modules are expected to have exactly 1 compile unit.\n");
445 GlobalData.error(Err, InputDWARFFile.FileName);
447 }
448 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
449 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
450 // ASTFileSignatures will change randomly when a module is rebuilt.
451 uint64_t PCMDwoId = getDwoId(ChildCUDie);
452 if (PCMDwoId != DwoId) {
453 if (GlobalData.getOptions().Verbose)
454 GlobalData.warn(
455 Twine("hash mismatch: this object file was built against a "
456 "different version of the module ") +
457 PCMFile + ".",
458 InputDWARFFile.FileName);
459 // Update the cache entry with the DwoId of the module loaded from disk.
460 ClangModules[PCMFile] = PCMDwoId;
461 }
462
463 // Empty modules units should not be cloned.
464 if (!ChildCUDie.hasChildren())
465 continue;
466
467 // Add this module.
468 Unit = std::make_unique<CompileUnit>(
469 GlobalData, *CU, UniqueUnitID.fetch_add(1), ModuleName, *ErrOrObj,
470 getUnitForOffset, CU->getFormParams(), getEndianness());
471 }
472 }
473
474 if (Unit) {
475 // Incrementing the shared counter needs no synchronization: reaching this
476 // point requires a loader, and only the serial pass over the object files
477 // supplies one.
478 if (Error E = Unit->setPriority(ModuleUnitObjFileIdx, ModuleUnitIdx++))
479 return E;
480
481 ModulesCompileUnits.emplace_back(std::move(Unit));
482 // Preload line table, as it can't be loaded asynchronously.
483 ModulesCompileUnits.back()->loadLineTable();
484 }
485
486 return Error::success();
487}
488
491 if (!InputDWARFFile.Dwarf)
492 return Error::success();
493
494 // Preload macro tables, as they can't be loaded asynchronously.
495 InputDWARFFile.Dwarf->getDebugMacinfo();
496 InputDWARFFile.Dwarf->getDebugMacro();
497
498 // Link modules compile units first.
499 parallelForEach(ModulesCompileUnits, [&](std::unique_ptr<CompileUnit> &Mod) {
500 // A module unit describes DIEs which no address reaches, so nothing marks
501 // it inter-connected and the inter-connected loops below, which iterate
502 // CompileUnits alone, would never advance it.
503 assert(!Mod->isInterconnectedCU() && "module unit is inter-connected");
505 });
506
507 // Check for live relocations. If there is no any live relocation then we
508 // can skip entire object file.
509 if (!GlobalData.getOptions().UpdateIndexTablesOnly &&
510 !InputDWARFFile.Addresses->hasValidRelocs()) {
511 if (GlobalData.getOptions().Verbose)
512 outs() << "No valid relocations found. Skipping.\n";
513 return Error::success();
514 }
515
517
518 // Create CompileUnit structures to keep information about source
519 // DWARFUnit`s, load line tables.
520 uint64_t LocalCUIdx = 0;
521 for (const auto &OrigCU : InputDWARFFile.Dwarf->compile_units()) {
522 // Load only unit DIE at this stage.
523 auto CUDie = OrigCU->getUnitDIE();
524 std::string PCMFile =
525 getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap);
526
527 // The !isClangModuleRef condition effectively skips over fully resolved
528 // skeleton units.
529 if (!CUDie || GlobalData.getOptions().UpdateIndexTablesOnly ||
530 !isClangModuleRef(CUDie, PCMFile, 0, true).first) {
531 CompileUnits.emplace_back(std::make_unique<CompileUnit>(
532 GlobalData, *OrigCU, UniqueUnitID.fetch_add(1), "", InputDWARFFile,
533 getUnitForOffset, OrigCU->getFormParams(), getEndianness()));
534 if (llvm::Error E =
535 CompileUnits.back()->setPriority(ObjectFileIdx, LocalCUIdx++))
536 return E;
537
538 // Preload line table, as it can't be loaded asynchronously.
539 CompileUnits.back()->loadLineTable();
540 }
541 };
542
544
545 // Link self-sufficient compile units and discover inter-connected compile
546 // units.
547 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
549 });
550
551 // Link all inter-connected units.
554
555 if (Error Err = finiteLoop([&]() -> Expected<bool> {
557
558 // Load inter-connected units.
559 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
560 if (CU->isInterconnectedCU()) {
561 CU->maybeResetToLoadedStage();
564 }
565 });
566
567 // Do liveness analysis for inter-connected units.
568 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
571 });
572
573 return HasNewInterconnectedCUs.load();
574 }))
575 return Err;
576
577 // Update dependencies.
578 if (Error Err = finiteLoop([&]() -> Expected<bool> {
580 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
584 });
585 return HasNewGlobalDependency.load();
586 }))
587 return Err;
588 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
589 if (CU->isInterconnectedCU() &&
592 });
593
594 // Assign type names.
595 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
598 });
599
600 // Clone inter-connected units.
601 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
604 });
605
606 // Update patches for inter-connected units.
607 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
610 });
611
612 // Release data.
613 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
616 });
617 }
618
619 if (GlobalData.getOptions().UpdateIndexTablesOnly) {
620 // Emit Invariant sections.
621
622 if (Error Err = emitInvariantSections())
623 return Err;
624 }
625
626 return Error::success();
627}
628
631 enum CompileUnit::Stage DoUntilStage) {
632 if (InterCUProcessingStarted != CU.isInterconnectedCU())
633 return;
634
635 if (Error Err = finiteLoop([&]() -> Expected<bool> {
636 if (CU.getStage() >= DoUntilStage)
637 return false;
638
639 switch (CU.getStage()) {
641 // Load input compilation unit DIEs.
642 // Analyze properties of DIEs.
643 if (!CU.loadInputDIEs()) {
644 // We do not need to do liveness analysis for invalid compilation
645 // unit.
647 } else {
648 CU.analyzeDWARFStructure();
649
650 // The registerModuleReference() condition effectively skips
651 // over fully resolved skeleton units. This second pass of
652 // registerModuleReferences doesn't do any new work, but it
653 // will collect top-level errors, which are suppressed. Module
654 // warnings were already displayed in the first iteration.
656 CU.getOrigUnit().getUnitDIE(), nullptr,
657 [](const DWARFUnit &) {}, 0))
659 else
661 }
662 } break;
663
665 // Mark all the DIEs that need to be present in the generated output.
666 // If ODR requested, build type names.
667 if (!CU.resolveDependenciesAndMarkLiveness(InterCUProcessingStarted,
670 "Flag indicating new inter-connections is not set");
671 return false;
672 }
673
675 } break;
676
679 if (CU.updateDependenciesCompleteness())
681 return false;
682 } else {
683 if (Error Err = finiteLoop([&]() -> Expected<bool> {
684 return CU.updateDependenciesCompleteness();
685 }))
686 return std::move(Err);
687
689 }
690 } break;
691
693#ifndef NDEBUG
694 CU.verifyDependencies();
695#endif
696
697 if (ArtificialTypeUnit) {
698 if (Error Err =
699 CU.assignTypeNames(ArtificialTypeUnit->getTypePool()))
700 return std::move(Err);
701 }
703 break;
704
706 // Clone input compile unit.
707 if (CU.isClangModule() ||
708 GlobalData.getOptions().UpdateIndexTablesOnly ||
709 CU.getContainingFile().Addresses->hasValidRelocs()) {
710 if (Error Err = CU.cloneAndEmit(GlobalData.getTargetTriple(),
712 return std::move(Err);
713 }
714
716 break;
717
719 // Update DIEs referencies.
720 CU.updateDieRefPatchesWithClonedOffsets();
721
722 // Later than cloning, so that the offsets are final, and no later,
723 // because a unit which got this far can no longer be skipped and have
724 // its section dropped from the output.
725 if (CU.isClangModule())
726 CU.noteModuleAnchors();
727
729 break;
730
732 // Cleanup resources.
733 CU.cleanupDataAfterClonning();
735 break;
736
738 assert(false);
739 break;
740
742 // Nothing to do.
743 break;
744 }
745
746 return true;
747 })) {
748 CU.error(std::move(Err));
749 CU.cleanupDataAfterClonning();
751 }
752}
753
755 if (!GlobalData.getTargetTriple().has_value())
756 return Error::success();
757
759 << InputDWARFFile.Dwarf->getDWARFObj().getLocSection().Data;
761 << InputDWARFFile.Dwarf->getDWARFObj().getLoclistsSection().Data;
763 << InputDWARFFile.Dwarf->getDWARFObj().getRangesSection().Data;
765 << InputDWARFFile.Dwarf->getDWARFObj().getRnglistsSection().Data;
767 << InputDWARFFile.Dwarf->getDWARFObj().getArangesSection();
769 << InputDWARFFile.Dwarf->getDWARFObj().getFrameSection().Data;
771 << InputDWARFFile.Dwarf->getDWARFObj().getAddrSection().Data;
772
773 return Error::success();
774}
775
777 if (GlobalData.getOptions().UpdateIndexTablesOnly)
778 return Error::success();
779 if (!GlobalData.getTargetTriple().has_value())
780 return Error::success();
781
782 if (InputDWARFFile.Dwarf == nullptr)
783 return Error::success();
784 if (CompileUnits.empty())
785 return Error::success();
786
787 const DWARFObject &InputDWARFObj = InputDWARFFile.Dwarf->getDWARFObj();
788
789 StringRef OrigFrameData = InputDWARFObj.getFrameSection().Data;
790 if (OrigFrameData.empty())
791 return Error::success();
792
793 auto Scan = std::make_unique<FrameScanResult>();
794 Scan->FrameData = OrigFrameData;
795 Scan->AddressSize = InputDWARFObj.getAddressSize();
796
797 RangesTy AllUnitsRanges;
798 for (std::unique_ptr<CompileUnit> &Unit : CompileUnits) {
799 for (auto CurRange : Unit->getFunctionRanges())
800 AllUnitsRanges.insert(CurRange.Range, CurRange.Value);
801 }
802
803 StringRef FrameBytes = Scan->FrameData;
804 DataExtractor Data(FrameBytes, InputDWARFObj.isLittleEndian());
805 uint64_t InputOffset = 0;
806 const unsigned SrcAddrSize = Scan->AddressSize;
807 // Width of the CIE_pointer field at the start of every FDE (and of the
808 // CIE_id sentinel at the start of every CIE) in DWARF32 .debug_frame.
809 constexpr unsigned CIEPointerSize = 4;
810
811 // CIEs defined in this input, keyed by their input offsets.
813 DenseSet<uint64_t> AddedCIEs;
814
815 while (Data.isValidOffset(InputOffset)) {
816 uint64_t EntryOffset = InputOffset;
817 uint32_t InitialLength = Data.getU32(&InputOffset);
818 if (InitialLength == 0xFFFFFFFF)
819 return createFileError(InputDWARFFile.FileName,
820 createStringError(std::errc::invalid_argument,
821 "Dwarf64 bits not supported"));
822
823 // Reject lengths that don't fit in the input section. substr() saturates
824 // silently, which would otherwise let a malformed length poison the
825 // CIE bytes used as the registry key.
826 if (InitialLength > FrameBytes.size() - InputOffset)
827 return createFileError(
828 InputDWARFFile.FileName,
829 createStringError(std::errc::invalid_argument,
830 "Truncated .debug_frame entry."));
831
832 uint32_t CIEId = Data.getU32(&InputOffset);
833 if (CIEId == 0xFFFFFFFF) {
834 // This is a CIE, store it.
835 StringRef CIEData = FrameBytes.substr(EntryOffset, InitialLength + 4);
836 LocalCIEs[EntryOffset] = CIEData;
837 // The -4 is to account for the CIEId we just read.
838 InputOffset += InitialLength - 4;
839 continue;
840 }
841
842 uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize);
843
844 // Some compilers seem to emit frame info that doesn't start at
845 // the function entry point, thus we can't just lookup the address
846 // in the debug map. Use the AddressInfo's range map to see if the FDE
847 // describes something that we can relocate.
848 std::optional<AddressRangeValuePair> Range =
849 AllUnitsRanges.getRangeThatContains(Loc);
850 if (!Range) {
851 // The +4 is to account for the size of the InitialLength field itself.
852 InputOffset = EntryOffset + InitialLength + 4;
853 continue;
854 }
855
856 // This is an FDE, and we have a mapping.
857 StringRef CIEData = LocalCIEs.lookup(CIEId);
858 if (CIEData.empty())
859 return createFileError(
860 InputDWARFFile.FileName,
861 createStringError(std::errc::invalid_argument,
862 "Inconsistent debug_frame content. Dropping."));
863
864 // Reject FDEs whose length doesn't even cover the CIE_pointer and
865 // initial_location fields; otherwise the unsigned subtraction below
866 // would wrap and substr() would saturate to a giant garbage blob.
867 if (InitialLength < CIEPointerSize + SrcAddrSize)
868 return createFileError(InputDWARFFile.FileName,
869 createStringError(std::errc::invalid_argument,
870 "Truncated .debug_frame FDE."));
871
872 // Promote each CIE on first reference; CIEs no FDE references are
873 // dropped from the output.
874 if (AddedCIEs.insert(CIEId).second)
875 Scan->CIEs.push_back(CIEData);
876
877 unsigned FDERemainingBytes = InitialLength - (CIEPointerSize + SrcAddrSize);
878 Scan->FDEs.push_back({CIEData, Loc + Range->Value,
879 FrameBytes.substr(InputOffset, FDERemainingBytes)});
880 InputOffset += FDERemainingBytes;
881 }
882
883 FrameScan = std::move(Scan);
884 return Error::success();
885}
886
888 assert(FrameScan && "registerCIEs called without FrameScan");
889 SectionDescriptor &OutSection =
891
892 uint32_t NextLocalOffset = 0;
893 for (StringRef CIEBytes : FrameScan->CIEs) {
894 auto [It, Inserted] =
895 CIEs.try_emplace(CIEBytes, CIELocation{&OutSection, NextLocalOffset});
896 if (Inserted) {
897 FrameScan->OwnedCIEs.push_back(CIEBytes);
898 NextLocalOffset += static_cast<uint32_t>(CIEBytes.size());
899 }
900 }
901}
902
904 assert(FrameScan && "emitDebugFrame called without FrameScan");
905 SectionDescriptor &OutSection =
907
908 // Emit owned CIEs at the offsets registerCIEs reserved for them.
909 for (StringRef CIEBytes : FrameScan->OwnedCIEs)
910 OutSection.OS << CIEBytes;
911
912 const dwarf::FormParams FP = OutSection.getFormParams();
913 const unsigned SrcAddrSize = FrameScan->AddressSize;
914
915 for (const FrameScanResult::FDE &FDE : FrameScan->FDEs) {
916 auto It = CIEs.find(FDE.CIEBytes);
917 assert(It != CIEs.end() && "CIE missing from registry");
918 SectionDescriptor *CIEOwnerSection = It->second.OwnerSection;
919 const uint32_t CIELocalOffset = It->second.LocalOffset;
920
921 const uint64_t FDEPos = OutSection.OS.tell();
922 // Note: this guards against a single context's section exceeding the
923 // DWARF32 limit. It does NOT catch the post-glue overflow that would
924 // happen if the concatenated .debug_frame across all contexts pushes
925 // past 4 GB; that case slips through silently because StartOffset is
926 // not yet assigned. A post-glue check would belong in the patch
927 // resolver in OutputSections.cpp.
928 if (FDEPos > FP.getDwarfMaxOffset())
929 return createFileError(
930 InputDWARFFile.FileName,
931 createStringError(".debug_frame section offset "
932 "0x" +
933 Twine::utohexstr(FDEPos) + " exceeds the " +
934 dwarf::FormatString(FP.Format) + " limit"));
935
936 // CIE_pointer field follows the 4-byte initial_length.
937 OutSection.notePatch(DebugOffsetPatch{FDEPos + 4, CIEOwnerSection, true});
938
939 emitFDE(CIELocalOffset, SrcAddrSize, FDE.Address, FDE.Instructions,
940 OutSection);
941 }
942
943 FrameScan.reset();
944 return Error::success();
945}
946
948 // Scan the input's .debug_frame now, while the DWARFContext is still
949 // loaded, so the later (post-pool) emission pass can run against the
950 // scan result alone.
951 Error ScanErr = scanFrameData();
952 InputDWARFFile.unload();
953 return ScanErr;
954}
955
956/// Emit a FDE into the debug_frame section. \p FDEBytes
957/// contains the FDE data without the length, CIE offset and address
958/// which will be replaced with the parameter values.
960 uint32_t AddrSize, uint64_t Address,
961 StringRef FDEBytes,
962 SectionDescriptor &Section) {
963 Section.emitIntVal(FDEBytes.size() + 4 + AddrSize, 4);
964 Section.emitIntVal(CIEOffset, 4);
965 Section.emitIntVal(Address, AddrSize);
966 Section.OS.write(FDEBytes.data(), FDEBytes.size());
967}
968
970 if (!GlobalData.getTargetTriple().has_value())
971 return;
973
974 // Go through all object files, all compile units and assign
975 // offsets to them.
977
978 // Patch size/offsets fields according to the assigned CU offsets.
980
981 // Emit common sections and write debug tables from all object files/compile
982 // units into the resulting file.
984
985 if (ArtificialTypeUnit != nullptr)
986 ArtificialTypeUnit.reset();
987
988 // Write common debug sections into the resulting file.
990
991 // Cleanup data.
993
994 if (GlobalData.getOptions().Statistics)
996}
997
999
1000 // For each object file map how many bytes were emitted.
1001 StringMap<DebugInfoSize> SizeByObject;
1002
1003 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) {
1004 uint64_t AllDebugInfoSectionsSize = 0;
1005
1006 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1007 if (std::optional<SectionDescriptor *> DebugInfo =
1008 CU->tryGetSectionDescriptor(DebugSectionKind::DebugInfo))
1009 AllDebugInfoSectionsSize += (*DebugInfo)->getContents().size();
1010
1011 auto &Size = SizeByObject[Context->InputDWARFFile.FileName];
1012 Size.Input = Context->OriginalDebugInfoSize;
1013 Size.Output = AllDebugInfoSectionsSize;
1014 }
1015
1016 // Create a vector sorted in descending order by output size.
1017 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted;
1018 for (auto &E : SizeByObject)
1019 Sorted.emplace_back(E.first(), E.second);
1020 llvm::sort(Sorted, [](auto &LHS, auto &RHS) {
1021 return LHS.second.Output > RHS.second.Output;
1022 });
1023
1024 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float {
1025 const float Difference = Output - Input;
1026 const float Sum = Input + Output;
1027 if (Sum == 0)
1028 return 0;
1029 return (Difference / (Sum / 2));
1030 };
1031
1032 int64_t InputTotal = 0;
1033 int64_t OutputTotal = 0;
1034 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
1035
1036 // Print header.
1037 outs() << ".debug_info section size (in bytes)\n";
1038 outs() << "----------------------------------------------------------------"
1039 "---------------\n";
1040 outs() << "Filename Object "
1041 " dSYM Change\n";
1042 outs() << "----------------------------------------------------------------"
1043 "---------------\n";
1044
1045 // Print body.
1046 for (auto &E : Sorted) {
1047 InputTotal += E.second.Input;
1048 OutputTotal += E.second.Output;
1049 llvm::outs() << formatv(
1050 FormatStr, sys::path::filename(E.first).take_back(45), E.second.Input,
1051 E.second.Output, ComputePercentange(E.second.Input, E.second.Output));
1052 }
1053 // Print total and footer.
1054 outs() << "----------------------------------------------------------------"
1055 "---------------\n";
1056 llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal,
1057 ComputePercentange(InputTotal, OutputTotal));
1058 outs() << "----------------------------------------------------------------"
1059 "---------------\n\n";
1060}
1061
1064 TGroup.spawn([&]() { assignOffsetsToStrings(); });
1065 TGroup.spawn([&]() { assignOffsetsToSections(); });
1066}
1067
1069 size_t CurDebugStrIndex = 1; // start from 1 to take into account zero entry.
1070 uint64_t CurDebugStrOffset =
1071 1; // start from 1 to take into account zero entry.
1072 size_t CurDebugLineStrIndex = 0;
1073 uint64_t CurDebugLineStrOffset = 0;
1074
1075 // Enumerates all strings, add them into the DwarfStringPoolEntry map,
1076 // assign offset and index to the string if it is not indexed yet.
1078 const StringEntry *String) {
1079 switch (Kind) {
1082 assert(Entry != nullptr);
1083
1084 if (!Entry->isIndexed()) {
1085 Entry->Offset = CurDebugStrOffset;
1086 CurDebugStrOffset += Entry->String.size() + 1;
1087 Entry->Index = CurDebugStrIndex++;
1088 }
1089 } break;
1093 assert(Entry != nullptr);
1094
1095 if (!Entry->isIndexed()) {
1096 Entry->Offset = CurDebugLineStrOffset;
1097 CurDebugLineStrOffset += Entry->String.size() + 1;
1098 Entry->Index = CurDebugLineStrIndex++;
1099 }
1100 } break;
1101 }
1102 });
1103}
1104
1106 std::array<uint64_t, SectionKindsNum> SectionSizesAccumulator = {0};
1107
1108 forEachObjectSectionsSet([&](OutputSections &UnitSections) {
1109 UnitSections.assignSectionsOffsetAndAccumulateSize(SectionSizesAccumulator);
1110 });
1111}
1112
1115 StringHandler) {
1116 // To save space we do not create any separate string table.
1117 // We use already allocated string patches and accelerator entries:
1118 // enumerate them in natural order and assign offsets.
1119 // ASSUMPTION: strings should be stored into .debug_str/.debug_line_str
1120 // sections in the same order as they were assigned offsets.
1122 CU->forEach([&](SectionDescriptor &OutSection) {
1123 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
1124 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1125 });
1126
1127 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
1128 StringHandler(StringDestinationKind::DebugLineStr, Patch.String);
1129 });
1130 });
1131
1132 CU->forEachAcceleratorRecord([&](DwarfUnit::AccelInfo &Info) {
1133 StringHandler(DebugStr, Info.String);
1134 });
1135 });
1136
1137 if (ArtificialTypeUnit != nullptr) {
1138 ArtificialTypeUnit->forEach([&](SectionDescriptor &OutSection) {
1139 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
1140 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1141 });
1142
1143 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
1144 StringHandler(StringDestinationKind::DebugLineStr, Patch.String);
1145 });
1146
1147 OutSection.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) {
1148 if (Patch.Die == nullptr)
1149 return;
1150
1151 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
1152 if (&TypeEntry->getFinalDie() != Patch.Die)
1153 return;
1154
1155 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1156 });
1157
1158 OutSection.ListDebugTypeLineStrPatch.forEach(
1159 [&](DebugTypeLineStrPatch &Patch) {
1160 if (Patch.Die == nullptr)
1161 return;
1162
1163 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
1164 if (&TypeEntry->getFinalDie() != Patch.Die)
1165 return;
1166
1167 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1168 });
1169 });
1170 }
1171}
1172
1174 function_ref<void(OutputSections &)> SectionsSetHandler) {
1175 // Handle artificial type unit first.
1176 if (ArtificialTypeUnit != nullptr)
1177 SectionsSetHandler(*ArtificialTypeUnit);
1178
1179 // Then all modules(before regular compilation units).
1180 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1181 for (std::unique_ptr<CompileUnit> &ModuleUnit :
1182 Context->ModulesCompileUnits)
1183 if (ModuleUnit->getStage() != CompileUnit::Stage::Skipped)
1184 SectionsSetHandler(*ModuleUnit);
1185
1186 // Finally all compilation units.
1187 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) {
1188 // Handle object file common sections.
1189 SectionsSetHandler(*Context);
1190
1191 // Handle compilation units.
1192 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1193 if (CU->getStage() != CompileUnit::Stage::Skipped)
1194 SectionsSetHandler(*CU);
1195 }
1196}
1197
1199 function_ref<void(DwarfUnit *CU)> UnitHandler) {
1200 if (ArtificialTypeUnit != nullptr)
1201 UnitHandler(ArtificialTypeUnit.get());
1202
1203 // Enumerate module units.
1204 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1205 for (std::unique_ptr<CompileUnit> &ModuleUnit :
1206 Context->ModulesCompileUnits)
1207 if (ModuleUnit->getStage() != CompileUnit::Stage::Skipped)
1208 UnitHandler(ModuleUnit.get());
1209
1210 // Enumerate compile units.
1211 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1212 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1213 if (CU->getStage() != CompileUnit::Stage::Skipped)
1214 UnitHandler(CU.get());
1215}
1216
1218 function_ref<void(CompileUnit *CU)> UnitHandler) {
1219 // Enumerate module units.
1220 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1221 for (std::unique_ptr<CompileUnit> &ModuleUnit :
1222 Context->ModulesCompileUnits)
1223 if (ModuleUnit->getStage() != CompileUnit::Stage::Skipped)
1224 UnitHandler(ModuleUnit.get());
1225
1226 // Enumerate compile units.
1227 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1228 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1229 if (CU->getStage() != CompileUnit::Stage::Skipped)
1230 UnitHandler(CU.get());
1231}
1232
1234 forEachObjectSectionsSet([&](OutputSections &SectionsSet) {
1235 SectionsSet.forEach([&](SectionDescriptor &OutSection) {
1236 SectionsSet.applyPatches(OutSection, DebugStrStrings, DebugLineStrStrings,
1237 ArtificialTypeUnit.get());
1238 });
1239 });
1240}
1241
1244
1245 // Create section descriptors ahead if they are not exist at the moment.
1246 // SectionDescriptors container is not thread safe. Thus we should be sure
1247 // that descriptors would not be created in following parallel tasks.
1248
1249 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugStr);
1250 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugLineStr);
1251
1252 if (llvm::is_contained(GlobalData.Options.AccelTables,
1254 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleNames);
1255 CommonSections.getOrCreateSectionDescriptor(
1257 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleObjC);
1258 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleTypes);
1259 }
1260
1261 if (llvm::is_contained(GlobalData.Options.AccelTables,
1263 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugNames);
1264
1265 // Emit .debug_str and .debug_line_str sections.
1266 TG.spawn([&]() { emitStringSections(); });
1267
1268 if (llvm::is_contained(GlobalData.Options.AccelTables,
1270 // Emit apple accelerator sections.
1271 TG.spawn([&]() {
1272 emitAppleAcceleratorSections((*GlobalData.getTargetTriple()).get());
1273 });
1274 }
1275
1276 if (llvm::is_contained(GlobalData.Options.AccelTables,
1278 // Emit .debug_names section.
1279 TG.spawn([&]() {
1280 emitDWARFv5DebugNamesSection((*GlobalData.getTargetTriple()).get());
1281 });
1282 }
1283
1284 // Write compile units to the output file.
1285 TG.spawn([&]() { writeCompileUnitsToTheOutput(); });
1286}
1287
1289 uint64_t DebugStrNextOffset = 0;
1290 uint64_t DebugLineStrNextOffset = 0;
1291
1292 // Emit zero length string. Accelerator tables does not work correctly
1293 // if the first string is not zero length string.
1294 CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr)
1295 .emitInplaceString("");
1296 DebugStrNextOffset++;
1297
1299 [&](StringDestinationKind Kind, const StringEntry *String) {
1300 switch (Kind) {
1302 DwarfStringPoolEntryWithExtString *StringToEmit =
1303 DebugStrStrings.getExistingEntry(String);
1304 assert(StringToEmit->isIndexed());
1305
1306 // Strings may be repeated. Use accumulated DebugStrNextOffset
1307 // to understand whether corresponding string is already emitted.
1308 // Skip string if its offset less than accumulated offset.
1309 if (StringToEmit->Offset >= DebugStrNextOffset) {
1310 DebugStrNextOffset =
1311 StringToEmit->Offset + StringToEmit->String.size() + 1;
1312 // Emit the string itself.
1313 CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr)
1314 .emitInplaceString(StringToEmit->String);
1315 }
1316 } break;
1318 DwarfStringPoolEntryWithExtString *StringToEmit =
1319 DebugLineStrStrings.getExistingEntry(String);
1320 assert(StringToEmit->isIndexed());
1321
1322 // Strings may be repeated. Use accumulated DebugLineStrStrings
1323 // to understand whether corresponding string is already emitted.
1324 // Skip string if its offset less than accumulated offset.
1325 if (StringToEmit->Offset >= DebugLineStrNextOffset) {
1326 DebugLineStrNextOffset =
1327 StringToEmit->Offset + StringToEmit->String.size() + 1;
1328 // Emit the string itself.
1330 .emitInplaceString(StringToEmit->String);
1331 }
1332 } break;
1333 }
1334 });
1335}
1336
1342
1344 CU->forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {
1345 uint64_t OutOffset = Info.OutOffset;
1346 switch (Info.Type) {
1348 llvm_unreachable("Unknown accelerator record");
1349 } break;
1351 AppleNamespaces.addName(
1352 *DebugStrStrings.getExistingEntry(Info.String),
1353 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1354 OutOffset);
1355 } break;
1357 AppleNames.addName(
1358 *DebugStrStrings.getExistingEntry(Info.String),
1359 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1360 OutOffset);
1361 } break;
1363 AppleObjC.addName(
1364 *DebugStrStrings.getExistingEntry(Info.String),
1365 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1366 OutOffset);
1367 } break;
1369 AppleTypes.addName(
1370 *DebugStrStrings.getExistingEntry(Info.String),
1371 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1372 OutOffset,
1373 Info.Tag,
1374 Info.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation
1375 : 0,
1376 Info.QualifiedNameHash);
1377 } break;
1378 }
1379 });
1380 });
1381
1382 {
1383 // FIXME: we use AsmPrinter to emit accelerator sections.
1384 // It might be beneficial to directly emit accelerator data
1385 // to the raw_svector_ostream.
1386 SectionDescriptor &OutSection =
1389 OutSection.OS);
1390 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1391 consumeError(std::move(Err));
1392 return;
1393 }
1394
1395 // Emit table.
1396 Emitter.emitAppleNamespaces(AppleNamespaces);
1397 Emitter.finish();
1398
1399 // Set start offset and size for output section.
1401 }
1402
1403 {
1404 // FIXME: we use AsmPrinter to emit accelerator sections.
1405 // It might be beneficial to directly emit accelerator data
1406 // to the raw_svector_ostream.
1407 SectionDescriptor &OutSection =
1408 CommonSections.getSectionDescriptor(DebugSectionKind::AppleNames);
1410 OutSection.OS);
1411 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1412 consumeError(std::move(Err));
1413 return;
1414 }
1415
1416 // Emit table.
1417 Emitter.emitAppleNames(AppleNames);
1418 Emitter.finish();
1419
1420 // Set start offset ans size for output section.
1422 }
1423
1424 {
1425 // FIXME: we use AsmPrinter to emit accelerator sections.
1426 // It might be beneficial to directly emit accelerator data
1427 // to the raw_svector_ostream.
1428 SectionDescriptor &OutSection =
1429 CommonSections.getSectionDescriptor(DebugSectionKind::AppleObjC);
1431 OutSection.OS);
1432 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1433 consumeError(std::move(Err));
1434 return;
1435 }
1436
1437 // Emit table.
1438 Emitter.emitAppleObjc(AppleObjC);
1439 Emitter.finish();
1440
1441 // Set start offset ans size for output section.
1443 }
1444
1445 {
1446 // FIXME: we use AsmPrinter to emit accelerator sections.
1447 // It might be beneficial to directly emit accelerator data
1448 // to the raw_svector_ostream.
1449 SectionDescriptor &OutSection =
1450 CommonSections.getSectionDescriptor(DebugSectionKind::AppleTypes);
1452 OutSection.OS);
1453 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1454 consumeError(std::move(Err));
1455 return;
1456 }
1457
1458 // Emit table.
1459 Emitter.emitAppleTypes(AppleTypes);
1460 Emitter.finish();
1461
1462 // Set start offset ans size for output section.
1464 }
1465}
1466
1468 std::unique_ptr<DWARF5AccelTable> DebugNames;
1469
1470 DebugNamesUnitsOffsets CompUnits;
1471 CompUnitIDToIdx CUidToIdx;
1472
1473 unsigned Id = 0;
1474
1476 bool HasRecords = false;
1477 CU->forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {
1478 if (DebugNames == nullptr)
1479 DebugNames = std::make_unique<DWARF5AccelTable>();
1480
1481 HasRecords = true;
1482 switch (Info.Type) {
1486 DebugNames->addName(*DebugStrStrings.getExistingEntry(Info.String),
1487 Info.OutOffset, Info.ParentOffset, Info.Tag,
1488 CU->getUniqueID(),
1489 CU->getTag() == dwarf::DW_TAG_type_unit);
1490 } break;
1491
1492 default:
1493 break; // Nothing to do.
1494 };
1495 });
1496
1497 if (HasRecords) {
1498 CompUnits.push_back(
1499 CU->getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)
1500 .StartOffset);
1501 CUidToIdx[CU->getUniqueID()] = Id++;
1502 }
1503 });
1504
1505 if (DebugNames != nullptr) {
1506 // FIXME: we use AsmPrinter to emit accelerator sections.
1507 // It might be beneficial to directly emit accelerator data
1508 // to the raw_svector_ostream.
1509 SectionDescriptor &OutSection =
1510 CommonSections.getSectionDescriptor(DebugSectionKind::DebugNames);
1512 OutSection.OS);
1513 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1514 consumeError(std::move(Err));
1515 return;
1516 }
1517
1518 // Emit table.
1519 Emitter.emitDebugNames(*DebugNames, CompUnits, CUidToIdx);
1520 Emitter.finish();
1521
1522 // Set start offset ans size for output section.
1524 }
1525}
1526
1528 GlobalData.getStringPool().clear();
1529 DebugStrStrings.clear();
1530 DebugLineStrStrings.clear();
1531}
1532
1534 // Enumerate all sections and store them into the final emitter.
1536 Sections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
1537 // Emit section content.
1538 SectionHandler(OutSection);
1539 });
1540 });
1541}
1542
1544 CommonSections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
1545 SectionHandler(OutSection);
1546 });
1547}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
dxil DXContainer Global Emitter
static fatal_error_handler_t ErrorHandler
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
The Input class is used to parse a yaml document into in-memory structs and vectors.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition AccelTable.h:203
std::optional< T > getRangeThatContains(uint64_t Addr) const
void insert(AddressRange Range, int64_t Value)
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition DWARFDie.h:43
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition DWARFDie.cpp:322
LLVM_ABI std::optional< uint64_t > getLanguage() const
Returns the DW_LANG_ code for this DIE's DWARF unit, if it exists.
Definition DWARFDie.cpp:493
virtual bool isLittleEndian() const =0
virtual const DWARFSection & getFrameSection() const
Definition DWARFObject.h:44
virtual uint8_t getAddressSize() const
Definition DWARFObject.h:35
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:250
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:128
iterator end()
Definition StringMap.h:213
iterator find(StringRef Key)
Definition StringMap.h:226
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
Definition StringMap.h:369
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
A group of tasks to be run on a thread pool.
Definition ThreadPool.h:269
auto async(Function &&F, Args &&...ArgList)
Calls ThreadPool::async() for this group.
Definition ThreadPool.h:280
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
This class represents DWARF information for source file and it's address map.
Definition DWARFFile.h:25
std::map< std::string, std::string > ObjectPrefixMapTy
function_ref< void(const DWARFUnit &Unit)> CompileUnitHandlerTy
std::function< void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
std::map< std::string, std::string > SwiftInterfacesMapTy
std::function< ErrorOr< DWARFFile & >( StringRef ContainerName, StringRef Path)> ObjFileLoaderTy
Stores all information related to a compile unit, be it in its original instance of the object file o...
Stage
The stages of new compile unit processing.
@ CreatedNotLoaded
Created, linked with input DWARF file.
@ PatchesUpdated
Offsets inside patch records are updated.
@ Cleaned
Resources(Input DWARF, Output DWARF tree) are released.
@ LivenessAnalysisDone
Input DWARF is analysed(DIEs pointing to the real code section arediscovered, type names are assigned...
@ UpdateDependenciesCompleteness
Check if dependencies have incompatible placement.
void forEachObjectSectionsSet(function_ref< void(OutputSections &SectionsSet)> SectionsSetHandler)
Enumerates sections for modules, invariant for object files, compile units.
void emitDWARFv5DebugNamesSection(const Triple &TargetTriple)
Emit .debug_names section.
static constexpr uint64_t ModuleUnitObjFileIdx
The object file index given to every clang module unit.
void writeCompileUnitsToTheOutput()
Enumerate all compile units and put their data into the output stream.
void forEachCompileUnit(function_ref< void(CompileUnit *CU)> UnitHandler)
Enumerates all comple units.
void assignOffsetsToStrings()
Enumerate all compile units and assign offsets to their strings.
void assignOffsets()
Enumerate all compile units and assign offsets to their sections and strings.
Error link() override
Link debug info for added files.
Error validateAndUpdateOptions()
Validate specified options.
void writeCommonSectionsToTheOutput()
Enumerate common sections and put their data into the output stream.
void assignOffsetsToSections()
Enumerate all compile units and assign offsets to their sections.
void printStatistic()
Print statistic for processed Debug Info.
void glueCompileUnitsAndWriteToTheOutput()
Take already linked compile units and glue them into single file.
void emitAppleAcceleratorSections(const Triple &TargetTriple)
Emit apple accelerator sections.
void verifyInput(const DWARFFile &File)
Verify input DWARF file.
void forEachCompileAndTypeUnit(function_ref< void(DwarfUnit *CU)> UnitHandler)
Enumerates all compile and type units.
DWARFLinkerImpl(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler)
void addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader=nullptr, CompileUnitHandlerTy OnCUDieLoaded=[](const DWARFUnit &) {}) override
Add object file to be linked.
void cleanupDataAfterDWARFOutputIsWritten()
Cleanup data(string pools) after output sections are generated.
void forEachOutputString(function_ref< void(StringDestinationKind, const StringEntry *)> StringHandler)
Enumerates all strings.
static constexpr uint64_t FirstObjFileIdx
Object file indices follow the module units'.
void emitCommonSectionsAndWriteCompileUnitsToTheOutput()
Emit debug sections common for all input files.
void patchOffsetsAndSizes()
Enumerates all patches and update them with the correct values.
This class emits DWARF data to the output stream.
Base class for all Dwarf units(Compile unit/Type table unit).
This class keeps data and services common for the whole linking process.
This class keeps contents and offsets to the debug sections.
void applyPatches(SectionDescriptor &Section, StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, TypeUnit *TypeUnitPtr)
Enumerate all sections, for each section apply all section patches.
OutputSections(LinkingGlobalData &GlobalData)
void forEach(function_ref< void(SectionDescriptor &)> Handler)
Enumerate all sections and call Handler for each.
llvm::endianness getEndianness() const
Endiannes for the sections.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
void assignSectionsOffsetAndAccumulateSize(std::array< uint64_t, SectionKindsNum > &SectionSizesAccumulator)
Enumerate all sections, for each section set current offset (kept by SectionSizesAccumulator),...
const SectionDescriptor & getSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
Keeps cloned data for the type DIE.
Definition TypePool.h:31
Type Unit is used to represent an artificial compilation unit which keeps all type information.
An efficient, type-erasing, non-owning reference to a callable.
LLVM_ABI void spawn(std::function< void()> f)
Definition Parallel.cpp:244
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
ThreadPoolInterface * ThreadPool
Thread pool that links the object files, or null to use a private pool.
std::atomic< size_t > UniqueUnitID
Unique ID for compile unit.
SmallVector< std::unique_ptr< LinkContext > > ObjectContexts
Keeps all linking contexts.
StringEntryToDwarfStringPoolEntryMap DebugLineStrStrings
DwarfStringPoolEntries for .debug_line_str section.
SectionHandlerTy SectionHandler
Hanler for output sections.
std::unique_ptr< TypeUnit > ArtificialTypeUnit
Type unit.
StringEntryToDwarfStringPoolEntryMap DebugStrStrings
DwarfStringPoolEntries for .debug_str section.
uint64_t ModuleUnitIdx
Numbers the clang module units of the whole link, so that they form one priority sequence regardless ...
OutputSections CommonSections
Common sections.
StringMap< uint64_t > ClangModules
Mapping the PCM filename to the DwoId.
LLVM_ABI StringRef FormatString(DwarfFormat Format)
Definition Dwarf.cpp:1062
void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override
Set estimated objects files amount, for preliminary data allocation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isODRLanguage(uint16_t Language)
std::vector< std::variant< MCSymbol *, uint64_t > > DebugNamesUnitsOffsets
DenseMap< unsigned, unsigned > CompUnitIDToIdx
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
Definition TypePool.h:28
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
Definition StringPool.h:23
Error finiteLoop(function_ref< Expected< bool >()> Iteration, size_t MaxCounter=100000)
This function calls Iteration() until it returns false.
Definition Utils.h:44
AddressRangesMap RangesTy
Mapped value in the address map is the offset to apply to the linked address.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
@ DWARF32
Definition Dwarf.h:93
@ DW_FLAG_type_implementation
Definition Dwarf.h:1036
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
LLVM_ABI ThreadPoolStrategy strategy
Definition Parallel.cpp:27
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition Path.cpp:716
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:594
LLVM_ABI bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
Definition Path.cpp:529
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:467
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)
Returns a default thread strategy where all available hardware resources are to be used,...
Definition Threading.h:190
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition Error.h:1415
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
static std::string remapPath(StringRef Path, const DWARFLinkerBase::ObjectPrefixMapTy &ObjectPrefixMap)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
static void resolveRelativeObjectPath(SmallVectorImpl< char > &Buf, DWARFDie CU)
Resolve the relative path to a build artifact referenced by DWARF by applying DW_AT_comp_dir.
static std::string getPCMFile(const DWARFDie &CUDie, const DWARFLinkerBase::ObjectPrefixMapTy *ObjectPrefixMap)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
static uint64_t getDwoId(const DWARFDie &CUDie)
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
void call_once(once_flag &flag, Function &&F, Args &&... ArgList)
Execute the function specified as a parameter once.
Definition Threading.h:86
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn)
Definition Parallel.h:209
endianness
Definition bit.h:71
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106
Container for dump options that control which debug information will be dumped.
Definition DIContext.h:196
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition DIContext.h:228
unsigned ChildRecurseDepth
Definition DIContext.h:198
DwarfStringPoolEntry with string keeping externally.
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition Dwarf.h:1199
Section + local offset of a .debug_frame CIE that has been (or will be) emitted by some LinkContext.
uint64_t getInputDebugInfoSize() const
Computes the total size of the debug info.
bool InterCUProcessingStarted
Flag indicating that all inter-connected units are loaded and the dwarf linking process for these uni...
bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent=0)
If this compile unit is really a skeleton CU that points to a clang module, register it in ClangModul...
Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent=0)
Recursively add the debug info in this clang module .pcm file (and all the modules imported by it in ...
LinkContext(LinkingGlobalData &GlobalData, DWARFFile &File, uint64_t ObjFileIdx, StringMap< uint64_t > &ClangModules, uint64_t &ModuleUnitIdx, std::atomic< size_t > &UniqueUnitID)
Error scanFrameData()
Parse this context's input .debug_frame into FrameScan.
uint64_t OriginalDebugInfoSize
Size of Debug info before optimizing.
std::pair< bool, bool > isClangModuleRef(const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet)
Check whether specified CUDie is a Clang module reference.
void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address, StringRef FDEBytes, SectionDescriptor &Section)
Emit FDE record.
UnitListTy CompileUnits
Set of Compilation Units(may be accessed asynchroniously for reading).
void linkSingleCompileUnit(CompileUnit &CU, TypeUnit *ArtificialTypeUnit, enum CompileUnit::Stage DoUntilStage=CompileUnit::Stage::Cleaned)
Link specified compile unit until specified stage.
UnitListTy ModulesCompileUnits
Set of Compile Units for modules.
void registerCIEs(CIERegistry &CIEs)
Register this context's CIEs with the linker-wide registry.
std::atomic< bool > HasNewInterconnectedCUs
Flag indicating that new inter-connected compilation units were discovered.
Error emitDebugFrame(const CIERegistry &CIEs)
Emit this context's .debug_frame section.
std::atomic< size_t > & UniqueUnitID
Counter for compile units ID.
Error link(TypeUnit *ArtificialTypeUnit)
Link compile units for this context.
StringMap< CIELocation > CIERegistry
Linker-wide registry for .debug_frame CIEs.
Error unloadInput()
Unload the input DWARFContext after scanning the input .debug_frame into FrameScan.
uint64_t ObjectFileIdx
Index of this object file in the link order (used for deterministic type DIE allocation).
std::function< CompileUnit *(uint64_t)> getUnitForOffset
This structure is used to update strings offsets into .debug_line_str.
This structure is used to update strings offsets into .debug_str.
This structure keeps fields which would be used for creating accelerator table.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
This structure is used to keep data of the concrete section.
raw_svector_ostream OS
Stream which stores data to the Contents.
void setSizesForSectionCreatedByAsmPrinter()
Some sections are emitted using AsmPrinter.
The llvm::once_flag structure.
Definition Threading.h:67