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