LLVM 24.0.0git
DWARFLinker.cpp
Go to the documentation of this file.
1//=== DWARFLinker.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
10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/BitVector.h"
12#include "llvm/ADT/STLExtras.h"
30#include "llvm/MC/MCDwarf.h"
32#include "llvm/Support/Error.h"
36#include "llvm/Support/LEB128.h"
37#include "llvm/Support/Path.h"
39#include <vector>
40
41namespace llvm {
42
43using namespace dwarf_linker;
44using namespace dwarf_linker::classic;
45
46/// Hold the input and output of the debug info size in bytes.
51
52/// Compute the total size of the debug info.
54 uint64_t Size = 0;
55 for (auto &Unit : Dwarf.compile_units()) {
56 Size += Unit->getLength();
57 }
58 return Size;
59}
60
61/// Similar to DWARFUnitSection::getUnitForOffset(), but returning our
62/// CompileUnit object instead.
64 auto CU = llvm::upper_bound(
65 Units, Offset, [](uint64_t LHS, const std::unique_ptr<CompileUnit> &RHS) {
66 return LHS < RHS->getOrigUnit().getNextUnitOffset();
67 });
68 return CU != Units.end() ? CU->get() : nullptr;
69}
70
71/// Resolve the DIE attribute reference that has been extracted in \p RefValue.
72/// The resulting DIE might be in another CompileUnit which is stored into \p
73/// ReferencedCU. \returns null if resolving fails for any reason.
74DWARFDie DWARFLinker::resolveDIEReference(const DWARFFile &File,
75 const UnitListTy &Units,
76 const DWARFFormValue &RefValue,
77 const DWARFDie &DIE,
78 CompileUnit *&RefCU) {
79 assert(RefValue.isFormClass(DWARFFormValue::FC_Reference));
80 uint64_t RefOffset;
81 if (std::optional<uint64_t> Off = RefValue.getAsRelativeReference()) {
82 RefOffset = RefValue.getUnit()->getOffset() + *Off;
83 } else if (Off = RefValue.getAsDebugInfoReference(); Off) {
84 RefOffset = *Off;
85 } else {
86 reportWarning("Unsupported reference type", File, &DIE);
87 return DWARFDie();
88 }
89 if ((RefCU = getUnitForOffset(Units, RefOffset)))
90 if (const auto RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset)) {
91 // In a file with broken references, an attribute might point to a NULL
92 // DIE.
93 if (!RefDie.isNULL())
94 return RefDie;
95 }
96
97 reportWarning("could not find referenced DIE", File, &DIE);
98 return DWARFDie();
99}
100
101/// \returns whether the passed \a Attr type might contain a DIE reference
102/// suitable for ODR uniquing.
103static bool isODRAttribute(uint16_t Attr) {
104 switch (Attr) {
105 default:
106 return false;
107 case dwarf::DW_AT_type:
108 case dwarf::DW_AT_containing_type:
109 case dwarf::DW_AT_specification:
110 case dwarf::DW_AT_abstract_origin:
111 case dwarf::DW_AT_import:
112 case dwarf::DW_AT_LLVM_alloc_type:
113 return true;
114 }
115 llvm_unreachable("Improper attribute.");
116}
117
118static bool isTypeTag(uint16_t Tag) {
119 switch (Tag) {
120 case dwarf::DW_TAG_array_type:
121 case dwarf::DW_TAG_class_type:
122 case dwarf::DW_TAG_enumeration_type:
123 case dwarf::DW_TAG_pointer_type:
124 case dwarf::DW_TAG_reference_type:
125 case dwarf::DW_TAG_string_type:
126 case dwarf::DW_TAG_structure_type:
127 case dwarf::DW_TAG_subroutine_type:
128 case dwarf::DW_TAG_template_alias:
129 case dwarf::DW_TAG_typedef:
130 case dwarf::DW_TAG_union_type:
131 case dwarf::DW_TAG_ptr_to_member_type:
132 case dwarf::DW_TAG_set_type:
133 case dwarf::DW_TAG_subrange_type:
134 case dwarf::DW_TAG_base_type:
135 case dwarf::DW_TAG_const_type:
136 case dwarf::DW_TAG_constant:
137 case dwarf::DW_TAG_file_type:
138 case dwarf::DW_TAG_namelist:
139 case dwarf::DW_TAG_packed_type:
140 case dwarf::DW_TAG_volatile_type:
141 case dwarf::DW_TAG_restrict_type:
142 case dwarf::DW_TAG_atomic_type:
143 case dwarf::DW_TAG_interface_type:
144 case dwarf::DW_TAG_unspecified_type:
145 case dwarf::DW_TAG_shared_type:
146 case dwarf::DW_TAG_immutable_type:
147 return true;
148 default:
149 break;
150 }
151 return false;
152}
153
154/// Recurse through the input DIE's canonical references until we find a
155/// DW_AT_name.
157DWARFLinker::DIECloner::getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
158 CompileUnit *Unit) {
159 if (!Die)
160 return {};
161
162 std::optional<DWARFFormValue> Ref;
163
164 auto GetDieName = [](const DWARFDie &D) -> llvm::StringRef {
165 auto NameForm = D.find(llvm::dwarf::DW_AT_name);
166 if (!NameForm)
167 return {};
168
169 auto NameOrErr = NameForm->getAsCString();
170 if (!NameOrErr) {
171 llvm::consumeError(NameOrErr.takeError());
172 return {};
173 }
174
175 return *NameOrErr;
176 };
177
178 llvm::StringRef Name = GetDieName(Die);
179 if (!Name.empty())
180 return Name;
181
182 while (true) {
183 if (!(Ref = Die.find(llvm::dwarf::DW_AT_specification)) &&
184 !(Ref = Die.find(llvm::dwarf::DW_AT_abstract_origin)))
185 break;
186
187 Die = Linker.resolveDIEReference(File, CompileUnits, *Ref, Die, Unit);
188 if (!Die)
189 break;
190
191 assert(Unit);
192
193 unsigned SpecIdx = Unit->getOrigUnit().getDIEIndex(Die);
194 CompileUnit::DIEInfo &SpecInfo = Unit->getInfo(SpecIdx);
195 if (SpecInfo.Ctxt && SpecInfo.Ctxt->hasCanonicalDIE()) {
196 if (!SpecInfo.Ctxt->getCanonicalName().empty()) {
197 Name = SpecInfo.Ctxt->getCanonicalName();
198 break;
199 }
200 }
201
202 Name = GetDieName(Die);
203 if (!Name.empty())
204 break;
205 }
206
207 return Name;
208}
209
210bool DWARFLinker::DIECloner::getDIENames(
211 const DWARFDie &Die, AttributesInfo &Info, OffsetsStringPool &StringPool,
212 const DWARFFile &File, CompileUnit &Unit, bool StripTemplate) {
213 // This function will be called on DIEs having low_pcs and
214 // ranges. As getting the name might be more expansive, filter out
215 // blocks directly.
216 if (Die.getTag() == dwarf::DW_TAG_lexical_block)
217 return false;
218
219 // The mangled name of an specification DIE will by virtue of the
220 // uniquing algorithm be the same as the one it got uniqued into.
221 // So just use the input DIE's linkage name.
222 if (!Info.MangledName)
223 if (const char *MangledName = Die.getLinkageName())
224 Info.MangledName = StringPool.getEntry(MangledName);
225
226 // For subprograms with linkage names, we unique on the linkage name,
227 // so DW_AT_name's may differ between the input and canonical DIEs.
228 // Use the name of the canonical DIE.
229 if (!Info.Name)
230 if (llvm::StringRef Name = getCanonicalDIEName(Die, File, &Unit);
231 !Name.empty())
232 Info.Name = StringPool.getEntry(Name);
233
234 if (!Info.MangledName)
235 Info.MangledName = Info.Name;
236
237 if (StripTemplate && Info.Name && Info.MangledName != Info.Name) {
238 StringRef Name = Info.Name.getString();
239 if (std::optional<StringRef> StrippedName = StripTemplateParameters(Name))
240 Info.NameWithoutTemplate = StringPool.getEntry(*StrippedName);
241 }
242
243 return Info.Name || Info.MangledName;
244}
245
246/// Resolve the relative path to a build artifact referenced by DWARF by
247/// applying DW_AT_comp_dir.
249 sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), ""));
250}
251
252/// Collect references to parseable Swift interfaces in imported
253/// DW_TAG_module blocks.
255 const DWARFDie &DIE, CompileUnit &CU,
256 DWARFLinkerBase::SwiftInterfacesMapTy *ParseableSwiftInterfaces,
257 std::function<void(const Twine &, const DWARFDie &)> ReportWarning) {
258 if (CU.getLanguage() != dwarf::DW_LANG_Swift)
259 return;
260
261 if (!ParseableSwiftInterfaces)
262 return;
263
264 StringRef Path = dwarf::toStringRef(DIE.find(dwarf::DW_AT_LLVM_include_path));
265 if (!Path.ends_with(".swiftinterface"))
266 return;
267 // Don't track interfaces that are part of the SDK.
268 StringRef SysRoot = dwarf::toStringRef(DIE.find(dwarf::DW_AT_LLVM_sysroot));
269 if (SysRoot.empty())
270 SysRoot = CU.getSysRoot();
271 if (!SysRoot.empty() && Path.starts_with(SysRoot))
272 return;
273 // Don't track interfaces that are part of the toolchain.
274 // For example: Swift, _Concurrency, ...
275 StringRef DeveloperDir = guessDeveloperDir(SysRoot);
276 if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))
277 return;
278 if (isInToolchainDir(Path))
279 return;
280 std::optional<const char *> Name =
281 dwarf::toString(DIE.find(dwarf::DW_AT_name));
282 if (!Name)
283 return;
284 auto &Entry = (*ParseableSwiftInterfaces)[*Name];
285 // The prepend path is applied later when copying.
286 DWARFDie CUDie = CU.getOrigUnit().getUnitDIE();
287 SmallString<128> ResolvedPath;
288 if (sys::path::is_relative(Path))
289 resolveRelativeObjectPath(ResolvedPath, CUDie);
290 sys::path::append(ResolvedPath, Path);
291 if (!Entry.empty() && Entry != ResolvedPath)
292 ReportWarning(Twine("Conflicting parseable interfaces for Swift Module ") +
293 *Name + ": " + Entry + " and " + Path,
294 DIE);
295 Entry = std::string(ResolvedPath);
296}
297
298/// The distinct types of work performed by the work loop in
299/// analyzeContextInfo.
305
306/// This class represents an item in the work list. The type defines what kind
307/// of work needs to be performed when processing the current item. Everything
308/// but the Type and Die fields are optional based on the type.
330
331static bool updatePruning(const DWARFDie &Die, CompileUnit &CU,
332 uint64_t ModulesEndOffset) {
333 CompileUnit::DIEInfo &Info = CU.getInfo(Die);
334
335 // Prune this DIE if it is either a forward declaration inside a
336 // DW_TAG_module or a DW_TAG_module that contains nothing but
337 // forward declarations.
338 Info.Prune &= (Die.getTag() == dwarf::DW_TAG_module) ||
339 (isTypeTag(Die.getTag()) &&
340 dwarf::toUnsigned(Die.find(dwarf::DW_AT_declaration), 0));
341
342 // Only prune forward declarations inside a DW_TAG_module for which a
343 // definition exists elsewhere.
344 if (ModulesEndOffset == 0)
345 Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset();
346 else
347 Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() > 0 &&
348 Info.Ctxt->getCanonicalDIEOffset() <= ModulesEndOffset;
349
350 return Info.Prune;
351}
352
353static void updateChildPruning(const DWARFDie &Die, CompileUnit &CU,
354 CompileUnit::DIEInfo &ChildInfo) {
355 CompileUnit::DIEInfo &Info = CU.getInfo(Die);
356 Info.Prune &= ChildInfo.Prune;
357}
358
359/// Recursive helper to build the global DeclContext information and
360/// gather the child->parent relationships in the original compile unit.
361///
362/// This function uses the same work list approach as lookForDIEsToKeep.
363///
364/// \return true when this DIE and all of its children are only
365/// forward declarations to types defined in external clang modules
366/// (i.e., forward declarations that are children of a DW_TAG_module).
368 const DWARFDie &DIE, unsigned ParentIdx, CompileUnit &CU,
369 DeclContext *CurrentDeclContext, DeclContextTree &Contexts,
370 uint64_t ModulesEndOffset,
371 DWARFLinkerBase::SwiftInterfacesMapTy *ParseableSwiftInterfaces,
372 std::function<void(const Twine &, const DWARFDie &)> ReportWarning) {
373 // LIFO work list.
374 std::vector<ContextWorklistItem> Worklist;
375 Worklist.emplace_back(DIE, CurrentDeclContext, ParentIdx, false);
376
377 while (!Worklist.empty()) {
378 ContextWorklistItem Current = Worklist.back();
379 Worklist.pop_back();
380
381 switch (Current.Type) {
383 updatePruning(Current.Die, CU, ModulesEndOffset);
384 continue;
386 updateChildPruning(Current.Die, CU, *Current.OtherInfo);
387 continue;
389 break;
390 }
391
392 unsigned Idx = CU.getOrigUnit().getDIEIndex(Current.Die);
393 CompileUnit::DIEInfo &Info = CU.getInfo(Idx);
394
395 // Clang imposes an ODR on modules(!) regardless of the language:
396 // "The module-id should consist of only a single identifier,
397 // which provides the name of the module being defined. Each
398 // module shall have a single definition."
399 //
400 // This does not extend to the types inside the modules:
401 // "[I]n C, this implies that if two structs are defined in
402 // different submodules with the same name, those two types are
403 // distinct types (but may be compatible types if their
404 // definitions match)."
405 //
406 // We treat non-C++ modules like namespaces for this reason.
407 if (Current.Die.getTag() == dwarf::DW_TAG_module &&
408 Current.ParentIdx == 0 &&
409 dwarf::toString(Current.Die.find(dwarf::DW_AT_name), "") !=
410 CU.getClangModuleName()) {
411 Current.InImportedModule = true;
412 analyzeImportedModule(Current.Die, CU, ParseableSwiftInterfaces,
413 ReportWarning);
414 }
415
416 Info.ParentIdx = Current.ParentIdx;
417 Info.InModuleScope = CU.isClangModule() || Current.InImportedModule;
418 if (CU.hasODR() || Info.InModuleScope) {
419 if (Current.Context) {
420 auto PtrInvalidPair = Contexts.getChildDeclContext(
421 *Current.Context, Current.Die, CU, Info.InModuleScope);
422 Current.Context = PtrInvalidPair.getPointer();
423 Info.Ctxt =
424 PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer();
425 if (Info.Ctxt)
426 Info.Ctxt->setDefinedInClangModule(Info.InModuleScope);
427 } else
428 Info.Ctxt = Current.Context = nullptr;
429 }
430
431 Info.Prune = Current.InImportedModule;
432 // Add children in reverse order to the worklist to effectively process
433 // them in order.
434 Worklist.emplace_back(Current.Die, ContextWorklistItemType::UpdatePruning);
435 for (auto Child : reverse(Current.Die.children())) {
436 CompileUnit::DIEInfo &ChildInfo = CU.getInfo(Child);
437 Worklist.emplace_back(
439 Worklist.emplace_back(Child, Current.Context, Idx,
440 Current.InImportedModule);
441 }
442 }
443}
444
446 switch (Tag) {
447 default:
448 return false;
449 case dwarf::DW_TAG_class_type:
450 case dwarf::DW_TAG_common_block:
451 case dwarf::DW_TAG_enumeration_type:
452 case dwarf::DW_TAG_lexical_block:
453 case dwarf::DW_TAG_structure_type:
454 case dwarf::DW_TAG_subprogram:
455 case dwarf::DW_TAG_subroutine_type:
456 case dwarf::DW_TAG_union_type:
457 return true;
458 }
459 llvm_unreachable("Invalid Tag");
460}
461
462void DWARFLinker::cleanupAuxiliarryData(LinkContext &Context) {
463 Context.clear();
464
465 for (DIEBlock *I : DIEBlocks)
466 I->~DIEBlock();
467 for (DIELoc *I : DIELocs)
468 I->~DIELoc();
469
470 DIEBlocks.clear();
471 DIELocs.clear();
472 DIEAlloc.Reset();
473}
474
476 CompileUnit &Unit, const DWARFDebugLine::LineTable &LT,
477 DenseMap<uint64_t, uint64_t> &SeqOffToOrigRow) {
478 // Collect this unit's DW_AT_LLVM_stmt_sequence attribute values
479 // (input offsets), sorted ascending and deduplicated, to drive the
480 // shared mapping builder.
481 auto StmtAttrs = Unit.getStmtSeqListAttributes();
482 SmallVector<uint64_t> SortedOffsets;
483 SortedOffsets.reserve(StmtAttrs.size());
484 for (const PatchLocation &P : StmtAttrs)
485 SortedOffsets.push_back(P.get());
486 llvm::sort(SortedOffsets);
487 SortedOffsets.erase(llvm::unique(SortedOffsets), SortedOffsets.end());
488
490 SeqOffToOrigRow);
491}
492
493std::pair<bool, std::optional<int64_t>>
494DWARFLinker::getVariableRelocAdjustment(AddressesMap &RelocMgr,
495 const DWARFDie &DIE) {
496 assert((DIE.getTag() == dwarf::DW_TAG_variable ||
497 DIE.getTag() == dwarf::DW_TAG_constant) &&
498 "Wrong type of input die");
499
500 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
501
502 // Check if DIE has DW_AT_location attribute.
503 DWARFUnit *U = DIE.getDwarfUnit();
504 std::optional<uint32_t> LocationIdx =
505 Abbrev->findAttributeIndex(dwarf::DW_AT_location);
506 if (!LocationIdx)
507 return std::make_pair(false, std::nullopt);
508
509 // Get offset to the DW_AT_location attribute.
510 uint64_t AttrOffset =
511 Abbrev->getAttributeOffsetFromIndex(*LocationIdx, DIE.getOffset(), *U);
512
513 // Get value of the DW_AT_location attribute.
514 std::optional<DWARFFormValue> LocationValue =
515 Abbrev->getAttributeValueFromOffset(*LocationIdx, AttrOffset, *U);
516 if (!LocationValue)
517 return std::make_pair(false, std::nullopt);
518
519 // Check that DW_AT_location attribute is of 'exprloc' class.
520 // Handling value of location expressions for attributes of 'loclist'
521 // class is not implemented yet.
522 std::optional<ArrayRef<uint8_t>> Expr = LocationValue->getAsBlock();
523 if (!Expr)
524 return std::make_pair(false, std::nullopt);
525
526 // Parse 'exprloc' expression.
527 DataExtractor Data(*Expr, U->getContext().isLittleEndian());
528 DWARFExpression Expression(Data, U->getAddressByteSize(),
529 U->getFormParams().Format);
530
531 bool HasLocationAddress = false;
532 uint64_t CurExprOffset = 0;
533 for (DWARFExpression::iterator It = Expression.begin();
534 It != Expression.end(); ++It) {
535 DWARFExpression::iterator NextIt = It;
536 ++NextIt;
537
538 const DWARFExpression::Operation &Op = *It;
539 switch (Op.getCode()) {
540 case dwarf::DW_OP_const2u:
541 case dwarf::DW_OP_const4u:
542 case dwarf::DW_OP_const8u:
543 case dwarf::DW_OP_const2s:
544 case dwarf::DW_OP_const4s:
545 case dwarf::DW_OP_const8s:
546 if (NextIt == Expression.end() ||
547 !dwarf::isTlsAddressOp(NextIt->getCode()))
548 break;
549 [[fallthrough]];
550 case dwarf::DW_OP_addr: {
551 HasLocationAddress = true;
552 // Check relocation for the address.
553 if (std::optional<int64_t> RelocAdjustment =
554 RelocMgr.getExprOpAddressRelocAdjustment(
555 *U, Op, AttrOffset + CurExprOffset,
556 AttrOffset + Op.getEndOffset(), Options.Verbose))
557 return std::make_pair(HasLocationAddress, *RelocAdjustment);
558 } break;
559 case dwarf::DW_OP_constx:
560 case dwarf::DW_OP_addrx: {
561 HasLocationAddress = true;
562 if (std::optional<uint64_t> AddressOffset =
563 DIE.getDwarfUnit()->getIndexedAddressOffset(
564 Op.getRawOperand(0))) {
565 // Check relocation for the address.
566 if (std::optional<int64_t> RelocAdjustment =
567 RelocMgr.getExprOpAddressRelocAdjustment(
568 *U, Op, *AddressOffset,
569 *AddressOffset + DIE.getDwarfUnit()->getAddressByteSize(),
570 Options.Verbose))
571 return std::make_pair(HasLocationAddress, *RelocAdjustment);
572 }
573 } break;
574 default: {
575 // Nothing to do.
576 } break;
577 }
578 CurExprOffset = Op.getEndOffset();
579 }
580
581 return std::make_pair(HasLocationAddress, std::nullopt);
582}
583
584/// Check if a variable describing DIE should be kept.
585/// \returns updated TraversalFlags.
586unsigned DWARFLinker::shouldKeepVariableDIE(AddressesMap &RelocMgr,
587 const DWARFDie &DIE,
588 CompileUnit::DIEInfo &MyInfo,
589 unsigned Flags) {
590 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
591
592 // Global variables with constant value can always be kept.
593 if (!(Flags & TF_InFunctionScope) &&
594 Abbrev->findAttributeIndex(dwarf::DW_AT_const_value)) {
595 MyInfo.InDebugMap = true;
596 return Flags | TF_Keep;
597 }
598
599 // See if there is a relocation to a valid debug map entry inside this
600 // variable's location. The order is important here. We want to always check
601 // if the variable has a valid relocation, so that the DIEInfo is filled.
602 // However, we don't want a static variable in a function to force us to keep
603 // the enclosing function, unless requested explicitly.
604 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
605 getVariableRelocAdjustment(RelocMgr, DIE);
606
607 if (LocExprAddrAndRelocAdjustment.first)
608 MyInfo.HasLocationExpressionAddr = true;
609
610 if (!LocExprAddrAndRelocAdjustment.second)
611 return Flags;
612
613 MyInfo.AddrAdjust = *LocExprAddrAndRelocAdjustment.second;
614 MyInfo.InDebugMap = true;
615
616 if (((Flags & TF_InFunctionScope) &&
617 !LLVM_UNLIKELY(Options.KeepFunctionForStatic)))
618 return Flags;
619
620 if (Options.Verbose) {
621 outs() << "Keeping variable DIE:";
622 DIDumpOptions DumpOpts;
623 DumpOpts.ChildRecurseDepth = 0;
624 DumpOpts.Verbose = Options.Verbose;
625 DIE.dump(outs(), 8 /* Indent */, DumpOpts);
626 }
627
628 return Flags | TF_Keep;
629}
630
631/// Check if a function describing DIE should be kept.
632/// \returns updated TraversalFlags.
633unsigned DWARFLinker::shouldKeepSubprogramDIE(
634 AddressesMap &RelocMgr, const DWARFDie &DIE, const DWARFFile &File,
635 CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags) {
636 Flags |= TF_InFunctionScope;
637
638 auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc));
639 if (!LowPc)
640 return Flags;
641
642 assert(LowPc && "low_pc attribute is not an address.");
643 std::optional<int64_t> RelocAdjustment =
644 RelocMgr.getSubprogramRelocAdjustment(DIE, Options.Verbose);
645 if (!RelocAdjustment)
646 return Flags;
647
648 MyInfo.AddrAdjust = *RelocAdjustment;
649 MyInfo.InDebugMap = true;
650
651 if (Options.Verbose) {
652 outs() << "Keeping subprogram DIE:";
653 DIDumpOptions DumpOpts;
654 DumpOpts.ChildRecurseDepth = 0;
655 DumpOpts.Verbose = Options.Verbose;
656 DIE.dump(outs(), 8 /* Indent */, DumpOpts);
657 }
658
659 if (DIE.getTag() == dwarf::DW_TAG_label) {
660 if (Unit.hasLabelAt(*LowPc))
661 return Flags;
662
663 DWARFUnit &OrigUnit = Unit.getOrigUnit();
664 // FIXME: dsymutil-classic compat. dsymutil-classic doesn't consider labels
665 // that don't fall into the CU's aranges. This is wrong IMO. Debug info
666 // generation bugs aside, this is really wrong in the case of labels, where
667 // a label marking the end of a function will have a PC == CU's high_pc.
668 if (dwarf::toAddress(OrigUnit.getUnitDIE().find(dwarf::DW_AT_high_pc))
669 .value_or(UINT64_MAX) <= LowPc)
670 return Flags;
671 // For assembly language files, try to preserve DWARF info by using
672 // function ranges when available, falling back to labels otherwise.
673 if (Unit.getLanguage() == dwarf::DW_LANG_Mips_Assembler ||
674 Unit.getLanguage() == dwarf::DW_LANG_Assembly) {
675 if (auto Range = RelocMgr.getSymbolRangeForAddress(*LowPc)) {
676 Unit.addFunctionRange(Range->LowPC, Range->HighPC, MyInfo.AddrAdjust);
677 } else {
678 Unit.addLabelLowPc(*LowPc, MyInfo.AddrAdjust);
679 }
680 } else {
681 Unit.addLabelLowPc(*LowPc, MyInfo.AddrAdjust);
682 }
683 return Flags | TF_Keep;
684 }
685
686 Flags |= TF_Keep;
687
688 std::optional<uint64_t> HighPc = DIE.getHighPC(*LowPc);
689 if (!HighPc) {
690 reportWarning("Function without high_pc. Range will be discarded.\n", File,
691 &DIE);
692 return Flags;
693 }
694 if (*LowPc > *HighPc) {
695 reportWarning("low_pc greater than high_pc. Range will be discarded.\n",
696 File, &DIE);
697 return Flags;
698 }
699
700 // Replace the debug map range with a more accurate one.
701 Unit.addFunctionRange(
702 *LowPc,
703 RelocMgr.constrainCodeRangeHighPC(*LowPc, *HighPc, MyInfo.AddrAdjust),
704 MyInfo.AddrAdjust);
705 return Flags;
706}
707
708/// Check if a DIE should be kept.
709/// \returns updated TraversalFlags.
710unsigned DWARFLinker::shouldKeepDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
711 const DWARFFile &File, CompileUnit &Unit,
712 CompileUnit::DIEInfo &MyInfo,
713 unsigned Flags) {
714 switch (DIE.getTag()) {
715 case dwarf::DW_TAG_constant:
716 case dwarf::DW_TAG_variable:
717 return shouldKeepVariableDIE(RelocMgr, DIE, MyInfo, Flags);
718 case dwarf::DW_TAG_subprogram:
719 case dwarf::DW_TAG_label:
720 return shouldKeepSubprogramDIE(RelocMgr, DIE, File, Unit, MyInfo, Flags);
721 case dwarf::DW_TAG_base_type:
722 // DWARF Expressions may reference basic types, but scanning them
723 // is expensive. Basic types are tiny, so just keep all of them.
724 case dwarf::DW_TAG_imported_module:
725 case dwarf::DW_TAG_imported_declaration:
726 case dwarf::DW_TAG_imported_unit:
727 // We always want to keep these.
728 return Flags | TF_Keep;
729 default:
730 break;
731 }
732
733 return Flags;
734}
735
736/// Helper that updates the completeness of the current DIE based on the
737/// completeness of one of its children. It depends on the incompleteness of
738/// the children already being computed.
740 CompileUnit::DIEInfo &ChildInfo) {
741 switch (Die.getTag()) {
742 case dwarf::DW_TAG_structure_type:
743 case dwarf::DW_TAG_class_type:
744 case dwarf::DW_TAG_union_type:
745 break;
746 default:
747 return;
748 }
749
750 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Die);
751
752 if (ChildInfo.Incomplete || ChildInfo.Prune)
753 MyInfo.Incomplete = true;
754}
755
756/// Helper that updates the completeness of the current DIE based on the
757/// completeness of the DIEs it references. It depends on the incompleteness of
758/// the referenced DIE already being computed.
760 CompileUnit::DIEInfo &RefInfo) {
761 switch (Die.getTag()) {
762 case dwarf::DW_TAG_typedef:
763 case dwarf::DW_TAG_member:
764 case dwarf::DW_TAG_reference_type:
765 case dwarf::DW_TAG_ptr_to_member_type:
766 case dwarf::DW_TAG_pointer_type:
767 break;
768 default:
769 return;
770 }
771
772 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Die);
773
774 if (MyInfo.Incomplete)
775 return;
776
777 if (RefInfo.Incomplete)
778 MyInfo.Incomplete = true;
779}
780
781/// Look at the children of the given DIE and decide whether they should be
782/// kept.
783void DWARFLinker::lookForChildDIEsToKeep(
784 const DWARFDie &Die, CompileUnit &CU, unsigned Flags,
785 SmallVectorImpl<WorklistItem> &Worklist) {
786 // The TF_ParentWalk flag tells us that we are currently walking up the
787 // parent chain of a required DIE, and we don't want to mark all the children
788 // of the parents as kept (consider for example a DW_TAG_namespace node in
789 // the parent chain). There are however a set of DIE types for which we want
790 // to ignore that directive and still walk their children.
791 if (dieNeedsChildrenToBeMeaningful(Die.getTag()))
792 Flags &= ~DWARFLinker::TF_ParentWalk;
793
794 // We're finished if this DIE has no children or we're walking the parent
795 // chain.
796 if (!Die.hasChildren() || (Flags & DWARFLinker::TF_ParentWalk))
797 return;
798
799 // Add children in reverse order to the worklist to effectively process them
800 // in order.
801 for (auto Child : reverse(Die.children())) {
802 // Add a worklist item before every child to calculate incompleteness right
803 // after the current child is processed.
804 CompileUnit::DIEInfo &ChildInfo = CU.getInfo(Child);
805 Worklist.emplace_back(Die, CU, WorklistItemType::UpdateChildIncompleteness,
806 &ChildInfo);
807 Worklist.emplace_back(Child, CU, Flags);
808 }
809}
810
812 CompileUnit::DIEInfo &Info = CU.getInfo(Die);
813
814 if (!Info.Ctxt || (Die.getTag() == dwarf::DW_TAG_namespace))
815 return false;
816
817 if (!CU.hasODR() && !Info.InModuleScope)
818 return false;
819
820 return !Info.Incomplete && Info.Ctxt != CU.getInfo(Info.ParentIdx).Ctxt;
821}
822
823void DWARFLinker::markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU) {
824 CompileUnit::DIEInfo &Info = CU.getInfo(Die);
825
826 Info.ODRMarkingDone = true;
827 if (Info.Keep && isODRCanonicalCandidate(Die, CU) &&
828 !Info.Ctxt->hasCanonicalDIE())
829 Info.Ctxt->setHasCanonicalDIE();
830}
831
832/// Look at DIEs referenced by the given DIE and decide whether they should be
833/// kept. All DIEs referenced though attributes should be kept.
834void DWARFLinker::lookForRefDIEsToKeep(
835 const DWARFDie &Die, CompileUnit &CU, unsigned Flags,
836 const UnitListTy &Units, const DWARFFile &File,
837 SmallVectorImpl<WorklistItem> &Worklist) {
838 bool UseOdr = (Flags & DWARFLinker::TF_DependencyWalk)
839 ? (Flags & DWARFLinker::TF_ODR)
840 : CU.hasODR();
841 DWARFUnit &Unit = CU.getOrigUnit();
842 DWARFDataExtractor Data = Unit.getDebugInfoExtractor();
843 const auto *Abbrev = Die.getAbbreviationDeclarationPtr();
844 uint64_t Offset = Die.getOffset() + getULEB128Size(Abbrev->getCode());
845
847 for (const auto &AttrSpec : Abbrev->attributes()) {
848 DWARFFormValue Val(AttrSpec.Form);
849 if (!Val.isFormClass(DWARFFormValue::FC_Reference) ||
850 AttrSpec.Attr == dwarf::DW_AT_sibling) {
851 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
852 Unit.getFormParams());
853 continue;
854 }
855
856 Val.extractValue(Data, &Offset, Unit.getFormParams(), &Unit);
857 CompileUnit *ReferencedCU;
858 if (auto RefDie =
859 resolveDIEReference(File, Units, Val, Die, ReferencedCU)) {
860 CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefDie);
861 // If the referenced DIE has a DeclContext that has already been
862 // emitted, then do not keep the one in this CU. We'll link to
863 // the canonical DIE in cloneDieReferenceAttribute.
864 //
865 // FIXME: compatibility with dsymutil-classic. UseODR shouldn't
866 // be necessary and could be advantageously replaced by
867 // ReferencedCU->hasODR() && CU.hasODR().
868 //
869 // FIXME: compatibility with dsymutil-classic. There is no
870 // reason not to unique ref_addr references.
871 if (AttrSpec.Form != dwarf::DW_FORM_ref_addr &&
872 isODRAttribute(AttrSpec.Attr) && Info.Ctxt &&
873 Info.Ctxt->hasCanonicalDIE())
874 continue;
875
876 // Keep a module forward declaration if there is no definition.
877 if (!(isODRAttribute(AttrSpec.Attr) && Info.Ctxt &&
878 Info.Ctxt->hasCanonicalDIE()))
879 Info.Prune = false;
880 ReferencedDIEs.emplace_back(RefDie, *ReferencedCU);
881 }
882 }
883
884 unsigned ODRFlag = UseOdr ? DWARFLinker::TF_ODR : 0;
885
886 // Add referenced DIEs in reverse order to the worklist to effectively
887 // process them in order.
888 for (auto &P : reverse(ReferencedDIEs)) {
889 // Add a worklist item before every child to calculate incompleteness right
890 // after the current child is processed.
891 CompileUnit::DIEInfo &Info = P.second.getInfo(P.first);
892 Worklist.emplace_back(Die, CU, WorklistItemType::UpdateRefIncompleteness,
893 &Info);
894 Worklist.emplace_back(P.first, P.second,
895 DWARFLinker::TF_Keep |
896 DWARFLinker::TF_DependencyWalk | ODRFlag);
897 }
898}
899
900/// Look at the parent of the given DIE and decide whether they should be kept.
901void DWARFLinker::lookForParentDIEsToKeep(
902 unsigned AncestorIdx, CompileUnit &CU, unsigned Flags,
903 SmallVectorImpl<WorklistItem> &Worklist) {
904 // Stop if we encounter an ancestor that's already marked as kept.
905 if (CU.getInfo(AncestorIdx).Keep)
906 return;
907
908 DWARFUnit &Unit = CU.getOrigUnit();
909 DWARFDie ParentDIE = Unit.getDIEAtIndex(AncestorIdx);
910 Worklist.emplace_back(CU.getInfo(AncestorIdx).ParentIdx, CU, Flags);
911 Worklist.emplace_back(ParentDIE, CU, Flags);
912}
913
914/// Recursively walk the \p DIE tree and look for DIEs to keep. Store that
915/// information in \p CU's DIEInfo.
916///
917/// This function is the entry point of the DIE selection algorithm. It is
918/// expected to walk the DIE tree in file order and (though the mediation of
919/// its helper) call hasValidRelocation() on each DIE that might be a 'root
920/// DIE' (See DwarfLinker class comment).
921///
922/// While walking the dependencies of root DIEs, this function is also called,
923/// but during these dependency walks the file order is not respected. The
924/// TF_DependencyWalk flag tells us which kind of traversal we are currently
925/// doing.
926///
927/// The recursive algorithm is implemented iteratively as a work list because
928/// very deep recursion could exhaust the stack for large projects. The work
929/// list acts as a scheduler for different types of work that need to be
930/// performed.
931///
932/// The recursive nature of the algorithm is simulated by running the "main"
933/// algorithm (LookForDIEsToKeep) followed by either looking at more DIEs
934/// (LookForChildDIEsToKeep, LookForRefDIEsToKeep, LookForParentDIEsToKeep) or
935/// fixing up a computed property (UpdateChildIncompleteness,
936/// UpdateRefIncompleteness).
937///
938/// The return value indicates whether the DIE is incomplete.
939void DWARFLinker::lookForDIEsToKeep(AddressesMap &AddressesMap,
940 const UnitListTy &Units,
941 const DWARFDie &Die, const DWARFFile &File,
942 CompileUnit &Cu, unsigned Flags) {
943 // LIFO work list.
945 Worklist.emplace_back(Die, Cu, Flags);
946
947 while (!Worklist.empty()) {
948 WorklistItem Current = Worklist.pop_back_val();
949
950 // Look at the worklist type to decide what kind of work to perform.
951 switch (Current.Type) {
952 case WorklistItemType::UpdateChildIncompleteness:
953 updateChildIncompleteness(Current.Die, Current.CU, *Current.OtherInfo);
954 continue;
955 case WorklistItemType::UpdateRefIncompleteness:
956 updateRefIncompleteness(Current.Die, Current.CU, *Current.OtherInfo);
957 continue;
958 case WorklistItemType::LookForChildDIEsToKeep:
959 lookForChildDIEsToKeep(Current.Die, Current.CU, Current.Flags, Worklist);
960 continue;
961 case WorklistItemType::LookForRefDIEsToKeep:
962 lookForRefDIEsToKeep(Current.Die, Current.CU, Current.Flags, Units, File,
963 Worklist);
964 continue;
965 case WorklistItemType::LookForParentDIEsToKeep:
966 lookForParentDIEsToKeep(Current.AncestorIdx, Current.CU, Current.Flags,
967 Worklist);
968 continue;
969 case WorklistItemType::MarkODRCanonicalDie:
970 markODRCanonicalDie(Current.Die, Current.CU);
971 continue;
972 case WorklistItemType::LookForDIEsToKeep:
973 break;
974 }
975
976 unsigned Idx = Current.CU.getOrigUnit().getDIEIndex(Current.Die);
977 CompileUnit::DIEInfo &MyInfo = Current.CU.getInfo(Idx);
978
979 if (MyInfo.Prune) {
980 // We're walking the dependencies of a module forward declaration that was
981 // kept because there is no definition.
982 if (Current.Flags & TF_DependencyWalk)
983 MyInfo.Prune = false;
984 else
985 continue;
986 }
987
988 // If the Keep flag is set, we are marking a required DIE's dependencies.
989 // If our target is already marked as kept, we're all set.
990 bool AlreadyKept = MyInfo.Keep;
991 if ((Current.Flags & TF_DependencyWalk) && AlreadyKept)
992 continue;
993
994 if (!(Current.Flags & TF_DependencyWalk))
995 Current.Flags = shouldKeepDIE(AddressesMap, Current.Die, File, Current.CU,
996 MyInfo, Current.Flags);
997
998 // We need to mark context for the canonical die in the end of normal
999 // traversing(not TF_DependencyWalk) or after normal traversing if die
1000 // was not marked as kept.
1001 if (!(Current.Flags & TF_DependencyWalk) ||
1002 (MyInfo.ODRMarkingDone && !MyInfo.Keep)) {
1003 if (Current.CU.hasODR() || MyInfo.InModuleScope)
1004 Worklist.emplace_back(Current.Die, Current.CU,
1005 WorklistItemType::MarkODRCanonicalDie);
1006 }
1007
1008 // Finish by looking for child DIEs. Because of the LIFO worklist we need
1009 // to schedule that work before any subsequent items are added to the
1010 // worklist.
1011 Worklist.emplace_back(Current.Die, Current.CU, Current.Flags,
1012 WorklistItemType::LookForChildDIEsToKeep);
1013
1014 if (AlreadyKept || !(Current.Flags & TF_Keep))
1015 continue;
1016
1017 // If it is a newly kept DIE mark it as well as all its dependencies as
1018 // kept.
1019 MyInfo.Keep = true;
1020
1021 // We're looking for incomplete types.
1022 MyInfo.Incomplete =
1023 Current.Die.getTag() != dwarf::DW_TAG_subprogram &&
1024 Current.Die.getTag() != dwarf::DW_TAG_member &&
1025 dwarf::toUnsigned(Current.Die.find(dwarf::DW_AT_declaration), 0);
1026
1027 // After looking at the parent chain, look for referenced DIEs. Because of
1028 // the LIFO worklist we need to schedule that work before any subsequent
1029 // items are added to the worklist.
1030 Worklist.emplace_back(Current.Die, Current.CU, Current.Flags,
1031 WorklistItemType::LookForRefDIEsToKeep);
1032
1033 bool UseOdr = (Current.Flags & TF_DependencyWalk) ? (Current.Flags & TF_ODR)
1034 : Current.CU.hasODR();
1035 unsigned ODRFlag = UseOdr ? TF_ODR : 0;
1036 unsigned ParFlags = TF_ParentWalk | TF_Keep | TF_DependencyWalk | ODRFlag;
1037
1038 // Now schedule the parent walk.
1039 Worklist.emplace_back(MyInfo.ParentIdx, Current.CU, ParFlags);
1040 }
1041}
1042
1043#ifndef NDEBUG
1044/// A broken link in the keep chain. By recording both the parent and the child
1045/// we can show only broken links for DIEs with multiple children.
1051
1052/// Verify the keep chain by looking for DIEs that are kept but who's parent
1053/// isn't.
1055 std::vector<DWARFDie> Worklist;
1056 Worklist.push_back(CU.getOrigUnit().getUnitDIE());
1057
1058 // List of broken links.
1059 std::vector<BrokenLink> BrokenLinks;
1060
1061 while (!Worklist.empty()) {
1062 const DWARFDie Current = Worklist.back();
1063 Worklist.pop_back();
1064
1065 const bool CurrentDieIsKept = CU.getInfo(Current).Keep;
1066
1067 for (DWARFDie Child : reverse(Current.children())) {
1068 Worklist.push_back(Child);
1069
1070 const bool ChildDieIsKept = CU.getInfo(Child).Keep;
1071 if (!CurrentDieIsKept && ChildDieIsKept)
1072 BrokenLinks.emplace_back(Current, Child);
1073 }
1074 }
1075
1076 if (!BrokenLinks.empty()) {
1077 for (BrokenLink Link : BrokenLinks) {
1079 "Found invalid link in keep chain between {0:x} and {1:x}\n",
1080 Link.Parent.getOffset(), Link.Child.getOffset());
1081
1082 errs() << "Parent:";
1083 Link.Parent.dump(errs(), 0, {});
1084 CU.getInfo(Link.Parent).dump();
1085
1086 errs() << "Child:";
1087 Link.Child.dump(errs(), 2, {});
1088 CU.getInfo(Link.Child).dump();
1089 }
1090 report_fatal_error("invalid keep chain");
1091 }
1092}
1093#endif
1094
1095/// Assign an abbreviation number to \p Abbrev.
1096///
1097/// Our DIEs get freed after every DebugMapObject has been processed,
1098/// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to
1099/// the instances hold by the DIEs. When we encounter an abbreviation
1100/// that we don't know, we create a permanent copy of it.
1101void DWARFLinker::assignAbbrev(DIEAbbrev &Abbrev) {
1102 // Check the set for priors.
1103 FoldingSetNodeID ID;
1104 Abbrev.Profile(ID);
1105 FoldingSetInsertToken Token;
1106 DIEAbbrev *InSet = AbbreviationsSet.lookup(ID, Token);
1107
1108 // If it's newly added.
1109 if (InSet) {
1110 // Assign existing abbreviation number.
1111 Abbrev.setNumber(InSet->getNumber());
1112 } else {
1113 // Add to abbreviation list.
1114 Abbreviations.push_back(
1115 std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren()));
1116 for (const auto &Attr : Abbrev.getData())
1117 Abbreviations.back()->AddAttribute(Attr);
1118 AbbreviationsSet.insert(Abbreviations.back().get(), Token);
1119 // Assign the unique abbreviation number.
1120 Abbrev.setNumber(Abbreviations.size());
1121 Abbreviations.back()->setNumber(Abbreviations.size());
1122 }
1123}
1124
1125unsigned DWARFLinker::DIECloner::cloneStringAttribute(DIE &Die,
1126 AttributeSpec AttrSpec,
1127 const DWARFFormValue &Val,
1128 const DWARFUnit &U,
1129 AttributesInfo &Info) {
1130 std::optional<const char *> String = dwarf::toString(Val);
1131 if (!String)
1132 return 0;
1133 DwarfStringPoolEntryRef StringEntry;
1134 if (AttrSpec.Form == dwarf::DW_FORM_line_strp) {
1135 StringEntry = DebugLineStrPool.getEntry(*String);
1136 } else {
1137 StringEntry = DebugStrPool.getEntry(*String);
1138
1139 if (AttrSpec.Attr == dwarf::DW_AT_APPLE_origin) {
1140 Info.HasAppleOrigin = true;
1141 if (std::optional<StringRef> FileName =
1142 ObjFile.Addresses->getLibraryInstallName()) {
1143 StringEntry = DebugStrPool.getEntry(*FileName);
1144 }
1145 }
1146
1147 // Update attributes info.
1148 if (AttrSpec.Attr == dwarf::DW_AT_name)
1149 Info.Name = StringEntry;
1150 else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name ||
1151 AttrSpec.Attr == dwarf::DW_AT_linkage_name)
1152 Info.MangledName = StringEntry;
1153 if (U.getVersion() >= 5) {
1154 // Switch everything to DW_FORM_strx strings.
1155 auto StringOffsetIndex =
1156 StringOffsetPool.getValueIndex(StringEntry.getOffset());
1157 return Die
1158 .addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1159 dwarf::DW_FORM_strx, DIEInteger(StringOffsetIndex))
1160 ->sizeOf(U.getFormParams());
1161 }
1162 // Switch everything to out of line strings.
1163 AttrSpec.Form = dwarf::DW_FORM_strp;
1164 }
1165 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), AttrSpec.Form,
1166 DIEInteger(StringEntry.getOffset()));
1167 return 4;
1168}
1169
1170unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute(
1171 DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec,
1172 unsigned AttrSize, const DWARFFormValue &Val, const DWARFFile &File,
1173 CompileUnit &Unit) {
1174 const DWARFUnit &U = Unit.getOrigUnit();
1175 uint64_t Ref;
1176 if (std::optional<uint64_t> Off = Val.getAsRelativeReference())
1177 Ref = Val.getUnit()->getOffset() + *Off;
1178 else if (Off = Val.getAsDebugInfoReference(); Off)
1179 Ref = *Off;
1180 else
1181 return 0;
1182
1183 DIE *NewRefDie = nullptr;
1184 CompileUnit *RefUnit = nullptr;
1185
1186 DWARFDie RefDie =
1187 Linker.resolveDIEReference(File, CompileUnits, Val, InputDIE, RefUnit);
1188
1189 // If the referenced DIE is not found, drop the attribute.
1190 if (!RefDie || AttrSpec.Attr == dwarf::DW_AT_sibling)
1191 return 0;
1192
1193 CompileUnit::DIEInfo &RefInfo = RefUnit->getInfo(RefDie);
1194
1195 // If we already have emitted an equivalent DeclContext, just point
1196 // at it.
1197 if (isODRAttribute(AttrSpec.Attr) && RefInfo.Ctxt &&
1198 RefInfo.Ctxt->getCanonicalDIEOffset()) {
1199 assert(RefInfo.Ctxt->hasCanonicalDIE() &&
1200 "Offset to canonical die is set, but context is not marked");
1201 DIEInteger Attr(RefInfo.Ctxt->getCanonicalDIEOffset());
1202 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1203 dwarf::DW_FORM_ref_addr, Attr);
1204 return U.getRefAddrByteSize();
1205 }
1206
1207 if (!RefInfo.Clone) {
1208 // We haven't cloned this DIE yet. Just create an empty one and
1209 // store it. It'll get really cloned when we process it.
1210 RefInfo.UnclonedReference = true;
1211 RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie.getTag()));
1212 }
1213 NewRefDie = RefInfo.Clone;
1214
1215 if (AttrSpec.Form == dwarf::DW_FORM_ref_addr ||
1216 (Unit.hasODR() && isODRAttribute(AttrSpec.Attr))) {
1217 if (Ref < InputDIE.getOffset() && !RefInfo.UnclonedReference) {
1218 // Backward reference: the target DIE is already cloned and
1219 // parented in a unit tree, so DIEEntry can resolve the
1220 // absolute offset at emission time.
1221 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1222 dwarf::DW_FORM_ref_addr, DIEEntry(*NewRefDie));
1223 } else {
1224 // Forward reference: the target DIE may be a placeholder that
1225 // never gets adopted into a unit tree (e.g. due to ODR
1226 // pruning), so DIEEntry cannot safely resolve it. Use a
1227 // placeholder integer and fix it up after all units are cloned.
1228 Unit.noteForwardReference(
1229 NewRefDie, RefUnit, RefInfo.Ctxt,
1230 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1231 dwarf::DW_FORM_ref_addr, DIEInteger(UINT64_MAX)));
1232 }
1233 return U.getRefAddrByteSize();
1234 }
1235
1236 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1237 dwarf::Form(AttrSpec.Form), DIEEntry(*NewRefDie));
1238
1239 return AttrSize;
1240}
1241
1242void DWARFLinker::DIECloner::cloneExpression(
1243 DataExtractor &Data, DWARFExpression Expression, const DWARFFile &File,
1244 CompileUnit &Unit, SmallVectorImpl<uint8_t> &OutputBuffer,
1245 int64_t AddrRelocAdjustment, bool IsLittleEndian) {
1246 using Encoding = DWARFExpression::Operation::Encoding;
1247
1248 uint8_t OrigAddressByteSize = Unit.getOrigUnit().getAddressByteSize();
1249
1250 uint64_t OpOffset = 0;
1251 for (auto &Op : Expression) {
1252 if (Op.isError()) {
1253 // The operation could not be decoded, so neither it nor anything after
1254 // it can be located. Its end offset is the offset it started at, so the
1255 // slice copied below would be empty and the rest of the expression
1256 // would be silently dropped. Preserve the remaining bytes instead.
1257 Linker.reportWarning(
1258 "cannot decode a DW_OP, copying the rest of the expression "
1259 "unmodified.",
1260 File);
1261 StringRef Bytes = Data.getData().substr(OpOffset);
1262 OutputBuffer.append(Bytes.begin(), Bytes.end());
1263 return;
1264 }
1265 auto Desc = Op.getDescription();
1266 // DW_OP_const_type is variable-length and has 3
1267 // operands. Thus far we only support 2.
1268 if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1269 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1270 Desc.Op[0] != Encoding::Size1))
1271 Linker.reportWarning("Unsupported DW_OP encoding.", File);
1272
1273 if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1274 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1275 Desc.Op[0] == Encoding::Size1)) {
1276 // This code assumes that the other non-typeref operand fits into 1 byte.
1277 assert(OpOffset < Op.getEndOffset());
1278 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;
1279 assert(ULEBsize <= 16);
1280
1281 // Copy over the operation.
1282 assert(!Op.getSubCode() && "SubOps not yet supported");
1283 OutputBuffer.push_back(Op.getCode());
1284 uint64_t RefOffset;
1285 if (Desc.Op.size() == 1) {
1286 RefOffset = Op.getRawOperand(0);
1287 } else {
1288 OutputBuffer.push_back(Op.getRawOperand(0));
1289 RefOffset = Op.getRawOperand(1);
1290 }
1291 uint32_t Offset = 0;
1292 // Look up the base type. For DW_OP_convert, the operand may be 0 to
1293 // instead indicate the generic type. The same holds for
1294 // DW_OP_reinterpret, which is currently not supported.
1295 if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {
1296 RefOffset += Unit.getOrigUnit().getOffset();
1297 auto RefDie = Unit.getOrigUnit().getDIEForOffset(RefOffset);
1298 CompileUnit::DIEInfo &Info = Unit.getInfo(RefDie);
1299 if (DIE *Clone = Info.Clone)
1300 Offset = Clone->getOffset();
1301 else
1302 Linker.reportWarning(
1303 "base type ref doesn't point to DW_TAG_base_type.", File);
1304 }
1305 uint8_t ULEB[16];
1306 unsigned RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
1307 if (RealSize > ULEBsize) {
1308 // Emit the generic type as a fallback.
1309 RealSize = encodeULEB128(0, ULEB, ULEBsize);
1310 Linker.reportWarning("base type ref doesn't fit.", File);
1311 }
1312 assert(RealSize == ULEBsize && "padding failed");
1313 ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
1314 OutputBuffer.append(ULEBbytes.begin(), ULEBbytes.end());
1315 } else if (!Linker.Options.Update && Op.getCode() == dwarf::DW_OP_addrx) {
1316 if (std::optional<object::SectionedAddress> SA =
1317 Unit.getOrigUnit().getAddrOffsetSectionItem(
1318 Op.getRawOperand(0))) {
1319 // DWARFLinker does not use addrx forms since it generates relocated
1320 // addresses. Replace DW_OP_addrx with DW_OP_addr here.
1321 // Argument of DW_OP_addrx should be relocated here as it is not
1322 // processed by applyValidRelocs.
1323 OutputBuffer.push_back(dwarf::DW_OP_addr);
1324 uint64_t LinkedAddress =
1325 SA->Address +
1326 File.Addresses
1327 ->getAddrIndexRelocAdjustment(Unit.getOrigUnit(), Op,
1328 Linker.Options.Verbose)
1329 .value_or(AddrRelocAdjustment);
1330 if (IsLittleEndian != sys::IsLittleEndianHost)
1331 sys::swapByteOrder(LinkedAddress);
1332 ArrayRef<uint8_t> AddressBytes(
1333 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1334 OrigAddressByteSize);
1335 OutputBuffer.append(AddressBytes.begin(), AddressBytes.end());
1336 } else
1337 Linker.reportWarning("cannot read DW_OP_addrx operand.", File);
1338 } else if (!Linker.Options.Update && Op.getCode() == dwarf::DW_OP_constx) {
1339 if (std::optional<object::SectionedAddress> SA =
1340 Unit.getOrigUnit().getAddrOffsetSectionItem(
1341 Op.getRawOperand(0))) {
1342 // DWARFLinker does not use constx forms since it generates relocated
1343 // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1344 // Argument of DW_OP_constx should be relocated here as it is not
1345 // processed by applyValidRelocs.
1346 std::optional<uint8_t> OutOperandKind;
1347 switch (OrigAddressByteSize) {
1348 case 4:
1349 OutOperandKind = dwarf::DW_OP_const4u;
1350 break;
1351 case 8:
1352 OutOperandKind = dwarf::DW_OP_const8u;
1353 break;
1354 default:
1355 Linker.reportWarning(
1356 formatv(("unsupported address size: {0}."), OrigAddressByteSize),
1357 File);
1358 break;
1359 }
1360
1361 if (OutOperandKind) {
1362 OutputBuffer.push_back(*OutOperandKind);
1363 uint64_t LinkedAddress =
1364 SA->Address +
1365 File.Addresses
1366 ->getAddrIndexRelocAdjustment(Unit.getOrigUnit(), Op,
1367 Linker.Options.Verbose)
1368 .value_or(AddrRelocAdjustment);
1369 if (IsLittleEndian != sys::IsLittleEndianHost)
1370 sys::swapByteOrder(LinkedAddress);
1371 ArrayRef<uint8_t> AddressBytes(
1372 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1373 OrigAddressByteSize);
1374 OutputBuffer.append(AddressBytes.begin(), AddressBytes.end());
1375 }
1376 } else
1377 Linker.reportWarning("cannot read DW_OP_constx operand.", File);
1378 } else {
1379 // Copy over everything else unmodified.
1380 StringRef Bytes = Data.getData().slice(OpOffset, Op.getEndOffset());
1381 OutputBuffer.append(Bytes.begin(), Bytes.end());
1382 }
1383 OpOffset = Op.getEndOffset();
1384 }
1385}
1386
1387unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
1388 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File,
1389 CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
1390 bool IsLittleEndian) {
1391 DIEValueList *Attr;
1392 DIEValue Value;
1393 DIELoc *Loc = nullptr;
1394 DIEBlock *Block = nullptr;
1395 if (AttrSpec.Form == dwarf::DW_FORM_exprloc) {
1396 Loc = new (DIEAlloc) DIELoc;
1397 Linker.DIELocs.push_back(Loc);
1398 } else {
1399 Block = new (DIEAlloc) DIEBlock;
1400 Linker.DIEBlocks.push_back(Block);
1401 }
1402 Attr = Loc ? static_cast<DIEValueList *>(Loc)
1403 : static_cast<DIEValueList *>(Block);
1404
1405 DWARFUnit &OrigUnit = Unit.getOrigUnit();
1406 // If the block is a DWARF Expression, clone it into the temporary
1407 // buffer using cloneExpression(), otherwise copy the data directly.
1408 SmallVector<uint8_t, 32> Buffer;
1409 ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
1410 if (DWARFAttribute::mayHaveLocationExpr(AttrSpec.Attr) &&
1411 (Val.isFormClass(DWARFFormValue::FC_Block) ||
1412 Val.isFormClass(DWARFFormValue::FC_Exprloc))) {
1413 DataExtractor Data(Bytes, IsLittleEndian);
1414 DWARFExpression Expr(Data, OrigUnit.getAddressByteSize(),
1415 OrigUnit.getFormParams().Format);
1416 cloneExpression(Data, Expr, File, Unit, Buffer,
1417 Unit.getInfo(InputDIE).AddrAdjust, IsLittleEndian);
1418 Bytes = Buffer;
1419 }
1420 for (auto Byte : Bytes)
1421 Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0),
1422 dwarf::DW_FORM_data1, DIEInteger(Byte));
1423
1424 // FIXME: If DIEBlock and DIELoc just reuses the Size field of
1425 // the DIE class, this "if" could be replaced by
1426 // Attr->setSize(Bytes.size()).
1427 if (Loc)
1428 Loc->setSize(Bytes.size());
1429 else
1430 Block->setSize(Bytes.size());
1431
1432 if (Loc)
1433 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
1434 dwarf::Form(AttrSpec.Form), Loc);
1435 else {
1436 // The expression location data might be updated and exceed the original
1437 // size. Check whether the new data fits into the original form.
1438 if ((AttrSpec.Form == dwarf::DW_FORM_block1 &&
1439 (Bytes.size() > UINT8_MAX)) ||
1440 (AttrSpec.Form == dwarf::DW_FORM_block2 &&
1441 (Bytes.size() > UINT16_MAX)) ||
1442 (AttrSpec.Form == dwarf::DW_FORM_block4 && (Bytes.size() > UINT32_MAX)))
1443 AttrSpec.Form = dwarf::DW_FORM_block;
1444
1445 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
1446 dwarf::Form(AttrSpec.Form), Block);
1447 }
1448
1449 return Die.addValue(DIEAlloc, Value)->sizeOf(OrigUnit.getFormParams());
1450}
1451
1452/// Returns \p InputDIE's DW_AT_high_pc value \p HighPC, constrained so the code
1453/// range it ends stays clear of the symbol the linker places next. \p IsLength
1454/// tells whether high_pc is encoded as a length rather than an address, and
1455/// \p PCOffset is the amount the range shifts by in the output.
1456///
1457/// A scope nested in a function inherits the overrun of the function, so it is
1458/// constrained as well.
1459static uint64_t constrainHighPC(const DWARFDie &InputDIE, uint64_t HighPC,
1460 bool IsLength, int64_t PCOffset,
1461 AddressesMap &Addresses) {
1462 std::optional<uint64_t> LowPC =
1463 dwarf::toAddress(InputDIE.find(dwarf::DW_AT_low_pc));
1464 if (!LowPC)
1465 return HighPC;
1466 uint64_t Constrained = Addresses.constrainCodeRangeHighPC(
1467 *LowPC, IsLength ? *LowPC + HighPC : HighPC, PCOffset);
1468 return IsLength ? Constrained - *LowPC : Constrained;
1469}
1470
1471unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
1472 DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec,
1473 unsigned AttrSize, const DWARFFormValue &Val, const CompileUnit &Unit,
1474 AttributesInfo &Info) {
1475 if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
1476 Info.HasLowPc = true;
1477
1478 if (LLVM_UNLIKELY(Linker.Options.Update)) {
1479 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1480 dwarf::Form(AttrSpec.Form), DIEInteger(Val.getRawUValue()));
1481 return AttrSize;
1482 }
1483
1484 // Cloned Die may have address attributes relocated to a
1485 // totally unrelated value. This can happen:
1486 // - If high_pc is an address (Dwarf version == 2), then it might have been
1487 // relocated to a totally unrelated value (because the end address in the
1488 // object file might be start address of another function which got moved
1489 // independently by the linker).
1490 // - If address relocated in an inline_subprogram that happens at the
1491 // beginning of its inlining function.
1492 // To avoid above cases and to not apply relocation twice (in
1493 // applyValidRelocs and here), read address attribute from InputDIE and apply
1494 // Info.PCOffset here.
1495
1496 std::optional<DWARFFormValue> AddrAttribute = InputDIE.find(AttrSpec.Attr);
1497 if (!AddrAttribute)
1498 llvm_unreachable("Cann't find attribute.");
1499
1500 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
1501 if (!Addr) {
1502 Linker.reportWarning("Cann't read address attribute value.", ObjFile);
1503 return 0;
1504 }
1505
1506 if (InputDIE.getTag() == dwarf::DW_TAG_compile_unit &&
1507 AttrSpec.Attr == dwarf::DW_AT_low_pc) {
1508 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
1509 Addr = *LowPC;
1510 else
1511 return 0;
1512 } else if (InputDIE.getTag() == dwarf::DW_TAG_compile_unit &&
1513 AttrSpec.Attr == dwarf::DW_AT_high_pc) {
1514 if (uint64_t HighPc = Unit.getHighPc())
1515 Addr = HighPc;
1516 else
1517 return 0;
1518 } else {
1519 if (AttrSpec.Attr == dwarf::DW_AT_high_pc)
1520 Addr = constrainHighPC(InputDIE, *Addr, /*IsLength=*/false, Info.PCOffset,
1521 *ObjFile.Addresses);
1522 *Addr += Info.PCOffset;
1523 }
1524
1525 if (AttrSpec.Form == dwarf::DW_FORM_addr) {
1526 Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr),
1527 AttrSpec.Form, DIEInteger(*Addr));
1528 return Unit.getOrigUnit().getAddressByteSize();
1529 }
1530
1531 auto AddrIndex = AddrPool.getValueIndex(*Addr);
1532
1533 return Die
1534 .addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr),
1535 dwarf::Form::DW_FORM_addrx, DIEInteger(AddrIndex))
1536 ->sizeOf(Unit.getOrigUnit().getFormParams());
1537}
1538
1539unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
1540 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File,
1541 CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
1542 unsigned AttrSize, AttributesInfo &Info) {
1544
1545 // We don't emit any skeleton CUs with dsymutil. So avoid emitting
1546 // a redundant DW_AT_GNU_dwo_id on the non-skeleton CU.
1547 if (AttrSpec.Attr == dwarf::DW_AT_GNU_dwo_id ||
1548 AttrSpec.Attr == dwarf::DW_AT_dwo_id)
1549 return 0;
1550
1551 // Check for the offset to the macro table. If offset is incorrect then we
1552 // need to remove the attribute.
1553 if (AttrSpec.Attr == dwarf::DW_AT_macro_info) {
1554 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
1555 const llvm::DWARFDebugMacro *Macro = File.Dwarf->getDebugMacinfo();
1556 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
1557 return 0;
1558 }
1559 }
1560
1561 if (AttrSpec.Attr == dwarf::DW_AT_macros) {
1562 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
1563 const llvm::DWARFDebugMacro *Macro = File.Dwarf->getDebugMacro();
1564 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
1565 return 0;
1566 }
1567 }
1568
1569 if (AttrSpec.Attr == dwarf::DW_AT_str_offsets_base) {
1570 // DWARFLinker generates common .debug_str_offsets table used for all
1571 // compile units. The offset to the common .debug_str_offsets table is 8 on
1572 // DWARF32.
1573 Info.AttrStrOffsetBaseSeen = true;
1574 return Die
1575 .addValue(DIEAlloc, dwarf::DW_AT_str_offsets_base,
1576 dwarf::DW_FORM_sec_offset, DIEInteger(8))
1577 ->sizeOf(Unit.getOrigUnit().getFormParams());
1578 }
1579
1580 if (AttrSpec.Attr == dwarf::DW_AT_LLVM_stmt_sequence) {
1581 // If needed, we'll patch this sec_offset later with the correct offset.
1582 auto Patch = Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1583 dwarf::DW_FORM_sec_offset,
1584 DIEInteger(*Val.getAsSectionOffset()));
1585
1586 // Record this patch location so that it can be fixed up later.
1587 Unit.noteStmtSeqListAttribute(Patch);
1588
1589 return Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
1590 }
1591
1592 if (LLVM_UNLIKELY(Linker.Options.Update)) {
1593 if (auto OptionalValue = Val.getAsUnsignedConstant())
1594 Value = *OptionalValue;
1595 else if (auto OptionalValue = Val.getAsSignedConstant())
1596 Value = *OptionalValue;
1597 else if (auto OptionalValue = Val.getAsSectionOffset())
1598 Value = *OptionalValue;
1599 else {
1600 Linker.reportWarning(
1601 "Unsupported scalar attribute form. Dropping attribute.", File,
1602 &InputDIE);
1603 return 0;
1604 }
1605 if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
1606 Info.IsDeclaration = true;
1607
1608 if (AttrSpec.Form == dwarf::DW_FORM_loclistx)
1609 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1610 dwarf::Form(AttrSpec.Form), DIELocList(Value));
1611 else
1612 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1613 dwarf::Form(AttrSpec.Form), DIEInteger(Value));
1614 return AttrSize;
1615 }
1616
1617 [[maybe_unused]] dwarf::Form OriginalForm = AttrSpec.Form;
1618 if (AttrSpec.Form == dwarf::DW_FORM_rnglistx) {
1619 // DWARFLinker does not generate .debug_addr table. Thus we need to change
1620 // all "addrx" related forms to "addr" version. Change DW_FORM_rnglistx
1621 // to DW_FORM_sec_offset here.
1622 std::optional<uint64_t> Index = Val.getAsSectionOffset();
1623 if (!Index) {
1624 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1625 &InputDIE);
1626 return 0;
1627 }
1628 std::optional<uint64_t> Offset =
1629 Unit.getOrigUnit().getRnglistOffset(*Index);
1630 if (!Offset) {
1631 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1632 &InputDIE);
1633 return 0;
1634 }
1635
1636 Value = *Offset;
1637 AttrSpec.Form = dwarf::DW_FORM_sec_offset;
1638 AttrSize = Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
1639 } else if (AttrSpec.Form == dwarf::DW_FORM_loclistx) {
1640 // DWARFLinker does not generate .debug_addr table. Thus we need to change
1641 // all "addrx" related forms to "addr" version. Change DW_FORM_loclistx
1642 // to DW_FORM_sec_offset here.
1643 std::optional<uint64_t> Index = Val.getAsSectionOffset();
1644 if (!Index) {
1645 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1646 &InputDIE);
1647 return 0;
1648 }
1649 std::optional<uint64_t> Offset =
1650 Unit.getOrigUnit().getLoclistOffset(*Index);
1651 if (!Offset) {
1652 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1653 &InputDIE);
1654 return 0;
1655 }
1656
1657 Value = *Offset;
1658 AttrSpec.Form = dwarf::DW_FORM_sec_offset;
1659 AttrSize = Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
1660 } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
1661 Die.getTag() == dwarf::DW_TAG_compile_unit) {
1662 std::optional<uint64_t> LowPC = Unit.getLowPc();
1663 if (!LowPC)
1664 return 0;
1665 // Dwarf >= 4 high_pc is an size, not an address.
1666 Value = Unit.getHighPc() - *LowPC;
1667 } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
1668 Value = *Val.getAsSectionOffset();
1669 else if (AttrSpec.Form == dwarf::DW_FORM_sdata)
1670 Value = *Val.getAsSignedConstant();
1671 else if (auto OptionalValue = Val.getAsUnsignedConstant())
1672 Value = *OptionalValue;
1673 else {
1674 Linker.reportWarning(
1675 "Unsupported scalar attribute form. Dropping attribute.", File,
1676 &InputDIE);
1677 return 0;
1678 }
1679
1680 // A compile unit's high_pc comes from the unit's own linked range and spans
1681 // every symbol in it.
1682 if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
1683 Die.getTag() != dwarf::DW_TAG_compile_unit)
1684 Value = constrainHighPC(InputDIE, Value, /*IsLength=*/true, Info.PCOffset,
1685 *File.Addresses);
1686
1687 DIE::value_iterator Patch =
1688 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1689 dwarf::Form(AttrSpec.Form), DIEInteger(Value));
1690 if (AttrSpec.Attr == dwarf::DW_AT_ranges ||
1691 AttrSpec.Attr == dwarf::DW_AT_start_scope) {
1692 Unit.noteRangeAttribute(Die, Patch);
1693 Info.HasRanges = true;
1694 } else if (DWARFAttribute::mayHaveLocationList(AttrSpec.Attr) &&
1695 dwarf::doesFormBelongToClass(AttrSpec.Form,
1697 Unit.getOrigUnit().getVersion())) {
1698
1699 CompileUnit::DIEInfo &LocationDieInfo = Unit.getInfo(InputDIE);
1700 Unit.noteLocationAttribute({Patch, LocationDieInfo.InDebugMap
1701 ? LocationDieInfo.AddrAdjust
1702 : Info.PCOffset});
1703 } else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
1704 Info.IsDeclaration = true;
1705
1706 // check that all dwarf::DW_FORM_rnglistx are handled previously.
1707 assert((Info.HasRanges || (OriginalForm != dwarf::DW_FORM_rnglistx)) &&
1708 "Unhandled DW_FORM_rnglistx attribute");
1709
1710 return AttrSize;
1711}
1712
1713/// Clone \p InputDIE's attribute described by \p AttrSpec with
1714/// value \p Val, and add it to \p Die.
1715/// \returns the size of the cloned attribute.
1716unsigned DWARFLinker::DIECloner::cloneAttribute(
1717 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File,
1718 CompileUnit &Unit, const DWARFFormValue &Val, const AttributeSpec AttrSpec,
1719 unsigned AttrSize, AttributesInfo &Info, bool IsLittleEndian) {
1720 const DWARFUnit &U = Unit.getOrigUnit();
1721
1722 switch (AttrSpec.Form) {
1723 case dwarf::DW_FORM_strp:
1724 case dwarf::DW_FORM_line_strp:
1725 case dwarf::DW_FORM_string:
1726 case dwarf::DW_FORM_strx:
1727 case dwarf::DW_FORM_strx1:
1728 case dwarf::DW_FORM_strx2:
1729 case dwarf::DW_FORM_strx3:
1730 case dwarf::DW_FORM_strx4:
1731 return cloneStringAttribute(Die, AttrSpec, Val, U, Info);
1732 case dwarf::DW_FORM_ref_addr:
1733 case dwarf::DW_FORM_ref1:
1734 case dwarf::DW_FORM_ref2:
1735 case dwarf::DW_FORM_ref4:
1736 case dwarf::DW_FORM_ref8:
1737 return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val,
1738 File, Unit);
1739 case dwarf::DW_FORM_block:
1740 case dwarf::DW_FORM_block1:
1741 case dwarf::DW_FORM_block2:
1742 case dwarf::DW_FORM_block4:
1743 case dwarf::DW_FORM_exprloc:
1744 return cloneBlockAttribute(Die, InputDIE, File, Unit, AttrSpec, Val,
1745 IsLittleEndian);
1746 case dwarf::DW_FORM_addr:
1747 case dwarf::DW_FORM_addrx:
1748 case dwarf::DW_FORM_addrx1:
1749 case dwarf::DW_FORM_addrx2:
1750 case dwarf::DW_FORM_addrx3:
1751 case dwarf::DW_FORM_addrx4:
1752 return cloneAddressAttribute(Die, InputDIE, AttrSpec, AttrSize, Val, Unit,
1753 Info);
1754 case dwarf::DW_FORM_data1:
1755 case dwarf::DW_FORM_data2:
1756 case dwarf::DW_FORM_data4:
1757 case dwarf::DW_FORM_data8:
1758 case dwarf::DW_FORM_udata:
1759 case dwarf::DW_FORM_sdata:
1760 case dwarf::DW_FORM_sec_offset:
1761 case dwarf::DW_FORM_flag:
1762 case dwarf::DW_FORM_flag_present:
1763 case dwarf::DW_FORM_rnglistx:
1764 case dwarf::DW_FORM_loclistx:
1765 case dwarf::DW_FORM_implicit_const:
1766 return cloneScalarAttribute(Die, InputDIE, File, Unit, AttrSpec, Val,
1767 AttrSize, Info);
1768 default:
1769 Linker.reportWarning("Unsupported attribute form " +
1770 dwarf::FormEncodingString(AttrSpec.Form) +
1771 " in cloneAttribute. Dropping.",
1772 File, &InputDIE);
1773 }
1774
1775 return 0;
1776}
1777
1778void DWARFLinker::DIECloner::addObjCAccelerator(CompileUnit &Unit,
1779 const DIE *Die,
1780 DwarfStringPoolEntryRef Name,
1781 OffsetsStringPool &StringPool,
1782 bool SkipPubSection) {
1783 std::optional<ObjCSelectorNames> Names =
1784 getObjCNamesIfSelector(Name.getString());
1785 if (!Names)
1786 return;
1787 Unit.addNameAccelerator(Die, StringPool.getEntry(Names->Selector),
1788 SkipPubSection);
1789 Unit.addObjCAccelerator(Die, StringPool.getEntry(Names->ClassName),
1790 SkipPubSection);
1791 if (Names->ClassNameNoCategory)
1792 Unit.addObjCAccelerator(
1793 Die, StringPool.getEntry(*Names->ClassNameNoCategory), SkipPubSection);
1794 if (Names->MethodNameNoCategory)
1795 Unit.addNameAccelerator(
1796 Die, StringPool.getEntry(*Names->MethodNameNoCategory), SkipPubSection);
1797}
1798
1799static bool
1802 bool SkipPC) {
1803 switch (AttrSpec.Attr) {
1804 default:
1805 return false;
1806 case dwarf::DW_AT_low_pc:
1807 case dwarf::DW_AT_high_pc:
1808 case dwarf::DW_AT_ranges:
1809 return !Update && SkipPC;
1810 case dwarf::DW_AT_rnglists_base:
1811 // In case !Update the .debug_addr table is not generated/preserved.
1812 // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used.
1813 // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
1814 // DW_AT_rnglists_base is removed.
1815 return !Update;
1816 case dwarf::DW_AT_loclists_base:
1817 // In case !Update the .debug_addr table is not generated/preserved.
1818 // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
1819 // Since DW_AT_loclists_base is used for only DW_FORM_loclistx the
1820 // DW_AT_loclists_base is removed.
1821 return !Update;
1822 case dwarf::DW_AT_location:
1823 case dwarf::DW_AT_frame_base:
1824 return !Update && SkipPC;
1825 }
1826}
1827
1833
1834DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
1835 const DWARFFile &File, CompileUnit &Unit,
1836 int64_t PCOffset, uint32_t OutOffset,
1837 unsigned Flags, bool IsLittleEndian,
1838 DIE *Die) {
1839 DWARFUnit &U = Unit.getOrigUnit();
1840 unsigned Idx = U.getDIEIndex(InputDIE);
1841 CompileUnit::DIEInfo &Info = Unit.getInfo(Idx);
1842
1843 // Should the DIE appear in the output?
1844 if (!Unit.getInfo(Idx).Keep)
1845 return nullptr;
1846
1847 uint64_t Offset = InputDIE.getOffset();
1848 assert(!(Die && Info.Clone) && "Can't supply a DIE and a cloned DIE");
1849 if (!Die) {
1850 // The DIE might have been already created by a forward reference
1851 // (see cloneDieReferenceAttribute()).
1852 if (!Info.Clone)
1853 Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag()));
1854 Die = Info.Clone;
1855 }
1856
1857 assert(Die->getTag() == InputDIE.getTag());
1858 Die->setOffset(OutOffset);
1859 if (isODRCanonicalCandidate(InputDIE, Unit) && Info.Ctxt &&
1860 (Info.Ctxt->getCanonicalDIEOffset() == 0)) {
1861 if (!Info.Ctxt->hasCanonicalDIE())
1862 Info.Ctxt->setHasCanonicalDIE();
1863 // We are about to emit a DIE that is the root of its own valid
1864 // DeclContext tree. Make the current offset the canonical offset
1865 // for this context.
1866 Info.Ctxt->setCanonicalDIEOffset(OutOffset + Unit.getStartOffset());
1867 }
1868
1869 // Extract and clone every attribute.
1870 DWARFDataExtractor Data = U.getDebugInfoExtractor();
1871 // Point to the next DIE (generally there is always at least a NULL
1872 // entry after the current one). If this is a lone
1873 // DW_TAG_compile_unit without any children, point to the next unit.
1874 uint64_t NextOffset = (Idx + 1 < U.getNumDIEs())
1875 ? U.getDIEAtIndex(Idx + 1).getOffset()
1876 : U.getNextUnitOffset();
1877 AttributesInfo AttrInfo;
1878
1879 // We could copy the data only if we need to apply a relocation to it. After
1880 // testing, it seems there is no performance downside to doing the copy
1881 // unconditionally, and it makes the code simpler.
1882 SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset));
1883 Data =
1884 DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
1885
1886 // Modify the copy with relocated addresses.
1887 ObjFile.Addresses->applyValidRelocs(DIECopy, Offset, Data.isLittleEndian());
1888
1889 // Reset the Offset to 0 as we will be working on the local copy of
1890 // the data.
1891 Offset = 0;
1892
1893 const auto *Abbrev = InputDIE.getAbbreviationDeclarationPtr();
1894 Offset += getULEB128Size(Abbrev->getCode());
1895
1896 // We are entering a subprogram. Get and propagate the PCOffset.
1897 if (Die->getTag() == dwarf::DW_TAG_subprogram)
1898 PCOffset = Info.AddrAdjust;
1899 AttrInfo.PCOffset = PCOffset;
1900
1901 if (Abbrev->getTag() == dwarf::DW_TAG_subprogram) {
1902 Flags |= TF_InFunctionScope;
1903 if (LLVM_LIKELY(!Update)) {
1904 if (Info.InDebugMap)
1905 Flags &= ~TF_SkipPC;
1906 else
1907 Flags |= TF_SkipPC;
1908 }
1909 } else if (Abbrev->getTag() == dwarf::DW_TAG_variable) {
1910 // Function-local globals could be in the debug map even when the function
1911 // is not, e.g., inlined functions.
1912 if ((Flags & TF_InFunctionScope) && Info.InDebugMap)
1913 Flags &= ~TF_SkipPC;
1914 // Location expressions referencing an address which is not in debug map
1915 // should be deleted.
1916 else if (!Info.InDebugMap && Info.HasLocationExpressionAddr &&
1917 LLVM_LIKELY(!Update))
1918 Flags |= TF_SkipPC;
1919 }
1920
1921 std::optional<StringRef> LibraryInstallName =
1922 ObjFile.Addresses->getLibraryInstallName();
1924 for (const auto &AttrSpec : Abbrev->attributes()) {
1925 if (shouldSkipAttribute(Update, AttrSpec, Flags & TF_SkipPC)) {
1926 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
1927 U.getFormParams());
1928 continue;
1929 }
1930
1931 AttributeLinkedOffsetFixup CurAttrFixup;
1932 CurAttrFixup.InputAttrStartOffset = InputDIE.getOffset() + Offset;
1933 CurAttrFixup.LinkedOffsetFixupVal =
1934 Unit.getStartOffset() + OutOffset - CurAttrFixup.InputAttrStartOffset;
1935
1936 DWARFFormValue Val = AttrSpec.getFormValue();
1937 uint64_t AttrSize = Offset;
1938 Val.extractValue(Data, &Offset, U.getFormParams(), &U);
1939 CurAttrFixup.InputAttrEndOffset = InputDIE.getOffset() + Offset;
1940 AttrSize = Offset - AttrSize;
1941
1942 uint64_t FinalAttrSize =
1943 cloneAttribute(*Die, InputDIE, File, Unit, Val, AttrSpec, AttrSize,
1944 AttrInfo, IsLittleEndian);
1945 if (FinalAttrSize != 0 && ObjFile.Addresses->needToSaveValidRelocs())
1946 AttributesFixups.push_back(CurAttrFixup);
1947
1948 OutOffset += FinalAttrSize;
1949 }
1950
1951 uint16_t Tag = InputDIE.getTag();
1952 // Add the DW_AT_APPLE_origin attribute to Compile Unit die if we have
1953 // an install name and the DWARF doesn't have the attribute yet.
1954 const bool NeedsAppleOrigin = (Tag == dwarf::DW_TAG_compile_unit) &&
1955 LibraryInstallName.has_value() &&
1956 !AttrInfo.HasAppleOrigin;
1957 if (NeedsAppleOrigin) {
1958 auto StringEntry = DebugStrPool.getEntry(LibraryInstallName.value());
1959 Die->addValue(DIEAlloc, dwarf::Attribute(dwarf::DW_AT_APPLE_origin),
1960 dwarf::DW_FORM_strp, DIEInteger(StringEntry.getOffset()));
1961 AttrInfo.Name = StringEntry;
1962 OutOffset += 4;
1963 }
1964
1965 // Look for accelerator entries.
1966 // FIXME: This is slightly wrong. An inline_subroutine without a
1967 // low_pc, but with AT_ranges might be interesting to get into the
1968 // accelerator tables too. For now stick with dsymutil's behavior.
1969 if ((Info.InDebugMap || AttrInfo.HasLowPc || AttrInfo.HasRanges) &&
1970 Tag != dwarf::DW_TAG_compile_unit &&
1971 !(Tag == dwarf::DW_TAG_variable &&
1972 hasImplicitAddressLocation(InputDIE)) &&
1973 getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit,
1974 Tag != dwarf::DW_TAG_inlined_subroutine)) {
1975 if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)
1976 Unit.addNameAccelerator(Die, AttrInfo.MangledName,
1977 Tag == dwarf::DW_TAG_inlined_subroutine);
1978 if (AttrInfo.Name) {
1979 if (AttrInfo.NameWithoutTemplate)
1980 Unit.addNameAccelerator(Die, AttrInfo.NameWithoutTemplate,
1981 /* SkipPubSection */ true);
1982 Unit.addNameAccelerator(Die, AttrInfo.Name,
1983 Tag == dwarf::DW_TAG_inlined_subroutine);
1984 }
1985 if (AttrInfo.Name)
1986 addObjCAccelerator(Unit, Die, AttrInfo.Name, DebugStrPool,
1987 /* SkipPubSection =*/true);
1988
1989 } else if (Tag == dwarf::DW_TAG_namespace) {
1990 if (!AttrInfo.Name)
1991 AttrInfo.Name = DebugStrPool.getEntry("(anonymous namespace)");
1992 Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
1993 } else if (Tag == dwarf::DW_TAG_imported_declaration && AttrInfo.Name) {
1994 Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
1995 } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration) {
1996 bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit);
1997 uint64_t RuntimeLang =
1998 dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
1999 .value_or(0);
2000 bool ObjCClassIsImplementation =
2001 (RuntimeLang == dwarf::DW_LANG_ObjC ||
2002 RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) &&
2003 dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type))
2004 .value_or(0);
2005 if (Success && AttrInfo.Name && !AttrInfo.Name.getString().empty()) {
2006 uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
2007 Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
2008 Hash);
2009 }
2010
2011 // For Swift, mangled names are put into DW_AT_linkage_name.
2012 if (Success && AttrInfo.MangledName &&
2013 RuntimeLang == dwarf::DW_LANG_Swift &&
2014 !AttrInfo.MangledName.getString().empty() &&
2015 AttrInfo.MangledName != AttrInfo.Name) {
2016 auto Hash = djbHash(AttrInfo.MangledName.getString().data());
2017 Unit.addTypeAccelerator(Die, AttrInfo.MangledName,
2018 ObjCClassIsImplementation, Hash);
2019 }
2020 }
2021
2022 // Determine whether there are any children that we want to keep.
2023 bool HasChildren = false;
2024 for (auto Child : InputDIE.children()) {
2025 unsigned Idx = U.getDIEIndex(Child);
2026 if (Unit.getInfo(Idx).Keep) {
2027 HasChildren = true;
2028 break;
2029 }
2030 }
2031
2032 if (Die == Unit.getOutputUnitDIE() && Unit.getOrigUnit().getVersion() >= 5 &&
2033 !AttrInfo.AttrStrOffsetBaseSeen) {
2034 // No DW_AT_str_offsets_base seen, add it to the DIE.
2035 Die->addValue(DIEAlloc, dwarf::DW_AT_str_offsets_base,
2036 dwarf::DW_FORM_sec_offset, DIEInteger(8));
2037 OutOffset += 4;
2038 }
2039
2040 // No DW_AT_addr_base seen, as GCC emits; add one for the addrx-indexed
2041 // entries. emitDebugAddrSection() patches in the real offset.
2042 if (!Update && Die == Unit.getOutputUnitDIE() && U.getVersion() >= 5 &&
2043 !Die->findAttribute(dwarf::DW_AT_addr_base)) {
2044 OutOffset += Die->addValue(DIEAlloc, dwarf::DW_AT_addr_base,
2045 dwarf::DW_FORM_sec_offset, DIEInteger(0))
2046 ->sizeOf(U.getFormParams());
2047 }
2048
2049 DIEAbbrev NewAbbrev = Die->generateAbbrev();
2050 if (HasChildren)
2052 // Assign a permanent abbrev number
2053 Linker.assignAbbrev(NewAbbrev);
2054 Die->setAbbrevNumber(NewAbbrev.getNumber());
2055
2056 uint64_t AbbrevNumberSize = getULEB128Size(Die->getAbbrevNumber());
2057
2058 // Add the size of the abbreviation number to the output offset.
2059 OutOffset += AbbrevNumberSize;
2060
2061 // Update fixups with the size of the abbreviation number
2062 for (AttributeLinkedOffsetFixup &F : AttributesFixups)
2063 F.LinkedOffsetFixupVal += AbbrevNumberSize;
2064
2065 for (AttributeLinkedOffsetFixup &F : AttributesFixups)
2066 ObjFile.Addresses->updateAndSaveValidRelocs(
2067 Unit.getOrigUnit().getVersion() >= 5, Unit.getOrigUnit().getOffset(),
2068 F.LinkedOffsetFixupVal, F.InputAttrStartOffset, F.InputAttrEndOffset);
2069
2070 if (!HasChildren) {
2071 // Update our size.
2072 Die->setSize(OutOffset - Die->getOffset());
2073 return Die;
2074 }
2075
2076 // Recursively clone children.
2077 for (auto Child : InputDIE.children()) {
2078 if (DIE *Clone = cloneDIE(Child, File, Unit, PCOffset, OutOffset, Flags,
2079 IsLittleEndian)) {
2080 Die->addChild(Clone);
2081 OutOffset = Clone->getOffset() + Clone->getSize();
2082 }
2083 }
2084
2085 // Account for the end of children marker.
2086 OutOffset += sizeof(int8_t);
2087 // Update our size.
2088 Die->setSize(OutOffset - Die->getOffset());
2089 return Die;
2090}
2091
2092/// Patch the input object file relevant debug_ranges or debug_rnglists
2093/// entries and emit them in the output file. Update the relevant attributes
2094/// to point at the new entries.
2095Error DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
2096 DebugDieValuePool &AddrPool) const {
2097 if (LLVM_UNLIKELY(Options.Update))
2098 return Error::success();
2099
2100 const auto &FunctionRanges = Unit.getFunctionRanges();
2101
2102 // Build set of linked address ranges for unit function ranges.
2103 AddressRanges LinkedFunctionRanges;
2104 for (const AddressRangeValuePair &Range : FunctionRanges)
2105 LinkedFunctionRanges.insert(
2106 {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
2107
2108 // Emit LinkedFunctionRanges into .debug_aranges
2109 if (!LinkedFunctionRanges.empty())
2110 TheDwarfEmitter->emitDwarfDebugArangesTable(Unit, LinkedFunctionRanges);
2111
2112 RngListAttributesTy AllRngListAttributes = Unit.getRangesAttributes();
2113 std::optional<PatchLocation> UnitRngListAttribute =
2114 Unit.getUnitRangesAttribute();
2115
2116 if (!AllRngListAttributes.empty() || UnitRngListAttribute) {
2117 std::optional<AddressRangeValuePair> CachedRange;
2118 MCSymbol *EndLabel = TheDwarfEmitter->emitDwarfDebugRangeListHeader(Unit);
2119
2120 // Read original address ranges, apply relocation value, emit linked address
2121 // ranges.
2122 for (PatchLocation &AttributePatch : AllRngListAttributes) {
2123 // Get ranges from the source DWARF corresponding to the current
2124 // attribute.
2125 AddressRanges LinkedRanges;
2126 if (Expected<DWARFAddressRangesVector> OriginalRanges =
2127 Unit.getOrigUnit().findRnglistFromOffset(AttributePatch.get())) {
2128 // Apply relocation adjustment.
2129 for (const auto &Range : *OriginalRanges) {
2130 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
2131 CachedRange = FunctionRanges.getRangeThatContains(Range.LowPC);
2132
2133 // All range entries should lie in the function range.
2134 if (!CachedRange) {
2135 reportWarning("inconsistent range data.", File);
2136 continue;
2137 }
2138
2139 // Store range for emiting.
2140 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
2141 Range.HighPC + CachedRange->Value});
2142 }
2143 } else {
2144 llvm::consumeError(OriginalRanges.takeError());
2145 reportWarning("invalid range list ignored.", File);
2146 }
2147
2148 // Emit linked ranges.
2149 if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment(
2150 Unit, LinkedRanges, AttributePatch, AddrPool))
2151 return E;
2152 }
2153
2154 // Emit ranges for Unit AT_ranges attribute.
2155 if (UnitRngListAttribute.has_value())
2156 if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment(
2157 Unit, LinkedFunctionRanges, *UnitRngListAttribute, AddrPool))
2158 return E;
2159
2160 // Emit ranges footer.
2161 TheDwarfEmitter->emitDwarfDebugRangeListFooter(Unit, EndLabel);
2162 }
2163
2164 return Error::success();
2165}
2166
2167Error DWARFLinker::DIECloner::generateUnitLocations(
2168 CompileUnit &Unit, const DWARFFile &File,
2169 ExpressionHandlerRef ExprHandler) {
2170 if (LLVM_UNLIKELY(Linker.Options.Update))
2171 return Error::success();
2172
2173 const LocListAttributesTy &AllLocListAttributes =
2174 Unit.getLocationAttributes();
2175
2176 if (AllLocListAttributes.empty())
2177 return Error::success();
2178
2179 // Emit locations list table header.
2180 MCSymbol *EndLabel = Emitter->emitDwarfDebugLocListHeader(Unit);
2181
2182 for (auto &CurLocAttr : AllLocListAttributes) {
2183 // Get location expressions vector corresponding to the current attribute
2184 // from the source DWARF.
2185 Expected<DWARFLocationExpressionsVector> OriginalLocations =
2186 Unit.getOrigUnit().findLoclistFromOffset(CurLocAttr.get());
2187
2188 if (!OriginalLocations) {
2189 llvm::consumeError(OriginalLocations.takeError());
2190 Linker.reportWarning("Invalid location attribute ignored.", File);
2191 continue;
2192 }
2193
2194 DWARFLocationExpressionsVector LinkedLocationExpressions;
2195 for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
2196 DWARFLocationExpression LinkedExpression;
2197
2198 if (CurExpression.Range) {
2199 // Relocate address range.
2200 LinkedExpression.Range = {
2201 CurExpression.Range->LowPC + CurLocAttr.RelocAdjustment,
2202 CurExpression.Range->HighPC + CurLocAttr.RelocAdjustment};
2203 }
2204
2205 // Clone expression.
2206 LinkedExpression.Expr.reserve(CurExpression.Expr.size());
2207 ExprHandler(CurExpression.Expr, LinkedExpression.Expr,
2208 CurLocAttr.RelocAdjustment);
2209
2210 LinkedLocationExpressions.push_back(LinkedExpression);
2211 }
2212
2213 // Emit locations list table fragment corresponding to the CurLocAttr.
2214 if (Error E = Emitter->emitDwarfDebugLocListFragment(
2215 Unit, LinkedLocationExpressions, CurLocAttr, AddrPool))
2216 return E;
2217 }
2218
2219 // Emit locations list table footer.
2220 Emitter->emitDwarfDebugLocListFooter(Unit, EndLabel);
2221
2222 return Error::success();
2223}
2224
2226 for (auto &V : Die.values())
2227 if (V.getAttribute() == dwarf::DW_AT_addr_base) {
2228 V = DIEValue(V.getAttribute(), V.getForm(), Offset);
2229 return;
2230 }
2231
2232 llvm_unreachable("Didn't find a DW_AT_addr_base in cloned DIE!");
2233}
2234
2235Error DWARFLinker::DIECloner::emitDebugAddrSection(
2236 CompileUnit &Unit, const uint16_t DwarfVersion) const {
2237
2238 if (LLVM_UNLIKELY(Linker.Options.Update))
2239 return Error::success();
2240
2241 if (DwarfVersion < 5)
2242 return Error::success();
2243
2244 // Every cloned unit root has DW_AT_addr_base, so emit the table even when it
2245 // is empty.
2246 DIE *OutputUnitDIE = Unit.getOutputUnitDIE();
2247 if (OutputUnitDIE == nullptr)
2248 return Error::success();
2249
2250 MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader(Unit);
2251 uint64_t AddrOffset = Emitter->getDebugAddrSectionSize();
2252 dwarf::FormParams FP = Unit.getOrigUnit().getFormParams();
2253 if (AddrOffset > FP.getDwarfMaxOffset())
2254 return createStringError(".debug_addr section offset 0x" +
2255 Twine::utohexstr(AddrOffset) + " exceeds the " +
2256 dwarf::FormatString(FP.Format) + " limit");
2257 patchAddrBase(*OutputUnitDIE, DIEInteger(AddrOffset));
2258 Emitter->emitDwarfDebugAddrs(AddrPool.getValues(),
2259 Unit.getOrigUnit().getAddressByteSize());
2260 Emitter->emitDwarfDebugAddrsFooter(Unit, EndLabel);
2261
2262 return Error::success();
2263}
2264
2265/// A helper struct to help keep track of the association between the input and
2266/// output rows during line table rewriting. This is used to patch
2267/// DW_AT_LLVM_stmt_sequence attributes, which reference a particular line table
2268/// row.
2274
2275/// Insert the new line info sequence \p Seq into the current
2276/// set of already linked line info \p Rows.
2277static void insertLineSequence(std::vector<TrackedRow> &Seq,
2278 std::vector<TrackedRow> &Rows) {
2279 if (Seq.empty())
2280 return;
2281
2282 // Mark the first row in Seq to indicate it is the start of a sequence
2283 // in the output line table.
2284 Seq.front().isStartSeqInOutput = true;
2285
2286 if (!Rows.empty() && Rows.back().Row.Address < Seq.front().Row.Address) {
2287 llvm::append_range(Rows, Seq);
2288 Seq.clear();
2289 return;
2290 }
2291
2292 object::SectionedAddress Front = Seq.front().Row.Address;
2294 Rows, [=](const TrackedRow &O) { return O.Row.Address < Front; });
2295
2296 // FIXME: this only removes the unneeded end_sequence if the
2297 // sequences have been inserted in order. Using a global sort like
2298 // described in generateLineTableForUnit() and delaying the end_sequence
2299 // elimination to emitLineTableForUnit() we can get rid of all of them.
2300 if (InsertPoint != Rows.end() && InsertPoint->Row.Address == Front &&
2301 InsertPoint->Row.EndSequence) {
2302 *InsertPoint = Seq.front();
2303 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
2304 } else {
2305 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
2306 }
2307
2308 Seq.clear();
2309}
2310
2312 for (auto &V : Die.values())
2313 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
2314 V = DIEValue(V.getAttribute(), V.getForm(), Offset);
2315 return;
2316 }
2317
2318 llvm_unreachable("Didn't find DW_AT_stmt_list in cloned DIE!");
2319}
2320
2321void DWARFLinker::DIECloner::rememberUnitForMacroOffset(CompileUnit &Unit) {
2322 DWARFUnit &OrigUnit = Unit.getOrigUnit();
2323 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
2324
2325 if (std::optional<uint64_t> MacroAttr =
2326 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
2327 UnitMacroMap.insert(std::make_pair(*MacroAttr, &Unit));
2328 return;
2329 }
2330
2331 if (std::optional<uint64_t> MacroAttr =
2332 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
2333 UnitMacroMap.insert(std::make_pair(*MacroAttr, &Unit));
2334 return;
2335 }
2336}
2337
2338Error DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
2339 if (LLVM_UNLIKELY(Emitter == nullptr))
2340 return Error::success();
2341
2342 // Check whether DW_AT_stmt_list attribute is presented.
2343 DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE();
2344 auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list));
2345 if (!StmtList)
2346 return Error::success();
2347
2348 // Update the cloned DW_AT_stmt_list with the correct debug_line offset.
2349 if (auto *OutputDIE = Unit.getOutputUnitDIE()) {
2350 uint64_t StmtOffset = Emitter->getLineSectionSize();
2351 dwarf::FormParams FP = Unit.getOrigUnit().getFormParams();
2352 if (StmtOffset > FP.getDwarfMaxOffset())
2353 return createStringError(".debug_line section offset 0x" +
2354 Twine::utohexstr(StmtOffset) + " exceeds the " +
2355 dwarf::FormatString(FP.Format) + " limit");
2356 patchStmtList(*OutputDIE, DIEInteger(StmtOffset));
2357 }
2358
2359 if (const DWARFDebugLine::LineTable *LT =
2360 ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) {
2361
2362 DWARFDebugLine::LineTable LineTable;
2363
2364 // Set Line Table header.
2365 LineTable.Prologue = LT->Prologue;
2366
2367 // Set Line Table Rows.
2368 if (Linker.Options.Update) {
2369 LineTable.Rows = LT->Rows;
2370 // If all the line table contains is a DW_LNE_end_sequence, clear the line
2371 // table rows, it will be inserted again in the DWARFStreamer.
2372 if (LineTable.Rows.size() == 1 && LineTable.Rows[0].EndSequence)
2373 LineTable.Rows.clear();
2374
2375 LineTable.Sequences = LT->Sequences;
2376
2377 Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
2378 DebugLineStrPool);
2379 } else {
2380 // Create TrackedRow objects for all input rows.
2381 std::vector<TrackedRow> InputRows;
2382 InputRows.reserve(LT->Rows.size());
2383 for (size_t i = 0; i < LT->Rows.size(); i++)
2384 InputRows.emplace_back(TrackedRow{LT->Rows[i], i, false});
2385
2386 // This vector is the output line table (still in TrackedRow form).
2387 std::vector<TrackedRow> OutputRows;
2388 OutputRows.reserve(InputRows.size());
2389
2390 // Current sequence of rows being extracted, before being inserted
2391 // in OutputRows.
2392 std::vector<TrackedRow> Seq;
2393 Seq.reserve(InputRows.size());
2394
2395 const auto &FunctionRanges = Unit.getFunctionRanges();
2396 std::optional<AddressRangeValuePair> CurrRange;
2397
2398 // FIXME: This logic is meant to generate exactly the same output as
2399 // Darwin's classic dsymutil. There is a nicer way to implement this
2400 // by simply putting all the relocated line info in OutputRows and simply
2401 // sorting OutputRows before passing it to emitLineTableForUnit. This
2402 // should be correct as sequences for a function should stay
2403 // together in the sorted output. There are a few corner cases that
2404 // look suspicious though, and that required to implement the logic
2405 // this way. Revisit that once initial validation is finished.
2406
2407 // Iterate over the object file line info and extract the sequences
2408 // that correspond to linked functions.
2409 for (size_t i = 0; i < InputRows.size(); i++) {
2410 TrackedRow TR = InputRows[i];
2411
2412 // Check whether we stepped out of the range. The range is
2413 // half-open, but consider accepting the end address of the range if
2414 // it is marked as end_sequence in the input (because in that
2415 // case, the relocation offset is accurate and that entry won't
2416 // serve as the start of another function).
2417 if (!CurrRange || !CurrRange->Range.contains(TR.Row.Address.Address)) {
2418 // We just stepped out of a known range. Insert an end_sequence
2419 // corresponding to the end of the range.
2420 uint64_t StopAddress =
2421 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
2422 CurrRange =
2423 FunctionRanges.getRangeThatContains(TR.Row.Address.Address);
2424 if (StopAddress != -1ULL && !Seq.empty()) {
2425 // Insert end sequence row with the computed end address, but
2426 // the same line as the previous one.
2427 auto NextLine = Seq.back();
2428 NextLine.Row.Address.Address = StopAddress;
2429 NextLine.Row.EndSequence = 1;
2430 NextLine.Row.PrologueEnd = 0;
2431 NextLine.Row.BasicBlock = 0;
2432 NextLine.Row.EpilogueBegin = 0;
2433 Seq.push_back(NextLine);
2434 insertLineSequence(Seq, OutputRows);
2435 }
2436
2437 if (!CurrRange)
2438 continue;
2439 }
2440
2441 // Ignore empty sequences.
2442 if (TR.Row.EndSequence && Seq.empty())
2443 continue;
2444
2445 // Relocate row address and add it to the current sequence.
2446 TR.Row.Address.Address += CurrRange->Value;
2447 Seq.push_back(TR);
2448
2449 if (TR.Row.EndSequence)
2450 insertLineSequence(Seq, OutputRows);
2451 }
2452
2453 // Recompute isStartSeqInOutput based on the final row ordering.
2454 // A row is a sequence start (will have DW_LNE_set_address emitted) iff:
2455 // 1. It's the first row, OR
2456 // 2. The previous row has EndSequence = 1
2457 // This is necessary because insertLineSequence may merge sequences when
2458 // an EndSequence row is replaced by the start of a new sequence, which
2459 // removes the EndSequence marker and invalidates the original flag.
2460 if (!OutputRows.empty()) {
2461 OutputRows[0].isStartSeqInOutput = true;
2462 for (size_t i = 1; i < OutputRows.size(); ++i)
2463 OutputRows[i].isStartSeqInOutput = OutputRows[i - 1].Row.EndSequence;
2464 }
2465
2466 // Materialize the tracked rows into final DWARFDebugLine::Row objects.
2467 LineTable.Rows.clear();
2468 LineTable.Rows.reserve(OutputRows.size());
2469 for (auto &TR : OutputRows)
2470 LineTable.Rows.push_back(TR.Row);
2471
2472 // Use OutputRowOffsets to store the offsets of each line table row in the
2473 // output .debug_line section.
2474 std::vector<uint64_t> OutputRowOffsets;
2475
2476 // The unit might not have any DW_AT_LLVM_stmt_sequence attributes, so use
2477 // hasStmtSeq to skip the patching logic.
2478 bool hasStmtSeq = Unit.getStmtSeqListAttributes().size() > 0;
2479 Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
2480 DebugLineStrPool,
2481 hasStmtSeq ? &OutputRowOffsets : nullptr);
2482
2483 if (hasStmtSeq) {
2484 assert(OutputRowOffsets.size() == OutputRows.size() &&
2485 "must have an offset for each row");
2486
2487 // Create a map of stmt sequence offsets to original row indices.
2488 DenseMap<uint64_t, uint64_t> SeqOffToOrigRow;
2489 // The DWARF parser's discovery of sequences can be incomplete. To
2490 // ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we
2491 // build a map from both the parser's results and a manual
2492 // reconstruction.
2493 if (!LT->Rows.empty())
2494 constructSeqOffsettoOrigRowMapping(Unit, *LT, SeqOffToOrigRow);
2495
2496 // Build two maps to handle stmt_sequence patching:
2497 // 1. OrigRowToOutputRow: maps original row indices to output row
2498 // indices (for all rows, not just sequence starts).
2499 // 2. OutputRowToSeqStart: maps each output row index to its sequence
2500 // start's output row index
2501 DenseMap<size_t, size_t> OrigRowToOutputRow;
2502 std::vector<size_t> OutputRowToSeqStart(OutputRows.size());
2503
2504 size_t CurrentSeqStart = 0;
2505 for (size_t i = 0; i < OutputRows.size(); ++i) {
2506 // Track the current sequence start.
2507 if (OutputRows[i].isStartSeqInOutput)
2508 CurrentSeqStart = i;
2509 OutputRowToSeqStart[i] = CurrentSeqStart;
2510
2511 // Map original row index to output row index.
2512 OrigRowToOutputRow[OutputRows[i].OriginalRowIndex] = i;
2513 }
2514
2515 // Patch DW_AT_LLVM_stmt_sequence attributes in the compile unit DIE
2516 // with the correct offset into the .debug_line section.
2517 for (const auto &StmtSeq : Unit.getStmtSeqListAttributes()) {
2518 uint64_t OrigStmtSeq = StmtSeq.get();
2519 // 1. Get the original row index from the stmt list offset.
2520 auto OrigRowIter = SeqOffToOrigRow.find(OrigStmtSeq);
2521 const uint64_t InvalidOffset =
2522 Unit.getOrigUnit().getFormParams().getDwarfMaxOffset();
2523 // Check whether we have an output sequence for the StmtSeq offset.
2524 // Some sequences are discarded by the DWARFLinker if they are invalid
2525 // (empty).
2526 if (OrigRowIter == SeqOffToOrigRow.end()) {
2527 StmtSeq.set(InvalidOffset);
2528 continue;
2529 }
2530 size_t OrigRowIndex = OrigRowIter->second;
2531
2532 // 2. Find the output row for this original row.
2533 auto OutputRowIter = OrigRowToOutputRow.find(OrigRowIndex);
2534 if (OutputRowIter == OrigRowToOutputRow.end()) {
2535 // Row was dropped during linking.
2536 StmtSeq.set(InvalidOffset);
2537 continue;
2538 }
2539 size_t OutputRowIdx = OutputRowIter->second;
2540
2541 // 3. Find the sequence start for this output row.
2542 // If the original row was a sequence start but got merged into
2543 // another sequence, this finds the correct sequence start.
2544 size_t SeqStartIdx = OutputRowToSeqStart[OutputRowIdx];
2545
2546 // 4. Get the offset of the sequence start in the output .debug_line
2547 // section. This offset points to the DW_LNE_set_address opcode.
2548 assert(SeqStartIdx < OutputRowOffsets.size() &&
2549 "Sequence start index out of bounds");
2550 uint64_t NewStmtSeqOffset = OutputRowOffsets[SeqStartIdx];
2551
2552 // 5. Patch the stmt_sequence attribute with the new offset.
2553 StmtSeq.set(NewStmtSeqOffset);
2554 }
2555 }
2556 }
2557
2558 } else
2559 Linker.reportWarning("Cann't load line table.", ObjFile);
2560
2561 return Error::success();
2562}
2563
2564void DWARFLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
2565 for (AccelTableKind AccelTableKind : Options.AccelTables) {
2566 switch (AccelTableKind) {
2567 case AccelTableKind::Apple: {
2568 // Add namespaces.
2569 for (const auto &Namespace : Unit.getNamespaces())
2570 AppleNamespaces.addName(Namespace.Name, Namespace.Die->getOffset() +
2571 Unit.getStartOffset());
2572 // Add names.
2573 for (const auto &Pubname : Unit.getPubnames())
2574 AppleNames.addName(Pubname.Name,
2575 Pubname.Die->getOffset() + Unit.getStartOffset());
2576 // Add types.
2577 for (const auto &Pubtype : Unit.getPubtypes())
2578 AppleTypes.addName(
2579 Pubtype.Name, Pubtype.Die->getOffset() + Unit.getStartOffset(),
2580 Pubtype.Die->getTag(),
2581 Pubtype.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation
2582 : 0,
2583 Pubtype.QualifiedNameHash);
2584 // Add ObjC names.
2585 for (const auto &ObjC : Unit.getObjC())
2586 AppleObjc.addName(ObjC.Name,
2587 ObjC.Die->getOffset() + Unit.getStartOffset());
2588 } break;
2589 case AccelTableKind::Pub: {
2590 TheDwarfEmitter->emitPubNamesForUnit(Unit);
2591 TheDwarfEmitter->emitPubTypesForUnit(Unit);
2592 } break;
2594 for (const auto &Namespace : Unit.getNamespaces())
2595 DebugNames.addName(
2596 Namespace.Name, Namespace.Die->getOffset(),
2598 Namespace.Die->getTag(), Unit.getUniqueID(),
2599 Unit.getTag() == dwarf::DW_TAG_type_unit);
2600 for (const auto &Pubname : Unit.getPubnames())
2601 DebugNames.addName(
2602 Pubname.Name, Pubname.Die->getOffset(),
2604 Pubname.Die->getTag(), Unit.getUniqueID(),
2605 Unit.getTag() == dwarf::DW_TAG_type_unit);
2606 for (const auto &Pubtype : Unit.getPubtypes())
2607 DebugNames.addName(
2608 Pubtype.Name, Pubtype.Die->getOffset(),
2610 Pubtype.Die->getTag(), Unit.getUniqueID(),
2611 Unit.getTag() == dwarf::DW_TAG_type_unit);
2612 } break;
2613 }
2614 }
2615}
2616
2617/// Read the frame info stored in the object, and emit the
2618/// patched frame descriptions for the resulting file.
2619///
2620/// This is actually pretty easy as the data of the CIEs and FDEs can
2621/// be considered as black boxes and moved as is. The only thing to do
2622/// is to patch the addresses in the headers.
2623void DWARFLinker::patchFrameInfoForObject(LinkContext &Context) {
2624 DWARFContext &OrigDwarf = *Context.File.Dwarf;
2625 unsigned SrcAddrSize = OrigDwarf.getDWARFObj().getAddressSize();
2626
2627 StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data;
2628 if (FrameData.empty())
2629 return;
2630
2631 RangesTy AllUnitsRanges;
2632 for (std::unique_ptr<CompileUnit> &Unit : Context.CompileUnits) {
2633 for (auto CurRange : Unit->getFunctionRanges())
2634 AllUnitsRanges.insert(CurRange.Range, CurRange.Value);
2635 }
2636
2637 DataExtractor Data(FrameData, OrigDwarf.isLittleEndian());
2638 uint64_t InputOffset = 0;
2639
2640 // Store the data of the CIEs defined in this object, keyed by their
2641 // offsets.
2642 DenseMap<uint64_t, StringRef> LocalCIES;
2643
2644 while (Data.isValidOffset(InputOffset)) {
2645 uint64_t EntryOffset = InputOffset;
2646 uint32_t InitialLength = Data.getU32(&InputOffset);
2647 if (InitialLength == 0xFFFFFFFF)
2648 return reportWarning("Dwarf64 bits no supported", Context.File);
2649
2650 uint32_t CIEId = Data.getU32(&InputOffset);
2651 if (CIEId == 0xFFFFFFFF) {
2652 // This is a CIE, store it.
2653 StringRef CIEData = FrameData.substr(EntryOffset, InitialLength + 4);
2654 LocalCIES[EntryOffset] = CIEData;
2655 // The -4 is to account for the CIEId we just read.
2656 InputOffset += InitialLength - 4;
2657 continue;
2658 }
2659
2660 uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize);
2661
2662 // Some compilers seem to emit frame info that doesn't start at
2663 // the function entry point, thus we can't just lookup the address
2664 // in the debug map. Use the AddressInfo's range map to see if the FDE
2665 // describes something that we can relocate.
2666 std::optional<AddressRangeValuePair> Range =
2667 AllUnitsRanges.getRangeThatContains(Loc);
2668 if (!Range) {
2669 // The +4 is to account for the size of the InitialLength field itself.
2670 InputOffset = EntryOffset + InitialLength + 4;
2671 continue;
2672 }
2673
2674 // This is an FDE, and we have a mapping.
2675 // Have we already emitted a corresponding CIE?
2676 StringRef CIEData = LocalCIES[CIEId];
2677 if (CIEData.empty())
2678 return reportWarning("Inconsistent debug_frame content. Dropping.",
2679 Context.File);
2680
2681 // Look if we already emitted a CIE that corresponds to the
2682 // referenced one (the CIE data is the key of that lookup).
2683 auto IteratorInserted = EmittedCIEs.insert(
2684 std::make_pair(CIEData, TheDwarfEmitter->getFrameSectionSize()));
2685 // If there is no CIE yet for this ID, emit it.
2686 if (IteratorInserted.second) {
2687 LastCIEOffset = TheDwarfEmitter->getFrameSectionSize();
2688 IteratorInserted.first->getValue() = LastCIEOffset;
2689 TheDwarfEmitter->emitCIE(CIEData);
2690 }
2691
2692 // Emit the FDE with updated address and CIE pointer.
2693 // (4 + AddrSize) is the size of the CIEId + initial_location
2694 // fields that will get reconstructed by emitFDE().
2695 unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize);
2696 TheDwarfEmitter->emitFDE(IteratorInserted.first->getValue(), SrcAddrSize,
2697 Loc + Range->Value,
2698 FrameData.substr(InputOffset, FDERemainingBytes));
2699 InputOffset += FDERemainingBytes;
2700 }
2701}
2702
2703uint32_t DWARFLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE,
2704 CompileUnit &U,
2705 const DWARFFile &File,
2706 int ChildRecurseDepth) {
2707 const char *Name = nullptr;
2708 DWARFUnit *OrigUnit = &U.getOrigUnit();
2709 CompileUnit *CU = &U;
2710 std::optional<DWARFFormValue> Ref;
2711
2712 while (true) {
2713 if (const char *CurrentName = DIE.getName(DINameKind::ShortName))
2714 Name = CurrentName;
2715
2716 if (!(Ref = DIE.find(dwarf::DW_AT_specification)) &&
2717 !(Ref = DIE.find(dwarf::DW_AT_abstract_origin)))
2718 break;
2719
2720 if (!Ref->isFormClass(DWARFFormValue::FC_Reference))
2721 break;
2722
2723 CompileUnit *RefCU;
2724 if (auto RefDIE =
2725 Linker.resolveDIEReference(File, CompileUnits, *Ref, DIE, RefCU)) {
2726 CU = RefCU;
2727 OrigUnit = &RefCU->getOrigUnit();
2728 DIE = RefDIE;
2729 }
2730 }
2731
2732 unsigned Idx = OrigUnit->getDIEIndex(DIE);
2733 if (!Name && DIE.getTag() == dwarf::DW_TAG_namespace)
2734 Name = "(anonymous namespace)";
2735
2736 if (CU->getInfo(Idx).ParentIdx == 0 ||
2737 // FIXME: dsymutil-classic compatibility. Ignore modules.
2738 CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() ==
2739 dwarf::DW_TAG_module)
2740 return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::"));
2741
2742 DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx);
2743 return djbHash(
2744 (Name ? Name : ""),
2745 djbHash((Name ? "::" : ""),
2746 hashFullyQualifiedName(Die, *CU, File, ++ChildRecurseDepth)));
2747}
2748
2749static uint64_t getDwoId(const DWARFDie &CUDie) {
2750 auto DwoId = dwarf::toUnsigned(
2751 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id}));
2752 if (DwoId)
2753 return *DwoId;
2754 return 0;
2755}
2756
2757static std::string
2759 const DWARFLinkerBase::ObjectPrefixMapTy &ObjectPrefixMap) {
2760 if (ObjectPrefixMap.empty())
2761 return Path.str();
2762
2763 SmallString<256> p = Path;
2764 for (const auto &Entry : ObjectPrefixMap)
2765 if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second))
2766 break;
2767 return p.str().str();
2768}
2769
2770static std::string
2772 const DWARFLinkerBase::ObjectPrefixMapTy *ObjectPrefixMap) {
2773 std::string PCMFile = dwarf::toString(
2774 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
2775
2776 if (PCMFile.empty())
2777 return PCMFile;
2778
2779 if (ObjectPrefixMap)
2780 PCMFile = remapPath(PCMFile, *ObjectPrefixMap);
2781
2782 return PCMFile;
2783}
2784
2785std::pair<bool, bool> DWARFLinker::isClangModuleRef(const DWARFDie &CUDie,
2786 std::string &PCMFile,
2787 LinkContext &Context,
2788 unsigned Indent,
2789 bool Quiet) {
2790 if (PCMFile.empty())
2791 return std::make_pair(false, false);
2792
2793 // Clang module DWARF skeleton CUs abuse this for the path to the module.
2794 uint64_t DwoId = getDwoId(CUDie);
2795
2796 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
2797 if (Name.empty()) {
2798 if (!Quiet)
2799 reportWarning("Anonymous module skeleton CU for " + PCMFile,
2800 Context.File);
2801 return std::make_pair(true, true);
2802 }
2803
2804 if (!Quiet && Options.Verbose) {
2805 outs().indent(Indent);
2806 outs() << "Found clang module reference " << PCMFile;
2807 }
2808
2809 auto Cached = ClangModules.find(PCMFile);
2810 if (Cached != ClangModules.end()) {
2811 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
2812 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
2813 // ASTFileSignatures will change randomly when a module is rebuilt.
2814 if (!Quiet && Options.Verbose && (Cached->second != DwoId))
2815 reportWarning(Twine("hash mismatch: this object file was built against a "
2816 "different version of the module ") +
2817 PCMFile,
2818 Context.File);
2819 if (!Quiet && Options.Verbose)
2820 outs() << " [cached].\n";
2821 return std::make_pair(true, true);
2822 }
2823
2824 return std::make_pair(true, false);
2825}
2826
2827bool DWARFLinker::registerModuleReference(const DWARFDie &CUDie,
2828 LinkContext &Context,
2829 ObjFileLoaderTy Loader,
2830 CompileUnitHandlerTy OnCUDieLoaded,
2831 unsigned Indent) {
2832 std::string PCMFile = getPCMFile(CUDie, Options.ObjectPrefixMap);
2833 std::pair<bool, bool> IsClangModuleRef =
2834 isClangModuleRef(CUDie, PCMFile, Context, Indent, false);
2835
2836 if (!IsClangModuleRef.first)
2837 return false;
2838
2839 if (IsClangModuleRef.second)
2840 return true;
2841
2842 if (Options.Verbose)
2843 outs() << " ...\n";
2844
2845 // Cyclic dependencies are disallowed by Clang, but we still
2846 // shouldn't run into an infinite loop, so mark it as processed now.
2847 ClangModules.insert({PCMFile, getDwoId(CUDie)});
2848
2849 if (Error E = loadClangModule(Loader, CUDie, PCMFile, Context, OnCUDieLoaded,
2850 Indent + 2)) {
2851 consumeError(std::move(E));
2852 return false;
2853 }
2854 return true;
2855}
2856
2857Error DWARFLinker::loadClangModule(
2858 ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile,
2859 LinkContext &Context, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) {
2860
2861 uint64_t DwoId = getDwoId(CUDie);
2862 std::string ModuleName = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
2863
2864 /// Using a SmallString<0> because loadClangModule() is recursive.
2865 SmallString<0> Path(Options.PrependPath);
2866 if (sys::path::is_relative(PCMFile))
2867 resolveRelativeObjectPath(Path, CUDie);
2868 sys::path::append(Path, PCMFile);
2869 // Don't use the cached binary holder because we have no thread-safety
2870 // guarantee and the lifetime is limited.
2871
2872 if (Loader == nullptr) {
2873 reportError("Could not load clang module: loader is not specified.\n",
2874 Context.File);
2875 return Error::success();
2876 }
2877
2878 auto ErrOrObj = Loader(Context.File.FileName, Path);
2879 if (!ErrOrObj)
2880 return Error::success();
2881
2882 std::unique_ptr<CompileUnit> Unit;
2883 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) {
2884 OnCUDieLoaded(*CU);
2885 // Recursively get all modules imported by this one.
2886 auto ChildCUDie = CU->getUnitDIE();
2887 if (!ChildCUDie)
2888 continue;
2889 if (!registerModuleReference(ChildCUDie, Context, Loader, OnCUDieLoaded,
2890 Indent)) {
2891 if (Unit) {
2892 std::string Err =
2893 (PCMFile +
2894 ": Clang modules are expected to have exactly 1 compile unit.\n");
2895 reportError(Err, Context.File);
2897 }
2898 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
2899 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
2900 // ASTFileSignatures will change randomly when a module is rebuilt.
2901 uint64_t PCMDwoId = getDwoId(ChildCUDie);
2902 if (PCMDwoId != DwoId) {
2903 if (Options.Verbose)
2904 reportWarning(
2905 Twine("hash mismatch: this object file was built against a "
2906 "different version of the module ") +
2907 PCMFile,
2908 Context.File);
2909 // Update the cache entry with the DwoId of the module loaded from disk.
2910 ClangModules[PCMFile] = PCMDwoId;
2911 }
2912
2913 // Add this module.
2914 Unit = std::make_unique<CompileUnit>(*CU, UniqueUnitID++, !Options.NoODR,
2915 ModuleName);
2916 }
2917 }
2918
2919 if (Unit)
2920 Context.ModuleUnits.emplace_back(RefModuleUnit{*ErrOrObj, std::move(Unit)});
2921
2922 return Error::success();
2923}
2924
2925Expected<uint64_t> DWARFLinker::DIECloner::cloneAllCompileUnits(
2926 DWARFContext &DwarfContext, const DWARFFile &File, bool IsLittleEndian) {
2927 uint64_t OutputDebugInfoSize =
2928 (Emitter == nullptr) ? 0 : Emitter->getDebugInfoSectionSize();
2929 const uint64_t StartOutputDebugInfoSize = OutputDebugInfoSize;
2930
2931 for (auto &CurrentUnit : CompileUnits) {
2932 const uint16_t DwarfVersion = CurrentUnit->getOrigUnit().getVersion();
2933 const uint32_t UnitHeaderSize = DwarfVersion >= 5 ? 12 : 11;
2934 auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE();
2935 CurrentUnit->setStartOffset(OutputDebugInfoSize);
2936 if (!InputDIE) {
2937 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);
2938 continue;
2939 }
2940 if (CurrentUnit->getInfo(0).Keep) {
2941 // Clone the InputDIE into your Unit DIE in our compile unit since it
2942 // already has a DIE inside of it.
2943 CurrentUnit->createOutputDIE();
2944 rememberUnitForMacroOffset(*CurrentUnit);
2945 cloneDIE(InputDIE, File, *CurrentUnit, 0 /* PC offset */, UnitHeaderSize,
2946 0, IsLittleEndian, CurrentUnit->getOutputUnitDIE());
2947 }
2948
2949 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);
2950
2951 if (Emitter != nullptr) {
2952
2953 if (Error E = generateLineTableForUnit(*CurrentUnit))
2954 return E;
2955
2956 Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
2957
2958 if (LLVM_UNLIKELY(Linker.Options.Update))
2959 continue;
2960
2961 if (Error E = Linker.generateUnitRanges(*CurrentUnit, File, AddrPool))
2962 return E;
2963
2964 auto ProcessExpr = [&](SmallVectorImpl<uint8_t> &SrcBytes,
2965 SmallVectorImpl<uint8_t> &OutBytes,
2966 int64_t RelocAdjustment) {
2967 DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit();
2968 DataExtractor Data(SrcBytes, IsLittleEndian);
2969 cloneExpression(Data,
2970 DWARFExpression(Data, OrigUnit.getAddressByteSize(),
2971 OrigUnit.getFormParams().Format),
2972 File, *CurrentUnit, OutBytes, RelocAdjustment,
2973 IsLittleEndian);
2974 };
2975 if (Error E = generateUnitLocations(*CurrentUnit, File, ProcessExpr))
2976 return E;
2977 if (Error E = emitDebugAddrSection(*CurrentUnit, DwarfVersion))
2978 return E;
2979 }
2980 AddrPool.clear();
2981 }
2982
2983 if (Emitter != nullptr) {
2984 assert(Emitter);
2985 // Emit macro tables.
2986 Emitter->emitMacroTables(File.Dwarf.get(), UnitMacroMap, DebugStrPool);
2987
2988 // Emit all the compile unit's debug information.
2989 for (auto &CurrentUnit : CompileUnits) {
2990 CurrentUnit->fixupForwardReferences();
2991
2992 if (!CurrentUnit->getOutputUnitDIE())
2993 continue;
2994
2995 unsigned DwarfVersion = CurrentUnit->getOrigUnit().getVersion();
2996
2997 assert(Emitter->getDebugInfoSectionSize() ==
2998 CurrentUnit->getStartOffset());
2999 Emitter->emitCompileUnitHeader(*CurrentUnit, DwarfVersion);
3000 Emitter->emitDIE(*CurrentUnit->getOutputUnitDIE());
3001 assert(Emitter->getDebugInfoSectionSize() ==
3002 CurrentUnit->computeNextUnitOffset(DwarfVersion));
3003 }
3004 }
3005
3006 return OutputDebugInfoSize - StartOutputDebugInfoSize;
3007}
3008
3009void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) {
3010 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getLocSection().Data,
3012 TheDwarfEmitter->emitSectionContents(
3013 Dwarf.getDWARFObj().getRangesSection().Data,
3015 TheDwarfEmitter->emitSectionContents(
3016 Dwarf.getDWARFObj().getFrameSection().Data, DebugSectionKind::DebugFrame);
3017 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(),
3019 TheDwarfEmitter->emitSectionContents(
3020 Dwarf.getDWARFObj().getAddrSection().Data, DebugSectionKind::DebugAddr);
3021 TheDwarfEmitter->emitSectionContents(
3022 Dwarf.getDWARFObj().getRnglistsSection().Data,
3024 TheDwarfEmitter->emitSectionContents(
3025 Dwarf.getDWARFObj().getLoclistsSection().Data,
3027}
3028
3030 CompileUnitHandlerTy OnCUDieLoaded) {
3031 ObjectContexts.emplace_back(LinkContext(File));
3032
3033 if (ObjectContexts.back().File.Dwarf) {
3034 for (const std::unique_ptr<DWARFUnit> &CU :
3035 ObjectContexts.back().File.Dwarf->compile_units()) {
3036 DWARFDie CUDie = CU->getUnitDIE();
3037
3038 if (!CUDie)
3039 continue;
3040
3041 OnCUDieLoaded(*CU);
3042
3043 if (!LLVM_UNLIKELY(Options.Update))
3044 registerModuleReference(CUDie, ObjectContexts.back(), Loader,
3045 OnCUDieLoaded);
3046 }
3047 }
3048}
3049
3051 assert((Options.TargetDWARFVersion != 0) &&
3052 "TargetDWARFVersion should be set");
3053
3054 // First populate the data structure we need for each iteration of the
3055 // parallel loop.
3056 unsigned NumObjects = ObjectContexts.size();
3057
3058 // This Dwarf string pool which is used for emission. It must be used
3059 // serially as the order of calling getStringOffset matters for
3060 // reproducibility.
3061 OffsetsStringPool DebugStrPool(true);
3062 OffsetsStringPool DebugLineStrPool(false);
3063 DebugDieValuePool StringOffsetPool;
3064
3065 // ODR Contexts for the optimize.
3066 DeclContextTree ODRContexts;
3067
3068 for (LinkContext &OptContext : ObjectContexts) {
3069 if (Options.Verbose)
3070 outs() << "DEBUG MAP OBJECT: " << OptContext.File.FileName << "\n";
3071
3072 if (!OptContext.File.Dwarf)
3073 continue;
3074
3075 if (Options.VerifyInputDWARF)
3076 verifyInput(OptContext.File);
3077
3078 // Look for relocations that correspond to address map entries.
3079
3080 // there was findvalidrelocations previously ... probably we need to gather
3081 // info here
3082 if (LLVM_LIKELY(!Options.Update) &&
3083 !OptContext.File.Addresses->hasValidRelocs()) {
3084 if (Options.Verbose)
3085 outs() << "No valid relocations found. Skipping.\n";
3086
3087 // Set "Skip" flag as a signal to other loops that we should not
3088 // process this iteration.
3089 OptContext.Skip = true;
3090 continue;
3091 }
3092
3093 // Setup access to the debug info.
3094 if (!OptContext.File.Dwarf)
3095 continue;
3096
3097 // Check whether type units are presented.
3098 if (!OptContext.File.Dwarf->types_section_units().empty()) {
3099 reportWarning("type units are not currently supported: file will "
3100 "be skipped",
3101 OptContext.File);
3102 OptContext.Skip = true;
3103 continue;
3104 }
3105
3106 // Clone all the clang modules with requires extracting the DIE units. We
3107 // don't need the full debug info until the Analyze phase.
3108 OptContext.CompileUnits.reserve(
3109 OptContext.File.Dwarf->getNumCompileUnits());
3110 for (const auto &CU : OptContext.File.Dwarf->compile_units()) {
3111 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/true);
3112 if (Options.Verbose) {
3113 outs() << "Input compilation unit:";
3114 DIDumpOptions DumpOpts;
3115 DumpOpts.ChildRecurseDepth = 0;
3116 DumpOpts.Verbose = Options.Verbose;
3117 CUDie.dump(outs(), 0, DumpOpts);
3118 }
3119 }
3120
3121 for (auto &CU : OptContext.ModuleUnits) {
3122 if (Error Err = cloneModuleUnit(OptContext, CU, ODRContexts, DebugStrPool,
3123 DebugLineStrPool, StringOffsetPool))
3124 reportWarning(toString(std::move(Err)), CU.File);
3125 }
3126 }
3127
3128 // At this point we know how much data we have emitted. We use this value to
3129 // compare canonical DIE offsets in analyzeContextInfo to see if a definition
3130 // is already emitted, without being affected by canonical die offsets set
3131 // later. This prevents undeterminism when analyze and clone execute
3132 // concurrently, as clone set the canonical DIE offset and analyze reads it.
3133 const uint64_t ModulesEndOffset =
3134 (TheDwarfEmitter == nullptr) ? 0
3135 : TheDwarfEmitter->getDebugInfoSectionSize();
3136
3137 // These variables manage the list of processed object files.
3138 // The mutex and condition variable are to ensure that this is thread safe.
3139 std::mutex ProcessedFilesMutex;
3140 std::condition_variable ProcessedFilesConditionVariable;
3141 BitVector ProcessedFiles(NumObjects, false);
3142
3143 // Analyzing the context info is particularly expensive so it is executed in
3144 // parallel with emitting the previous compile unit.
3145 auto AnalyzeLambda = [&](size_t I) {
3146 auto &Context = ObjectContexts[I];
3147
3148 if (Context.Skip || !Context.File.Dwarf)
3149 return;
3150
3151 for (const auto &CU : Context.File.Dwarf->compile_units()) {
3152 // Previously we only extracted the unit DIEs. We need the full debug info
3153 // now.
3154 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);
3155 std::string PCMFile = getPCMFile(CUDie, Options.ObjectPrefixMap);
3156
3157 if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
3158 !isClangModuleRef(CUDie, PCMFile, Context, 0, true).first) {
3159 Context.CompileUnits.push_back(std::make_unique<CompileUnit>(
3160 *CU, UniqueUnitID++, !Options.NoODR && !Options.Update, ""));
3161 }
3162 }
3163
3164 // Now build the DIE parent links that we will use during the next phase.
3165 for (auto &CurrentUnit : Context.CompileUnits) {
3166 auto CUDie = CurrentUnit->getOrigUnit().getUnitDIE();
3167 if (!CUDie)
3168 continue;
3169 analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0,
3170 *CurrentUnit, &ODRContexts.getRoot(), ODRContexts,
3171 ModulesEndOffset, Options.ParseableSwiftInterfaces,
3172 [&](const Twine &Warning, const DWARFDie &DIE) {
3173 reportWarning(Warning, Context.File, &DIE);
3174 });
3175 }
3176 };
3177
3178 // For each object file map how many bytes were emitted.
3179 StringMap<DebugInfoSize> SizeByObject;
3180
3181 // And then the remaining work in serial again.
3182 // Note, although this loop runs in serial, it can run in parallel with
3183 // the analyzeContextInfo loop so long as we process files with indices >=
3184 // than those processed by analyzeContextInfo.
3185 auto CloneLambda = [&](size_t I, llvm::Error &CE) {
3186 auto &OptContext = ObjectContexts[I];
3187 if (OptContext.Skip || !OptContext.File.Dwarf)
3188 return;
3189
3190 // Then mark all the DIEs that need to be present in the generated output
3191 // and collect some information about them.
3192 // Note that this loop can not be merged with the previous one because
3193 // cross-cu references require the ParentIdx to be setup for every CU in
3194 // the object file before calling this.
3195 if (LLVM_UNLIKELY(Options.Update)) {
3196 for (auto &CurrentUnit : OptContext.CompileUnits)
3197 CurrentUnit->markEverythingAsKept();
3198 copyInvariantDebugSection(*OptContext.File.Dwarf);
3199 } else {
3200 for (auto &CurrentUnit : OptContext.CompileUnits) {
3201 lookForDIEsToKeep(*OptContext.File.Addresses, OptContext.CompileUnits,
3202 CurrentUnit->getOrigUnit().getUnitDIE(),
3203 OptContext.File, *CurrentUnit, 0);
3204#ifndef NDEBUG
3205 verifyKeepChain(*CurrentUnit);
3206#endif
3207 }
3208 }
3209
3210 // The calls to applyValidRelocs inside cloneDIE will walk the reloc
3211 // array again (in the same way findValidRelocsInDebugInfo() did). We
3212 // need to reset the NextValidReloc index to the beginning.
3213 if (OptContext.File.Addresses->hasValidRelocs() ||
3214 LLVM_UNLIKELY(Options.Update)) {
3215 SizeByObject[OptContext.File.FileName].Input =
3216 getDebugInfoSize(*OptContext.File.Dwarf);
3217 Expected<uint64_t> SizeOrErr =
3218 DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc,
3219 OptContext.CompileUnits, Options.Update, DebugStrPool,
3220 DebugLineStrPool, StringOffsetPool)
3221 .cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File,
3222 OptContext.File.Dwarf->isLittleEndian());
3223 if (!SizeOrErr) {
3224 CE = SizeOrErr.takeError();
3225 return;
3226 }
3227 SizeByObject[OptContext.File.FileName].Output = *SizeOrErr;
3228 }
3229 if ((TheDwarfEmitter != nullptr) && !OptContext.CompileUnits.empty() &&
3230 LLVM_LIKELY(!Options.Update))
3231 patchFrameInfoForObject(OptContext);
3232
3233 // Clean-up before starting working on the next object.
3234 cleanupAuxiliarryData(OptContext);
3235 };
3236
3237 auto EmitLambda = [&]() {
3238 // Emit everything that's global.
3239 if (TheDwarfEmitter != nullptr) {
3240 TheDwarfEmitter->emitAbbrevs(Abbreviations, Options.TargetDWARFVersion);
3241 TheDwarfEmitter->emitStrings(DebugStrPool);
3242 TheDwarfEmitter->emitStringOffsets(StringOffsetPool.getValues(),
3243 Options.TargetDWARFVersion);
3244 TheDwarfEmitter->emitLineStrings(DebugLineStrPool);
3245 for (AccelTableKind TableKind : Options.AccelTables) {
3246 switch (TableKind) {
3248 TheDwarfEmitter->emitAppleNamespaces(AppleNamespaces);
3249 TheDwarfEmitter->emitAppleNames(AppleNames);
3250 TheDwarfEmitter->emitAppleTypes(AppleTypes);
3251 TheDwarfEmitter->emitAppleObjc(AppleObjc);
3252 break;
3254 // Already emitted by emitAcceleratorEntriesForUnit.
3255 // Already emitted by emitAcceleratorEntriesForUnit.
3256 break;
3258 TheDwarfEmitter->emitDebugNames(DebugNames);
3259 break;
3260 }
3261 }
3262 }
3263 };
3264
3265 auto AnalyzeAll = [&]() {
3266 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3267 AnalyzeLambda(I);
3268
3269 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
3270 ProcessedFiles.set(I);
3271 ProcessedFilesConditionVariable.notify_one();
3272 }
3273 };
3274
3275 auto CloneAll = [&](llvm::Error &CE) {
3276 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3277 {
3278 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
3279 if (!ProcessedFiles[I]) {
3280 ProcessedFilesConditionVariable.wait(
3281 LockGuard, [&]() { return ProcessedFiles[I]; });
3282 }
3283 }
3284
3285 CloneLambda(I, CE);
3286 if (CE)
3287 return;
3288 }
3289 EmitLambda();
3290 };
3291
3292 Error CE = Error::success();
3293
3294 // To limit memory usage in the single threaded case, analyze and clone are
3295 // run sequentially so the OptContext is freed after processing each object
3296 // in endDebugObject.
3297 if (Options.Threads == 1) {
3298 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3299 AnalyzeLambda(I);
3300 CloneLambda(I, CE);
3301 if (CE)
3302 break;
3303 }
3304 if (!CE)
3305 EmitLambda();
3306 } else {
3308 Pool.async(AnalyzeAll);
3309 Pool.async(CloneAll, std::reference_wrapper<Error>(CE));
3310 Pool.wait();
3311 }
3312
3313 if (CE)
3314 return CE;
3315
3316 if (Options.Statistics) {
3317 // Create a vector sorted in descending order by output size.
3318 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted;
3319 for (auto &E : SizeByObject)
3320 Sorted.emplace_back(E.first(), E.second);
3321 llvm::sort(Sorted, [](auto &LHS, auto &RHS) {
3322 return LHS.second.Output > RHS.second.Output;
3323 });
3324
3325 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float {
3326 const float Difference = Output - Input;
3327 const float Sum = Input + Output;
3328 if (Sum == 0)
3329 return 0;
3330 return (Difference / (Sum / 2));
3331 };
3332
3333 int64_t InputTotal = 0;
3334 int64_t OutputTotal = 0;
3335 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
3336
3337 // Print header.
3338 outs() << ".debug_info section size (in bytes)\n";
3339 outs() << "----------------------------------------------------------------"
3340 "---------------\n";
3341 outs() << "Filename Object "
3342 " dSYM Change\n";
3343 outs() << "----------------------------------------------------------------"
3344 "---------------\n";
3345
3346 // Print body.
3347 for (auto &E : Sorted) {
3348 InputTotal += E.second.Input;
3349 OutputTotal += E.second.Output;
3350 llvm::outs() << formatv(
3351 FormatStr, sys::path::filename(E.first).take_back(45), E.second.Input,
3352 E.second.Output, ComputePercentange(E.second.Input, E.second.Output));
3353 }
3354 // Print total and footer.
3355 outs() << "----------------------------------------------------------------"
3356 "---------------\n";
3357 llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal,
3358 ComputePercentange(InputTotal, OutputTotal));
3359 outs() << "----------------------------------------------------------------"
3360 "---------------\n\n";
3361 }
3362
3363 return Error::success();
3364}
3365
3366Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
3367 DeclContextTree &ODRContexts,
3368 OffsetsStringPool &DebugStrPool,
3369 OffsetsStringPool &DebugLineStrPool,
3370 DebugDieValuePool &StringOffsetPool,
3371 unsigned Indent) {
3372 assert(Unit.Unit.get() != nullptr);
3373
3374 if (!Unit.Unit->getOrigUnit().getUnitDIE().hasChildren())
3375 return Error::success();
3376
3377 if (Options.Verbose) {
3378 outs().indent(Indent);
3379 outs() << "cloning .debug_info from " << Unit.File.FileName << "\n";
3380 }
3381
3382 // Analyze context for the module.
3383 analyzeContextInfo(Unit.Unit->getOrigUnit().getUnitDIE(), 0, *(Unit.Unit),
3384 &ODRContexts.getRoot(), ODRContexts, 0,
3385 Options.ParseableSwiftInterfaces,
3386 [&](const Twine &Warning, const DWARFDie &DIE) {
3387 reportWarning(Warning, Context.File, &DIE);
3388 });
3389 // Keep everything.
3390 Unit.Unit->markEverythingAsKept();
3391
3392 // Clone unit.
3393 UnitListTy CompileUnits;
3394 CompileUnits.emplace_back(std::move(Unit.Unit));
3395 assert(TheDwarfEmitter);
3396 Expected<uint64_t> SizeOrErr =
3397 DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits,
3398 Options.Update, DebugStrPool, DebugLineStrPool,
3399 StringOffsetPool)
3400 .cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File,
3401 Unit.File.Dwarf->isLittleEndian());
3402 if (!SizeOrErr)
3403 return SizeOrErr.takeError();
3404 return Error::success();
3405}
3406
3407void DWARFLinker::verifyInput(const DWARFFile &File) {
3408 assert(File.Dwarf);
3409
3410 std::string Buffer;
3411 raw_string_ostream OS(Buffer);
3412 DIDumpOptions DumpOpts;
3413 if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) {
3414 if (Options.InputVerificationHandler)
3415 Options.InputVerificationHandler(File, OS.str());
3416 }
3417}
3418
3419} // namespace llvm
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
static uint32_t hashFullyQualifiedName(CompileUnit &InputCU, DWARFDie &InputDIE, int ChildRecurseDepth=0)
This file implements the BitVector class.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:348
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:347
dxil DXContainer Global Emitter
Provides ErrorOr<T> smart pointer.
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
if(PassOpts->AAPipeline)
This file contains some templates that are useful if you are working with the STL at all.
This file contains some functions that are useful when dealing with strings.
Value * RHS
Value * LHS
The Input class is used to parse a yaml document into in-memory structs and vectors.
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
void setChildrenFlag(bool hasChild)
Definition DIE.h:105
An integer value DIE.
Definition DIE.h:169
value_range values()
Definition DIE.h:823
value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V)
Definition DIE.h:756
A structured debug information entry.
Definition DIE.h:835
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
Definition DIE.cpp:202
unsigned getAbbrevNumber() const
Definition DIE.h:867
DIE & addChild(DIE *Child)
Add a child to the DIE.
Definition DIE.h:945
LLVM_ABI DIEAbbrev generateAbbrev() const
Generate the abbreviation for this DIE.
Definition DIE.cpp:173
void setSize(unsigned S)
Definition DIE.h:942
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
Definition DIE.h:862
void setAbbrevNumber(unsigned I)
Set the abbreviation number for this DIE.
Definition DIE.h:903
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition DIE.h:870
void setOffset(unsigned O)
Definition DIE.h:941
dwarf::Tag getTag() const
Definition DIE.h:868
static std::optional< uint64_t > getDefiningParentDieOffset(const DIE &Die)
If Die has a non-null parent and the parent is not a declaration, return its offset.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition DWARFDie.h:43
uint64_t getOffset() const
Get the absolute offset into the debug info or types section.
Definition DWARFDie.h:68
iterator_range< iterator > children() const
Definition DWARFDie.h:407
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition DWARFDie.cpp:335
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Get the abbreviation declaration for this DIE.
Definition DWARFDie.h:60
dwarf::Tag getTag() const
Definition DWARFDie.h:73
LLVM_ABI std::optional< unsigned > getSubCode() const
Encoding
Size and signedness of expression operations' operands.
const Description & getDescription() const
uint64_t getRawOperand(unsigned Idx) const
bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, const dwarf::FormParams Params) const
Skip a form's value in DebugInfoData at the offset specified by OffsetPtr.
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
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
void wait() override
Blocking wait for all the tasks to execute first.
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...
void reserve(size_type N)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Definition ThreadPool.h:80
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
static LLVM_ABI raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition WithColor.cpp:84
AddressesMap represents information about valid addresses used by debug information.
uint64_t constrainCodeRangeHighPC(uint64_t LowPC, uint64_t HighPC, int64_t Adjustment)
Constrains the end of the code range starting at LowPC, whose addresses shift by Adjustment in the ou...
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
AccelTableKind
The kind of accelerator tables to be emitted.
@ 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
const SmallVector< T > & getValues() const
Stores all information relating to a compile unit, be it in its original instance in the object file ...
void addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader=nullptr, CompileUnitHandlerTy OnCUDieLoaded=[](const DWARFUnit &) {}) override
Add object file to be linked.
Error link() override
Link debug info for added objFiles. Object files are linked all together.
This class gives a tree-like API to the DenseMap that stores the DeclContext objects.
LLVM_ABI PointerIntPair< DeclContext *, 1 > getChildDeclContext(DeclContext &Context, const DWARFDie &DIE, CompileUnit &Unit, bool InClangModule)
Get the child of Context described by DIE in Unit.
A DeclContext is a named program scope that is used for ODR uniquing of types.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an std::string.
LLVM_ABI StringRef FormEncodingString(unsigned Encoding)
Definition Dwarf.cpp:105
LLVM_ABI StringRef FormatString(DwarfFormat Format)
Definition Dwarf.cpp:1065
#define UINT64_MAX
Definition DataTypes.h:77
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SmallVector< PatchLocation > RngListAttributesTy
std::vector< std::unique_ptr< CompileUnit > > UnitListTy
IndexedValuesMap< uint64_t > DebugDieValuePool
Definition DWARFLinker.h:38
AddressRangesMap RangesTy
Mapped value in the address map is the offset to apply to the linked address.
SmallVector< PatchLocation > LocListAttributesTy
StringRef guessDeveloperDir(StringRef SysRoot)
Make a best effort to guess the Xcode.app/Contents/Developer path from an SDK path.
Definition Utils.h:80
LLVM_ABI bool hasImplicitAddressLocation(const DWARFDie &Die)
Test if the location of variable Die contains a global address but only uses to compute the variable'...
Definition Utils.cpp:21
LLVM_ABI void buildStmtSeqOffsetToFirstRowIndex(const DWARFDebugLine::LineTable &LT, ArrayRef< uint64_t > SortedStmtSeqOffsets, DenseMap< uint64_t, uint64_t > &SeqOffToFirstRow)
Build a map from an input DW_AT_LLVM_stmt_sequence byte offset to the first-row index (in LT....
Definition Utils.cpp:82
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
bool isInToolchainDir(StringRef Path)
Make a best effort to determine whether Path is inside a toolchain.
Definition Utils.h:116
bool isTlsAddressOp(uint8_t O)
Definition Dwarf.h:1196
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
Attribute
Attributes.
Definition Dwarf.h:125
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
LLVM_ABI bool doesFormBelongToClass(dwarf::Form Form, DWARFFormValue::FormClass FC, uint16_t DwarfVersion)
Check whether specified Form belongs to the FC class.
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
@ DW_CHILDREN_yes
Definition Dwarf.h:964
@ DW_FLAG_type_implementation
Definition Dwarf.h:1051
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
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
constexpr bool IsLittleEndianHost
void swapByteOrder(T &Value)
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
static void verifyKeepChain(CompileUnit &CU)
Verify the keep chain by looking for DIEs that are kept but who's parent isn't.
@ Offset
Definition DWP.cpp:577
static void updateRefIncompleteness(const DWARFDie &Die, CompileUnit &CU, CompileUnit::DIEInfo &RefInfo)
Helper that updates the completeness of the current DIE based on the completeness of the DIEs it refe...
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.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Definition STLExtras.h:2145
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
static void patchAddrBase(DIE &Die, DIEInteger Offset)
auto unique(Range &&R, Predicate P)
Definition STLExtras.h:2150
static std::string remapPath(StringRef Path, const DWARFLinkerBase::ObjectPrefixMapTy &ObjectPrefixMap)
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2081
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
Op::Description Desc
static CompileUnit * getUnitForOffset(const UnitListTy &Units, uint64_t Offset)
Similar to DWARFUnitSection::getUnitForOffset(), but returning our CompileUnit object instead.
static void insertLineSequence(std::vector< TrackedRow > &Seq, std::vector< TrackedRow > &Rows)
Insert the new line info sequence Seq into the current set of already linked line info Rows.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
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)
static bool shouldSkipAttribute(bool Update, DWARFAbbreviationDeclaration::AttributeSpec AttrSpec, bool SkipPC)
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
static uint64_t getDebugInfoSize(DWARFContext &Dwarf)
Compute the total size of the debug info.
static bool isTypeTag(uint16_t Tag)
@ Dwarf
DWARF v5 .debug_names.
Definition DwarfDebug.h:348
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
LLVM_ABI std::optional< StringRef > StripTemplateParameters(StringRef Name)
If Name is the name of a templated function that includes template parameters, returns a substring of...
static uint64_t getDwoId(const DWARFDie &CUDie)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
static bool updatePruning(const DWARFDie &Die, CompileUnit &CU, uint64_t ModulesEndOffset)
@ Success
The lock was released successfully.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition LEB128.cpp:19
static void updateChildIncompleteness(const DWARFDie &Die, CompileUnit &CU, CompileUnit::DIEInfo &ChildInfo)
Helper that updates the completeness of the current DIE based on the completeness of one of its child...
SingleThreadExecutor DefaultThreadPool
Definition ThreadPool.h:262
DWARFExpression::Operation Op
static void updateChildPruning(const DWARFDie &Die, CompileUnit &CU, CompileUnit::DIEInfo &ChildInfo)
uint32_t djbHash(StringRef Buffer, uint32_t H=5381)
The Bernstein hash function used by the DWARF accelerator tables.
Definition DJB.h:22
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
LLVM_ABI std::optional< ObjCSelectorNames > getObjCNamesIfSelector(StringRef Name)
If Name is the AT_name of a DIE which refers to an Objective-C selector, returns an instance of ObjCS...
static void analyzeContextInfo(const DWARFDie &DIE, unsigned ParentIdx, CompileUnit &CU, DeclContext *CurrentDeclContext, DeclContextTree &Contexts, uint64_t ModulesEndOffset, DWARFLinkerBase::SwiftInterfacesMapTy *ParseableSwiftInterfaces, std::function< void(const Twine &, const DWARFDie &)> ReportWarning)
Recursive helper to build the global DeclContext information and gather the child->parent relationshi...
static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag)
StrongType< NonRelocatableStringpool, OffsetsTag > OffsetsStringPool
static bool isODRCanonicalCandidate(const DWARFDie &Die, CompileUnit &CU)
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition LEB128.h:79
static void analyzeImportedModule(const DWARFDie &DIE, CompileUnit &CU, DWARFLinkerBase::SwiftInterfacesMapTy *ParseableSwiftInterfaces, std::function< void(const Twine &, const DWARFDie &)> ReportWarning)
Collect references to parseable Swift interfaces in imported DW_TAG_module blocks.
ContextWorklistItemType
The distinct types of work performed by the work loop in analyzeContextInfo.
static uint64_t constrainHighPC(const DWARFDie &InputDIE, uint64_t HighPC, bool IsLength, int64_t PCOffset, AddressesMap &Addresses)
Returns InputDIE's DW_AT_high_pc value HighPC, constrained so the code range it ends stays clear of t...
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106
static bool isODRAttribute(uint16_t Attr)
static void patchStmtList(DIE &Die, DIEInteger Offset)
static void constructSeqOffsettoOrigRowMapping(CompileUnit &Unit, const DWARFDebugLine::LineTable &LT, DenseMap< uint64_t, uint64_t > &SeqOffToOrigRow)
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
This class represents an item in the work list.
CompileUnit::DIEInfo * OtherInfo
ContextWorklistItem(DWARFDie Die, DeclContext *Context, unsigned ParentIdx, bool InImportedModule)
ContextWorklistItemType Type
ContextWorklistItem(DWARFDie Die, ContextWorklistItemType T, CompileUnit::DIEInfo *OtherInfo=nullptr)
Container for dump options that control which debug information will be dumped.
Definition DIContext.h:197
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition DIContext.h:235
unsigned ChildRecurseDepth
Definition DIContext.h:199
static LLVM_ABI bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
Definition DWARFDie.cpp:836
static LLVM_ABI bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition DWARFDie.cpp:853
Standard .debug_line state machine structure.
SmallVector< Encoding > Op
Encoding for Op operands.
Hold the input and output of the debug info size in bytes.
A helper struct to help keep track of the association between the input and output rows during line t...
DWARFDebugLine::Row Row
Information gathered about a DIE in the object file.
bool Prune
Is this a pure forward declaration we can strip?
bool Incomplete
Does DIE transitively refer an incomplete decl?