xref: /freebsd/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //=== DWARFLinkerCompileUnit.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 "DWARFLinkerCompileUnit.h"
10 #include "AcceleratorRecordsSaver.h"
11 #include "DIEAttributeCloner.h"
12 #include "DIEGenerator.h"
13 #include "DependencyTracker.h"
14 #include "SyntheticTypeNameBuilder.h"
15 #include "llvm/DWARFLinker/Utils.h"
16 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
17 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
18 #include "llvm/Support/DJB.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/FormatVariadic.h"
21 #include "llvm/Support/Path.h"
22 #include <utility>
23 
24 using namespace llvm;
25 using namespace dwarf_linker;
26 using namespace dwarf_linker::parallel;
27 
CompileUnit(LinkingGlobalData & GlobalData,unsigned ID,StringRef ClangModuleName,DWARFFile & File,OffsetToUnitTy UnitFromOffset,dwarf::FormParams Format,llvm::endianness Endianess)28 CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,
29                          StringRef ClangModuleName, DWARFFile &File,
30                          OffsetToUnitTy UnitFromOffset,
31                          dwarf::FormParams Format, llvm::endianness Endianess)
32     : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),
33       getUnitFromOffset(UnitFromOffset), Stage(Stage::CreatedNotLoaded),
34       AcceleratorRecords(&GlobalData.getAllocator()) {
35   UnitName = File.FileName;
36   setOutputFormat(Format, Endianess);
37   getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
38 }
39 
CompileUnit(LinkingGlobalData & GlobalData,DWARFUnit & OrigUnit,unsigned ID,StringRef ClangModuleName,DWARFFile & File,OffsetToUnitTy UnitFromOffset,dwarf::FormParams Format,llvm::endianness Endianess)40 CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit,
41                          unsigned ID, StringRef ClangModuleName,
42                          DWARFFile &File, OffsetToUnitTy UnitFromOffset,
43                          dwarf::FormParams Format, llvm::endianness Endianess)
44     : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),
45       OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
46       Stage(Stage::CreatedNotLoaded),
47       AcceleratorRecords(&GlobalData.getAllocator()) {
48   setOutputFormat(Format, Endianess);
49   getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
50 
51   DWARFDie CUDie = OrigUnit.getUnitDIE();
52   if (!CUDie)
53     return;
54 
55   if (std::optional<DWARFFormValue> Val = CUDie.find(dwarf::DW_AT_language)) {
56     uint16_t LangVal = dwarf::toUnsigned(Val, 0);
57     if (isODRLanguage(LangVal))
58       Language = LangVal;
59   }
60 
61   if (!GlobalData.getOptions().NoODR && Language.has_value())
62     NoODR = false;
63 
64   if (const char *CUName = CUDie.getName(DINameKind::ShortName))
65     UnitName = CUName;
66   else
67     UnitName = File.FileName;
68   SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str();
69 }
70 
loadLineTable()71 void CompileUnit::loadLineTable() {
72   LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit());
73 }
74 
maybeResetToLoadedStage()75 void CompileUnit::maybeResetToLoadedStage() {
76   // Nothing to reset if stage is less than "Loaded".
77   if (getStage() < Stage::Loaded)
78     return;
79 
80   // Note: We need to do erasing for "Loaded" stage because
81   // if live analysys failed then we will have "Loaded" stage
82   // with marking from "LivenessAnalysisDone" stage partially
83   // done. That marking should be cleared.
84 
85   for (DIEInfo &Info : DieInfoArray)
86     Info.unsetFlagsWhichSetDuringLiveAnalysis();
87 
88   LowPc = std::nullopt;
89   HighPc = 0;
90   Labels.clear();
91   Ranges.clear();
92   Dependencies.reset(nullptr);
93 
94   if (getStage() < Stage::Cloned) {
95     setStage(Stage::Loaded);
96     return;
97   }
98 
99   AcceleratorRecords.erase();
100   AbbreviationsSet.clear();
101   Abbreviations.clear();
102   OutUnitDIE = nullptr;
103   DebugAddrIndexMap.clear();
104 
105   for (uint64_t &Offset : OutDieOffsetArray)
106     Offset = 0;
107   for (TypeEntry *&Name : TypeEntries)
108     Name = nullptr;
109   eraseSections();
110 
111   setStage(Stage::CreatedNotLoaded);
112 }
113 
loadInputDIEs()114 bool CompileUnit::loadInputDIEs() {
115   DWARFDie InputUnitDIE = getUnitDIE(false);
116   if (!InputUnitDIE)
117     return false;
118 
119   // load input dies, resize Info structures array.
120   DieInfoArray.resize(getOrigUnit().getNumDIEs());
121   OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);
122   if (!NoODR)
123     TypeEntries.resize(getOrigUnit().getNumDIEs());
124   return true;
125 }
126 
analyzeDWARFStructureRec(const DWARFDebugInfoEntry * DieEntry,bool IsODRUnavailableFunctionScope)127 void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
128                                            bool IsODRUnavailableFunctionScope) {
129   CompileUnit::DIEInfo &DieInfo = getDIEInfo(DieEntry);
130 
131   for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);
132        CurChild && CurChild->getAbbreviationDeclarationPtr();
133        CurChild = getSiblingEntry(CurChild)) {
134     CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);
135     bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
136 
137     if (DieInfo.getIsInMouduleScope())
138       ChildInfo.setIsInMouduleScope();
139 
140     if (DieInfo.getIsInFunctionScope())
141       ChildInfo.setIsInFunctionScope();
142 
143     if (DieInfo.getIsInAnonNamespaceScope())
144       ChildInfo.setIsInAnonNamespaceScope();
145 
146     switch (CurChild->getTag()) {
147     case dwarf::DW_TAG_module:
148       ChildInfo.setIsInMouduleScope();
149       if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
150           dwarf::toString(find(CurChild, dwarf::DW_AT_name), "") !=
151               getClangModuleName())
152         analyzeImportedModule(CurChild);
153       break;
154     case dwarf::DW_TAG_subprogram:
155       ChildInfo.setIsInFunctionScope();
156       if (!ChildIsODRUnavailableFunctionScope &&
157           !ChildInfo.getIsInMouduleScope()) {
158         if (find(CurChild,
159                  {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
160           ChildIsODRUnavailableFunctionScope = true;
161       }
162       break;
163     case dwarf::DW_TAG_namespace: {
164       UnitEntryPairTy NamespaceEntry = {this, CurChild};
165 
166       if (find(CurChild, dwarf::DW_AT_extension))
167         NamespaceEntry = NamespaceEntry.getNamespaceOrigin();
168 
169       if (!NamespaceEntry.CU->find(NamespaceEntry.DieEntry, dwarf::DW_AT_name))
170         ChildInfo.setIsInAnonNamespaceScope();
171     } break;
172     default:
173       break;
174     }
175 
176     if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)
177       ChildInfo.setTrackLiveness();
178 
179     if ((!ChildInfo.getIsInAnonNamespaceScope() &&
180          !ChildIsODRUnavailableFunctionScope && !NoODR))
181       ChildInfo.setODRAvailable();
182 
183     if (CurChild->hasChildren())
184       analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
185   }
186 }
187 
getFileName(unsigned FileIdx,StringPool & GlobalStrings)188 StringEntry *CompileUnit::getFileName(unsigned FileIdx,
189                                       StringPool &GlobalStrings) {
190   if (LineTablePtr) {
191     if (LineTablePtr->hasFileAtIndex(FileIdx)) {
192       // Cache the resolved paths based on the index in the line table,
193       // because calling realpath is expensive.
194       ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx);
195       if (It == ResolvedFullPaths.end()) {
196         std::string OrigFileName;
197         bool FoundFileName = LineTablePtr->getFileNameByIndex(
198             FileIdx, getOrigUnit().getCompilationDir(),
199             DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
200             OrigFileName);
201         (void)FoundFileName;
202         assert(FoundFileName && "Must get file name from line table");
203 
204         // Second level of caching, this time based on the file's parent
205         // path.
206         StringRef FileName = sys::path::filename(OrigFileName);
207         StringRef ParentPath = sys::path::parent_path(OrigFileName);
208 
209         // If the ParentPath has not yet been resolved, resolve and cache it for
210         // future look-ups.
211         StringMap<StringEntry *>::iterator ParentIt =
212             ResolvedParentPaths.find(ParentPath);
213         if (ParentIt == ResolvedParentPaths.end()) {
214           SmallString<256> RealPath;
215           sys::fs::real_path(ParentPath, RealPath);
216           ParentIt =
217               ResolvedParentPaths
218                   .insert({ParentPath, GlobalStrings.insert(RealPath).first})
219                   .first;
220         }
221 
222         // Join the file name again with the resolved path.
223         SmallString<256> ResolvedPath(ParentIt->second->first());
224         sys::path::append(ResolvedPath, FileName);
225 
226         It = ResolvedFullPaths
227                  .insert(std::make_pair(
228                      FileIdx, GlobalStrings.insert(ResolvedPath).first))
229                  .first;
230       }
231 
232       return It->second;
233     }
234   }
235 
236   return nullptr;
237 }
238 
cleanupDataAfterClonning()239 void CompileUnit::cleanupDataAfterClonning() {
240   AbbreviationsSet.clear();
241   ResolvedFullPaths.shrink_and_clear();
242   ResolvedParentPaths.clear();
243   FileNames.shrink_and_clear();
244   DieInfoArray = SmallVector<DIEInfo>();
245   OutDieOffsetArray = SmallVector<uint64_t>();
246   TypeEntries = SmallVector<TypeEntry *>();
247   Dependencies.reset(nullptr);
248   getOrigUnit().clear();
249 }
250 
251 /// Collect references to parseable Swift interfaces in imported
252 /// DW_TAG_module blocks.
analyzeImportedModule(const DWARFDebugInfoEntry * DieEntry)253 void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {
254   if (!Language || Language != dwarf::DW_LANG_Swift)
255     return;
256 
257   if (!GlobalData.getOptions().ParseableSwiftInterfaces)
258     return;
259 
260   StringRef Path =
261       dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path));
262   if (!Path.ends_with(".swiftinterface"))
263     return;
264   // Don't track interfaces that are part of the SDK.
265   StringRef SysRoot =
266       dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot));
267   if (SysRoot.empty())
268     SysRoot = getSysRoot();
269   if (!SysRoot.empty() && Path.starts_with(SysRoot))
270     return;
271   // Don't track interfaces that are part of the toolchain.
272   // For example: Swift, _Concurrency, ...
273   StringRef DeveloperDir = guessDeveloperDir(SysRoot);
274   if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))
275     return;
276   if (isInToolchainDir(Path))
277     return;
278   if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {
279     Expected<const char *> Name = Val->getAsCString();
280     if (!Name) {
281       warn(Name.takeError());
282       return;
283     }
284 
285     auto &Entry = (*GlobalData.getOptions().ParseableSwiftInterfaces)[*Name];
286     // The prepend path is applied later when copying.
287     SmallString<128> ResolvedPath;
288     if (sys::path::is_relative(Path))
289       sys::path::append(
290           ResolvedPath,
291           dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir), ""));
292     sys::path::append(ResolvedPath, Path);
293     if (!Entry.empty() && Entry != ResolvedPath) {
294       DWARFDie Die = getDIE(DieEntry);
295       warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name +
296                ": " + Entry + " and " + Path + ".",
297            &Die);
298     }
299     Entry = std::string(ResolvedPath);
300   }
301 }
302 
assignTypeNames(TypePool & TypePoolRef)303 Error CompileUnit::assignTypeNames(TypePool &TypePoolRef) {
304   if (!getUnitDIE().isValid())
305     return Error::success();
306 
307   SyntheticTypeNameBuilder NameBuilder(TypePoolRef);
308   return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder);
309 }
310 
assignTypeNamesRec(const DWARFDebugInfoEntry * DieEntry,SyntheticTypeNameBuilder & NameBuilder)311 Error CompileUnit::assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,
312                                       SyntheticTypeNameBuilder &NameBuilder) {
313   OrderedChildrenIndexAssigner ChildrenIndexAssigner(*this, DieEntry);
314   for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);
315        CurChild && CurChild->getAbbreviationDeclarationPtr();
316        CurChild = getSiblingEntry(CurChild)) {
317     CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);
318     if (!ChildInfo.needToPlaceInTypeTable())
319       continue;
320 
321     assert(ChildInfo.getODRAvailable());
322     if (Error Err = NameBuilder.assignName(
323             {this, CurChild},
324             ChildrenIndexAssigner.getChildIndex(*this, CurChild)))
325       return Err;
326 
327     if (Error Err = assignTypeNamesRec(CurChild, NameBuilder))
328       return Err;
329   }
330 
331   return Error::success();
332 }
333 
updateDieRefPatchesWithClonedOffsets()334 void CompileUnit::updateDieRefPatchesWithClonedOffsets() {
335   if (std::optional<SectionDescriptor *> DebugInfoSection =
336           tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) {
337 
338     (*DebugInfoSection)
339         ->ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) {
340           /// Replace stored DIE indexes with DIE output offsets.
341           Patch.RefDieIdxOrClonedOffset =
342               Patch.RefCU.getPointer()->getDieOutOffset(
343                   Patch.RefDieIdxOrClonedOffset);
344         });
345 
346     (*DebugInfoSection)
347         ->ListDebugULEB128DieRefPatch.forEach(
348             [&](DebugULEB128DieRefPatch &Patch) {
349               /// Replace stored DIE indexes with DIE output offsets.
350               Patch.RefDieIdxOrClonedOffset =
351                   Patch.RefCU.getPointer()->getDieOutOffset(
352                       Patch.RefDieIdxOrClonedOffset);
353             });
354   }
355 
356   if (std::optional<SectionDescriptor *> DebugLocSection =
357           tryGetSectionDescriptor(DebugSectionKind::DebugLoc)) {
358     (*DebugLocSection)
359         ->ListDebugULEB128DieRefPatch.forEach(
360             [](DebugULEB128DieRefPatch &Patch) {
361               /// Replace stored DIE indexes with DIE output offsets.
362               Patch.RefDieIdxOrClonedOffset =
363                   Patch.RefCU.getPointer()->getDieOutOffset(
364                       Patch.RefDieIdxOrClonedOffset);
365             });
366   }
367 
368   if (std::optional<SectionDescriptor *> DebugLocListsSection =
369           tryGetSectionDescriptor(DebugSectionKind::DebugLocLists)) {
370     (*DebugLocListsSection)
371         ->ListDebugULEB128DieRefPatch.forEach(
372             [](DebugULEB128DieRefPatch &Patch) {
373               /// Replace stored DIE indexes with DIE output offsets.
374               Patch.RefDieIdxOrClonedOffset =
375                   Patch.RefCU.getPointer()->getDieOutOffset(
376                       Patch.RefDieIdxOrClonedOffset);
377             });
378   }
379 }
380 
resolveDIEReference(const DWARFFormValue & RefValue,ResolveInterCUReferencesMode CanResolveInterCUReferences)381 std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
382     const DWARFFormValue &RefValue,
383     ResolveInterCUReferencesMode CanResolveInterCUReferences) {
384   CompileUnit *RefCU;
385   uint64_t RefDIEOffset;
386   if (std::optional<uint64_t> Offset = RefValue.getAsRelativeReference()) {
387     RefCU = this;
388     RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset;
389   } else if (Offset = RefValue.getAsDebugInfoReference(); Offset) {
390     RefCU = getUnitFromOffset(*Offset);
391     RefDIEOffset = *Offset;
392   } else {
393     return std::nullopt;
394   }
395 
396   if (RefCU == this) {
397     // Referenced DIE is in current compile unit.
398     if (std::optional<uint32_t> RefDieIdx = getDIEIndexForOffset(RefDIEOffset))
399       return UnitEntryPairTy{this, getDebugInfoEntry(*RefDieIdx)};
400   } else if (RefCU && CanResolveInterCUReferences) {
401     // Referenced DIE is in other compile unit.
402 
403     // Check whether DIEs are loaded for that compile unit.
404     enum Stage ReferredCUStage = RefCU->getStage();
405     if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned)
406       return UnitEntryPairTy{RefCU, nullptr};
407 
408     if (std::optional<uint32_t> RefDieIdx =
409             RefCU->getDIEIndexForOffset(RefDIEOffset))
410       return UnitEntryPairTy{RefCU, RefCU->getDebugInfoEntry(*RefDieIdx)};
411   } else {
412     return UnitEntryPairTy{RefCU, nullptr};
413   }
414   return std::nullopt;
415 }
416 
resolveDIEReference(const DWARFDebugInfoEntry * DieEntry,dwarf::Attribute Attr,ResolveInterCUReferencesMode CanResolveInterCUReferences)417 std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
418     const DWARFDebugInfoEntry *DieEntry, dwarf::Attribute Attr,
419     ResolveInterCUReferencesMode CanResolveInterCUReferences) {
420   if (std::optional<DWARFFormValue> AttrVal = find(DieEntry, Attr))
421     return resolveDIEReference(*AttrVal, CanResolveInterCUReferences);
422 
423   return std::nullopt;
424 }
425 
addFunctionRange(uint64_t FuncLowPc,uint64_t FuncHighPc,int64_t PcOffset)426 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
427                                    int64_t PcOffset) {
428   std::lock_guard<std::mutex> Guard(RangesMutex);
429 
430   Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
431   if (LowPc)
432     LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
433   else
434     LowPc = FuncLowPc + PcOffset;
435   this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
436 }
437 
addLabelLowPc(uint64_t LabelLowPc,int64_t PcOffset)438 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
439   std::lock_guard<std::mutex> Guard(LabelsMutex);
440   Labels.insert({LabelLowPc, PcOffset});
441 }
442 
cloneAndEmitDebugLocations()443 Error CompileUnit::cloneAndEmitDebugLocations() {
444   if (getGlobalData().getOptions().UpdateIndexTablesOnly)
445     return Error::success();
446 
447   if (getOrigUnit().getVersion() < 5) {
448     emitLocations(DebugSectionKind::DebugLoc);
449     return Error::success();
450   }
451 
452   emitLocations(DebugSectionKind::DebugLocLists);
453   return Error::success();
454 }
455 
emitLocations(DebugSectionKind LocationSectionKind)456 void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {
457   SectionDescriptor &DebugInfoSection =
458       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
459 
460   if (!DebugInfoSection.ListDebugLocPatch.empty()) {
461     SectionDescriptor &OutLocationSection =
462         getOrCreateSectionDescriptor(LocationSectionKind);
463     DWARFUnit &OrigUnit = getOrigUnit();
464 
465     uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
466 
467     DebugInfoSection.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {
468       // Get location expressions vector corresponding to the current
469       // attribute from the source DWARF.
470       uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal(
471           Patch.PatchOffset,
472           DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
473       Expected<DWARFLocationExpressionsVector> OriginalLocations =
474           OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset);
475 
476       if (!OriginalLocations) {
477         warn(OriginalLocations.takeError());
478         return;
479       }
480 
481       LinkedLocationExpressionsVector LinkedLocationExpressions;
482       for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
483         LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
484 
485         if (CurExpression.Range) {
486           // Relocate address range.
487           LinkedExpression.Expression.Range = {
488               CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,
489               CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};
490         }
491 
492         DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(),
493                            OrigUnit.getAddressByteSize());
494 
495         DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),
496                                         OrigUnit.getFormParams().Format);
497         cloneDieAttrExpression(InputExpression,
498                                LinkedExpression.Expression.Expr,
499                                OutLocationSection, Patch.AddrAdjustmentValue,
500                                LinkedExpression.Patches);
501 
502         LinkedLocationExpressions.push_back({LinkedExpression});
503       }
504 
505       // Emit locations list table fragment corresponding to the CurLocAttr.
506       DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
507                              OutLocationSection.OS.tell());
508       emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
509     });
510 
511     if (OffsetAfterUnitLength > 0) {
512       assert(OffsetAfterUnitLength -
513                  OutLocationSection.getFormParams().getDwarfOffsetByteSize() <
514              OffsetAfterUnitLength);
515       OutLocationSection.apply(
516           OffsetAfterUnitLength -
517               OutLocationSection.getFormParams().getDwarfOffsetByteSize(),
518           dwarf::DW_FORM_sec_offset,
519           OutLocationSection.OS.tell() - OffsetAfterUnitLength);
520     }
521   }
522 }
523 
524 /// Emit debug locations(.debug_loc, .debug_loclists) header.
emitLocListHeader(SectionDescriptor & OutLocationSection)525 uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {
526   if (getOrigUnit().getVersion() < 5)
527     return 0;
528 
529   // unit_length.
530   OutLocationSection.emitUnitLength(0xBADDEF);
531   uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell();
532 
533   // Version.
534   OutLocationSection.emitIntVal(5, 2);
535 
536   // Address size.
537   OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1);
538 
539   // Seg_size
540   OutLocationSection.emitIntVal(0, 1);
541 
542   // Offset entry count
543   OutLocationSection.emitIntVal(0, 4);
544 
545   return OffsetAfterUnitLength;
546 }
547 
548 /// Emit debug locations(.debug_loc, .debug_loclists) fragment.
emitLocListFragment(const LinkedLocationExpressionsVector & LinkedLocationExpression,SectionDescriptor & OutLocationSection)549 uint64_t CompileUnit::emitLocListFragment(
550     const LinkedLocationExpressionsVector &LinkedLocationExpression,
551     SectionDescriptor &OutLocationSection) {
552   uint64_t OffsetBeforeLocationExpression = 0;
553 
554   if (getOrigUnit().getVersion() < 5) {
555     uint64_t BaseAddress = 0;
556     if (std::optional<uint64_t> LowPC = getLowPc())
557       BaseAddress = *LowPC;
558 
559     for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
560          LinkedLocationExpression) {
561       if (LocExpression.Expression.Range) {
562         OutLocationSection.emitIntVal(
563             LocExpression.Expression.Range->LowPC - BaseAddress,
564             OutLocationSection.getFormParams().AddrSize);
565         OutLocationSection.emitIntVal(
566             LocExpression.Expression.Range->HighPC - BaseAddress,
567             OutLocationSection.getFormParams().AddrSize);
568       }
569 
570       OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2);
571       OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
572       for (uint64_t *OffsetPtr : LocExpression.Patches)
573         *OffsetPtr += OffsetBeforeLocationExpression;
574 
575       OutLocationSection.OS
576           << StringRef((const char *)LocExpression.Expression.Expr.data(),
577                        LocExpression.Expression.Expr.size());
578     }
579 
580     // Emit the terminator entry.
581     OutLocationSection.emitIntVal(0,
582                                   OutLocationSection.getFormParams().AddrSize);
583     OutLocationSection.emitIntVal(0,
584                                   OutLocationSection.getFormParams().AddrSize);
585     return OffsetBeforeLocationExpression;
586   }
587 
588   std::optional<uint64_t> BaseAddress;
589   for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
590        LinkedLocationExpression) {
591     if (LocExpression.Expression.Range) {
592       // Check whether base address is set. If it is not set yet
593       // then set current base address and emit base address selection entry.
594       if (!BaseAddress) {
595         BaseAddress = LocExpression.Expression.Range->LowPC;
596 
597         // Emit base address.
598         OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1);
599         encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress),
600                       OutLocationSection.OS);
601       }
602 
603       // Emit type of entry.
604       OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1);
605 
606       // Emit start offset relative to base address.
607       encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
608                     OutLocationSection.OS);
609 
610       // Emit end offset relative to base address.
611       encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
612                     OutLocationSection.OS);
613     } else
614       // Emit type of entry.
615       OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1);
616 
617     encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS);
618     OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
619     for (uint64_t *OffsetPtr : LocExpression.Patches)
620       *OffsetPtr += OffsetBeforeLocationExpression;
621 
622     OutLocationSection.OS << StringRef(
623         (const char *)LocExpression.Expression.Expr.data(),
624         LocExpression.Expression.Expr.size());
625   }
626 
627   // Emit the terminator entry.
628   OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1);
629   return OffsetBeforeLocationExpression;
630 }
631 
emitDebugAddrSection()632 Error CompileUnit::emitDebugAddrSection() {
633   if (GlobalData.getOptions().UpdateIndexTablesOnly)
634     return Error::success();
635 
636   if (getVersion() < 5)
637     return Error::success();
638 
639   if (DebugAddrIndexMap.empty())
640     return Error::success();
641 
642   SectionDescriptor &OutAddrSection =
643       getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr);
644 
645   // Emit section header.
646 
647   //   Emit length.
648   OutAddrSection.emitUnitLength(0xBADDEF);
649   uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell();
650 
651   //   Emit version.
652   OutAddrSection.emitIntVal(5, 2);
653 
654   //   Emit address size.
655   OutAddrSection.emitIntVal(getFormParams().AddrSize, 1);
656 
657   //   Emit segment size.
658   OutAddrSection.emitIntVal(0, 1);
659 
660   // Emit addresses.
661   for (uint64_t AddrValue : DebugAddrIndexMap.getValues())
662     OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize);
663 
664   // Patch section length.
665   OutAddrSection.apply(
666       OffsetAfterSectionLength -
667           OutAddrSection.getFormParams().getDwarfOffsetByteSize(),
668       dwarf::DW_FORM_sec_offset,
669       OutAddrSection.OS.tell() - OffsetAfterSectionLength);
670 
671   return Error::success();
672 }
673 
cloneAndEmitRanges()674 Error CompileUnit::cloneAndEmitRanges() {
675   if (getGlobalData().getOptions().UpdateIndexTablesOnly)
676     return Error::success();
677 
678   // Build set of linked address ranges for unit function ranges.
679   AddressRanges LinkedFunctionRanges;
680   for (const AddressRangeValuePair &Range : getFunctionRanges())
681     LinkedFunctionRanges.insert(
682         {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
683 
684   emitAranges(LinkedFunctionRanges);
685 
686   if (getOrigUnit().getVersion() < 5) {
687     cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges);
688     return Error::success();
689   }
690 
691   cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges);
692   return Error::success();
693 }
694 
cloneAndEmitRangeList(DebugSectionKind RngSectionKind,AddressRanges & LinkedFunctionRanges)695 void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
696                                         AddressRanges &LinkedFunctionRanges) {
697   SectionDescriptor &DebugInfoSection =
698       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
699   SectionDescriptor &OutRangeSection =
700       getOrCreateSectionDescriptor(RngSectionKind);
701 
702   if (!DebugInfoSection.ListDebugRangePatch.empty()) {
703     std::optional<AddressRangeValuePair> CachedRange;
704     uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
705 
706     DebugRangePatch *CompileUnitRangePtr = nullptr;
707     DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
708       if (Patch.IsCompileUnitRanges) {
709         CompileUnitRangePtr = &Patch;
710       } else {
711         // Get ranges from the source DWARF corresponding to the current
712         // attribute.
713         AddressRanges LinkedRanges;
714         uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
715             Patch.PatchOffset,
716             DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
717         if (Expected<DWARFAddressRangesVector> InputRanges =
718                 getOrigUnit().findRnglistFromOffset(
719                     InputDebugRangesSectionOffset)) {
720           // Apply relocation adjustment.
721           for (const auto &Range : *InputRanges) {
722             if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
723               CachedRange =
724                   getFunctionRanges().getRangeThatContains(Range.LowPC);
725 
726             // All range entries should lie in the function range.
727             if (!CachedRange) {
728               warn("inconsistent range data.");
729               continue;
730             }
731 
732             // Store range for emiting.
733             LinkedRanges.insert({Range.LowPC + CachedRange->Value,
734                                  Range.HighPC + CachedRange->Value});
735           }
736         } else {
737           llvm::consumeError(InputRanges.takeError());
738           warn("invalid range list ignored.");
739         }
740 
741         // Emit linked ranges.
742         DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
743                                OutRangeSection.OS.tell());
744         emitRangeListFragment(LinkedRanges, OutRangeSection);
745       }
746     });
747 
748     if (CompileUnitRangePtr != nullptr) {
749       // Emit compile unit ranges last to be binary compatible with classic
750       // dsymutil.
751       DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset,
752                              dwarf::DW_FORM_sec_offset,
753                              OutRangeSection.OS.tell());
754       emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
755     }
756 
757     if (OffsetAfterUnitLength > 0) {
758       assert(OffsetAfterUnitLength -
759                  OutRangeSection.getFormParams().getDwarfOffsetByteSize() <
760              OffsetAfterUnitLength);
761       OutRangeSection.apply(
762           OffsetAfterUnitLength -
763               OutRangeSection.getFormParams().getDwarfOffsetByteSize(),
764           dwarf::DW_FORM_sec_offset,
765           OutRangeSection.OS.tell() - OffsetAfterUnitLength);
766     }
767   }
768 }
769 
emitRangeListHeader(SectionDescriptor & OutRangeSection)770 uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {
771   if (OutRangeSection.getFormParams().Version < 5)
772     return 0;
773 
774   // unit_length.
775   OutRangeSection.emitUnitLength(0xBADDEF);
776   uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell();
777 
778   // Version.
779   OutRangeSection.emitIntVal(5, 2);
780 
781   // Address size.
782   OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1);
783 
784   // Seg_size
785   OutRangeSection.emitIntVal(0, 1);
786 
787   // Offset entry count
788   OutRangeSection.emitIntVal(0, 4);
789 
790   return OffsetAfterUnitLength;
791 }
792 
emitRangeListFragment(const AddressRanges & LinkedRanges,SectionDescriptor & OutRangeSection)793 void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges,
794                                         SectionDescriptor &OutRangeSection) {
795   if (OutRangeSection.getFormParams().Version < 5) {
796     // Emit ranges.
797     uint64_t BaseAddress = 0;
798     if (std::optional<uint64_t> LowPC = getLowPc())
799       BaseAddress = *LowPC;
800 
801     for (const AddressRange &Range : LinkedRanges) {
802       OutRangeSection.emitIntVal(Range.start() - BaseAddress,
803                                  OutRangeSection.getFormParams().AddrSize);
804       OutRangeSection.emitIntVal(Range.end() - BaseAddress,
805                                  OutRangeSection.getFormParams().AddrSize);
806     }
807 
808     // Add the terminator entry.
809     OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
810     OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
811     return;
812   }
813 
814   std::optional<uint64_t> BaseAddress;
815   for (const AddressRange &Range : LinkedRanges) {
816     if (!BaseAddress) {
817       BaseAddress = Range.start();
818 
819       // Emit base address.
820       OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1);
821       encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS);
822     }
823 
824     // Emit type of entry.
825     OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1);
826 
827     // Emit start offset relative to base address.
828     encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS);
829 
830     // Emit end offset relative to base address.
831     encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS);
832   }
833 
834   // Emit the terminator entry.
835   OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1);
836 }
837 
emitAranges(AddressRanges & LinkedFunctionRanges)838 void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
839   if (LinkedFunctionRanges.empty())
840     return;
841 
842   SectionDescriptor &DebugInfoSection =
843       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
844   SectionDescriptor &OutArangesSection =
845       getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges);
846 
847   // Emit Header.
848   unsigned HeaderSize =
849       sizeof(int32_t) + // Size of contents (w/o this field
850       sizeof(int16_t) + // DWARF ARange version number
851       sizeof(int32_t) + // Offset of CU in the .debug_info section
852       sizeof(int8_t) +  // Pointer Size (in bytes)
853       sizeof(int8_t);   // Segment Size (in bytes)
854 
855   unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;
856   unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
857 
858   OutArangesSection.emitOffset(0xBADDEF); // Aranges length
859   uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();
860 
861   OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2); // Version number
862   OutArangesSection.notePatch(
863       DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection});
864   OutArangesSection.emitOffset(0xBADDEF); // Corresponding unit's offset
865   OutArangesSection.emitIntVal(OutArangesSection.getFormParams().AddrSize,
866                                1);    // Address size
867   OutArangesSection.emitIntVal(0, 1); // Segment size
868 
869   for (size_t Idx = 0; Idx < Padding; Idx++)
870     OutArangesSection.emitIntVal(0, 1); // Padding
871 
872   // Emit linked ranges.
873   for (const AddressRange &Range : LinkedFunctionRanges) {
874     OutArangesSection.emitIntVal(Range.start(),
875                                  OutArangesSection.getFormParams().AddrSize);
876     OutArangesSection.emitIntVal(Range.end() - Range.start(),
877                                  OutArangesSection.getFormParams().AddrSize);
878   }
879 
880   // Emit terminator.
881   OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
882   OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
883 
884   uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell();
885 
886   // Update Aranges lentgh.
887   OutArangesSection.apply(
888       OffsetAfterArangesLengthField -
889           OutArangesSection.getFormParams().getDwarfOffsetByteSize(),
890       dwarf::DW_FORM_sec_offset,
891       OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
892 }
893 
cloneAndEmitDebugMacro()894 Error CompileUnit::cloneAndEmitDebugMacro() {
895   if (getOutUnitDIE() == nullptr)
896     return Error::success();
897 
898   DWARFUnit &OrigUnit = getOrigUnit();
899   DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
900 
901   // Check for .debug_macro table.
902   if (std::optional<uint64_t> MacroAttr =
903           dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
904     if (const DWARFDebugMacro *Table =
905             getContaingFile().Dwarf->getDebugMacro()) {
906       emitMacroTableImpl(Table, *MacroAttr, true);
907     }
908   }
909 
910   // Check for .debug_macinfo table.
911   if (std::optional<uint64_t> MacroAttr =
912           dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
913     if (const DWARFDebugMacro *Table =
914             getContaingFile().Dwarf->getDebugMacinfo()) {
915       emitMacroTableImpl(Table, *MacroAttr, false);
916     }
917   }
918 
919   return Error::success();
920 }
921 
emitMacroTableImpl(const DWARFDebugMacro * MacroTable,uint64_t OffsetToMacroTable,bool hasDWARFv5Header)922 void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
923                                      uint64_t OffsetToMacroTable,
924                                      bool hasDWARFv5Header) {
925   SectionDescriptor &OutSection =
926       hasDWARFv5Header
927           ? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro)
928           : getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo);
929 
930   bool DefAttributeIsReported = false;
931   bool UndefAttributeIsReported = false;
932   bool ImportAttributeIsReported = false;
933 
934   for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
935     if (OffsetToMacroTable == List.Offset) {
936       // Write DWARFv5 header.
937       if (hasDWARFv5Header) {
938         // Write header version.
939         OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version));
940 
941         uint8_t Flags = List.Header.Flags;
942 
943         // Check for OPCODE_OPERANDS_TABLE.
944         if (Flags &
945             DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
946           Flags &=
947               ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
948           warn("opcode_operands_table is not supported yet.");
949         }
950 
951         // Check for DEBUG_LINE_OFFSET.
952         std::optional<uint64_t> StmtListOffset;
953         if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
954           // Get offset to the line table from the cloned compile unit.
955           for (auto &V : getOutUnitDIE()->values()) {
956             if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
957               StmtListOffset = V.getDIEInteger().getValue();
958               break;
959             }
960           }
961 
962           if (!StmtListOffset) {
963             Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
964             warn("couldn`t find line table for macro table.");
965           }
966         }
967 
968         // Write flags.
969         OutSection.emitIntVal(Flags, sizeof(Flags));
970 
971         // Write offset to line table.
972         if (StmtListOffset) {
973           OutSection.notePatch(DebugOffsetPatch{
974               OutSection.OS.tell(),
975               &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine)});
976           // TODO: check that List.Header.getOffsetByteSize() and
977           // DebugOffsetPatch agree on size.
978           OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize());
979         }
980       }
981 
982       // Write macro entries.
983       for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
984         if (MacroEntry.Type == 0) {
985           encodeULEB128(MacroEntry.Type, OutSection.OS);
986           continue;
987         }
988 
989         uint8_t MacroType = MacroEntry.Type;
990         switch (MacroType) {
991         default: {
992           bool HasVendorSpecificExtension =
993               (!hasDWARFv5Header &&
994                MacroType == dwarf::DW_MACINFO_vendor_ext) ||
995               (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
996                                     MacroType <= dwarf::DW_MACRO_hi_user));
997 
998           if (HasVendorSpecificExtension) {
999             // Write macinfo type.
1000             OutSection.emitIntVal(MacroType, 1);
1001 
1002             // Write vendor extension constant.
1003             encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);
1004 
1005             // Write vendor extension string.
1006             OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1007           } else
1008             warn("unknown macro type. skip.");
1009         } break;
1010         // debug_macro and debug_macinfo share some common encodings.
1011         // DW_MACRO_define     == DW_MACINFO_define
1012         // DW_MACRO_undef      == DW_MACINFO_undef
1013         // DW_MACRO_start_file == DW_MACINFO_start_file
1014         // DW_MACRO_end_file   == DW_MACINFO_end_file
1015         // For readibility/uniformity we are using DW_MACRO_*.
1016         case dwarf::DW_MACRO_define:
1017         case dwarf::DW_MACRO_undef: {
1018           // Write macinfo type.
1019           OutSection.emitIntVal(MacroType, 1);
1020 
1021           // Write source line.
1022           encodeULEB128(MacroEntry.Line, OutSection.OS);
1023 
1024           // Write macro string.
1025           OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1026         } break;
1027         case dwarf::DW_MACRO_define_strp:
1028         case dwarf::DW_MACRO_undef_strp:
1029         case dwarf::DW_MACRO_define_strx:
1030         case dwarf::DW_MACRO_undef_strx: {
1031           // DW_MACRO_*_strx forms are not supported currently.
1032           // Convert to *_strp.
1033           switch (MacroType) {
1034           case dwarf::DW_MACRO_define_strx: {
1035             MacroType = dwarf::DW_MACRO_define_strp;
1036             if (!DefAttributeIsReported) {
1037               warn("DW_MACRO_define_strx unsupported yet. Convert to "
1038                    "DW_MACRO_define_strp.");
1039               DefAttributeIsReported = true;
1040             }
1041           } break;
1042           case dwarf::DW_MACRO_undef_strx: {
1043             MacroType = dwarf::DW_MACRO_undef_strp;
1044             if (!UndefAttributeIsReported) {
1045               warn("DW_MACRO_undef_strx unsupported yet. Convert to "
1046                    "DW_MACRO_undef_strp.");
1047               UndefAttributeIsReported = true;
1048             }
1049           } break;
1050           default:
1051             // Nothing to do.
1052             break;
1053           }
1054 
1055           // Write macinfo type.
1056           OutSection.emitIntVal(MacroType, 1);
1057 
1058           // Write source line.
1059           encodeULEB128(MacroEntry.Line, OutSection.OS);
1060 
1061           // Write macro string.
1062           OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1063           break;
1064         }
1065         case dwarf::DW_MACRO_start_file: {
1066           // Write macinfo type.
1067           OutSection.emitIntVal(MacroType, 1);
1068           // Write source line.
1069           encodeULEB128(MacroEntry.Line, OutSection.OS);
1070           // Write source file id.
1071           encodeULEB128(MacroEntry.File, OutSection.OS);
1072         } break;
1073         case dwarf::DW_MACRO_end_file: {
1074           // Write macinfo type.
1075           OutSection.emitIntVal(MacroType, 1);
1076         } break;
1077         case dwarf::DW_MACRO_import:
1078         case dwarf::DW_MACRO_import_sup: {
1079           if (!ImportAttributeIsReported) {
1080             warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1081                  "yet. remove.");
1082             ImportAttributeIsReported = true;
1083           }
1084         } break;
1085         }
1086       }
1087 
1088       return;
1089     }
1090   }
1091 }
1092 
cloneDieAttrExpression(const DWARFExpression & InputExpression,SmallVectorImpl<uint8_t> & OutputExpression,SectionDescriptor & Section,std::optional<int64_t> VarAddressAdjustment,OffsetsPtrVector & PatchesOffsets)1093 void CompileUnit::cloneDieAttrExpression(
1094     const DWARFExpression &InputExpression,
1095     SmallVectorImpl<uint8_t> &OutputExpression, SectionDescriptor &Section,
1096     std::optional<int64_t> VarAddressAdjustment,
1097     OffsetsPtrVector &PatchesOffsets) {
1098   using Encoding = DWARFExpression::Operation::Encoding;
1099 
1100   DWARFUnit &OrigUnit = getOrigUnit();
1101   uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
1102 
1103   uint64_t OpOffset = 0;
1104   for (auto &Op : InputExpression) {
1105     auto Desc = Op.getDescription();
1106     // DW_OP_const_type is variable-length and has 3
1107     // operands. Thus far we only support 2.
1108     if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1109         (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1110          Desc.Op[0] != Encoding::Size1))
1111       warn("unsupported DW_OP encoding.");
1112 
1113     if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1114         (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1115          Desc.Op[0] == Encoding::Size1)) {
1116       // This code assumes that the other non-typeref operand fits into 1 byte.
1117       assert(OpOffset < Op.getEndOffset());
1118       uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;
1119       assert(ULEBsize <= 16);
1120 
1121       // Copy over the operation.
1122       assert(!Op.getSubCode() && "SubOps not yet supported");
1123       OutputExpression.push_back(Op.getCode());
1124       uint64_t RefOffset;
1125       if (Desc.Op.size() == 1) {
1126         RefOffset = Op.getRawOperand(0);
1127       } else {
1128         OutputExpression.push_back(Op.getRawOperand(0));
1129         RefOffset = Op.getRawOperand(1);
1130       }
1131       uint8_t ULEB[16];
1132       uint32_t Offset = 0;
1133       unsigned RealSize = 0;
1134       // Look up the base type. For DW_OP_convert, the operand may be 0 to
1135       // instead indicate the generic type. The same holds for
1136       // DW_OP_reinterpret, which is currently not supported.
1137       if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {
1138         RefOffset += OrigUnit.getOffset();
1139         uint32_t RefDieIdx = 0;
1140         if (std::optional<uint32_t> Idx =
1141                 OrigUnit.getDIEIndexForOffset(RefOffset))
1142           RefDieIdx = *Idx;
1143 
1144         // Use fixed size for ULEB128 data, since we need to update that size
1145         // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64.
1146         ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1;
1147 
1148         RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize);
1149 
1150         Section.notePatchWithOffsetUpdate(
1151             DebugULEB128DieRefPatch(OutputExpression.size(), this, this,
1152                                     RefDieIdx),
1153             PatchesOffsets);
1154       } else
1155         RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
1156 
1157       if (RealSize > ULEBsize) {
1158         // Emit the generic type as a fallback.
1159         RealSize = encodeULEB128(0, ULEB, ULEBsize);
1160         warn("base type ref doesn't fit.");
1161       }
1162       assert(RealSize == ULEBsize && "padding failed");
1163       ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
1164       OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end());
1165     } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1166                Op.getCode() == dwarf::DW_OP_addrx) {
1167       if (std::optional<object::SectionedAddress> SA =
1168               OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
1169         // DWARFLinker does not use addrx forms since it generates relocated
1170         // addresses. Replace DW_OP_addrx with DW_OP_addr here.
1171         // Argument of DW_OP_addrx should be relocated here as it is not
1172         // processed by applyValidRelocs.
1173         OutputExpression.push_back(dwarf::DW_OP_addr);
1174         uint64_t LinkedAddress =
1175             SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1176         if (getEndianness() != llvm::endianness::native)
1177           sys::swapByteOrder(LinkedAddress);
1178         ArrayRef<uint8_t> AddressBytes(
1179             reinterpret_cast<const uint8_t *>(&LinkedAddress),
1180             OrigAddressByteSize);
1181         OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1182       } else
1183         warn("cann't read DW_OP_addrx operand.");
1184     } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1185                Op.getCode() == dwarf::DW_OP_constx) {
1186       if (std::optional<object::SectionedAddress> SA =
1187               OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
1188         // DWARFLinker does not use constx forms since it generates relocated
1189         // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1190         // Argument of DW_OP_constx should be relocated here as it is not
1191         // processed by applyValidRelocs.
1192         std::optional<uint8_t> OutOperandKind;
1193         switch (OrigAddressByteSize) {
1194         case 2:
1195           OutOperandKind = dwarf::DW_OP_const2u;
1196           break;
1197         case 4:
1198           OutOperandKind = dwarf::DW_OP_const4u;
1199           break;
1200         case 8:
1201           OutOperandKind = dwarf::DW_OP_const8u;
1202           break;
1203         default:
1204           warn(
1205               formatv(("unsupported address size: {0}."), OrigAddressByteSize));
1206           break;
1207         }
1208 
1209         if (OutOperandKind) {
1210           OutputExpression.push_back(*OutOperandKind);
1211           uint64_t LinkedAddress =
1212               SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1213           if (getEndianness() != llvm::endianness::native)
1214             sys::swapByteOrder(LinkedAddress);
1215           ArrayRef<uint8_t> AddressBytes(
1216               reinterpret_cast<const uint8_t *>(&LinkedAddress),
1217               OrigAddressByteSize);
1218           OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1219         }
1220       } else
1221         warn("cann't read DW_OP_constx operand.");
1222     } else {
1223       // Copy over everything else unmodified.
1224       StringRef Bytes =
1225           InputExpression.getData().slice(OpOffset, Op.getEndOffset());
1226       OutputExpression.append(Bytes.begin(), Bytes.end());
1227     }
1228     OpOffset = Op.getEndOffset();
1229   }
1230 }
1231 
cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,TypeUnit * ArtificialTypeUnit)1232 Error CompileUnit::cloneAndEmit(
1233     std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1234     TypeUnit *ArtificialTypeUnit) {
1235   BumpPtrAllocator Allocator;
1236 
1237   DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
1238   if (!OrigUnitDIE.isValid())
1239     return Error::success();
1240 
1241   TypeEntry *RootEntry = nullptr;
1242   if (ArtificialTypeUnit)
1243     RootEntry = ArtificialTypeUnit->getTypePool().getRoot();
1244 
1245   // Clone input DIE entry recursively.
1246   std::pair<DIE *, TypeEntry *> OutCUDie = cloneDIE(
1247       OrigUnitDIE.getDebugInfoEntry(), RootEntry, getDebugInfoHeaderSize(),
1248       std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit);
1249   setOutUnitDIE(OutCUDie.first);
1250 
1251   if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))
1252     return Error::success();
1253 
1254   if (Error Err = cloneAndEmitLineTable((*TargetTriple).get()))
1255     return Err;
1256 
1257   if (Error Err = cloneAndEmitDebugMacro())
1258     return Err;
1259 
1260   getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
1261   if (Error Err = emitDebugInfo((*TargetTriple).get()))
1262     return Err;
1263 
1264   // ASSUMPTION: .debug_info section should already be emitted at this point.
1265   // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1266   // data.
1267 
1268   if (Error Err = cloneAndEmitRanges())
1269     return Err;
1270 
1271   if (Error Err = cloneAndEmitDebugLocations())
1272     return Err;
1273 
1274   if (Error Err = emitDebugAddrSection())
1275     return Err;
1276 
1277   // Generate Pub accelerator tables.
1278   if (llvm::is_contained(GlobalData.getOptions().AccelTables,
1279                          DWARFLinker::AccelTableKind::Pub))
1280     emitPubAccelerators();
1281 
1282   if (Error Err = emitDebugStringOffsetSection())
1283     return Err;
1284 
1285   return emitAbbreviations();
1286 }
1287 
cloneDIE(const DWARFDebugInfoEntry * InputDieEntry,TypeEntry * ClonedParentTypeDIE,uint64_t OutOffset,std::optional<int64_t> FuncAddressAdjustment,std::optional<int64_t> VarAddressAdjustment,BumpPtrAllocator & Allocator,TypeUnit * ArtificialTypeUnit)1288 std::pair<DIE *, TypeEntry *> CompileUnit::cloneDIE(
1289     const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE,
1290     uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1291     std::optional<int64_t> VarAddressAdjustment, BumpPtrAllocator &Allocator,
1292     TypeUnit *ArtificialTypeUnit) {
1293   uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
1294   CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);
1295 
1296   bool NeedToClonePlainDIE = Info.needToKeepInPlainDwarf();
1297   bool NeedToCloneTypeDIE =
1298       (InputDieEntry->getTag() != dwarf::DW_TAG_compile_unit) &&
1299       Info.needToPlaceInTypeTable();
1300   std::pair<DIE *, TypeEntry *> ClonedDIE;
1301 
1302   DIEGenerator PlainDIEGenerator(Allocator, *this);
1303 
1304   if (NeedToClonePlainDIE)
1305     // Create a cloned DIE which would be placed into the cloned version
1306     // of input compile unit.
1307     ClonedDIE.first = createPlainDIEandCloneAttributes(
1308         InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1309         VarAddressAdjustment);
1310   if (NeedToCloneTypeDIE) {
1311     // Create a cloned DIE which would be placed into the artificial type
1312     // unit.
1313     assert(ArtificialTypeUnit != nullptr);
1314     DIEGenerator TypeDIEGenerator(
1315         ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this);
1316 
1317     ClonedDIE.second = createTypeDIEandCloneAttributes(
1318         InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1319         ArtificialTypeUnit);
1320   }
1321   TypeEntry *TypeParentForChild =
1322       ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;
1323 
1324   bool HasPlainChildrenToClone =
1325       (ClonedDIE.first && Info.getKeepPlainChildren());
1326 
1327   bool HasTypeChildrenToClone =
1328       ((ClonedDIE.second ||
1329         InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) &&
1330        Info.getKeepTypeChildren());
1331 
1332   // Recursively clone children.
1333   if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1334     for (const DWARFDebugInfoEntry *CurChild =
1335              getFirstChildEntry(InputDieEntry);
1336          CurChild && CurChild->getAbbreviationDeclarationPtr();
1337          CurChild = getSiblingEntry(CurChild)) {
1338       std::pair<DIE *, TypeEntry *> ClonedChild = cloneDIE(
1339           CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
1340           VarAddressAdjustment, Allocator, ArtificialTypeUnit);
1341 
1342       if (ClonedChild.first) {
1343         OutOffset =
1344             ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1345         PlainDIEGenerator.addChild(ClonedChild.first);
1346       }
1347     }
1348     assert(ClonedDIE.first == nullptr ||
1349            HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1350 
1351     // Account for the end of children marker.
1352     if (HasPlainChildrenToClone)
1353       OutOffset += sizeof(int8_t);
1354   }
1355 
1356   // Update our size.
1357   if (ClonedDIE.first != nullptr)
1358     ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1359 
1360   return ClonedDIE;
1361 }
1362 
createPlainDIEandCloneAttributes(const DWARFDebugInfoEntry * InputDieEntry,DIEGenerator & PlainDIEGenerator,uint64_t & OutOffset,std::optional<int64_t> & FuncAddressAdjustment,std::optional<int64_t> & VarAddressAdjustment)1363 DIE *CompileUnit::createPlainDIEandCloneAttributes(
1364     const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,
1365     uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1366     std::optional<int64_t> &VarAddressAdjustment) {
1367   uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
1368   CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);
1369   DIE *ClonedDIE = nullptr;
1370   bool HasLocationExpressionAddress = false;
1371   if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) {
1372     // Get relocation adjustment value for the current function.
1373     FuncAddressAdjustment =
1374         getContaingFile().Addresses->getSubprogramRelocAdjustment(
1375             getDIE(InputDieEntry), false);
1376   } else if (InputDieEntry->getTag() == dwarf::DW_TAG_label) {
1377     // Get relocation adjustment value for the current label.
1378     std::optional<uint64_t> lowPC =
1379         dwarf::toAddress(find(InputDieEntry, dwarf::DW_AT_low_pc));
1380     if (lowPC) {
1381       LabelMapTy::iterator It = Labels.find(*lowPC);
1382       if (It != Labels.end())
1383         FuncAddressAdjustment = It->second;
1384     }
1385   } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) {
1386     // Get relocation adjustment value for the current variable.
1387     std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1388         getContaingFile().Addresses->getVariableRelocAdjustment(
1389             getDIE(InputDieEntry), false);
1390 
1391     HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1392     if (LocExprAddrAndRelocAdjustment.first &&
1393         LocExprAddrAndRelocAdjustment.second)
1394       VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1395   }
1396 
1397   ClonedDIE = PlainDIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset);
1398 
1399   // Offset to the DIE would be used after output DIE tree is deleted.
1400   // Thus we need to remember DIE offset separately.
1401   rememberDieOutOffset(InputDieIdx, OutOffset);
1402 
1403   // Clone Attributes.
1404   DIEAttributeCloner AttributesCloner(ClonedDIE, *this, this, InputDieEntry,
1405                                       PlainDIEGenerator, FuncAddressAdjustment,
1406                                       VarAddressAdjustment,
1407                                       HasLocationExpressionAddress);
1408   AttributesCloner.clone();
1409 
1410   // Remember accelerator info.
1411   AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, this);
1412   AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1413                          nullptr);
1414 
1415   OutOffset =
1416       AttributesCloner.finalizeAbbreviations(Info.getKeepPlainChildren());
1417 
1418   return ClonedDIE;
1419 }
1420 
1421 /// Allocates output DIE for the specified \p TypeDescriptor.
allocateTypeDie(TypeEntryBody * TypeDescriptor,DIEGenerator & TypeDIEGenerator,dwarf::Tag DieTag,bool IsDeclaration,bool IsParentDeclaration)1422 DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
1423                                   DIEGenerator &TypeDIEGenerator,
1424                                   dwarf::Tag DieTag, bool IsDeclaration,
1425                                   bool IsParentDeclaration) {
1426   DIE *DefinitionDie = TypeDescriptor->Die;
1427   // Do not allocate any new DIE if definition DIE is already met.
1428   if (DefinitionDie)
1429     return nullptr;
1430 
1431   DIE *DeclarationDie = TypeDescriptor->DeclarationDie;
1432   bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration;
1433 
1434   if (IsDeclaration && !DeclarationDie) {
1435     // Alocate declaration DIE.
1436     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1437     if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
1438                                                              NewDie))
1439       return NewDie;
1440   } else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
1441     // Overwrite existing declaration DIE if it's parent is also an declaration
1442     // while parent of current declaration DIE is a definition.
1443     if (TypeDescriptor->ParentIsDeclaration.compare_exchange_weak(
1444             OldParentIsDeclaration, false)) {
1445       DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1446       TypeDescriptor->DeclarationDie = NewDie;
1447       return NewDie;
1448     }
1449   } else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
1450     // Alocate declaration DIE since parent of current DIE is marked as
1451     // declaration.
1452     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1453     if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
1454                                                              NewDie))
1455       return NewDie;
1456   } else if (!IsDeclaration && !IsParentDeclaration) {
1457     // Allocate definition DIE.
1458     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1459     if (TypeDescriptor->Die.compare_exchange_weak(DefinitionDie, NewDie)) {
1460       TypeDescriptor->ParentIsDeclaration = false;
1461       return NewDie;
1462     }
1463   }
1464 
1465   return nullptr;
1466 }
1467 
createTypeDIEandCloneAttributes(const DWARFDebugInfoEntry * InputDieEntry,DIEGenerator & TypeDIEGenerator,TypeEntry * ClonedParentTypeDIE,TypeUnit * ArtificialTypeUnit)1468 TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1469     const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,
1470     TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit) {
1471   assert(ArtificialTypeUnit != nullptr);
1472   uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
1473 
1474   TypeEntry *Entry = getDieTypeEntry(InputDieIdx);
1475   assert(Entry != nullptr);
1476   assert(ClonedParentTypeDIE != nullptr);
1477   TypeEntryBody *EntryBody =
1478       ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody(
1479           Entry, ClonedParentTypeDIE);
1480   assert(EntryBody);
1481 
1482   bool IsDeclaration =
1483       dwarf::toUnsigned(find(InputDieEntry, dwarf::DW_AT_declaration), 0);
1484 
1485   bool ParentIsDeclaration = false;
1486   if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx())
1487     ParentIsDeclaration =
1488         dwarf::toUnsigned(find(*ParentIdx, dwarf::DW_AT_declaration), 0);
1489 
1490   DIE *OutDIE =
1491       allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->getTag(),
1492                       IsDeclaration, ParentIsDeclaration);
1493 
1494   if (OutDIE != nullptr) {
1495     assert(ArtificialTypeUnit != nullptr);
1496     ArtificialTypeUnit->getSectionDescriptor(DebugSectionKind::DebugInfo);
1497 
1498     DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit,
1499                                         InputDieEntry, TypeDIEGenerator,
1500                                         std::nullopt, std::nullopt, false);
1501     AttributesCloner.clone();
1502 
1503     // Remember accelerator info.
1504     AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,
1505                                               ArtificialTypeUnit);
1506     AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1507                            Entry);
1508 
1509     // if AttributesCloner.getOutOffset() == 0 then we need to add
1510     // 1 to avoid assertion for zero size. We will subtract it back later.
1511     OutDIE->setSize(AttributesCloner.getOutOffset() + 1);
1512   }
1513 
1514   return Entry;
1515 }
1516 
cloneAndEmitLineTable(const Triple & TargetTriple)1517 Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) {
1518   const DWARFDebugLine::LineTable *InputLineTable =
1519       getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());
1520   if (InputLineTable == nullptr) {
1521     if (getOrigUnit().getUnitDIE().find(dwarf::DW_AT_stmt_list))
1522       warn("cann't load line table.");
1523     return Error::success();
1524   }
1525 
1526   DWARFDebugLine::LineTable OutLineTable;
1527 
1528   // Set Line Table header.
1529   OutLineTable.Prologue = InputLineTable->Prologue;
1530   OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize;
1531 
1532   // Set Line Table Rows.
1533   if (getGlobalData().getOptions().UpdateIndexTablesOnly) {
1534     OutLineTable.Rows = InputLineTable->Rows;
1535     // If all the line table contains is a DW_LNE_end_sequence, clear the line
1536     // table rows, it will be inserted again in the DWARFStreamer.
1537     if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence)
1538       OutLineTable.Rows.clear();
1539 
1540     OutLineTable.Sequences = InputLineTable->Sequences;
1541   } else {
1542     // This vector is the output line table.
1543     std::vector<DWARFDebugLine::Row> NewRows;
1544     NewRows.reserve(InputLineTable->Rows.size());
1545 
1546     // Current sequence of rows being extracted, before being inserted
1547     // in NewRows.
1548     std::vector<DWARFDebugLine::Row> Seq;
1549 
1550     const auto &FunctionRanges = getFunctionRanges();
1551     std::optional<AddressRangeValuePair> CurrRange;
1552 
1553     // FIXME: This logic is meant to generate exactly the same output as
1554     // Darwin's classic dsymutil. There is a nicer way to implement this
1555     // by simply putting all the relocated line info in NewRows and simply
1556     // sorting NewRows before passing it to emitLineTableForUnit. This
1557     // should be correct as sequences for a function should stay
1558     // together in the sorted output. There are a few corner cases that
1559     // look suspicious though, and that required to implement the logic
1560     // this way. Revisit that once initial validation is finished.
1561 
1562     // Iterate over the object file line info and extract the sequences
1563     // that correspond to linked functions.
1564     for (DWARFDebugLine::Row Row : InputLineTable->Rows) {
1565       // Check whether we stepped out of the range. The range is
1566       // half-open, but consider accept the end address of the range if
1567       // it is marked as end_sequence in the input (because in that
1568       // case, the relocation offset is accurate and that entry won't
1569       // serve as the start of another function).
1570       if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1571         // We just stepped out of a known range. Insert a end_sequence
1572         // corresponding to the end of the range.
1573         uint64_t StopAddress =
1574             CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1575         CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1576         if (StopAddress != -1ULL && !Seq.empty()) {
1577           // Insert end sequence row with the computed end address, but
1578           // the same line as the previous one.
1579           auto NextLine = Seq.back();
1580           NextLine.Address.Address = StopAddress;
1581           NextLine.EndSequence = 1;
1582           NextLine.PrologueEnd = 0;
1583           NextLine.BasicBlock = 0;
1584           NextLine.EpilogueBegin = 0;
1585           Seq.push_back(NextLine);
1586           insertLineSequence(Seq, NewRows);
1587         }
1588 
1589         if (!CurrRange)
1590           continue;
1591       }
1592 
1593       // Ignore empty sequences.
1594       if (Row.EndSequence && Seq.empty())
1595         continue;
1596 
1597       // Relocate row address and add it to the current sequence.
1598       Row.Address.Address += CurrRange->Value;
1599       Seq.emplace_back(Row);
1600 
1601       if (Row.EndSequence)
1602         insertLineSequence(Seq, NewRows);
1603     }
1604 
1605     OutLineTable.Rows = std::move(NewRows);
1606   }
1607 
1608   return emitDebugLine(TargetTriple, OutLineTable);
1609 }
1610 
insertLineSequence(std::vector<DWARFDebugLine::Row> & Seq,std::vector<DWARFDebugLine::Row> & Rows)1611 void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1612                                      std::vector<DWARFDebugLine::Row> &Rows) {
1613   if (Seq.empty())
1614     return;
1615 
1616   if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1617     llvm::append_range(Rows, Seq);
1618     Seq.clear();
1619     return;
1620   }
1621 
1622   object::SectionedAddress Front = Seq.front().Address;
1623   auto InsertPoint = partition_point(
1624       Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });
1625 
1626   // FIXME: this only removes the unneeded end_sequence if the
1627   // sequences have been inserted in order. Using a global sort like
1628   // described in cloneAndEmitLineTable() and delaying the end_sequene
1629   // elimination to DebugLineEmitter::emit() we can get rid of all of them.
1630   if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1631       InsertPoint->EndSequence) {
1632     *InsertPoint = Seq.front();
1633     Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
1634   } else {
1635     Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1636   }
1637 
1638   Seq.clear();
1639 }
1640 
1641 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump()1642 LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() {
1643   llvm::errs() << "{";
1644   llvm::errs() << "  Placement: ";
1645   switch (getPlacement()) {
1646   case NotSet:
1647     llvm::errs() << "NotSet";
1648     break;
1649   case TypeTable:
1650     llvm::errs() << "TypeTable";
1651     break;
1652   case PlainDwarf:
1653     llvm::errs() << "PlainDwarf";
1654     break;
1655   case Both:
1656     llvm::errs() << "Both";
1657     break;
1658   }
1659 
1660   llvm::errs() << "  Keep: " << getKeep();
1661   llvm::errs() << "  KeepPlainChildren: " << getKeepPlainChildren();
1662   llvm::errs() << "  KeepTypeChildren: " << getKeepTypeChildren();
1663   llvm::errs() << "  IsInMouduleScope: " << getIsInMouduleScope();
1664   llvm::errs() << "  IsInFunctionScope: " << getIsInFunctionScope();
1665   llvm::errs() << "  IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1666   llvm::errs() << "  ODRAvailable: " << getODRAvailable();
1667   llvm::errs() << "  TrackLiveness: " << getTrackLiveness();
1668   llvm::errs() << "}\n";
1669 }
1670 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1671 
1672 std::optional<std::pair<StringRef, StringRef>>
getDirAndFilenameFromLineTable(const DWARFFormValue & FileIdxValue)1673 CompileUnit::getDirAndFilenameFromLineTable(
1674     const DWARFFormValue &FileIdxValue) {
1675   uint64_t FileIdx;
1676   if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant())
1677     FileIdx = *Val;
1678   else if (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant())
1679     FileIdx = *Val;
1680   else if (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset())
1681     FileIdx = *Val;
1682   else
1683     return std::nullopt;
1684 
1685   return getDirAndFilenameFromLineTable(FileIdx);
1686 }
1687 
1688 std::optional<std::pair<StringRef, StringRef>>
getDirAndFilenameFromLineTable(uint64_t FileIdx)1689 CompileUnit::getDirAndFilenameFromLineTable(uint64_t FileIdx) {
1690   FileNamesCache::iterator FileData = FileNames.find(FileIdx);
1691   if (FileData != FileNames.end())
1692     return std::make_pair(StringRef(FileData->second.first),
1693                           StringRef(FileData->second.second));
1694 
1695   if (const DWARFDebugLine::LineTable *LineTable =
1696           getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) {
1697     if (LineTable->hasFileAtIndex(FileIdx)) {
1698 
1699       const llvm::DWARFDebugLine::FileNameEntry &Entry =
1700           LineTable->Prologue.getFileNameEntry(FileIdx);
1701 
1702       Expected<const char *> Name = Entry.Name.getAsCString();
1703       if (!Name) {
1704         warn(Name.takeError());
1705         return std::nullopt;
1706       }
1707 
1708       std::string FileName = *Name;
1709       if (isPathAbsoluteOnWindowsOrPosix(FileName)) {
1710         FileNamesCache::iterator FileData =
1711             FileNames
1712                 .insert(std::make_pair(
1713                     FileIdx,
1714                     std::make_pair(std::string(""), std::move(FileName))))
1715                 .first;
1716         return std::make_pair(StringRef(FileData->second.first),
1717                               StringRef(FileData->second.second));
1718       }
1719 
1720       SmallString<256> FilePath;
1721       StringRef IncludeDir;
1722       // Be defensive about the contents of Entry.
1723       if (getVersion() >= 5) {
1724         // DirIdx 0 is the compilation directory, so don't include it for
1725         // relative names.
1726         if ((Entry.DirIdx != 0) &&
1727             Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1728           Expected<const char *> DirName =
1729               LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1730                   .getAsCString();
1731           if (DirName)
1732             IncludeDir = *DirName;
1733           else {
1734             warn(DirName.takeError());
1735             return std::nullopt;
1736           }
1737         }
1738       } else {
1739         if (0 < Entry.DirIdx &&
1740             Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1741           Expected<const char *> DirName =
1742               LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1743                   .getAsCString();
1744           if (DirName)
1745             IncludeDir = *DirName;
1746           else {
1747             warn(DirName.takeError());
1748             return std::nullopt;
1749           }
1750         }
1751       }
1752 
1753       StringRef CompDir = getOrigUnit().getCompilationDir();
1754 
1755       if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) {
1756         sys::path::append(FilePath, sys::path::Style::native, CompDir);
1757       }
1758 
1759       sys::path::append(FilePath, sys::path::Style::native, IncludeDir);
1760 
1761       FileNamesCache::iterator FileData =
1762           FileNames
1763               .insert(
1764                   std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
1765                                                          std::move(FileName))))
1766               .first;
1767       return std::make_pair(StringRef(FileData->second.first),
1768                             StringRef(FileData->second.second));
1769     }
1770   }
1771 
1772   return std::nullopt;
1773 }
1774 
1775 #define MAX_REFERENCIES_DEPTH 1000
getNamespaceOrigin()1776 UnitEntryPairTy UnitEntryPairTy::getNamespaceOrigin() {
1777   UnitEntryPairTy CUDiePair(*this);
1778   std::optional<UnitEntryPairTy> RefDiePair;
1779   int refDepth = 0;
1780   do {
1781     RefDiePair = CUDiePair.CU->resolveDIEReference(
1782         CUDiePair.DieEntry, dwarf::DW_AT_extension,
1783         ResolveInterCUReferencesMode::Resolve);
1784     if (!RefDiePair || !RefDiePair->DieEntry)
1785       return CUDiePair;
1786 
1787     CUDiePair = *RefDiePair;
1788   } while (refDepth++ < MAX_REFERENCIES_DEPTH);
1789 
1790   return CUDiePair;
1791 }
1792 
getParent()1793 std::optional<UnitEntryPairTy> UnitEntryPairTy::getParent() {
1794   if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx())
1795     return UnitEntryPairTy{CU, CU->getDebugInfoEntry(*ParentIdx)};
1796 
1797   return std::nullopt;
1798 }
1799 
OutputUnitVariantPtr(CompileUnit * U)1800 CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit *U)
1801     : Ptr(U) {
1802   assert(U != nullptr);
1803 }
1804 
OutputUnitVariantPtr(TypeUnit * U)1805 CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit *U) : Ptr(U) {
1806   assert(U != nullptr);
1807 }
1808 
operator ->()1809 DwarfUnit *CompileUnit::OutputUnitVariantPtr::operator->() {
1810   if (isCompileUnit())
1811     return getAsCompileUnit();
1812   else
1813     return getAsTypeUnit();
1814 }
1815 
isCompileUnit()1816 bool CompileUnit::OutputUnitVariantPtr::isCompileUnit() {
1817   return Ptr.is<CompileUnit *>();
1818 }
1819 
isTypeUnit()1820 bool CompileUnit::OutputUnitVariantPtr::isTypeUnit() {
1821   return Ptr.is<TypeUnit *>();
1822 }
1823 
getAsCompileUnit()1824 CompileUnit *CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() {
1825   return Ptr.get<CompileUnit *>();
1826 }
1827 
getAsTypeUnit()1828 TypeUnit *CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() {
1829   return Ptr.get<TypeUnit *>();
1830 }
1831 
resolveDependenciesAndMarkLiveness(bool InterCUProcessingStarted,std::atomic<bool> & HasNewInterconnectedCUs)1832 bool CompileUnit::resolveDependenciesAndMarkLiveness(
1833     bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1834   if (!Dependencies)
1835     Dependencies.reset(new DependencyTracker(*this));
1836 
1837   return Dependencies->resolveDependenciesAndMarkLiveness(
1838       InterCUProcessingStarted, HasNewInterconnectedCUs);
1839 }
1840 
updateDependenciesCompleteness()1841 bool CompileUnit::updateDependenciesCompleteness() {
1842   assert(Dependencies.get());
1843 
1844   return Dependencies->updateDependenciesCompleteness();
1845 }
1846 
verifyDependencies()1847 void CompileUnit::verifyDependencies() {
1848   assert(Dependencies.get());
1849 
1850   Dependencies->verifyKeepChain();
1851 }
1852 
getODRAttributes()1853 ArrayRef<dwarf::Attribute> dwarf_linker::parallel::getODRAttributes() {
1854   static dwarf::Attribute ODRAttributes[] = {
1855       dwarf::DW_AT_type, dwarf::DW_AT_specification,
1856       dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};
1857 
1858   return ODRAttributes;
1859 }
1860