blob: 016cc985283442ea557e1ac170e55c29ec5378bd [file] [log] [blame]
Yonghong Song7b410ac2018-12-19 16:40:25 +00001//===- BTFDebug.h -----------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Yonghong Song7b410ac2018-12-19 16:40:25 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file contains support for writing BTF debug info.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H
15#define LLVM_LIB_TARGET_BPF_BTFDEBUG_H
16
17#include "llvm/ADT/StringMap.h"
18#include "llvm/CodeGen/DebugHandlerBase.h"
19#include <unordered_map>
20#include "BTF.h"
21
22namespace llvm {
23
24class AsmPrinter;
25class BTFDebug;
26class DIType;
27class MCStreamer;
28class MCSymbol;
29class MachineFunction;
30
31/// The base class for BTF type generation.
32class BTFTypeBase {
33protected:
34 uint8_t Kind;
35 uint32_t Id;
36 struct BTF::CommonType BTFType;
37
38public:
39 virtual ~BTFTypeBase() = default;
40 void setId(uint32_t Id) { this->Id = Id; }
41 uint32_t getId() { return Id; }
42 uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }
43 /// Get the size of this BTF type entry.
44 virtual uint32_t getSize() { return BTF::CommonTypeSize; }
45 /// Complete BTF type generation after all related DebugInfo types
46 /// have been visited so their BTF type id's are available
47 /// for cross referece.
48 virtual void completeType(BTFDebug &BDebug) {}
49 /// Emit types for this BTF type entry.
50 virtual void emitType(MCStreamer &OS);
51};
52
53/// Handle several derived types include pointer, const,
54/// volatile, typedef and restrict.
55class BTFTypeDerived : public BTFTypeBase {
56 const DIDerivedType *DTy;
57
58public:
59 BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag);
60 void completeType(BTFDebug &BDebug);
61 void emitType(MCStreamer &OS);
62};
63
64/// Handle struct or union forward declaration.
65class BTFTypeFwd : public BTFTypeBase {
66 StringRef Name;
67
68public:
69 BTFTypeFwd(StringRef Name, bool IsUnion);
70 void completeType(BTFDebug &BDebug);
71 void emitType(MCStreamer &OS);
72};
73
74/// Handle int type.
75class BTFTypeInt : public BTFTypeBase {
76 StringRef Name;
77 uint32_t IntVal; ///< Encoding, offset, bits
78
79public:
80 BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,
81 StringRef TypeName);
82 uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); }
83 void completeType(BTFDebug &BDebug);
84 void emitType(MCStreamer &OS);
85};
86
87/// Handle enumerate type.
88class BTFTypeEnum : public BTFTypeBase {
89 const DICompositeType *ETy;
90 std::vector<struct BTF::BTFEnum> EnumValues;
91
92public:
93 BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues);
94 uint32_t getSize() {
95 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;
96 }
97 void completeType(BTFDebug &BDebug);
98 void emitType(MCStreamer &OS);
99};
100
101/// Handle array type.
102class BTFTypeArray : public BTFTypeBase {
103 const DICompositeType *ATy;
104 struct BTF::BTFArray ArrayInfo;
105
106public:
107 BTFTypeArray(const DICompositeType *ATy);
108 uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
109 void completeType(BTFDebug &BDebug);
110 void emitType(MCStreamer &OS);
111};
112
113/// Handle struct/union type.
114class BTFTypeStruct : public BTFTypeBase {
115 const DICompositeType *STy;
116 bool HasBitField;
117 std::vector<struct BTF::BTFMember> Members;
118
119public:
120 BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
121 uint32_t NumMembers);
122 uint32_t getSize() {
123 return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
124 }
125 void completeType(BTFDebug &BDebug);
126 void emitType(MCStreamer &OS);
127};
128
129/// Handle function pointer.
130class BTFTypeFuncProto : public BTFTypeBase {
131 const DISubroutineType *STy;
132 std::unordered_map<uint32_t, StringRef> FuncArgNames;
133 std::vector<struct BTF::BTFParam> Parameters;
134
135public:
136 BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
137 const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
138 uint32_t getSize() {
139 return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
140 }
141 void completeType(BTFDebug &BDebug);
142 void emitType(MCStreamer &OS);
143};
144
145/// Handle subprogram
146class BTFTypeFunc : public BTFTypeBase {
147 StringRef Name;
148
149public:
150 BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId);
151 uint32_t getSize() { return BTFTypeBase::getSize(); }
152 void completeType(BTFDebug &BDebug);
153 void emitType(MCStreamer &OS);
154};
155
Yonghong Song6db6b562019-03-16 15:36:31 +0000156/// Handle variable instances
157class BTFKindVar : public BTFTypeBase {
158 StringRef Name;
159 uint32_t Info;
160
161public:
162 BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);
163 uint32_t getSize() { return BTFTypeBase::getSize() + 4; }
164 void completeType(BTFDebug &BDebug);
165 void emitType(MCStreamer &OS);
166};
167
168/// Handle data sections
169class BTFKindDataSec : public BTFTypeBase {
170 AsmPrinter *Asm;
171 std::string Name;
172 std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
173
174public:
175 BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);
176 uint32_t getSize() {
177 return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
178 }
179 void addVar(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
180 Vars.push_back(std::make_tuple(Id, Sym, Size));
181 }
182 std::string getName() { return Name; }
183 void completeType(BTFDebug &BDebug);
184 void emitType(MCStreamer &OS);
185};
186
Yonghong Song7b410ac2018-12-19 16:40:25 +0000187/// String table.
188class BTFStringTable {
189 /// String table size in bytes.
190 uint32_t Size;
191 /// A mapping from string table offset to the index
192 /// of the Table. It is used to avoid putting
193 /// duplicated strings in the table.
194 std::unordered_map<uint32_t, uint32_t> OffsetToIdMap;
195 /// A vector of strings to represent the string table.
196 std::vector<std::string> Table;
197
198public:
199 BTFStringTable() : Size(0) {}
200 uint32_t getSize() { return Size; }
201 std::vector<std::string> &getTable() { return Table; }
202 /// Add a string to the string table and returns its offset
203 /// in the table.
204 uint32_t addString(StringRef S);
205};
206
207/// Represent one func and its type id.
208struct BTFFuncInfo {
209 const MCSymbol *Label; ///< Func MCSymbol
210 uint32_t TypeId; ///< Type id referring to .BTF type section
211};
212
213/// Represent one line info.
214struct BTFLineInfo {
215 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo
216 uint32_t FileNameOff; ///< file name offset in the .BTF string table
217 uint32_t LineOff; ///< line offset in the .BTF string table
218 uint32_t LineNum; ///< the line number
219 uint32_t ColumnNum; ///< the column number
220};
221
222/// Collect and emit BTF information.
223class BTFDebug : public DebugHandlerBase {
224 MCStreamer &OS;
225 bool SkipInstruction;
226 bool LineInfoGenerated;
227 uint32_t SecNameOff;
228 uint32_t ArrayIndexTypeId;
229 BTFStringTable StringTable;
230 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
231 std::unordered_map<const DIType *, uint32_t> DIToIdMap;
232 std::unordered_map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
233 std::unordered_map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
234 StringMap<std::vector<std::string>> FileContent;
Yonghong Song6db6b562019-03-16 15:36:31 +0000235 std::unordered_map<std::string, std::unique_ptr<BTFKindDataSec>>
236 DataSecEntries;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000237
238 /// Add types to TypeEntries.
239 /// @{
240 /// Add types to TypeEntries and DIToIdMap.
Yonghong Song6db6b562019-03-16 15:36:31 +0000241 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000242 /// Add types to TypeEntries only and return type id.
243 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
244 /// @}
245
246 /// IR type visiting functions.
247 /// @{
248 void visitTypeEntry(const DIType *Ty);
Yonghong Song6db6b562019-03-16 15:36:31 +0000249 void visitTypeEntry(const DIType *Ty, uint32_t &TypeId);
250 void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000251 void visitSubroutineType(
252 const DISubroutineType *STy, bool ForSubprog,
253 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
254 uint32_t &TypeId);
Yonghong Song6db6b562019-03-16 15:36:31 +0000255 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
256 uint32_t &TypeId);
257 void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);
258 void visitStructType(const DICompositeType *STy, bool IsStruct,
259 uint32_t &TypeId);
260 void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);
261 void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);
262 void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000263 /// @}
264
265 /// Get the file content for the subprogram. Certain lines of the file
266 /// later may be put into string table and referenced by line info.
267 std::string populateFileContent(const DISubprogram *SP);
268
269 /// Construct a line info.
270 void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line,
271 uint32_t Column);
272
Yonghong Song6db6b562019-03-16 15:36:31 +0000273 /// Generate types and variables for globals.
274 void processGlobals(void);
275
Yonghong Song7b410ac2018-12-19 16:40:25 +0000276 /// Emit common header of .BTF and .BTF.ext sections.
277 void emitCommonHeader();
278
279 /// Emit the .BTF section.
280 void emitBTFSection();
281
282 /// Emit the .BTF.ext section.
283 void emitBTFExtSection();
284
285protected:
286 /// Gather pre-function debug information.
287 void beginFunctionImpl(const MachineFunction *MF) override;
288
289 /// Post process after all instructions in this function are processed.
290 void endFunctionImpl(const MachineFunction *MF) override;
291
292public:
293 BTFDebug(AsmPrinter *AP);
294
295 /// Get the special array index type id.
296 uint32_t getArrayIndexTypeId() {
297 assert(ArrayIndexTypeId);
298 return ArrayIndexTypeId;
299 }
300
301 /// Add string to the string table.
302 size_t addString(StringRef S) { return StringTable.addString(S); }
303
304 /// Get the type id for a particular DIType.
305 uint32_t getTypeId(const DIType *Ty) {
306 assert(Ty && "Invalid null Type");
307 assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
308 "DIType not added in the BDIToIdMap");
309 return DIToIdMap[Ty];
310 }
311
312 void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {}
313
314 /// Process beginning of an instruction.
315 void beginInstruction(const MachineInstr *MI) override;
316
317 /// Complete all the types and emit the BTF sections.
318 void endModule() override;
319};
320
321} // end namespace llvm
322
323#endif