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