1 //===- DWARFLinkerTypeUnit.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H 10 #define LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H 11 12 #include "DWARFLinkerUnit.h" 13 #include "llvm/CodeGen/DIE.h" 14 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 15 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 16 17 namespace llvm { 18 namespace dwarf_linker { 19 namespace parallel { 20 21 /// Type Unit is used to represent an artificial compilation unit 22 /// which keeps all type information. This type information is referenced 23 /// from other compilation units. 24 class TypeUnit : public DwarfUnit { 25 public: 26 TypeUnit(LinkingGlobalData &GlobalData, unsigned ID, 27 std::optional<uint16_t> Language, dwarf::FormParams Format, 28 llvm::endianness Endianess); 29 30 /// Generates DIE tree based on information from TypesMap. 31 void createDIETree(BumpPtrAllocator &Allocator); 32 33 /// Emits resulting dwarf based on information from DIE tree. 34 Error finishCloningAndEmit(const Triple &TargetTriple); 35 36 /// Returns global type pool. 37 TypePool &getTypePool() { return Types; } 38 39 /// TypeUnitAccelInfo extends AccelInfo structure with type specific fileds. 40 /// We need these additional fields to decide whether OutDIE should have an 41 /// accelerator record or not. The TypeEntryBodyPtr can refer to the 42 /// declaration DIE and definition DIE corresponding to the type entry. 43 /// Only one of them would be used in final output. So if TypeUnitAccelInfo 44 /// refers OutDIE which does not match with TypeEntryBodyPtr->getFinalDie() 45 /// then such record should be skipped. 46 struct TypeUnitAccelInfo : public AccelInfo { 47 /// Pointer to the output DIE which owns this accelerator record. 48 DIE *OutDIE = nullptr; 49 50 /// Pointer to the type entry body. 51 TypeEntryBody *TypeEntryBodyPtr = nullptr; 52 }; 53 54 /// Enumerates all accelerator records and call \p Handler for each. 55 void 56 forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override { 57 AcceleratorRecords.forEach([&](TypeUnitAccelInfo &Info) { 58 // Check whether current record is for the final DIE. 59 assert(Info.TypeEntryBodyPtr != nullptr); 60 61 if (&Info.TypeEntryBodyPtr->getFinalDie() != Info.OutDIE) 62 return; 63 64 Info.OutOffset = Info.OutDIE->getOffset(); 65 Handler(Info); 66 }); 67 } 68 69 /// Returns index for the specified \p String inside .debug_str_offsets. 70 uint64_t getDebugStrIndex(const StringEntry *String) override { 71 std::unique_lock<std::mutex> LockGuard(DebugStringIndexMapMutex); 72 return DebugStringIndexMap.getValueIndex(String); 73 } 74 75 /// Adds \p Info to the unit's accelerator records. 76 void saveAcceleratorInfo(const TypeUnitAccelInfo &Info) { 77 AcceleratorRecords.add(Info); 78 } 79 80 private: 81 /// Type DIEs are partially created at clonning stage. They are organised 82 /// as a tree using type entries. This function links DIEs(corresponding 83 /// to the type entries) into the tree structure. 84 uint64_t finalizeTypeEntryRec(uint64_t OutOffset, DIE *OutDIE, 85 TypeEntry *Entry); 86 87 /// Prepares DIEs to be linked into the tree. 88 void prepareDataForTreeCreation(); 89 90 /// Add specified \p Dir and \p Filename into the line table 91 /// of this type unit. 92 uint32_t addFileNameIntoLinetable(StringEntry *Dir, StringEntry *FileName); 93 94 std::pair<dwarf::Form, uint8_t> getScalarFormForValue(uint64_t Value) const; 95 96 uint8_t getSizeByAttrForm(dwarf::Form Form) const; 97 98 struct CmpStringEntryRef { 99 bool operator()(const StringEntry *LHS, const StringEntry *RHS) const { 100 return LHS->first() < RHS->first(); 101 } 102 }; 103 struct CmpDirIDStringEntryRef { 104 bool operator()(const std::pair<StringEntry *, uint64_t> &LHS, 105 const std::pair<StringEntry *, uint64_t> &RHS) const { 106 return LHS.second < RHS.second || 107 (!(RHS.second < LHS.second) && 108 LHS.first->first() < RHS.first->first()); 109 } 110 }; 111 112 /// The DW_AT_language of this unit. 113 std::optional<uint16_t> Language; 114 115 /// This unit line table. 116 DWARFDebugLine::LineTable LineTable; 117 118 /// Data members keeping file names for line table. 119 using DirectoriesMapTy = std::map<StringEntry *, size_t, CmpStringEntryRef>; 120 using FilenamesMapTy = std::map<std::pair<StringEntry *, uint64_t>, size_t, 121 CmpDirIDStringEntryRef>; 122 123 DirectoriesMapTy DirectoriesMap; 124 FilenamesMapTy FileNamesMap; 125 126 /// Type DIEs tree. 127 TypePool Types; 128 129 /// List of accelerator entries for this unit. 130 ArrayList<TypeUnitAccelInfo> AcceleratorRecords; 131 132 /// Guard for DebugStringIndexMap. 133 std::mutex DebugStringIndexMapMutex; 134 }; 135 136 } // end of namespace parallel 137 } // end of namespace dwarf_linker 138 } // end of namespace llvm 139 140 #endif // LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H 141