1 //=== DWARFLinkerImpl.cpp -------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "DWARFLinkerImpl.h"
10 #include "DIEGenerator.h"
11 #include "DependencyTracker.h"
12 #include "llvm/Support/FormatVariadic.h"
13 #include "llvm/Support/Parallel.h"
14 #include "llvm/Support/ThreadPool.h"
17 namespace dwarflinker_parallel
{
19 Error
DWARFLinkerImpl::createEmitter(const Triple
&TheTriple
,
20 OutputFileType FileType
,
21 raw_pwrite_stream
&OutFile
) {
23 TheDwarfEmitter
= std::make_unique
<DwarfEmitterImpl
>(FileType
, OutFile
);
25 return TheDwarfEmitter
->init(TheTriple
, "__DWARF");
28 ExtraDwarfEmitter
*DWARFLinkerImpl::getEmitter() {
29 return TheDwarfEmitter
.get();
32 void DWARFLinkerImpl::addObjectFile(DWARFFile
&File
, ObjFileLoaderTy Loader
,
33 CompileUnitHandlerTy OnCUDieLoaded
) {
34 ObjectContexts
.emplace_back(std::make_unique
<LinkContext
>(
35 GlobalData
, File
, ClangModules
, UniqueUnitID
,
36 (TheDwarfEmitter
.get() == nullptr ? std::optional
<Triple
>(std::nullopt
)
37 : TheDwarfEmitter
->getTargetTriple())));
39 if (ObjectContexts
.back()->InputDWARFFile
.Dwarf
) {
40 for (const std::unique_ptr
<DWARFUnit
> &CU
:
41 ObjectContexts
.back()->InputDWARFFile
.Dwarf
->compile_units()) {
42 DWARFDie CUDie
= CU
->getUnitDIE();
50 // Register mofule reference.
51 if (!GlobalData
.getOptions().UpdateIndexTablesOnly
)
52 ObjectContexts
.back()->registerModuleReference(CUDie
, Loader
,
58 Error
DWARFLinkerImpl::link() {
59 // reset compile unit unique ID counter.
62 if (Error Err
= validateAndUpdateOptions())
65 dwarf::FormParams GlobalFormat
= {GlobalData
.getOptions().TargetDWARFVersion
,
66 0, dwarf::DwarfFormat::DWARF32
};
67 llvm::endianness GlobalEndianness
= llvm::endianness::native
;
69 if (TheDwarfEmitter
) {
70 GlobalEndianness
= TheDwarfEmitter
->getTargetTriple().isLittleEndian()
71 ? llvm::endianness::little
72 : llvm::endianness::big
;
75 for (std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
) {
76 if (Context
->InputDWARFFile
.Dwarf
.get() == nullptr) {
77 Context
->setOutputFormat(Context
->getFormParams(), GlobalEndianness
);
81 if (GlobalData
.getOptions().Verbose
) {
82 outs() << "OBJECT: " << Context
->InputDWARFFile
.FileName
<< "\n";
84 for (const std::unique_ptr
<DWARFUnit
> &OrigCU
:
85 Context
->InputDWARFFile
.Dwarf
->compile_units()) {
86 outs() << "Input compilation unit:";
87 DIDumpOptions DumpOpts
;
88 DumpOpts
.ChildRecurseDepth
= 0;
89 DumpOpts
.Verbose
= GlobalData
.getOptions().Verbose
;
90 OrigCU
->getUnitDIE().dump(outs(), 0, DumpOpts
);
94 // Verify input DWARF if requested.
95 if (GlobalData
.getOptions().VerifyInputDWARF
)
96 verifyInput(Context
->InputDWARFFile
);
99 GlobalEndianness
= Context
->getEndianness();
100 GlobalFormat
.AddrSize
=
101 std::max(GlobalFormat
.AddrSize
, Context
->getFormParams().AddrSize
);
103 Context
->setOutputFormat(Context
->getFormParams(), GlobalEndianness
);
106 if (GlobalFormat
.AddrSize
== 0) {
108 GlobalFormat
.AddrSize
=
109 TheDwarfEmitter
->getTargetTriple().isArch32Bit() ? 4 : 8;
111 GlobalFormat
.AddrSize
= 8;
114 CommonSections
.setOutputFormat(GlobalFormat
, GlobalEndianness
);
116 // Set parallel options.
117 if (GlobalData
.getOptions().Threads
== 0)
118 parallel::strategy
= optimal_concurrency(OverallNumberOfCU
);
120 parallel::strategy
= hardware_concurrency(GlobalData
.getOptions().Threads
);
122 // Link object files.
123 if (GlobalData
.getOptions().Threads
== 1) {
124 for (std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
) {
126 if (Error Err
= Context
->link())
127 GlobalData
.error(std::move(Err
), Context
->InputDWARFFile
.FileName
);
129 Context
->InputDWARFFile
.unload();
132 ThreadPool
Pool(parallel::strategy
);
133 for (std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
)
136 if (Error Err
= Context
->link())
137 GlobalData
.error(std::move(Err
), Context
->InputDWARFFile
.FileName
);
139 Context
->InputDWARFFile
.unload();
145 // At this stage each compile units are cloned to their own set of debug
146 // sections. Now, update patches, assign offsets and assemble final file
147 // glueing debug tables from each compile unit.
148 glueCompileUnitsAndWriteToTheOutput();
150 return Error::success();
153 void DWARFLinkerImpl::verifyInput(const DWARFFile
&File
) {
157 raw_string_ostream
OS(Buffer
);
158 DIDumpOptions DumpOpts
;
159 if (!File
.Dwarf
->verify(OS
, DumpOpts
.noImplicitRecursion())) {
160 if (GlobalData
.getOptions().InputVerificationHandler
)
161 GlobalData
.getOptions().InputVerificationHandler(File
, OS
.str());
165 Error
DWARFLinkerImpl::validateAndUpdateOptions() {
166 if (GlobalData
.getOptions().TargetDWARFVersion
== 0)
167 return createStringError(std::errc::invalid_argument
,
168 "target DWARF version is not set");
170 GlobalData
.Options
.NoOutput
= TheDwarfEmitter
.get() == nullptr;
172 if (GlobalData
.getOptions().Verbose
&& GlobalData
.getOptions().Threads
!= 1) {
173 GlobalData
.Options
.Threads
= 1;
175 "set number of threads to 1 to make --verbose to work properly.", "");
178 return Error::success();
181 /// Resolve the relative path to a build artifact referenced by DWARF by
182 /// applying DW_AT_comp_dir.
183 static void resolveRelativeObjectPath(SmallVectorImpl
<char> &Buf
, DWARFDie CU
) {
184 sys::path::append(Buf
, dwarf::toString(CU
.find(dwarf::DW_AT_comp_dir
), ""));
187 static uint64_t getDwoId(const DWARFDie
&CUDie
) {
188 auto DwoId
= dwarf::toUnsigned(
189 CUDie
.find({dwarf::DW_AT_dwo_id
, dwarf::DW_AT_GNU_dwo_id
}));
196 remapPath(StringRef Path
,
197 const DWARFLinker::ObjectPrefixMapTy
&ObjectPrefixMap
) {
198 if (ObjectPrefixMap
.empty())
201 SmallString
<256> p
= Path
;
202 for (const auto &Entry
: ObjectPrefixMap
)
203 if (llvm::sys::path::replace_path_prefix(p
, Entry
.first
, Entry
.second
))
205 return p
.str().str();
208 static std::string
getPCMFile(const DWARFDie
&CUDie
,
209 DWARFLinker::ObjectPrefixMapTy
*ObjectPrefixMap
) {
210 std::string PCMFile
= dwarf::toString(
211 CUDie
.find({dwarf::DW_AT_dwo_name
, dwarf::DW_AT_GNU_dwo_name
}), "");
217 PCMFile
= remapPath(PCMFile
, *ObjectPrefixMap
);
222 std::pair
<bool, bool> DWARFLinkerImpl::LinkContext::isClangModuleRef(
223 const DWARFDie
&CUDie
, std::string
&PCMFile
, unsigned Indent
, bool Quiet
) {
225 return std::make_pair(false, false);
227 // Clang module DWARF skeleton CUs abuse this for the path to the module.
228 uint64_t DwoId
= getDwoId(CUDie
);
230 std::string Name
= dwarf::toString(CUDie
.find(dwarf::DW_AT_name
), "");
233 GlobalData
.warn("anonymous module skeleton CU for " + PCMFile
+ ".",
234 InputDWARFFile
.FileName
);
235 return std::make_pair(true, true);
238 if (!Quiet
&& GlobalData
.getOptions().Verbose
) {
239 outs().indent(Indent
);
240 outs() << "Found clang module reference " << PCMFile
;
243 auto Cached
= ClangModules
.find(PCMFile
);
244 if (Cached
!= ClangModules
.end()) {
245 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
246 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
247 // ASTFileSignatures will change randomly when a module is rebuilt.
248 if (!Quiet
&& GlobalData
.getOptions().Verbose
&& (Cached
->second
!= DwoId
))
250 Twine("hash mismatch: this object file was built against a "
251 "different version of the module ") +
253 InputDWARFFile
.FileName
);
254 if (!Quiet
&& GlobalData
.getOptions().Verbose
)
255 outs() << " [cached].\n";
256 return std::make_pair(true, true);
259 return std::make_pair(true, false);
262 /// If this compile unit is really a skeleton CU that points to a
263 /// clang module, register it in ClangModules and return true.
265 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
266 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
268 bool DWARFLinkerImpl::LinkContext::registerModuleReference(
269 const DWARFDie
&CUDie
, ObjFileLoaderTy Loader
,
270 CompileUnitHandlerTy OnCUDieLoaded
, unsigned Indent
) {
271 std::string PCMFile
=
272 getPCMFile(CUDie
, GlobalData
.getOptions().ObjectPrefixMap
);
273 std::pair
<bool, bool> IsClangModuleRef
=
274 isClangModuleRef(CUDie
, PCMFile
, Indent
, false);
276 if (!IsClangModuleRef
.first
)
279 if (IsClangModuleRef
.second
)
282 if (GlobalData
.getOptions().Verbose
)
285 // Cyclic dependencies are disallowed by Clang, but we still
286 // shouldn't run into an infinite loop, so mark it as processed now.
287 ClangModules
.insert({PCMFile
, getDwoId(CUDie
)});
290 loadClangModule(Loader
, CUDie
, PCMFile
, OnCUDieLoaded
, Indent
+ 2)) {
291 consumeError(std::move(E
));
297 Error
DWARFLinkerImpl::LinkContext::loadClangModule(
298 ObjFileLoaderTy Loader
, const DWARFDie
&CUDie
, const std::string
&PCMFile
,
299 CompileUnitHandlerTy OnCUDieLoaded
, unsigned Indent
) {
301 uint64_t DwoId
= getDwoId(CUDie
);
302 std::string ModuleName
= dwarf::toString(CUDie
.find(dwarf::DW_AT_name
), "");
304 /// Using a SmallString<0> because loadClangModule() is recursive.
305 SmallString
<0> Path(GlobalData
.getOptions().PrependPath
);
306 if (sys::path::is_relative(PCMFile
))
307 resolveRelativeObjectPath(Path
, CUDie
);
308 sys::path::append(Path
, PCMFile
);
309 // Don't use the cached binary holder because we have no thread-safety
310 // guarantee and the lifetime is limited.
312 if (Loader
== nullptr) {
313 GlobalData
.error("cann't load clang module: loader is not specified.",
314 InputDWARFFile
.FileName
);
315 return Error::success();
318 auto ErrOrObj
= Loader(InputDWARFFile
.FileName
, Path
);
320 return Error::success();
322 std::unique_ptr
<CompileUnit
> Unit
;
323 for (const auto &CU
: ErrOrObj
->Dwarf
->compile_units()) {
325 // Recursively get all modules imported by this one.
326 auto ChildCUDie
= CU
->getUnitDIE();
329 if (!registerModuleReference(ChildCUDie
, Loader
, OnCUDieLoaded
, Indent
)) {
333 ": Clang modules are expected to have exactly 1 compile unit.\n");
334 GlobalData
.error(Err
, InputDWARFFile
.FileName
);
335 return make_error
<StringError
>(Err
, inconvertibleErrorCode());
337 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
338 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
339 // ASTFileSignatures will change randomly when a module is rebuilt.
340 uint64_t PCMDwoId
= getDwoId(ChildCUDie
);
341 if (PCMDwoId
!= DwoId
) {
342 if (GlobalData
.getOptions().Verbose
)
344 Twine("hash mismatch: this object file was built against a "
345 "different version of the module ") +
347 InputDWARFFile
.FileName
);
348 // Update the cache entry with the DwoId of the module loaded from disk.
349 ClangModules
[PCMFile
] = PCMDwoId
;
352 // Empty modules units should not be cloned.
353 if (!ChildCUDie
.hasChildren())
357 Unit
= std::make_unique
<CompileUnit
>(
358 GlobalData
, *CU
, UniqueUnitID
.fetch_add(1), ModuleName
, *ErrOrObj
,
359 getUnitForOffset
, CU
->getFormParams(), getEndianness());
364 ModulesCompileUnits
.emplace_back(RefModuleUnit
{*ErrOrObj
, std::move(Unit
)});
365 // Preload line table, as it can't be loaded asynchronously.
366 ModulesCompileUnits
.back().Unit
->loadLineTable();
369 return Error::success();
372 Error
DWARFLinkerImpl::LinkContext::link() {
373 InterCUProcessingStarted
= false;
374 if (!InputDWARFFile
.Dwarf
)
375 return Error::success();
377 // Preload macro tables, as they can't be loaded asynchronously.
378 InputDWARFFile
.Dwarf
->getDebugMacinfo();
379 InputDWARFFile
.Dwarf
->getDebugMacro();
381 // Link modules compile units first.
382 parallelForEach(ModulesCompileUnits
, [&](RefModuleUnit
&RefModule
) {
383 linkSingleCompileUnit(*RefModule
.Unit
);
386 // Check for live relocations. If there is no any live relocation then we
387 // can skip entire object file.
388 if (!GlobalData
.getOptions().UpdateIndexTablesOnly
&&
389 !InputDWARFFile
.Addresses
->hasValidRelocs()) {
390 if (GlobalData
.getOptions().Verbose
)
391 outs() << "No valid relocations found. Skipping.\n";
392 return Error::success();
395 OriginalDebugInfoSize
= getInputDebugInfoSize();
397 // Create CompileUnit structures to keep information about source
398 // DWARFUnit`s, load line tables.
399 for (const auto &OrigCU
: InputDWARFFile
.Dwarf
->compile_units()) {
400 // Load only unit DIE at this stage.
401 auto CUDie
= OrigCU
->getUnitDIE();
402 std::string PCMFile
=
403 getPCMFile(CUDie
, GlobalData
.getOptions().ObjectPrefixMap
);
405 // The !isClangModuleRef condition effectively skips over fully resolved
407 if (!CUDie
|| GlobalData
.getOptions().UpdateIndexTablesOnly
||
408 !isClangModuleRef(CUDie
, PCMFile
, 0, true).first
) {
409 CompileUnits
.emplace_back(std::make_unique
<CompileUnit
>(
410 GlobalData
, *OrigCU
, UniqueUnitID
.fetch_add(1), "", InputDWARFFile
,
411 getUnitForOffset
, OrigCU
->getFormParams(), getEndianness()));
413 // Preload line table, as it can't be loaded asynchronously.
414 CompileUnits
.back()->loadLineTable();
418 HasNewInterconnectedCUs
= false;
420 // Link self-sufficient compile units and discover inter-connected compile
422 parallelForEach(CompileUnits
, [&](std::unique_ptr
<CompileUnit
> &CU
) {
423 linkSingleCompileUnit(*CU
);
426 // Link all inter-connected units.
427 if (HasNewInterconnectedCUs
) {
428 InterCUProcessingStarted
= true;
431 HasNewInterconnectedCUs
= false;
433 // Load inter-connected units.
434 parallelForEach(CompileUnits
, [&](std::unique_ptr
<CompileUnit
> &CU
) {
435 if (CU
->isInterconnectedCU()) {
436 CU
->maybeResetToLoadedStage();
437 linkSingleCompileUnit(*CU
, CompileUnit::Stage::Loaded
);
441 // Do liveness analysis for inter-connected units.
442 parallelForEach(CompileUnits
, [&](std::unique_ptr
<CompileUnit
> &CU
) {
443 linkSingleCompileUnit(*CU
, CompileUnit::Stage::LivenessAnalysisDone
);
445 } while (HasNewInterconnectedCUs
);
447 // Clone inter-connected units.
448 parallelForEach(CompileUnits
, [&](std::unique_ptr
<CompileUnit
> &CU
) {
449 linkSingleCompileUnit(*CU
, CompileUnit::Stage::Cloned
);
452 // Update patches for inter-connected units.
453 parallelForEach(CompileUnits
, [&](std::unique_ptr
<CompileUnit
> &CU
) {
454 linkSingleCompileUnit(*CU
, CompileUnit::Stage::PatchesUpdated
);
458 parallelForEach(CompileUnits
, [&](std::unique_ptr
<CompileUnit
> &CU
) {
459 linkSingleCompileUnit(*CU
, CompileUnit::Stage::Cleaned
);
463 if (GlobalData
.getOptions().UpdateIndexTablesOnly
) {
464 // Emit Invariant sections.
466 if (Error Err
= emitInvariantSections())
468 } else if (!CompileUnits
.empty()) {
469 // Emit .debug_frame section.
471 Error ResultErr
= Error::success();
472 parallel::TaskGroup TGroup
;
473 // We use task group here as PerThreadBumpPtrAllocator should be called from
474 // the threads created by ThreadPoolExecutor.
476 if (Error Err
= cloneAndEmitDebugFrame())
477 ResultErr
= std::move(Err
);
482 return Error::success();
485 void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
486 CompileUnit
&CU
, enum CompileUnit::Stage DoUntilStage
) {
487 while (CU
.getStage() < DoUntilStage
) {
488 if (InterCUProcessingStarted
!= CU
.isInterconnectedCU())
491 switch (CU
.getStage()) {
492 case CompileUnit::Stage::CreatedNotLoaded
: {
493 // Load input compilation unit DIEs.
494 // Analyze properties of DIEs.
495 if (!CU
.loadInputDIEs()) {
496 // We do not need to do liveness analysis for invalud compilation unit.
497 CU
.setStage(CompileUnit::Stage::LivenessAnalysisDone
);
499 CU
.analyzeDWARFStructure();
501 // The registerModuleReference() condition effectively skips
502 // over fully resolved skeleton units. This second pass of
503 // registerModuleReferences doesn't do any new work, but it
504 // will collect top-level errors, which are suppressed. Module
505 // warnings were already displayed in the first iteration.
506 if (registerModuleReference(
507 CU
.getOrigUnit().getUnitDIE(), nullptr,
508 [](const DWARFUnit
&) {}, 0))
509 CU
.setStage(CompileUnit::Stage::PatchesUpdated
);
511 CU
.setStage(CompileUnit::Stage::Loaded
);
515 case CompileUnit::Stage::Loaded
: {
516 // Mark all the DIEs that need to be present in the generated output.
517 // If ODR requested, build type names.
518 if (!DependencyTracker(*this).resolveDependenciesAndMarkLiveness(CU
)) {
519 assert(HasNewInterconnectedCUs
);
523 CU
.setStage(CompileUnit::Stage::LivenessAnalysisDone
);
526 case CompileUnit::Stage::LivenessAnalysisDone
:
529 DependencyTracker::verifyKeepChain(CU
);
532 // Clone input compile unit.
533 if (CU
.isClangModule() || GlobalData
.getOptions().UpdateIndexTablesOnly
||
534 CU
.getContaingFile().Addresses
->hasValidRelocs()) {
535 if (Error Err
= CU
.cloneAndEmit(TargetTriple
))
536 CU
.error(std::move(Err
));
539 CU
.setStage(CompileUnit::Stage::Cloned
);
542 case CompileUnit::Stage::Cloned
:
543 // Update DIEs referencies.
544 CU
.updateDieRefPatchesWithClonedOffsets();
545 CU
.setStage(CompileUnit::Stage::PatchesUpdated
);
548 case CompileUnit::Stage::PatchesUpdated
:
549 // Cleanup resources.
550 CU
.cleanupDataAfterClonning();
551 CU
.setStage(CompileUnit::Stage::Cleaned
);
554 case CompileUnit::Stage::Cleaned
:
561 Error
DWARFLinkerImpl::LinkContext::emitInvariantSections() {
562 if (GlobalData
.getOptions().NoOutput
)
563 return Error::success();
565 getOrCreateSectionDescriptor(DebugSectionKind::DebugLoc
).OS
566 << InputDWARFFile
.Dwarf
->getDWARFObj().getLocSection().Data
;
567 getOrCreateSectionDescriptor(DebugSectionKind::DebugLocLists
).OS
568 << InputDWARFFile
.Dwarf
->getDWARFObj().getLoclistsSection().Data
;
569 getOrCreateSectionDescriptor(DebugSectionKind::DebugRange
).OS
570 << InputDWARFFile
.Dwarf
->getDWARFObj().getRangesSection().Data
;
571 getOrCreateSectionDescriptor(DebugSectionKind::DebugRngLists
).OS
572 << InputDWARFFile
.Dwarf
->getDWARFObj().getRnglistsSection().Data
;
573 getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges
).OS
574 << InputDWARFFile
.Dwarf
->getDWARFObj().getArangesSection();
575 getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame
).OS
576 << InputDWARFFile
.Dwarf
->getDWARFObj().getFrameSection().Data
;
577 getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr
).OS
578 << InputDWARFFile
.Dwarf
->getDWARFObj().getAddrSection().Data
;
580 return Error::success();
583 Error
DWARFLinkerImpl::LinkContext::cloneAndEmitDebugFrame() {
584 if (GlobalData
.getOptions().NoOutput
)
585 return Error::success();
587 if (InputDWARFFile
.Dwarf
.get() == nullptr)
588 return Error::success();
590 const DWARFObject
&InputDWARFObj
= InputDWARFFile
.Dwarf
->getDWARFObj();
592 StringRef OrigFrameData
= InputDWARFObj
.getFrameSection().Data
;
593 if (OrigFrameData
.empty())
594 return Error::success();
596 RangesTy AllUnitsRanges
;
597 for (std::unique_ptr
<CompileUnit
> &Unit
: CompileUnits
) {
598 for (auto CurRange
: Unit
->getFunctionRanges())
599 AllUnitsRanges
.insert(CurRange
.Range
, CurRange
.Value
);
602 unsigned SrcAddrSize
= InputDWARFObj
.getAddressSize();
604 SectionDescriptor
&OutSection
=
605 getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame
);
607 DataExtractor
Data(OrigFrameData
, InputDWARFObj
.isLittleEndian(), 0);
608 uint64_t InputOffset
= 0;
610 // Store the data of the CIEs defined in this object, keyed by their
612 DenseMap
<uint64_t, StringRef
> LocalCIES
;
614 /// The CIEs that have been emitted in the output section. The actual CIE
615 /// data serves a the key to this StringMap.
616 StringMap
<uint32_t> EmittedCIEs
;
618 while (Data
.isValidOffset(InputOffset
)) {
619 uint64_t EntryOffset
= InputOffset
;
620 uint32_t InitialLength
= Data
.getU32(&InputOffset
);
621 if (InitialLength
== 0xFFFFFFFF)
622 return createFileError(InputDWARFObj
.getFileName(),
623 createStringError(std::errc::invalid_argument
,
624 "Dwarf64 bits no supported"));
626 uint32_t CIEId
= Data
.getU32(&InputOffset
);
627 if (CIEId
== 0xFFFFFFFF) {
628 // This is a CIE, store it.
629 StringRef CIEData
= OrigFrameData
.substr(EntryOffset
, InitialLength
+ 4);
630 LocalCIES
[EntryOffset
] = CIEData
;
631 // The -4 is to account for the CIEId we just read.
632 InputOffset
+= InitialLength
- 4;
636 uint64_t Loc
= Data
.getUnsigned(&InputOffset
, SrcAddrSize
);
638 // Some compilers seem to emit frame info that doesn't start at
639 // the function entry point, thus we can't just lookup the address
640 // in the debug map. Use the AddressInfo's range map to see if the FDE
641 // describes something that we can relocate.
642 std::optional
<AddressRangeValuePair
> Range
=
643 AllUnitsRanges
.getRangeThatContains(Loc
);
645 // The +4 is to account for the size of the InitialLength field itself.
646 InputOffset
= EntryOffset
+ InitialLength
+ 4;
650 // This is an FDE, and we have a mapping.
651 // Have we already emitted a corresponding CIE?
652 StringRef CIEData
= LocalCIES
[CIEId
];
654 return createFileError(
655 InputDWARFObj
.getFileName(),
656 createStringError(std::errc::invalid_argument
,
657 "Inconsistent debug_frame content. Dropping."));
659 uint64_t OffsetToCIERecord
= OutSection
.OS
.tell();
661 // Look if we already emitted a CIE that corresponds to the
662 // referenced one (the CIE data is the key of that lookup).
663 auto IteratorInserted
=
664 EmittedCIEs
.insert(std::make_pair(CIEData
, OffsetToCIERecord
));
665 OffsetToCIERecord
= IteratorInserted
.first
->getValue();
667 // Emit CIE for this ID if it is not emitted yet.
668 if (IteratorInserted
.second
)
669 OutSection
.OS
<< CIEData
;
671 // Remember offset to the FDE record, so that we might update
672 // field referencing CIE record(containing OffsetToCIERecord),
673 // when final offsets are known. OffsetToCIERecord(which is written later)
674 // is local to the current .debug_frame section, it should be updated
675 // with final offset of the .debug_frame section.
676 OutSection
.notePatch(
677 DebugOffsetPatch
{OutSection
.OS
.tell() + 4, &OutSection
, true});
679 // Emit the FDE with updated address and CIE pointer.
680 // (4 + AddrSize) is the size of the CIEId + initial_location
681 // fields that will get reconstructed by emitFDE().
682 unsigned FDERemainingBytes
= InitialLength
- (4 + SrcAddrSize
);
683 emitFDE(OffsetToCIERecord
, SrcAddrSize
, Loc
+ Range
->Value
,
684 OrigFrameData
.substr(InputOffset
, FDERemainingBytes
), OutSection
);
685 InputOffset
+= FDERemainingBytes
;
688 return Error::success();
691 /// Emit a FDE into the debug_frame section. \p FDEBytes
692 /// contains the FDE data without the length, CIE offset and address
693 /// which will be replaced with the parameter values.
694 void DWARFLinkerImpl::LinkContext::emitFDE(uint32_t CIEOffset
,
695 uint32_t AddrSize
, uint64_t Address
,
697 SectionDescriptor
&Section
) {
698 Section
.emitIntVal(FDEBytes
.size() + 4 + AddrSize
, 4);
699 Section
.emitIntVal(CIEOffset
, 4);
700 Section
.emitIntVal(Address
, AddrSize
);
701 Section
.OS
.write(FDEBytes
.data(), FDEBytes
.size());
704 void DWARFLinkerImpl::glueCompileUnitsAndWriteToTheOutput() {
705 if (GlobalData
.getOptions().NoOutput
)
708 // Go through all object files, all compile units and assign
712 // Patch size/offsets fields according to the assigned CU offsets.
713 patchOffsetsAndSizes();
715 // Emit common sections and write debug tables from all object files/compile
716 // units into the resulting file.
717 emitCommonSectionsAndWriteCompileUnitsToTheOutput();
719 // Write common debug sections into the resulting file.
720 writeCommonSectionsToTheOutput();
723 cleanupDataAfterDWARFOutputIsWritten();
725 if (GlobalData
.getOptions().Statistics
)
729 void DWARFLinkerImpl::printStatistic() {
731 // For each object file map how many bytes were emitted.
732 StringMap
<DebugInfoSize
> SizeByObject
;
734 for (const std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
) {
735 uint64_t AllDebugInfoSectionsSize
= 0;
737 for (std::unique_ptr
<CompileUnit
> &CU
: Context
->CompileUnits
)
738 if (std::optional
<SectionDescriptor
*> DebugInfo
=
739 CU
->tryGetSectionDescriptor(DebugSectionKind::DebugInfo
))
740 AllDebugInfoSectionsSize
+= (*DebugInfo
)->getContents().size();
742 SizeByObject
[Context
->InputDWARFFile
.FileName
].Input
=
743 Context
->OriginalDebugInfoSize
;
744 SizeByObject
[Context
->InputDWARFFile
.FileName
].Output
=
745 AllDebugInfoSectionsSize
;
748 // Create a vector sorted in descending order by output size.
749 std::vector
<std::pair
<StringRef
, DebugInfoSize
>> Sorted
;
750 for (auto &E
: SizeByObject
)
751 Sorted
.emplace_back(E
.first(), E
.second
);
752 llvm::sort(Sorted
, [](auto &LHS
, auto &RHS
) {
753 return LHS
.second
.Output
> RHS
.second
.Output
;
756 auto ComputePercentange
= [](int64_t Input
, int64_t Output
) -> float {
757 const float Difference
= Output
- Input
;
758 const float Sum
= Input
+ Output
;
761 return (Difference
/ (Sum
/ 2));
764 int64_t InputTotal
= 0;
765 int64_t OutputTotal
= 0;
766 const char *FormatStr
= "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
769 outs() << ".debug_info section size (in bytes)\n";
770 outs() << "----------------------------------------------------------------"
772 outs() << "Filename Object "
774 outs() << "----------------------------------------------------------------"
778 for (auto &E
: Sorted
) {
779 InputTotal
+= E
.second
.Input
;
780 OutputTotal
+= E
.second
.Output
;
781 llvm::outs() << formatv(
782 FormatStr
, sys::path::filename(E
.first
).take_back(45), E
.second
.Input
,
783 E
.second
.Output
, ComputePercentange(E
.second
.Input
, E
.second
.Output
));
785 // Print total and footer.
786 outs() << "----------------------------------------------------------------"
788 llvm::outs() << formatv(FormatStr
, "Total", InputTotal
, OutputTotal
,
789 ComputePercentange(InputTotal
, OutputTotal
));
790 outs() << "----------------------------------------------------------------"
791 "---------------\n\n";
794 void DWARFLinkerImpl::assignOffsets() {
795 parallel::TaskGroup TGroup
;
796 TGroup
.spawn([&]() { assignOffsetsToStrings(); });
797 TGroup
.spawn([&]() { assignOffsetsToSections(); });
800 void DWARFLinkerImpl::assignOffsetsToStrings() {
801 size_t CurDebugStrIndex
= 1; // start from 1 to take into account zero entry.
802 uint64_t CurDebugStrOffset
=
803 1; // start from 1 to take into account zero entry.
804 size_t CurDebugLineStrIndex
= 0;
805 uint64_t CurDebugLineStrOffset
= 0;
807 // Enumerates all strings, add them into the DwarfStringPoolEntry map,
808 // assign offset and index to the string if it is not indexed yet.
809 forEachOutputString([&](StringDestinationKind Kind
,
810 const StringEntry
*String
) {
812 case StringDestinationKind::DebugStr
: {
813 DwarfStringPoolEntryWithExtString
*Entry
= DebugStrStrings
.add(String
);
814 assert(Entry
!= nullptr);
816 if (!Entry
->isIndexed()) {
817 Entry
->Offset
= CurDebugStrOffset
;
818 CurDebugStrOffset
+= Entry
->String
.size() + 1;
819 Entry
->Index
= CurDebugStrIndex
++;
822 case StringDestinationKind::DebugLineStr
: {
823 DwarfStringPoolEntryWithExtString
*Entry
=
824 DebugLineStrStrings
.add(String
);
825 assert(Entry
!= nullptr);
827 if (!Entry
->isIndexed()) {
828 Entry
->Offset
= CurDebugLineStrOffset
;
829 CurDebugLineStrOffset
+= Entry
->String
.size() + 1;
830 Entry
->Index
= CurDebugLineStrIndex
++;
837 void DWARFLinkerImpl::assignOffsetsToSections() {
838 std::array
<uint64_t, SectionKindsNum
> SectionSizesAccumulator
= {0};
840 forEachObjectSectionsSet([&](OutputSections
&UnitSections
) {
841 UnitSections
.assignSectionsOffsetAndAccumulateSize(SectionSizesAccumulator
);
845 void DWARFLinkerImpl::forEachOutputString(
846 function_ref
<void(StringDestinationKind Kind
, const StringEntry
*String
)>
848 // To save space we do not create any separate string table.
849 // We use already allocated string patches and accelerator entries:
850 // enumerate them in natural order and assign offsets.
851 // ASSUMPTION: strings should be stored into .debug_str/.debug_line_str
852 // sections in the same order as they were assigned offsets.
853 forEachCompileUnit([&](CompileUnit
*CU
) {
854 CU
->forEach([&](SectionDescriptor
&OutSection
) {
855 OutSection
.ListDebugStrPatch
.forEach([&](DebugStrPatch
&Patch
) {
856 StringHandler(StringDestinationKind::DebugStr
, Patch
.String
);
859 OutSection
.ListDebugLineStrPatch
.forEach([&](DebugLineStrPatch
&Patch
) {
860 StringHandler(StringDestinationKind::DebugLineStr
, Patch
.String
);
864 CU
->AcceleratorRecords
.forEach([&](DwarfUnit::AccelInfo
&Info
) {
865 StringHandler(DebugStr
, Info
.String
);
870 void DWARFLinkerImpl::forEachObjectSectionsSet(
871 function_ref
<void(OutputSections
&)> SectionsSetHandler
) {
872 // Handle all modules first(before regular compilation units).
873 for (const std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
)
874 for (LinkContext::RefModuleUnit
&ModuleUnit
: Context
->ModulesCompileUnits
)
875 SectionsSetHandler(*ModuleUnit
.Unit
);
877 for (const std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
) {
878 // Handle object file common sections.
879 SectionsSetHandler(*Context
);
881 // Handle compilation units.
882 for (std::unique_ptr
<CompileUnit
> &CU
: Context
->CompileUnits
)
883 SectionsSetHandler(*CU
);
887 void DWARFLinkerImpl::forEachCompileUnit(
888 function_ref
<void(CompileUnit
*CU
)> UnitHandler
) {
889 // Enumerate module units.
890 for (const std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
)
891 for (LinkContext::RefModuleUnit
&ModuleUnit
: Context
->ModulesCompileUnits
)
892 UnitHandler(ModuleUnit
.Unit
.get());
894 // Enumerate compile units.
895 for (const std::unique_ptr
<LinkContext
> &Context
: ObjectContexts
)
896 for (std::unique_ptr
<CompileUnit
> &CU
: Context
->CompileUnits
)
897 UnitHandler(CU
.get());
900 void DWARFLinkerImpl::patchOffsetsAndSizes() {
901 forEachObjectSectionsSet([&](OutputSections
&SectionsSet
) {
902 SectionsSet
.forEach([&](SectionDescriptor
&OutSection
) {
903 SectionsSet
.applyPatches(OutSection
, DebugStrStrings
,
904 DebugLineStrStrings
);
909 void DWARFLinkerImpl::emitCommonSectionsAndWriteCompileUnitsToTheOutput() {
910 parallel::TaskGroup TG
;
912 // Create section descriptors ahead if they are not exist at the moment.
913 // SectionDescriptors container is not thread safe. Thus we should be sure
914 // that descriptors would not be created in following parallel tasks.
916 CommonSections
.getOrCreateSectionDescriptor(DebugSectionKind::DebugStr
);
917 CommonSections
.getOrCreateSectionDescriptor(DebugSectionKind::DebugLineStr
);
919 if (llvm::is_contained(GlobalData
.Options
.AccelTables
,
920 AccelTableKind::Apple
)) {
921 CommonSections
.getOrCreateSectionDescriptor(DebugSectionKind::AppleNames
);
922 CommonSections
.getOrCreateSectionDescriptor(
923 DebugSectionKind::AppleNamespaces
);
924 CommonSections
.getOrCreateSectionDescriptor(DebugSectionKind::AppleObjC
);
925 CommonSections
.getOrCreateSectionDescriptor(DebugSectionKind::AppleTypes
);
928 if (llvm::is_contained(GlobalData
.Options
.AccelTables
,
929 AccelTableKind::DebugNames
))
930 CommonSections
.getOrCreateSectionDescriptor(DebugSectionKind::DebugNames
);
932 const Triple
&TargetTriple
= TheDwarfEmitter
->getTargetTriple();
934 // Emit .debug_str and .debug_line_str sections.
935 TG
.spawn([&]() { emitStringSections(); });
937 if (llvm::is_contained(GlobalData
.Options
.AccelTables
,
938 AccelTableKind::Apple
)) {
939 // Emit apple accelerator sections.
940 TG
.spawn([&]() { emitAppleAcceleratorSections(TargetTriple
); });
943 if (llvm::is_contained(GlobalData
.Options
.AccelTables
,
944 AccelTableKind::DebugNames
)) {
945 // Emit .debug_names section.
946 TG
.spawn([&]() { emitDWARFv5DebugNamesSection(TargetTriple
); });
949 // Write compile units to the output file.
950 TG
.spawn([&]() { writeCompileUnitsToTheOutput(); });
953 void DWARFLinkerImpl::emitStringSections() {
954 uint64_t DebugStrNextOffset
= 0;
955 uint64_t DebugLineStrNextOffset
= 0;
957 // Emit zero length string. Accelerator tables does not work correctly
958 // if the first string is not zero length string.
959 CommonSections
.getSectionDescriptor(DebugSectionKind::DebugStr
)
960 .emitInplaceString("");
961 DebugStrNextOffset
++;
964 [&](StringDestinationKind Kind
, const StringEntry
*String
) {
966 case StringDestinationKind::DebugStr
: {
967 DwarfStringPoolEntryWithExtString
*StringToEmit
=
968 DebugStrStrings
.getExistingEntry(String
);
969 assert(StringToEmit
->isIndexed());
971 // Strings may be repeated. Use accumulated DebugStrNextOffset
972 // to understand whether corresponding string is already emitted.
973 // Skip string if its offset less than accumulated offset.
974 if (StringToEmit
->Offset
>= DebugStrNextOffset
) {
976 StringToEmit
->Offset
+ StringToEmit
->String
.size() + 1;
977 // Emit the string itself.
978 CommonSections
.getSectionDescriptor(DebugSectionKind::DebugStr
)
979 .emitInplaceString(StringToEmit
->String
);
982 case StringDestinationKind::DebugLineStr
: {
983 DwarfStringPoolEntryWithExtString
*StringToEmit
=
984 DebugLineStrStrings
.getExistingEntry(String
);
985 assert(StringToEmit
->isIndexed());
987 // Strings may be repeated. Use accumulated DebugLineStrStrings
988 // to understand whether corresponding string is already emitted.
989 // Skip string if its offset less than accumulated offset.
990 if (StringToEmit
->Offset
>= DebugLineStrNextOffset
) {
991 DebugLineStrNextOffset
=
992 StringToEmit
->Offset
+ StringToEmit
->String
.size() + 1;
993 // Emit the string itself.
994 CommonSections
.getSectionDescriptor(DebugSectionKind::DebugLineStr
)
995 .emitInplaceString(StringToEmit
->String
);
1002 void DWARFLinkerImpl::emitAppleAcceleratorSections(const Triple
&TargetTriple
) {
1003 AccelTable
<AppleAccelTableStaticOffsetData
> AppleNamespaces
;
1004 AccelTable
<AppleAccelTableStaticOffsetData
> AppleNames
;
1005 AccelTable
<AppleAccelTableStaticOffsetData
> AppleObjC
;
1006 AccelTable
<AppleAccelTableStaticTypeData
> AppleTypes
;
1008 forEachCompileUnit([&](CompileUnit
*CU
) {
1009 CU
->AcceleratorRecords
.forEach([&](const DwarfUnit::AccelInfo
&Info
) {
1010 switch (Info
.Type
) {
1011 case DwarfUnit::AccelType::None
: {
1012 llvm_unreachable("Unknown accelerator record");
1014 case DwarfUnit::AccelType::Namespace
: {
1015 AppleNamespaces
.addName(
1016 *DebugStrStrings
.getExistingEntry(Info
.String
),
1017 CU
->getSectionDescriptor(DebugSectionKind::DebugInfo
).StartOffset
+
1020 case DwarfUnit::AccelType::Name
: {
1022 *DebugStrStrings
.getExistingEntry(Info
.String
),
1023 CU
->getSectionDescriptor(DebugSectionKind::DebugInfo
).StartOffset
+
1026 case DwarfUnit::AccelType::ObjC
: {
1028 *DebugStrStrings
.getExistingEntry(Info
.String
),
1029 CU
->getSectionDescriptor(DebugSectionKind::DebugInfo
).StartOffset
+
1032 case DwarfUnit::AccelType::Type
: {
1034 *DebugStrStrings
.getExistingEntry(Info
.String
),
1035 CU
->getSectionDescriptor(DebugSectionKind::DebugInfo
).StartOffset
+
1038 Info
.ObjcClassImplementation
? dwarf::DW_FLAG_type_implementation
1040 Info
.QualifiedNameHash
);
1047 // FIXME: we use AsmPrinter to emit accelerator sections.
1048 // It might be beneficial to directly emit accelerator data
1049 // to the raw_svector_ostream.
1050 SectionDescriptor
&OutSection
=
1051 CommonSections
.getSectionDescriptor(DebugSectionKind::AppleNamespaces
);
1052 DwarfEmitterImpl
Emitter(DWARFLinker::OutputFileType::Object
,
1054 if (Error Err
= Emitter
.init(TargetTriple
, "__DWARF")) {
1055 consumeError(std::move(Err
));
1060 Emitter
.emitAppleNamespaces(AppleNamespaces
);
1063 // Set start offset and size for output section.
1064 OutSection
.setSizesForSectionCreatedByAsmPrinter();
1068 // FIXME: we use AsmPrinter to emit accelerator sections.
1069 // It might be beneficial to directly emit accelerator data
1070 // to the raw_svector_ostream.
1071 SectionDescriptor
&OutSection
=
1072 CommonSections
.getSectionDescriptor(DebugSectionKind::AppleNames
);
1073 DwarfEmitterImpl
Emitter(DWARFLinker::OutputFileType::Object
,
1075 if (Error Err
= Emitter
.init(TargetTriple
, "__DWARF")) {
1076 consumeError(std::move(Err
));
1081 Emitter
.emitAppleNames(AppleNames
);
1084 // Set start offset ans size for output section.
1085 OutSection
.setSizesForSectionCreatedByAsmPrinter();
1089 // FIXME: we use AsmPrinter to emit accelerator sections.
1090 // It might be beneficial to directly emit accelerator data
1091 // to the raw_svector_ostream.
1092 SectionDescriptor
&OutSection
=
1093 CommonSections
.getSectionDescriptor(DebugSectionKind::AppleObjC
);
1094 DwarfEmitterImpl
Emitter(DWARFLinker::OutputFileType::Object
,
1096 if (Error Err
= Emitter
.init(TargetTriple
, "__DWARF")) {
1097 consumeError(std::move(Err
));
1102 Emitter
.emitAppleObjc(AppleObjC
);
1105 // Set start offset ans size for output section.
1106 OutSection
.setSizesForSectionCreatedByAsmPrinter();
1110 // FIXME: we use AsmPrinter to emit accelerator sections.
1111 // It might be beneficial to directly emit accelerator data
1112 // to the raw_svector_ostream.
1113 SectionDescriptor
&OutSection
=
1114 CommonSections
.getSectionDescriptor(DebugSectionKind::AppleTypes
);
1115 DwarfEmitterImpl
Emitter(DWARFLinker::OutputFileType::Object
,
1117 if (Error Err
= Emitter
.init(TargetTriple
, "__DWARF")) {
1118 consumeError(std::move(Err
));
1123 Emitter
.emitAppleTypes(AppleTypes
);
1126 // Set start offset ans size for output section.
1127 OutSection
.setSizesForSectionCreatedByAsmPrinter();
1131 void DWARFLinkerImpl::emitDWARFv5DebugNamesSection(const Triple
&TargetTriple
) {
1132 std::unique_ptr
<DWARF5AccelTable
> DebugNames
;
1134 DebugNamesUnitsOffsets CompUnits
;
1135 CompUnitIDToIdx CUidToIdx
;
1139 forEachCompileUnit([&](CompileUnit
*CU
) {
1140 CompUnits
.push_back(
1141 CU
->getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
)
1143 CUidToIdx
[CU
->getUniqueID()] = Id
++;
1145 CU
->AcceleratorRecords
.forEach([&](const DwarfUnit::AccelInfo
&Info
) {
1146 if (DebugNames
.get() == nullptr)
1147 DebugNames
= std::make_unique
<DWARF5AccelTable
>();
1149 switch (Info
.Type
) {
1150 case DwarfUnit::AccelType::Name
:
1151 case DwarfUnit::AccelType::Namespace
:
1152 case DwarfUnit::AccelType::Type
: {
1153 DebugNames
->addName(*DebugStrStrings
.getExistingEntry(Info
.String
),
1154 Info
.OutOffset
, Info
.Tag
, CU
->getUniqueID());
1158 break; // Nothing to do.
1163 if (DebugNames
.get() != nullptr) {
1164 // FIXME: we use AsmPrinter to emit accelerator sections.
1165 // It might be beneficial to directly emit accelerator data
1166 // to the raw_svector_ostream.
1167 SectionDescriptor
&OutSection
=
1168 CommonSections
.getSectionDescriptor(DebugSectionKind::DebugNames
);
1169 DwarfEmitterImpl
Emitter(DWARFLinker::OutputFileType::Object
,
1171 if (Error Err
= Emitter
.init(TargetTriple
, "__DWARF")) {
1172 consumeError(std::move(Err
));
1177 Emitter
.emitDebugNames(*DebugNames
, CompUnits
, CUidToIdx
);
1180 // Set start offset ans size for output section.
1181 OutSection
.setSizesForSectionCreatedByAsmPrinter();
1185 void DWARFLinkerImpl::cleanupDataAfterDWARFOutputIsWritten() {
1186 GlobalData
.getStringPool().clear();
1187 DebugStrStrings
.clear();
1188 DebugLineStrStrings
.clear();
1191 void DWARFLinkerImpl::writeCompileUnitsToTheOutput() {
1192 bool HasAbbreviations
= false;
1194 // Enumerate all sections and store them into the final emitter.
1195 forEachObjectSectionsSet([&](OutputSections
&Sections
) {
1196 Sections
.forEach([&](SectionDescriptor
&OutSection
) {
1197 if (!HasAbbreviations
&& !OutSection
.getContents().empty() &&
1198 OutSection
.getKind() == DebugSectionKind::DebugAbbrev
)
1199 HasAbbreviations
= true;
1201 // Emit section content.
1202 TheDwarfEmitter
->emitSectionContents(OutSection
.getContents(),
1203 OutSection
.getName());
1204 OutSection
.clearSectionContent();
1208 if (!HasAbbreviations
) {
1209 const SmallVector
<std::unique_ptr
<DIEAbbrev
>> Abbreviations
;
1210 TheDwarfEmitter
->emitAbbrevs(Abbreviations
, 3);
1214 void DWARFLinkerImpl::writeCommonSectionsToTheOutput() {
1215 CommonSections
.forEach([&](SectionDescriptor
&OutSection
) {
1216 // Emit section content.
1217 TheDwarfEmitter
->emitSectionContents(OutSection
.getContents(),
1218 OutSection
.getName());
1219 OutSection
.clearSectionContent();
1223 } // end of namespace dwarflinker_parallel