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 (Unit.getOrigUnit().getVersion() >= 5 && !AttrInfo.AttrStrOffsetBaseSeen &&
2033 Die->getTag() == dwarf::DW_TAG_compile_unit) {
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 DIEAbbrev NewAbbrev = Die->generateAbbrev();
2041 if (HasChildren)
2043 // Assign a permanent abbrev number
2044 Linker.assignAbbrev(NewAbbrev);
2045 Die->setAbbrevNumber(NewAbbrev.getNumber());
2046
2047 uint64_t AbbrevNumberSize = getULEB128Size(Die->getAbbrevNumber());
2048
2049 // Add the size of the abbreviation number to the output offset.
2050 OutOffset += AbbrevNumberSize;
2051
2052 // Update fixups with the size of the abbreviation number
2053 for (AttributeLinkedOffsetFixup &F : AttributesFixups)
2054 F.LinkedOffsetFixupVal += AbbrevNumberSize;
2055
2056 for (AttributeLinkedOffsetFixup &F : AttributesFixups)
2057 ObjFile.Addresses->updateAndSaveValidRelocs(
2058 Unit.getOrigUnit().getVersion() >= 5, Unit.getOrigUnit().getOffset(),
2059 F.LinkedOffsetFixupVal, F.InputAttrStartOffset, F.InputAttrEndOffset);
2060
2061 if (!HasChildren) {
2062 // Update our size.
2063 Die->setSize(OutOffset - Die->getOffset());
2064 return Die;
2065 }
2066
2067 // Recursively clone children.
2068 for (auto Child : InputDIE.children()) {
2069 if (DIE *Clone = cloneDIE(Child, File, Unit, PCOffset, OutOffset, Flags,
2070 IsLittleEndian)) {
2071 Die->addChild(Clone);
2072 OutOffset = Clone->getOffset() + Clone->getSize();
2073 }
2074 }
2075
2076 // Account for the end of children marker.
2077 OutOffset += sizeof(int8_t);
2078 // Update our size.
2079 Die->setSize(OutOffset - Die->getOffset());
2080 return Die;
2081}
2082
2083/// Patch the input object file relevant debug_ranges or debug_rnglists
2084/// entries and emit them in the output file. Update the relevant attributes
2085/// to point at the new entries.
2086Error DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
2087 DebugDieValuePool &AddrPool) const {
2088 if (LLVM_UNLIKELY(Options.Update))
2089 return Error::success();
2090
2091 const auto &FunctionRanges = Unit.getFunctionRanges();
2092
2093 // Build set of linked address ranges for unit function ranges.
2094 AddressRanges LinkedFunctionRanges;
2095 for (const AddressRangeValuePair &Range : FunctionRanges)
2096 LinkedFunctionRanges.insert(
2097 {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
2098
2099 // Emit LinkedFunctionRanges into .debug_aranges
2100 if (!LinkedFunctionRanges.empty())
2101 TheDwarfEmitter->emitDwarfDebugArangesTable(Unit, LinkedFunctionRanges);
2102
2103 RngListAttributesTy AllRngListAttributes = Unit.getRangesAttributes();
2104 std::optional<PatchLocation> UnitRngListAttribute =
2105 Unit.getUnitRangesAttribute();
2106
2107 if (!AllRngListAttributes.empty() || UnitRngListAttribute) {
2108 std::optional<AddressRangeValuePair> CachedRange;
2109 MCSymbol *EndLabel = TheDwarfEmitter->emitDwarfDebugRangeListHeader(Unit);
2110
2111 // Read original address ranges, apply relocation value, emit linked address
2112 // ranges.
2113 for (PatchLocation &AttributePatch : AllRngListAttributes) {
2114 // Get ranges from the source DWARF corresponding to the current
2115 // attribute.
2116 AddressRanges LinkedRanges;
2117 if (Expected<DWARFAddressRangesVector> OriginalRanges =
2118 Unit.getOrigUnit().findRnglistFromOffset(AttributePatch.get())) {
2119 // Apply relocation adjustment.
2120 for (const auto &Range : *OriginalRanges) {
2121 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
2122 CachedRange = FunctionRanges.getRangeThatContains(Range.LowPC);
2123
2124 // All range entries should lie in the function range.
2125 if (!CachedRange) {
2126 reportWarning("inconsistent range data.", File);
2127 continue;
2128 }
2129
2130 // Store range for emiting.
2131 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
2132 Range.HighPC + CachedRange->Value});
2133 }
2134 } else {
2135 llvm::consumeError(OriginalRanges.takeError());
2136 reportWarning("invalid range list ignored.", File);
2137 }
2138
2139 // Emit linked ranges.
2140 if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment(
2141 Unit, LinkedRanges, AttributePatch, AddrPool))
2142 return E;
2143 }
2144
2145 // Emit ranges for Unit AT_ranges attribute.
2146 if (UnitRngListAttribute.has_value())
2147 if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment(
2148 Unit, LinkedFunctionRanges, *UnitRngListAttribute, AddrPool))
2149 return E;
2150
2151 // Emit ranges footer.
2152 TheDwarfEmitter->emitDwarfDebugRangeListFooter(Unit, EndLabel);
2153 }
2154
2155 return Error::success();
2156}
2157
2158Error DWARFLinker::DIECloner::generateUnitLocations(
2159 CompileUnit &Unit, const DWARFFile &File,
2160 ExpressionHandlerRef ExprHandler) {
2161 if (LLVM_UNLIKELY(Linker.Options.Update))
2162 return Error::success();
2163
2164 const LocListAttributesTy &AllLocListAttributes =
2165 Unit.getLocationAttributes();
2166
2167 if (AllLocListAttributes.empty())
2168 return Error::success();
2169
2170 // Emit locations list table header.
2171 MCSymbol *EndLabel = Emitter->emitDwarfDebugLocListHeader(Unit);
2172
2173 for (auto &CurLocAttr : AllLocListAttributes) {
2174 // Get location expressions vector corresponding to the current attribute
2175 // from the source DWARF.
2176 Expected<DWARFLocationExpressionsVector> OriginalLocations =
2177 Unit.getOrigUnit().findLoclistFromOffset(CurLocAttr.get());
2178
2179 if (!OriginalLocations) {
2180 llvm::consumeError(OriginalLocations.takeError());
2181 Linker.reportWarning("Invalid location attribute ignored.", File);
2182 continue;
2183 }
2184
2185 DWARFLocationExpressionsVector LinkedLocationExpressions;
2186 for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
2187 DWARFLocationExpression LinkedExpression;
2188
2189 if (CurExpression.Range) {
2190 // Relocate address range.
2191 LinkedExpression.Range = {
2192 CurExpression.Range->LowPC + CurLocAttr.RelocAdjustment,
2193 CurExpression.Range->HighPC + CurLocAttr.RelocAdjustment};
2194 }
2195
2196 // Clone expression.
2197 LinkedExpression.Expr.reserve(CurExpression.Expr.size());
2198 ExprHandler(CurExpression.Expr, LinkedExpression.Expr,
2199 CurLocAttr.RelocAdjustment);
2200
2201 LinkedLocationExpressions.push_back(LinkedExpression);
2202 }
2203
2204 // Emit locations list table fragment corresponding to the CurLocAttr.
2205 if (Error E = Emitter->emitDwarfDebugLocListFragment(
2206 Unit, LinkedLocationExpressions, CurLocAttr, AddrPool))
2207 return E;
2208 }
2209
2210 // Emit locations list table footer.
2211 Emitter->emitDwarfDebugLocListFooter(Unit, EndLabel);
2212
2213 return Error::success();
2214}
2215
2217 for (auto &V : Die.values())
2218 if (V.getAttribute() == dwarf::DW_AT_addr_base) {
2219 V = DIEValue(V.getAttribute(), V.getForm(), Offset);
2220 return;
2221 }
2222
2223 llvm_unreachable("Didn't find a DW_AT_addr_base in cloned DIE!");
2224}
2225
2226Error DWARFLinker::DIECloner::emitDebugAddrSection(
2227 CompileUnit &Unit, const uint16_t DwarfVersion) const {
2228
2229 if (LLVM_UNLIKELY(Linker.Options.Update))
2230 return Error::success();
2231
2232 if (DwarfVersion < 5)
2233 return Error::success();
2234
2235 if (AddrPool.getValues().empty())
2236 return Error::success();
2237
2238 MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader(Unit);
2239 uint64_t AddrOffset = Emitter->getDebugAddrSectionSize();
2240 dwarf::FormParams FP = Unit.getOrigUnit().getFormParams();
2241 if (AddrOffset > FP.getDwarfMaxOffset())
2242 return createStringError(".debug_addr section offset 0x" +
2243 Twine::utohexstr(AddrOffset) + " exceeds the " +
2244 dwarf::FormatString(FP.Format) + " limit");
2245 patchAddrBase(*Unit.getOutputUnitDIE(), DIEInteger(AddrOffset));
2246 Emitter->emitDwarfDebugAddrs(AddrPool.getValues(),
2247 Unit.getOrigUnit().getAddressByteSize());
2248 Emitter->emitDwarfDebugAddrsFooter(Unit, EndLabel);
2249
2250 return Error::success();
2251}
2252
2253/// A helper struct to help keep track of the association between the input and
2254/// output rows during line table rewriting. This is used to patch
2255/// DW_AT_LLVM_stmt_sequence attributes, which reference a particular line table
2256/// row.
2262
2263/// Insert the new line info sequence \p Seq into the current
2264/// set of already linked line info \p Rows.
2265static void insertLineSequence(std::vector<TrackedRow> &Seq,
2266 std::vector<TrackedRow> &Rows) {
2267 if (Seq.empty())
2268 return;
2269
2270 // Mark the first row in Seq to indicate it is the start of a sequence
2271 // in the output line table.
2272 Seq.front().isStartSeqInOutput = true;
2273
2274 if (!Rows.empty() && Rows.back().Row.Address < Seq.front().Row.Address) {
2275 llvm::append_range(Rows, Seq);
2276 Seq.clear();
2277 return;
2278 }
2279
2280 object::SectionedAddress Front = Seq.front().Row.Address;
2282 Rows, [=](const TrackedRow &O) { return O.Row.Address < Front; });
2283
2284 // FIXME: this only removes the unneeded end_sequence if the
2285 // sequences have been inserted in order. Using a global sort like
2286 // described in generateLineTableForUnit() and delaying the end_sequence
2287 // elimination to emitLineTableForUnit() we can get rid of all of them.
2288 if (InsertPoint != Rows.end() && InsertPoint->Row.Address == Front &&
2289 InsertPoint->Row.EndSequence) {
2290 *InsertPoint = Seq.front();
2291 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
2292 } else {
2293 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
2294 }
2295
2296 Seq.clear();
2297}
2298
2300 for (auto &V : Die.values())
2301 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
2302 V = DIEValue(V.getAttribute(), V.getForm(), Offset);
2303 return;
2304 }
2305
2306 llvm_unreachable("Didn't find DW_AT_stmt_list in cloned DIE!");
2307}
2308
2309void DWARFLinker::DIECloner::rememberUnitForMacroOffset(CompileUnit &Unit) {
2310 DWARFUnit &OrigUnit = Unit.getOrigUnit();
2311 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
2312
2313 if (std::optional<uint64_t> MacroAttr =
2314 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
2315 UnitMacroMap.insert(std::make_pair(*MacroAttr, &Unit));
2316 return;
2317 }
2318
2319 if (std::optional<uint64_t> MacroAttr =
2320 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
2321 UnitMacroMap.insert(std::make_pair(*MacroAttr, &Unit));
2322 return;
2323 }
2324}
2325
2326Error DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
2327 if (LLVM_UNLIKELY(Emitter == nullptr))
2328 return Error::success();
2329
2330 // Check whether DW_AT_stmt_list attribute is presented.
2331 DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE();
2332 auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list));
2333 if (!StmtList)
2334 return Error::success();
2335
2336 // Update the cloned DW_AT_stmt_list with the correct debug_line offset.
2337 if (auto *OutputDIE = Unit.getOutputUnitDIE()) {
2338 uint64_t StmtOffset = Emitter->getLineSectionSize();
2339 dwarf::FormParams FP = Unit.getOrigUnit().getFormParams();
2340 if (StmtOffset > FP.getDwarfMaxOffset())
2341 return createStringError(".debug_line section offset 0x" +
2342 Twine::utohexstr(StmtOffset) + " exceeds the " +
2343 dwarf::FormatString(FP.Format) + " limit");
2344 patchStmtList(*OutputDIE, DIEInteger(StmtOffset));
2345 }
2346
2347 if (const DWARFDebugLine::LineTable *LT =
2348 ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) {
2349
2350 DWARFDebugLine::LineTable LineTable;
2351
2352 // Set Line Table header.
2353 LineTable.Prologue = LT->Prologue;
2354
2355 // Set Line Table Rows.
2356 if (Linker.Options.Update) {
2357 LineTable.Rows = LT->Rows;
2358 // If all the line table contains is a DW_LNE_end_sequence, clear the line
2359 // table rows, it will be inserted again in the DWARFStreamer.
2360 if (LineTable.Rows.size() == 1 && LineTable.Rows[0].EndSequence)
2361 LineTable.Rows.clear();
2362
2363 LineTable.Sequences = LT->Sequences;
2364
2365 Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
2366 DebugLineStrPool);
2367 } else {
2368 // Create TrackedRow objects for all input rows.
2369 std::vector<TrackedRow> InputRows;
2370 InputRows.reserve(LT->Rows.size());
2371 for (size_t i = 0; i < LT->Rows.size(); i++)
2372 InputRows.emplace_back(TrackedRow{LT->Rows[i], i, false});
2373
2374 // This vector is the output line table (still in TrackedRow form).
2375 std::vector<TrackedRow> OutputRows;
2376 OutputRows.reserve(InputRows.size());
2377
2378 // Current sequence of rows being extracted, before being inserted
2379 // in OutputRows.
2380 std::vector<TrackedRow> Seq;
2381 Seq.reserve(InputRows.size());
2382
2383 const auto &FunctionRanges = Unit.getFunctionRanges();
2384 std::optional<AddressRangeValuePair> CurrRange;
2385
2386 // FIXME: This logic is meant to generate exactly the same output as
2387 // Darwin's classic dsymutil. There is a nicer way to implement this
2388 // by simply putting all the relocated line info in OutputRows and simply
2389 // sorting OutputRows before passing it to emitLineTableForUnit. This
2390 // should be correct as sequences for a function should stay
2391 // together in the sorted output. There are a few corner cases that
2392 // look suspicious though, and that required to implement the logic
2393 // this way. Revisit that once initial validation is finished.
2394
2395 // Iterate over the object file line info and extract the sequences
2396 // that correspond to linked functions.
2397 for (size_t i = 0; i < InputRows.size(); i++) {
2398 TrackedRow TR = InputRows[i];
2399
2400 // Check whether we stepped out of the range. The range is
2401 // half-open, but consider accepting the end address of the range if
2402 // it is marked as end_sequence in the input (because in that
2403 // case, the relocation offset is accurate and that entry won't
2404 // serve as the start of another function).
2405 if (!CurrRange || !CurrRange->Range.contains(TR.Row.Address.Address)) {
2406 // We just stepped out of a known range. Insert an end_sequence
2407 // corresponding to the end of the range.
2408 uint64_t StopAddress =
2409 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
2410 CurrRange =
2411 FunctionRanges.getRangeThatContains(TR.Row.Address.Address);
2412 if (StopAddress != -1ULL && !Seq.empty()) {
2413 // Insert end sequence row with the computed end address, but
2414 // the same line as the previous one.
2415 auto NextLine = Seq.back();
2416 NextLine.Row.Address.Address = StopAddress;
2417 NextLine.Row.EndSequence = 1;
2418 NextLine.Row.PrologueEnd = 0;
2419 NextLine.Row.BasicBlock = 0;
2420 NextLine.Row.EpilogueBegin = 0;
2421 Seq.push_back(NextLine);
2422 insertLineSequence(Seq, OutputRows);
2423 }
2424
2425 if (!CurrRange)
2426 continue;
2427 }
2428
2429 // Ignore empty sequences.
2430 if (TR.Row.EndSequence && Seq.empty())
2431 continue;
2432
2433 // Relocate row address and add it to the current sequence.
2434 TR.Row.Address.Address += CurrRange->Value;
2435 Seq.push_back(TR);
2436
2437 if (TR.Row.EndSequence)
2438 insertLineSequence(Seq, OutputRows);
2439 }
2440
2441 // Recompute isStartSeqInOutput based on the final row ordering.
2442 // A row is a sequence start (will have DW_LNE_set_address emitted) iff:
2443 // 1. It's the first row, OR
2444 // 2. The previous row has EndSequence = 1
2445 // This is necessary because insertLineSequence may merge sequences when
2446 // an EndSequence row is replaced by the start of a new sequence, which
2447 // removes the EndSequence marker and invalidates the original flag.
2448 if (!OutputRows.empty()) {
2449 OutputRows[0].isStartSeqInOutput = true;
2450 for (size_t i = 1; i < OutputRows.size(); ++i)
2451 OutputRows[i].isStartSeqInOutput = OutputRows[i - 1].Row.EndSequence;
2452 }
2453
2454 // Materialize the tracked rows into final DWARFDebugLine::Row objects.
2455 LineTable.Rows.clear();
2456 LineTable.Rows.reserve(OutputRows.size());
2457 for (auto &TR : OutputRows)
2458 LineTable.Rows.push_back(TR.Row);
2459
2460 // Use OutputRowOffsets to store the offsets of each line table row in the
2461 // output .debug_line section.
2462 std::vector<uint64_t> OutputRowOffsets;
2463
2464 // The unit might not have any DW_AT_LLVM_stmt_sequence attributes, so use
2465 // hasStmtSeq to skip the patching logic.
2466 bool hasStmtSeq = Unit.getStmtSeqListAttributes().size() > 0;
2467 Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
2468 DebugLineStrPool,
2469 hasStmtSeq ? &OutputRowOffsets : nullptr);
2470
2471 if (hasStmtSeq) {
2472 assert(OutputRowOffsets.size() == OutputRows.size() &&
2473 "must have an offset for each row");
2474
2475 // Create a map of stmt sequence offsets to original row indices.
2476 DenseMap<uint64_t, uint64_t> SeqOffToOrigRow;
2477 // The DWARF parser's discovery of sequences can be incomplete. To
2478 // ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we
2479 // build a map from both the parser's results and a manual
2480 // reconstruction.
2481 if (!LT->Rows.empty())
2482 constructSeqOffsettoOrigRowMapping(Unit, *LT, SeqOffToOrigRow);
2483
2484 // Build two maps to handle stmt_sequence patching:
2485 // 1. OrigRowToOutputRow: maps original row indices to output row
2486 // indices (for all rows, not just sequence starts).
2487 // 2. OutputRowToSeqStart: maps each output row index to its sequence
2488 // start's output row index
2489 DenseMap<size_t, size_t> OrigRowToOutputRow;
2490 std::vector<size_t> OutputRowToSeqStart(OutputRows.size());
2491
2492 size_t CurrentSeqStart = 0;
2493 for (size_t i = 0; i < OutputRows.size(); ++i) {
2494 // Track the current sequence start.
2495 if (OutputRows[i].isStartSeqInOutput)
2496 CurrentSeqStart = i;
2497 OutputRowToSeqStart[i] = CurrentSeqStart;
2498
2499 // Map original row index to output row index.
2500 OrigRowToOutputRow[OutputRows[i].OriginalRowIndex] = i;
2501 }
2502
2503 // Patch DW_AT_LLVM_stmt_sequence attributes in the compile unit DIE
2504 // with the correct offset into the .debug_line section.
2505 for (const auto &StmtSeq : Unit.getStmtSeqListAttributes()) {
2506 uint64_t OrigStmtSeq = StmtSeq.get();
2507 // 1. Get the original row index from the stmt list offset.
2508 auto OrigRowIter = SeqOffToOrigRow.find(OrigStmtSeq);
2509 const uint64_t InvalidOffset =
2510 Unit.getOrigUnit().getFormParams().getDwarfMaxOffset();
2511 // Check whether we have an output sequence for the StmtSeq offset.
2512 // Some sequences are discarded by the DWARFLinker if they are invalid
2513 // (empty).
2514 if (OrigRowIter == SeqOffToOrigRow.end()) {
2515 StmtSeq.set(InvalidOffset);
2516 continue;
2517 }
2518 size_t OrigRowIndex = OrigRowIter->second;
2519
2520 // 2. Find the output row for this original row.
2521 auto OutputRowIter = OrigRowToOutputRow.find(OrigRowIndex);
2522 if (OutputRowIter == OrigRowToOutputRow.end()) {
2523 // Row was dropped during linking.
2524 StmtSeq.set(InvalidOffset);
2525 continue;
2526 }
2527 size_t OutputRowIdx = OutputRowIter->second;
2528
2529 // 3. Find the sequence start for this output row.
2530 // If the original row was a sequence start but got merged into
2531 // another sequence, this finds the correct sequence start.
2532 size_t SeqStartIdx = OutputRowToSeqStart[OutputRowIdx];
2533
2534 // 4. Get the offset of the sequence start in the output .debug_line
2535 // section. This offset points to the DW_LNE_set_address opcode.
2536 assert(SeqStartIdx < OutputRowOffsets.size() &&
2537 "Sequence start index out of bounds");
2538 uint64_t NewStmtSeqOffset = OutputRowOffsets[SeqStartIdx];
2539
2540 // 5. Patch the stmt_sequence attribute with the new offset.
2541 StmtSeq.set(NewStmtSeqOffset);
2542 }
2543 }
2544 }
2545
2546 } else
2547 Linker.reportWarning("Cann't load line table.", ObjFile);
2548
2549 return Error::success();
2550}
2551
2552void DWARFLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
2553 for (AccelTableKind AccelTableKind : Options.AccelTables) {
2554 switch (AccelTableKind) {
2555 case AccelTableKind::Apple: {
2556 // Add namespaces.
2557 for (const auto &Namespace : Unit.getNamespaces())
2558 AppleNamespaces.addName(Namespace.Name, Namespace.Die->getOffset() +
2559 Unit.getStartOffset());
2560 // Add names.
2561 for (const auto &Pubname : Unit.getPubnames())
2562 AppleNames.addName(Pubname.Name,
2563 Pubname.Die->getOffset() + Unit.getStartOffset());
2564 // Add types.
2565 for (const auto &Pubtype : Unit.getPubtypes())
2566 AppleTypes.addName(
2567 Pubtype.Name, Pubtype.Die->getOffset() + Unit.getStartOffset(),
2568 Pubtype.Die->getTag(),
2569 Pubtype.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation
2570 : 0,
2571 Pubtype.QualifiedNameHash);
2572 // Add ObjC names.
2573 for (const auto &ObjC : Unit.getObjC())
2574 AppleObjc.addName(ObjC.Name,
2575 ObjC.Die->getOffset() + Unit.getStartOffset());
2576 } break;
2577 case AccelTableKind::Pub: {
2578 TheDwarfEmitter->emitPubNamesForUnit(Unit);
2579 TheDwarfEmitter->emitPubTypesForUnit(Unit);
2580 } break;
2582 for (const auto &Namespace : Unit.getNamespaces())
2583 DebugNames.addName(
2584 Namespace.Name, Namespace.Die->getOffset(),
2586 Namespace.Die->getTag(), Unit.getUniqueID(),
2587 Unit.getTag() == dwarf::DW_TAG_type_unit);
2588 for (const auto &Pubname : Unit.getPubnames())
2589 DebugNames.addName(
2590 Pubname.Name, Pubname.Die->getOffset(),
2592 Pubname.Die->getTag(), Unit.getUniqueID(),
2593 Unit.getTag() == dwarf::DW_TAG_type_unit);
2594 for (const auto &Pubtype : Unit.getPubtypes())
2595 DebugNames.addName(
2596 Pubtype.Name, Pubtype.Die->getOffset(),
2598 Pubtype.Die->getTag(), Unit.getUniqueID(),
2599 Unit.getTag() == dwarf::DW_TAG_type_unit);
2600 } break;
2601 }
2602 }
2603}
2604
2605/// Read the frame info stored in the object, and emit the
2606/// patched frame descriptions for the resulting file.
2607///
2608/// This is actually pretty easy as the data of the CIEs and FDEs can
2609/// be considered as black boxes and moved as is. The only thing to do
2610/// is to patch the addresses in the headers.
2611void DWARFLinker::patchFrameInfoForObject(LinkContext &Context) {
2612 DWARFContext &OrigDwarf = *Context.File.Dwarf;
2613 unsigned SrcAddrSize = OrigDwarf.getDWARFObj().getAddressSize();
2614
2615 StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data;
2616 if (FrameData.empty())
2617 return;
2618
2619 RangesTy AllUnitsRanges;
2620 for (std::unique_ptr<CompileUnit> &Unit : Context.CompileUnits) {
2621 for (auto CurRange : Unit->getFunctionRanges())
2622 AllUnitsRanges.insert(CurRange.Range, CurRange.Value);
2623 }
2624
2625 DataExtractor Data(FrameData, OrigDwarf.isLittleEndian());
2626 uint64_t InputOffset = 0;
2627
2628 // Store the data of the CIEs defined in this object, keyed by their
2629 // offsets.
2630 DenseMap<uint64_t, StringRef> LocalCIES;
2631
2632 while (Data.isValidOffset(InputOffset)) {
2633 uint64_t EntryOffset = InputOffset;
2634 uint32_t InitialLength = Data.getU32(&InputOffset);
2635 if (InitialLength == 0xFFFFFFFF)
2636 return reportWarning("Dwarf64 bits no supported", Context.File);
2637
2638 uint32_t CIEId = Data.getU32(&InputOffset);
2639 if (CIEId == 0xFFFFFFFF) {
2640 // This is a CIE, store it.
2641 StringRef CIEData = FrameData.substr(EntryOffset, InitialLength + 4);
2642 LocalCIES[EntryOffset] = CIEData;
2643 // The -4 is to account for the CIEId we just read.
2644 InputOffset += InitialLength - 4;
2645 continue;
2646 }
2647
2648 uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize);
2649
2650 // Some compilers seem to emit frame info that doesn't start at
2651 // the function entry point, thus we can't just lookup the address
2652 // in the debug map. Use the AddressInfo's range map to see if the FDE
2653 // describes something that we can relocate.
2654 std::optional<AddressRangeValuePair> Range =
2655 AllUnitsRanges.getRangeThatContains(Loc);
2656 if (!Range) {
2657 // The +4 is to account for the size of the InitialLength field itself.
2658 InputOffset = EntryOffset + InitialLength + 4;
2659 continue;
2660 }
2661
2662 // This is an FDE, and we have a mapping.
2663 // Have we already emitted a corresponding CIE?
2664 StringRef CIEData = LocalCIES[CIEId];
2665 if (CIEData.empty())
2666 return reportWarning("Inconsistent debug_frame content. Dropping.",
2667 Context.File);
2668
2669 // Look if we already emitted a CIE that corresponds to the
2670 // referenced one (the CIE data is the key of that lookup).
2671 auto IteratorInserted = EmittedCIEs.insert(
2672 std::make_pair(CIEData, TheDwarfEmitter->getFrameSectionSize()));
2673 // If there is no CIE yet for this ID, emit it.
2674 if (IteratorInserted.second) {
2675 LastCIEOffset = TheDwarfEmitter->getFrameSectionSize();
2676 IteratorInserted.first->getValue() = LastCIEOffset;
2677 TheDwarfEmitter->emitCIE(CIEData);
2678 }
2679
2680 // Emit the FDE with updated address and CIE pointer.
2681 // (4 + AddrSize) is the size of the CIEId + initial_location
2682 // fields that will get reconstructed by emitFDE().
2683 unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize);
2684 TheDwarfEmitter->emitFDE(IteratorInserted.first->getValue(), SrcAddrSize,
2685 Loc + Range->Value,
2686 FrameData.substr(InputOffset, FDERemainingBytes));
2687 InputOffset += FDERemainingBytes;
2688 }
2689}
2690
2691uint32_t DWARFLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE,
2692 CompileUnit &U,
2693 const DWARFFile &File,
2694 int ChildRecurseDepth) {
2695 const char *Name = nullptr;
2696 DWARFUnit *OrigUnit = &U.getOrigUnit();
2697 CompileUnit *CU = &U;
2698 std::optional<DWARFFormValue> Ref;
2699
2700 while (true) {
2701 if (const char *CurrentName = DIE.getName(DINameKind::ShortName))
2702 Name = CurrentName;
2703
2704 if (!(Ref = DIE.find(dwarf::DW_AT_specification)) &&
2705 !(Ref = DIE.find(dwarf::DW_AT_abstract_origin)))
2706 break;
2707
2708 if (!Ref->isFormClass(DWARFFormValue::FC_Reference))
2709 break;
2710
2711 CompileUnit *RefCU;
2712 if (auto RefDIE =
2713 Linker.resolveDIEReference(File, CompileUnits, *Ref, DIE, RefCU)) {
2714 CU = RefCU;
2715 OrigUnit = &RefCU->getOrigUnit();
2716 DIE = RefDIE;
2717 }
2718 }
2719
2720 unsigned Idx = OrigUnit->getDIEIndex(DIE);
2721 if (!Name && DIE.getTag() == dwarf::DW_TAG_namespace)
2722 Name = "(anonymous namespace)";
2723
2724 if (CU->getInfo(Idx).ParentIdx == 0 ||
2725 // FIXME: dsymutil-classic compatibility. Ignore modules.
2726 CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() ==
2727 dwarf::DW_TAG_module)
2728 return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::"));
2729
2730 DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx);
2731 return djbHash(
2732 (Name ? Name : ""),
2733 djbHash((Name ? "::" : ""),
2734 hashFullyQualifiedName(Die, *CU, File, ++ChildRecurseDepth)));
2735}
2736
2737static uint64_t getDwoId(const DWARFDie &CUDie) {
2738 auto DwoId = dwarf::toUnsigned(
2739 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id}));
2740 if (DwoId)
2741 return *DwoId;
2742 return 0;
2743}
2744
2745static std::string
2747 const DWARFLinkerBase::ObjectPrefixMapTy &ObjectPrefixMap) {
2748 if (ObjectPrefixMap.empty())
2749 return Path.str();
2750
2751 SmallString<256> p = Path;
2752 for (const auto &Entry : ObjectPrefixMap)
2753 if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second))
2754 break;
2755 return p.str().str();
2756}
2757
2758static std::string
2760 const DWARFLinkerBase::ObjectPrefixMapTy *ObjectPrefixMap) {
2761 std::string PCMFile = dwarf::toString(
2762 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
2763
2764 if (PCMFile.empty())
2765 return PCMFile;
2766
2767 if (ObjectPrefixMap)
2768 PCMFile = remapPath(PCMFile, *ObjectPrefixMap);
2769
2770 return PCMFile;
2771}
2772
2773std::pair<bool, bool> DWARFLinker::isClangModuleRef(const DWARFDie &CUDie,
2774 std::string &PCMFile,
2775 LinkContext &Context,
2776 unsigned Indent,
2777 bool Quiet) {
2778 if (PCMFile.empty())
2779 return std::make_pair(false, false);
2780
2781 // Clang module DWARF skeleton CUs abuse this for the path to the module.
2782 uint64_t DwoId = getDwoId(CUDie);
2783
2784 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
2785 if (Name.empty()) {
2786 if (!Quiet)
2787 reportWarning("Anonymous module skeleton CU for " + PCMFile,
2788 Context.File);
2789 return std::make_pair(true, true);
2790 }
2791
2792 if (!Quiet && Options.Verbose) {
2793 outs().indent(Indent);
2794 outs() << "Found clang module reference " << PCMFile;
2795 }
2796
2797 auto Cached = ClangModules.find(PCMFile);
2798 if (Cached != ClangModules.end()) {
2799 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
2800 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
2801 // ASTFileSignatures will change randomly when a module is rebuilt.
2802 if (!Quiet && Options.Verbose && (Cached->second != DwoId))
2803 reportWarning(Twine("hash mismatch: this object file was built against a "
2804 "different version of the module ") +
2805 PCMFile,
2806 Context.File);
2807 if (!Quiet && Options.Verbose)
2808 outs() << " [cached].\n";
2809 return std::make_pair(true, true);
2810 }
2811
2812 return std::make_pair(true, false);
2813}
2814
2815bool DWARFLinker::registerModuleReference(const DWARFDie &CUDie,
2816 LinkContext &Context,
2817 ObjFileLoaderTy Loader,
2818 CompileUnitHandlerTy OnCUDieLoaded,
2819 unsigned Indent) {
2820 std::string PCMFile = getPCMFile(CUDie, Options.ObjectPrefixMap);
2821 std::pair<bool, bool> IsClangModuleRef =
2822 isClangModuleRef(CUDie, PCMFile, Context, Indent, false);
2823
2824 if (!IsClangModuleRef.first)
2825 return false;
2826
2827 if (IsClangModuleRef.second)
2828 return true;
2829
2830 if (Options.Verbose)
2831 outs() << " ...\n";
2832
2833 // Cyclic dependencies are disallowed by Clang, but we still
2834 // shouldn't run into an infinite loop, so mark it as processed now.
2835 ClangModules.insert({PCMFile, getDwoId(CUDie)});
2836
2837 if (Error E = loadClangModule(Loader, CUDie, PCMFile, Context, OnCUDieLoaded,
2838 Indent + 2)) {
2839 consumeError(std::move(E));
2840 return false;
2841 }
2842 return true;
2843}
2844
2845Error DWARFLinker::loadClangModule(
2846 ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile,
2847 LinkContext &Context, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) {
2848
2849 uint64_t DwoId = getDwoId(CUDie);
2850 std::string ModuleName = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
2851
2852 /// Using a SmallString<0> because loadClangModule() is recursive.
2853 SmallString<0> Path(Options.PrependPath);
2854 if (sys::path::is_relative(PCMFile))
2855 resolveRelativeObjectPath(Path, CUDie);
2856 sys::path::append(Path, PCMFile);
2857 // Don't use the cached binary holder because we have no thread-safety
2858 // guarantee and the lifetime is limited.
2859
2860 if (Loader == nullptr) {
2861 reportError("Could not load clang module: loader is not specified.\n",
2862 Context.File);
2863 return Error::success();
2864 }
2865
2866 auto ErrOrObj = Loader(Context.File.FileName, Path);
2867 if (!ErrOrObj)
2868 return Error::success();
2869
2870 std::unique_ptr<CompileUnit> Unit;
2871 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) {
2872 OnCUDieLoaded(*CU);
2873 // Recursively get all modules imported by this one.
2874 auto ChildCUDie = CU->getUnitDIE();
2875 if (!ChildCUDie)
2876 continue;
2877 if (!registerModuleReference(ChildCUDie, Context, Loader, OnCUDieLoaded,
2878 Indent)) {
2879 if (Unit) {
2880 std::string Err =
2881 (PCMFile +
2882 ": Clang modules are expected to have exactly 1 compile unit.\n");
2883 reportError(Err, Context.File);
2885 }
2886 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
2887 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
2888 // ASTFileSignatures will change randomly when a module is rebuilt.
2889 uint64_t PCMDwoId = getDwoId(ChildCUDie);
2890 if (PCMDwoId != DwoId) {
2891 if (Options.Verbose)
2892 reportWarning(
2893 Twine("hash mismatch: this object file was built against a "
2894 "different version of the module ") +
2895 PCMFile,
2896 Context.File);
2897 // Update the cache entry with the DwoId of the module loaded from disk.
2898 ClangModules[PCMFile] = PCMDwoId;
2899 }
2900
2901 // Add this module.
2902 Unit = std::make_unique<CompileUnit>(*CU, UniqueUnitID++, !Options.NoODR,
2903 ModuleName);
2904 }
2905 }
2906
2907 if (Unit)
2908 Context.ModuleUnits.emplace_back(RefModuleUnit{*ErrOrObj, std::move(Unit)});
2909
2910 return Error::success();
2911}
2912
2913Expected<uint64_t> DWARFLinker::DIECloner::cloneAllCompileUnits(
2914 DWARFContext &DwarfContext, const DWARFFile &File, bool IsLittleEndian) {
2915 uint64_t OutputDebugInfoSize =
2916 (Emitter == nullptr) ? 0 : Emitter->getDebugInfoSectionSize();
2917 const uint64_t StartOutputDebugInfoSize = OutputDebugInfoSize;
2918
2919 for (auto &CurrentUnit : CompileUnits) {
2920 const uint16_t DwarfVersion = CurrentUnit->getOrigUnit().getVersion();
2921 const uint32_t UnitHeaderSize = DwarfVersion >= 5 ? 12 : 11;
2922 auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE();
2923 CurrentUnit->setStartOffset(OutputDebugInfoSize);
2924 if (!InputDIE) {
2925 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);
2926 continue;
2927 }
2928 if (CurrentUnit->getInfo(0).Keep) {
2929 // Clone the InputDIE into your Unit DIE in our compile unit since it
2930 // already has a DIE inside of it.
2931 CurrentUnit->createOutputDIE();
2932 rememberUnitForMacroOffset(*CurrentUnit);
2933 cloneDIE(InputDIE, File, *CurrentUnit, 0 /* PC offset */, UnitHeaderSize,
2934 0, IsLittleEndian, CurrentUnit->getOutputUnitDIE());
2935 }
2936
2937 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);
2938
2939 if (Emitter != nullptr) {
2940
2941 if (Error E = generateLineTableForUnit(*CurrentUnit))
2942 return E;
2943
2944 Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
2945
2946 if (LLVM_UNLIKELY(Linker.Options.Update))
2947 continue;
2948
2949 if (Error E = Linker.generateUnitRanges(*CurrentUnit, File, AddrPool))
2950 return E;
2951
2952 auto ProcessExpr = [&](SmallVectorImpl<uint8_t> &SrcBytes,
2953 SmallVectorImpl<uint8_t> &OutBytes,
2954 int64_t RelocAdjustment) {
2955 DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit();
2956 DataExtractor Data(SrcBytes, IsLittleEndian);
2957 cloneExpression(Data,
2958 DWARFExpression(Data, OrigUnit.getAddressByteSize(),
2959 OrigUnit.getFormParams().Format),
2960 File, *CurrentUnit, OutBytes, RelocAdjustment,
2961 IsLittleEndian);
2962 };
2963 if (Error E = generateUnitLocations(*CurrentUnit, File, ProcessExpr))
2964 return E;
2965 if (Error E = emitDebugAddrSection(*CurrentUnit, DwarfVersion))
2966 return E;
2967 }
2968 AddrPool.clear();
2969 }
2970
2971 if (Emitter != nullptr) {
2972 assert(Emitter);
2973 // Emit macro tables.
2974 Emitter->emitMacroTables(File.Dwarf.get(), UnitMacroMap, DebugStrPool);
2975
2976 // Emit all the compile unit's debug information.
2977 for (auto &CurrentUnit : CompileUnits) {
2978 CurrentUnit->fixupForwardReferences();
2979
2980 if (!CurrentUnit->getOutputUnitDIE())
2981 continue;
2982
2983 unsigned DwarfVersion = CurrentUnit->getOrigUnit().getVersion();
2984
2985 assert(Emitter->getDebugInfoSectionSize() ==
2986 CurrentUnit->getStartOffset());
2987 Emitter->emitCompileUnitHeader(*CurrentUnit, DwarfVersion);
2988 Emitter->emitDIE(*CurrentUnit->getOutputUnitDIE());
2989 assert(Emitter->getDebugInfoSectionSize() ==
2990 CurrentUnit->computeNextUnitOffset(DwarfVersion));
2991 }
2992 }
2993
2994 return OutputDebugInfoSize - StartOutputDebugInfoSize;
2995}
2996
2997void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) {
2998 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getLocSection().Data,
3000 TheDwarfEmitter->emitSectionContents(
3001 Dwarf.getDWARFObj().getRangesSection().Data,
3003 TheDwarfEmitter->emitSectionContents(
3004 Dwarf.getDWARFObj().getFrameSection().Data, DebugSectionKind::DebugFrame);
3005 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(),
3007 TheDwarfEmitter->emitSectionContents(
3008 Dwarf.getDWARFObj().getAddrSection().Data, DebugSectionKind::DebugAddr);
3009 TheDwarfEmitter->emitSectionContents(
3010 Dwarf.getDWARFObj().getRnglistsSection().Data,
3012 TheDwarfEmitter->emitSectionContents(
3013 Dwarf.getDWARFObj().getLoclistsSection().Data,
3015}
3016
3018 CompileUnitHandlerTy OnCUDieLoaded) {
3019 ObjectContexts.emplace_back(LinkContext(File));
3020
3021 if (ObjectContexts.back().File.Dwarf) {
3022 for (const std::unique_ptr<DWARFUnit> &CU :
3023 ObjectContexts.back().File.Dwarf->compile_units()) {
3024 DWARFDie CUDie = CU->getUnitDIE();
3025
3026 if (!CUDie)
3027 continue;
3028
3029 OnCUDieLoaded(*CU);
3030
3031 if (!LLVM_UNLIKELY(Options.Update))
3032 registerModuleReference(CUDie, ObjectContexts.back(), Loader,
3033 OnCUDieLoaded);
3034 }
3035 }
3036}
3037
3039 assert((Options.TargetDWARFVersion != 0) &&
3040 "TargetDWARFVersion should be set");
3041
3042 // First populate the data structure we need for each iteration of the
3043 // parallel loop.
3044 unsigned NumObjects = ObjectContexts.size();
3045
3046 // This Dwarf string pool which is used for emission. It must be used
3047 // serially as the order of calling getStringOffset matters for
3048 // reproducibility.
3049 OffsetsStringPool DebugStrPool(true);
3050 OffsetsStringPool DebugLineStrPool(false);
3051 DebugDieValuePool StringOffsetPool;
3052
3053 // ODR Contexts for the optimize.
3054 DeclContextTree ODRContexts;
3055
3056 for (LinkContext &OptContext : ObjectContexts) {
3057 if (Options.Verbose)
3058 outs() << "DEBUG MAP OBJECT: " << OptContext.File.FileName << "\n";
3059
3060 if (!OptContext.File.Dwarf)
3061 continue;
3062
3063 if (Options.VerifyInputDWARF)
3064 verifyInput(OptContext.File);
3065
3066 // Look for relocations that correspond to address map entries.
3067
3068 // there was findvalidrelocations previously ... probably we need to gather
3069 // info here
3070 if (LLVM_LIKELY(!Options.Update) &&
3071 !OptContext.File.Addresses->hasValidRelocs()) {
3072 if (Options.Verbose)
3073 outs() << "No valid relocations found. Skipping.\n";
3074
3075 // Set "Skip" flag as a signal to other loops that we should not
3076 // process this iteration.
3077 OptContext.Skip = true;
3078 continue;
3079 }
3080
3081 // Setup access to the debug info.
3082 if (!OptContext.File.Dwarf)
3083 continue;
3084
3085 // Check whether type units are presented.
3086 if (!OptContext.File.Dwarf->types_section_units().empty()) {
3087 reportWarning("type units are not currently supported: file will "
3088 "be skipped",
3089 OptContext.File);
3090 OptContext.Skip = true;
3091 continue;
3092 }
3093
3094 // Clone all the clang modules with requires extracting the DIE units. We
3095 // don't need the full debug info until the Analyze phase.
3096 OptContext.CompileUnits.reserve(
3097 OptContext.File.Dwarf->getNumCompileUnits());
3098 for (const auto &CU : OptContext.File.Dwarf->compile_units()) {
3099 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/true);
3100 if (Options.Verbose) {
3101 outs() << "Input compilation unit:";
3102 DIDumpOptions DumpOpts;
3103 DumpOpts.ChildRecurseDepth = 0;
3104 DumpOpts.Verbose = Options.Verbose;
3105 CUDie.dump(outs(), 0, DumpOpts);
3106 }
3107 }
3108
3109 for (auto &CU : OptContext.ModuleUnits) {
3110 if (Error Err = cloneModuleUnit(OptContext, CU, ODRContexts, DebugStrPool,
3111 DebugLineStrPool, StringOffsetPool))
3112 reportWarning(toString(std::move(Err)), CU.File);
3113 }
3114 }
3115
3116 // At this point we know how much data we have emitted. We use this value to
3117 // compare canonical DIE offsets in analyzeContextInfo to see if a definition
3118 // is already emitted, without being affected by canonical die offsets set
3119 // later. This prevents undeterminism when analyze and clone execute
3120 // concurrently, as clone set the canonical DIE offset and analyze reads it.
3121 const uint64_t ModulesEndOffset =
3122 (TheDwarfEmitter == nullptr) ? 0
3123 : TheDwarfEmitter->getDebugInfoSectionSize();
3124
3125 // These variables manage the list of processed object files.
3126 // The mutex and condition variable are to ensure that this is thread safe.
3127 std::mutex ProcessedFilesMutex;
3128 std::condition_variable ProcessedFilesConditionVariable;
3129 BitVector ProcessedFiles(NumObjects, false);
3130
3131 // Analyzing the context info is particularly expensive so it is executed in
3132 // parallel with emitting the previous compile unit.
3133 auto AnalyzeLambda = [&](size_t I) {
3134 auto &Context = ObjectContexts[I];
3135
3136 if (Context.Skip || !Context.File.Dwarf)
3137 return;
3138
3139 for (const auto &CU : Context.File.Dwarf->compile_units()) {
3140 // Previously we only extracted the unit DIEs. We need the full debug info
3141 // now.
3142 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);
3143 std::string PCMFile = getPCMFile(CUDie, Options.ObjectPrefixMap);
3144
3145 if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
3146 !isClangModuleRef(CUDie, PCMFile, Context, 0, true).first) {
3147 Context.CompileUnits.push_back(std::make_unique<CompileUnit>(
3148 *CU, UniqueUnitID++, !Options.NoODR && !Options.Update, ""));
3149 }
3150 }
3151
3152 // Now build the DIE parent links that we will use during the next phase.
3153 for (auto &CurrentUnit : Context.CompileUnits) {
3154 auto CUDie = CurrentUnit->getOrigUnit().getUnitDIE();
3155 if (!CUDie)
3156 continue;
3157 analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0,
3158 *CurrentUnit, &ODRContexts.getRoot(), ODRContexts,
3159 ModulesEndOffset, Options.ParseableSwiftInterfaces,
3160 [&](const Twine &Warning, const DWARFDie &DIE) {
3161 reportWarning(Warning, Context.File, &DIE);
3162 });
3163 }
3164 };
3165
3166 // For each object file map how many bytes were emitted.
3167 StringMap<DebugInfoSize> SizeByObject;
3168
3169 // And then the remaining work in serial again.
3170 // Note, although this loop runs in serial, it can run in parallel with
3171 // the analyzeContextInfo loop so long as we process files with indices >=
3172 // than those processed by analyzeContextInfo.
3173 auto CloneLambda = [&](size_t I, llvm::Error &CE) {
3174 auto &OptContext = ObjectContexts[I];
3175 if (OptContext.Skip || !OptContext.File.Dwarf)
3176 return;
3177
3178 // Then mark all the DIEs that need to be present in the generated output
3179 // and collect some information about them.
3180 // Note that this loop can not be merged with the previous one because
3181 // cross-cu references require the ParentIdx to be setup for every CU in
3182 // the object file before calling this.
3183 if (LLVM_UNLIKELY(Options.Update)) {
3184 for (auto &CurrentUnit : OptContext.CompileUnits)
3185 CurrentUnit->markEverythingAsKept();
3186 copyInvariantDebugSection(*OptContext.File.Dwarf);
3187 } else {
3188 for (auto &CurrentUnit : OptContext.CompileUnits) {
3189 lookForDIEsToKeep(*OptContext.File.Addresses, OptContext.CompileUnits,
3190 CurrentUnit->getOrigUnit().getUnitDIE(),
3191 OptContext.File, *CurrentUnit, 0);
3192#ifndef NDEBUG
3193 verifyKeepChain(*CurrentUnit);
3194#endif
3195 }
3196 }
3197
3198 // The calls to applyValidRelocs inside cloneDIE will walk the reloc
3199 // array again (in the same way findValidRelocsInDebugInfo() did). We
3200 // need to reset the NextValidReloc index to the beginning.
3201 if (OptContext.File.Addresses->hasValidRelocs() ||
3202 LLVM_UNLIKELY(Options.Update)) {
3203 SizeByObject[OptContext.File.FileName].Input =
3204 getDebugInfoSize(*OptContext.File.Dwarf);
3205 Expected<uint64_t> SizeOrErr =
3206 DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc,
3207 OptContext.CompileUnits, Options.Update, DebugStrPool,
3208 DebugLineStrPool, StringOffsetPool)
3209 .cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File,
3210 OptContext.File.Dwarf->isLittleEndian());
3211 if (!SizeOrErr) {
3212 CE = SizeOrErr.takeError();
3213 return;
3214 }
3215 SizeByObject[OptContext.File.FileName].Output = *SizeOrErr;
3216 }
3217 if ((TheDwarfEmitter != nullptr) && !OptContext.CompileUnits.empty() &&
3218 LLVM_LIKELY(!Options.Update))
3219 patchFrameInfoForObject(OptContext);
3220
3221 // Clean-up before starting working on the next object.
3222 cleanupAuxiliarryData(OptContext);
3223 };
3224
3225 auto EmitLambda = [&]() {
3226 // Emit everything that's global.
3227 if (TheDwarfEmitter != nullptr) {
3228 TheDwarfEmitter->emitAbbrevs(Abbreviations, Options.TargetDWARFVersion);
3229 TheDwarfEmitter->emitStrings(DebugStrPool);
3230 TheDwarfEmitter->emitStringOffsets(StringOffsetPool.getValues(),
3231 Options.TargetDWARFVersion);
3232 TheDwarfEmitter->emitLineStrings(DebugLineStrPool);
3233 for (AccelTableKind TableKind : Options.AccelTables) {
3234 switch (TableKind) {
3236 TheDwarfEmitter->emitAppleNamespaces(AppleNamespaces);
3237 TheDwarfEmitter->emitAppleNames(AppleNames);
3238 TheDwarfEmitter->emitAppleTypes(AppleTypes);
3239 TheDwarfEmitter->emitAppleObjc(AppleObjc);
3240 break;
3242 // Already emitted by emitAcceleratorEntriesForUnit.
3243 // Already emitted by emitAcceleratorEntriesForUnit.
3244 break;
3246 TheDwarfEmitter->emitDebugNames(DebugNames);
3247 break;
3248 }
3249 }
3250 }
3251 };
3252
3253 auto AnalyzeAll = [&]() {
3254 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3255 AnalyzeLambda(I);
3256
3257 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
3258 ProcessedFiles.set(I);
3259 ProcessedFilesConditionVariable.notify_one();
3260 }
3261 };
3262
3263 auto CloneAll = [&](llvm::Error &CE) {
3264 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3265 {
3266 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
3267 if (!ProcessedFiles[I]) {
3268 ProcessedFilesConditionVariable.wait(
3269 LockGuard, [&]() { return ProcessedFiles[I]; });
3270 }
3271 }
3272
3273 CloneLambda(I, CE);
3274 if (CE)
3275 return;
3276 }
3277 EmitLambda();
3278 };
3279
3280 Error CE = Error::success();
3281
3282 // To limit memory usage in the single threaded case, analyze and clone are
3283 // run sequentially so the OptContext is freed after processing each object
3284 // in endDebugObject.
3285 if (Options.Threads == 1) {
3286 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3287 AnalyzeLambda(I);
3288 CloneLambda(I, CE);
3289 if (CE)
3290 break;
3291 }
3292 if (!CE)
3293 EmitLambda();
3294 } else {
3296 Pool.async(AnalyzeAll);
3297 Pool.async(CloneAll, std::reference_wrapper<Error>(CE));
3298 Pool.wait();
3299 }
3300
3301 if (CE)
3302 return CE;
3303
3304 if (Options.Statistics) {
3305 // Create a vector sorted in descending order by output size.
3306 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted;
3307 for (auto &E : SizeByObject)
3308 Sorted.emplace_back(E.first(), E.second);
3309 llvm::sort(Sorted, [](auto &LHS, auto &RHS) {
3310 return LHS.second.Output > RHS.second.Output;
3311 });
3312
3313 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float {
3314 const float Difference = Output - Input;
3315 const float Sum = Input + Output;
3316 if (Sum == 0)
3317 return 0;
3318 return (Difference / (Sum / 2));
3319 };
3320
3321 int64_t InputTotal = 0;
3322 int64_t OutputTotal = 0;
3323 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
3324
3325 // Print header.
3326 outs() << ".debug_info section size (in bytes)\n";
3327 outs() << "----------------------------------------------------------------"
3328 "---------------\n";
3329 outs() << "Filename Object "
3330 " dSYM Change\n";
3331 outs() << "----------------------------------------------------------------"
3332 "---------------\n";
3333
3334 // Print body.
3335 for (auto &E : Sorted) {
3336 InputTotal += E.second.Input;
3337 OutputTotal += E.second.Output;
3338 llvm::outs() << formatv(
3339 FormatStr, sys::path::filename(E.first).take_back(45), E.second.Input,
3340 E.second.Output, ComputePercentange(E.second.Input, E.second.Output));
3341 }
3342 // Print total and footer.
3343 outs() << "----------------------------------------------------------------"
3344 "---------------\n";
3345 llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal,
3346 ComputePercentange(InputTotal, OutputTotal));
3347 outs() << "----------------------------------------------------------------"
3348 "---------------\n\n";
3349 }
3350
3351 return Error::success();
3352}
3353
3354Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
3355 DeclContextTree &ODRContexts,
3356 OffsetsStringPool &DebugStrPool,
3357 OffsetsStringPool &DebugLineStrPool,
3358 DebugDieValuePool &StringOffsetPool,
3359 unsigned Indent) {
3360 assert(Unit.Unit.get() != nullptr);
3361
3362 if (!Unit.Unit->getOrigUnit().getUnitDIE().hasChildren())
3363 return Error::success();
3364
3365 if (Options.Verbose) {
3366 outs().indent(Indent);
3367 outs() << "cloning .debug_info from " << Unit.File.FileName << "\n";
3368 }
3369
3370 // Analyze context for the module.
3371 analyzeContextInfo(Unit.Unit->getOrigUnit().getUnitDIE(), 0, *(Unit.Unit),
3372 &ODRContexts.getRoot(), ODRContexts, 0,
3373 Options.ParseableSwiftInterfaces,
3374 [&](const Twine &Warning, const DWARFDie &DIE) {
3375 reportWarning(Warning, Context.File, &DIE);
3376 });
3377 // Keep everything.
3378 Unit.Unit->markEverythingAsKept();
3379
3380 // Clone unit.
3381 UnitListTy CompileUnits;
3382 CompileUnits.emplace_back(std::move(Unit.Unit));
3383 assert(TheDwarfEmitter);
3384 Expected<uint64_t> SizeOrErr =
3385 DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits,
3386 Options.Update, DebugStrPool, DebugLineStrPool,
3387 StringOffsetPool)
3388 .cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File,
3389 Unit.File.Dwarf->isLittleEndian());
3390 if (!SizeOrErr)
3391 return SizeOrErr.takeError();
3392 return Error::success();
3393}
3394
3395void DWARFLinker::verifyInput(const DWARFFile &File) {
3396 assert(File.Dwarf);
3397
3398 std::string Buffer;
3399 raw_string_ostream OS(Buffer);
3400 DIDumpOptions DumpOpts;
3401 if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) {
3402 if (Options.InputVerificationHandler)
3403 Options.InputVerificationHandler(File, OS.str());
3404 }
3405}
3406
3407} // namespace llvm
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned 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:352
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:351
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
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 LLVM_ABI 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:66
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:41
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:102
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?