xref: /llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp (revision 2f8238f849c4836b333082f387d91408234ea73b)
12357e899Savl-llvm //=== DWARFLinkerCompileUnit.cpp ------------------------------------------===//
22357e899Savl-llvm //
32357e899Savl-llvm // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42357e899Savl-llvm // See https://llvm.org/LICENSE.txt for license information.
52357e899Savl-llvm // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62357e899Savl-llvm //
72357e899Savl-llvm //===----------------------------------------------------------------------===//
82357e899Savl-llvm 
92357e899Savl-llvm #include "DWARFLinkerCompileUnit.h"
102357e899Savl-llvm #include "AcceleratorRecordsSaver.h"
112357e899Savl-llvm #include "DIEAttributeCloner.h"
122357e899Savl-llvm #include "DIEGenerator.h"
132357e899Savl-llvm #include "DependencyTracker.h"
142357e899Savl-llvm #include "SyntheticTypeNameBuilder.h"
15a02c0d94Savl-llvm #include "llvm/DWARFLinker/Utils.h"
162357e899Savl-llvm #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
172357e899Savl-llvm #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
182357e899Savl-llvm #include "llvm/Support/DJB.h"
192357e899Savl-llvm #include "llvm/Support/FileSystem.h"
202357e899Savl-llvm #include "llvm/Support/FormatVariadic.h"
212357e899Savl-llvm #include "llvm/Support/Path.h"
222357e899Savl-llvm #include <utility>
232357e899Savl-llvm 
242357e899Savl-llvm using namespace llvm;
252357e899Savl-llvm using namespace dwarf_linker;
262357e899Savl-llvm using namespace dwarf_linker::parallel;
272357e899Savl-llvm 
282357e899Savl-llvm CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,
292357e899Savl-llvm                          StringRef ClangModuleName, DWARFFile &File,
302357e899Savl-llvm                          OffsetToUnitTy UnitFromOffset,
312357e899Savl-llvm                          dwarf::FormParams Format, llvm::endianness Endianess)
322357e899Savl-llvm     : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),
332357e899Savl-llvm       getUnitFromOffset(UnitFromOffset), Stage(Stage::CreatedNotLoaded),
342357e899Savl-llvm       AcceleratorRecords(&GlobalData.getAllocator()) {
352357e899Savl-llvm   UnitName = File.FileName;
362357e899Savl-llvm   setOutputFormat(Format, Endianess);
372357e899Savl-llvm   getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
382357e899Savl-llvm }
392357e899Savl-llvm 
402357e899Savl-llvm CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit,
412357e899Savl-llvm                          unsigned ID, StringRef ClangModuleName,
422357e899Savl-llvm                          DWARFFile &File, OffsetToUnitTy UnitFromOffset,
432357e899Savl-llvm                          dwarf::FormParams Format, llvm::endianness Endianess)
442357e899Savl-llvm     : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),
452357e899Savl-llvm       OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
462357e899Savl-llvm       Stage(Stage::CreatedNotLoaded),
472357e899Savl-llvm       AcceleratorRecords(&GlobalData.getAllocator()) {
482357e899Savl-llvm   setOutputFormat(Format, Endianess);
492357e899Savl-llvm   getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
502357e899Savl-llvm 
512357e899Savl-llvm   DWARFDie CUDie = OrigUnit.getUnitDIE();
522357e899Savl-llvm   if (!CUDie)
532357e899Savl-llvm     return;
542357e899Savl-llvm 
552357e899Savl-llvm   if (std::optional<DWARFFormValue> Val = CUDie.find(dwarf::DW_AT_language)) {
562357e899Savl-llvm     uint16_t LangVal = dwarf::toUnsigned(Val, 0);
572357e899Savl-llvm     if (isODRLanguage(LangVal))
582357e899Savl-llvm       Language = LangVal;
592357e899Savl-llvm   }
602357e899Savl-llvm 
612357e899Savl-llvm   if (!GlobalData.getOptions().NoODR && Language.has_value())
622357e899Savl-llvm     NoODR = false;
632357e899Savl-llvm 
642357e899Savl-llvm   if (const char *CUName = CUDie.getName(DINameKind::ShortName))
652357e899Savl-llvm     UnitName = CUName;
662357e899Savl-llvm   else
672357e899Savl-llvm     UnitName = File.FileName;
682357e899Savl-llvm   SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str();
692357e899Savl-llvm }
702357e899Savl-llvm 
712357e899Savl-llvm void CompileUnit::loadLineTable() {
722357e899Savl-llvm   LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit());
732357e899Savl-llvm }
742357e899Savl-llvm 
752357e899Savl-llvm void CompileUnit::maybeResetToLoadedStage() {
762357e899Savl-llvm   // Nothing to reset if stage is less than "Loaded".
772357e899Savl-llvm   if (getStage() < Stage::Loaded)
782357e899Savl-llvm     return;
792357e899Savl-llvm 
802357e899Savl-llvm   // Note: We need to do erasing for "Loaded" stage because
812357e899Savl-llvm   // if live analysys failed then we will have "Loaded" stage
822357e899Savl-llvm   // with marking from "LivenessAnalysisDone" stage partially
832357e899Savl-llvm   // done. That marking should be cleared.
842357e899Savl-llvm 
852357e899Savl-llvm   for (DIEInfo &Info : DieInfoArray)
862357e899Savl-llvm     Info.unsetFlagsWhichSetDuringLiveAnalysis();
872357e899Savl-llvm 
882357e899Savl-llvm   LowPc = std::nullopt;
892357e899Savl-llvm   HighPc = 0;
902357e899Savl-llvm   Labels.clear();
912357e899Savl-llvm   Ranges.clear();
922357e899Savl-llvm   Dependencies.reset(nullptr);
932357e899Savl-llvm 
942357e899Savl-llvm   if (getStage() < Stage::Cloned) {
952357e899Savl-llvm     setStage(Stage::Loaded);
962357e899Savl-llvm     return;
972357e899Savl-llvm   }
982357e899Savl-llvm 
992357e899Savl-llvm   AcceleratorRecords.erase();
1002357e899Savl-llvm   AbbreviationsSet.clear();
1012357e899Savl-llvm   Abbreviations.clear();
1022357e899Savl-llvm   OutUnitDIE = nullptr;
1032357e899Savl-llvm   DebugAddrIndexMap.clear();
1042357e899Savl-llvm 
1052357e899Savl-llvm   for (uint64_t &Offset : OutDieOffsetArray)
1062357e899Savl-llvm     Offset = 0;
1072357e899Savl-llvm   for (TypeEntry *&Name : TypeEntries)
1082357e899Savl-llvm     Name = nullptr;
1092357e899Savl-llvm   eraseSections();
1102357e899Savl-llvm 
1112357e899Savl-llvm   setStage(Stage::CreatedNotLoaded);
1122357e899Savl-llvm }
1132357e899Savl-llvm 
1142357e899Savl-llvm bool CompileUnit::loadInputDIEs() {
1152357e899Savl-llvm   DWARFDie InputUnitDIE = getUnitDIE(false);
1162357e899Savl-llvm   if (!InputUnitDIE)
1172357e899Savl-llvm     return false;
1182357e899Savl-llvm 
1192357e899Savl-llvm   // load input dies, resize Info structures array.
1202357e899Savl-llvm   DieInfoArray.resize(getOrigUnit().getNumDIEs());
1212357e899Savl-llvm   OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);
1222357e899Savl-llvm   if (!NoODR)
1232357e899Savl-llvm     TypeEntries.resize(getOrigUnit().getNumDIEs());
1242357e899Savl-llvm   return true;
1252357e899Savl-llvm }
1262357e899Savl-llvm 
1272357e899Savl-llvm void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
1282357e899Savl-llvm                                            bool IsODRUnavailableFunctionScope) {
1292357e899Savl-llvm   CompileUnit::DIEInfo &DieInfo = getDIEInfo(DieEntry);
1302357e899Savl-llvm 
1312357e899Savl-llvm   for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);
1322357e899Savl-llvm        CurChild && CurChild->getAbbreviationDeclarationPtr();
1332357e899Savl-llvm        CurChild = getSiblingEntry(CurChild)) {
1342357e899Savl-llvm     CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);
1352357e899Savl-llvm     bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
1362357e899Savl-llvm 
1372357e899Savl-llvm     if (DieInfo.getIsInMouduleScope())
1382357e899Savl-llvm       ChildInfo.setIsInMouduleScope();
1392357e899Savl-llvm 
1402357e899Savl-llvm     if (DieInfo.getIsInFunctionScope())
1412357e899Savl-llvm       ChildInfo.setIsInFunctionScope();
1422357e899Savl-llvm 
1432357e899Savl-llvm     if (DieInfo.getIsInAnonNamespaceScope())
1442357e899Savl-llvm       ChildInfo.setIsInAnonNamespaceScope();
1452357e899Savl-llvm 
1462357e899Savl-llvm     switch (CurChild->getTag()) {
1472357e899Savl-llvm     case dwarf::DW_TAG_module:
1482357e899Savl-llvm       ChildInfo.setIsInMouduleScope();
1492357e899Savl-llvm       if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
1502357e899Savl-llvm           dwarf::toString(find(CurChild, dwarf::DW_AT_name), "") !=
1512357e899Savl-llvm               getClangModuleName())
1522357e899Savl-llvm         analyzeImportedModule(CurChild);
1532357e899Savl-llvm       break;
1542357e899Savl-llvm     case dwarf::DW_TAG_subprogram:
1552357e899Savl-llvm       ChildInfo.setIsInFunctionScope();
1562357e899Savl-llvm       if (!ChildIsODRUnavailableFunctionScope &&
1572357e899Savl-llvm           !ChildInfo.getIsInMouduleScope()) {
1582357e899Savl-llvm         if (find(CurChild,
1592357e899Savl-llvm                  {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
1602357e899Savl-llvm           ChildIsODRUnavailableFunctionScope = true;
1612357e899Savl-llvm       }
1622357e899Savl-llvm       break;
1632357e899Savl-llvm     case dwarf::DW_TAG_namespace: {
1642357e899Savl-llvm       UnitEntryPairTy NamespaceEntry = {this, CurChild};
1652357e899Savl-llvm 
1662357e899Savl-llvm       if (find(CurChild, dwarf::DW_AT_extension))
1672357e899Savl-llvm         NamespaceEntry = NamespaceEntry.getNamespaceOrigin();
1682357e899Savl-llvm 
1692357e899Savl-llvm       if (!NamespaceEntry.CU->find(NamespaceEntry.DieEntry, dwarf::DW_AT_name))
1702357e899Savl-llvm         ChildInfo.setIsInAnonNamespaceScope();
1712357e899Savl-llvm     } break;
1722357e899Savl-llvm     default:
1732357e899Savl-llvm       break;
1742357e899Savl-llvm     }
1752357e899Savl-llvm 
1762357e899Savl-llvm     if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)
1772357e899Savl-llvm       ChildInfo.setTrackLiveness();
1782357e899Savl-llvm 
1792357e899Savl-llvm     if ((!ChildInfo.getIsInAnonNamespaceScope() &&
1802357e899Savl-llvm          !ChildIsODRUnavailableFunctionScope && !NoODR))
1812357e899Savl-llvm       ChildInfo.setODRAvailable();
1822357e899Savl-llvm 
1832357e899Savl-llvm     if (CurChild->hasChildren())
1842357e899Savl-llvm       analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
1852357e899Savl-llvm   }
1862357e899Savl-llvm }
1872357e899Savl-llvm 
1882357e899Savl-llvm StringEntry *CompileUnit::getFileName(unsigned FileIdx,
1892357e899Savl-llvm                                       StringPool &GlobalStrings) {
1902357e899Savl-llvm   if (LineTablePtr) {
1912357e899Savl-llvm     if (LineTablePtr->hasFileAtIndex(FileIdx)) {
1922357e899Savl-llvm       // Cache the resolved paths based on the index in the line table,
1932357e899Savl-llvm       // because calling realpath is expensive.
1942357e899Savl-llvm       ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx);
1952357e899Savl-llvm       if (It == ResolvedFullPaths.end()) {
1962357e899Savl-llvm         std::string OrigFileName;
1972357e899Savl-llvm         bool FoundFileName = LineTablePtr->getFileNameByIndex(
1982357e899Savl-llvm             FileIdx, getOrigUnit().getCompilationDir(),
1992357e899Savl-llvm             DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
2002357e899Savl-llvm             OrigFileName);
2012357e899Savl-llvm         (void)FoundFileName;
2022357e899Savl-llvm         assert(FoundFileName && "Must get file name from line table");
2032357e899Savl-llvm 
2042357e899Savl-llvm         // Second level of caching, this time based on the file's parent
2052357e899Savl-llvm         // path.
2062357e899Savl-llvm         StringRef FileName = sys::path::filename(OrigFileName);
2072357e899Savl-llvm         StringRef ParentPath = sys::path::parent_path(OrigFileName);
2082357e899Savl-llvm 
2092357e899Savl-llvm         // If the ParentPath has not yet been resolved, resolve and cache it for
2102357e899Savl-llvm         // future look-ups.
2112357e899Savl-llvm         StringMap<StringEntry *>::iterator ParentIt =
2122357e899Savl-llvm             ResolvedParentPaths.find(ParentPath);
2132357e899Savl-llvm         if (ParentIt == ResolvedParentPaths.end()) {
2142357e899Savl-llvm           SmallString<256> RealPath;
2152357e899Savl-llvm           sys::fs::real_path(ParentPath, RealPath);
2162357e899Savl-llvm           ParentIt =
2172357e899Savl-llvm               ResolvedParentPaths
2182357e899Savl-llvm                   .insert({ParentPath, GlobalStrings.insert(RealPath).first})
2192357e899Savl-llvm                   .first;
2202357e899Savl-llvm         }
2212357e899Savl-llvm 
2222357e899Savl-llvm         // Join the file name again with the resolved path.
2232357e899Savl-llvm         SmallString<256> ResolvedPath(ParentIt->second->first());
2242357e899Savl-llvm         sys::path::append(ResolvedPath, FileName);
2252357e899Savl-llvm 
2262357e899Savl-llvm         It = ResolvedFullPaths
2272357e899Savl-llvm                  .insert(std::make_pair(
2282357e899Savl-llvm                      FileIdx, GlobalStrings.insert(ResolvedPath).first))
2292357e899Savl-llvm                  .first;
2302357e899Savl-llvm       }
2312357e899Savl-llvm 
2322357e899Savl-llvm       return It->second;
2332357e899Savl-llvm     }
2342357e899Savl-llvm   }
2352357e899Savl-llvm 
2362357e899Savl-llvm   return nullptr;
2372357e899Savl-llvm }
2382357e899Savl-llvm 
2392357e899Savl-llvm void CompileUnit::cleanupDataAfterClonning() {
2402357e899Savl-llvm   AbbreviationsSet.clear();
2412357e899Savl-llvm   ResolvedFullPaths.shrink_and_clear();
2422357e899Savl-llvm   ResolvedParentPaths.clear();
2432357e899Savl-llvm   FileNames.shrink_and_clear();
2442357e899Savl-llvm   DieInfoArray = SmallVector<DIEInfo>();
2452357e899Savl-llvm   OutDieOffsetArray = SmallVector<uint64_t>();
2462357e899Savl-llvm   TypeEntries = SmallVector<TypeEntry *>();
2472357e899Savl-llvm   Dependencies.reset(nullptr);
2482357e899Savl-llvm   getOrigUnit().clear();
2492357e899Savl-llvm }
2502357e899Savl-llvm 
2512357e899Savl-llvm /// Collect references to parseable Swift interfaces in imported
2522357e899Savl-llvm /// DW_TAG_module blocks.
2532357e899Savl-llvm void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {
2542357e899Savl-llvm   if (!Language || Language != dwarf::DW_LANG_Swift)
2552357e899Savl-llvm     return;
2562357e899Savl-llvm 
2572357e899Savl-llvm   if (!GlobalData.getOptions().ParseableSwiftInterfaces)
2582357e899Savl-llvm     return;
2592357e899Savl-llvm 
2602357e899Savl-llvm   StringRef Path =
2612357e899Savl-llvm       dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path));
2622357e899Savl-llvm   if (!Path.ends_with(".swiftinterface"))
2632357e899Savl-llvm     return;
2642357e899Savl-llvm   // Don't track interfaces that are part of the SDK.
2652357e899Savl-llvm   StringRef SysRoot =
2662357e899Savl-llvm       dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot));
2672357e899Savl-llvm   if (SysRoot.empty())
2682357e899Savl-llvm     SysRoot = getSysRoot();
2692357e899Savl-llvm   if (!SysRoot.empty() && Path.starts_with(SysRoot))
2702357e899Savl-llvm     return;
2712357e899Savl-llvm   // Don't track interfaces that are part of the toolchain.
2722357e899Savl-llvm   // For example: Swift, _Concurrency, ...
273f8cc183eSAdrian Prantl   StringRef DeveloperDir = guessDeveloperDir(SysRoot);
274f8cc183eSAdrian Prantl   if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))
2752357e899Savl-llvm     return;
27622ada554SAdrian Prantl   if (isInToolchainDir(Path))
27722ada554SAdrian Prantl     return;
2782357e899Savl-llvm   if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {
2792357e899Savl-llvm     Expected<const char *> Name = Val->getAsCString();
2802357e899Savl-llvm     if (!Name) {
2812357e899Savl-llvm       warn(Name.takeError());
2822357e899Savl-llvm       return;
2832357e899Savl-llvm     }
2842357e899Savl-llvm 
2852357e899Savl-llvm     auto &Entry = (*GlobalData.getOptions().ParseableSwiftInterfaces)[*Name];
2862357e899Savl-llvm     // The prepend path is applied later when copying.
2872357e899Savl-llvm     SmallString<128> ResolvedPath;
2882357e899Savl-llvm     if (sys::path::is_relative(Path))
2892357e899Savl-llvm       sys::path::append(
2902357e899Savl-llvm           ResolvedPath,
2912357e899Savl-llvm           dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir), ""));
2922357e899Savl-llvm     sys::path::append(ResolvedPath, Path);
2932357e899Savl-llvm     if (!Entry.empty() && Entry != ResolvedPath) {
2942357e899Savl-llvm       DWARFDie Die = getDIE(DieEntry);
2952357e899Savl-llvm       warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name +
2962357e899Savl-llvm                ": " + Entry + " and " + Path + ".",
2972357e899Savl-llvm            &Die);
2982357e899Savl-llvm     }
299b7a66d0fSKazu Hirata     Entry = std::string(ResolvedPath);
3002357e899Savl-llvm   }
3012357e899Savl-llvm }
3022357e899Savl-llvm 
3032357e899Savl-llvm Error CompileUnit::assignTypeNames(TypePool &TypePoolRef) {
3042357e899Savl-llvm   if (!getUnitDIE().isValid())
3052357e899Savl-llvm     return Error::success();
3062357e899Savl-llvm 
3072357e899Savl-llvm   SyntheticTypeNameBuilder NameBuilder(TypePoolRef);
3082357e899Savl-llvm   return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder);
3092357e899Savl-llvm }
3102357e899Savl-llvm 
3112357e899Savl-llvm Error CompileUnit::assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,
3122357e899Savl-llvm                                       SyntheticTypeNameBuilder &NameBuilder) {
3132357e899Savl-llvm   OrderedChildrenIndexAssigner ChildrenIndexAssigner(*this, DieEntry);
3142357e899Savl-llvm   for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);
3152357e899Savl-llvm        CurChild && CurChild->getAbbreviationDeclarationPtr();
3162357e899Savl-llvm        CurChild = getSiblingEntry(CurChild)) {
3172357e899Savl-llvm     CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);
3182357e899Savl-llvm     if (!ChildInfo.needToPlaceInTypeTable())
3192357e899Savl-llvm       continue;
3202357e899Savl-llvm 
3212357e899Savl-llvm     assert(ChildInfo.getODRAvailable());
3222357e899Savl-llvm     if (Error Err = NameBuilder.assignName(
3232357e899Savl-llvm             {this, CurChild},
3242357e899Savl-llvm             ChildrenIndexAssigner.getChildIndex(*this, CurChild)))
3252357e899Savl-llvm       return Err;
3262357e899Savl-llvm 
3272357e899Savl-llvm     if (Error Err = assignTypeNamesRec(CurChild, NameBuilder))
3282357e899Savl-llvm       return Err;
3292357e899Savl-llvm   }
3302357e899Savl-llvm 
3312357e899Savl-llvm   return Error::success();
3322357e899Savl-llvm }
3332357e899Savl-llvm 
3342357e899Savl-llvm void CompileUnit::updateDieRefPatchesWithClonedOffsets() {
3352357e899Savl-llvm   if (std::optional<SectionDescriptor *> DebugInfoSection =
3362357e899Savl-llvm           tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) {
3372357e899Savl-llvm 
3382357e899Savl-llvm     (*DebugInfoSection)
3392357e899Savl-llvm         ->ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) {
3402357e899Savl-llvm           /// Replace stored DIE indexes with DIE output offsets.
3412357e899Savl-llvm           Patch.RefDieIdxOrClonedOffset =
3422357e899Savl-llvm               Patch.RefCU.getPointer()->getDieOutOffset(
3432357e899Savl-llvm                   Patch.RefDieIdxOrClonedOffset);
3442357e899Savl-llvm         });
3452357e899Savl-llvm 
3462357e899Savl-llvm     (*DebugInfoSection)
3472357e899Savl-llvm         ->ListDebugULEB128DieRefPatch.forEach(
3482357e899Savl-llvm             [&](DebugULEB128DieRefPatch &Patch) {
3492357e899Savl-llvm               /// Replace stored DIE indexes with DIE output offsets.
3502357e899Savl-llvm               Patch.RefDieIdxOrClonedOffset =
3512357e899Savl-llvm                   Patch.RefCU.getPointer()->getDieOutOffset(
3522357e899Savl-llvm                       Patch.RefDieIdxOrClonedOffset);
3532357e899Savl-llvm             });
3542357e899Savl-llvm   }
3552357e899Savl-llvm 
3562357e899Savl-llvm   if (std::optional<SectionDescriptor *> DebugLocSection =
3572357e899Savl-llvm           tryGetSectionDescriptor(DebugSectionKind::DebugLoc)) {
3582357e899Savl-llvm     (*DebugLocSection)
3592357e899Savl-llvm         ->ListDebugULEB128DieRefPatch.forEach(
3602357e899Savl-llvm             [](DebugULEB128DieRefPatch &Patch) {
3612357e899Savl-llvm               /// Replace stored DIE indexes with DIE output offsets.
3622357e899Savl-llvm               Patch.RefDieIdxOrClonedOffset =
3632357e899Savl-llvm                   Patch.RefCU.getPointer()->getDieOutOffset(
3642357e899Savl-llvm                       Patch.RefDieIdxOrClonedOffset);
3652357e899Savl-llvm             });
3662357e899Savl-llvm   }
3672357e899Savl-llvm 
3682357e899Savl-llvm   if (std::optional<SectionDescriptor *> DebugLocListsSection =
3692357e899Savl-llvm           tryGetSectionDescriptor(DebugSectionKind::DebugLocLists)) {
3702357e899Savl-llvm     (*DebugLocListsSection)
3712357e899Savl-llvm         ->ListDebugULEB128DieRefPatch.forEach(
3722357e899Savl-llvm             [](DebugULEB128DieRefPatch &Patch) {
3732357e899Savl-llvm               /// Replace stored DIE indexes with DIE output offsets.
3742357e899Savl-llvm               Patch.RefDieIdxOrClonedOffset =
3752357e899Savl-llvm                   Patch.RefCU.getPointer()->getDieOutOffset(
3762357e899Savl-llvm                       Patch.RefDieIdxOrClonedOffset);
3772357e899Savl-llvm             });
3782357e899Savl-llvm   }
3792357e899Savl-llvm }
3802357e899Savl-llvm 
3812357e899Savl-llvm std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
3822357e899Savl-llvm     const DWARFFormValue &RefValue,
3832357e899Savl-llvm     ResolveInterCUReferencesMode CanResolveInterCUReferences) {
384d0d61a7eSPavel Labath   CompileUnit *RefCU;
385d0d61a7eSPavel Labath   uint64_t RefDIEOffset;
386d0d61a7eSPavel Labath   if (std::optional<uint64_t> Offset = RefValue.getAsRelativeReference()) {
387d0d61a7eSPavel Labath     RefCU = this;
388d0d61a7eSPavel Labath     RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset;
389d0d61a7eSPavel Labath   } else if (Offset = RefValue.getAsDebugInfoReference(); Offset) {
390d0d61a7eSPavel Labath     RefCU = getUnitFromOffset(*Offset);
391d0d61a7eSPavel Labath     RefDIEOffset = *Offset;
392d0d61a7eSPavel Labath   } else {
393d0d61a7eSPavel Labath     return std::nullopt;
3942357e899Savl-llvm   }
395d0d61a7eSPavel Labath 
3962357e899Savl-llvm   if (RefCU == this) {
3972357e899Savl-llvm     // Referenced DIE is in current compile unit.
398d0d61a7eSPavel Labath     if (std::optional<uint32_t> RefDieIdx = getDIEIndexForOffset(RefDIEOffset))
3992357e899Savl-llvm       return UnitEntryPairTy{this, getDebugInfoEntry(*RefDieIdx)};
400d0d61a7eSPavel Labath   } else if (RefCU && CanResolveInterCUReferences) {
4012357e899Savl-llvm     // Referenced DIE is in other compile unit.
4022357e899Savl-llvm 
4032357e899Savl-llvm     // Check whether DIEs are loaded for that compile unit.
4042357e899Savl-llvm     enum Stage ReferredCUStage = RefCU->getStage();
4052357e899Savl-llvm     if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned)
4062357e899Savl-llvm       return UnitEntryPairTy{RefCU, nullptr};
4072357e899Savl-llvm 
4082357e899Savl-llvm     if (std::optional<uint32_t> RefDieIdx =
4092357e899Savl-llvm             RefCU->getDIEIndexForOffset(RefDIEOffset))
4102357e899Savl-llvm       return UnitEntryPairTy{RefCU, RefCU->getDebugInfoEntry(*RefDieIdx)};
411d0d61a7eSPavel Labath   } else {
4122357e899Savl-llvm     return UnitEntryPairTy{RefCU, nullptr};
4132357e899Savl-llvm   }
4142357e899Savl-llvm   return std::nullopt;
4152357e899Savl-llvm }
4162357e899Savl-llvm 
4172357e899Savl-llvm std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
4182357e899Savl-llvm     const DWARFDebugInfoEntry *DieEntry, dwarf::Attribute Attr,
4192357e899Savl-llvm     ResolveInterCUReferencesMode CanResolveInterCUReferences) {
4202357e899Savl-llvm   if (std::optional<DWARFFormValue> AttrVal = find(DieEntry, Attr))
4212357e899Savl-llvm     return resolveDIEReference(*AttrVal, CanResolveInterCUReferences);
4222357e899Savl-llvm 
4232357e899Savl-llvm   return std::nullopt;
4242357e899Savl-llvm }
4252357e899Savl-llvm 
4262357e899Savl-llvm void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
4272357e899Savl-llvm                                    int64_t PcOffset) {
4282357e899Savl-llvm   std::lock_guard<std::mutex> Guard(RangesMutex);
4292357e899Savl-llvm 
4302357e899Savl-llvm   Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
4312357e899Savl-llvm   if (LowPc)
4322357e899Savl-llvm     LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
4332357e899Savl-llvm   else
4342357e899Savl-llvm     LowPc = FuncLowPc + PcOffset;
4352357e899Savl-llvm   this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
4362357e899Savl-llvm }
4372357e899Savl-llvm 
4382357e899Savl-llvm void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
4392357e899Savl-llvm   std::lock_guard<std::mutex> Guard(LabelsMutex);
4402357e899Savl-llvm   Labels.insert({LabelLowPc, PcOffset});
4412357e899Savl-llvm }
4422357e899Savl-llvm 
4432357e899Savl-llvm Error CompileUnit::cloneAndEmitDebugLocations() {
4442357e899Savl-llvm   if (getGlobalData().getOptions().UpdateIndexTablesOnly)
4452357e899Savl-llvm     return Error::success();
4462357e899Savl-llvm 
4472357e899Savl-llvm   if (getOrigUnit().getVersion() < 5) {
4482357e899Savl-llvm     emitLocations(DebugSectionKind::DebugLoc);
4492357e899Savl-llvm     return Error::success();
4502357e899Savl-llvm   }
4512357e899Savl-llvm 
4522357e899Savl-llvm   emitLocations(DebugSectionKind::DebugLocLists);
4532357e899Savl-llvm   return Error::success();
4542357e899Savl-llvm }
4552357e899Savl-llvm 
4562357e899Savl-llvm void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {
4572357e899Savl-llvm   SectionDescriptor &DebugInfoSection =
4582357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
4592357e899Savl-llvm 
4602357e899Savl-llvm   if (!DebugInfoSection.ListDebugLocPatch.empty()) {
4612357e899Savl-llvm     SectionDescriptor &OutLocationSection =
4622357e899Savl-llvm         getOrCreateSectionDescriptor(LocationSectionKind);
4632357e899Savl-llvm     DWARFUnit &OrigUnit = getOrigUnit();
4642357e899Savl-llvm 
4652357e899Savl-llvm     uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
4662357e899Savl-llvm 
4672357e899Savl-llvm     DebugInfoSection.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {
4682357e899Savl-llvm       // Get location expressions vector corresponding to the current
4692357e899Savl-llvm       // attribute from the source DWARF.
4702357e899Savl-llvm       uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal(
4712357e899Savl-llvm           Patch.PatchOffset,
4722357e899Savl-llvm           DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
4732357e899Savl-llvm       Expected<DWARFLocationExpressionsVector> OriginalLocations =
4742357e899Savl-llvm           OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset);
4752357e899Savl-llvm 
4762357e899Savl-llvm       if (!OriginalLocations) {
4772357e899Savl-llvm         warn(OriginalLocations.takeError());
4782357e899Savl-llvm         return;
4792357e899Savl-llvm       }
4802357e899Savl-llvm 
4812357e899Savl-llvm       LinkedLocationExpressionsVector LinkedLocationExpressions;
4822357e899Savl-llvm       for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
4832357e899Savl-llvm         LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
4842357e899Savl-llvm 
4852357e899Savl-llvm         if (CurExpression.Range) {
4862357e899Savl-llvm           // Relocate address range.
4872357e899Savl-llvm           LinkedExpression.Expression.Range = {
4882357e899Savl-llvm               CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,
4892357e899Savl-llvm               CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};
4902357e899Savl-llvm         }
4912357e899Savl-llvm 
4922357e899Savl-llvm         DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(),
4932357e899Savl-llvm                            OrigUnit.getAddressByteSize());
4942357e899Savl-llvm 
4952357e899Savl-llvm         DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),
4962357e899Savl-llvm                                         OrigUnit.getFormParams().Format);
4972357e899Savl-llvm         cloneDieAttrExpression(InputExpression,
4982357e899Savl-llvm                                LinkedExpression.Expression.Expr,
4992357e899Savl-llvm                                OutLocationSection, Patch.AddrAdjustmentValue,
5002357e899Savl-llvm                                LinkedExpression.Patches);
5012357e899Savl-llvm 
5022357e899Savl-llvm         LinkedLocationExpressions.push_back({LinkedExpression});
5032357e899Savl-llvm       }
5042357e899Savl-llvm 
5052357e899Savl-llvm       // Emit locations list table fragment corresponding to the CurLocAttr.
5062357e899Savl-llvm       DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
5072357e899Savl-llvm                              OutLocationSection.OS.tell());
5082357e899Savl-llvm       emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
5092357e899Savl-llvm     });
5102357e899Savl-llvm 
5112357e899Savl-llvm     if (OffsetAfterUnitLength > 0) {
5122357e899Savl-llvm       assert(OffsetAfterUnitLength -
5132357e899Savl-llvm                  OutLocationSection.getFormParams().getDwarfOffsetByteSize() <
5142357e899Savl-llvm              OffsetAfterUnitLength);
5152357e899Savl-llvm       OutLocationSection.apply(
5162357e899Savl-llvm           OffsetAfterUnitLength -
5172357e899Savl-llvm               OutLocationSection.getFormParams().getDwarfOffsetByteSize(),
5182357e899Savl-llvm           dwarf::DW_FORM_sec_offset,
5192357e899Savl-llvm           OutLocationSection.OS.tell() - OffsetAfterUnitLength);
5202357e899Savl-llvm     }
5212357e899Savl-llvm   }
5222357e899Savl-llvm }
5232357e899Savl-llvm 
5242357e899Savl-llvm /// Emit debug locations(.debug_loc, .debug_loclists) header.
5252357e899Savl-llvm uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {
5262357e899Savl-llvm   if (getOrigUnit().getVersion() < 5)
5272357e899Savl-llvm     return 0;
5282357e899Savl-llvm 
5292357e899Savl-llvm   // unit_length.
5302357e899Savl-llvm   OutLocationSection.emitUnitLength(0xBADDEF);
5312357e899Savl-llvm   uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell();
5322357e899Savl-llvm 
5332357e899Savl-llvm   // Version.
5342357e899Savl-llvm   OutLocationSection.emitIntVal(5, 2);
5352357e899Savl-llvm 
5362357e899Savl-llvm   // Address size.
5372357e899Savl-llvm   OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1);
5382357e899Savl-llvm 
5392357e899Savl-llvm   // Seg_size
5402357e899Savl-llvm   OutLocationSection.emitIntVal(0, 1);
5412357e899Savl-llvm 
5422357e899Savl-llvm   // Offset entry count
5432357e899Savl-llvm   OutLocationSection.emitIntVal(0, 4);
5442357e899Savl-llvm 
5452357e899Savl-llvm   return OffsetAfterUnitLength;
5462357e899Savl-llvm }
5472357e899Savl-llvm 
5482357e899Savl-llvm /// Emit debug locations(.debug_loc, .debug_loclists) fragment.
5492357e899Savl-llvm uint64_t CompileUnit::emitLocListFragment(
5502357e899Savl-llvm     const LinkedLocationExpressionsVector &LinkedLocationExpression,
5512357e899Savl-llvm     SectionDescriptor &OutLocationSection) {
5522357e899Savl-llvm   uint64_t OffsetBeforeLocationExpression = 0;
5532357e899Savl-llvm 
5542357e899Savl-llvm   if (getOrigUnit().getVersion() < 5) {
5552357e899Savl-llvm     uint64_t BaseAddress = 0;
5562357e899Savl-llvm     if (std::optional<uint64_t> LowPC = getLowPc())
5572357e899Savl-llvm       BaseAddress = *LowPC;
5582357e899Savl-llvm 
5592357e899Savl-llvm     for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
5602357e899Savl-llvm          LinkedLocationExpression) {
5612357e899Savl-llvm       if (LocExpression.Expression.Range) {
5622357e899Savl-llvm         OutLocationSection.emitIntVal(
5632357e899Savl-llvm             LocExpression.Expression.Range->LowPC - BaseAddress,
5642357e899Savl-llvm             OutLocationSection.getFormParams().AddrSize);
5652357e899Savl-llvm         OutLocationSection.emitIntVal(
5662357e899Savl-llvm             LocExpression.Expression.Range->HighPC - BaseAddress,
5672357e899Savl-llvm             OutLocationSection.getFormParams().AddrSize);
5682357e899Savl-llvm       }
5692357e899Savl-llvm 
5702357e899Savl-llvm       OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2);
5712357e899Savl-llvm       OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
5722357e899Savl-llvm       for (uint64_t *OffsetPtr : LocExpression.Patches)
5732357e899Savl-llvm         *OffsetPtr += OffsetBeforeLocationExpression;
5742357e899Savl-llvm 
5752357e899Savl-llvm       OutLocationSection.OS
5762357e899Savl-llvm           << StringRef((const char *)LocExpression.Expression.Expr.data(),
5772357e899Savl-llvm                        LocExpression.Expression.Expr.size());
5782357e899Savl-llvm     }
5792357e899Savl-llvm 
5802357e899Savl-llvm     // Emit the terminator entry.
5812357e899Savl-llvm     OutLocationSection.emitIntVal(0,
5822357e899Savl-llvm                                   OutLocationSection.getFormParams().AddrSize);
5832357e899Savl-llvm     OutLocationSection.emitIntVal(0,
5842357e899Savl-llvm                                   OutLocationSection.getFormParams().AddrSize);
5852357e899Savl-llvm     return OffsetBeforeLocationExpression;
5862357e899Savl-llvm   }
5872357e899Savl-llvm 
5882357e899Savl-llvm   std::optional<uint64_t> BaseAddress;
5892357e899Savl-llvm   for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
5902357e899Savl-llvm        LinkedLocationExpression) {
5912357e899Savl-llvm     if (LocExpression.Expression.Range) {
5922357e899Savl-llvm       // Check whether base address is set. If it is not set yet
5932357e899Savl-llvm       // then set current base address and emit base address selection entry.
5942357e899Savl-llvm       if (!BaseAddress) {
5952357e899Savl-llvm         BaseAddress = LocExpression.Expression.Range->LowPC;
5962357e899Savl-llvm 
5972357e899Savl-llvm         // Emit base address.
5982357e899Savl-llvm         OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1);
5992357e899Savl-llvm         encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress),
6002357e899Savl-llvm                       OutLocationSection.OS);
6012357e899Savl-llvm       }
6022357e899Savl-llvm 
6032357e899Savl-llvm       // Emit type of entry.
6042357e899Savl-llvm       OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1);
6052357e899Savl-llvm 
6062357e899Savl-llvm       // Emit start offset relative to base address.
6072357e899Savl-llvm       encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
6082357e899Savl-llvm                     OutLocationSection.OS);
6092357e899Savl-llvm 
6102357e899Savl-llvm       // Emit end offset relative to base address.
6112357e899Savl-llvm       encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
6122357e899Savl-llvm                     OutLocationSection.OS);
6132357e899Savl-llvm     } else
6142357e899Savl-llvm       // Emit type of entry.
6152357e899Savl-llvm       OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1);
6162357e899Savl-llvm 
6172357e899Savl-llvm     encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS);
6182357e899Savl-llvm     OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
6192357e899Savl-llvm     for (uint64_t *OffsetPtr : LocExpression.Patches)
6202357e899Savl-llvm       *OffsetPtr += OffsetBeforeLocationExpression;
6212357e899Savl-llvm 
6222357e899Savl-llvm     OutLocationSection.OS << StringRef(
6232357e899Savl-llvm         (const char *)LocExpression.Expression.Expr.data(),
6242357e899Savl-llvm         LocExpression.Expression.Expr.size());
6252357e899Savl-llvm   }
6262357e899Savl-llvm 
6272357e899Savl-llvm   // Emit the terminator entry.
6282357e899Savl-llvm   OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1);
6292357e899Savl-llvm   return OffsetBeforeLocationExpression;
6302357e899Savl-llvm }
6312357e899Savl-llvm 
6322357e899Savl-llvm Error CompileUnit::emitDebugAddrSection() {
6332357e899Savl-llvm   if (GlobalData.getOptions().UpdateIndexTablesOnly)
6342357e899Savl-llvm     return Error::success();
6352357e899Savl-llvm 
6362357e899Savl-llvm   if (getVersion() < 5)
6372357e899Savl-llvm     return Error::success();
6382357e899Savl-llvm 
6392357e899Savl-llvm   if (DebugAddrIndexMap.empty())
6402357e899Savl-llvm     return Error::success();
6412357e899Savl-llvm 
6422357e899Savl-llvm   SectionDescriptor &OutAddrSection =
6432357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr);
6442357e899Savl-llvm 
6452357e899Savl-llvm   // Emit section header.
6462357e899Savl-llvm 
6472357e899Savl-llvm   //   Emit length.
6482357e899Savl-llvm   OutAddrSection.emitUnitLength(0xBADDEF);
6492357e899Savl-llvm   uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell();
6502357e899Savl-llvm 
6512357e899Savl-llvm   //   Emit version.
6522357e899Savl-llvm   OutAddrSection.emitIntVal(5, 2);
6532357e899Savl-llvm 
6542357e899Savl-llvm   //   Emit address size.
6552357e899Savl-llvm   OutAddrSection.emitIntVal(getFormParams().AddrSize, 1);
6562357e899Savl-llvm 
6572357e899Savl-llvm   //   Emit segment size.
6582357e899Savl-llvm   OutAddrSection.emitIntVal(0, 1);
6592357e899Savl-llvm 
6602357e899Savl-llvm   // Emit addresses.
6612357e899Savl-llvm   for (uint64_t AddrValue : DebugAddrIndexMap.getValues())
6622357e899Savl-llvm     OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize);
6632357e899Savl-llvm 
6642357e899Savl-llvm   // Patch section length.
6652357e899Savl-llvm   OutAddrSection.apply(
6662357e899Savl-llvm       OffsetAfterSectionLength -
6672357e899Savl-llvm           OutAddrSection.getFormParams().getDwarfOffsetByteSize(),
6682357e899Savl-llvm       dwarf::DW_FORM_sec_offset,
6692357e899Savl-llvm       OutAddrSection.OS.tell() - OffsetAfterSectionLength);
6702357e899Savl-llvm 
6712357e899Savl-llvm   return Error::success();
6722357e899Savl-llvm }
6732357e899Savl-llvm 
6742357e899Savl-llvm Error CompileUnit::cloneAndEmitRanges() {
6752357e899Savl-llvm   if (getGlobalData().getOptions().UpdateIndexTablesOnly)
6762357e899Savl-llvm     return Error::success();
6772357e899Savl-llvm 
6782357e899Savl-llvm   // Build set of linked address ranges for unit function ranges.
6792357e899Savl-llvm   AddressRanges LinkedFunctionRanges;
6802357e899Savl-llvm   for (const AddressRangeValuePair &Range : getFunctionRanges())
6812357e899Savl-llvm     LinkedFunctionRanges.insert(
6822357e899Savl-llvm         {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
6832357e899Savl-llvm 
6842357e899Savl-llvm   emitAranges(LinkedFunctionRanges);
6852357e899Savl-llvm 
6862357e899Savl-llvm   if (getOrigUnit().getVersion() < 5) {
6872357e899Savl-llvm     cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges);
6882357e899Savl-llvm     return Error::success();
6892357e899Savl-llvm   }
6902357e899Savl-llvm 
6912357e899Savl-llvm   cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges);
6922357e899Savl-llvm   return Error::success();
6932357e899Savl-llvm }
6942357e899Savl-llvm 
6952357e899Savl-llvm void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
6962357e899Savl-llvm                                         AddressRanges &LinkedFunctionRanges) {
6972357e899Savl-llvm   SectionDescriptor &DebugInfoSection =
6982357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
6992357e899Savl-llvm   SectionDescriptor &OutRangeSection =
7002357e899Savl-llvm       getOrCreateSectionDescriptor(RngSectionKind);
7012357e899Savl-llvm 
7022357e899Savl-llvm   if (!DebugInfoSection.ListDebugRangePatch.empty()) {
7032357e899Savl-llvm     std::optional<AddressRangeValuePair> CachedRange;
7042357e899Savl-llvm     uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
7052357e899Savl-llvm 
7062357e899Savl-llvm     DebugRangePatch *CompileUnitRangePtr = nullptr;
7072357e899Savl-llvm     DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
7082357e899Savl-llvm       if (Patch.IsCompileUnitRanges) {
7092357e899Savl-llvm         CompileUnitRangePtr = &Patch;
7102357e899Savl-llvm       } else {
7112357e899Savl-llvm         // Get ranges from the source DWARF corresponding to the current
7122357e899Savl-llvm         // attribute.
7132357e899Savl-llvm         AddressRanges LinkedRanges;
7142357e899Savl-llvm         uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
7152357e899Savl-llvm             Patch.PatchOffset,
7162357e899Savl-llvm             DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
7172357e899Savl-llvm         if (Expected<DWARFAddressRangesVector> InputRanges =
7182357e899Savl-llvm                 getOrigUnit().findRnglistFromOffset(
7192357e899Savl-llvm                     InputDebugRangesSectionOffset)) {
7202357e899Savl-llvm           // Apply relocation adjustment.
7212357e899Savl-llvm           for (const auto &Range : *InputRanges) {
7222357e899Savl-llvm             if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
7232357e899Savl-llvm               CachedRange =
7242357e899Savl-llvm                   getFunctionRanges().getRangeThatContains(Range.LowPC);
7252357e899Savl-llvm 
7262357e899Savl-llvm             // All range entries should lie in the function range.
7272357e899Savl-llvm             if (!CachedRange) {
7282357e899Savl-llvm               warn("inconsistent range data.");
7292357e899Savl-llvm               continue;
7302357e899Savl-llvm             }
7312357e899Savl-llvm 
7322357e899Savl-llvm             // Store range for emiting.
7332357e899Savl-llvm             LinkedRanges.insert({Range.LowPC + CachedRange->Value,
7342357e899Savl-llvm                                  Range.HighPC + CachedRange->Value});
7352357e899Savl-llvm           }
7362357e899Savl-llvm         } else {
7372357e899Savl-llvm           llvm::consumeError(InputRanges.takeError());
7382357e899Savl-llvm           warn("invalid range list ignored.");
7392357e899Savl-llvm         }
7402357e899Savl-llvm 
7412357e899Savl-llvm         // Emit linked ranges.
7422357e899Savl-llvm         DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
7432357e899Savl-llvm                                OutRangeSection.OS.tell());
7442357e899Savl-llvm         emitRangeListFragment(LinkedRanges, OutRangeSection);
7452357e899Savl-llvm       }
7462357e899Savl-llvm     });
7472357e899Savl-llvm 
7482357e899Savl-llvm     if (CompileUnitRangePtr != nullptr) {
7492357e899Savl-llvm       // Emit compile unit ranges last to be binary compatible with classic
7502357e899Savl-llvm       // dsymutil.
7512357e899Savl-llvm       DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset,
7522357e899Savl-llvm                              dwarf::DW_FORM_sec_offset,
7532357e899Savl-llvm                              OutRangeSection.OS.tell());
7542357e899Savl-llvm       emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
7552357e899Savl-llvm     }
7562357e899Savl-llvm 
7572357e899Savl-llvm     if (OffsetAfterUnitLength > 0) {
7582357e899Savl-llvm       assert(OffsetAfterUnitLength -
7592357e899Savl-llvm                  OutRangeSection.getFormParams().getDwarfOffsetByteSize() <
7602357e899Savl-llvm              OffsetAfterUnitLength);
7612357e899Savl-llvm       OutRangeSection.apply(
7622357e899Savl-llvm           OffsetAfterUnitLength -
7632357e899Savl-llvm               OutRangeSection.getFormParams().getDwarfOffsetByteSize(),
7642357e899Savl-llvm           dwarf::DW_FORM_sec_offset,
7652357e899Savl-llvm           OutRangeSection.OS.tell() - OffsetAfterUnitLength);
7662357e899Savl-llvm     }
7672357e899Savl-llvm   }
7682357e899Savl-llvm }
7692357e899Savl-llvm 
7702357e899Savl-llvm uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {
7712357e899Savl-llvm   if (OutRangeSection.getFormParams().Version < 5)
7722357e899Savl-llvm     return 0;
7732357e899Savl-llvm 
7742357e899Savl-llvm   // unit_length.
7752357e899Savl-llvm   OutRangeSection.emitUnitLength(0xBADDEF);
7762357e899Savl-llvm   uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell();
7772357e899Savl-llvm 
7782357e899Savl-llvm   // Version.
7792357e899Savl-llvm   OutRangeSection.emitIntVal(5, 2);
7802357e899Savl-llvm 
7812357e899Savl-llvm   // Address size.
7822357e899Savl-llvm   OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1);
7832357e899Savl-llvm 
7842357e899Savl-llvm   // Seg_size
7852357e899Savl-llvm   OutRangeSection.emitIntVal(0, 1);
7862357e899Savl-llvm 
7872357e899Savl-llvm   // Offset entry count
7882357e899Savl-llvm   OutRangeSection.emitIntVal(0, 4);
7892357e899Savl-llvm 
7902357e899Savl-llvm   return OffsetAfterUnitLength;
7912357e899Savl-llvm }
7922357e899Savl-llvm 
7932357e899Savl-llvm void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges,
7942357e899Savl-llvm                                         SectionDescriptor &OutRangeSection) {
7952357e899Savl-llvm   if (OutRangeSection.getFormParams().Version < 5) {
7962357e899Savl-llvm     // Emit ranges.
7972357e899Savl-llvm     uint64_t BaseAddress = 0;
7982357e899Savl-llvm     if (std::optional<uint64_t> LowPC = getLowPc())
7992357e899Savl-llvm       BaseAddress = *LowPC;
8002357e899Savl-llvm 
8012357e899Savl-llvm     for (const AddressRange &Range : LinkedRanges) {
8022357e899Savl-llvm       OutRangeSection.emitIntVal(Range.start() - BaseAddress,
8032357e899Savl-llvm                                  OutRangeSection.getFormParams().AddrSize);
8042357e899Savl-llvm       OutRangeSection.emitIntVal(Range.end() - BaseAddress,
8052357e899Savl-llvm                                  OutRangeSection.getFormParams().AddrSize);
8062357e899Savl-llvm     }
8072357e899Savl-llvm 
8082357e899Savl-llvm     // Add the terminator entry.
8092357e899Savl-llvm     OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
8102357e899Savl-llvm     OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
8112357e899Savl-llvm     return;
8122357e899Savl-llvm   }
8132357e899Savl-llvm 
8142357e899Savl-llvm   std::optional<uint64_t> BaseAddress;
8152357e899Savl-llvm   for (const AddressRange &Range : LinkedRanges) {
8162357e899Savl-llvm     if (!BaseAddress) {
8172357e899Savl-llvm       BaseAddress = Range.start();
8182357e899Savl-llvm 
8192357e899Savl-llvm       // Emit base address.
8202357e899Savl-llvm       OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1);
8212357e899Savl-llvm       encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS);
8222357e899Savl-llvm     }
8232357e899Savl-llvm 
8242357e899Savl-llvm     // Emit type of entry.
8252357e899Savl-llvm     OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1);
8262357e899Savl-llvm 
8272357e899Savl-llvm     // Emit start offset relative to base address.
8282357e899Savl-llvm     encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS);
8292357e899Savl-llvm 
8302357e899Savl-llvm     // Emit end offset relative to base address.
8312357e899Savl-llvm     encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS);
8322357e899Savl-llvm   }
8332357e899Savl-llvm 
8342357e899Savl-llvm   // Emit the terminator entry.
8352357e899Savl-llvm   OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1);
8362357e899Savl-llvm }
8372357e899Savl-llvm 
8382357e899Savl-llvm void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
8392357e899Savl-llvm   if (LinkedFunctionRanges.empty())
8402357e899Savl-llvm     return;
8412357e899Savl-llvm 
8422357e899Savl-llvm   SectionDescriptor &DebugInfoSection =
8432357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
8442357e899Savl-llvm   SectionDescriptor &OutArangesSection =
8452357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges);
8462357e899Savl-llvm 
8472357e899Savl-llvm   // Emit Header.
8482357e899Savl-llvm   unsigned HeaderSize =
8492357e899Savl-llvm       sizeof(int32_t) + // Size of contents (w/o this field
8502357e899Savl-llvm       sizeof(int16_t) + // DWARF ARange version number
8512357e899Savl-llvm       sizeof(int32_t) + // Offset of CU in the .debug_info section
8522357e899Savl-llvm       sizeof(int8_t) +  // Pointer Size (in bytes)
8532357e899Savl-llvm       sizeof(int8_t);   // Segment Size (in bytes)
8542357e899Savl-llvm 
8552357e899Savl-llvm   unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;
8562357e899Savl-llvm   unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
8572357e899Savl-llvm 
8582357e899Savl-llvm   OutArangesSection.emitOffset(0xBADDEF); // Aranges length
8592357e899Savl-llvm   uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();
8602357e899Savl-llvm 
8612357e899Savl-llvm   OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2); // Version number
8622357e899Savl-llvm   OutArangesSection.notePatch(
8632357e899Savl-llvm       DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection});
8642357e899Savl-llvm   OutArangesSection.emitOffset(0xBADDEF); // Corresponding unit's offset
8652357e899Savl-llvm   OutArangesSection.emitIntVal(OutArangesSection.getFormParams().AddrSize,
8662357e899Savl-llvm                                1);    // Address size
8672357e899Savl-llvm   OutArangesSection.emitIntVal(0, 1); // Segment size
8682357e899Savl-llvm 
8692357e899Savl-llvm   for (size_t Idx = 0; Idx < Padding; Idx++)
8702357e899Savl-llvm     OutArangesSection.emitIntVal(0, 1); // Padding
8712357e899Savl-llvm 
8722357e899Savl-llvm   // Emit linked ranges.
8732357e899Savl-llvm   for (const AddressRange &Range : LinkedFunctionRanges) {
8742357e899Savl-llvm     OutArangesSection.emitIntVal(Range.start(),
8752357e899Savl-llvm                                  OutArangesSection.getFormParams().AddrSize);
8762357e899Savl-llvm     OutArangesSection.emitIntVal(Range.end() - Range.start(),
8772357e899Savl-llvm                                  OutArangesSection.getFormParams().AddrSize);
8782357e899Savl-llvm   }
8792357e899Savl-llvm 
8802357e899Savl-llvm   // Emit terminator.
8812357e899Savl-llvm   OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
8822357e899Savl-llvm   OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
8832357e899Savl-llvm 
8842357e899Savl-llvm   uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell();
8852357e899Savl-llvm 
8862357e899Savl-llvm   // Update Aranges lentgh.
8872357e899Savl-llvm   OutArangesSection.apply(
8882357e899Savl-llvm       OffsetAfterArangesLengthField -
8892357e899Savl-llvm           OutArangesSection.getFormParams().getDwarfOffsetByteSize(),
8902357e899Savl-llvm       dwarf::DW_FORM_sec_offset,
8912357e899Savl-llvm       OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
8922357e899Savl-llvm }
8932357e899Savl-llvm 
8942357e899Savl-llvm Error CompileUnit::cloneAndEmitDebugMacro() {
8952357e899Savl-llvm   if (getOutUnitDIE() == nullptr)
8962357e899Savl-llvm     return Error::success();
8972357e899Savl-llvm 
8982357e899Savl-llvm   DWARFUnit &OrigUnit = getOrigUnit();
8992357e899Savl-llvm   DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
9002357e899Savl-llvm 
9012357e899Savl-llvm   // Check for .debug_macro table.
9022357e899Savl-llvm   if (std::optional<uint64_t> MacroAttr =
9032357e899Savl-llvm           dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
9042357e899Savl-llvm     if (const DWARFDebugMacro *Table =
9052357e899Savl-llvm             getContaingFile().Dwarf->getDebugMacro()) {
9062357e899Savl-llvm       emitMacroTableImpl(Table, *MacroAttr, true);
9072357e899Savl-llvm     }
9082357e899Savl-llvm   }
9092357e899Savl-llvm 
9102357e899Savl-llvm   // Check for .debug_macinfo table.
9112357e899Savl-llvm   if (std::optional<uint64_t> MacroAttr =
9122357e899Savl-llvm           dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
9132357e899Savl-llvm     if (const DWARFDebugMacro *Table =
9142357e899Savl-llvm             getContaingFile().Dwarf->getDebugMacinfo()) {
9152357e899Savl-llvm       emitMacroTableImpl(Table, *MacroAttr, false);
9162357e899Savl-llvm     }
9172357e899Savl-llvm   }
9182357e899Savl-llvm 
9192357e899Savl-llvm   return Error::success();
9202357e899Savl-llvm }
9212357e899Savl-llvm 
9222357e899Savl-llvm void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
9232357e899Savl-llvm                                      uint64_t OffsetToMacroTable,
9242357e899Savl-llvm                                      bool hasDWARFv5Header) {
9252357e899Savl-llvm   SectionDescriptor &OutSection =
9262357e899Savl-llvm       hasDWARFv5Header
9272357e899Savl-llvm           ? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro)
9282357e899Savl-llvm           : getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo);
9292357e899Savl-llvm 
9302357e899Savl-llvm   bool DefAttributeIsReported = false;
9312357e899Savl-llvm   bool UndefAttributeIsReported = false;
9322357e899Savl-llvm   bool ImportAttributeIsReported = false;
9332357e899Savl-llvm 
9342357e899Savl-llvm   for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
9352357e899Savl-llvm     if (OffsetToMacroTable == List.Offset) {
9362357e899Savl-llvm       // Write DWARFv5 header.
9372357e899Savl-llvm       if (hasDWARFv5Header) {
9382357e899Savl-llvm         // Write header version.
9392357e899Savl-llvm         OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version));
9402357e899Savl-llvm 
9412357e899Savl-llvm         uint8_t Flags = List.Header.Flags;
9422357e899Savl-llvm 
9432357e899Savl-llvm         // Check for OPCODE_OPERANDS_TABLE.
9442357e899Savl-llvm         if (Flags &
9452357e899Savl-llvm             DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
9462357e899Savl-llvm           Flags &=
9472357e899Savl-llvm               ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
9482357e899Savl-llvm           warn("opcode_operands_table is not supported yet.");
9492357e899Savl-llvm         }
9502357e899Savl-llvm 
9512357e899Savl-llvm         // Check for DEBUG_LINE_OFFSET.
9522357e899Savl-llvm         std::optional<uint64_t> StmtListOffset;
9532357e899Savl-llvm         if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
9542357e899Savl-llvm           // Get offset to the line table from the cloned compile unit.
9552357e899Savl-llvm           for (auto &V : getOutUnitDIE()->values()) {
9562357e899Savl-llvm             if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
9572357e899Savl-llvm               StmtListOffset = V.getDIEInteger().getValue();
9582357e899Savl-llvm               break;
9592357e899Savl-llvm             }
9602357e899Savl-llvm           }
9612357e899Savl-llvm 
9622357e899Savl-llvm           if (!StmtListOffset) {
9632357e899Savl-llvm             Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
9642357e899Savl-llvm             warn("couldn`t find line table for macro table.");
9652357e899Savl-llvm           }
9662357e899Savl-llvm         }
9672357e899Savl-llvm 
9682357e899Savl-llvm         // Write flags.
9692357e899Savl-llvm         OutSection.emitIntVal(Flags, sizeof(Flags));
9702357e899Savl-llvm 
9712357e899Savl-llvm         // Write offset to line table.
9722357e899Savl-llvm         if (StmtListOffset) {
9732357e899Savl-llvm           OutSection.notePatch(DebugOffsetPatch{
9742357e899Savl-llvm               OutSection.OS.tell(),
9752357e899Savl-llvm               &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine)});
9762357e899Savl-llvm           // TODO: check that List.Header.getOffsetByteSize() and
9772357e899Savl-llvm           // DebugOffsetPatch agree on size.
9782357e899Savl-llvm           OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize());
9792357e899Savl-llvm         }
9802357e899Savl-llvm       }
9812357e899Savl-llvm 
9822357e899Savl-llvm       // Write macro entries.
9832357e899Savl-llvm       for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
9842357e899Savl-llvm         if (MacroEntry.Type == 0) {
9852357e899Savl-llvm           encodeULEB128(MacroEntry.Type, OutSection.OS);
9862357e899Savl-llvm           continue;
9872357e899Savl-llvm         }
9882357e899Savl-llvm 
9892357e899Savl-llvm         uint8_t MacroType = MacroEntry.Type;
9902357e899Savl-llvm         switch (MacroType) {
9912357e899Savl-llvm         default: {
9922357e899Savl-llvm           bool HasVendorSpecificExtension =
9932357e899Savl-llvm               (!hasDWARFv5Header &&
9942357e899Savl-llvm                MacroType == dwarf::DW_MACINFO_vendor_ext) ||
9952357e899Savl-llvm               (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
9962357e899Savl-llvm                                     MacroType <= dwarf::DW_MACRO_hi_user));
9972357e899Savl-llvm 
9982357e899Savl-llvm           if (HasVendorSpecificExtension) {
9992357e899Savl-llvm             // Write macinfo type.
10002357e899Savl-llvm             OutSection.emitIntVal(MacroType, 1);
10012357e899Savl-llvm 
10022357e899Savl-llvm             // Write vendor extension constant.
10032357e899Savl-llvm             encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);
10042357e899Savl-llvm 
10052357e899Savl-llvm             // Write vendor extension string.
10062357e899Savl-llvm             OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
10072357e899Savl-llvm           } else
10082357e899Savl-llvm             warn("unknown macro type. skip.");
10092357e899Savl-llvm         } break;
10102357e899Savl-llvm         // debug_macro and debug_macinfo share some common encodings.
10112357e899Savl-llvm         // DW_MACRO_define     == DW_MACINFO_define
10122357e899Savl-llvm         // DW_MACRO_undef      == DW_MACINFO_undef
10132357e899Savl-llvm         // DW_MACRO_start_file == DW_MACINFO_start_file
10142357e899Savl-llvm         // DW_MACRO_end_file   == DW_MACINFO_end_file
10152357e899Savl-llvm         // For readibility/uniformity we are using DW_MACRO_*.
10162357e899Savl-llvm         case dwarf::DW_MACRO_define:
10172357e899Savl-llvm         case dwarf::DW_MACRO_undef: {
10182357e899Savl-llvm           // Write macinfo type.
10192357e899Savl-llvm           OutSection.emitIntVal(MacroType, 1);
10202357e899Savl-llvm 
10212357e899Savl-llvm           // Write source line.
10222357e899Savl-llvm           encodeULEB128(MacroEntry.Line, OutSection.OS);
10232357e899Savl-llvm 
10242357e899Savl-llvm           // Write macro string.
10252357e899Savl-llvm           OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
10262357e899Savl-llvm         } break;
10272357e899Savl-llvm         case dwarf::DW_MACRO_define_strp:
10282357e899Savl-llvm         case dwarf::DW_MACRO_undef_strp:
10292357e899Savl-llvm         case dwarf::DW_MACRO_define_strx:
10302357e899Savl-llvm         case dwarf::DW_MACRO_undef_strx: {
10312357e899Savl-llvm           // DW_MACRO_*_strx forms are not supported currently.
10322357e899Savl-llvm           // Convert to *_strp.
10332357e899Savl-llvm           switch (MacroType) {
10342357e899Savl-llvm           case dwarf::DW_MACRO_define_strx: {
10352357e899Savl-llvm             MacroType = dwarf::DW_MACRO_define_strp;
10362357e899Savl-llvm             if (!DefAttributeIsReported) {
10372357e899Savl-llvm               warn("DW_MACRO_define_strx unsupported yet. Convert to "
10382357e899Savl-llvm                    "DW_MACRO_define_strp.");
10392357e899Savl-llvm               DefAttributeIsReported = true;
10402357e899Savl-llvm             }
10412357e899Savl-llvm           } break;
10422357e899Savl-llvm           case dwarf::DW_MACRO_undef_strx: {
10432357e899Savl-llvm             MacroType = dwarf::DW_MACRO_undef_strp;
10442357e899Savl-llvm             if (!UndefAttributeIsReported) {
10452357e899Savl-llvm               warn("DW_MACRO_undef_strx unsupported yet. Convert to "
10462357e899Savl-llvm                    "DW_MACRO_undef_strp.");
10472357e899Savl-llvm               UndefAttributeIsReported = true;
10482357e899Savl-llvm             }
10492357e899Savl-llvm           } break;
10502357e899Savl-llvm           default:
10512357e899Savl-llvm             // Nothing to do.
10522357e899Savl-llvm             break;
10532357e899Savl-llvm           }
10542357e899Savl-llvm 
10552357e899Savl-llvm           // Write macinfo type.
10562357e899Savl-llvm           OutSection.emitIntVal(MacroType, 1);
10572357e899Savl-llvm 
10582357e899Savl-llvm           // Write source line.
10592357e899Savl-llvm           encodeULEB128(MacroEntry.Line, OutSection.OS);
10602357e899Savl-llvm 
10612357e899Savl-llvm           // Write macro string.
10622357e899Savl-llvm           OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
10632357e899Savl-llvm           break;
10642357e899Savl-llvm         }
10652357e899Savl-llvm         case dwarf::DW_MACRO_start_file: {
10662357e899Savl-llvm           // Write macinfo type.
10672357e899Savl-llvm           OutSection.emitIntVal(MacroType, 1);
10682357e899Savl-llvm           // Write source line.
10692357e899Savl-llvm           encodeULEB128(MacroEntry.Line, OutSection.OS);
10702357e899Savl-llvm           // Write source file id.
10712357e899Savl-llvm           encodeULEB128(MacroEntry.File, OutSection.OS);
10722357e899Savl-llvm         } break;
10732357e899Savl-llvm         case dwarf::DW_MACRO_end_file: {
10742357e899Savl-llvm           // Write macinfo type.
10752357e899Savl-llvm           OutSection.emitIntVal(MacroType, 1);
10762357e899Savl-llvm         } break;
10772357e899Savl-llvm         case dwarf::DW_MACRO_import:
10782357e899Savl-llvm         case dwarf::DW_MACRO_import_sup: {
10792357e899Savl-llvm           if (!ImportAttributeIsReported) {
10802357e899Savl-llvm             warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported "
10812357e899Savl-llvm                  "yet. remove.");
10822357e899Savl-llvm             ImportAttributeIsReported = true;
10832357e899Savl-llvm           }
10842357e899Savl-llvm         } break;
10852357e899Savl-llvm         }
10862357e899Savl-llvm       }
10872357e899Savl-llvm 
10882357e899Savl-llvm       return;
10892357e899Savl-llvm     }
10902357e899Savl-llvm   }
10912357e899Savl-llvm }
10922357e899Savl-llvm 
10932357e899Savl-llvm void CompileUnit::cloneDieAttrExpression(
10942357e899Savl-llvm     const DWARFExpression &InputExpression,
10952357e899Savl-llvm     SmallVectorImpl<uint8_t> &OutputExpression, SectionDescriptor &Section,
10962357e899Savl-llvm     std::optional<int64_t> VarAddressAdjustment,
10972357e899Savl-llvm     OffsetsPtrVector &PatchesOffsets) {
10982357e899Savl-llvm   using Encoding = DWARFExpression::Operation::Encoding;
10992357e899Savl-llvm 
11002357e899Savl-llvm   DWARFUnit &OrigUnit = getOrigUnit();
11012357e899Savl-llvm   uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
11022357e899Savl-llvm 
11032357e899Savl-llvm   uint64_t OpOffset = 0;
11042357e899Savl-llvm   for (auto &Op : InputExpression) {
11052357e899Savl-llvm     auto Desc = Op.getDescription();
11062357e899Savl-llvm     // DW_OP_const_type is variable-length and has 3
11072357e899Savl-llvm     // operands. Thus far we only support 2.
11082357e899Savl-llvm     if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||
11092357e899Savl-llvm         (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
11102357e899Savl-llvm          Desc.Op[0] != Encoding::Size1))
11112357e899Savl-llvm       warn("unsupported DW_OP encoding.");
11122357e899Savl-llvm 
11132357e899Savl-llvm     if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||
11142357e899Savl-llvm         (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
11152357e899Savl-llvm          Desc.Op[0] == Encoding::Size1)) {
11162357e899Savl-llvm       // This code assumes that the other non-typeref operand fits into 1 byte.
11172357e899Savl-llvm       assert(OpOffset < Op.getEndOffset());
11182357e899Savl-llvm       uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;
11192357e899Savl-llvm       assert(ULEBsize <= 16);
11202357e899Savl-llvm 
11212357e899Savl-llvm       // Copy over the operation.
11222357e899Savl-llvm       assert(!Op.getSubCode() && "SubOps not yet supported");
11232357e899Savl-llvm       OutputExpression.push_back(Op.getCode());
11242357e899Savl-llvm       uint64_t RefOffset;
11252357e899Savl-llvm       if (Desc.Op.size() == 1) {
11262357e899Savl-llvm         RefOffset = Op.getRawOperand(0);
11272357e899Savl-llvm       } else {
11282357e899Savl-llvm         OutputExpression.push_back(Op.getRawOperand(0));
11292357e899Savl-llvm         RefOffset = Op.getRawOperand(1);
11302357e899Savl-llvm       }
11312357e899Savl-llvm       uint8_t ULEB[16];
11322357e899Savl-llvm       uint32_t Offset = 0;
11332357e899Savl-llvm       unsigned RealSize = 0;
11342357e899Savl-llvm       // Look up the base type. For DW_OP_convert, the operand may be 0 to
11352357e899Savl-llvm       // instead indicate the generic type. The same holds for
11362357e899Savl-llvm       // DW_OP_reinterpret, which is currently not supported.
11372357e899Savl-llvm       if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {
11382357e899Savl-llvm         RefOffset += OrigUnit.getOffset();
11392357e899Savl-llvm         uint32_t RefDieIdx = 0;
11402357e899Savl-llvm         if (std::optional<uint32_t> Idx =
11412357e899Savl-llvm                 OrigUnit.getDIEIndexForOffset(RefOffset))
11422357e899Savl-llvm           RefDieIdx = *Idx;
11432357e899Savl-llvm 
11442357e899Savl-llvm         // Use fixed size for ULEB128 data, since we need to update that size
11452357e899Savl-llvm         // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64.
11462357e899Savl-llvm         ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1;
11472357e899Savl-llvm 
11482357e899Savl-llvm         RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize);
11492357e899Savl-llvm 
11502357e899Savl-llvm         Section.notePatchWithOffsetUpdate(
11512357e899Savl-llvm             DebugULEB128DieRefPatch(OutputExpression.size(), this, this,
11522357e899Savl-llvm                                     RefDieIdx),
11532357e899Savl-llvm             PatchesOffsets);
11542357e899Savl-llvm       } else
11552357e899Savl-llvm         RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
11562357e899Savl-llvm 
11572357e899Savl-llvm       if (RealSize > ULEBsize) {
11582357e899Savl-llvm         // Emit the generic type as a fallback.
11592357e899Savl-llvm         RealSize = encodeULEB128(0, ULEB, ULEBsize);
11602357e899Savl-llvm         warn("base type ref doesn't fit.");
11612357e899Savl-llvm       }
11622357e899Savl-llvm       assert(RealSize == ULEBsize && "padding failed");
11632357e899Savl-llvm       ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
11642357e899Savl-llvm       OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end());
11652357e899Savl-llvm     } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
11662357e899Savl-llvm                Op.getCode() == dwarf::DW_OP_addrx) {
11672357e899Savl-llvm       if (std::optional<object::SectionedAddress> SA =
11682357e899Savl-llvm               OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
11692357e899Savl-llvm         // DWARFLinker does not use addrx forms since it generates relocated
11702357e899Savl-llvm         // addresses. Replace DW_OP_addrx with DW_OP_addr here.
11712357e899Savl-llvm         // Argument of DW_OP_addrx should be relocated here as it is not
11722357e899Savl-llvm         // processed by applyValidRelocs.
11732357e899Savl-llvm         OutputExpression.push_back(dwarf::DW_OP_addr);
1174e4e3ff5aSKazu Hirata         uint64_t LinkedAddress = SA->Address + VarAddressAdjustment.value_or(0);
11752357e899Savl-llvm         if (getEndianness() != llvm::endianness::native)
11762357e899Savl-llvm           sys::swapByteOrder(LinkedAddress);
11772357e899Savl-llvm         ArrayRef<uint8_t> AddressBytes(
11782357e899Savl-llvm             reinterpret_cast<const uint8_t *>(&LinkedAddress),
11792357e899Savl-llvm             OrigAddressByteSize);
11802357e899Savl-llvm         OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
11812357e899Savl-llvm       } else
11822357e899Savl-llvm         warn("cann't read DW_OP_addrx operand.");
11832357e899Savl-llvm     } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
11842357e899Savl-llvm                Op.getCode() == dwarf::DW_OP_constx) {
11852357e899Savl-llvm       if (std::optional<object::SectionedAddress> SA =
11862357e899Savl-llvm               OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
11872357e899Savl-llvm         // DWARFLinker does not use constx forms since it generates relocated
11882357e899Savl-llvm         // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
11892357e899Savl-llvm         // Argument of DW_OP_constx should be relocated here as it is not
11902357e899Savl-llvm         // processed by applyValidRelocs.
11912357e899Savl-llvm         std::optional<uint8_t> OutOperandKind;
11922357e899Savl-llvm         switch (OrigAddressByteSize) {
11932357e899Savl-llvm         case 2:
11942357e899Savl-llvm           OutOperandKind = dwarf::DW_OP_const2u;
11952357e899Savl-llvm           break;
11962357e899Savl-llvm         case 4:
11972357e899Savl-llvm           OutOperandKind = dwarf::DW_OP_const4u;
11982357e899Savl-llvm           break;
11992357e899Savl-llvm         case 8:
12002357e899Savl-llvm           OutOperandKind = dwarf::DW_OP_const8u;
12012357e899Savl-llvm           break;
12022357e899Savl-llvm         default:
12032357e899Savl-llvm           warn(
12042357e899Savl-llvm               formatv(("unsupported address size: {0}."), OrigAddressByteSize));
12052357e899Savl-llvm           break;
12062357e899Savl-llvm         }
12072357e899Savl-llvm 
12082357e899Savl-llvm         if (OutOperandKind) {
12092357e899Savl-llvm           OutputExpression.push_back(*OutOperandKind);
12102357e899Savl-llvm           uint64_t LinkedAddress =
1211e4e3ff5aSKazu Hirata               SA->Address + VarAddressAdjustment.value_or(0);
12122357e899Savl-llvm           if (getEndianness() != llvm::endianness::native)
12132357e899Savl-llvm             sys::swapByteOrder(LinkedAddress);
12142357e899Savl-llvm           ArrayRef<uint8_t> AddressBytes(
12152357e899Savl-llvm               reinterpret_cast<const uint8_t *>(&LinkedAddress),
12162357e899Savl-llvm               OrigAddressByteSize);
12172357e899Savl-llvm           OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
12182357e899Savl-llvm         }
12192357e899Savl-llvm       } else
12202357e899Savl-llvm         warn("cann't read DW_OP_constx operand.");
12212357e899Savl-llvm     } else {
12222357e899Savl-llvm       // Copy over everything else unmodified.
12232357e899Savl-llvm       StringRef Bytes =
12242357e899Savl-llvm           InputExpression.getData().slice(OpOffset, Op.getEndOffset());
12252357e899Savl-llvm       OutputExpression.append(Bytes.begin(), Bytes.end());
12262357e899Savl-llvm     }
12272357e899Savl-llvm     OpOffset = Op.getEndOffset();
12282357e899Savl-llvm   }
12292357e899Savl-llvm }
12302357e899Savl-llvm 
12319ff4be64SAlexey Lapshin Error CompileUnit::cloneAndEmit(
12329ff4be64SAlexey Lapshin     std::optional<std::reference_wrapper<const Triple>> TargetTriple,
12332357e899Savl-llvm     TypeUnit *ArtificialTypeUnit) {
12342357e899Savl-llvm   BumpPtrAllocator Allocator;
12352357e899Savl-llvm 
12362357e899Savl-llvm   DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
12372357e899Savl-llvm   if (!OrigUnitDIE.isValid())
12382357e899Savl-llvm     return Error::success();
12392357e899Savl-llvm 
12402357e899Savl-llvm   TypeEntry *RootEntry = nullptr;
12412357e899Savl-llvm   if (ArtificialTypeUnit)
12422357e899Savl-llvm     RootEntry = ArtificialTypeUnit->getTypePool().getRoot();
12432357e899Savl-llvm 
12442357e899Savl-llvm   // Clone input DIE entry recursively.
12452357e899Savl-llvm   std::pair<DIE *, TypeEntry *> OutCUDie = cloneDIE(
12462357e899Savl-llvm       OrigUnitDIE.getDebugInfoEntry(), RootEntry, getDebugInfoHeaderSize(),
12472357e899Savl-llvm       std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit);
12482357e899Savl-llvm   setOutUnitDIE(OutCUDie.first);
12492357e899Savl-llvm 
12509ff4be64SAlexey Lapshin   if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))
12512357e899Savl-llvm     return Error::success();
12522357e899Savl-llvm 
12539ff4be64SAlexey Lapshin   if (Error Err = cloneAndEmitLineTable((*TargetTriple).get()))
12542357e899Savl-llvm     return Err;
12552357e899Savl-llvm 
12562357e899Savl-llvm   if (Error Err = cloneAndEmitDebugMacro())
12572357e899Savl-llvm     return Err;
12582357e899Savl-llvm 
12592357e899Savl-llvm   getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
12609ff4be64SAlexey Lapshin   if (Error Err = emitDebugInfo((*TargetTriple).get()))
12612357e899Savl-llvm     return Err;
12622357e899Savl-llvm 
12632357e899Savl-llvm   // ASSUMPTION: .debug_info section should already be emitted at this point.
12642357e899Savl-llvm   // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
12652357e899Savl-llvm   // data.
12662357e899Savl-llvm 
12672357e899Savl-llvm   if (Error Err = cloneAndEmitRanges())
12682357e899Savl-llvm     return Err;
12692357e899Savl-llvm 
12702357e899Savl-llvm   if (Error Err = cloneAndEmitDebugLocations())
12712357e899Savl-llvm     return Err;
12722357e899Savl-llvm 
12732357e899Savl-llvm   if (Error Err = emitDebugAddrSection())
12742357e899Savl-llvm     return Err;
12752357e899Savl-llvm 
12762357e899Savl-llvm   // Generate Pub accelerator tables.
12772357e899Savl-llvm   if (llvm::is_contained(GlobalData.getOptions().AccelTables,
12782357e899Savl-llvm                          DWARFLinker::AccelTableKind::Pub))
12792357e899Savl-llvm     emitPubAccelerators();
12802357e899Savl-llvm 
12812357e899Savl-llvm   if (Error Err = emitDebugStringOffsetSection())
12822357e899Savl-llvm     return Err;
12832357e899Savl-llvm 
12842357e899Savl-llvm   return emitAbbreviations();
12852357e899Savl-llvm }
12862357e899Savl-llvm 
12872357e899Savl-llvm std::pair<DIE *, TypeEntry *> CompileUnit::cloneDIE(
12882357e899Savl-llvm     const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE,
12892357e899Savl-llvm     uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
12902357e899Savl-llvm     std::optional<int64_t> VarAddressAdjustment, BumpPtrAllocator &Allocator,
12912357e899Savl-llvm     TypeUnit *ArtificialTypeUnit) {
12922357e899Savl-llvm   uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
12932357e899Savl-llvm   CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);
12942357e899Savl-llvm 
12952357e899Savl-llvm   bool NeedToClonePlainDIE = Info.needToKeepInPlainDwarf();
12962357e899Savl-llvm   bool NeedToCloneTypeDIE =
12972357e899Savl-llvm       (InputDieEntry->getTag() != dwarf::DW_TAG_compile_unit) &&
12982357e899Savl-llvm       Info.needToPlaceInTypeTable();
12992357e899Savl-llvm   std::pair<DIE *, TypeEntry *> ClonedDIE;
13002357e899Savl-llvm 
13012357e899Savl-llvm   DIEGenerator PlainDIEGenerator(Allocator, *this);
13022357e899Savl-llvm 
13032357e899Savl-llvm   if (NeedToClonePlainDIE)
13042357e899Savl-llvm     // Create a cloned DIE which would be placed into the cloned version
13052357e899Savl-llvm     // of input compile unit.
13062357e899Savl-llvm     ClonedDIE.first = createPlainDIEandCloneAttributes(
13072357e899Savl-llvm         InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
13082357e899Savl-llvm         VarAddressAdjustment);
13092357e899Savl-llvm   if (NeedToCloneTypeDIE) {
13102357e899Savl-llvm     // Create a cloned DIE which would be placed into the artificial type
13112357e899Savl-llvm     // unit.
13122357e899Savl-llvm     assert(ArtificialTypeUnit != nullptr);
13132357e899Savl-llvm     DIEGenerator TypeDIEGenerator(
13142357e899Savl-llvm         ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this);
13152357e899Savl-llvm 
13162357e899Savl-llvm     ClonedDIE.second = createTypeDIEandCloneAttributes(
13172357e899Savl-llvm         InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
13182357e899Savl-llvm         ArtificialTypeUnit);
13192357e899Savl-llvm   }
13202357e899Savl-llvm   TypeEntry *TypeParentForChild =
13212357e899Savl-llvm       ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;
13222357e899Savl-llvm 
13232357e899Savl-llvm   bool HasPlainChildrenToClone =
13242357e899Savl-llvm       (ClonedDIE.first && Info.getKeepPlainChildren());
13252357e899Savl-llvm 
13262357e899Savl-llvm   bool HasTypeChildrenToClone =
13272357e899Savl-llvm       ((ClonedDIE.second ||
13282357e899Savl-llvm         InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) &&
13292357e899Savl-llvm        Info.getKeepTypeChildren());
13302357e899Savl-llvm 
13312357e899Savl-llvm   // Recursively clone children.
13322357e899Savl-llvm   if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
13332357e899Savl-llvm     for (const DWARFDebugInfoEntry *CurChild =
13342357e899Savl-llvm              getFirstChildEntry(InputDieEntry);
13352357e899Savl-llvm          CurChild && CurChild->getAbbreviationDeclarationPtr();
13362357e899Savl-llvm          CurChild = getSiblingEntry(CurChild)) {
13372357e899Savl-llvm       std::pair<DIE *, TypeEntry *> ClonedChild = cloneDIE(
13382357e899Savl-llvm           CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
13392357e899Savl-llvm           VarAddressAdjustment, Allocator, ArtificialTypeUnit);
13402357e899Savl-llvm 
13412357e899Savl-llvm       if (ClonedChild.first) {
13422357e899Savl-llvm         OutOffset =
13432357e899Savl-llvm             ClonedChild.first->getOffset() + ClonedChild.first->getSize();
13442357e899Savl-llvm         PlainDIEGenerator.addChild(ClonedChild.first);
13452357e899Savl-llvm       }
13462357e899Savl-llvm     }
13472357e899Savl-llvm     assert(ClonedDIE.first == nullptr ||
13482357e899Savl-llvm            HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
13492357e899Savl-llvm 
13502357e899Savl-llvm     // Account for the end of children marker.
13512357e899Savl-llvm     if (HasPlainChildrenToClone)
13522357e899Savl-llvm       OutOffset += sizeof(int8_t);
13532357e899Savl-llvm   }
13542357e899Savl-llvm 
13552357e899Savl-llvm   // Update our size.
13562357e899Savl-llvm   if (ClonedDIE.first != nullptr)
13572357e899Savl-llvm     ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
13582357e899Savl-llvm 
13592357e899Savl-llvm   return ClonedDIE;
13602357e899Savl-llvm }
13612357e899Savl-llvm 
13622357e899Savl-llvm DIE *CompileUnit::createPlainDIEandCloneAttributes(
13632357e899Savl-llvm     const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,
13642357e899Savl-llvm     uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
13652357e899Savl-llvm     std::optional<int64_t> &VarAddressAdjustment) {
13662357e899Savl-llvm   uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
13672357e899Savl-llvm   CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);
13682357e899Savl-llvm   DIE *ClonedDIE = nullptr;
13692357e899Savl-llvm   bool HasLocationExpressionAddress = false;
13702357e899Savl-llvm   if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) {
13712357e899Savl-llvm     // Get relocation adjustment value for the current function.
13722357e899Savl-llvm     FuncAddressAdjustment =
13732357e899Savl-llvm         getContaingFile().Addresses->getSubprogramRelocAdjustment(
13740ed81942SAlexey Lapshin             getDIE(InputDieEntry), false);
13752357e899Savl-llvm   } else if (InputDieEntry->getTag() == dwarf::DW_TAG_label) {
13762357e899Savl-llvm     // Get relocation adjustment value for the current label.
13772357e899Savl-llvm     std::optional<uint64_t> lowPC =
13782357e899Savl-llvm         dwarf::toAddress(find(InputDieEntry, dwarf::DW_AT_low_pc));
13792357e899Savl-llvm     if (lowPC) {
13802357e899Savl-llvm       LabelMapTy::iterator It = Labels.find(*lowPC);
13812357e899Savl-llvm       if (It != Labels.end())
13822357e899Savl-llvm         FuncAddressAdjustment = It->second;
13832357e899Savl-llvm     }
13842357e899Savl-llvm   } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) {
13852357e899Savl-llvm     // Get relocation adjustment value for the current variable.
13862357e899Savl-llvm     std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
13872357e899Savl-llvm         getContaingFile().Addresses->getVariableRelocAdjustment(
13880ed81942SAlexey Lapshin             getDIE(InputDieEntry), false);
13892357e899Savl-llvm 
13902357e899Savl-llvm     HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
13912357e899Savl-llvm     if (LocExprAddrAndRelocAdjustment.first &&
13922357e899Savl-llvm         LocExprAddrAndRelocAdjustment.second)
13932357e899Savl-llvm       VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
13942357e899Savl-llvm   }
13952357e899Savl-llvm 
13962357e899Savl-llvm   ClonedDIE = PlainDIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset);
13972357e899Savl-llvm 
13982357e899Savl-llvm   // Offset to the DIE would be used after output DIE tree is deleted.
13992357e899Savl-llvm   // Thus we need to remember DIE offset separately.
14002357e899Savl-llvm   rememberDieOutOffset(InputDieIdx, OutOffset);
14012357e899Savl-llvm 
14022357e899Savl-llvm   // Clone Attributes.
14032357e899Savl-llvm   DIEAttributeCloner AttributesCloner(ClonedDIE, *this, this, InputDieEntry,
14042357e899Savl-llvm                                       PlainDIEGenerator, FuncAddressAdjustment,
14052357e899Savl-llvm                                       VarAddressAdjustment,
14062357e899Savl-llvm                                       HasLocationExpressionAddress);
14072357e899Savl-llvm   AttributesCloner.clone();
14082357e899Savl-llvm 
14092357e899Savl-llvm   // Remember accelerator info.
14102357e899Savl-llvm   AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, this);
14112357e899Savl-llvm   AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
14122357e899Savl-llvm                          nullptr);
14132357e899Savl-llvm 
14142357e899Savl-llvm   OutOffset =
14152357e899Savl-llvm       AttributesCloner.finalizeAbbreviations(Info.getKeepPlainChildren());
14162357e899Savl-llvm 
14172357e899Savl-llvm   return ClonedDIE;
14182357e899Savl-llvm }
14192357e899Savl-llvm 
14202357e899Savl-llvm /// Allocates output DIE for the specified \p TypeDescriptor.
14212357e899Savl-llvm DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
14222357e899Savl-llvm                                   DIEGenerator &TypeDIEGenerator,
14232357e899Savl-llvm                                   dwarf::Tag DieTag, bool IsDeclaration,
14242357e899Savl-llvm                                   bool IsParentDeclaration) {
14252357e899Savl-llvm   DIE *DefinitionDie = TypeDescriptor->Die;
14262357e899Savl-llvm   // Do not allocate any new DIE if definition DIE is already met.
14272357e899Savl-llvm   if (DefinitionDie)
14282357e899Savl-llvm     return nullptr;
14292357e899Savl-llvm 
14302357e899Savl-llvm   DIE *DeclarationDie = TypeDescriptor->DeclarationDie;
14312357e899Savl-llvm   bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration;
14322357e899Savl-llvm 
14332357e899Savl-llvm   if (IsDeclaration && !DeclarationDie) {
14342357e899Savl-llvm     // Alocate declaration DIE.
14352357e899Savl-llvm     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
14362357e899Savl-llvm     if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
14372357e899Savl-llvm                                                              NewDie))
14382357e899Savl-llvm       return NewDie;
14392357e899Savl-llvm   } else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
14402357e899Savl-llvm     // Overwrite existing declaration DIE if it's parent is also an declaration
14412357e899Savl-llvm     // while parent of current declaration DIE is a definition.
14422357e899Savl-llvm     if (TypeDescriptor->ParentIsDeclaration.compare_exchange_weak(
14432357e899Savl-llvm             OldParentIsDeclaration, false)) {
14442357e899Savl-llvm       DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
14452357e899Savl-llvm       TypeDescriptor->DeclarationDie = NewDie;
14462357e899Savl-llvm       return NewDie;
14472357e899Savl-llvm     }
14482357e899Savl-llvm   } else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
14492357e899Savl-llvm     // Alocate declaration DIE since parent of current DIE is marked as
14502357e899Savl-llvm     // declaration.
14512357e899Savl-llvm     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
14522357e899Savl-llvm     if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
14532357e899Savl-llvm                                                              NewDie))
14542357e899Savl-llvm       return NewDie;
14552357e899Savl-llvm   } else if (!IsDeclaration && !IsParentDeclaration) {
14562357e899Savl-llvm     // Allocate definition DIE.
14572357e899Savl-llvm     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
14582357e899Savl-llvm     if (TypeDescriptor->Die.compare_exchange_weak(DefinitionDie, NewDie)) {
14592357e899Savl-llvm       TypeDescriptor->ParentIsDeclaration = false;
14602357e899Savl-llvm       return NewDie;
14612357e899Savl-llvm     }
14622357e899Savl-llvm   }
14632357e899Savl-llvm 
14642357e899Savl-llvm   return nullptr;
14652357e899Savl-llvm }
14662357e899Savl-llvm 
14672357e899Savl-llvm TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
14682357e899Savl-llvm     const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,
14692357e899Savl-llvm     TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit) {
14702357e899Savl-llvm   assert(ArtificialTypeUnit != nullptr);
14712357e899Savl-llvm   uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
14722357e899Savl-llvm 
14732357e899Savl-llvm   TypeEntry *Entry = getDieTypeEntry(InputDieIdx);
14742357e899Savl-llvm   assert(Entry != nullptr);
14752357e899Savl-llvm   assert(ClonedParentTypeDIE != nullptr);
14762357e899Savl-llvm   TypeEntryBody *EntryBody =
14772357e899Savl-llvm       ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody(
14782357e899Savl-llvm           Entry, ClonedParentTypeDIE);
14792357e899Savl-llvm   assert(EntryBody);
14802357e899Savl-llvm 
14812357e899Savl-llvm   bool IsDeclaration =
14822357e899Savl-llvm       dwarf::toUnsigned(find(InputDieEntry, dwarf::DW_AT_declaration), 0);
14832357e899Savl-llvm 
14842357e899Savl-llvm   bool ParentIsDeclaration = false;
14852357e899Savl-llvm   if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx())
14862357e899Savl-llvm     ParentIsDeclaration =
14872357e899Savl-llvm         dwarf::toUnsigned(find(*ParentIdx, dwarf::DW_AT_declaration), 0);
14882357e899Savl-llvm 
14892357e899Savl-llvm   DIE *OutDIE =
14902357e899Savl-llvm       allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->getTag(),
14912357e899Savl-llvm                       IsDeclaration, ParentIsDeclaration);
14922357e899Savl-llvm 
14932357e899Savl-llvm   if (OutDIE != nullptr) {
14942357e899Savl-llvm     assert(ArtificialTypeUnit != nullptr);
14952357e899Savl-llvm     ArtificialTypeUnit->getSectionDescriptor(DebugSectionKind::DebugInfo);
14962357e899Savl-llvm 
14972357e899Savl-llvm     DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit,
14982357e899Savl-llvm                                         InputDieEntry, TypeDIEGenerator,
14992357e899Savl-llvm                                         std::nullopt, std::nullopt, false);
15002357e899Savl-llvm     AttributesCloner.clone();
15012357e899Savl-llvm 
15022357e899Savl-llvm     // Remember accelerator info.
15032357e899Savl-llvm     AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,
15042357e899Savl-llvm                                               ArtificialTypeUnit);
15052357e899Savl-llvm     AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
15062357e899Savl-llvm                            Entry);
15072357e899Savl-llvm 
15082357e899Savl-llvm     // if AttributesCloner.getOutOffset() == 0 then we need to add
15092357e899Savl-llvm     // 1 to avoid assertion for zero size. We will subtract it back later.
15102357e899Savl-llvm     OutDIE->setSize(AttributesCloner.getOutOffset() + 1);
15112357e899Savl-llvm   }
15122357e899Savl-llvm 
15132357e899Savl-llvm   return Entry;
15142357e899Savl-llvm }
15152357e899Savl-llvm 
15169ff4be64SAlexey Lapshin Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) {
15172357e899Savl-llvm   const DWARFDebugLine::LineTable *InputLineTable =
15182357e899Savl-llvm       getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());
15192357e899Savl-llvm   if (InputLineTable == nullptr) {
15202357e899Savl-llvm     if (getOrigUnit().getUnitDIE().find(dwarf::DW_AT_stmt_list))
15212357e899Savl-llvm       warn("cann't load line table.");
15222357e899Savl-llvm     return Error::success();
15232357e899Savl-llvm   }
15242357e899Savl-llvm 
15252357e899Savl-llvm   DWARFDebugLine::LineTable OutLineTable;
15262357e899Savl-llvm 
15272357e899Savl-llvm   // Set Line Table header.
15282357e899Savl-llvm   OutLineTable.Prologue = InputLineTable->Prologue;
15292357e899Savl-llvm   OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize;
15302357e899Savl-llvm 
15312357e899Savl-llvm   // Set Line Table Rows.
15322357e899Savl-llvm   if (getGlobalData().getOptions().UpdateIndexTablesOnly) {
15332357e899Savl-llvm     OutLineTable.Rows = InputLineTable->Rows;
15342357e899Savl-llvm     // If all the line table contains is a DW_LNE_end_sequence, clear the line
15352357e899Savl-llvm     // table rows, it will be inserted again in the DWARFStreamer.
15362357e899Savl-llvm     if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence)
15372357e899Savl-llvm       OutLineTable.Rows.clear();
15382357e899Savl-llvm 
15392357e899Savl-llvm     OutLineTable.Sequences = InputLineTable->Sequences;
15402357e899Savl-llvm   } else {
15412357e899Savl-llvm     // This vector is the output line table.
15422357e899Savl-llvm     std::vector<DWARFDebugLine::Row> NewRows;
15432357e899Savl-llvm     NewRows.reserve(InputLineTable->Rows.size());
15442357e899Savl-llvm 
15452357e899Savl-llvm     // Current sequence of rows being extracted, before being inserted
15462357e899Savl-llvm     // in NewRows.
15472357e899Savl-llvm     std::vector<DWARFDebugLine::Row> Seq;
15482357e899Savl-llvm 
15492357e899Savl-llvm     const auto &FunctionRanges = getFunctionRanges();
15502357e899Savl-llvm     std::optional<AddressRangeValuePair> CurrRange;
15512357e899Savl-llvm 
15522357e899Savl-llvm     // FIXME: This logic is meant to generate exactly the same output as
15532357e899Savl-llvm     // Darwin's classic dsymutil. There is a nicer way to implement this
15542357e899Savl-llvm     // by simply putting all the relocated line info in NewRows and simply
15552357e899Savl-llvm     // sorting NewRows before passing it to emitLineTableForUnit. This
15562357e899Savl-llvm     // should be correct as sequences for a function should stay
15572357e899Savl-llvm     // together in the sorted output. There are a few corner cases that
15582357e899Savl-llvm     // look suspicious though, and that required to implement the logic
15592357e899Savl-llvm     // this way. Revisit that once initial validation is finished.
15602357e899Savl-llvm 
15612357e899Savl-llvm     // Iterate over the object file line info and extract the sequences
15622357e899Savl-llvm     // that correspond to linked functions.
15632357e899Savl-llvm     for (DWARFDebugLine::Row Row : InputLineTable->Rows) {
15642357e899Savl-llvm       // Check whether we stepped out of the range. The range is
15652357e899Savl-llvm       // half-open, but consider accept the end address of the range if
15662357e899Savl-llvm       // it is marked as end_sequence in the input (because in that
15672357e899Savl-llvm       // case, the relocation offset is accurate and that entry won't
15682357e899Savl-llvm       // serve as the start of another function).
15692357e899Savl-llvm       if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
15702357e899Savl-llvm         // We just stepped out of a known range. Insert a end_sequence
15712357e899Savl-llvm         // corresponding to the end of the range.
15722357e899Savl-llvm         uint64_t StopAddress =
15732357e899Savl-llvm             CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
15742357e899Savl-llvm         CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
15752357e899Savl-llvm         if (StopAddress != -1ULL && !Seq.empty()) {
15762357e899Savl-llvm           // Insert end sequence row with the computed end address, but
15772357e899Savl-llvm           // the same line as the previous one.
15782357e899Savl-llvm           auto NextLine = Seq.back();
15792357e899Savl-llvm           NextLine.Address.Address = StopAddress;
15802357e899Savl-llvm           NextLine.EndSequence = 1;
15812357e899Savl-llvm           NextLine.PrologueEnd = 0;
15822357e899Savl-llvm           NextLine.BasicBlock = 0;
15832357e899Savl-llvm           NextLine.EpilogueBegin = 0;
15842357e899Savl-llvm           Seq.push_back(NextLine);
15852357e899Savl-llvm           insertLineSequence(Seq, NewRows);
15862357e899Savl-llvm         }
15872357e899Savl-llvm 
15882357e899Savl-llvm         if (!CurrRange)
15892357e899Savl-llvm           continue;
15902357e899Savl-llvm       }
15912357e899Savl-llvm 
15922357e899Savl-llvm       // Ignore empty sequences.
15932357e899Savl-llvm       if (Row.EndSequence && Seq.empty())
15942357e899Savl-llvm         continue;
15952357e899Savl-llvm 
15962357e899Savl-llvm       // Relocate row address and add it to the current sequence.
15972357e899Savl-llvm       Row.Address.Address += CurrRange->Value;
15982357e899Savl-llvm       Seq.emplace_back(Row);
15992357e899Savl-llvm 
16002357e899Savl-llvm       if (Row.EndSequence)
16012357e899Savl-llvm         insertLineSequence(Seq, NewRows);
16022357e899Savl-llvm     }
16032357e899Savl-llvm 
16042357e899Savl-llvm     OutLineTable.Rows = std::move(NewRows);
16052357e899Savl-llvm   }
16062357e899Savl-llvm 
16072357e899Savl-llvm   return emitDebugLine(TargetTriple, OutLineTable);
16082357e899Savl-llvm }
16092357e899Savl-llvm 
16102357e899Savl-llvm void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
16112357e899Savl-llvm                                      std::vector<DWARFDebugLine::Row> &Rows) {
16122357e899Savl-llvm   if (Seq.empty())
16132357e899Savl-llvm     return;
16142357e899Savl-llvm 
16152357e899Savl-llvm   if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
16162357e899Savl-llvm     llvm::append_range(Rows, Seq);
16172357e899Savl-llvm     Seq.clear();
16182357e899Savl-llvm     return;
16192357e899Savl-llvm   }
16202357e899Savl-llvm 
16212357e899Savl-llvm   object::SectionedAddress Front = Seq.front().Address;
16222357e899Savl-llvm   auto InsertPoint = partition_point(
16232357e899Savl-llvm       Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });
16242357e899Savl-llvm 
16252357e899Savl-llvm   // FIXME: this only removes the unneeded end_sequence if the
16262357e899Savl-llvm   // sequences have been inserted in order. Using a global sort like
16272357e899Savl-llvm   // described in cloneAndEmitLineTable() and delaying the end_sequene
16282357e899Savl-llvm   // elimination to DebugLineEmitter::emit() we can get rid of all of them.
16292357e899Savl-llvm   if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
16302357e899Savl-llvm       InsertPoint->EndSequence) {
16312357e899Savl-llvm     *InsertPoint = Seq.front();
16322357e899Savl-llvm     Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
16332357e899Savl-llvm   } else {
16342357e899Savl-llvm     Rows.insert(InsertPoint, Seq.begin(), Seq.end());
16352357e899Savl-llvm   }
16362357e899Savl-llvm 
16372357e899Savl-llvm   Seq.clear();
16382357e899Savl-llvm }
16392357e899Savl-llvm 
16402357e899Savl-llvm #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
16412357e899Savl-llvm LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() {
16422357e899Savl-llvm   llvm::errs() << "{";
16432357e899Savl-llvm   llvm::errs() << "  Placement: ";
16442357e899Savl-llvm   switch (getPlacement()) {
16452357e899Savl-llvm   case NotSet:
16462357e899Savl-llvm     llvm::errs() << "NotSet";
16472357e899Savl-llvm     break;
16482357e899Savl-llvm   case TypeTable:
16492357e899Savl-llvm     llvm::errs() << "TypeTable";
16502357e899Savl-llvm     break;
16512357e899Savl-llvm   case PlainDwarf:
16522357e899Savl-llvm     llvm::errs() << "PlainDwarf";
16532357e899Savl-llvm     break;
16542357e899Savl-llvm   case Both:
16552357e899Savl-llvm     llvm::errs() << "Both";
16562357e899Savl-llvm     break;
16572357e899Savl-llvm   }
16582357e899Savl-llvm 
16592357e899Savl-llvm   llvm::errs() << "  Keep: " << getKeep();
16602357e899Savl-llvm   llvm::errs() << "  KeepPlainChildren: " << getKeepPlainChildren();
16612357e899Savl-llvm   llvm::errs() << "  KeepTypeChildren: " << getKeepTypeChildren();
16622357e899Savl-llvm   llvm::errs() << "  IsInMouduleScope: " << getIsInMouduleScope();
16632357e899Savl-llvm   llvm::errs() << "  IsInFunctionScope: " << getIsInFunctionScope();
16642357e899Savl-llvm   llvm::errs() << "  IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
16652357e899Savl-llvm   llvm::errs() << "  ODRAvailable: " << getODRAvailable();
16662357e899Savl-llvm   llvm::errs() << "  TrackLiveness: " << getTrackLiveness();
16672357e899Savl-llvm   llvm::errs() << "}\n";
16682357e899Savl-llvm }
16692357e899Savl-llvm #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
16702357e899Savl-llvm 
16712357e899Savl-llvm std::optional<std::pair<StringRef, StringRef>>
16722357e899Savl-llvm CompileUnit::getDirAndFilenameFromLineTable(
16732357e899Savl-llvm     const DWARFFormValue &FileIdxValue) {
16742357e899Savl-llvm   uint64_t FileIdx;
16752357e899Savl-llvm   if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant())
16762357e899Savl-llvm     FileIdx = *Val;
16772357e899Savl-llvm   else if (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant())
16782357e899Savl-llvm     FileIdx = *Val;
16792357e899Savl-llvm   else if (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset())
16802357e899Savl-llvm     FileIdx = *Val;
16812357e899Savl-llvm   else
16822357e899Savl-llvm     return std::nullopt;
16832357e899Savl-llvm 
16842357e899Savl-llvm   return getDirAndFilenameFromLineTable(FileIdx);
16852357e899Savl-llvm }
16862357e899Savl-llvm 
16872357e899Savl-llvm std::optional<std::pair<StringRef, StringRef>>
16882357e899Savl-llvm CompileUnit::getDirAndFilenameFromLineTable(uint64_t FileIdx) {
16892357e899Savl-llvm   FileNamesCache::iterator FileData = FileNames.find(FileIdx);
16902357e899Savl-llvm   if (FileData != FileNames.end())
16912357e899Savl-llvm     return std::make_pair(StringRef(FileData->second.first),
16922357e899Savl-llvm                           StringRef(FileData->second.second));
16932357e899Savl-llvm 
16942357e899Savl-llvm   if (const DWARFDebugLine::LineTable *LineTable =
16952357e899Savl-llvm           getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) {
16962357e899Savl-llvm     if (LineTable->hasFileAtIndex(FileIdx)) {
16972357e899Savl-llvm 
16982357e899Savl-llvm       const llvm::DWARFDebugLine::FileNameEntry &Entry =
16992357e899Savl-llvm           LineTable->Prologue.getFileNameEntry(FileIdx);
17002357e899Savl-llvm 
17012357e899Savl-llvm       Expected<const char *> Name = Entry.Name.getAsCString();
17022357e899Savl-llvm       if (!Name) {
17032357e899Savl-llvm         warn(Name.takeError());
17042357e899Savl-llvm         return std::nullopt;
17052357e899Savl-llvm       }
17062357e899Savl-llvm 
17072357e899Savl-llvm       std::string FileName = *Name;
17082357e899Savl-llvm       if (isPathAbsoluteOnWindowsOrPosix(FileName)) {
17092357e899Savl-llvm         FileNamesCache::iterator FileData =
17102357e899Savl-llvm             FileNames
17112357e899Savl-llvm                 .insert(std::make_pair(
17122357e899Savl-llvm                     FileIdx,
17132357e899Savl-llvm                     std::make_pair(std::string(""), std::move(FileName))))
17142357e899Savl-llvm                 .first;
17152357e899Savl-llvm         return std::make_pair(StringRef(FileData->second.first),
17162357e899Savl-llvm                               StringRef(FileData->second.second));
17172357e899Savl-llvm       }
17182357e899Savl-llvm 
17192357e899Savl-llvm       SmallString<256> FilePath;
17202357e899Savl-llvm       StringRef IncludeDir;
17212357e899Savl-llvm       // Be defensive about the contents of Entry.
17222357e899Savl-llvm       if (getVersion() >= 5) {
17232357e899Savl-llvm         // DirIdx 0 is the compilation directory, so don't include it for
17242357e899Savl-llvm         // relative names.
17252357e899Savl-llvm         if ((Entry.DirIdx != 0) &&
17262357e899Savl-llvm             Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
17272357e899Savl-llvm           Expected<const char *> DirName =
17282357e899Savl-llvm               LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
17292357e899Savl-llvm                   .getAsCString();
17302357e899Savl-llvm           if (DirName)
17312357e899Savl-llvm             IncludeDir = *DirName;
17322357e899Savl-llvm           else {
17332357e899Savl-llvm             warn(DirName.takeError());
17342357e899Savl-llvm             return std::nullopt;
17352357e899Savl-llvm           }
17362357e899Savl-llvm         }
17372357e899Savl-llvm       } else {
17382357e899Savl-llvm         if (0 < Entry.DirIdx &&
17392357e899Savl-llvm             Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
17402357e899Savl-llvm           Expected<const char *> DirName =
17412357e899Savl-llvm               LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
17422357e899Savl-llvm                   .getAsCString();
17432357e899Savl-llvm           if (DirName)
17442357e899Savl-llvm             IncludeDir = *DirName;
17452357e899Savl-llvm           else {
17462357e899Savl-llvm             warn(DirName.takeError());
17472357e899Savl-llvm             return std::nullopt;
17482357e899Savl-llvm           }
17492357e899Savl-llvm         }
17502357e899Savl-llvm       }
17512357e899Savl-llvm 
17522357e899Savl-llvm       StringRef CompDir = getOrigUnit().getCompilationDir();
17532357e899Savl-llvm 
17542357e899Savl-llvm       if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) {
17552357e899Savl-llvm         sys::path::append(FilePath, sys::path::Style::native, CompDir);
17562357e899Savl-llvm       }
17572357e899Savl-llvm 
17582357e899Savl-llvm       sys::path::append(FilePath, sys::path::Style::native, IncludeDir);
17592357e899Savl-llvm 
17602357e899Savl-llvm       FileNamesCache::iterator FileData =
17612357e899Savl-llvm           FileNames
17622357e899Savl-llvm               .insert(
17632357e899Savl-llvm                   std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
17642357e899Savl-llvm                                                          std::move(FileName))))
17652357e899Savl-llvm               .first;
17662357e899Savl-llvm       return std::make_pair(StringRef(FileData->second.first),
17672357e899Savl-llvm                             StringRef(FileData->second.second));
17682357e899Savl-llvm     }
17692357e899Savl-llvm   }
17702357e899Savl-llvm 
17712357e899Savl-llvm   return std::nullopt;
17722357e899Savl-llvm }
17732357e899Savl-llvm 
17742357e899Savl-llvm #define MAX_REFERENCIES_DEPTH 1000
17752357e899Savl-llvm UnitEntryPairTy UnitEntryPairTy::getNamespaceOrigin() {
17762357e899Savl-llvm   UnitEntryPairTy CUDiePair(*this);
17772357e899Savl-llvm   std::optional<UnitEntryPairTy> RefDiePair;
17782357e899Savl-llvm   int refDepth = 0;
17792357e899Savl-llvm   do {
17802357e899Savl-llvm     RefDiePair = CUDiePair.CU->resolveDIEReference(
17812357e899Savl-llvm         CUDiePair.DieEntry, dwarf::DW_AT_extension,
17822357e899Savl-llvm         ResolveInterCUReferencesMode::Resolve);
17832357e899Savl-llvm     if (!RefDiePair || !RefDiePair->DieEntry)
17842357e899Savl-llvm       return CUDiePair;
17852357e899Savl-llvm 
17862357e899Savl-llvm     CUDiePair = *RefDiePair;
17872357e899Savl-llvm   } while (refDepth++ < MAX_REFERENCIES_DEPTH);
17882357e899Savl-llvm 
17892357e899Savl-llvm   return CUDiePair;
17902357e899Savl-llvm }
17912357e899Savl-llvm 
17922357e899Savl-llvm std::optional<UnitEntryPairTy> UnitEntryPairTy::getParent() {
17932357e899Savl-llvm   if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx())
17942357e899Savl-llvm     return UnitEntryPairTy{CU, CU->getDebugInfoEntry(*ParentIdx)};
17952357e899Savl-llvm 
17962357e899Savl-llvm   return std::nullopt;
17972357e899Savl-llvm }
17982357e899Savl-llvm 
17992357e899Savl-llvm CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit *U)
18002357e899Savl-llvm     : Ptr(U) {
18012357e899Savl-llvm   assert(U != nullptr);
18022357e899Savl-llvm }
18032357e899Savl-llvm 
18042357e899Savl-llvm CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit *U) : Ptr(U) {
18052357e899Savl-llvm   assert(U != nullptr);
18062357e899Savl-llvm }
18072357e899Savl-llvm 
18082357e899Savl-llvm DwarfUnit *CompileUnit::OutputUnitVariantPtr::operator->() {
18092357e899Savl-llvm   if (isCompileUnit())
18102357e899Savl-llvm     return getAsCompileUnit();
18112357e899Savl-llvm   else
18122357e899Savl-llvm     return getAsTypeUnit();
18132357e899Savl-llvm }
18142357e899Savl-llvm 
18152357e899Savl-llvm bool CompileUnit::OutputUnitVariantPtr::isCompileUnit() {
1816*2f8238f8SKazu Hirata   return isa<CompileUnit *>(Ptr);
18172357e899Savl-llvm }
18182357e899Savl-llvm 
18192357e899Savl-llvm bool CompileUnit::OutputUnitVariantPtr::isTypeUnit() {
1820*2f8238f8SKazu Hirata   return isa<TypeUnit *>(Ptr);
18212357e899Savl-llvm }
18222357e899Savl-llvm 
18232357e899Savl-llvm CompileUnit *CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() {
1824*2f8238f8SKazu Hirata   return cast<CompileUnit *>(Ptr);
18252357e899Savl-llvm }
18262357e899Savl-llvm 
18272357e899Savl-llvm TypeUnit *CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() {
1828*2f8238f8SKazu Hirata   return cast<TypeUnit *>(Ptr);
18292357e899Savl-llvm }
18302357e899Savl-llvm 
18312357e899Savl-llvm bool CompileUnit::resolveDependenciesAndMarkLiveness(
18322357e899Savl-llvm     bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1833acd7a688SKazu Hirata   if (!Dependencies)
18342357e899Savl-llvm     Dependencies.reset(new DependencyTracker(*this));
18352357e899Savl-llvm 
18362357e899Savl-llvm   return Dependencies->resolveDependenciesAndMarkLiveness(
18372357e899Savl-llvm       InterCUProcessingStarted, HasNewInterconnectedCUs);
18382357e899Savl-llvm }
18392357e899Savl-llvm 
18402357e899Savl-llvm bool CompileUnit::updateDependenciesCompleteness() {
18412357e899Savl-llvm   assert(Dependencies.get());
18422357e899Savl-llvm 
184375bc20ffSKazu Hirata   return Dependencies->updateDependenciesCompleteness();
18442357e899Savl-llvm }
18452357e899Savl-llvm 
18462357e899Savl-llvm void CompileUnit::verifyDependencies() {
18472357e899Savl-llvm   assert(Dependencies.get());
18482357e899Savl-llvm 
184975bc20ffSKazu Hirata   Dependencies->verifyKeepChain();
18502357e899Savl-llvm }
18512357e899Savl-llvm 
18522357e899Savl-llvm ArrayRef<dwarf::Attribute> dwarf_linker::parallel::getODRAttributes() {
18532357e899Savl-llvm   static dwarf::Attribute ODRAttributes[] = {
18542357e899Savl-llvm       dwarf::DW_AT_type, dwarf::DW_AT_specification,
18552357e899Savl-llvm       dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};
18562357e899Savl-llvm 
18572357e899Savl-llvm   return ODRAttributes;
18582357e899Savl-llvm }
1859