1 //===- BTFDebug.h -----------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file contains support for writing BTF debug info.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H
16 #define LLVM_LIB_TARGET_BPF_BTFDEBUG_H
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/CodeGen/DebugHandlerBase.h"
20 #include <unordered_map>
30 class MachineFunction;
32 /// The base class for BTF type generation.
37 struct BTF::CommonType BTFType;
40 virtual ~BTFTypeBase() = default;
41 void setId(uint32_t Id) { this->Id = Id; }
42 uint32_t getId() { return Id; }
43 uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }
44 /// Get the size of this BTF type entry.
45 virtual uint32_t getSize() { return BTF::CommonTypeSize; }
46 /// Complete BTF type generation after all related DebugInfo types
47 /// have been visited so their BTF type id's are available
48 /// for cross referece.
49 virtual void completeType(BTFDebug &BDebug) {}
50 /// Emit types for this BTF type entry.
51 virtual void emitType(MCStreamer &OS);
54 /// Handle several derived types include pointer, const,
55 /// volatile, typedef and restrict.
56 class BTFTypeDerived : public BTFTypeBase {
57 const DIDerivedType *DTy;
60 BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag);
61 void completeType(BTFDebug &BDebug);
62 void emitType(MCStreamer &OS);
65 /// Handle struct or union forward declaration.
66 class BTFTypeFwd : public BTFTypeBase {
70 BTFTypeFwd(StringRef Name, bool IsUnion);
71 void completeType(BTFDebug &BDebug);
72 void emitType(MCStreamer &OS);
76 class BTFTypeInt : public BTFTypeBase {
78 uint32_t IntVal; ///< Encoding, offset, bits
81 BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,
83 uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); }
84 void completeType(BTFDebug &BDebug);
85 void emitType(MCStreamer &OS);
88 /// Handle enumerate type.
89 class BTFTypeEnum : public BTFTypeBase {
90 const DICompositeType *ETy;
91 std::vector<struct BTF::BTFEnum> EnumValues;
94 BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues);
96 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;
98 void completeType(BTFDebug &BDebug);
99 void emitType(MCStreamer &OS);
102 /// Handle array type.
103 class BTFTypeArray : public BTFTypeBase {
104 const DICompositeType *ATy;
105 struct BTF::BTFArray ArrayInfo;
108 BTFTypeArray(const DICompositeType *ATy);
109 uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
110 void completeType(BTFDebug &BDebug);
111 void emitType(MCStreamer &OS);
114 /// Handle struct/union type.
115 class BTFTypeStruct : public BTFTypeBase {
116 const DICompositeType *STy;
118 std::vector<struct BTF::BTFMember> Members;
121 BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
122 uint32_t NumMembers);
124 return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
126 void completeType(BTFDebug &BDebug);
127 void emitType(MCStreamer &OS);
130 /// Handle function pointer.
131 class BTFTypeFuncProto : public BTFTypeBase {
132 const DISubroutineType *STy;
133 std::unordered_map<uint32_t, StringRef> FuncArgNames;
134 std::vector<struct BTF::BTFParam> Parameters;
137 BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
138 const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
140 return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
142 void completeType(BTFDebug &BDebug);
143 void emitType(MCStreamer &OS);
146 /// Handle subprogram
147 class BTFTypeFunc : public BTFTypeBase {
151 BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId);
152 uint32_t getSize() { return BTFTypeBase::getSize(); }
153 void completeType(BTFDebug &BDebug);
154 void emitType(MCStreamer &OS);
158 class BTFStringTable {
159 /// String table size in bytes.
161 /// A mapping from string table offset to the index
162 /// of the Table. It is used to avoid putting
163 /// duplicated strings in the table.
164 std::unordered_map<uint32_t, uint32_t> OffsetToIdMap;
165 /// A vector of strings to represent the string table.
166 std::vector<std::string> Table;
169 BTFStringTable() : Size(0) {}
170 uint32_t getSize() { return Size; }
171 std::vector<std::string> &getTable() { return Table; }
172 /// Add a string to the string table and returns its offset
174 uint32_t addString(StringRef S);
177 /// Represent one func and its type id.
179 const MCSymbol *Label; ///< Func MCSymbol
180 uint32_t TypeId; ///< Type id referring to .BTF type section
183 /// Represent one line info.
185 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo
186 uint32_t FileNameOff; ///< file name offset in the .BTF string table
187 uint32_t LineOff; ///< line offset in the .BTF string table
188 uint32_t LineNum; ///< the line number
189 uint32_t ColumnNum; ///< the column number
192 /// Collect and emit BTF information.
193 class BTFDebug : public DebugHandlerBase {
195 bool SkipInstruction;
196 bool LineInfoGenerated;
198 uint32_t ArrayIndexTypeId;
199 BTFStringTable StringTable;
200 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
201 std::unordered_map<const DIType *, uint32_t> DIToIdMap;
202 std::unordered_map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
203 std::unordered_map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
204 StringMap<std::vector<std::string>> FileContent;
206 /// Add types to TypeEntries.
208 /// Add types to TypeEntries and DIToIdMap.
209 void addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
210 /// Add types to TypeEntries only and return type id.
211 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
214 /// IR type visiting functions.
216 void visitTypeEntry(const DIType *Ty);
217 void visitBasicType(const DIBasicType *BTy);
218 void visitSubroutineType(
219 const DISubroutineType *STy, bool ForSubprog,
220 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
222 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion);
223 void visitCompositeType(const DICompositeType *CTy);
224 void visitStructType(const DICompositeType *STy, bool IsStruct);
225 void visitArrayType(const DICompositeType *ATy);
226 void visitEnumType(const DICompositeType *ETy);
227 void visitDerivedType(const DIDerivedType *DTy);
230 /// Get the file content for the subprogram. Certain lines of the file
231 /// later may be put into string table and referenced by line info.
232 std::string populateFileContent(const DISubprogram *SP);
234 /// Construct a line info.
235 void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line,
238 /// Emit common header of .BTF and .BTF.ext sections.
239 void emitCommonHeader();
241 /// Emit the .BTF section.
242 void emitBTFSection();
244 /// Emit the .BTF.ext section.
245 void emitBTFExtSection();
248 /// Gather pre-function debug information.
249 void beginFunctionImpl(const MachineFunction *MF) override;
251 /// Post process after all instructions in this function are processed.
252 void endFunctionImpl(const MachineFunction *MF) override;
255 BTFDebug(AsmPrinter *AP);
257 /// Get the special array index type id.
258 uint32_t getArrayIndexTypeId() {
259 assert(ArrayIndexTypeId);
260 return ArrayIndexTypeId;
263 /// Add string to the string table.
264 size_t addString(StringRef S) { return StringTable.addString(S); }
266 /// Get the type id for a particular DIType.
267 uint32_t getTypeId(const DIType *Ty) {
268 assert(Ty && "Invalid null Type");
269 assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
270 "DIType not added in the BDIToIdMap");
271 return DIToIdMap[Ty];
274 void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {}
276 /// Process beginning of an instruction.
277 void beginInstruction(const MachineInstr *MI) override;
279 /// Complete all the types and emit the BTF sections.
280 void endModule() override;
283 } // end namespace llvm