1//===- bolt/Core/DebugNames.h - Debug names support ---*- 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// This file contains declaration of classes required for generation of
10// .debug_names section.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef BOLT_CORE_DEBUG_NAMES_H
15#define BOLT_CORE_DEBUG_NAMES_H
16
17#include "bolt/Core/DebugData.h"
18#include "llvm/CodeGen/AccelTable.h"
19
20namespace llvm {
21namespace bolt {
22class BOLTDWARF5AccelTableData : public DWARF5AccelTableData {
23public:
24 BOLTDWARF5AccelTableData(const uint64_t DieOffset,
25 const std::optional<uint64_t> DefiningParentOffset,
26 const unsigned DieTag, const unsigned UnitID,
27 const bool IsTU,
28 const std::optional<unsigned> SecondUnitID)
29 : DWARF5AccelTableData(DieOffset, DefiningParentOffset, DieTag, UnitID,
30 IsTU),
31 SecondUnitID(SecondUnitID) {}
32
33 uint64_t getDieOffset() const { return DWARF5AccelTableData::getDieOffset(); }
34 unsigned getDieTag() const { return DWARF5AccelTableData::getDieTag(); }
35 unsigned getUnitID() const { return DWARF5AccelTableData::getUnitID(); }
36 bool isTU() const { return DWARF5AccelTableData::isTU(); }
37 std::optional<unsigned> getSecondUnitID() const { return SecondUnitID; }
38
39 void setPatchOffset(uint64_t PatchOffset) { OffsetVal = PatchOffset; }
40 uint64_t getPatchOffset() const { return std::get<uint64_t>(v: OffsetVal); }
41
42private:
43 std::optional<unsigned> SecondUnitID;
44};
45
46class DWARF5AcceleratorTable {
47public:
48 DWARF5AcceleratorTable(const bool CreateDebugNames, BinaryContext &BC,
49 DebugStrWriter &MainBinaryStrWriter);
50 ~DWARF5AcceleratorTable() {
51 for (DebugNamesAbbrev *Abbrev : AbbreviationsVector)
52 Abbrev->~DebugNamesAbbrev();
53 }
54 /// Add DWARF5 Accelerator table entry.
55 /// Input is DWARFUnit being processed, DIE that belongs to it, potential
56 /// DWOID if the Unit comes from a DWO section, and potential parent entry.
57 std::optional<BOLTDWARF5AccelTableData *>
58 addAccelTableEntry(DWARFUnit &Unit, const DIE &Die,
59 const std::optional<uint64_t> &DWOID,
60 std::optional<BOLTDWARF5AccelTableData *> &Parent);
61 /// Set current unit being processed.
62 void setCurrentUnit(DWARFUnit &Unit, const uint64_t UnitStartOffset);
63 /// Emit Accelerator table.
64 void emitAccelTable();
65 /// Returns true if the table was crated.
66 bool isCreated() const { return NeedToCreate; }
67 /// Returns buffer containing the accelerator table.
68 std::unique_ptr<DebugBufferVector> releaseBuffer() {
69 return std::move(FullTableBuffer);
70 }
71 /// Adds a DIE that is referenced across CUs.
72 void addCrossCUDie(const DIE *Die) {
73 CrossCUDies.insert(KV: {Die->getOffset(), Die});
74 }
75 /// Returns true if the DIE can generate an entry for a cross cu reference.
76 /// This only checks TAGs of a DIE because when this is invoked DIE might not
77 /// be fully constructed.
78 bool canGenerateEntryWithCrossCUReference(
79 const DWARFUnit &Unit, const DIE &Die,
80 const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);
81
82private:
83 BinaryContext &BC;
84 bool NeedToCreate = false;
85 BumpPtrAllocator Allocator;
86 DebugStrWriter &MainBinaryStrWriter;
87 StringRef StrSection;
88 uint64_t CurrentUnitOffset = 0;
89 const DWARFUnit *CurrentUnit = nullptr;
90 std::unordered_map<uint32_t, uint32_t> AbbrevTagToIndexMap;
91
92 /// Represents a group of entries with identical name (and hence, hash value).
93 struct HashData {
94 uint64_t StrOffset;
95 uint32_t HashValue;
96 uint32_t EntryOffset;
97 std::vector<BOLTDWARF5AccelTableData *> Values;
98 };
99 using HashList = std::vector<HashData *>;
100 using BucketList = std::vector<HashList>;
101 /// Contains all the offsets of CUs.
102 SmallVector<uint32_t, 1> CUList;
103 /// Contains all the offsets of local TUs.
104 SmallVector<uint32_t, 1> LocalTUList;
105 /// Contains all the type hashes for split dwarf TUs.
106 SmallVector<uint64_t, 1> ForeignTUList;
107 using StringEntries =
108 MapVector<std::string, HashData, llvm::StringMap<unsigned>>;
109 StringEntries Entries;
110 /// FoldingSet that uniques the abbreviations.
111 FoldingSet<DebugNamesAbbrev> AbbreviationsSet;
112 /// Vector containing DebugNames abbreviations for iteration in order.
113 SmallVector<DebugNamesAbbrev *, 5> AbbreviationsVector;
114 /// The bump allocator to use when creating DIEAbbrev objects in the uniqued
115 /// storage container.
116 BumpPtrAllocator Alloc;
117 uint32_t BucketCount = 0;
118 uint32_t UniqueHashCount = 0;
119 uint32_t AbbrevTableSize = 0;
120 uint32_t CUIndexEncodingSize = 4;
121 uint32_t TUIndexEncodingSize = 4;
122 uint32_t AugmentationStringSize = 0;
123 dwarf::Form CUIndexForm = dwarf::DW_FORM_data4;
124 dwarf::Form TUIndexForm = dwarf::DW_FORM_data4;
125
126 BucketList Buckets;
127
128 std::unique_ptr<DebugBufferVector> FullTableBuffer;
129 std::unique_ptr<raw_svector_ostream> FullTableStream;
130 std::unique_ptr<DebugBufferVector> StrBuffer;
131 std::unique_ptr<raw_svector_ostream> StrStream;
132 std::unique_ptr<DebugBufferVector> EntriesBuffer;
133 std::unique_ptr<raw_svector_ostream> Entriestream;
134 std::unique_ptr<DebugBufferVector> AugStringBuffer;
135 std::unique_ptr<raw_svector_ostream> AugStringtream;
136 llvm::DenseMap<llvm::hash_code, uint64_t> StrCacheToOffsetMap;
137 // Contains DWO ID to CUList Index.
138 llvm::DenseMap<uint64_t, uint32_t> CUOffsetsToPatch;
139 // Contains a map of Entry ID to Entry relative offset.
140 llvm::DenseMap<uint64_t, uint32_t> EntryRelativeOffsets;
141 llvm::DenseMap<uint64_t, const DIE *> CrossCUDies;
142 /// Adds Unit to either CUList, LocalTUList or ForeignTUList.
143 /// Input Unit being processed, and DWO ID if Unit is being processed comes
144 /// from a DWO section.
145 void addUnit(DWARFUnit &Unit, const std::optional<uint64_t> &DWOID);
146 /// Returns number of buckets in .debug_name table.
147 ArrayRef<HashList> getBuckets() const { return Buckets; }
148 /// Get encoding for a given attribute.
149 std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
150 getIndexForEntry(const BOLTDWARF5AccelTableData &Value) const;
151 /// Get encoding for a given attribute for second index.
152 /// Returns nullopt if there is no second index.
153 std::optional<DWARF5AccelTable::UnitIndexAndEncoding>
154 getSecondIndexForEntry(const BOLTDWARF5AccelTableData &Value) const;
155 /// Uniquify Entries.
156 void finalize();
157 /// Computes bucket count.
158 void computeBucketCount();
159 /// Populate Abbreviations Map.
160 void populateAbbrevsMap();
161 /// Write Entries.
162 void writeEntries();
163 /// Write an Entry.
164 void writeEntry(BOLTDWARF5AccelTableData &Entry);
165 /// Write augmentation_string for BOLT.
166 void writeAugmentationString();
167 /// Emit out Header for DWARF5 Accelerator table.
168 void emitHeader() const;
169 /// Emit out CU list.
170 void emitCUList() const;
171 /// Emit out TU List. Combination of LocalTUList and ForeignTUList.
172 void emitTUList() const;
173 /// Emit buckets.
174 void emitBuckets() const;
175 /// Emit hashes for hash table.
176 void emitHashes() const;
177 /// Emit string offsets for hash table.
178 void emitStringOffsets() const;
179 /// Emit Entry Offsets for hash table.
180 void emitOffsets() const;
181 /// Emit abbreviation table.
182 void emitAbbrevs();
183 /// Emit entries.
184 void emitData();
185 /// Emit augmentation string.
186 void emitAugmentationString() const;
187};
188} // namespace bolt
189} // namespace llvm
190#endif
191

source code of bolt/include/bolt/Core/DebugNames.h