11db9f3b2SDimitry Andric //===- DWARFLinkerCompileUnit.h ---------------------------------*- C++ -*-===// 21db9f3b2SDimitry Andric // 31db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 51db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61db9f3b2SDimitry Andric // 71db9f3b2SDimitry Andric //===----------------------------------------------------------------------===// 81db9f3b2SDimitry Andric 91db9f3b2SDimitry Andric #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H 101db9f3b2SDimitry Andric #define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H 111db9f3b2SDimitry Andric 121db9f3b2SDimitry Andric #include "DWARFLinkerUnit.h" 131db9f3b2SDimitry Andric #include "llvm/DWARFLinker/DWARFFile.h" 141db9f3b2SDimitry Andric #include <optional> 151db9f3b2SDimitry Andric 161db9f3b2SDimitry Andric namespace llvm { 171db9f3b2SDimitry Andric namespace dwarf_linker { 181db9f3b2SDimitry Andric namespace parallel { 191db9f3b2SDimitry Andric 201db9f3b2SDimitry Andric using OffsetToUnitTy = function_ref<CompileUnit *(uint64_t Offset)>; 211db9f3b2SDimitry Andric 221db9f3b2SDimitry Andric struct AttributesInfo; 231db9f3b2SDimitry Andric class SyntheticTypeNameBuilder; 241db9f3b2SDimitry Andric class DIEGenerator; 251db9f3b2SDimitry Andric class TypeUnit; 261db9f3b2SDimitry Andric class DependencyTracker; 271db9f3b2SDimitry Andric 281db9f3b2SDimitry Andric class CompileUnit; 291db9f3b2SDimitry Andric 301db9f3b2SDimitry Andric /// This is a helper structure which keeps a debug info entry 311db9f3b2SDimitry Andric /// with it's containing compilation unit. 321db9f3b2SDimitry Andric struct UnitEntryPairTy { 331db9f3b2SDimitry Andric UnitEntryPairTy() = default; UnitEntryPairTyUnitEntryPairTy341db9f3b2SDimitry Andric UnitEntryPairTy(CompileUnit *CU, const DWARFDebugInfoEntry *DieEntry) 351db9f3b2SDimitry Andric : CU(CU), DieEntry(DieEntry) {} 361db9f3b2SDimitry Andric 371db9f3b2SDimitry Andric CompileUnit *CU = nullptr; 381db9f3b2SDimitry Andric const DWARFDebugInfoEntry *DieEntry = nullptr; 391db9f3b2SDimitry Andric 401db9f3b2SDimitry Andric UnitEntryPairTy getNamespaceOrigin(); 411db9f3b2SDimitry Andric std::optional<UnitEntryPairTy> getParent(); 421db9f3b2SDimitry Andric }; 431db9f3b2SDimitry Andric 441db9f3b2SDimitry Andric enum ResolveInterCUReferencesMode : bool { 451db9f3b2SDimitry Andric Resolve = true, 461db9f3b2SDimitry Andric AvoidResolving = false, 471db9f3b2SDimitry Andric }; 481db9f3b2SDimitry Andric 491db9f3b2SDimitry Andric /// Stores all information related to a compile unit, be it in its original 501db9f3b2SDimitry Andric /// instance of the object file or its brand new cloned and generated DIE tree. 511db9f3b2SDimitry Andric /// NOTE: we need alignment of at least 8 bytes as we use 521db9f3b2SDimitry Andric /// PointerIntPair<CompileUnit *, 3> in the DependencyTracker.h 531db9f3b2SDimitry Andric class alignas(8) CompileUnit : public DwarfUnit { 541db9f3b2SDimitry Andric public: 551db9f3b2SDimitry Andric /// The stages of new compile unit processing. 561db9f3b2SDimitry Andric enum class Stage : uint8_t { 571db9f3b2SDimitry Andric /// Created, linked with input DWARF file. 581db9f3b2SDimitry Andric CreatedNotLoaded = 0, 591db9f3b2SDimitry Andric 601db9f3b2SDimitry Andric /// Input DWARF is loaded. 611db9f3b2SDimitry Andric Loaded, 621db9f3b2SDimitry Andric 631db9f3b2SDimitry Andric /// Input DWARF is analysed(DIEs pointing to the real code section are 641db9f3b2SDimitry Andric /// discovered, type names are assigned if ODR is requested). 651db9f3b2SDimitry Andric LivenessAnalysisDone, 661db9f3b2SDimitry Andric 671db9f3b2SDimitry Andric /// Check if dependencies have incompatible placement. 681db9f3b2SDimitry Andric /// If that is the case modify placement to be compatible. 691db9f3b2SDimitry Andric UpdateDependenciesCompleteness, 701db9f3b2SDimitry Andric 711db9f3b2SDimitry Andric /// Type names assigned to DIEs. 721db9f3b2SDimitry Andric TypeNamesAssigned, 731db9f3b2SDimitry Andric 741db9f3b2SDimitry Andric /// Output DWARF is generated. 751db9f3b2SDimitry Andric Cloned, 761db9f3b2SDimitry Andric 771db9f3b2SDimitry Andric /// Offsets inside patch records are updated. 781db9f3b2SDimitry Andric PatchesUpdated, 791db9f3b2SDimitry Andric 801db9f3b2SDimitry Andric /// Resources(Input DWARF, Output DWARF tree) are released. 811db9f3b2SDimitry Andric Cleaned, 821db9f3b2SDimitry Andric 831db9f3b2SDimitry Andric /// Compile Unit should be skipped 841db9f3b2SDimitry Andric Skipped 851db9f3b2SDimitry Andric }; 861db9f3b2SDimitry Andric 871db9f3b2SDimitry Andric CompileUnit(LinkingGlobalData &GlobalData, unsigned ID, 881db9f3b2SDimitry Andric StringRef ClangModuleName, DWARFFile &File, 891db9f3b2SDimitry Andric OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format, 901db9f3b2SDimitry Andric llvm::endianness Endianess); 911db9f3b2SDimitry Andric 921db9f3b2SDimitry Andric CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit, unsigned ID, 931db9f3b2SDimitry Andric StringRef ClangModuleName, DWARFFile &File, 941db9f3b2SDimitry Andric OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format, 951db9f3b2SDimitry Andric llvm::endianness Endianess); 961db9f3b2SDimitry Andric 971db9f3b2SDimitry Andric /// Returns stage of overall processing. getStage()981db9f3b2SDimitry Andric Stage getStage() const { return Stage; } 991db9f3b2SDimitry Andric 1001db9f3b2SDimitry Andric /// Set stage of overall processing. setStage(Stage Stage)1011db9f3b2SDimitry Andric void setStage(Stage Stage) { this->Stage = Stage; } 1021db9f3b2SDimitry Andric 1031db9f3b2SDimitry Andric /// Loads unit line table. 1041db9f3b2SDimitry Andric void loadLineTable(); 1051db9f3b2SDimitry Andric 1061db9f3b2SDimitry Andric /// Returns name of the file for the \p FileIdx 1071db9f3b2SDimitry Andric /// from the unit`s line table. 1081db9f3b2SDimitry Andric StringEntry *getFileName(unsigned FileIdx, StringPool &GlobalStrings); 1091db9f3b2SDimitry Andric 1101db9f3b2SDimitry Andric /// Returns DWARFFile containing this compile unit. getContaingFile()1111db9f3b2SDimitry Andric const DWARFFile &getContaingFile() const { return File; } 1121db9f3b2SDimitry Andric 1131db9f3b2SDimitry Andric /// Load DIEs of input compilation unit. \returns true if input DIEs 1141db9f3b2SDimitry Andric /// successfully loaded. 1151db9f3b2SDimitry Andric bool loadInputDIEs(); 1161db9f3b2SDimitry Andric 1171db9f3b2SDimitry Andric /// Reset compile units data(results of liveness analysis, clonning) 1181db9f3b2SDimitry Andric /// if current stage greater than Stage::Loaded. We need to reset data 1191db9f3b2SDimitry Andric /// as we are going to repeat stages. 1201db9f3b2SDimitry Andric void maybeResetToLoadedStage(); 1211db9f3b2SDimitry Andric 1221db9f3b2SDimitry Andric /// Collect references to parseable Swift interfaces in imported 1231db9f3b2SDimitry Andric /// DW_TAG_module blocks. 1241db9f3b2SDimitry Andric void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry); 1251db9f3b2SDimitry Andric 1261db9f3b2SDimitry Andric /// Navigate DWARF tree and set die properties. analyzeDWARFStructure()1271db9f3b2SDimitry Andric void analyzeDWARFStructure() { 1281db9f3b2SDimitry Andric analyzeDWARFStructureRec(getUnitDIE().getDebugInfoEntry(), false); 1291db9f3b2SDimitry Andric } 1301db9f3b2SDimitry Andric 1311db9f3b2SDimitry Andric /// Cleanup unneeded resources after compile unit is cloned. 1321db9f3b2SDimitry Andric void cleanupDataAfterClonning(); 1331db9f3b2SDimitry Andric 1341db9f3b2SDimitry Andric /// After cloning stage the output DIEs offsets are deallocated. 1351db9f3b2SDimitry Andric /// This method copies output offsets for referenced DIEs into DIEs patches. 1361db9f3b2SDimitry Andric void updateDieRefPatchesWithClonedOffsets(); 1371db9f3b2SDimitry Andric 1381db9f3b2SDimitry Andric /// Search for subprograms and variables referencing live code and discover 1391db9f3b2SDimitry Andric /// dependend DIEs. Mark live DIEs, set placement for DIEs. 1401db9f3b2SDimitry Andric bool resolveDependenciesAndMarkLiveness( 1411db9f3b2SDimitry Andric bool InterCUProcessingStarted, 1421db9f3b2SDimitry Andric std::atomic<bool> &HasNewInterconnectedCUs); 1431db9f3b2SDimitry Andric 1441db9f3b2SDimitry Andric /// Check dependend DIEs for incompatible placement. 1451db9f3b2SDimitry Andric /// Make placement to be consistent. 1461db9f3b2SDimitry Andric bool updateDependenciesCompleteness(); 1471db9f3b2SDimitry Andric 1481db9f3b2SDimitry Andric /// Check DIEs to have a consistent marking(keep marking, placement marking). 1491db9f3b2SDimitry Andric void verifyDependencies(); 1501db9f3b2SDimitry Andric 1511db9f3b2SDimitry Andric /// Search for type entries and assign names. 1521db9f3b2SDimitry Andric Error assignTypeNames(TypePool &TypePoolRef); 1531db9f3b2SDimitry Andric 1541db9f3b2SDimitry Andric /// Kinds of placement for the output die. 1551db9f3b2SDimitry Andric enum DieOutputPlacement : uint8_t { 1561db9f3b2SDimitry Andric NotSet = 0, 1571db9f3b2SDimitry Andric 1581db9f3b2SDimitry Andric /// Corresponding DIE goes to the type table only. 1591db9f3b2SDimitry Andric TypeTable = 1, 1601db9f3b2SDimitry Andric 1611db9f3b2SDimitry Andric /// Corresponding DIE goes to the plain dwarf only. 1621db9f3b2SDimitry Andric PlainDwarf = 2, 1631db9f3b2SDimitry Andric 1641db9f3b2SDimitry Andric /// Corresponding DIE goes to type table and to plain dwarf. 1651db9f3b2SDimitry Andric Both = 3, 1661db9f3b2SDimitry Andric }; 1671db9f3b2SDimitry Andric 1681db9f3b2SDimitry Andric /// Information gathered about source DIEs. 1691db9f3b2SDimitry Andric struct DIEInfo { 1701db9f3b2SDimitry Andric DIEInfo() = default; DIEInfoDIEInfo1711db9f3b2SDimitry Andric DIEInfo(const DIEInfo &Other) { Flags = Other.Flags.load(); } 1721db9f3b2SDimitry Andric DIEInfo &operator=(const DIEInfo &Other) { 1731db9f3b2SDimitry Andric Flags = Other.Flags.load(); 1741db9f3b2SDimitry Andric return *this; 1751db9f3b2SDimitry Andric } 1761db9f3b2SDimitry Andric 1771db9f3b2SDimitry Andric /// Data member keeping various flags. 1781db9f3b2SDimitry Andric std::atomic<uint16_t> Flags = {0}; 1791db9f3b2SDimitry Andric 1801db9f3b2SDimitry Andric /// \returns Placement kind for the corresponding die. getPlacementDIEInfo1811db9f3b2SDimitry Andric DieOutputPlacement getPlacement() const { 1821db9f3b2SDimitry Andric return DieOutputPlacement(Flags & 0x7); 1831db9f3b2SDimitry Andric } 1841db9f3b2SDimitry Andric 1851db9f3b2SDimitry Andric /// Sets Placement kind for the corresponding die. setPlacementDIEInfo1861db9f3b2SDimitry Andric void setPlacement(DieOutputPlacement Placement) { 1871db9f3b2SDimitry Andric auto InputData = Flags.load(); 1881db9f3b2SDimitry Andric while (!Flags.compare_exchange_weak(InputData, 1891db9f3b2SDimitry Andric ((InputData & ~0x7) | Placement))) { 1901db9f3b2SDimitry Andric } 1911db9f3b2SDimitry Andric } 1921db9f3b2SDimitry Andric 1931db9f3b2SDimitry Andric /// Unsets Placement kind for the corresponding die. unsetPlacementDIEInfo1941db9f3b2SDimitry Andric void unsetPlacement() { 1951db9f3b2SDimitry Andric auto InputData = Flags.load(); 1961db9f3b2SDimitry Andric while (!Flags.compare_exchange_weak(InputData, (InputData & ~0x7))) { 1971db9f3b2SDimitry Andric } 1981db9f3b2SDimitry Andric } 1991db9f3b2SDimitry Andric 2001db9f3b2SDimitry Andric /// Sets Placement kind for the corresponding die. setPlacementIfUnsetDIEInfo2011db9f3b2SDimitry Andric bool setPlacementIfUnset(DieOutputPlacement Placement) { 2021db9f3b2SDimitry Andric auto InputData = Flags.load(); 2031db9f3b2SDimitry Andric if ((InputData & 0x7) == NotSet) 2041db9f3b2SDimitry Andric if (Flags.compare_exchange_weak(InputData, (InputData | Placement))) 2051db9f3b2SDimitry Andric return true; 2061db9f3b2SDimitry Andric 2071db9f3b2SDimitry Andric return false; 2081db9f3b2SDimitry Andric } 2091db9f3b2SDimitry Andric 2101db9f3b2SDimitry Andric #define SINGLE_FLAG_METHODS_SET(Name, Value) \ 2111db9f3b2SDimitry Andric bool get##Name() const { return Flags & Value; } \ 2121db9f3b2SDimitry Andric void set##Name() { \ 2131db9f3b2SDimitry Andric auto InputData = Flags.load(); \ 2141db9f3b2SDimitry Andric while (!Flags.compare_exchange_weak(InputData, InputData | Value)) { \ 2151db9f3b2SDimitry Andric } \ 2161db9f3b2SDimitry Andric } \ 2171db9f3b2SDimitry Andric void unset##Name() { \ 2181db9f3b2SDimitry Andric auto InputData = Flags.load(); \ 2191db9f3b2SDimitry Andric while (!Flags.compare_exchange_weak(InputData, InputData & ~Value)) { \ 2201db9f3b2SDimitry Andric } \ 2211db9f3b2SDimitry Andric } 2221db9f3b2SDimitry Andric 2231db9f3b2SDimitry Andric /// DIE is a part of the linked output. 2241db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(Keep, 0x08) 2251db9f3b2SDimitry Andric 2261db9f3b2SDimitry Andric /// DIE has children which are part of the linked output. 2271db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(KeepPlainChildren, 0x10) 2281db9f3b2SDimitry Andric 2291db9f3b2SDimitry Andric /// DIE has children which are part of the type table. 2301db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(KeepTypeChildren, 0x20) 2311db9f3b2SDimitry Andric 2321db9f3b2SDimitry Andric /// DIE is in module scope. 2331db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(IsInMouduleScope, 0x40) 2341db9f3b2SDimitry Andric 2351db9f3b2SDimitry Andric /// DIE is in function scope. 2361db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(IsInFunctionScope, 0x80) 2371db9f3b2SDimitry Andric 2381db9f3b2SDimitry Andric /// DIE is in anonymous namespace scope. 2391db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(IsInAnonNamespaceScope, 0x100) 2401db9f3b2SDimitry Andric 2411db9f3b2SDimitry Andric /// DIE is available for ODR type deduplication. 2421db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(ODRAvailable, 0x200) 2431db9f3b2SDimitry Andric 2441db9f3b2SDimitry Andric /// Track liveness for the DIE. 2451db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(TrackLiveness, 0x400) 2461db9f3b2SDimitry Andric 2471db9f3b2SDimitry Andric /// Track liveness for the DIE. 2481db9f3b2SDimitry Andric SINGLE_FLAG_METHODS_SET(HasAnAddress, 0x800) 2491db9f3b2SDimitry Andric unsetFlagsWhichSetDuringLiveAnalysisDIEInfo2501db9f3b2SDimitry Andric void unsetFlagsWhichSetDuringLiveAnalysis() { 2511db9f3b2SDimitry Andric auto InputData = Flags.load(); 2521db9f3b2SDimitry Andric while (!Flags.compare_exchange_weak( 2531db9f3b2SDimitry Andric InputData, InputData & ~(0x7 | 0x8 | 0x10 | 0x20))) { 2541db9f3b2SDimitry Andric } 2551db9f3b2SDimitry Andric } 2561db9f3b2SDimitry Andric 2571db9f3b2SDimitry Andric /// Erase all flags. eraseDataDIEInfo2581db9f3b2SDimitry Andric void eraseData() { Flags = 0; } 2591db9f3b2SDimitry Andric 2601db9f3b2SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 2611db9f3b2SDimitry Andric LLVM_DUMP_METHOD void dump(); 2621db9f3b2SDimitry Andric #endif 2631db9f3b2SDimitry Andric needToPlaceInTypeTableDIEInfo2641db9f3b2SDimitry Andric bool needToPlaceInTypeTable() const { 2651db9f3b2SDimitry Andric return (getKeep() && (getPlacement() == CompileUnit::TypeTable || 2661db9f3b2SDimitry Andric getPlacement() == CompileUnit::Both)) || 2671db9f3b2SDimitry Andric getKeepTypeChildren(); 2681db9f3b2SDimitry Andric } 2691db9f3b2SDimitry Andric needToKeepInPlainDwarfDIEInfo2701db9f3b2SDimitry Andric bool needToKeepInPlainDwarf() const { 2711db9f3b2SDimitry Andric return (getKeep() && (getPlacement() == CompileUnit::PlainDwarf || 2721db9f3b2SDimitry Andric getPlacement() == CompileUnit::Both)) || 2731db9f3b2SDimitry Andric getKeepPlainChildren(); 2741db9f3b2SDimitry Andric } 2751db9f3b2SDimitry Andric }; 2761db9f3b2SDimitry Andric 2771db9f3b2SDimitry Andric /// \defgroup Group of functions returning DIE info. 2781db9f3b2SDimitry Andric /// 2791db9f3b2SDimitry Andric /// @{ 2801db9f3b2SDimitry Andric 2811db9f3b2SDimitry Andric /// \p Idx index of the DIE. 2821db9f3b2SDimitry Andric /// \returns DieInfo descriptor. getDIEInfo(unsigned Idx)2831db9f3b2SDimitry Andric DIEInfo &getDIEInfo(unsigned Idx) { return DieInfoArray[Idx]; } 2841db9f3b2SDimitry Andric 2851db9f3b2SDimitry Andric /// \p Idx index of the DIE. 2861db9f3b2SDimitry Andric /// \returns DieInfo descriptor. getDIEInfo(unsigned Idx)2871db9f3b2SDimitry Andric const DIEInfo &getDIEInfo(unsigned Idx) const { return DieInfoArray[Idx]; } 2881db9f3b2SDimitry Andric 2891db9f3b2SDimitry Andric /// \p Idx index of the DIE. 2901db9f3b2SDimitry Andric /// \returns DieInfo descriptor. getDIEInfo(const DWARFDebugInfoEntry * Entry)2911db9f3b2SDimitry Andric DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) { 2921db9f3b2SDimitry Andric return DieInfoArray[getOrigUnit().getDIEIndex(Entry)]; 2931db9f3b2SDimitry Andric } 2941db9f3b2SDimitry Andric 2951db9f3b2SDimitry Andric /// \p Idx index of the DIE. 2961db9f3b2SDimitry Andric /// \returns DieInfo descriptor. getDIEInfo(const DWARFDebugInfoEntry * Entry)2971db9f3b2SDimitry Andric const DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) const { 2981db9f3b2SDimitry Andric return DieInfoArray[getOrigUnit().getDIEIndex(Entry)]; 2991db9f3b2SDimitry Andric } 3001db9f3b2SDimitry Andric 3011db9f3b2SDimitry Andric /// \p Die 3021db9f3b2SDimitry Andric /// \returns PlainDieInfo descriptor. getDIEInfo(const DWARFDie & Die)3031db9f3b2SDimitry Andric DIEInfo &getDIEInfo(const DWARFDie &Die) { 3041db9f3b2SDimitry Andric return DieInfoArray[getOrigUnit().getDIEIndex(Die)]; 3051db9f3b2SDimitry Andric } 3061db9f3b2SDimitry Andric 3071db9f3b2SDimitry Andric /// \p Die 3081db9f3b2SDimitry Andric /// \returns PlainDieInfo descriptor. getDIEInfo(const DWARFDie & Die)3091db9f3b2SDimitry Andric const DIEInfo &getDIEInfo(const DWARFDie &Die) const { 3101db9f3b2SDimitry Andric return DieInfoArray[getOrigUnit().getDIEIndex(Die)]; 3111db9f3b2SDimitry Andric } 3121db9f3b2SDimitry Andric 3131db9f3b2SDimitry Andric /// \p Idx index of the DIE. 3141db9f3b2SDimitry Andric /// \returns DieInfo descriptor. getDieOutOffset(uint32_t Idx)3151db9f3b2SDimitry Andric uint64_t getDieOutOffset(uint32_t Idx) { 3161db9f3b2SDimitry Andric return reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx]) 3171db9f3b2SDimitry Andric ->load(); 3181db9f3b2SDimitry Andric } 3191db9f3b2SDimitry Andric 3201db9f3b2SDimitry Andric /// \p Idx index of the DIE. 3211db9f3b2SDimitry Andric /// \returns type entry. getDieTypeEntry(uint32_t Idx)3221db9f3b2SDimitry Andric TypeEntry *getDieTypeEntry(uint32_t Idx) { 3231db9f3b2SDimitry Andric return reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx]) 3241db9f3b2SDimitry Andric ->load(); 3251db9f3b2SDimitry Andric } 3261db9f3b2SDimitry Andric 3271db9f3b2SDimitry Andric /// \p InputDieEntry debug info entry. 3281db9f3b2SDimitry Andric /// \returns DieInfo descriptor. getDieOutOffset(const DWARFDebugInfoEntry * InputDieEntry)3291db9f3b2SDimitry Andric uint64_t getDieOutOffset(const DWARFDebugInfoEntry *InputDieEntry) { 3301db9f3b2SDimitry Andric return reinterpret_cast<std::atomic<uint64_t> *>( 3311db9f3b2SDimitry Andric &OutDieOffsetArray[getOrigUnit().getDIEIndex(InputDieEntry)]) 3321db9f3b2SDimitry Andric ->load(); 3331db9f3b2SDimitry Andric } 3341db9f3b2SDimitry Andric 3351db9f3b2SDimitry Andric /// \p InputDieEntry debug info entry. 3361db9f3b2SDimitry Andric /// \returns type entry. getDieTypeEntry(const DWARFDebugInfoEntry * InputDieEntry)3371db9f3b2SDimitry Andric TypeEntry *getDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry) { 3381db9f3b2SDimitry Andric return reinterpret_cast<std::atomic<TypeEntry *> *>( 3391db9f3b2SDimitry Andric &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)]) 3401db9f3b2SDimitry Andric ->load(); 3411db9f3b2SDimitry Andric } 3421db9f3b2SDimitry Andric 3431db9f3b2SDimitry Andric /// \p Idx index of the DIE. 3441db9f3b2SDimitry Andric /// \returns DieInfo descriptor. rememberDieOutOffset(uint32_t Idx,uint64_t Offset)3451db9f3b2SDimitry Andric void rememberDieOutOffset(uint32_t Idx, uint64_t Offset) { 3461db9f3b2SDimitry Andric reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx]) 3471db9f3b2SDimitry Andric ->store(Offset); 3481db9f3b2SDimitry Andric } 3491db9f3b2SDimitry Andric 3501db9f3b2SDimitry Andric /// \p Idx index of the DIE. 3511db9f3b2SDimitry Andric /// \p Type entry. setDieTypeEntry(uint32_t Idx,TypeEntry * Entry)3521db9f3b2SDimitry Andric void setDieTypeEntry(uint32_t Idx, TypeEntry *Entry) { 3531db9f3b2SDimitry Andric reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx]) 3541db9f3b2SDimitry Andric ->store(Entry); 3551db9f3b2SDimitry Andric } 3561db9f3b2SDimitry Andric 3571db9f3b2SDimitry Andric /// \p InputDieEntry debug info entry. 3581db9f3b2SDimitry Andric /// \p Type entry. setDieTypeEntry(const DWARFDebugInfoEntry * InputDieEntry,TypeEntry * Entry)3591db9f3b2SDimitry Andric void setDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry, 3601db9f3b2SDimitry Andric TypeEntry *Entry) { 3611db9f3b2SDimitry Andric reinterpret_cast<std::atomic<TypeEntry *> *>( 3621db9f3b2SDimitry Andric &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)]) 3631db9f3b2SDimitry Andric ->store(Entry); 3641db9f3b2SDimitry Andric } 3651db9f3b2SDimitry Andric 3661db9f3b2SDimitry Andric /// @} 3671db9f3b2SDimitry Andric 3681db9f3b2SDimitry Andric /// Returns value of DW_AT_low_pc attribute. getLowPc()3691db9f3b2SDimitry Andric std::optional<uint64_t> getLowPc() const { return LowPc; } 3701db9f3b2SDimitry Andric 3711db9f3b2SDimitry Andric /// Returns value of DW_AT_high_pc attribute. getHighPc()3721db9f3b2SDimitry Andric uint64_t getHighPc() const { return HighPc; } 3731db9f3b2SDimitry Andric 3741db9f3b2SDimitry Andric /// Returns true if there is a label corresponding to the specified \p Addr. hasLabelAt(uint64_t Addr)3751db9f3b2SDimitry Andric bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); } 3761db9f3b2SDimitry Andric 3771db9f3b2SDimitry Andric /// Add the low_pc of a label that is relocated by applying 3781db9f3b2SDimitry Andric /// offset \p PCOffset. 3791db9f3b2SDimitry Andric void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset); 3801db9f3b2SDimitry Andric 3811db9f3b2SDimitry Andric /// Resolve the DIE attribute reference that has been extracted in \p 3821db9f3b2SDimitry Andric /// RefValue. The resulting DIE might be in another CompileUnit. 3831db9f3b2SDimitry Andric /// \returns referenced die and corresponding compilation unit. 3841db9f3b2SDimitry Andric /// compilation unit is null if reference could not be resolved. 3851db9f3b2SDimitry Andric std::optional<UnitEntryPairTy> 3861db9f3b2SDimitry Andric resolveDIEReference(const DWARFFormValue &RefValue, 3871db9f3b2SDimitry Andric ResolveInterCUReferencesMode CanResolveInterCUReferences); 3881db9f3b2SDimitry Andric 3891db9f3b2SDimitry Andric std::optional<UnitEntryPairTy> 3901db9f3b2SDimitry Andric resolveDIEReference(const DWARFDebugInfoEntry *DieEntry, 3911db9f3b2SDimitry Andric dwarf::Attribute Attr, 3921db9f3b2SDimitry Andric ResolveInterCUReferencesMode CanResolveInterCUReferences); 3931db9f3b2SDimitry Andric 3941db9f3b2SDimitry Andric /// @} 3951db9f3b2SDimitry Andric 3961db9f3b2SDimitry Andric /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying 3971db9f3b2SDimitry Andric /// offset \p PCOffset. 3981db9f3b2SDimitry Andric void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset); 3991db9f3b2SDimitry Andric 4001db9f3b2SDimitry Andric /// Returns function ranges of this unit. getFunctionRanges()4011db9f3b2SDimitry Andric const RangesTy &getFunctionRanges() const { return Ranges; } 4021db9f3b2SDimitry Andric 4031db9f3b2SDimitry Andric /// Clone and emit this compilation unit. 404*7a6dacacSDimitry Andric Error 405*7a6dacacSDimitry Andric cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple, 4061db9f3b2SDimitry Andric TypeUnit *ArtificialTypeUnit); 4071db9f3b2SDimitry Andric 4081db9f3b2SDimitry Andric /// Clone and emit debug locations(.debug_loc/.debug_loclists). 4091db9f3b2SDimitry Andric Error cloneAndEmitDebugLocations(); 4101db9f3b2SDimitry Andric 4111db9f3b2SDimitry Andric /// Clone and emit ranges. 4121db9f3b2SDimitry Andric Error cloneAndEmitRanges(); 4131db9f3b2SDimitry Andric 4141db9f3b2SDimitry Andric /// Clone and emit debug macros(.debug_macinfo/.debug_macro). 4151db9f3b2SDimitry Andric Error cloneAndEmitDebugMacro(); 4161db9f3b2SDimitry Andric 4171db9f3b2SDimitry Andric // Clone input DIE entry. 4181db9f3b2SDimitry Andric std::pair<DIE *, TypeEntry *> 4191db9f3b2SDimitry Andric cloneDIE(const DWARFDebugInfoEntry *InputDieEntry, 4201db9f3b2SDimitry Andric TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset, 4211db9f3b2SDimitry Andric std::optional<int64_t> FuncAddressAdjustment, 4221db9f3b2SDimitry Andric std::optional<int64_t> VarAddressAdjustment, 4231db9f3b2SDimitry Andric BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit); 4241db9f3b2SDimitry Andric 4251db9f3b2SDimitry Andric // Clone and emit line table. 426*7a6dacacSDimitry Andric Error cloneAndEmitLineTable(const Triple &TargetTriple); 4271db9f3b2SDimitry Andric 4281db9f3b2SDimitry Andric /// Clone attribute location axpression. 4291db9f3b2SDimitry Andric void cloneDieAttrExpression(const DWARFExpression &InputExpression, 4301db9f3b2SDimitry Andric SmallVectorImpl<uint8_t> &OutputExpression, 4311db9f3b2SDimitry Andric SectionDescriptor &Section, 4321db9f3b2SDimitry Andric std::optional<int64_t> VarAddressAdjustment, 4331db9f3b2SDimitry Andric OffsetsPtrVector &PatchesOffsets); 4341db9f3b2SDimitry Andric 4351db9f3b2SDimitry Andric /// Returns index(inside .debug_addr) of an address. getDebugAddrIndex(uint64_t Addr)4361db9f3b2SDimitry Andric uint64_t getDebugAddrIndex(uint64_t Addr) { 4371db9f3b2SDimitry Andric return DebugAddrIndexMap.getValueIndex(Addr); 4381db9f3b2SDimitry Andric } 4391db9f3b2SDimitry Andric 4401db9f3b2SDimitry Andric /// Returns directory and file from the line table by index. 4411db9f3b2SDimitry Andric std::optional<std::pair<StringRef, StringRef>> 4421db9f3b2SDimitry Andric getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue); 4431db9f3b2SDimitry Andric 4441db9f3b2SDimitry Andric /// Returns directory and file from the line table by index. 4451db9f3b2SDimitry Andric std::optional<std::pair<StringRef, StringRef>> 4461db9f3b2SDimitry Andric getDirAndFilenameFromLineTable(uint64_t FileIdx); 4471db9f3b2SDimitry Andric 4481db9f3b2SDimitry Andric /// \defgroup Helper methods to access OrigUnit. 4491db9f3b2SDimitry Andric /// 4501db9f3b2SDimitry Andric /// @{ 4511db9f3b2SDimitry Andric 4521db9f3b2SDimitry Andric /// Returns paired compile unit from input DWARF. getOrigUnit()4531db9f3b2SDimitry Andric DWARFUnit &getOrigUnit() const { 4541db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4551db9f3b2SDimitry Andric return *OrigUnit; 4561db9f3b2SDimitry Andric } 4571db9f3b2SDimitry Andric 4581db9f3b2SDimitry Andric const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry * Die)4591db9f3b2SDimitry Andric getFirstChildEntry(const DWARFDebugInfoEntry *Die) const { 4601db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4611db9f3b2SDimitry Andric return OrigUnit->getFirstChildEntry(Die); 4621db9f3b2SDimitry Andric } 4631db9f3b2SDimitry Andric 4641db9f3b2SDimitry Andric const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry * Die)4651db9f3b2SDimitry Andric getSiblingEntry(const DWARFDebugInfoEntry *Die) const { 4661db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4671db9f3b2SDimitry Andric return OrigUnit->getSiblingEntry(Die); 4681db9f3b2SDimitry Andric } 4691db9f3b2SDimitry Andric getParent(const DWARFDebugInfoEntry * Die)4701db9f3b2SDimitry Andric DWARFDie getParent(const DWARFDebugInfoEntry *Die) { 4711db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4721db9f3b2SDimitry Andric return OrigUnit->getParent(Die); 4731db9f3b2SDimitry Andric } 4741db9f3b2SDimitry Andric getDIEAtIndex(unsigned Index)4751db9f3b2SDimitry Andric DWARFDie getDIEAtIndex(unsigned Index) { 4761db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4771db9f3b2SDimitry Andric return OrigUnit->getDIEAtIndex(Index); 4781db9f3b2SDimitry Andric } 4791db9f3b2SDimitry Andric getDebugInfoEntry(unsigned Index)4801db9f3b2SDimitry Andric const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const { 4811db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4821db9f3b2SDimitry Andric return OrigUnit->getDebugInfoEntry(Index); 4831db9f3b2SDimitry Andric } 4841db9f3b2SDimitry Andric 4851db9f3b2SDimitry Andric DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) { 4861db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4871db9f3b2SDimitry Andric return OrigUnit->getUnitDIE(ExtractUnitDIEOnly); 4881db9f3b2SDimitry Andric } 4891db9f3b2SDimitry Andric getDIE(const DWARFDebugInfoEntry * Die)4901db9f3b2SDimitry Andric DWARFDie getDIE(const DWARFDebugInfoEntry *Die) { 4911db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4921db9f3b2SDimitry Andric return DWARFDie(OrigUnit, Die); 4931db9f3b2SDimitry Andric } 4941db9f3b2SDimitry Andric getDIEIndex(const DWARFDebugInfoEntry * Die)4951db9f3b2SDimitry Andric uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const { 4961db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 4971db9f3b2SDimitry Andric return OrigUnit->getDIEIndex(Die); 4981db9f3b2SDimitry Andric } 4991db9f3b2SDimitry Andric getDIEIndex(const DWARFDie & Die)5001db9f3b2SDimitry Andric uint32_t getDIEIndex(const DWARFDie &Die) const { 5011db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 5021db9f3b2SDimitry Andric return OrigUnit->getDIEIndex(Die); 5031db9f3b2SDimitry Andric } 5041db9f3b2SDimitry Andric find(uint32_t DieIdx,ArrayRef<dwarf::Attribute> Attrs)5051db9f3b2SDimitry Andric std::optional<DWARFFormValue> find(uint32_t DieIdx, 5061db9f3b2SDimitry Andric ArrayRef<dwarf::Attribute> Attrs) const { 5071db9f3b2SDimitry Andric assert(OrigUnit != nullptr); 5081db9f3b2SDimitry Andric return find(OrigUnit->getDebugInfoEntry(DieIdx), Attrs); 5091db9f3b2SDimitry Andric } 5101db9f3b2SDimitry Andric find(const DWARFDebugInfoEntry * Die,ArrayRef<dwarf::Attribute> Attrs)5111db9f3b2SDimitry Andric std::optional<DWARFFormValue> find(const DWARFDebugInfoEntry *Die, 5121db9f3b2SDimitry Andric ArrayRef<dwarf::Attribute> Attrs) const { 5131db9f3b2SDimitry Andric if (!Die) 5141db9f3b2SDimitry Andric return std::nullopt; 5151db9f3b2SDimitry Andric auto AbbrevDecl = Die->getAbbreviationDeclarationPtr(); 5161db9f3b2SDimitry Andric if (AbbrevDecl) { 5171db9f3b2SDimitry Andric for (auto Attr : Attrs) { 5181db9f3b2SDimitry Andric if (auto Value = AbbrevDecl->getAttributeValue(Die->getOffset(), Attr, 5191db9f3b2SDimitry Andric *OrigUnit)) 5201db9f3b2SDimitry Andric return Value; 5211db9f3b2SDimitry Andric } 5221db9f3b2SDimitry Andric } 5231db9f3b2SDimitry Andric return std::nullopt; 5241db9f3b2SDimitry Andric } 5251db9f3b2SDimitry Andric getDIEIndexForOffset(uint64_t Offset)5261db9f3b2SDimitry Andric std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) { 5271db9f3b2SDimitry Andric return OrigUnit->getDIEIndexForOffset(Offset); 5281db9f3b2SDimitry Andric } 5291db9f3b2SDimitry Andric 5301db9f3b2SDimitry Andric /// @} 5311db9f3b2SDimitry Andric 5321db9f3b2SDimitry Andric /// \defgroup Methods used for reporting warnings and errors: 5331db9f3b2SDimitry Andric /// 5341db9f3b2SDimitry Andric /// @{ 5351db9f3b2SDimitry Andric 5361db9f3b2SDimitry Andric void warn(const Twine &Warning, const DWARFDie *DIE = nullptr) { 5371db9f3b2SDimitry Andric GlobalData.warn(Warning, getUnitName(), DIE); 5381db9f3b2SDimitry Andric } 5391db9f3b2SDimitry Andric 5401db9f3b2SDimitry Andric void warn(Error Warning, const DWARFDie *DIE = nullptr) { 5411db9f3b2SDimitry Andric handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) { 5421db9f3b2SDimitry Andric GlobalData.warn(Info.message(), getUnitName(), DIE); 5431db9f3b2SDimitry Andric }); 5441db9f3b2SDimitry Andric } 5451db9f3b2SDimitry Andric warn(const Twine & Warning,const DWARFDebugInfoEntry * DieEntry)5461db9f3b2SDimitry Andric void warn(const Twine &Warning, const DWARFDebugInfoEntry *DieEntry) { 5471db9f3b2SDimitry Andric if (DieEntry != nullptr) { 5481db9f3b2SDimitry Andric DWARFDie DIE(&getOrigUnit(), DieEntry); 5491db9f3b2SDimitry Andric GlobalData.warn(Warning, getUnitName(), &DIE); 5501db9f3b2SDimitry Andric return; 5511db9f3b2SDimitry Andric } 5521db9f3b2SDimitry Andric 5531db9f3b2SDimitry Andric GlobalData.warn(Warning, getUnitName()); 5541db9f3b2SDimitry Andric } 5551db9f3b2SDimitry Andric 5561db9f3b2SDimitry Andric void error(const Twine &Err, const DWARFDie *DIE = nullptr) { 5571db9f3b2SDimitry Andric GlobalData.warn(Err, getUnitName(), DIE); 5581db9f3b2SDimitry Andric } 5591db9f3b2SDimitry Andric 5601db9f3b2SDimitry Andric void error(Error Err, const DWARFDie *DIE = nullptr) { 5611db9f3b2SDimitry Andric handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) { 5621db9f3b2SDimitry Andric GlobalData.error(Info.message(), getUnitName(), DIE); 5631db9f3b2SDimitry Andric }); 5641db9f3b2SDimitry Andric } 5651db9f3b2SDimitry Andric 5661db9f3b2SDimitry Andric /// @} 5671db9f3b2SDimitry Andric 5681db9f3b2SDimitry Andric /// Save specified accelerator info \p Info. saveAcceleratorInfo(const DwarfUnit::AccelInfo & Info)5691db9f3b2SDimitry Andric void saveAcceleratorInfo(const DwarfUnit::AccelInfo &Info) { 5701db9f3b2SDimitry Andric AcceleratorRecords.add(Info); 5711db9f3b2SDimitry Andric } 5721db9f3b2SDimitry Andric 5731db9f3b2SDimitry Andric /// Enumerates all units accelerator records. 5741db9f3b2SDimitry Andric void forEachAcceleratorRecord(function_ref<void (AccelInfo &)> Handler)5751db9f3b2SDimitry Andric forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override { 5761db9f3b2SDimitry Andric AcceleratorRecords.forEach(Handler); 5771db9f3b2SDimitry Andric } 5781db9f3b2SDimitry Andric 5791db9f3b2SDimitry Andric /// Output unit selector. 5801db9f3b2SDimitry Andric class OutputUnitVariantPtr { 5811db9f3b2SDimitry Andric public: 5821db9f3b2SDimitry Andric OutputUnitVariantPtr(CompileUnit *U); 5831db9f3b2SDimitry Andric OutputUnitVariantPtr(TypeUnit *U); 5841db9f3b2SDimitry Andric 5851db9f3b2SDimitry Andric /// Accessor for common functionality. 5861db9f3b2SDimitry Andric DwarfUnit *operator->(); 5871db9f3b2SDimitry Andric 5881db9f3b2SDimitry Andric bool isCompileUnit(); 5891db9f3b2SDimitry Andric 5901db9f3b2SDimitry Andric bool isTypeUnit(); 5911db9f3b2SDimitry Andric 5921db9f3b2SDimitry Andric /// Returns CompileUnit if applicable. 5931db9f3b2SDimitry Andric CompileUnit *getAsCompileUnit(); 5941db9f3b2SDimitry Andric 5951db9f3b2SDimitry Andric /// Returns TypeUnit if applicable. 5961db9f3b2SDimitry Andric TypeUnit *getAsTypeUnit(); 5971db9f3b2SDimitry Andric 5981db9f3b2SDimitry Andric protected: 5991db9f3b2SDimitry Andric PointerUnion<CompileUnit *, TypeUnit *> Ptr; 6001db9f3b2SDimitry Andric }; 6011db9f3b2SDimitry Andric 6021db9f3b2SDimitry Andric private: 6031db9f3b2SDimitry Andric /// Navigate DWARF tree recursively and set die properties. 6041db9f3b2SDimitry Andric void analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry, 6051db9f3b2SDimitry Andric bool IsODRUnavailableFunctionScope); 6061db9f3b2SDimitry Andric 6071db9f3b2SDimitry Andric struct LinkedLocationExpressionsWithOffsetPatches { 6081db9f3b2SDimitry Andric DWARFLocationExpression Expression; 6091db9f3b2SDimitry Andric OffsetsPtrVector Patches; 6101db9f3b2SDimitry Andric }; 6111db9f3b2SDimitry Andric using LinkedLocationExpressionsVector = 6121db9f3b2SDimitry Andric SmallVector<LinkedLocationExpressionsWithOffsetPatches>; 6131db9f3b2SDimitry Andric 6141db9f3b2SDimitry Andric /// Emit debug locations. 6151db9f3b2SDimitry Andric void emitLocations(DebugSectionKind LocationSectionKind); 6161db9f3b2SDimitry Andric 6171db9f3b2SDimitry Andric /// Emit location list header. 6181db9f3b2SDimitry Andric uint64_t emitLocListHeader(SectionDescriptor &OutLocationSection); 6191db9f3b2SDimitry Andric 6201db9f3b2SDimitry Andric /// Emit location list fragment. 6211db9f3b2SDimitry Andric uint64_t emitLocListFragment( 6221db9f3b2SDimitry Andric const LinkedLocationExpressionsVector &LinkedLocationExpression, 6231db9f3b2SDimitry Andric SectionDescriptor &OutLocationSection); 6241db9f3b2SDimitry Andric 6251db9f3b2SDimitry Andric /// Emit the .debug_addr section fragment for current unit. 6261db9f3b2SDimitry Andric Error emitDebugAddrSection(); 6271db9f3b2SDimitry Andric 6281db9f3b2SDimitry Andric /// Emit .debug_aranges. 6291db9f3b2SDimitry Andric void emitAranges(AddressRanges &LinkedFunctionRanges); 6301db9f3b2SDimitry Andric 6311db9f3b2SDimitry Andric /// Clone and emit .debug_ranges/.debug_rnglists. 6321db9f3b2SDimitry Andric void cloneAndEmitRangeList(DebugSectionKind RngSectionKind, 6331db9f3b2SDimitry Andric AddressRanges &LinkedFunctionRanges); 6341db9f3b2SDimitry Andric 6351db9f3b2SDimitry Andric /// Emit range list header. 6361db9f3b2SDimitry Andric uint64_t emitRangeListHeader(SectionDescriptor &OutRangeSection); 6371db9f3b2SDimitry Andric 6381db9f3b2SDimitry Andric /// Emit range list fragment. 6391db9f3b2SDimitry Andric void emitRangeListFragment(const AddressRanges &LinkedRanges, 6401db9f3b2SDimitry Andric SectionDescriptor &OutRangeSection); 6411db9f3b2SDimitry Andric 6421db9f3b2SDimitry Andric /// Insert the new line info sequence \p Seq into the current 6431db9f3b2SDimitry Andric /// set of already linked line info \p Rows. 6441db9f3b2SDimitry Andric void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq, 6451db9f3b2SDimitry Andric std::vector<DWARFDebugLine::Row> &Rows); 6461db9f3b2SDimitry Andric 6471db9f3b2SDimitry Andric /// Emits body for both macro sections. 6481db9f3b2SDimitry Andric void emitMacroTableImpl(const DWARFDebugMacro *MacroTable, 6491db9f3b2SDimitry Andric uint64_t OffsetToMacroTable, bool hasDWARFv5Header); 6501db9f3b2SDimitry Andric 6511db9f3b2SDimitry Andric /// Creates DIE which would be placed into the "Plain" compile unit. 6521db9f3b2SDimitry Andric DIE *createPlainDIEandCloneAttributes( 6531db9f3b2SDimitry Andric const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator, 6541db9f3b2SDimitry Andric uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment, 6551db9f3b2SDimitry Andric std::optional<int64_t> &VarAddressAdjustment); 6561db9f3b2SDimitry Andric 6571db9f3b2SDimitry Andric /// Creates DIE which would be placed into the "Type" compile unit. 6581db9f3b2SDimitry Andric TypeEntry *createTypeDIEandCloneAttributes( 6591db9f3b2SDimitry Andric const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator, 6601db9f3b2SDimitry Andric TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit); 6611db9f3b2SDimitry Andric 6621db9f3b2SDimitry Andric /// Create output DIE inside specified \p TypeDescriptor. 6631db9f3b2SDimitry Andric DIE *allocateTypeDie(TypeEntryBody *TypeDescriptor, 6641db9f3b2SDimitry Andric DIEGenerator &TypeDIEGenerator, dwarf::Tag DieTag, 6651db9f3b2SDimitry Andric bool IsDeclaration, bool IsParentDeclaration); 6661db9f3b2SDimitry Andric 6671db9f3b2SDimitry Andric /// Enumerate \p DieEntry children and assign names for them. 6681db9f3b2SDimitry Andric Error assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry, 6691db9f3b2SDimitry Andric SyntheticTypeNameBuilder &NameBuilder); 6701db9f3b2SDimitry Andric 6711db9f3b2SDimitry Andric /// DWARFFile containing this compile unit. 6721db9f3b2SDimitry Andric DWARFFile &File; 6731db9f3b2SDimitry Andric 6741db9f3b2SDimitry Andric /// Pointer to the paired compile unit from the input DWARF. 6751db9f3b2SDimitry Andric DWARFUnit *OrigUnit = nullptr; 6761db9f3b2SDimitry Andric 6771db9f3b2SDimitry Andric /// The DW_AT_language of this unit. 6781db9f3b2SDimitry Andric std::optional<uint16_t> Language; 6791db9f3b2SDimitry Andric 6801db9f3b2SDimitry Andric /// Line table for this unit. 6811db9f3b2SDimitry Andric const DWARFDebugLine::LineTable *LineTablePtr = nullptr; 6821db9f3b2SDimitry Andric 6831db9f3b2SDimitry Andric /// Cached resolved paths from the line table. 6841db9f3b2SDimitry Andric /// The key is <UniqueUnitID, FileIdx>. 6851db9f3b2SDimitry Andric using ResolvedPathsMap = DenseMap<unsigned, StringEntry *>; 6861db9f3b2SDimitry Andric ResolvedPathsMap ResolvedFullPaths; 6871db9f3b2SDimitry Andric StringMap<StringEntry *> ResolvedParentPaths; 6881db9f3b2SDimitry Andric 6891db9f3b2SDimitry Andric /// Maps an address into the index inside .debug_addr section. 6901db9f3b2SDimitry Andric IndexedValuesMap<uint64_t> DebugAddrIndexMap; 6911db9f3b2SDimitry Andric 6921db9f3b2SDimitry Andric std::unique_ptr<DependencyTracker> Dependencies; 6931db9f3b2SDimitry Andric 6941db9f3b2SDimitry Andric /// \defgroup Data Members accessed asinchronously. 6951db9f3b2SDimitry Andric /// 6961db9f3b2SDimitry Andric /// @{ 6971db9f3b2SDimitry Andric OffsetToUnitTy getUnitFromOffset; 6981db9f3b2SDimitry Andric 6991db9f3b2SDimitry Andric std::optional<uint64_t> LowPc; 7001db9f3b2SDimitry Andric uint64_t HighPc = 0; 7011db9f3b2SDimitry Andric 7021db9f3b2SDimitry Andric /// Flag indicating whether type de-duplication is forbidden. 7031db9f3b2SDimitry Andric bool NoODR = true; 7041db9f3b2SDimitry Andric 7051db9f3b2SDimitry Andric /// The ranges in that map are the PC ranges for functions in this unit, 7061db9f3b2SDimitry Andric /// associated with the PC offset to apply to the addresses to get 7071db9f3b2SDimitry Andric /// the linked address. 7081db9f3b2SDimitry Andric RangesTy Ranges; 7091db9f3b2SDimitry Andric std::mutex RangesMutex; 7101db9f3b2SDimitry Andric 7111db9f3b2SDimitry Andric /// The DW_AT_low_pc of each DW_TAG_label. 7121db9f3b2SDimitry Andric using LabelMapTy = SmallDenseMap<uint64_t, uint64_t, 1>; 7131db9f3b2SDimitry Andric LabelMapTy Labels; 7141db9f3b2SDimitry Andric std::mutex LabelsMutex; 7151db9f3b2SDimitry Andric 7161db9f3b2SDimitry Andric /// This field keeps current stage of overall compile unit processing. 7171db9f3b2SDimitry Andric std::atomic<Stage> Stage; 7181db9f3b2SDimitry Andric 7191db9f3b2SDimitry Andric /// DIE info indexed by DIE index. 7201db9f3b2SDimitry Andric SmallVector<DIEInfo> DieInfoArray; 7211db9f3b2SDimitry Andric SmallVector<uint64_t> OutDieOffsetArray; 7221db9f3b2SDimitry Andric SmallVector<TypeEntry *> TypeEntries; 7231db9f3b2SDimitry Andric 7241db9f3b2SDimitry Andric /// The list of accelerator records for this unit. 7251db9f3b2SDimitry Andric ArrayList<AccelInfo> AcceleratorRecords; 7261db9f3b2SDimitry Andric /// @} 7271db9f3b2SDimitry Andric }; 7281db9f3b2SDimitry Andric 7291db9f3b2SDimitry Andric /// \returns list of attributes referencing type DIEs which might be 7301db9f3b2SDimitry Andric /// deduplicated. 7311db9f3b2SDimitry Andric /// Note: it does not include DW_AT_containing_type attribute to avoid 7321db9f3b2SDimitry Andric /// infinite recursion. 7331db9f3b2SDimitry Andric ArrayRef<dwarf::Attribute> getODRAttributes(); 7341db9f3b2SDimitry Andric 7351db9f3b2SDimitry Andric } // end of namespace parallel 7361db9f3b2SDimitry Andric } // end of namespace dwarf_linker 7371db9f3b2SDimitry Andric } // end of namespace llvm 7381db9f3b2SDimitry Andric 7391db9f3b2SDimitry Andric #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H 740