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 void *InsertToken;
1106 DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken);
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.InsertNode(Abbreviations.back().get(), InsertToken);
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 auto Desc = Op.getDescription();
1253 // DW_OP_const_type is variable-length and has 3
1254 // operands. Thus far we only support 2.
1255 if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1256 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1257 Desc.Op[0] != Encoding::Size1))
1258 Linker.reportWarning("Unsupported DW_OP encoding.", File);
1259
1260 if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1261 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1262 Desc.Op[0] == Encoding::Size1)) {
1263 // This code assumes that the other non-typeref operand fits into 1 byte.
1264 assert(OpOffset < Op.getEndOffset());
1265 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;
1266 assert(ULEBsize <= 16);
1267
1268 // Copy over the operation.
1269 assert(!Op.getSubCode() && "SubOps not yet supported");
1270 OutputBuffer.push_back(Op.getCode());
1271 uint64_t RefOffset;
1272 if (Desc.Op.size() == 1) {
1273 RefOffset = Op.getRawOperand(0);
1274 } else {
1275 OutputBuffer.push_back(Op.getRawOperand(0));
1276 RefOffset = Op.getRawOperand(1);
1277 }
1278 uint32_t Offset = 0;
1279 // Look up the base type. For DW_OP_convert, the operand may be 0 to
1280 // instead indicate the generic type. The same holds for
1281 // DW_OP_reinterpret, which is currently not supported.
1282 if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {
1283 RefOffset += Unit.getOrigUnit().getOffset();
1284 auto RefDie = Unit.getOrigUnit().getDIEForOffset(RefOffset);
1285 CompileUnit::DIEInfo &Info = Unit.getInfo(RefDie);
1286 if (DIE *Clone = Info.Clone)
1287 Offset = Clone->getOffset();
1288 else
1289 Linker.reportWarning(
1290 "base type ref doesn't point to DW_TAG_base_type.", File);
1291 }
1292 uint8_t ULEB[16];
1293 unsigned RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
1294 if (RealSize > ULEBsize) {
1295 // Emit the generic type as a fallback.
1296 RealSize = encodeULEB128(0, ULEB, ULEBsize);
1297 Linker.reportWarning("base type ref doesn't fit.", File);
1298 }
1299 assert(RealSize == ULEBsize && "padding failed");
1300 ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
1301 OutputBuffer.append(ULEBbytes.begin(), ULEBbytes.end());
1302 } else if (!Linker.Options.Update && Op.getCode() == dwarf::DW_OP_addrx) {
1303 if (std::optional<object::SectionedAddress> SA =
1304 Unit.getOrigUnit().getAddrOffsetSectionItem(
1305 Op.getRawOperand(0))) {
1306 // DWARFLinker does not use addrx forms since it generates relocated
1307 // addresses. Replace DW_OP_addrx with DW_OP_addr here.
1308 // Argument of DW_OP_addrx should be relocated here as it is not
1309 // processed by applyValidRelocs.
1310 OutputBuffer.push_back(dwarf::DW_OP_addr);
1311 uint64_t LinkedAddress = SA->Address + AddrRelocAdjustment;
1312 if (IsLittleEndian != sys::IsLittleEndianHost)
1313 sys::swapByteOrder(LinkedAddress);
1314 ArrayRef<uint8_t> AddressBytes(
1315 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1316 OrigAddressByteSize);
1317 OutputBuffer.append(AddressBytes.begin(), AddressBytes.end());
1318 } else
1319 Linker.reportWarning("cannot read DW_OP_addrx operand.", File);
1320 } else if (!Linker.Options.Update && Op.getCode() == dwarf::DW_OP_constx) {
1321 if (std::optional<object::SectionedAddress> SA =
1322 Unit.getOrigUnit().getAddrOffsetSectionItem(
1323 Op.getRawOperand(0))) {
1324 // DWARFLinker does not use constx forms since it generates relocated
1325 // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1326 // Argument of DW_OP_constx should be relocated here as it is not
1327 // processed by applyValidRelocs.
1328 std::optional<uint8_t> OutOperandKind;
1329 switch (OrigAddressByteSize) {
1330 case 4:
1331 OutOperandKind = dwarf::DW_OP_const4u;
1332 break;
1333 case 8:
1334 OutOperandKind = dwarf::DW_OP_const8u;
1335 break;
1336 default:
1337 Linker.reportWarning(
1338 formatv(("unsupported address size: {0}."), OrigAddressByteSize),
1339 File);
1340 break;
1341 }
1342
1343 if (OutOperandKind) {
1344 OutputBuffer.push_back(*OutOperandKind);
1345 uint64_t LinkedAddress = SA->Address + AddrRelocAdjustment;
1346 if (IsLittleEndian != sys::IsLittleEndianHost)
1347 sys::swapByteOrder(LinkedAddress);
1348 ArrayRef<uint8_t> AddressBytes(
1349 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1350 OrigAddressByteSize);
1351 OutputBuffer.append(AddressBytes.begin(), AddressBytes.end());
1352 }
1353 } else
1354 Linker.reportWarning("cannot read DW_OP_constx operand.", File);
1355 } else {
1356 // Copy over everything else unmodified.
1357 StringRef Bytes = Data.getData().slice(OpOffset, Op.getEndOffset());
1358 OutputBuffer.append(Bytes.begin(), Bytes.end());
1359 }
1360 OpOffset = Op.getEndOffset();
1361 }
1362}
1363
1364unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
1365 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File,
1366 CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
1367 bool IsLittleEndian) {
1368 DIEValueList *Attr;
1369 DIEValue Value;
1370 DIELoc *Loc = nullptr;
1371 DIEBlock *Block = nullptr;
1372 if (AttrSpec.Form == dwarf::DW_FORM_exprloc) {
1373 Loc = new (DIEAlloc) DIELoc;
1374 Linker.DIELocs.push_back(Loc);
1375 } else {
1376 Block = new (DIEAlloc) DIEBlock;
1377 Linker.DIEBlocks.push_back(Block);
1378 }
1379 Attr = Loc ? static_cast<DIEValueList *>(Loc)
1380 : static_cast<DIEValueList *>(Block);
1381
1382 DWARFUnit &OrigUnit = Unit.getOrigUnit();
1383 // If the block is a DWARF Expression, clone it into the temporary
1384 // buffer using cloneExpression(), otherwise copy the data directly.
1385 SmallVector<uint8_t, 32> Buffer;
1386 ArrayRef<uint8_t> Bytes = *Val.getAsBlock();
1387 if (DWARFAttribute::mayHaveLocationExpr(AttrSpec.Attr) &&
1388 (Val.isFormClass(DWARFFormValue::FC_Block) ||
1389 Val.isFormClass(DWARFFormValue::FC_Exprloc))) {
1390 DataExtractor Data(Bytes, IsLittleEndian);
1391 DWARFExpression Expr(Data, OrigUnit.getAddressByteSize(),
1392 OrigUnit.getFormParams().Format);
1393 cloneExpression(Data, Expr, File, Unit, Buffer,
1394 Unit.getInfo(InputDIE).AddrAdjust, IsLittleEndian);
1395 Bytes = Buffer;
1396 }
1397 for (auto Byte : Bytes)
1398 Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0),
1399 dwarf::DW_FORM_data1, DIEInteger(Byte));
1400
1401 // FIXME: If DIEBlock and DIELoc just reuses the Size field of
1402 // the DIE class, this "if" could be replaced by
1403 // Attr->setSize(Bytes.size()).
1404 if (Loc)
1405 Loc->setSize(Bytes.size());
1406 else
1407 Block->setSize(Bytes.size());
1408
1409 if (Loc)
1410 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
1411 dwarf::Form(AttrSpec.Form), Loc);
1412 else {
1413 // The expression location data might be updated and exceed the original
1414 // size. Check whether the new data fits into the original form.
1415 if ((AttrSpec.Form == dwarf::DW_FORM_block1 &&
1416 (Bytes.size() > UINT8_MAX)) ||
1417 (AttrSpec.Form == dwarf::DW_FORM_block2 &&
1418 (Bytes.size() > UINT16_MAX)) ||
1419 (AttrSpec.Form == dwarf::DW_FORM_block4 && (Bytes.size() > UINT32_MAX)))
1420 AttrSpec.Form = dwarf::DW_FORM_block;
1421
1422 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
1423 dwarf::Form(AttrSpec.Form), Block);
1424 }
1425
1426 return Die.addValue(DIEAlloc, Value)->sizeOf(OrigUnit.getFormParams());
1427}
1428
1429/// Returns \p InputDIE's DW_AT_high_pc value \p HighPC, constrained so the code
1430/// range it ends stays clear of the symbol the linker places next. \p IsLength
1431/// tells whether high_pc is encoded as a length rather than an address, and
1432/// \p PCOffset is the amount the range shifts by in the output.
1433///
1434/// A scope nested in a function inherits the overrun of the function, so it is
1435/// constrained as well.
1436static uint64_t constrainHighPC(const DWARFDie &InputDIE, uint64_t HighPC,
1437 bool IsLength, int64_t PCOffset,
1438 AddressesMap &Addresses) {
1439 std::optional<uint64_t> LowPC =
1440 dwarf::toAddress(InputDIE.find(dwarf::DW_AT_low_pc));
1441 if (!LowPC)
1442 return HighPC;
1443 uint64_t Constrained = Addresses.constrainCodeRangeHighPC(
1444 *LowPC, IsLength ? *LowPC + HighPC : HighPC, PCOffset);
1445 return IsLength ? Constrained - *LowPC : Constrained;
1446}
1447
1448unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
1449 DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec,
1450 unsigned AttrSize, const DWARFFormValue &Val, const CompileUnit &Unit,
1451 AttributesInfo &Info) {
1452 if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
1453 Info.HasLowPc = true;
1454
1455 if (LLVM_UNLIKELY(Linker.Options.Update)) {
1456 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1457 dwarf::Form(AttrSpec.Form), DIEInteger(Val.getRawUValue()));
1458 return AttrSize;
1459 }
1460
1461 // Cloned Die may have address attributes relocated to a
1462 // totally unrelated value. This can happen:
1463 // - If high_pc is an address (Dwarf version == 2), then it might have been
1464 // relocated to a totally unrelated value (because the end address in the
1465 // object file might be start address of another function which got moved
1466 // independently by the linker).
1467 // - If address relocated in an inline_subprogram that happens at the
1468 // beginning of its inlining function.
1469 // To avoid above cases and to not apply relocation twice (in
1470 // applyValidRelocs and here), read address attribute from InputDIE and apply
1471 // Info.PCOffset here.
1472
1473 std::optional<DWARFFormValue> AddrAttribute = InputDIE.find(AttrSpec.Attr);
1474 if (!AddrAttribute)
1475 llvm_unreachable("Cann't find attribute.");
1476
1477 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress();
1478 if (!Addr) {
1479 Linker.reportWarning("Cann't read address attribute value.", ObjFile);
1480 return 0;
1481 }
1482
1483 if (InputDIE.getTag() == dwarf::DW_TAG_compile_unit &&
1484 AttrSpec.Attr == dwarf::DW_AT_low_pc) {
1485 if (std::optional<uint64_t> LowPC = Unit.getLowPc())
1486 Addr = *LowPC;
1487 else
1488 return 0;
1489 } else if (InputDIE.getTag() == dwarf::DW_TAG_compile_unit &&
1490 AttrSpec.Attr == dwarf::DW_AT_high_pc) {
1491 if (uint64_t HighPc = Unit.getHighPc())
1492 Addr = HighPc;
1493 else
1494 return 0;
1495 } else {
1496 if (AttrSpec.Attr == dwarf::DW_AT_high_pc)
1497 Addr = constrainHighPC(InputDIE, *Addr, /*IsLength=*/false, Info.PCOffset,
1498 *ObjFile.Addresses);
1499 *Addr += Info.PCOffset;
1500 }
1501
1502 if (AttrSpec.Form == dwarf::DW_FORM_addr) {
1503 Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr),
1504 AttrSpec.Form, DIEInteger(*Addr));
1505 return Unit.getOrigUnit().getAddressByteSize();
1506 }
1507
1508 auto AddrIndex = AddrPool.getValueIndex(*Addr);
1509
1510 return Die
1511 .addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr),
1512 dwarf::Form::DW_FORM_addrx, DIEInteger(AddrIndex))
1513 ->sizeOf(Unit.getOrigUnit().getFormParams());
1514}
1515
1516unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
1517 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File,
1518 CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val,
1519 unsigned AttrSize, AttributesInfo &Info) {
1520 uint64_t Value;
1521
1522 // We don't emit any skeleton CUs with dsymutil. So avoid emitting
1523 // a redundant DW_AT_GNU_dwo_id on the non-skeleton CU.
1524 if (AttrSpec.Attr == dwarf::DW_AT_GNU_dwo_id ||
1525 AttrSpec.Attr == dwarf::DW_AT_dwo_id)
1526 return 0;
1527
1528 // Check for the offset to the macro table. If offset is incorrect then we
1529 // need to remove the attribute.
1530 if (AttrSpec.Attr == dwarf::DW_AT_macro_info) {
1531 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
1532 const llvm::DWARFDebugMacro *Macro = File.Dwarf->getDebugMacinfo();
1533 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
1534 return 0;
1535 }
1536 }
1537
1538 if (AttrSpec.Attr == dwarf::DW_AT_macros) {
1539 if (std::optional<uint64_t> Offset = Val.getAsSectionOffset()) {
1540 const llvm::DWARFDebugMacro *Macro = File.Dwarf->getDebugMacro();
1541 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset))
1542 return 0;
1543 }
1544 }
1545
1546 if (AttrSpec.Attr == dwarf::DW_AT_str_offsets_base) {
1547 // DWARFLinker generates common .debug_str_offsets table used for all
1548 // compile units. The offset to the common .debug_str_offsets table is 8 on
1549 // DWARF32.
1550 Info.AttrStrOffsetBaseSeen = true;
1551 return Die
1552 .addValue(DIEAlloc, dwarf::DW_AT_str_offsets_base,
1553 dwarf::DW_FORM_sec_offset, DIEInteger(8))
1554 ->sizeOf(Unit.getOrigUnit().getFormParams());
1555 }
1556
1557 if (AttrSpec.Attr == dwarf::DW_AT_LLVM_stmt_sequence) {
1558 // If needed, we'll patch this sec_offset later with the correct offset.
1559 auto Patch = Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1560 dwarf::DW_FORM_sec_offset,
1561 DIEInteger(*Val.getAsSectionOffset()));
1562
1563 // Record this patch location so that it can be fixed up later.
1564 Unit.noteStmtSeqListAttribute(Patch);
1565
1566 return Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
1567 }
1568
1569 if (LLVM_UNLIKELY(Linker.Options.Update)) {
1570 if (auto OptionalValue = Val.getAsUnsignedConstant())
1571 Value = *OptionalValue;
1572 else if (auto OptionalValue = Val.getAsSignedConstant())
1573 Value = *OptionalValue;
1574 else if (auto OptionalValue = Val.getAsSectionOffset())
1575 Value = *OptionalValue;
1576 else {
1577 Linker.reportWarning(
1578 "Unsupported scalar attribute form. Dropping attribute.", File,
1579 &InputDIE);
1580 return 0;
1581 }
1582 if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
1583 Info.IsDeclaration = true;
1584
1585 if (AttrSpec.Form == dwarf::DW_FORM_loclistx)
1586 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1587 dwarf::Form(AttrSpec.Form), DIELocList(Value));
1588 else
1589 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1590 dwarf::Form(AttrSpec.Form), DIEInteger(Value));
1591 return AttrSize;
1592 }
1593
1594 [[maybe_unused]] dwarf::Form OriginalForm = AttrSpec.Form;
1595 if (AttrSpec.Form == dwarf::DW_FORM_rnglistx) {
1596 // DWARFLinker does not generate .debug_addr table. Thus we need to change
1597 // all "addrx" related forms to "addr" version. Change DW_FORM_rnglistx
1598 // to DW_FORM_sec_offset here.
1599 std::optional<uint64_t> Index = Val.getAsSectionOffset();
1600 if (!Index) {
1601 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1602 &InputDIE);
1603 return 0;
1604 }
1605 std::optional<uint64_t> Offset =
1606 Unit.getOrigUnit().getRnglistOffset(*Index);
1607 if (!Offset) {
1608 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1609 &InputDIE);
1610 return 0;
1611 }
1612
1613 Value = *Offset;
1614 AttrSpec.Form = dwarf::DW_FORM_sec_offset;
1615 AttrSize = Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
1616 } else if (AttrSpec.Form == dwarf::DW_FORM_loclistx) {
1617 // DWARFLinker does not generate .debug_addr table. Thus we need to change
1618 // all "addrx" related forms to "addr" version. Change DW_FORM_loclistx
1619 // to DW_FORM_sec_offset here.
1620 std::optional<uint64_t> Index = Val.getAsSectionOffset();
1621 if (!Index) {
1622 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1623 &InputDIE);
1624 return 0;
1625 }
1626 std::optional<uint64_t> Offset =
1627 Unit.getOrigUnit().getLoclistOffset(*Index);
1628 if (!Offset) {
1629 Linker.reportWarning("Cannot read the attribute. Dropping.", File,
1630 &InputDIE);
1631 return 0;
1632 }
1633
1634 Value = *Offset;
1635 AttrSpec.Form = dwarf::DW_FORM_sec_offset;
1636 AttrSize = Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
1637 } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
1638 Die.getTag() == dwarf::DW_TAG_compile_unit) {
1639 std::optional<uint64_t> LowPC = Unit.getLowPc();
1640 if (!LowPC)
1641 return 0;
1642 // Dwarf >= 4 high_pc is an size, not an address.
1643 Value = Unit.getHighPc() - *LowPC;
1644 } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset)
1645 Value = *Val.getAsSectionOffset();
1646 else if (AttrSpec.Form == dwarf::DW_FORM_sdata)
1647 Value = *Val.getAsSignedConstant();
1648 else if (auto OptionalValue = Val.getAsUnsignedConstant())
1649 Value = *OptionalValue;
1650 else {
1651 Linker.reportWarning(
1652 "Unsupported scalar attribute form. Dropping attribute.", File,
1653 &InputDIE);
1654 return 0;
1655 }
1656
1657 // A compile unit's high_pc comes from the unit's own linked range and spans
1658 // every symbol in it.
1659 if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
1660 Die.getTag() != dwarf::DW_TAG_compile_unit)
1661 Value = constrainHighPC(InputDIE, Value, /*IsLength=*/true, Info.PCOffset,
1662 *File.Addresses);
1663
1664 DIE::value_iterator Patch =
1665 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
1666 dwarf::Form(AttrSpec.Form), DIEInteger(Value));
1667 if (AttrSpec.Attr == dwarf::DW_AT_ranges ||
1668 AttrSpec.Attr == dwarf::DW_AT_start_scope) {
1669 Unit.noteRangeAttribute(Die, Patch);
1670 Info.HasRanges = true;
1671 } else if (DWARFAttribute::mayHaveLocationList(AttrSpec.Attr) &&
1672 dwarf::doesFormBelongToClass(AttrSpec.Form,
1674 Unit.getOrigUnit().getVersion())) {
1675
1676 CompileUnit::DIEInfo &LocationDieInfo = Unit.getInfo(InputDIE);
1677 Unit.noteLocationAttribute({Patch, LocationDieInfo.InDebugMap
1678 ? LocationDieInfo.AddrAdjust
1679 : Info.PCOffset});
1680 } else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
1681 Info.IsDeclaration = true;
1682
1683 // check that all dwarf::DW_FORM_rnglistx are handled previously.
1684 assert((Info.HasRanges || (OriginalForm != dwarf::DW_FORM_rnglistx)) &&
1685 "Unhandled DW_FORM_rnglistx attribute");
1686
1687 return AttrSize;
1688}
1689
1690/// Clone \p InputDIE's attribute described by \p AttrSpec with
1691/// value \p Val, and add it to \p Die.
1692/// \returns the size of the cloned attribute.
1693unsigned DWARFLinker::DIECloner::cloneAttribute(
1694 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File,
1695 CompileUnit &Unit, const DWARFFormValue &Val, const AttributeSpec AttrSpec,
1696 unsigned AttrSize, AttributesInfo &Info, bool IsLittleEndian) {
1697 const DWARFUnit &U = Unit.getOrigUnit();
1698
1699 switch (AttrSpec.Form) {
1700 case dwarf::DW_FORM_strp:
1701 case dwarf::DW_FORM_line_strp:
1702 case dwarf::DW_FORM_string:
1703 case dwarf::DW_FORM_strx:
1704 case dwarf::DW_FORM_strx1:
1705 case dwarf::DW_FORM_strx2:
1706 case dwarf::DW_FORM_strx3:
1707 case dwarf::DW_FORM_strx4:
1708 return cloneStringAttribute(Die, AttrSpec, Val, U, Info);
1709 case dwarf::DW_FORM_ref_addr:
1710 case dwarf::DW_FORM_ref1:
1711 case dwarf::DW_FORM_ref2:
1712 case dwarf::DW_FORM_ref4:
1713 case dwarf::DW_FORM_ref8:
1714 return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val,
1715 File, Unit);
1716 case dwarf::DW_FORM_block:
1717 case dwarf::DW_FORM_block1:
1718 case dwarf::DW_FORM_block2:
1719 case dwarf::DW_FORM_block4:
1720 case dwarf::DW_FORM_exprloc:
1721 return cloneBlockAttribute(Die, InputDIE, File, Unit, AttrSpec, Val,
1722 IsLittleEndian);
1723 case dwarf::DW_FORM_addr:
1724 case dwarf::DW_FORM_addrx:
1725 case dwarf::DW_FORM_addrx1:
1726 case dwarf::DW_FORM_addrx2:
1727 case dwarf::DW_FORM_addrx3:
1728 case dwarf::DW_FORM_addrx4:
1729 return cloneAddressAttribute(Die, InputDIE, AttrSpec, AttrSize, Val, Unit,
1730 Info);
1731 case dwarf::DW_FORM_data1:
1732 case dwarf::DW_FORM_data2:
1733 case dwarf::DW_FORM_data4:
1734 case dwarf::DW_FORM_data8:
1735 case dwarf::DW_FORM_udata:
1736 case dwarf::DW_FORM_sdata:
1737 case dwarf::DW_FORM_sec_offset:
1738 case dwarf::DW_FORM_flag:
1739 case dwarf::DW_FORM_flag_present:
1740 case dwarf::DW_FORM_rnglistx:
1741 case dwarf::DW_FORM_loclistx:
1742 case dwarf::DW_FORM_implicit_const:
1743 return cloneScalarAttribute(Die, InputDIE, File, Unit, AttrSpec, Val,
1744 AttrSize, Info);
1745 default:
1746 Linker.reportWarning("Unsupported attribute form " +
1747 dwarf::FormEncodingString(AttrSpec.Form) +
1748 " in cloneAttribute. Dropping.",
1749 File, &InputDIE);
1750 }
1751
1752 return 0;
1753}
1754
1755void DWARFLinker::DIECloner::addObjCAccelerator(CompileUnit &Unit,
1756 const DIE *Die,
1757 DwarfStringPoolEntryRef Name,
1758 OffsetsStringPool &StringPool,
1759 bool SkipPubSection) {
1760 std::optional<ObjCSelectorNames> Names =
1761 getObjCNamesIfSelector(Name.getString());
1762 if (!Names)
1763 return;
1764 Unit.addNameAccelerator(Die, StringPool.getEntry(Names->Selector),
1765 SkipPubSection);
1766 Unit.addObjCAccelerator(Die, StringPool.getEntry(Names->ClassName),
1767 SkipPubSection);
1768 if (Names->ClassNameNoCategory)
1769 Unit.addObjCAccelerator(
1770 Die, StringPool.getEntry(*Names->ClassNameNoCategory), SkipPubSection);
1771 if (Names->MethodNameNoCategory)
1772 Unit.addNameAccelerator(
1773 Die, StringPool.getEntry(*Names->MethodNameNoCategory), SkipPubSection);
1774}
1775
1776static bool
1779 bool SkipPC) {
1780 switch (AttrSpec.Attr) {
1781 default:
1782 return false;
1783 case dwarf::DW_AT_low_pc:
1784 case dwarf::DW_AT_high_pc:
1785 case dwarf::DW_AT_ranges:
1786 return !Update && SkipPC;
1787 case dwarf::DW_AT_rnglists_base:
1788 // In case !Update the .debug_addr table is not generated/preserved.
1789 // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used.
1790 // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
1791 // DW_AT_rnglists_base is removed.
1792 return !Update;
1793 case dwarf::DW_AT_loclists_base:
1794 // In case !Update the .debug_addr table is not generated/preserved.
1795 // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
1796 // Since DW_AT_loclists_base is used for only DW_FORM_loclistx the
1797 // DW_AT_loclists_base is removed.
1798 return !Update;
1799 case dwarf::DW_AT_location:
1800 case dwarf::DW_AT_frame_base:
1801 return !Update && SkipPC;
1802 }
1803}
1804
1810
1811DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
1812 const DWARFFile &File, CompileUnit &Unit,
1813 int64_t PCOffset, uint32_t OutOffset,
1814 unsigned Flags, bool IsLittleEndian,
1815 DIE *Die) {
1816 DWARFUnit &U = Unit.getOrigUnit();
1817 unsigned Idx = U.getDIEIndex(InputDIE);
1818 CompileUnit::DIEInfo &Info = Unit.getInfo(Idx);
1819
1820 // Should the DIE appear in the output?
1821 if (!Unit.getInfo(Idx).Keep)
1822 return nullptr;
1823
1824 uint64_t Offset = InputDIE.getOffset();
1825 assert(!(Die && Info.Clone) && "Can't supply a DIE and a cloned DIE");
1826 if (!Die) {
1827 // The DIE might have been already created by a forward reference
1828 // (see cloneDieReferenceAttribute()).
1829 if (!Info.Clone)
1830 Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag()));
1831 Die = Info.Clone;
1832 }
1833
1834 assert(Die->getTag() == InputDIE.getTag());
1835 Die->setOffset(OutOffset);
1836 if (isODRCanonicalCandidate(InputDIE, Unit) && Info.Ctxt &&
1837 (Info.Ctxt->getCanonicalDIEOffset() == 0)) {
1838 if (!Info.Ctxt->hasCanonicalDIE())
1839 Info.Ctxt->setHasCanonicalDIE();
1840 // We are about to emit a DIE that is the root of its own valid
1841 // DeclContext tree. Make the current offset the canonical offset
1842 // for this context.
1843 Info.Ctxt->setCanonicalDIEOffset(OutOffset + Unit.getStartOffset());
1844 }
1845
1846 // Extract and clone every attribute.
1847 DWARFDataExtractor Data = U.getDebugInfoExtractor();
1848 // Point to the next DIE (generally there is always at least a NULL
1849 // entry after the current one). If this is a lone
1850 // DW_TAG_compile_unit without any children, point to the next unit.
1851 uint64_t NextOffset = (Idx + 1 < U.getNumDIEs())
1852 ? U.getDIEAtIndex(Idx + 1).getOffset()
1853 : U.getNextUnitOffset();
1854 AttributesInfo AttrInfo;
1855
1856 // We could copy the data only if we need to apply a relocation to it. After
1857 // testing, it seems there is no performance downside to doing the copy
1858 // unconditionally, and it makes the code simpler.
1859 SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset));
1860 Data =
1861 DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize());
1862
1863 // Modify the copy with relocated addresses.
1864 ObjFile.Addresses->applyValidRelocs(DIECopy, Offset, Data.isLittleEndian());
1865
1866 // Reset the Offset to 0 as we will be working on the local copy of
1867 // the data.
1868 Offset = 0;
1869
1870 const auto *Abbrev = InputDIE.getAbbreviationDeclarationPtr();
1871 Offset += getULEB128Size(Abbrev->getCode());
1872
1873 // We are entering a subprogram. Get and propagate the PCOffset.
1874 if (Die->getTag() == dwarf::DW_TAG_subprogram)
1875 PCOffset = Info.AddrAdjust;
1876 AttrInfo.PCOffset = PCOffset;
1877
1878 if (Abbrev->getTag() == dwarf::DW_TAG_subprogram) {
1879 Flags |= TF_InFunctionScope;
1880 if (!Info.InDebugMap && LLVM_LIKELY(!Update))
1881 Flags |= TF_SkipPC;
1882 } else if (Abbrev->getTag() == dwarf::DW_TAG_variable) {
1883 // Function-local globals could be in the debug map even when the function
1884 // is not, e.g., inlined functions.
1885 if ((Flags & TF_InFunctionScope) && Info.InDebugMap)
1886 Flags &= ~TF_SkipPC;
1887 // Location expressions referencing an address which is not in debug map
1888 // should be deleted.
1889 else if (!Info.InDebugMap && Info.HasLocationExpressionAddr &&
1890 LLVM_LIKELY(!Update))
1891 Flags |= TF_SkipPC;
1892 }
1893
1894 std::optional<StringRef> LibraryInstallName =
1895 ObjFile.Addresses->getLibraryInstallName();
1897 for (const auto &AttrSpec : Abbrev->attributes()) {
1898 if (shouldSkipAttribute(Update, AttrSpec, Flags & TF_SkipPC)) {
1899 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset,
1900 U.getFormParams());
1901 continue;
1902 }
1903
1904 AttributeLinkedOffsetFixup CurAttrFixup;
1905 CurAttrFixup.InputAttrStartOffset = InputDIE.getOffset() + Offset;
1906 CurAttrFixup.LinkedOffsetFixupVal =
1907 Unit.getStartOffset() + OutOffset - CurAttrFixup.InputAttrStartOffset;
1908
1909 DWARFFormValue Val = AttrSpec.getFormValue();
1910 uint64_t AttrSize = Offset;
1911 Val.extractValue(Data, &Offset, U.getFormParams(), &U);
1912 CurAttrFixup.InputAttrEndOffset = InputDIE.getOffset() + Offset;
1913 AttrSize = Offset - AttrSize;
1914
1915 uint64_t FinalAttrSize =
1916 cloneAttribute(*Die, InputDIE, File, Unit, Val, AttrSpec, AttrSize,
1917 AttrInfo, IsLittleEndian);
1918 if (FinalAttrSize != 0 && ObjFile.Addresses->needToSaveValidRelocs())
1919 AttributesFixups.push_back(CurAttrFixup);
1920
1921 OutOffset += FinalAttrSize;
1922 }
1923
1924 uint16_t Tag = InputDIE.getTag();
1925 // Add the DW_AT_APPLE_origin attribute to Compile Unit die if we have
1926 // an install name and the DWARF doesn't have the attribute yet.
1927 const bool NeedsAppleOrigin = (Tag == dwarf::DW_TAG_compile_unit) &&
1928 LibraryInstallName.has_value() &&
1929 !AttrInfo.HasAppleOrigin;
1930 if (NeedsAppleOrigin) {
1931 auto StringEntry = DebugStrPool.getEntry(LibraryInstallName.value());
1932 Die->addValue(DIEAlloc, dwarf::Attribute(dwarf::DW_AT_APPLE_origin),
1933 dwarf::DW_FORM_strp, DIEInteger(StringEntry.getOffset()));
1934 AttrInfo.Name = StringEntry;
1935 OutOffset += 4;
1936 }
1937
1938 // Look for accelerator entries.
1939 // FIXME: This is slightly wrong. An inline_subroutine without a
1940 // low_pc, but with AT_ranges might be interesting to get into the
1941 // accelerator tables too. For now stick with dsymutil's behavior.
1942 if ((Info.InDebugMap || AttrInfo.HasLowPc || AttrInfo.HasRanges) &&
1943 Tag != dwarf::DW_TAG_compile_unit &&
1944 getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit,
1945 Tag != dwarf::DW_TAG_inlined_subroutine)) {
1946 if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)
1947 Unit.addNameAccelerator(Die, AttrInfo.MangledName,
1948 Tag == dwarf::DW_TAG_inlined_subroutine);
1949 if (AttrInfo.Name) {
1950 if (AttrInfo.NameWithoutTemplate)
1951 Unit.addNameAccelerator(Die, AttrInfo.NameWithoutTemplate,
1952 /* SkipPubSection */ true);
1953 Unit.addNameAccelerator(Die, AttrInfo.Name,
1954 Tag == dwarf::DW_TAG_inlined_subroutine);
1955 }
1956 if (AttrInfo.Name)
1957 addObjCAccelerator(Unit, Die, AttrInfo.Name, DebugStrPool,
1958 /* SkipPubSection =*/true);
1959
1960 } else if (Tag == dwarf::DW_TAG_namespace) {
1961 if (!AttrInfo.Name)
1962 AttrInfo.Name = DebugStrPool.getEntry("(anonymous namespace)");
1963 Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
1964 } else if (Tag == dwarf::DW_TAG_imported_declaration && AttrInfo.Name) {
1965 Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
1966 } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration) {
1967 bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit);
1968 uint64_t RuntimeLang =
1969 dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
1970 .value_or(0);
1971 bool ObjCClassIsImplementation =
1972 (RuntimeLang == dwarf::DW_LANG_ObjC ||
1973 RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) &&
1974 dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type))
1975 .value_or(0);
1976 if (Success && AttrInfo.Name && !AttrInfo.Name.getString().empty()) {
1977 uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
1978 Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
1979 Hash);
1980 }
1981
1982 // For Swift, mangled names are put into DW_AT_linkage_name.
1983 if (Success && AttrInfo.MangledName &&
1984 RuntimeLang == dwarf::DW_LANG_Swift &&
1985 !AttrInfo.MangledName.getString().empty() &&
1986 AttrInfo.MangledName != AttrInfo.Name) {
1987 auto Hash = djbHash(AttrInfo.MangledName.getString().data());
1988 Unit.addTypeAccelerator(Die, AttrInfo.MangledName,
1989 ObjCClassIsImplementation, Hash);
1990 }
1991 }
1992
1993 // Determine whether there are any children that we want to keep.
1994 bool HasChildren = false;
1995 for (auto Child : InputDIE.children()) {
1996 unsigned Idx = U.getDIEIndex(Child);
1997 if (Unit.getInfo(Idx).Keep) {
1998 HasChildren = true;
1999 break;
2000 }
2001 }
2002
2003 if (Unit.getOrigUnit().getVersion() >= 5 && !AttrInfo.AttrStrOffsetBaseSeen &&
2004 Die->getTag() == dwarf::DW_TAG_compile_unit) {
2005 // No DW_AT_str_offsets_base seen, add it to the DIE.
2006 Die->addValue(DIEAlloc, dwarf::DW_AT_str_offsets_base,
2007 dwarf::DW_FORM_sec_offset, DIEInteger(8));
2008 OutOffset += 4;
2009 }
2010
2011 DIEAbbrev NewAbbrev = Die->generateAbbrev();
2012 if (HasChildren)
2014 // Assign a permanent abbrev number
2015 Linker.assignAbbrev(NewAbbrev);
2016 Die->setAbbrevNumber(NewAbbrev.getNumber());
2017
2018 uint64_t AbbrevNumberSize = getULEB128Size(Die->getAbbrevNumber());
2019
2020 // Add the size of the abbreviation number to the output offset.
2021 OutOffset += AbbrevNumberSize;
2022
2023 // Update fixups with the size of the abbreviation number
2024 for (AttributeLinkedOffsetFixup &F : AttributesFixups)
2025 F.LinkedOffsetFixupVal += AbbrevNumberSize;
2026
2027 for (AttributeLinkedOffsetFixup &F : AttributesFixups)
2028 ObjFile.Addresses->updateAndSaveValidRelocs(
2029 Unit.getOrigUnit().getVersion() >= 5, Unit.getOrigUnit().getOffset(),
2030 F.LinkedOffsetFixupVal, F.InputAttrStartOffset, F.InputAttrEndOffset);
2031
2032 if (!HasChildren) {
2033 // Update our size.
2034 Die->setSize(OutOffset - Die->getOffset());
2035 return Die;
2036 }
2037
2038 // Recursively clone children.
2039 for (auto Child : InputDIE.children()) {
2040 if (DIE *Clone = cloneDIE(Child, File, Unit, PCOffset, OutOffset, Flags,
2041 IsLittleEndian)) {
2042 Die->addChild(Clone);
2043 OutOffset = Clone->getOffset() + Clone->getSize();
2044 }
2045 }
2046
2047 // Account for the end of children marker.
2048 OutOffset += sizeof(int8_t);
2049 // Update our size.
2050 Die->setSize(OutOffset - Die->getOffset());
2051 return Die;
2052}
2053
2054/// Patch the input object file relevant debug_ranges or debug_rnglists
2055/// entries and emit them in the output file. Update the relevant attributes
2056/// to point at the new entries.
2057Error DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
2058 DebugDieValuePool &AddrPool) const {
2059 if (LLVM_UNLIKELY(Options.Update))
2060 return Error::success();
2061
2062 const auto &FunctionRanges = Unit.getFunctionRanges();
2063
2064 // Build set of linked address ranges for unit function ranges.
2065 AddressRanges LinkedFunctionRanges;
2066 for (const AddressRangeValuePair &Range : FunctionRanges)
2067 LinkedFunctionRanges.insert(
2068 {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
2069
2070 // Emit LinkedFunctionRanges into .debug_aranges
2071 if (!LinkedFunctionRanges.empty())
2072 TheDwarfEmitter->emitDwarfDebugArangesTable(Unit, LinkedFunctionRanges);
2073
2074 RngListAttributesTy AllRngListAttributes = Unit.getRangesAttributes();
2075 std::optional<PatchLocation> UnitRngListAttribute =
2076 Unit.getUnitRangesAttribute();
2077
2078 if (!AllRngListAttributes.empty() || UnitRngListAttribute) {
2079 std::optional<AddressRangeValuePair> CachedRange;
2080 MCSymbol *EndLabel = TheDwarfEmitter->emitDwarfDebugRangeListHeader(Unit);
2081
2082 // Read original address ranges, apply relocation value, emit linked address
2083 // ranges.
2084 for (PatchLocation &AttributePatch : AllRngListAttributes) {
2085 // Get ranges from the source DWARF corresponding to the current
2086 // attribute.
2087 AddressRanges LinkedRanges;
2088 if (Expected<DWARFAddressRangesVector> OriginalRanges =
2089 Unit.getOrigUnit().findRnglistFromOffset(AttributePatch.get())) {
2090 // Apply relocation adjustment.
2091 for (const auto &Range : *OriginalRanges) {
2092 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
2093 CachedRange = FunctionRanges.getRangeThatContains(Range.LowPC);
2094
2095 // All range entries should lie in the function range.
2096 if (!CachedRange) {
2097 reportWarning("inconsistent range data.", File);
2098 continue;
2099 }
2100
2101 // Store range for emiting.
2102 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
2103 Range.HighPC + CachedRange->Value});
2104 }
2105 } else {
2106 llvm::consumeError(OriginalRanges.takeError());
2107 reportWarning("invalid range list ignored.", File);
2108 }
2109
2110 // Emit linked ranges.
2111 if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment(
2112 Unit, LinkedRanges, AttributePatch, AddrPool))
2113 return E;
2114 }
2115
2116 // Emit ranges for Unit AT_ranges attribute.
2117 if (UnitRngListAttribute.has_value())
2118 if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment(
2119 Unit, LinkedFunctionRanges, *UnitRngListAttribute, AddrPool))
2120 return E;
2121
2122 // Emit ranges footer.
2123 TheDwarfEmitter->emitDwarfDebugRangeListFooter(Unit, EndLabel);
2124 }
2125
2126 return Error::success();
2127}
2128
2129Error DWARFLinker::DIECloner::generateUnitLocations(
2130 CompileUnit &Unit, const DWARFFile &File,
2131 ExpressionHandlerRef ExprHandler) {
2132 if (LLVM_UNLIKELY(Linker.Options.Update))
2133 return Error::success();
2134
2135 const LocListAttributesTy &AllLocListAttributes =
2136 Unit.getLocationAttributes();
2137
2138 if (AllLocListAttributes.empty())
2139 return Error::success();
2140
2141 // Emit locations list table header.
2142 MCSymbol *EndLabel = Emitter->emitDwarfDebugLocListHeader(Unit);
2143
2144 for (auto &CurLocAttr : AllLocListAttributes) {
2145 // Get location expressions vector corresponding to the current attribute
2146 // from the source DWARF.
2147 Expected<DWARFLocationExpressionsVector> OriginalLocations =
2148 Unit.getOrigUnit().findLoclistFromOffset(CurLocAttr.get());
2149
2150 if (!OriginalLocations) {
2151 llvm::consumeError(OriginalLocations.takeError());
2152 Linker.reportWarning("Invalid location attribute ignored.", File);
2153 continue;
2154 }
2155
2156 DWARFLocationExpressionsVector LinkedLocationExpressions;
2157 for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
2158 DWARFLocationExpression LinkedExpression;
2159
2160 if (CurExpression.Range) {
2161 // Relocate address range.
2162 LinkedExpression.Range = {
2163 CurExpression.Range->LowPC + CurLocAttr.RelocAdjustment,
2164 CurExpression.Range->HighPC + CurLocAttr.RelocAdjustment};
2165 }
2166
2167 // Clone expression.
2168 LinkedExpression.Expr.reserve(CurExpression.Expr.size());
2169 ExprHandler(CurExpression.Expr, LinkedExpression.Expr,
2170 CurLocAttr.RelocAdjustment);
2171
2172 LinkedLocationExpressions.push_back(LinkedExpression);
2173 }
2174
2175 // Emit locations list table fragment corresponding to the CurLocAttr.
2176 if (Error E = Emitter->emitDwarfDebugLocListFragment(
2177 Unit, LinkedLocationExpressions, CurLocAttr, AddrPool))
2178 return E;
2179 }
2180
2181 // Emit locations list table footer.
2182 Emitter->emitDwarfDebugLocListFooter(Unit, EndLabel);
2183
2184 return Error::success();
2185}
2186
2188 for (auto &V : Die.values())
2189 if (V.getAttribute() == dwarf::DW_AT_addr_base) {
2190 V = DIEValue(V.getAttribute(), V.getForm(), Offset);
2191 return;
2192 }
2193
2194 llvm_unreachable("Didn't find a DW_AT_addr_base in cloned DIE!");
2195}
2196
2197Error DWARFLinker::DIECloner::emitDebugAddrSection(
2198 CompileUnit &Unit, const uint16_t DwarfVersion) const {
2199
2200 if (LLVM_UNLIKELY(Linker.Options.Update))
2201 return Error::success();
2202
2203 if (DwarfVersion < 5)
2204 return Error::success();
2205
2206 if (AddrPool.getValues().empty())
2207 return Error::success();
2208
2209 MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader(Unit);
2210 uint64_t AddrOffset = Emitter->getDebugAddrSectionSize();
2211 dwarf::FormParams FP = Unit.getOrigUnit().getFormParams();
2212 if (AddrOffset > FP.getDwarfMaxOffset())
2213 return createStringError(".debug_addr section offset 0x" +
2214 Twine::utohexstr(AddrOffset) + " exceeds the " +
2215 dwarf::FormatString(FP.Format) + " limit");
2216 patchAddrBase(*Unit.getOutputUnitDIE(), DIEInteger(AddrOffset));
2217 Emitter->emitDwarfDebugAddrs(AddrPool.getValues(),
2218 Unit.getOrigUnit().getAddressByteSize());
2219 Emitter->emitDwarfDebugAddrsFooter(Unit, EndLabel);
2220
2221 return Error::success();
2222}
2223
2224/// A helper struct to help keep track of the association between the input and
2225/// output rows during line table rewriting. This is used to patch
2226/// DW_AT_LLVM_stmt_sequence attributes, which reference a particular line table
2227/// row.
2233
2234/// Insert the new line info sequence \p Seq into the current
2235/// set of already linked line info \p Rows.
2236static void insertLineSequence(std::vector<TrackedRow> &Seq,
2237 std::vector<TrackedRow> &Rows) {
2238 if (Seq.empty())
2239 return;
2240
2241 // Mark the first row in Seq to indicate it is the start of a sequence
2242 // in the output line table.
2243 Seq.front().isStartSeqInOutput = true;
2244
2245 if (!Rows.empty() && Rows.back().Row.Address < Seq.front().Row.Address) {
2246 llvm::append_range(Rows, Seq);
2247 Seq.clear();
2248 return;
2249 }
2250
2251 object::SectionedAddress Front = Seq.front().Row.Address;
2253 Rows, [=](const TrackedRow &O) { return O.Row.Address < Front; });
2254
2255 // FIXME: this only removes the unneeded end_sequence if the
2256 // sequences have been inserted in order. Using a global sort like
2257 // described in generateLineTableForUnit() and delaying the end_sequence
2258 // elimination to emitLineTableForUnit() we can get rid of all of them.
2259 if (InsertPoint != Rows.end() && InsertPoint->Row.Address == Front &&
2260 InsertPoint->Row.EndSequence) {
2261 *InsertPoint = Seq.front();
2262 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
2263 } else {
2264 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
2265 }
2266
2267 Seq.clear();
2268}
2269
2271 for (auto &V : Die.values())
2272 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
2273 V = DIEValue(V.getAttribute(), V.getForm(), Offset);
2274 return;
2275 }
2276
2277 llvm_unreachable("Didn't find DW_AT_stmt_list in cloned DIE!");
2278}
2279
2280void DWARFLinker::DIECloner::rememberUnitForMacroOffset(CompileUnit &Unit) {
2281 DWARFUnit &OrigUnit = Unit.getOrigUnit();
2282 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
2283
2284 if (std::optional<uint64_t> MacroAttr =
2285 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
2286 UnitMacroMap.insert(std::make_pair(*MacroAttr, &Unit));
2287 return;
2288 }
2289
2290 if (std::optional<uint64_t> MacroAttr =
2291 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
2292 UnitMacroMap.insert(std::make_pair(*MacroAttr, &Unit));
2293 return;
2294 }
2295}
2296
2297Error DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
2298 if (LLVM_UNLIKELY(Emitter == nullptr))
2299 return Error::success();
2300
2301 // Check whether DW_AT_stmt_list attribute is presented.
2302 DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE();
2303 auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list));
2304 if (!StmtList)
2305 return Error::success();
2306
2307 // Update the cloned DW_AT_stmt_list with the correct debug_line offset.
2308 if (auto *OutputDIE = Unit.getOutputUnitDIE()) {
2309 uint64_t StmtOffset = Emitter->getLineSectionSize();
2310 dwarf::FormParams FP = Unit.getOrigUnit().getFormParams();
2311 if (StmtOffset > FP.getDwarfMaxOffset())
2312 return createStringError(".debug_line section offset 0x" +
2313 Twine::utohexstr(StmtOffset) + " exceeds the " +
2314 dwarf::FormatString(FP.Format) + " limit");
2315 patchStmtList(*OutputDIE, DIEInteger(StmtOffset));
2316 }
2317
2318 if (const DWARFDebugLine::LineTable *LT =
2319 ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) {
2320
2321 DWARFDebugLine::LineTable LineTable;
2322
2323 // Set Line Table header.
2324 LineTable.Prologue = LT->Prologue;
2325
2326 // Set Line Table Rows.
2327 if (Linker.Options.Update) {
2328 LineTable.Rows = LT->Rows;
2329 // If all the line table contains is a DW_LNE_end_sequence, clear the line
2330 // table rows, it will be inserted again in the DWARFStreamer.
2331 if (LineTable.Rows.size() == 1 && LineTable.Rows[0].EndSequence)
2332 LineTable.Rows.clear();
2333
2334 LineTable.Sequences = LT->Sequences;
2335
2336 Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
2337 DebugLineStrPool);
2338 } else {
2339 // Create TrackedRow objects for all input rows.
2340 std::vector<TrackedRow> InputRows;
2341 InputRows.reserve(LT->Rows.size());
2342 for (size_t i = 0; i < LT->Rows.size(); i++)
2343 InputRows.emplace_back(TrackedRow{LT->Rows[i], i, false});
2344
2345 // This vector is the output line table (still in TrackedRow form).
2346 std::vector<TrackedRow> OutputRows;
2347 OutputRows.reserve(InputRows.size());
2348
2349 // Current sequence of rows being extracted, before being inserted
2350 // in OutputRows.
2351 std::vector<TrackedRow> Seq;
2352 Seq.reserve(InputRows.size());
2353
2354 const auto &FunctionRanges = Unit.getFunctionRanges();
2355 std::optional<AddressRangeValuePair> CurrRange;
2356
2357 // FIXME: This logic is meant to generate exactly the same output as
2358 // Darwin's classic dsymutil. There is a nicer way to implement this
2359 // by simply putting all the relocated line info in OutputRows and simply
2360 // sorting OutputRows before passing it to emitLineTableForUnit. This
2361 // should be correct as sequences for a function should stay
2362 // together in the sorted output. There are a few corner cases that
2363 // look suspicious though, and that required to implement the logic
2364 // this way. Revisit that once initial validation is finished.
2365
2366 // Iterate over the object file line info and extract the sequences
2367 // that correspond to linked functions.
2368 for (size_t i = 0; i < InputRows.size(); i++) {
2369 TrackedRow TR = InputRows[i];
2370
2371 // Check whether we stepped out of the range. The range is
2372 // half-open, but consider accepting the end address of the range if
2373 // it is marked as end_sequence in the input (because in that
2374 // case, the relocation offset is accurate and that entry won't
2375 // serve as the start of another function).
2376 if (!CurrRange || !CurrRange->Range.contains(TR.Row.Address.Address)) {
2377 // We just stepped out of a known range. Insert an end_sequence
2378 // corresponding to the end of the range.
2379 uint64_t StopAddress =
2380 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
2381 CurrRange =
2382 FunctionRanges.getRangeThatContains(TR.Row.Address.Address);
2383 if (StopAddress != -1ULL && !Seq.empty()) {
2384 // Insert end sequence row with the computed end address, but
2385 // the same line as the previous one.
2386 auto NextLine = Seq.back();
2387 NextLine.Row.Address.Address = StopAddress;
2388 NextLine.Row.EndSequence = 1;
2389 NextLine.Row.PrologueEnd = 0;
2390 NextLine.Row.BasicBlock = 0;
2391 NextLine.Row.EpilogueBegin = 0;
2392 Seq.push_back(NextLine);
2393 insertLineSequence(Seq, OutputRows);
2394 }
2395
2396 if (!CurrRange)
2397 continue;
2398 }
2399
2400 // Ignore empty sequences.
2401 if (TR.Row.EndSequence && Seq.empty())
2402 continue;
2403
2404 // Relocate row address and add it to the current sequence.
2405 TR.Row.Address.Address += CurrRange->Value;
2406 Seq.push_back(TR);
2407
2408 if (TR.Row.EndSequence)
2409 insertLineSequence(Seq, OutputRows);
2410 }
2411
2412 // Recompute isStartSeqInOutput based on the final row ordering.
2413 // A row is a sequence start (will have DW_LNE_set_address emitted) iff:
2414 // 1. It's the first row, OR
2415 // 2. The previous row has EndSequence = 1
2416 // This is necessary because insertLineSequence may merge sequences when
2417 // an EndSequence row is replaced by the start of a new sequence, which
2418 // removes the EndSequence marker and invalidates the original flag.
2419 if (!OutputRows.empty()) {
2420 OutputRows[0].isStartSeqInOutput = true;
2421 for (size_t i = 1; i < OutputRows.size(); ++i)
2422 OutputRows[i].isStartSeqInOutput = OutputRows[i - 1].Row.EndSequence;
2423 }
2424
2425 // Materialize the tracked rows into final DWARFDebugLine::Row objects.
2426 LineTable.Rows.clear();
2427 LineTable.Rows.reserve(OutputRows.size());
2428 for (auto &TR : OutputRows)
2429 LineTable.Rows.push_back(TR.Row);
2430
2431 // Use OutputRowOffsets to store the offsets of each line table row in the
2432 // output .debug_line section.
2433 std::vector<uint64_t> OutputRowOffsets;
2434
2435 // The unit might not have any DW_AT_LLVM_stmt_sequence attributes, so use
2436 // hasStmtSeq to skip the patching logic.
2437 bool hasStmtSeq = Unit.getStmtSeqListAttributes().size() > 0;
2438 Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool,
2439 DebugLineStrPool,
2440 hasStmtSeq ? &OutputRowOffsets : nullptr);
2441
2442 if (hasStmtSeq) {
2443 assert(OutputRowOffsets.size() == OutputRows.size() &&
2444 "must have an offset for each row");
2445
2446 // Create a map of stmt sequence offsets to original row indices.
2447 DenseMap<uint64_t, uint64_t> SeqOffToOrigRow;
2448 // The DWARF parser's discovery of sequences can be incomplete. To
2449 // ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we
2450 // build a map from both the parser's results and a manual
2451 // reconstruction.
2452 if (!LT->Rows.empty())
2453 constructSeqOffsettoOrigRowMapping(Unit, *LT, SeqOffToOrigRow);
2454
2455 // Build two maps to handle stmt_sequence patching:
2456 // 1. OrigRowToOutputRow: maps original row indices to output row
2457 // indices (for all rows, not just sequence starts).
2458 // 2. OutputRowToSeqStart: maps each output row index to its sequence
2459 // start's output row index
2460 DenseMap<size_t, size_t> OrigRowToOutputRow;
2461 std::vector<size_t> OutputRowToSeqStart(OutputRows.size());
2462
2463 size_t CurrentSeqStart = 0;
2464 for (size_t i = 0; i < OutputRows.size(); ++i) {
2465 // Track the current sequence start.
2466 if (OutputRows[i].isStartSeqInOutput)
2467 CurrentSeqStart = i;
2468 OutputRowToSeqStart[i] = CurrentSeqStart;
2469
2470 // Map original row index to output row index.
2471 OrigRowToOutputRow[OutputRows[i].OriginalRowIndex] = i;
2472 }
2473
2474 // Patch DW_AT_LLVM_stmt_sequence attributes in the compile unit DIE
2475 // with the correct offset into the .debug_line section.
2476 for (const auto &StmtSeq : Unit.getStmtSeqListAttributes()) {
2477 uint64_t OrigStmtSeq = StmtSeq.get();
2478 // 1. Get the original row index from the stmt list offset.
2479 auto OrigRowIter = SeqOffToOrigRow.find(OrigStmtSeq);
2480 const uint64_t InvalidOffset =
2481 Unit.getOrigUnit().getFormParams().getDwarfMaxOffset();
2482 // Check whether we have an output sequence for the StmtSeq offset.
2483 // Some sequences are discarded by the DWARFLinker if they are invalid
2484 // (empty).
2485 if (OrigRowIter == SeqOffToOrigRow.end()) {
2486 StmtSeq.set(InvalidOffset);
2487 continue;
2488 }
2489 size_t OrigRowIndex = OrigRowIter->second;
2490
2491 // 2. Find the output row for this original row.
2492 auto OutputRowIter = OrigRowToOutputRow.find(OrigRowIndex);
2493 if (OutputRowIter == OrigRowToOutputRow.end()) {
2494 // Row was dropped during linking.
2495 StmtSeq.set(InvalidOffset);
2496 continue;
2497 }
2498 size_t OutputRowIdx = OutputRowIter->second;
2499
2500 // 3. Find the sequence start for this output row.
2501 // If the original row was a sequence start but got merged into
2502 // another sequence, this finds the correct sequence start.
2503 size_t SeqStartIdx = OutputRowToSeqStart[OutputRowIdx];
2504
2505 // 4. Get the offset of the sequence start in the output .debug_line
2506 // section. This offset points to the DW_LNE_set_address opcode.
2507 assert(SeqStartIdx < OutputRowOffsets.size() &&
2508 "Sequence start index out of bounds");
2509 uint64_t NewStmtSeqOffset = OutputRowOffsets[SeqStartIdx];
2510
2511 // 5. Patch the stmt_sequence attribute with the new offset.
2512 StmtSeq.set(NewStmtSeqOffset);
2513 }
2514 }
2515 }
2516
2517 } else
2518 Linker.reportWarning("Cann't load line table.", ObjFile);
2519
2520 return Error::success();
2521}
2522
2523void DWARFLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
2524 for (AccelTableKind AccelTableKind : Options.AccelTables) {
2525 switch (AccelTableKind) {
2526 case AccelTableKind::Apple: {
2527 // Add namespaces.
2528 for (const auto &Namespace : Unit.getNamespaces())
2529 AppleNamespaces.addName(Namespace.Name, Namespace.Die->getOffset() +
2530 Unit.getStartOffset());
2531 // Add names.
2532 for (const auto &Pubname : Unit.getPubnames())
2533 AppleNames.addName(Pubname.Name,
2534 Pubname.Die->getOffset() + Unit.getStartOffset());
2535 // Add types.
2536 for (const auto &Pubtype : Unit.getPubtypes())
2537 AppleTypes.addName(
2538 Pubtype.Name, Pubtype.Die->getOffset() + Unit.getStartOffset(),
2539 Pubtype.Die->getTag(),
2540 Pubtype.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation
2541 : 0,
2542 Pubtype.QualifiedNameHash);
2543 // Add ObjC names.
2544 for (const auto &ObjC : Unit.getObjC())
2545 AppleObjc.addName(ObjC.Name,
2546 ObjC.Die->getOffset() + Unit.getStartOffset());
2547 } break;
2548 case AccelTableKind::Pub: {
2549 TheDwarfEmitter->emitPubNamesForUnit(Unit);
2550 TheDwarfEmitter->emitPubTypesForUnit(Unit);
2551 } break;
2553 for (const auto &Namespace : Unit.getNamespaces())
2554 DebugNames.addName(
2555 Namespace.Name, Namespace.Die->getOffset(),
2557 Namespace.Die->getTag(), Unit.getUniqueID(),
2558 Unit.getTag() == dwarf::DW_TAG_type_unit);
2559 for (const auto &Pubname : Unit.getPubnames())
2560 DebugNames.addName(
2561 Pubname.Name, Pubname.Die->getOffset(),
2563 Pubname.Die->getTag(), Unit.getUniqueID(),
2564 Unit.getTag() == dwarf::DW_TAG_type_unit);
2565 for (const auto &Pubtype : Unit.getPubtypes())
2566 DebugNames.addName(
2567 Pubtype.Name, Pubtype.Die->getOffset(),
2569 Pubtype.Die->getTag(), Unit.getUniqueID(),
2570 Unit.getTag() == dwarf::DW_TAG_type_unit);
2571 } break;
2572 }
2573 }
2574}
2575
2576/// Read the frame info stored in the object, and emit the
2577/// patched frame descriptions for the resulting file.
2578///
2579/// This is actually pretty easy as the data of the CIEs and FDEs can
2580/// be considered as black boxes and moved as is. The only thing to do
2581/// is to patch the addresses in the headers.
2582void DWARFLinker::patchFrameInfoForObject(LinkContext &Context) {
2583 DWARFContext &OrigDwarf = *Context.File.Dwarf;
2584 unsigned SrcAddrSize = OrigDwarf.getDWARFObj().getAddressSize();
2585
2586 StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data;
2587 if (FrameData.empty())
2588 return;
2589
2590 RangesTy AllUnitsRanges;
2591 for (std::unique_ptr<CompileUnit> &Unit : Context.CompileUnits) {
2592 for (auto CurRange : Unit->getFunctionRanges())
2593 AllUnitsRanges.insert(CurRange.Range, CurRange.Value);
2594 }
2595
2596 DataExtractor Data(FrameData, OrigDwarf.isLittleEndian());
2597 uint64_t InputOffset = 0;
2598
2599 // Store the data of the CIEs defined in this object, keyed by their
2600 // offsets.
2601 DenseMap<uint64_t, StringRef> LocalCIES;
2602
2603 while (Data.isValidOffset(InputOffset)) {
2604 uint64_t EntryOffset = InputOffset;
2605 uint32_t InitialLength = Data.getU32(&InputOffset);
2606 if (InitialLength == 0xFFFFFFFF)
2607 return reportWarning("Dwarf64 bits no supported", Context.File);
2608
2609 uint32_t CIEId = Data.getU32(&InputOffset);
2610 if (CIEId == 0xFFFFFFFF) {
2611 // This is a CIE, store it.
2612 StringRef CIEData = FrameData.substr(EntryOffset, InitialLength + 4);
2613 LocalCIES[EntryOffset] = CIEData;
2614 // The -4 is to account for the CIEId we just read.
2615 InputOffset += InitialLength - 4;
2616 continue;
2617 }
2618
2619 uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize);
2620
2621 // Some compilers seem to emit frame info that doesn't start at
2622 // the function entry point, thus we can't just lookup the address
2623 // in the debug map. Use the AddressInfo's range map to see if the FDE
2624 // describes something that we can relocate.
2625 std::optional<AddressRangeValuePair> Range =
2626 AllUnitsRanges.getRangeThatContains(Loc);
2627 if (!Range) {
2628 // The +4 is to account for the size of the InitialLength field itself.
2629 InputOffset = EntryOffset + InitialLength + 4;
2630 continue;
2631 }
2632
2633 // This is an FDE, and we have a mapping.
2634 // Have we already emitted a corresponding CIE?
2635 StringRef CIEData = LocalCIES[CIEId];
2636 if (CIEData.empty())
2637 return reportWarning("Inconsistent debug_frame content. Dropping.",
2638 Context.File);
2639
2640 // Look if we already emitted a CIE that corresponds to the
2641 // referenced one (the CIE data is the key of that lookup).
2642 auto IteratorInserted = EmittedCIEs.insert(
2643 std::make_pair(CIEData, TheDwarfEmitter->getFrameSectionSize()));
2644 // If there is no CIE yet for this ID, emit it.
2645 if (IteratorInserted.second) {
2646 LastCIEOffset = TheDwarfEmitter->getFrameSectionSize();
2647 IteratorInserted.first->getValue() = LastCIEOffset;
2648 TheDwarfEmitter->emitCIE(CIEData);
2649 }
2650
2651 // Emit the FDE with updated address and CIE pointer.
2652 // (4 + AddrSize) is the size of the CIEId + initial_location
2653 // fields that will get reconstructed by emitFDE().
2654 unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize);
2655 TheDwarfEmitter->emitFDE(IteratorInserted.first->getValue(), SrcAddrSize,
2656 Loc + Range->Value,
2657 FrameData.substr(InputOffset, FDERemainingBytes));
2658 InputOffset += FDERemainingBytes;
2659 }
2660}
2661
2662uint32_t DWARFLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE,
2663 CompileUnit &U,
2664 const DWARFFile &File,
2665 int ChildRecurseDepth) {
2666 const char *Name = nullptr;
2667 DWARFUnit *OrigUnit = &U.getOrigUnit();
2668 CompileUnit *CU = &U;
2669 std::optional<DWARFFormValue> Ref;
2670
2671 while (true) {
2672 if (const char *CurrentName = DIE.getName(DINameKind::ShortName))
2673 Name = CurrentName;
2674
2675 if (!(Ref = DIE.find(dwarf::DW_AT_specification)) &&
2676 !(Ref = DIE.find(dwarf::DW_AT_abstract_origin)))
2677 break;
2678
2679 if (!Ref->isFormClass(DWARFFormValue::FC_Reference))
2680 break;
2681
2682 CompileUnit *RefCU;
2683 if (auto RefDIE =
2684 Linker.resolveDIEReference(File, CompileUnits, *Ref, DIE, RefCU)) {
2685 CU = RefCU;
2686 OrigUnit = &RefCU->getOrigUnit();
2687 DIE = RefDIE;
2688 }
2689 }
2690
2691 unsigned Idx = OrigUnit->getDIEIndex(DIE);
2692 if (!Name && DIE.getTag() == dwarf::DW_TAG_namespace)
2693 Name = "(anonymous namespace)";
2694
2695 if (CU->getInfo(Idx).ParentIdx == 0 ||
2696 // FIXME: dsymutil-classic compatibility. Ignore modules.
2697 CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() ==
2698 dwarf::DW_TAG_module)
2699 return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::"));
2700
2701 DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx);
2702 return djbHash(
2703 (Name ? Name : ""),
2704 djbHash((Name ? "::" : ""),
2705 hashFullyQualifiedName(Die, *CU, File, ++ChildRecurseDepth)));
2706}
2707
2708static uint64_t getDwoId(const DWARFDie &CUDie) {
2709 auto DwoId = dwarf::toUnsigned(
2710 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id}));
2711 if (DwoId)
2712 return *DwoId;
2713 return 0;
2714}
2715
2716static std::string
2718 const DWARFLinkerBase::ObjectPrefixMapTy &ObjectPrefixMap) {
2719 if (ObjectPrefixMap.empty())
2720 return Path.str();
2721
2722 SmallString<256> p = Path;
2723 for (const auto &Entry : ObjectPrefixMap)
2724 if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second))
2725 break;
2726 return p.str().str();
2727}
2728
2729static std::string
2731 const DWARFLinkerBase::ObjectPrefixMapTy *ObjectPrefixMap) {
2732 std::string PCMFile = dwarf::toString(
2733 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
2734
2735 if (PCMFile.empty())
2736 return PCMFile;
2737
2738 if (ObjectPrefixMap)
2739 PCMFile = remapPath(PCMFile, *ObjectPrefixMap);
2740
2741 return PCMFile;
2742}
2743
2744std::pair<bool, bool> DWARFLinker::isClangModuleRef(const DWARFDie &CUDie,
2745 std::string &PCMFile,
2746 LinkContext &Context,
2747 unsigned Indent,
2748 bool Quiet) {
2749 if (PCMFile.empty())
2750 return std::make_pair(false, false);
2751
2752 // Clang module DWARF skeleton CUs abuse this for the path to the module.
2753 uint64_t DwoId = getDwoId(CUDie);
2754
2755 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
2756 if (Name.empty()) {
2757 if (!Quiet)
2758 reportWarning("Anonymous module skeleton CU for " + PCMFile,
2759 Context.File);
2760 return std::make_pair(true, true);
2761 }
2762
2763 if (!Quiet && Options.Verbose) {
2764 outs().indent(Indent);
2765 outs() << "Found clang module reference " << PCMFile;
2766 }
2767
2768 auto Cached = ClangModules.find(PCMFile);
2769 if (Cached != ClangModules.end()) {
2770 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
2771 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
2772 // ASTFileSignatures will change randomly when a module is rebuilt.
2773 if (!Quiet && Options.Verbose && (Cached->second != DwoId))
2774 reportWarning(Twine("hash mismatch: this object file was built against a "
2775 "different version of the module ") +
2776 PCMFile,
2777 Context.File);
2778 if (!Quiet && Options.Verbose)
2779 outs() << " [cached].\n";
2780 return std::make_pair(true, true);
2781 }
2782
2783 return std::make_pair(true, false);
2784}
2785
2786bool DWARFLinker::registerModuleReference(const DWARFDie &CUDie,
2787 LinkContext &Context,
2788 ObjFileLoaderTy Loader,
2789 CompileUnitHandlerTy OnCUDieLoaded,
2790 unsigned Indent) {
2791 std::string PCMFile = getPCMFile(CUDie, Options.ObjectPrefixMap);
2792 std::pair<bool, bool> IsClangModuleRef =
2793 isClangModuleRef(CUDie, PCMFile, Context, Indent, false);
2794
2795 if (!IsClangModuleRef.first)
2796 return false;
2797
2798 if (IsClangModuleRef.second)
2799 return true;
2800
2801 if (Options.Verbose)
2802 outs() << " ...\n";
2803
2804 // Cyclic dependencies are disallowed by Clang, but we still
2805 // shouldn't run into an infinite loop, so mark it as processed now.
2806 ClangModules.insert({PCMFile, getDwoId(CUDie)});
2807
2808 if (Error E = loadClangModule(Loader, CUDie, PCMFile, Context, OnCUDieLoaded,
2809 Indent + 2)) {
2810 consumeError(std::move(E));
2811 return false;
2812 }
2813 return true;
2814}
2815
2816Error DWARFLinker::loadClangModule(
2817 ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile,
2818 LinkContext &Context, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) {
2819
2820 uint64_t DwoId = getDwoId(CUDie);
2821 std::string ModuleName = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
2822
2823 /// Using a SmallString<0> because loadClangModule() is recursive.
2824 SmallString<0> Path(Options.PrependPath);
2825 if (sys::path::is_relative(PCMFile))
2826 resolveRelativeObjectPath(Path, CUDie);
2827 sys::path::append(Path, PCMFile);
2828 // Don't use the cached binary holder because we have no thread-safety
2829 // guarantee and the lifetime is limited.
2830
2831 if (Loader == nullptr) {
2832 reportError("Could not load clang module: loader is not specified.\n",
2833 Context.File);
2834 return Error::success();
2835 }
2836
2837 auto ErrOrObj = Loader(Context.File.FileName, Path);
2838 if (!ErrOrObj)
2839 return Error::success();
2840
2841 std::unique_ptr<CompileUnit> Unit;
2842 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) {
2843 OnCUDieLoaded(*CU);
2844 // Recursively get all modules imported by this one.
2845 auto ChildCUDie = CU->getUnitDIE();
2846 if (!ChildCUDie)
2847 continue;
2848 if (!registerModuleReference(ChildCUDie, Context, Loader, OnCUDieLoaded,
2849 Indent)) {
2850 if (Unit) {
2851 std::string Err =
2852 (PCMFile +
2853 ": Clang modules are expected to have exactly 1 compile unit.\n");
2854 reportError(Err, Context.File);
2856 }
2857 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
2858 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
2859 // ASTFileSignatures will change randomly when a module is rebuilt.
2860 uint64_t PCMDwoId = getDwoId(ChildCUDie);
2861 if (PCMDwoId != DwoId) {
2862 if (Options.Verbose)
2863 reportWarning(
2864 Twine("hash mismatch: this object file was built against a "
2865 "different version of the module ") +
2866 PCMFile,
2867 Context.File);
2868 // Update the cache entry with the DwoId of the module loaded from disk.
2869 ClangModules[PCMFile] = PCMDwoId;
2870 }
2871
2872 // Add this module.
2873 Unit = std::make_unique<CompileUnit>(*CU, UniqueUnitID++, !Options.NoODR,
2874 ModuleName);
2875 }
2876 }
2877
2878 if (Unit)
2879 Context.ModuleUnits.emplace_back(RefModuleUnit{*ErrOrObj, std::move(Unit)});
2880
2881 return Error::success();
2882}
2883
2884Expected<uint64_t> DWARFLinker::DIECloner::cloneAllCompileUnits(
2885 DWARFContext &DwarfContext, const DWARFFile &File, bool IsLittleEndian) {
2886 uint64_t OutputDebugInfoSize =
2887 (Emitter == nullptr) ? 0 : Emitter->getDebugInfoSectionSize();
2888 const uint64_t StartOutputDebugInfoSize = OutputDebugInfoSize;
2889
2890 for (auto &CurrentUnit : CompileUnits) {
2891 const uint16_t DwarfVersion = CurrentUnit->getOrigUnit().getVersion();
2892 const uint32_t UnitHeaderSize = DwarfVersion >= 5 ? 12 : 11;
2893 auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE();
2894 CurrentUnit->setStartOffset(OutputDebugInfoSize);
2895 if (!InputDIE) {
2896 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);
2897 continue;
2898 }
2899 if (CurrentUnit->getInfo(0).Keep) {
2900 // Clone the InputDIE into your Unit DIE in our compile unit since it
2901 // already has a DIE inside of it.
2902 CurrentUnit->createOutputDIE();
2903 rememberUnitForMacroOffset(*CurrentUnit);
2904 cloneDIE(InputDIE, File, *CurrentUnit, 0 /* PC offset */, UnitHeaderSize,
2905 0, IsLittleEndian, CurrentUnit->getOutputUnitDIE());
2906 }
2907
2908 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion);
2909
2910 if (Emitter != nullptr) {
2911
2912 if (Error E = generateLineTableForUnit(*CurrentUnit))
2913 return E;
2914
2915 Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
2916
2917 if (LLVM_UNLIKELY(Linker.Options.Update))
2918 continue;
2919
2920 if (Error E = Linker.generateUnitRanges(*CurrentUnit, File, AddrPool))
2921 return E;
2922
2923 auto ProcessExpr = [&](SmallVectorImpl<uint8_t> &SrcBytes,
2924 SmallVectorImpl<uint8_t> &OutBytes,
2925 int64_t RelocAdjustment) {
2926 DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit();
2927 DataExtractor Data(SrcBytes, IsLittleEndian);
2928 cloneExpression(Data,
2929 DWARFExpression(Data, OrigUnit.getAddressByteSize(),
2930 OrigUnit.getFormParams().Format),
2931 File, *CurrentUnit, OutBytes, RelocAdjustment,
2932 IsLittleEndian);
2933 };
2934 if (Error E = generateUnitLocations(*CurrentUnit, File, ProcessExpr))
2935 return E;
2936 if (Error E = emitDebugAddrSection(*CurrentUnit, DwarfVersion))
2937 return E;
2938 }
2939 AddrPool.clear();
2940 }
2941
2942 if (Emitter != nullptr) {
2943 assert(Emitter);
2944 // Emit macro tables.
2945 Emitter->emitMacroTables(File.Dwarf.get(), UnitMacroMap, DebugStrPool);
2946
2947 // Emit all the compile unit's debug information.
2948 for (auto &CurrentUnit : CompileUnits) {
2949 CurrentUnit->fixupForwardReferences();
2950
2951 if (!CurrentUnit->getOutputUnitDIE())
2952 continue;
2953
2954 unsigned DwarfVersion = CurrentUnit->getOrigUnit().getVersion();
2955
2956 assert(Emitter->getDebugInfoSectionSize() ==
2957 CurrentUnit->getStartOffset());
2958 Emitter->emitCompileUnitHeader(*CurrentUnit, DwarfVersion);
2959 Emitter->emitDIE(*CurrentUnit->getOutputUnitDIE());
2960 assert(Emitter->getDebugInfoSectionSize() ==
2961 CurrentUnit->computeNextUnitOffset(DwarfVersion));
2962 }
2963 }
2964
2965 return OutputDebugInfoSize - StartOutputDebugInfoSize;
2966}
2967
2968void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) {
2969 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getLocSection().Data,
2971 TheDwarfEmitter->emitSectionContents(
2972 Dwarf.getDWARFObj().getRangesSection().Data,
2974 TheDwarfEmitter->emitSectionContents(
2975 Dwarf.getDWARFObj().getFrameSection().Data, DebugSectionKind::DebugFrame);
2976 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(),
2978 TheDwarfEmitter->emitSectionContents(
2979 Dwarf.getDWARFObj().getAddrSection().Data, DebugSectionKind::DebugAddr);
2980 TheDwarfEmitter->emitSectionContents(
2981 Dwarf.getDWARFObj().getRnglistsSection().Data,
2983 TheDwarfEmitter->emitSectionContents(
2984 Dwarf.getDWARFObj().getLoclistsSection().Data,
2986}
2987
2989 CompileUnitHandlerTy OnCUDieLoaded) {
2990 ObjectContexts.emplace_back(LinkContext(File));
2991
2992 if (ObjectContexts.back().File.Dwarf) {
2993 for (const std::unique_ptr<DWARFUnit> &CU :
2994 ObjectContexts.back().File.Dwarf->compile_units()) {
2995 DWARFDie CUDie = CU->getUnitDIE();
2996
2997 if (!CUDie)
2998 continue;
2999
3000 OnCUDieLoaded(*CU);
3001
3002 if (!LLVM_UNLIKELY(Options.Update))
3003 registerModuleReference(CUDie, ObjectContexts.back(), Loader,
3004 OnCUDieLoaded);
3005 }
3006 }
3007}
3008
3010 assert((Options.TargetDWARFVersion != 0) &&
3011 "TargetDWARFVersion should be set");
3012
3013 // First populate the data structure we need for each iteration of the
3014 // parallel loop.
3015 unsigned NumObjects = ObjectContexts.size();
3016
3017 // This Dwarf string pool which is used for emission. It must be used
3018 // serially as the order of calling getStringOffset matters for
3019 // reproducibility.
3020 OffsetsStringPool DebugStrPool(true);
3021 OffsetsStringPool DebugLineStrPool(false);
3022 DebugDieValuePool StringOffsetPool;
3023
3024 // ODR Contexts for the optimize.
3025 DeclContextTree ODRContexts;
3026
3027 for (LinkContext &OptContext : ObjectContexts) {
3028 if (Options.Verbose)
3029 outs() << "DEBUG MAP OBJECT: " << OptContext.File.FileName << "\n";
3030
3031 if (!OptContext.File.Dwarf)
3032 continue;
3033
3034 if (Options.VerifyInputDWARF)
3035 verifyInput(OptContext.File);
3036
3037 // Look for relocations that correspond to address map entries.
3038
3039 // there was findvalidrelocations previously ... probably we need to gather
3040 // info here
3041 if (LLVM_LIKELY(!Options.Update) &&
3042 !OptContext.File.Addresses->hasValidRelocs()) {
3043 if (Options.Verbose)
3044 outs() << "No valid relocations found. Skipping.\n";
3045
3046 // Set "Skip" flag as a signal to other loops that we should not
3047 // process this iteration.
3048 OptContext.Skip = true;
3049 continue;
3050 }
3051
3052 // Setup access to the debug info.
3053 if (!OptContext.File.Dwarf)
3054 continue;
3055
3056 // Check whether type units are presented.
3057 if (!OptContext.File.Dwarf->types_section_units().empty()) {
3058 reportWarning("type units are not currently supported: file will "
3059 "be skipped",
3060 OptContext.File);
3061 OptContext.Skip = true;
3062 continue;
3063 }
3064
3065 // Clone all the clang modules with requires extracting the DIE units. We
3066 // don't need the full debug info until the Analyze phase.
3067 OptContext.CompileUnits.reserve(
3068 OptContext.File.Dwarf->getNumCompileUnits());
3069 for (const auto &CU : OptContext.File.Dwarf->compile_units()) {
3070 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/true);
3071 if (Options.Verbose) {
3072 outs() << "Input compilation unit:";
3073 DIDumpOptions DumpOpts;
3074 DumpOpts.ChildRecurseDepth = 0;
3075 DumpOpts.Verbose = Options.Verbose;
3076 CUDie.dump(outs(), 0, DumpOpts);
3077 }
3078 }
3079
3080 for (auto &CU : OptContext.ModuleUnits) {
3081 if (Error Err = cloneModuleUnit(OptContext, CU, ODRContexts, DebugStrPool,
3082 DebugLineStrPool, StringOffsetPool))
3083 reportWarning(toString(std::move(Err)), CU.File);
3084 }
3085 }
3086
3087 // At this point we know how much data we have emitted. We use this value to
3088 // compare canonical DIE offsets in analyzeContextInfo to see if a definition
3089 // is already emitted, without being affected by canonical die offsets set
3090 // later. This prevents undeterminism when analyze and clone execute
3091 // concurrently, as clone set the canonical DIE offset and analyze reads it.
3092 const uint64_t ModulesEndOffset =
3093 (TheDwarfEmitter == nullptr) ? 0
3094 : TheDwarfEmitter->getDebugInfoSectionSize();
3095
3096 // These variables manage the list of processed object files.
3097 // The mutex and condition variable are to ensure that this is thread safe.
3098 std::mutex ProcessedFilesMutex;
3099 std::condition_variable ProcessedFilesConditionVariable;
3100 BitVector ProcessedFiles(NumObjects, false);
3101
3102 // Analyzing the context info is particularly expensive so it is executed in
3103 // parallel with emitting the previous compile unit.
3104 auto AnalyzeLambda = [&](size_t I) {
3105 auto &Context = ObjectContexts[I];
3106
3107 if (Context.Skip || !Context.File.Dwarf)
3108 return;
3109
3110 for (const auto &CU : Context.File.Dwarf->compile_units()) {
3111 // Previously we only extracted the unit DIEs. We need the full debug info
3112 // now.
3113 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);
3114 std::string PCMFile = getPCMFile(CUDie, Options.ObjectPrefixMap);
3115
3116 if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
3117 !isClangModuleRef(CUDie, PCMFile, Context, 0, true).first) {
3118 Context.CompileUnits.push_back(std::make_unique<CompileUnit>(
3119 *CU, UniqueUnitID++, !Options.NoODR && !Options.Update, ""));
3120 }
3121 }
3122
3123 // Now build the DIE parent links that we will use during the next phase.
3124 for (auto &CurrentUnit : Context.CompileUnits) {
3125 auto CUDie = CurrentUnit->getOrigUnit().getUnitDIE();
3126 if (!CUDie)
3127 continue;
3128 analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0,
3129 *CurrentUnit, &ODRContexts.getRoot(), ODRContexts,
3130 ModulesEndOffset, Options.ParseableSwiftInterfaces,
3131 [&](const Twine &Warning, const DWARFDie &DIE) {
3132 reportWarning(Warning, Context.File, &DIE);
3133 });
3134 }
3135 };
3136
3137 // For each object file map how many bytes were emitted.
3138 StringMap<DebugInfoSize> SizeByObject;
3139
3140 // And then the remaining work in serial again.
3141 // Note, although this loop runs in serial, it can run in parallel with
3142 // the analyzeContextInfo loop so long as we process files with indices >=
3143 // than those processed by analyzeContextInfo.
3144 auto CloneLambda = [&](size_t I, llvm::Error &CE) {
3145 auto &OptContext = ObjectContexts[I];
3146 if (OptContext.Skip || !OptContext.File.Dwarf)
3147 return;
3148
3149 // Then mark all the DIEs that need to be present in the generated output
3150 // and collect some information about them.
3151 // Note that this loop can not be merged with the previous one because
3152 // cross-cu references require the ParentIdx to be setup for every CU in
3153 // the object file before calling this.
3154 if (LLVM_UNLIKELY(Options.Update)) {
3155 for (auto &CurrentUnit : OptContext.CompileUnits)
3156 CurrentUnit->markEverythingAsKept();
3157 copyInvariantDebugSection(*OptContext.File.Dwarf);
3158 } else {
3159 for (auto &CurrentUnit : OptContext.CompileUnits) {
3160 lookForDIEsToKeep(*OptContext.File.Addresses, OptContext.CompileUnits,
3161 CurrentUnit->getOrigUnit().getUnitDIE(),
3162 OptContext.File, *CurrentUnit, 0);
3163#ifndef NDEBUG
3164 verifyKeepChain(*CurrentUnit);
3165#endif
3166 }
3167 }
3168
3169 // The calls to applyValidRelocs inside cloneDIE will walk the reloc
3170 // array again (in the same way findValidRelocsInDebugInfo() did). We
3171 // need to reset the NextValidReloc index to the beginning.
3172 if (OptContext.File.Addresses->hasValidRelocs() ||
3173 LLVM_UNLIKELY(Options.Update)) {
3174 SizeByObject[OptContext.File.FileName].Input =
3175 getDebugInfoSize(*OptContext.File.Dwarf);
3176 Expected<uint64_t> SizeOrErr =
3177 DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc,
3178 OptContext.CompileUnits, Options.Update, DebugStrPool,
3179 DebugLineStrPool, StringOffsetPool)
3180 .cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File,
3181 OptContext.File.Dwarf->isLittleEndian());
3182 if (!SizeOrErr) {
3183 CE = SizeOrErr.takeError();
3184 return;
3185 }
3186 SizeByObject[OptContext.File.FileName].Output = *SizeOrErr;
3187 }
3188 if ((TheDwarfEmitter != nullptr) && !OptContext.CompileUnits.empty() &&
3189 LLVM_LIKELY(!Options.Update))
3190 patchFrameInfoForObject(OptContext);
3191
3192 // Clean-up before starting working on the next object.
3193 cleanupAuxiliarryData(OptContext);
3194 };
3195
3196 auto EmitLambda = [&]() {
3197 // Emit everything that's global.
3198 if (TheDwarfEmitter != nullptr) {
3199 TheDwarfEmitter->emitAbbrevs(Abbreviations, Options.TargetDWARFVersion);
3200 TheDwarfEmitter->emitStrings(DebugStrPool);
3201 TheDwarfEmitter->emitStringOffsets(StringOffsetPool.getValues(),
3202 Options.TargetDWARFVersion);
3203 TheDwarfEmitter->emitLineStrings(DebugLineStrPool);
3204 for (AccelTableKind TableKind : Options.AccelTables) {
3205 switch (TableKind) {
3207 TheDwarfEmitter->emitAppleNamespaces(AppleNamespaces);
3208 TheDwarfEmitter->emitAppleNames(AppleNames);
3209 TheDwarfEmitter->emitAppleTypes(AppleTypes);
3210 TheDwarfEmitter->emitAppleObjc(AppleObjc);
3211 break;
3213 // Already emitted by emitAcceleratorEntriesForUnit.
3214 // Already emitted by emitAcceleratorEntriesForUnit.
3215 break;
3217 TheDwarfEmitter->emitDebugNames(DebugNames);
3218 break;
3219 }
3220 }
3221 }
3222 };
3223
3224 auto AnalyzeAll = [&]() {
3225 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3226 AnalyzeLambda(I);
3227
3228 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
3229 ProcessedFiles.set(I);
3230 ProcessedFilesConditionVariable.notify_one();
3231 }
3232 };
3233
3234 auto CloneAll = [&](llvm::Error &CE) {
3235 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3236 {
3237 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
3238 if (!ProcessedFiles[I]) {
3239 ProcessedFilesConditionVariable.wait(
3240 LockGuard, [&]() { return ProcessedFiles[I]; });
3241 }
3242 }
3243
3244 CloneLambda(I, CE);
3245 if (CE)
3246 return;
3247 }
3248 EmitLambda();
3249 };
3250
3251 Error CE = Error::success();
3252
3253 // To limit memory usage in the single threaded case, analyze and clone are
3254 // run sequentially so the OptContext is freed after processing each object
3255 // in endDebugObject.
3256 if (Options.Threads == 1) {
3257 for (unsigned I = 0, E = NumObjects; I != E; ++I) {
3258 AnalyzeLambda(I);
3259 CloneLambda(I, CE);
3260 if (CE)
3261 break;
3262 }
3263 if (!CE)
3264 EmitLambda();
3265 } else {
3267 Pool.async(AnalyzeAll);
3268 Pool.async(CloneAll, std::reference_wrapper<Error>(CE));
3269 Pool.wait();
3270 }
3271
3272 if (CE)
3273 return CE;
3274
3275 if (Options.Statistics) {
3276 // Create a vector sorted in descending order by output size.
3277 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted;
3278 for (auto &E : SizeByObject)
3279 Sorted.emplace_back(E.first(), E.second);
3280 llvm::sort(Sorted, [](auto &LHS, auto &RHS) {
3281 return LHS.second.Output > RHS.second.Output;
3282 });
3283
3284 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float {
3285 const float Difference = Output - Input;
3286 const float Sum = Input + Output;
3287 if (Sum == 0)
3288 return 0;
3289 return (Difference / (Sum / 2));
3290 };
3291
3292 int64_t InputTotal = 0;
3293 int64_t OutputTotal = 0;
3294 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
3295
3296 // Print header.
3297 outs() << ".debug_info section size (in bytes)\n";
3298 outs() << "----------------------------------------------------------------"
3299 "---------------\n";
3300 outs() << "Filename Object "
3301 " dSYM Change\n";
3302 outs() << "----------------------------------------------------------------"
3303 "---------------\n";
3304
3305 // Print body.
3306 for (auto &E : Sorted) {
3307 InputTotal += E.second.Input;
3308 OutputTotal += E.second.Output;
3309 llvm::outs() << formatv(
3310 FormatStr, sys::path::filename(E.first).take_back(45), E.second.Input,
3311 E.second.Output, ComputePercentange(E.second.Input, E.second.Output));
3312 }
3313 // Print total and footer.
3314 outs() << "----------------------------------------------------------------"
3315 "---------------\n";
3316 llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal,
3317 ComputePercentange(InputTotal, OutputTotal));
3318 outs() << "----------------------------------------------------------------"
3319 "---------------\n\n";
3320 }
3321
3322 return Error::success();
3323}
3324
3325Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
3326 DeclContextTree &ODRContexts,
3327 OffsetsStringPool &DebugStrPool,
3328 OffsetsStringPool &DebugLineStrPool,
3329 DebugDieValuePool &StringOffsetPool,
3330 unsigned Indent) {
3331 assert(Unit.Unit.get() != nullptr);
3332
3333 if (!Unit.Unit->getOrigUnit().getUnitDIE().hasChildren())
3334 return Error::success();
3335
3336 if (Options.Verbose) {
3337 outs().indent(Indent);
3338 outs() << "cloning .debug_info from " << Unit.File.FileName << "\n";
3339 }
3340
3341 // Analyze context for the module.
3342 analyzeContextInfo(Unit.Unit->getOrigUnit().getUnitDIE(), 0, *(Unit.Unit),
3343 &ODRContexts.getRoot(), ODRContexts, 0,
3344 Options.ParseableSwiftInterfaces,
3345 [&](const Twine &Warning, const DWARFDie &DIE) {
3346 reportWarning(Warning, Context.File, &DIE);
3347 });
3348 // Keep everything.
3349 Unit.Unit->markEverythingAsKept();
3350
3351 // Clone unit.
3352 UnitListTy CompileUnits;
3353 CompileUnits.emplace_back(std::move(Unit.Unit));
3354 assert(TheDwarfEmitter);
3355 Expected<uint64_t> SizeOrErr =
3356 DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits,
3357 Options.Update, DebugStrPool, DebugLineStrPool,
3358 StringOffsetPool)
3359 .cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File,
3360 Unit.File.Dwarf->isLittleEndian());
3361 if (!SizeOrErr)
3362 return SizeOrErr.takeError();
3363 return Error::success();
3364}
3365
3366void DWARFLinker::verifyInput(const DWARFFile &File) {
3367 assert(File.Dwarf);
3368
3369 std::string Buffer;
3370 raw_string_ostream OS(Buffer);
3371 DIDumpOptions DumpOpts;
3372 if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) {
3373 if (Options.InputVerificationHandler)
3374 Options.InputVerificationHandler(File, OS.str());
3375 }
3376}
3377
3378} // namespace llvm
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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:344
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:343
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:828
value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V)
Definition DIE.h:761
A structured debug information entry.
Definition DIE.h:840
unsigned getAbbrevNumber() const
Definition DIE.h:875
DIE & addChild(DIE *Child)
Add a child to the DIE.
Definition DIE.h:956
LLVM_ABI DIEAbbrev generateAbbrev() const
Generate the abbreviation for this DIE.
Definition DIE.cpp:174
void setSize(unsigned S)
Definition DIE.h:953
static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)
Definition DIE.h:870
void setAbbrevNumber(unsigned I)
Set the abbreviation number for this DIE.
Definition DIE.h:912
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition DIE.h:878
void setOffset(unsigned O)
Definition DIE.h:952
dwarf::Tag getTag() const
Definition DIE.h:876
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:317
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:128
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:1061
#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:59
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:17
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:95
bool isTlsAddressOp(uint8_t O)
Definition Dwarf.h:1179
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:949
@ DW_FLAG_type_implementation
Definition Dwarf.h:1036
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
LLVM_ABI 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:578
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:2129
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
static void patchAddrBase(DIE &Die, DIEInteger Offset)
auto unique(Range &&R, Predicate P)
Definition STLExtras.h:2134
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:2065
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:407
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
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:196
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition DIContext.h:228
unsigned ChildRecurseDepth
Definition DIContext.h:198
static LLVM_ABI bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
Definition DWARFDie.cpp:818
static LLVM_ABI bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition DWARFDie.cpp:835
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?