xref: /freebsd/contrib/llvm-project/llvm/lib/Target/BPF/BTFDebug.h (revision ece7a5e9849032f4a31e725714c2db89d055b706)
1 //===- BTFDebug.h -----------------------------------------------*- 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 /// \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 
22 namespace llvm {
23 
24 class AsmPrinter;
25 class BTFDebug;
26 class DIType;
27 class MCStreamer;
28 class MCSymbol;
29 class MachineFunction;
30 
31 /// The base class for BTF type generation.
32 class BTFTypeBase {
33 protected:
34   uint8_t Kind;
35   bool IsCompleted;
36   uint32_t Id;
37   struct BTF::CommonType BTFType;
38 
39 public:
40   BTFTypeBase() : IsCompleted(false) {}
41   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.
57 class BTFTypeDerived : public BTFTypeBase {
58   const DIDerivedType *DTy;
59   bool NeedsFixup;
60 
61 public:
62   BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);
63   void completeType(BTFDebug &BDebug);
64   void emitType(MCStreamer &OS);
65   void setPointeeType(uint32_t PointeeType);
66 };
67 
68 /// Handle struct or union forward declaration.
69 class BTFTypeFwd : public BTFTypeBase {
70   StringRef Name;
71 
72 public:
73   BTFTypeFwd(StringRef Name, bool IsUnion);
74   void completeType(BTFDebug &BDebug);
75   void emitType(MCStreamer &OS);
76 };
77 
78 /// Handle int type.
79 class BTFTypeInt : public BTFTypeBase {
80   StringRef Name;
81   uint32_t IntVal; ///< Encoding, offset, bits
82 
83 public:
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.
92 class BTFTypeEnum : public BTFTypeBase {
93   const DICompositeType *ETy;
94   std::vector<struct BTF::BTFEnum> EnumValues;
95 
96 public:
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.
106 class BTFTypeArray : public BTFTypeBase {
107   const DIType *ElemTyNoQual;
108   uint32_t ElemSize;
109   struct BTF::BTFArray ArrayInfo;
110   uint32_t ElemTypeNoQual;
111 
112 public:
113   BTFTypeArray(const DIType *Ty, uint32_t ElemTypeId,
114                uint32_t ElemSize, uint32_t NumElems);
115   uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
116   void completeType(BTFDebug &BDebug);
117   void emitType(MCStreamer &OS);
118   void getLocInfo(uint32_t Loc, uint32_t &LocOffset, uint32_t &ElementTypeId);
119 };
120 
121 /// Handle struct/union type.
122 class BTFTypeStruct : public BTFTypeBase {
123   const DICompositeType *STy;
124   bool HasBitField;
125   std::vector<struct BTF::BTFMember> Members;
126   std::vector<uint32_t> MemberTypeNoQual;
127 
128 public:
129   BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
130                 uint32_t NumMembers);
131   uint32_t getSize() {
132     return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
133   }
134   void completeType(BTFDebug &BDebug);
135   void emitType(MCStreamer &OS);
136   std::string getName();
137   void getMemberInfo(uint32_t Loc, uint32_t &Offset, uint32_t &MemberType);
138   uint32_t getStructSize();
139 };
140 
141 /// Handle function pointer.
142 class BTFTypeFuncProto : public BTFTypeBase {
143   const DISubroutineType *STy;
144   std::unordered_map<uint32_t, StringRef> FuncArgNames;
145   std::vector<struct BTF::BTFParam> Parameters;
146 
147 public:
148   BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
149                    const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
150   uint32_t getSize() {
151     return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
152   }
153   void completeType(BTFDebug &BDebug);
154   void emitType(MCStreamer &OS);
155 };
156 
157 /// Handle subprogram
158 class BTFTypeFunc : public BTFTypeBase {
159   StringRef Name;
160 
161 public:
162   BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId);
163   uint32_t getSize() { return BTFTypeBase::getSize(); }
164   void completeType(BTFDebug &BDebug);
165   void emitType(MCStreamer &OS);
166 };
167 
168 /// Handle variable instances
169 class BTFKindVar : public BTFTypeBase {
170   StringRef Name;
171   uint32_t Info;
172 
173 public:
174   BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);
175   uint32_t getSize() { return BTFTypeBase::getSize() + 4; }
176   void completeType(BTFDebug &BDebug);
177   void emitType(MCStreamer &OS);
178 };
179 
180 /// Handle data sections
181 class BTFKindDataSec : public BTFTypeBase {
182   AsmPrinter *Asm;
183   std::string Name;
184   std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
185 
186 public:
187   BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);
188   uint32_t getSize() {
189     return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
190   }
191   void addVar(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
192     Vars.push_back(std::make_tuple(Id, Sym, Size));
193   }
194   std::string getName() { return Name; }
195   void completeType(BTFDebug &BDebug);
196   void emitType(MCStreamer &OS);
197 };
198 
199 /// String table.
200 class BTFStringTable {
201   /// String table size in bytes.
202   uint32_t Size;
203   /// A mapping from string table offset to the index
204   /// of the Table. It is used to avoid putting
205   /// duplicated strings in the table.
206   std::unordered_map<uint32_t, uint32_t> OffsetToIdMap;
207   /// A vector of strings to represent the string table.
208   std::vector<std::string> Table;
209 
210 public:
211   BTFStringTable() : Size(0) {}
212   uint32_t getSize() { return Size; }
213   std::vector<std::string> &getTable() { return Table; }
214   /// Add a string to the string table and returns its offset
215   /// in the table.
216   uint32_t addString(StringRef S);
217 };
218 
219 /// Represent one func and its type id.
220 struct BTFFuncInfo {
221   const MCSymbol *Label; ///< Func MCSymbol
222   uint32_t TypeId;       ///< Type id referring to .BTF type section
223 };
224 
225 /// Represent one line info.
226 struct BTFLineInfo {
227   MCSymbol *Label;      ///< MCSymbol identifying insn for the lineinfo
228   uint32_t FileNameOff; ///< file name offset in the .BTF string table
229   uint32_t LineOff;     ///< line offset in the .BTF string table
230   uint32_t LineNum;     ///< the line number
231   uint32_t ColumnNum;   ///< the column number
232 };
233 
234 /// Represent one offset relocation.
235 struct BTFOffsetReloc {
236   const MCSymbol *Label;  ///< MCSymbol identifying insn for the reloc
237   uint32_t TypeID;        ///< Type ID
238   uint32_t OffsetNameOff; ///< The string to traverse types
239 };
240 
241 /// Represent one extern relocation.
242 struct BTFExternReloc {
243   const MCSymbol *Label;  ///< MCSymbol identifying insn for the reloc
244   uint32_t ExternNameOff; ///< The extern variable name
245 };
246 
247 /// Collect and emit BTF information.
248 class BTFDebug : public DebugHandlerBase {
249   MCStreamer &OS;
250   bool SkipInstruction;
251   bool LineInfoGenerated;
252   uint32_t SecNameOff;
253   uint32_t ArrayIndexTypeId;
254   bool MapDefNotCollected;
255   BTFStringTable StringTable;
256   std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
257   std::unordered_map<const DIType *, uint32_t> DIToIdMap;
258   std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
259   std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
260   std::map<uint32_t, std::vector<BTFOffsetReloc>> OffsetRelocTable;
261   std::map<uint32_t, std::vector<BTFExternReloc>> ExternRelocTable;
262   StringMap<std::vector<std::string>> FileContent;
263   std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
264   std::vector<BTFTypeStruct *> StructTypes;
265   std::vector<BTFTypeArray *> ArrayTypes;
266   std::map<std::string, int64_t> AccessOffsets;
267   std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
268       FixupDerivedTypes;
269 
270   /// Add types to TypeEntries.
271   /// @{
272   /// Add types to TypeEntries and DIToIdMap.
273   uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
274   /// Add types to TypeEntries only and return type id.
275   uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
276   /// @}
277 
278   /// IR type visiting functions.
279   /// @{
280   void visitTypeEntry(const DIType *Ty);
281   void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,
282                       bool SeenPointer);
283   void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
284   void visitSubroutineType(
285       const DISubroutineType *STy, bool ForSubprog,
286       const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
287       uint32_t &TypeId);
288   void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
289                         uint32_t &TypeId);
290   void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);
291   void visitStructType(const DICompositeType *STy, bool IsStruct,
292                        uint32_t &TypeId);
293   void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);
294   void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);
295   void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
296                         bool CheckPointer, bool SeenPointer);
297   void visitMapDefType(const DIType *Ty, uint32_t &TypeId);
298   /// @}
299 
300   /// Get the file content for the subprogram. Certain lines of the file
301   /// later may be put into string table and referenced by line info.
302   std::string populateFileContent(const DISubprogram *SP);
303 
304   /// Construct a line info.
305   void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line,
306                          uint32_t Column);
307 
308   /// Generate types and variables for globals.
309   void processGlobals(bool ProcessingMapDef);
310 
311   /// Generate one offset relocation record.
312   void generateOffsetReloc(const MachineInstr *MI, const MCSymbol *ORSym,
313                            DIType *RootTy, StringRef AccessPattern);
314 
315   /// Set the to-be-traversed Struct/Array Type based on TypeId.
316   void setTypeFromId(uint32_t TypeId, BTFTypeStruct **PrevStructType,
317                      BTFTypeArray **PrevArrayType);
318 
319   /// Populating unprocessed struct type.
320   unsigned populateStructType(const DIType *Ty);
321 
322   /// Process LD_imm64 instructions.
323   void processLDimm64(const MachineInstr *MI);
324 
325   /// Emit common header of .BTF and .BTF.ext sections.
326   void emitCommonHeader();
327 
328   /// Emit the .BTF section.
329   void emitBTFSection();
330 
331   /// Emit the .BTF.ext section.
332   void emitBTFExtSection();
333 
334 protected:
335   /// Gather pre-function debug information.
336   void beginFunctionImpl(const MachineFunction *MF) override;
337 
338   /// Post process after all instructions in this function are processed.
339   void endFunctionImpl(const MachineFunction *MF) override;
340 
341 public:
342   BTFDebug(AsmPrinter *AP);
343 
344   ///
345   bool InstLower(const MachineInstr *MI, MCInst &OutMI);
346 
347   /// Get the special array index type id.
348   uint32_t getArrayIndexTypeId() {
349     assert(ArrayIndexTypeId);
350     return ArrayIndexTypeId;
351   }
352 
353   /// Add string to the string table.
354   size_t addString(StringRef S) { return StringTable.addString(S); }
355 
356   /// Get the type id for a particular DIType.
357   uint32_t getTypeId(const DIType *Ty) {
358     assert(Ty && "Invalid null Type");
359     assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
360            "DIType not added in the BDIToIdMap");
361     return DIToIdMap[Ty];
362   }
363 
364   void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {}
365 
366   /// Process beginning of an instruction.
367   void beginInstruction(const MachineInstr *MI) override;
368 
369   /// Complete all the types and emit the BTF sections.
370   void endModule() override;
371 };
372 
373 } // end namespace llvm
374 
375 #endif
376