740 lines · c
1//===- DWARFLinkerCompileUnit.h ---------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H10#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H11 12#include "DWARFLinkerUnit.h"13#include "llvm/DWARFLinker/DWARFFile.h"14#include <optional>15 16namespace llvm {17namespace dwarf_linker {18namespace parallel {19 20using OffsetToUnitTy = function_ref<CompileUnit *(uint64_t Offset)>;21 22struct AttributesInfo;23class SyntheticTypeNameBuilder;24class DIEGenerator;25class TypeUnit;26class DependencyTracker;27 28class CompileUnit;29 30/// This is a helper structure which keeps a debug info entry31/// with it's containing compilation unit.32struct UnitEntryPairTy {33 UnitEntryPairTy() = default;34 UnitEntryPairTy(CompileUnit *CU, const DWARFDebugInfoEntry *DieEntry)35 : CU(CU), DieEntry(DieEntry) {}36 37 CompileUnit *CU = nullptr;38 const DWARFDebugInfoEntry *DieEntry = nullptr;39 40 UnitEntryPairTy getNamespaceOrigin();41 std::optional<UnitEntryPairTy> getParent();42};43 44enum ResolveInterCUReferencesMode : bool {45 Resolve = true,46 AvoidResolving = false,47};48 49/// Stores all information related to a compile unit, be it in its original50/// instance of the object file or its brand new cloned and generated DIE tree.51/// NOTE: we need alignment of at least 8 bytes as we use52/// PointerIntPair<CompileUnit *, 3> in the DependencyTracker.h53class alignas(8) CompileUnit : public DwarfUnit {54public:55 /// The stages of new compile unit processing.56 enum class Stage : uint8_t {57 /// Created, linked with input DWARF file.58 CreatedNotLoaded = 0,59 60 /// Input DWARF is loaded.61 Loaded,62 63 /// Input DWARF is analysed(DIEs pointing to the real code section are64 /// discovered, type names are assigned if ODR is requested).65 LivenessAnalysisDone,66 67 /// Check if dependencies have incompatible placement.68 /// If that is the case modify placement to be compatible.69 UpdateDependenciesCompleteness,70 71 /// Type names assigned to DIEs.72 TypeNamesAssigned,73 74 /// Output DWARF is generated.75 Cloned,76 77 /// Offsets inside patch records are updated.78 PatchesUpdated,79 80 /// Resources(Input DWARF, Output DWARF tree) are released.81 Cleaned,82 83 /// Compile Unit should be skipped84 Skipped85 };86 87 CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,88 StringRef ClangModuleName, DWARFFile &File,89 OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,90 llvm::endianness Endianess);91 92 CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit, unsigned ID,93 StringRef ClangModuleName, DWARFFile &File,94 OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,95 llvm::endianness Endianess);96 97 /// Returns stage of overall processing.98 Stage getStage() const { return Stage; }99 100 /// Set stage of overall processing.101 void setStage(Stage Stage) { this->Stage = Stage; }102 103 /// Loads unit line table.104 void loadLineTable();105 106 /// Returns name of the file for the \p FileIdx107 /// from the unit`s line table.108 StringEntry *getFileName(unsigned FileIdx, StringPool &GlobalStrings);109 110 /// Returns DWARFFile containing this compile unit.111 const DWARFFile &getContaingFile() const { return File; }112 113 /// Load DIEs of input compilation unit. \returns true if input DIEs114 /// successfully loaded.115 bool loadInputDIEs();116 117 /// Reset compile units data(results of liveness analysis, clonning)118 /// if current stage greater than Stage::Loaded. We need to reset data119 /// as we are going to repeat stages.120 void maybeResetToLoadedStage();121 122 /// Collect references to parseable Swift interfaces in imported123 /// DW_TAG_module blocks.124 void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry);125 126 /// Navigate DWARF tree and set die properties.127 void analyzeDWARFStructure() {128 analyzeDWARFStructureRec(getUnitDIE().getDebugInfoEntry(), false);129 }130 131 /// Cleanup unneeded resources after compile unit is cloned.132 void cleanupDataAfterClonning();133 134 /// After cloning stage the output DIEs offsets are deallocated.135 /// This method copies output offsets for referenced DIEs into DIEs patches.136 void updateDieRefPatchesWithClonedOffsets();137 138 /// Search for subprograms and variables referencing live code and discover139 /// dependend DIEs. Mark live DIEs, set placement for DIEs.140 bool resolveDependenciesAndMarkLiveness(141 bool InterCUProcessingStarted,142 std::atomic<bool> &HasNewInterconnectedCUs);143 144 /// Check dependend DIEs for incompatible placement.145 /// Make placement to be consistent.146 bool updateDependenciesCompleteness();147 148 /// Check DIEs to have a consistent marking(keep marking, placement marking).149 void verifyDependencies();150 151 /// Search for type entries and assign names.152 Error assignTypeNames(TypePool &TypePoolRef);153 154 /// Kinds of placement for the output die.155 enum DieOutputPlacement : uint8_t {156 NotSet = 0,157 158 /// Corresponding DIE goes to the type table only.159 TypeTable = 1,160 161 /// Corresponding DIE goes to the plain dwarf only.162 PlainDwarf = 2,163 164 /// Corresponding DIE goes to type table and to plain dwarf.165 Both = 3,166 };167 168 /// Information gathered about source DIEs.169 struct DIEInfo {170 DIEInfo() = default;171 DIEInfo(const DIEInfo &Other) { Flags = Other.Flags.load(); }172 DIEInfo &operator=(const DIEInfo &Other) {173 Flags = Other.Flags.load();174 return *this;175 }176 177 /// Data member keeping various flags.178 std::atomic<uint16_t> Flags = {0};179 180 /// \returns Placement kind for the corresponding die.181 DieOutputPlacement getPlacement() const {182 return DieOutputPlacement(Flags & 0x7);183 }184 185 /// Sets Placement kind for the corresponding die.186 void setPlacement(DieOutputPlacement Placement) {187 auto InputData = Flags.load();188 while (!Flags.compare_exchange_weak(InputData,189 ((InputData & ~0x7) | Placement))) {190 }191 }192 193 /// Unsets Placement kind for the corresponding die.194 void unsetPlacement() {195 auto InputData = Flags.load();196 while (!Flags.compare_exchange_weak(InputData, (InputData & ~0x7))) {197 }198 }199 200 /// Sets Placement kind for the corresponding die.201 bool setPlacementIfUnset(DieOutputPlacement Placement) {202 auto InputData = Flags.load();203 if ((InputData & 0x7) == NotSet)204 if (Flags.compare_exchange_strong(InputData, (InputData | Placement)))205 return true;206 207 return false;208 }209 210#define SINGLE_FLAG_METHODS_SET(Name, Value) \211 bool get##Name() const { return Flags & Value; } \212 void set##Name() { \213 auto InputData = Flags.load(); \214 while (!Flags.compare_exchange_weak(InputData, InputData | Value)) { \215 } \216 } \217 void unset##Name() { \218 auto InputData = Flags.load(); \219 while (!Flags.compare_exchange_weak(InputData, InputData & ~Value)) { \220 } \221 }222 223 /// DIE is a part of the linked output.224 SINGLE_FLAG_METHODS_SET(Keep, 0x08)225 226 /// DIE has children which are part of the linked output.227 SINGLE_FLAG_METHODS_SET(KeepPlainChildren, 0x10)228 229 /// DIE has children which are part of the type table.230 SINGLE_FLAG_METHODS_SET(KeepTypeChildren, 0x20)231 232 /// DIE is in module scope.233 SINGLE_FLAG_METHODS_SET(IsInMouduleScope, 0x40)234 235 /// DIE is in function scope.236 SINGLE_FLAG_METHODS_SET(IsInFunctionScope, 0x80)237 238 /// DIE is in anonymous namespace scope.239 SINGLE_FLAG_METHODS_SET(IsInAnonNamespaceScope, 0x100)240 241 /// DIE is available for ODR type deduplication.242 SINGLE_FLAG_METHODS_SET(ODRAvailable, 0x200)243 244 /// Track liveness for the DIE.245 SINGLE_FLAG_METHODS_SET(TrackLiveness, 0x400)246 247 /// Track liveness for the DIE.248 SINGLE_FLAG_METHODS_SET(HasAnAddress, 0x800)249 250 void unsetFlagsWhichSetDuringLiveAnalysis() {251 auto InputData = Flags.load();252 while (!Flags.compare_exchange_weak(253 InputData, InputData & ~(0x7 | 0x8 | 0x10 | 0x20))) {254 }255 }256 257 /// Erase all flags.258 void eraseData() { Flags = 0; }259 260#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)261 LLVM_DUMP_METHOD void dump();262#endif263 264 bool needToPlaceInTypeTable() const {265 return (getKeep() && (getPlacement() == CompileUnit::TypeTable ||266 getPlacement() == CompileUnit::Both)) ||267 getKeepTypeChildren();268 }269 270 bool needToKeepInPlainDwarf() const {271 return (getKeep() && (getPlacement() == CompileUnit::PlainDwarf ||272 getPlacement() == CompileUnit::Both)) ||273 getKeepPlainChildren();274 }275 };276 277 /// \defgroup Group of functions returning DIE info.278 ///279 /// @{280 281 /// \p Idx index of the DIE.282 /// \returns DieInfo descriptor.283 DIEInfo &getDIEInfo(unsigned Idx) { return DieInfoArray[Idx]; }284 285 /// \p Idx index of the DIE.286 /// \returns DieInfo descriptor.287 const DIEInfo &getDIEInfo(unsigned Idx) const { return DieInfoArray[Idx]; }288 289 /// \p Idx index of the DIE.290 /// \returns DieInfo descriptor.291 DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) {292 return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];293 }294 295 /// \p Idx index of the DIE.296 /// \returns DieInfo descriptor.297 const DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) const {298 return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];299 }300 301 /// \p Die302 /// \returns PlainDieInfo descriptor.303 DIEInfo &getDIEInfo(const DWARFDie &Die) {304 return DieInfoArray[getOrigUnit().getDIEIndex(Die)];305 }306 307 /// \p Die308 /// \returns PlainDieInfo descriptor.309 const DIEInfo &getDIEInfo(const DWARFDie &Die) const {310 return DieInfoArray[getOrigUnit().getDIEIndex(Die)];311 }312 313 /// \p Idx index of the DIE.314 /// \returns DieInfo descriptor.315 uint64_t getDieOutOffset(uint32_t Idx) {316 return reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])317 ->load();318 }319 320 /// \p Idx index of the DIE.321 /// \returns type entry.322 TypeEntry *getDieTypeEntry(uint32_t Idx) {323 return reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])324 ->load();325 }326 327 /// \p InputDieEntry debug info entry.328 /// \returns DieInfo descriptor.329 uint64_t getDieOutOffset(const DWARFDebugInfoEntry *InputDieEntry) {330 return reinterpret_cast<std::atomic<uint64_t> *>(331 &OutDieOffsetArray[getOrigUnit().getDIEIndex(InputDieEntry)])332 ->load();333 }334 335 /// \p InputDieEntry debug info entry.336 /// \returns type entry.337 TypeEntry *getDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry) {338 return reinterpret_cast<std::atomic<TypeEntry *> *>(339 &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])340 ->load();341 }342 343 /// \p Idx index of the DIE.344 /// \returns DieInfo descriptor.345 void rememberDieOutOffset(uint32_t Idx, uint64_t Offset) {346 reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])347 ->store(Offset);348 }349 350 /// \p Idx index of the DIE.351 /// \p Type entry.352 void setDieTypeEntry(uint32_t Idx, TypeEntry *Entry) {353 reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])354 ->store(Entry);355 }356 357 /// \p InputDieEntry debug info entry.358 /// \p Type entry.359 void setDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry,360 TypeEntry *Entry) {361 reinterpret_cast<std::atomic<TypeEntry *> *>(362 &TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])363 ->store(Entry);364 }365 366 /// @}367 368 /// Returns value of DW_AT_low_pc attribute.369 std::optional<uint64_t> getLowPc() const { return LowPc; }370 371 /// Returns value of DW_AT_high_pc attribute.372 uint64_t getHighPc() const { return HighPc; }373 374 /// Returns true if there is a label corresponding to the specified \p Addr.375 bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }376 377 /// Add the low_pc of a label that is relocated by applying378 /// offset \p PCOffset.379 void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);380 381 /// Resolve the DIE attribute reference that has been extracted in \p382 /// RefValue. The resulting DIE might be in another CompileUnit.383 /// \returns referenced die and corresponding compilation unit.384 /// compilation unit is null if reference could not be resolved.385 std::optional<UnitEntryPairTy>386 resolveDIEReference(const DWARFFormValue &RefValue,387 ResolveInterCUReferencesMode CanResolveInterCUReferences);388 389 std::optional<UnitEntryPairTy>390 resolveDIEReference(const DWARFDebugInfoEntry *DieEntry,391 dwarf::Attribute Attr,392 ResolveInterCUReferencesMode CanResolveInterCUReferences);393 394 /// @}395 396 /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying397 /// offset \p PCOffset.398 void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);399 400 /// Returns function ranges of this unit.401 const RangesTy &getFunctionRanges() const { return Ranges; }402 403 /// Clone and emit this compilation unit.404 Error405 cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,406 TypeUnit *ArtificialTypeUnit);407 408 /// Clone and emit debug locations(.debug_loc/.debug_loclists).409 Error cloneAndEmitDebugLocations();410 411 /// Clone and emit ranges.412 Error cloneAndEmitRanges();413 414 /// Clone and emit debug macros(.debug_macinfo/.debug_macro).415 Error cloneAndEmitDebugMacro();416 417 // Clone input DIE entry.418 std::pair<DIE *, TypeEntry *>419 cloneDIE(const DWARFDebugInfoEntry *InputDieEntry,420 TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset,421 std::optional<int64_t> FuncAddressAdjustment,422 std::optional<int64_t> VarAddressAdjustment,423 BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit);424 425 // Clone and emit line table.426 Error cloneAndEmitLineTable(const Triple &TargetTriple);427 428 /// Clone attribute location axpression.429 void cloneDieAttrExpression(const DWARFExpression &InputExpression,430 SmallVectorImpl<uint8_t> &OutputExpression,431 SectionDescriptor &Section,432 std::optional<int64_t> VarAddressAdjustment,433 OffsetsPtrVector &PatchesOffsets);434 435 /// Returns index(inside .debug_addr) of an address.436 uint64_t getDebugAddrIndex(uint64_t Addr) {437 return DebugAddrIndexMap.getValueIndex(Addr);438 }439 440 /// Returns directory and file from the line table by index.441 std::optional<std::pair<StringRef, StringRef>>442 getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue);443 444 /// Returns directory and file from the line table by index.445 std::optional<std::pair<StringRef, StringRef>>446 getDirAndFilenameFromLineTable(uint64_t FileIdx);447 448 /// \defgroup Helper methods to access OrigUnit.449 ///450 /// @{451 452 /// Returns paired compile unit from input DWARF.453 DWARFUnit &getOrigUnit() const {454 assert(OrigUnit != nullptr);455 return *OrigUnit;456 }457 458 const DWARFDebugInfoEntry *459 getFirstChildEntry(const DWARFDebugInfoEntry *Die) const {460 assert(OrigUnit != nullptr);461 return OrigUnit->getFirstChildEntry(Die);462 }463 464 const DWARFDebugInfoEntry *465 getSiblingEntry(const DWARFDebugInfoEntry *Die) const {466 assert(OrigUnit != nullptr);467 return OrigUnit->getSiblingEntry(Die);468 }469 470 DWARFDie getParent(const DWARFDebugInfoEntry *Die) {471 assert(OrigUnit != nullptr);472 return OrigUnit->getParent(Die);473 }474 475 DWARFDie getDIEAtIndex(unsigned Index) {476 assert(OrigUnit != nullptr);477 return OrigUnit->getDIEAtIndex(Index);478 }479 480 const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {481 assert(OrigUnit != nullptr);482 return OrigUnit->getDebugInfoEntry(Index);483 }484 485 DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {486 assert(OrigUnit != nullptr);487 return OrigUnit->getUnitDIE(ExtractUnitDIEOnly);488 }489 490 DWARFDie getDIE(const DWARFDebugInfoEntry *Die) {491 assert(OrigUnit != nullptr);492 return DWARFDie(OrigUnit, Die);493 }494 495 uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {496 assert(OrigUnit != nullptr);497 return OrigUnit->getDIEIndex(Die);498 }499 500 uint32_t getDIEIndex(const DWARFDie &Die) const {501 assert(OrigUnit != nullptr);502 return OrigUnit->getDIEIndex(Die);503 }504 505 std::optional<DWARFFormValue> find(uint32_t DieIdx,506 ArrayRef<dwarf::Attribute> Attrs) const {507 assert(OrigUnit != nullptr);508 return find(OrigUnit->getDebugInfoEntry(DieIdx), Attrs);509 }510 511 std::optional<DWARFFormValue> find(const DWARFDebugInfoEntry *Die,512 ArrayRef<dwarf::Attribute> Attrs) const {513 if (!Die)514 return std::nullopt;515 auto AbbrevDecl = Die->getAbbreviationDeclarationPtr();516 if (AbbrevDecl) {517 for (auto Attr : Attrs) {518 if (auto Value = AbbrevDecl->getAttributeValue(Die->getOffset(), Attr,519 *OrigUnit))520 return Value;521 }522 }523 return std::nullopt;524 }525 526 std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {527 return OrigUnit->getDIEIndexForOffset(Offset);528 }529 530 /// @}531 532 /// \defgroup Methods used for reporting warnings and errors:533 ///534 /// @{535 536 void warn(const Twine &Warning, const DWARFDie *DIE = nullptr) {537 GlobalData.warn(Warning, getUnitName(), DIE);538 }539 540 void warn(Error Warning, const DWARFDie *DIE = nullptr) {541 handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) {542 GlobalData.warn(Info.message(), getUnitName(), DIE);543 });544 }545 546 void warn(const Twine &Warning, const DWARFDebugInfoEntry *DieEntry) {547 if (DieEntry != nullptr) {548 DWARFDie DIE(&getOrigUnit(), DieEntry);549 GlobalData.warn(Warning, getUnitName(), &DIE);550 return;551 }552 553 GlobalData.warn(Warning, getUnitName());554 }555 556 void error(const Twine &Err, const DWARFDie *DIE = nullptr) {557 GlobalData.warn(Err, getUnitName(), DIE);558 }559 560 void error(Error Err, const DWARFDie *DIE = nullptr) {561 handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) {562 GlobalData.error(Info.message(), getUnitName(), DIE);563 });564 }565 566 /// @}567 568 /// Save specified accelerator info \p Info.569 void saveAcceleratorInfo(const DwarfUnit::AccelInfo &Info) {570 AcceleratorRecords.add(Info);571 }572 573 /// Enumerates all units accelerator records.574 void575 forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override {576 AcceleratorRecords.forEach(Handler);577 }578 579 /// Output unit selector.580 class OutputUnitVariantPtr {581 public:582 OutputUnitVariantPtr(CompileUnit *U);583 OutputUnitVariantPtr(TypeUnit *U);584 585 /// Accessor for common functionality.586 DwarfUnit *operator->();587 588 bool isCompileUnit();589 590 bool isTypeUnit();591 592 /// Returns CompileUnit if applicable.593 CompileUnit *getAsCompileUnit();594 595 /// Returns TypeUnit if applicable.596 TypeUnit *getAsTypeUnit();597 598 protected:599 PointerUnion<CompileUnit *, TypeUnit *> Ptr;600 };601 602private:603 /// Navigate DWARF tree recursively and set die properties.604 void analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,605 bool IsODRUnavailableFunctionScope);606 607 struct LinkedLocationExpressionsWithOffsetPatches {608 DWARFLocationExpression Expression;609 OffsetsPtrVector Patches;610 };611 using LinkedLocationExpressionsVector =612 SmallVector<LinkedLocationExpressionsWithOffsetPatches>;613 614 /// Emit debug locations.615 void emitLocations(DebugSectionKind LocationSectionKind);616 617 /// Emit location list header.618 uint64_t emitLocListHeader(SectionDescriptor &OutLocationSection);619 620 /// Emit location list fragment.621 uint64_t emitLocListFragment(622 const LinkedLocationExpressionsVector &LinkedLocationExpression,623 SectionDescriptor &OutLocationSection);624 625 /// Emit the .debug_addr section fragment for current unit.626 Error emitDebugAddrSection();627 628 /// Emit .debug_aranges.629 void emitAranges(AddressRanges &LinkedFunctionRanges);630 631 /// Clone and emit .debug_ranges/.debug_rnglists.632 void cloneAndEmitRangeList(DebugSectionKind RngSectionKind,633 AddressRanges &LinkedFunctionRanges);634 635 /// Emit range list header.636 uint64_t emitRangeListHeader(SectionDescriptor &OutRangeSection);637 638 /// Emit range list fragment.639 void emitRangeListFragment(const AddressRanges &LinkedRanges,640 SectionDescriptor &OutRangeSection);641 642 /// Insert the new line info sequence \p Seq into the current643 /// set of already linked line info \p Rows.644 void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,645 std::vector<DWARFDebugLine::Row> &Rows);646 647 /// Emits body for both macro sections.648 void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,649 uint64_t OffsetToMacroTable, bool hasDWARFv5Header);650 651 /// Creates DIE which would be placed into the "Plain" compile unit.652 DIE *createPlainDIEandCloneAttributes(653 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,654 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,655 std::optional<int64_t> &VarAddressAdjustment);656 657 /// Creates DIE which would be placed into the "Type" compile unit.658 TypeEntry *createTypeDIEandCloneAttributes(659 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,660 TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit);661 662 /// Create output DIE inside specified \p TypeDescriptor.663 DIE *allocateTypeDie(TypeEntryBody *TypeDescriptor,664 DIEGenerator &TypeDIEGenerator, dwarf::Tag DieTag,665 bool IsDeclaration, bool IsParentDeclaration);666 667 /// Enumerate \p DieEntry children and assign names for them.668 Error assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,669 SyntheticTypeNameBuilder &NameBuilder);670 671 /// DWARFFile containing this compile unit.672 DWARFFile &File;673 674 /// Pointer to the paired compile unit from the input DWARF.675 DWARFUnit *OrigUnit = nullptr;676 677 /// The DW_AT_language of this unit.678 std::optional<uint16_t> Language;679 680 /// Line table for this unit.681 const DWARFDebugLine::LineTable *LineTablePtr = nullptr;682 683 /// Cached resolved paths from the line table.684 /// The key is <UniqueUnitID, FileIdx>.685 using ResolvedPathsMap = DenseMap<unsigned, StringEntry *>;686 ResolvedPathsMap ResolvedFullPaths;687 StringMap<StringEntry *> ResolvedParentPaths;688 689 /// Maps an address into the index inside .debug_addr section.690 IndexedValuesMap<uint64_t> DebugAddrIndexMap;691 692 std::unique_ptr<DependencyTracker> Dependencies;693 694 /// \defgroup Data Members accessed asinchronously.695 ///696 /// @{697 OffsetToUnitTy getUnitFromOffset;698 699 std::optional<uint64_t> LowPc;700 uint64_t HighPc = 0;701 702 /// Flag indicating whether type de-duplication is forbidden.703 bool NoODR = true;704 705 /// The ranges in that map are the PC ranges for functions in this unit,706 /// associated with the PC offset to apply to the addresses to get707 /// the linked address.708 RangesTy Ranges;709 std::mutex RangesMutex;710 711 /// The DW_AT_low_pc of each DW_TAG_label.712 using LabelMapTy = SmallDenseMap<uint64_t, uint64_t, 1>;713 LabelMapTy Labels;714 std::mutex LabelsMutex;715 716 /// This field keeps current stage of overall compile unit processing.717 std::atomic<Stage> Stage;718 719 /// DIE info indexed by DIE index.720 SmallVector<DIEInfo> DieInfoArray;721 SmallVector<uint64_t> OutDieOffsetArray;722 SmallVector<TypeEntry *> TypeEntries;723 724 /// The list of accelerator records for this unit.725 ArrayList<AccelInfo> AcceleratorRecords;726 /// @}727};728 729/// \returns list of attributes referencing type DIEs which might be730/// deduplicated.731/// Note: it does not include DW_AT_containing_type attribute to avoid732/// infinite recursion.733ArrayRef<dwarf::Attribute> getODRAttributes();734 735} // end of namespace parallel736} // end of namespace dwarf_linker737} // end of namespace llvm738 739#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H740