blob: 0812c4f7915ded8b257d3ba73b2869dc6fe1b292 [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"
Yonghong Songfbb64aa2019-12-17 16:24:23 -080019#include <set>
Yonghong Song7b410ac2018-12-19 16:40:25 +000020#include <unordered_map>
21#include "BTF.h"
22
23namespace llvm {
24
25class AsmPrinter;
26class BTFDebug;
27class DIType;
28class MCStreamer;
29class MCSymbol;
30class MachineFunction;
31
32/// The base class for BTF type generation.
33class BTFTypeBase {
34protected:
35 uint8_t Kind;
Yonghong Songd3d88d02019-07-09 15:28:41 +000036 bool IsCompleted;
Yonghong Song7b410ac2018-12-19 16:40:25 +000037 uint32_t Id;
38 struct BTF::CommonType BTFType;
39
40public:
Yonghong Songd3d88d02019-07-09 15:28:41 +000041 BTFTypeBase() : IsCompleted(false) {}
Yonghong Song7b410ac2018-12-19 16:40:25 +000042 virtual ~BTFTypeBase() = default;
43 void setId(uint32_t Id) { this->Id = Id; }
44 uint32_t getId() { return Id; }
45 uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }
46 /// Get the size of this BTF type entry.
47 virtual uint32_t getSize() { return BTF::CommonTypeSize; }
48 /// Complete BTF type generation after all related DebugInfo types
49 /// have been visited so their BTF type id's are available
50 /// for cross referece.
51 virtual void completeType(BTFDebug &BDebug) {}
52 /// Emit types for this BTF type entry.
53 virtual void emitType(MCStreamer &OS);
54};
55
56/// Handle several derived types include pointer, const,
57/// volatile, typedef and restrict.
58class BTFTypeDerived : public BTFTypeBase {
59 const DIDerivedType *DTy;
Yonghong Songd3d88d02019-07-09 15:28:41 +000060 bool NeedsFixup;
Yonghong Song7b410ac2018-12-19 16:40:25 +000061
62public:
Yonghong Songd3d88d02019-07-09 15:28:41 +000063 BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);
Yonghong Song7b410ac2018-12-19 16:40:25 +000064 void completeType(BTFDebug &BDebug);
65 void emitType(MCStreamer &OS);
Yonghong Songd3d88d02019-07-09 15:28:41 +000066 void setPointeeType(uint32_t PointeeType);
Yonghong Song7b410ac2018-12-19 16:40:25 +000067};
68
69/// Handle struct or union forward declaration.
70class BTFTypeFwd : public BTFTypeBase {
71 StringRef Name;
72
73public:
74 BTFTypeFwd(StringRef Name, bool IsUnion);
75 void completeType(BTFDebug &BDebug);
76 void emitType(MCStreamer &OS);
77};
78
79/// Handle int type.
80class BTFTypeInt : public BTFTypeBase {
81 StringRef Name;
82 uint32_t IntVal; ///< Encoding, offset, bits
83
84public:
85 BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,
86 StringRef TypeName);
87 uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); }
88 void completeType(BTFDebug &BDebug);
89 void emitType(MCStreamer &OS);
90};
91
92/// Handle enumerate type.
93class BTFTypeEnum : public BTFTypeBase {
94 const DICompositeType *ETy;
95 std::vector<struct BTF::BTFEnum> EnumValues;
96
97public:
98 BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues);
99 uint32_t getSize() {
100 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;
101 }
102 void completeType(BTFDebug &BDebug);
103 void emitType(MCStreamer &OS);
104};
105
106/// Handle array type.
107class BTFTypeArray : public BTFTypeBase {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000108 struct BTF::BTFArray ArrayInfo;
109
110public:
Yonghong Song37d24a62019-08-02 23:16:44 +0000111 BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000112 uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
113 void completeType(BTFDebug &BDebug);
114 void emitType(MCStreamer &OS);
115};
116
117/// Handle struct/union type.
118class BTFTypeStruct : public BTFTypeBase {
119 const DICompositeType *STy;
120 bool HasBitField;
121 std::vector<struct BTF::BTFMember> Members;
122
123public:
124 BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
125 uint32_t NumMembers);
126 uint32_t getSize() {
127 return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
128 }
129 void completeType(BTFDebug &BDebug);
130 void emitType(MCStreamer &OS);
Yonghong Songd3d88d02019-07-09 15:28:41 +0000131 std::string getName();
Yonghong Song7b410ac2018-12-19 16:40:25 +0000132};
133
134/// Handle function pointer.
135class BTFTypeFuncProto : public BTFTypeBase {
136 const DISubroutineType *STy;
137 std::unordered_map<uint32_t, StringRef> FuncArgNames;
138 std::vector<struct BTF::BTFParam> Parameters;
139
140public:
141 BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
142 const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
143 uint32_t getSize() {
144 return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
145 }
146 void completeType(BTFDebug &BDebug);
147 void emitType(MCStreamer &OS);
148};
149
150/// Handle subprogram
151class BTFTypeFunc : public BTFTypeBase {
152 StringRef Name;
153
154public:
Yonghong Songfbb64aa2019-12-17 16:24:23 -0800155 BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000156 uint32_t getSize() { return BTFTypeBase::getSize(); }
157 void completeType(BTFDebug &BDebug);
158 void emitType(MCStreamer &OS);
159};
160
Yonghong Song6db6b562019-03-16 15:36:31 +0000161/// Handle variable instances
162class BTFKindVar : public BTFTypeBase {
163 StringRef Name;
164 uint32_t Info;
165
166public:
167 BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);
168 uint32_t getSize() { return BTFTypeBase::getSize() + 4; }
169 void completeType(BTFDebug &BDebug);
170 void emitType(MCStreamer &OS);
171};
172
173/// Handle data sections
174class BTFKindDataSec : public BTFTypeBase {
175 AsmPrinter *Asm;
176 std::string Name;
177 std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
178
179public:
180 BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);
181 uint32_t getSize() {
182 return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
183 }
184 void addVar(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
185 Vars.push_back(std::make_tuple(Id, Sym, Size));
186 }
187 std::string getName() { return Name; }
188 void completeType(BTFDebug &BDebug);
189 void emitType(MCStreamer &OS);
190};
191
Yonghong Song7b410ac2018-12-19 16:40:25 +0000192/// String table.
193class BTFStringTable {
194 /// String table size in bytes.
195 uint32_t Size;
196 /// A mapping from string table offset to the index
197 /// of the Table. It is used to avoid putting
198 /// duplicated strings in the table.
Yonghong Song05e46972019-10-08 18:23:17 +0000199 std::map<uint32_t, uint32_t> OffsetToIdMap;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000200 /// A vector of strings to represent the string table.
201 std::vector<std::string> Table;
202
203public:
204 BTFStringTable() : Size(0) {}
205 uint32_t getSize() { return Size; }
206 std::vector<std::string> &getTable() { return Table; }
207 /// Add a string to the string table and returns its offset
208 /// in the table.
209 uint32_t addString(StringRef S);
210};
211
212/// Represent one func and its type id.
213struct BTFFuncInfo {
214 const MCSymbol *Label; ///< Func MCSymbol
215 uint32_t TypeId; ///< Type id referring to .BTF type section
216};
217
218/// Represent one line info.
219struct BTFLineInfo {
220 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo
221 uint32_t FileNameOff; ///< file name offset in the .BTF string table
222 uint32_t LineOff; ///< line offset in the .BTF string table
223 uint32_t LineNum; ///< the line number
224 uint32_t ColumnNum; ///< the column number
225};
226
Yonghong Songffd57402019-12-19 15:21:53 -0800227/// Represent one field relocation.
Yonghong Song05e46972019-10-08 18:23:17 +0000228struct BTFFieldReloc {
Yonghong Songd3d88d02019-07-09 15:28:41 +0000229 const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc
230 uint32_t TypeID; ///< Type ID
231 uint32_t OffsetNameOff; ///< The string to traverse types
Yonghong Song05e46972019-10-08 18:23:17 +0000232 uint32_t RelocKind; ///< What to patch the instruction
Yonghong Songd3d88d02019-07-09 15:28:41 +0000233};
234
Yonghong Song7b410ac2018-12-19 16:40:25 +0000235/// Collect and emit BTF information.
236class BTFDebug : public DebugHandlerBase {
237 MCStreamer &OS;
238 bool SkipInstruction;
239 bool LineInfoGenerated;
240 uint32_t SecNameOff;
241 uint32_t ArrayIndexTypeId;
Yonghong Songd3d88d02019-07-09 15:28:41 +0000242 bool MapDefNotCollected;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000243 BTFStringTable StringTable;
244 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
245 std::unordered_map<const DIType *, uint32_t> DIToIdMap;
Yonghong Song6c56edf2019-03-27 15:45:27 +0000246 std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
247 std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
Yonghong Song05e46972019-10-08 18:23:17 +0000248 std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000249 StringMap<std::vector<std::string>> FileContent;
Yonghong Songd3d88d02019-07-09 15:28:41 +0000250 std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
251 std::vector<BTFTypeStruct *> StructTypes;
Yonghong Song05e46972019-10-08 18:23:17 +0000252 std::map<std::string, uint32_t> PatchImms;
Yonghong Songd3d88d02019-07-09 15:28:41 +0000253 std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
254 FixupDerivedTypes;
Yonghong Songfbb64aa2019-12-17 16:24:23 -0800255 std::set<const Function *>ProtoFunctions;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000256
257 /// Add types to TypeEntries.
258 /// @{
259 /// Add types to TypeEntries and DIToIdMap.
Yonghong Song6db6b562019-03-16 15:36:31 +0000260 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000261 /// Add types to TypeEntries only and return type id.
262 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
263 /// @}
264
265 /// IR type visiting functions.
266 /// @{
267 void visitTypeEntry(const DIType *Ty);
Yonghong Songd3d88d02019-07-09 15:28:41 +0000268 void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,
269 bool SeenPointer);
Yonghong Song6db6b562019-03-16 15:36:31 +0000270 void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000271 void visitSubroutineType(
272 const DISubroutineType *STy, bool ForSubprog,
273 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
274 uint32_t &TypeId);
Yonghong Song6db6b562019-03-16 15:36:31 +0000275 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
276 uint32_t &TypeId);
277 void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);
278 void visitStructType(const DICompositeType *STy, bool IsStruct,
279 uint32_t &TypeId);
280 void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);
281 void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);
Yonghong Songd3d88d02019-07-09 15:28:41 +0000282 void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
283 bool CheckPointer, bool SeenPointer);
284 void visitMapDefType(const DIType *Ty, uint32_t &TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000285 /// @}
286
287 /// Get the file content for the subprogram. Certain lines of the file
288 /// later may be put into string table and referenced by line info.
289 std::string populateFileContent(const DISubprogram *SP);
290
291 /// Construct a line info.
292 void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line,
293 uint32_t Column);
294
Yonghong Song6db6b562019-03-16 15:36:31 +0000295 /// Generate types and variables for globals.
Yonghong Songd3d88d02019-07-09 15:28:41 +0000296 void processGlobals(bool ProcessingMapDef);
297
Yonghong Song44481252019-11-22 08:45:37 -0800298 /// Generate types for function prototypes.
Yonghong Songfbb64aa2019-12-17 16:24:23 -0800299 void processFuncPrototypes(const Function *);
Yonghong Song44481252019-11-22 08:45:37 -0800300
Yonghong Songffd57402019-12-19 15:21:53 -0800301 /// Generate one field relocation record.
302 void generateFieldReloc(const MCSymbol *ORSym, DIType *RootTy,
303 StringRef AccessPattern);
Yonghong Songd3d88d02019-07-09 15:28:41 +0000304
Yonghong Songd3d88d02019-07-09 15:28:41 +0000305 /// Populating unprocessed struct type.
306 unsigned populateStructType(const DIType *Ty);
307
Yonghong Songffd57402019-12-19 15:21:53 -0800308 /// Process relocation instructions.
309 void processReloc(const MachineOperand &MO);
Yonghong Song6db6b562019-03-16 15:36:31 +0000310
Yonghong Song7b410ac2018-12-19 16:40:25 +0000311 /// Emit common header of .BTF and .BTF.ext sections.
312 void emitCommonHeader();
313
314 /// Emit the .BTF section.
315 void emitBTFSection();
316
317 /// Emit the .BTF.ext section.
318 void emitBTFExtSection();
319
320protected:
321 /// Gather pre-function debug information.
322 void beginFunctionImpl(const MachineFunction *MF) override;
323
324 /// Post process after all instructions in this function are processed.
325 void endFunctionImpl(const MachineFunction *MF) override;
326
327public:
328 BTFDebug(AsmPrinter *AP);
329
Yonghong Songd3d88d02019-07-09 15:28:41 +0000330 ///
331 bool InstLower(const MachineInstr *MI, MCInst &OutMI);
332
Yonghong Song7b410ac2018-12-19 16:40:25 +0000333 /// Get the special array index type id.
334 uint32_t getArrayIndexTypeId() {
335 assert(ArrayIndexTypeId);
336 return ArrayIndexTypeId;
337 }
338
339 /// Add string to the string table.
340 size_t addString(StringRef S) { return StringTable.addString(S); }
341
342 /// Get the type id for a particular DIType.
343 uint32_t getTypeId(const DIType *Ty) {
344 assert(Ty && "Invalid null Type");
345 assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
346 "DIType not added in the BDIToIdMap");
347 return DIToIdMap[Ty];
348 }
349
350 void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {}
351
352 /// Process beginning of an instruction.
353 void beginInstruction(const MachineInstr *MI) override;
354
355 /// Complete all the types and emit the BTF sections.
356 void endModule() override;
357};
358
359} // end namespace llvm
360
361#endif