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