blob: c0d3f36fa8be3aea5be92cc108eba7fcf0fbd7e5 [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;
Yonghong Songd3d88d02019-07-09 15:28:41 +000035 bool IsCompleted;
Yonghong Song7b410ac2018-12-19 16:40:25 +000036 uint32_t Id;
37 struct BTF::CommonType BTFType;
38
39public:
Yonghong Songd3d88d02019-07-09 15:28:41 +000040 BTFTypeBase() : IsCompleted(false) {}
Yonghong Song7b410ac2018-12-19 16:40:25 +000041 virtual ~BTFTypeBase() = default;
42 void setId(uint32_t Id) { this->Id = Id; }
43 uint32_t getId() { return Id; }
44 uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }
45 /// Get the size of this BTF type entry.
46 virtual uint32_t getSize() { return BTF::CommonTypeSize; }
47 /// Complete BTF type generation after all related DebugInfo types
48 /// have been visited so their BTF type id's are available
49 /// for cross referece.
50 virtual void completeType(BTFDebug &BDebug) {}
51 /// Emit types for this BTF type entry.
52 virtual void emitType(MCStreamer &OS);
53};
54
55/// Handle several derived types include pointer, const,
56/// volatile, typedef and restrict.
57class BTFTypeDerived : public BTFTypeBase {
58 const DIDerivedType *DTy;
Yonghong Songd3d88d02019-07-09 15:28:41 +000059 bool NeedsFixup;
Yonghong Song7b410ac2018-12-19 16:40:25 +000060
61public:
Yonghong Songd3d88d02019-07-09 15:28:41 +000062 BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);
Yonghong Song7b410ac2018-12-19 16:40:25 +000063 void completeType(BTFDebug &BDebug);
64 void emitType(MCStreamer &OS);
Yonghong Songd3d88d02019-07-09 15:28:41 +000065 void setPointeeType(uint32_t PointeeType);
Yonghong Song7b410ac2018-12-19 16:40:25 +000066};
67
68/// Handle struct or union forward declaration.
69class BTFTypeFwd : public BTFTypeBase {
70 StringRef Name;
71
72public:
73 BTFTypeFwd(StringRef Name, bool IsUnion);
74 void completeType(BTFDebug &BDebug);
75 void emitType(MCStreamer &OS);
76};
77
78/// Handle int type.
79class BTFTypeInt : public BTFTypeBase {
80 StringRef Name;
81 uint32_t IntVal; ///< Encoding, offset, bits
82
83public:
84 BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,
85 StringRef TypeName);
86 uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); }
87 void completeType(BTFDebug &BDebug);
88 void emitType(MCStreamer &OS);
89};
90
91/// Handle enumerate type.
92class BTFTypeEnum : public BTFTypeBase {
93 const DICompositeType *ETy;
94 std::vector<struct BTF::BTFEnum> EnumValues;
95
96public:
97 BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues);
98 uint32_t getSize() {
99 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;
100 }
101 void completeType(BTFDebug &BDebug);
102 void emitType(MCStreamer &OS);
103};
104
105/// Handle array type.
106class BTFTypeArray : public BTFTypeBase {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000107 struct BTF::BTFArray ArrayInfo;
108
109public:
Yonghong Song37d24a62019-08-02 23:16:44 +0000110 BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000111 uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
112 void completeType(BTFDebug &BDebug);
113 void emitType(MCStreamer &OS);
114};
115
116/// Handle struct/union type.
117class BTFTypeStruct : public BTFTypeBase {
118 const DICompositeType *STy;
119 bool HasBitField;
120 std::vector<struct BTF::BTFMember> Members;
121
122public:
123 BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
124 uint32_t NumMembers);
125 uint32_t getSize() {
126 return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
127 }
128 void completeType(BTFDebug &BDebug);
129 void emitType(MCStreamer &OS);
Yonghong Songd3d88d02019-07-09 15:28:41 +0000130 std::string getName();
Yonghong Song7b410ac2018-12-19 16:40:25 +0000131};
132
133/// Handle function pointer.
134class BTFTypeFuncProto : public BTFTypeBase {
135 const DISubroutineType *STy;
136 std::unordered_map<uint32_t, StringRef> FuncArgNames;
137 std::vector<struct BTF::BTFParam> Parameters;
138
139public:
140 BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
141 const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
142 uint32_t getSize() {
143 return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
144 }
145 void completeType(BTFDebug &BDebug);
146 void emitType(MCStreamer &OS);
147};
148
149/// Handle subprogram
150class BTFTypeFunc : public BTFTypeBase {
151 StringRef Name;
152
153public:
154 BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId);
155 uint32_t getSize() { return BTFTypeBase::getSize(); }
156 void completeType(BTFDebug &BDebug);
157 void emitType(MCStreamer &OS);
158};
159
Yonghong Song6db6b562019-03-16 15:36:31 +0000160/// Handle variable instances
161class BTFKindVar : public BTFTypeBase {
162 StringRef Name;
163 uint32_t Info;
164
165public:
166 BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);
167 uint32_t getSize() { return BTFTypeBase::getSize() + 4; }
168 void completeType(BTFDebug &BDebug);
169 void emitType(MCStreamer &OS);
170};
171
172/// Handle data sections
173class BTFKindDataSec : public BTFTypeBase {
174 AsmPrinter *Asm;
175 std::string Name;
176 std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
177
178public:
179 BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);
180 uint32_t getSize() {
181 return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
182 }
183 void addVar(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
184 Vars.push_back(std::make_tuple(Id, Sym, Size));
185 }
186 std::string getName() { return Name; }
187 void completeType(BTFDebug &BDebug);
188 void emitType(MCStreamer &OS);
189};
190
Yonghong Song7b410ac2018-12-19 16:40:25 +0000191/// String table.
192class BTFStringTable {
193 /// String table size in bytes.
194 uint32_t Size;
195 /// A mapping from string table offset to the index
196 /// of the Table. It is used to avoid putting
197 /// duplicated strings in the table.
Yonghong Song05e46972019-10-08 18:23:17 +0000198 std::map<uint32_t, uint32_t> OffsetToIdMap;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000199 /// A vector of strings to represent the string table.
200 std::vector<std::string> Table;
201
202public:
203 BTFStringTable() : Size(0) {}
204 uint32_t getSize() { return Size; }
205 std::vector<std::string> &getTable() { return Table; }
206 /// Add a string to the string table and returns its offset
207 /// in the table.
208 uint32_t addString(StringRef S);
209};
210
211/// Represent one func and its type id.
212struct BTFFuncInfo {
213 const MCSymbol *Label; ///< Func MCSymbol
214 uint32_t TypeId; ///< Type id referring to .BTF type section
215};
216
217/// Represent one line info.
218struct BTFLineInfo {
219 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo
220 uint32_t FileNameOff; ///< file name offset in the .BTF string table
221 uint32_t LineOff; ///< line offset in the .BTF string table
222 uint32_t LineNum; ///< the line number
223 uint32_t ColumnNum; ///< the column number
224};
225
Yonghong Songd3d88d02019-07-09 15:28:41 +0000226/// Represent one offset relocation.
Yonghong Song05e46972019-10-08 18:23:17 +0000227struct BTFFieldReloc {
Yonghong Songd3d88d02019-07-09 15:28:41 +0000228 const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc
229 uint32_t TypeID; ///< Type ID
230 uint32_t OffsetNameOff; ///< The string to traverse types
Yonghong Song05e46972019-10-08 18:23:17 +0000231 uint32_t RelocKind; ///< What to patch the instruction
Yonghong Songd3d88d02019-07-09 15:28:41 +0000232};
233
Yonghong Song7b410ac2018-12-19 16:40:25 +0000234/// Collect and emit BTF information.
235class BTFDebug : public DebugHandlerBase {
236 MCStreamer &OS;
237 bool SkipInstruction;
238 bool LineInfoGenerated;
239 uint32_t SecNameOff;
240 uint32_t ArrayIndexTypeId;
Yonghong Songd3d88d02019-07-09 15:28:41 +0000241 bool MapDefNotCollected;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000242 BTFStringTable StringTable;
243 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
244 std::unordered_map<const DIType *, uint32_t> DIToIdMap;
Yonghong Song6c56edf2019-03-27 15:45:27 +0000245 std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
246 std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
Yonghong Song05e46972019-10-08 18:23:17 +0000247 std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000248 StringMap<std::vector<std::string>> FileContent;
Yonghong Songd3d88d02019-07-09 15:28:41 +0000249 std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
250 std::vector<BTFTypeStruct *> StructTypes;
Yonghong Song05e46972019-10-08 18:23:17 +0000251 std::map<std::string, uint32_t> PatchImms;
Yonghong Songd3d88d02019-07-09 15:28:41 +0000252 std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
253 FixupDerivedTypes;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000254
255 /// Add types to TypeEntries.
256 /// @{
257 /// Add types to TypeEntries and DIToIdMap.
Yonghong Song6db6b562019-03-16 15:36:31 +0000258 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000259 /// Add types to TypeEntries only and return type id.
260 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
261 /// @}
262
263 /// IR type visiting functions.
264 /// @{
265 void visitTypeEntry(const DIType *Ty);
Yonghong Songd3d88d02019-07-09 15:28:41 +0000266 void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,
267 bool SeenPointer);
Yonghong Song6db6b562019-03-16 15:36:31 +0000268 void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000269 void visitSubroutineType(
270 const DISubroutineType *STy, bool ForSubprog,
271 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
272 uint32_t &TypeId);
Yonghong Song6db6b562019-03-16 15:36:31 +0000273 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
274 uint32_t &TypeId);
275 void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);
276 void visitStructType(const DICompositeType *STy, bool IsStruct,
277 uint32_t &TypeId);
278 void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);
279 void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);
Yonghong Songd3d88d02019-07-09 15:28:41 +0000280 void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
281 bool CheckPointer, bool SeenPointer);
282 void visitMapDefType(const DIType *Ty, uint32_t &TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000283 /// @}
284
285 /// Get the file content for the subprogram. Certain lines of the file
286 /// later may be put into string table and referenced by line info.
287 std::string populateFileContent(const DISubprogram *SP);
288
289 /// Construct a line info.
290 void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line,
291 uint32_t Column);
292
Yonghong Song6db6b562019-03-16 15:36:31 +0000293 /// Generate types and variables for globals.
Yonghong Songd3d88d02019-07-09 15:28:41 +0000294 void processGlobals(bool ProcessingMapDef);
295
Yonghong Song44481252019-11-22 08:45:37 -0800296 /// Generate types for function prototypes.
297 void processFuncPrototypes();
298
Yonghong Songd3d88d02019-07-09 15:28:41 +0000299 /// Generate one offset relocation record.
Yonghong Song05e46972019-10-08 18:23:17 +0000300 void generateFieldReloc(const MachineInstr *MI, const MCSymbol *ORSym,
Yonghong Songd3d88d02019-07-09 15:28:41 +0000301 DIType *RootTy, StringRef AccessPattern);
302
Yonghong Songd3d88d02019-07-09 15:28:41 +0000303 /// Populating unprocessed struct type.
304 unsigned populateStructType(const DIType *Ty);
305
306 /// Process LD_imm64 instructions.
307 void processLDimm64(const MachineInstr *MI);
Yonghong Song6db6b562019-03-16 15:36:31 +0000308
Yonghong Song7b410ac2018-12-19 16:40:25 +0000309 /// Emit common header of .BTF and .BTF.ext sections.
310 void emitCommonHeader();
311
312 /// Emit the .BTF section.
313 void emitBTFSection();
314
315 /// Emit the .BTF.ext section.
316 void emitBTFExtSection();
317
318protected:
319 /// Gather pre-function debug information.
320 void beginFunctionImpl(const MachineFunction *MF) override;
321
322 /// Post process after all instructions in this function are processed.
323 void endFunctionImpl(const MachineFunction *MF) override;
324
325public:
326 BTFDebug(AsmPrinter *AP);
327
Yonghong Songd3d88d02019-07-09 15:28:41 +0000328 ///
329 bool InstLower(const MachineInstr *MI, MCInst &OutMI);
330
Yonghong Song7b410ac2018-12-19 16:40:25 +0000331 /// Get the special array index type id.
332 uint32_t getArrayIndexTypeId() {
333 assert(ArrayIndexTypeId);
334 return ArrayIndexTypeId;
335 }
336
337 /// Add string to the string table.
338 size_t addString(StringRef S) { return StringTable.addString(S); }
339
340 /// Get the type id for a particular DIType.
341 uint32_t getTypeId(const DIType *Ty) {
342 assert(Ty && "Invalid null Type");
343 assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
344 "DIType not added in the BDIToIdMap");
345 return DIToIdMap[Ty];
346 }
347
348 void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {}
349
350 /// Process beginning of an instruction.
351 void beginInstruction(const MachineInstr *MI) override;
352
353 /// Complete all the types and emit the BTF sections.
354 void endModule() override;
355};
356
357} // end namespace llvm
358
359#endif