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 <set>
20 #include <unordered_map>
21 #include "BTF.h"
22 
23 namespace llvm {
24 
25 class AsmPrinter;
26 class BTFDebug;
27 class DIType;
28 class MCStreamer;
29 class MCSymbol;
30 class MachineFunction;
31 
32 /// The base class for BTF type generation.
33 class BTFTypeBase {
34 protected:
35   uint8_t Kind;
36   bool IsCompleted;
37   uint32_t Id;
38   struct BTF::CommonType BTFType;
39 
40 public:
41   BTFTypeBase() : IsCompleted(false) {}
42   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.
58 class BTFTypeDerived : public BTFTypeBase {
59   const DIDerivedType *DTy;
60   bool NeedsFixup;
61 
62 public:
63   BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);
64   void completeType(BTFDebug &BDebug);
65   void emitType(MCStreamer &OS);
66   void setPointeeType(uint32_t PointeeType);
67 };
68 
69 /// Handle struct or union forward declaration.
70 class BTFTypeFwd : public BTFTypeBase {
71   StringRef Name;
72 
73 public:
74   BTFTypeFwd(StringRef Name, bool IsUnion);
75   void completeType(BTFDebug &BDebug);
76   void emitType(MCStreamer &OS);
77 };
78 
79 /// Handle int type.
80 class BTFTypeInt : public BTFTypeBase {
81   StringRef Name;
82   uint32_t IntVal; ///< Encoding, offset, bits
83 
84 public:
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.
93 class BTFTypeEnum : public BTFTypeBase {
94   const DICompositeType *ETy;
95   std::vector<struct BTF::BTFEnum> EnumValues;
96 
97 public:
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.
107 class BTFTypeArray : public BTFTypeBase {
108   struct BTF::BTFArray ArrayInfo;
109 
110 public:
111   BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);
112   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.
118 class BTFTypeStruct : public BTFTypeBase {
119   const DICompositeType *STy;
120   bool HasBitField;
121   std::vector<struct BTF::BTFMember> Members;
122 
123 public:
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);
131   std::string getName();
132 };
133 
134 /// Handle function pointer.
135 class BTFTypeFuncProto : public BTFTypeBase {
136   const DISubroutineType *STy;
137   std::unordered_map<uint32_t, StringRef> FuncArgNames;
138   std::vector<struct BTF::BTFParam> Parameters;
139 
140 public:
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
151 class BTFTypeFunc : public BTFTypeBase {
152   StringRef Name;
153 
154 public:
155   BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope);
156   uint32_t getSize() { return BTFTypeBase::getSize(); }
157   void completeType(BTFDebug &BDebug);
158   void emitType(MCStreamer &OS);
159 };
160 
161 /// Handle variable instances
162 class BTFKindVar : public BTFTypeBase {
163   StringRef Name;
164   uint32_t Info;
165 
166 public:
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
174 class BTFKindDataSec : public BTFTypeBase {
175   AsmPrinter *Asm;
176   std::string Name;
177   std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
178 
179 public:
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 
192 /// String table.
193 class 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.
199   std::map<uint32_t, uint32_t> OffsetToIdMap;
200   /// A vector of strings to represent the string table.
201   std::vector<std::string> Table;
202 
203 public:
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.
213 struct 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.
219 struct 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 
227 /// Represent one field relocation.
228 struct BTFFieldReloc {
229   const MCSymbol *Label;  ///< MCSymbol identifying insn for the reloc
230   uint32_t TypeID;        ///< Type ID
231   uint32_t OffsetNameOff; ///< The string to traverse types
232   uint32_t RelocKind;     ///< What to patch the instruction
233 };
234 
235 /// Collect and emit BTF information.
236 class BTFDebug : public DebugHandlerBase {
237   MCStreamer &OS;
238   bool SkipInstruction;
239   bool LineInfoGenerated;
240   uint32_t SecNameOff;
241   uint32_t ArrayIndexTypeId;
242   bool MapDefNotCollected;
243   BTFStringTable StringTable;
244   std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
245   std::unordered_map<const DIType *, uint32_t> DIToIdMap;
246   std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
247   std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
248   std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable;
249   StringMap<std::vector<std::string>> FileContent;
250   std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
251   std::vector<BTFTypeStruct *> StructTypes;
252   std::map<std::string, uint32_t> PatchImms;
253   std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>>
254       FixupDerivedTypes;
255   std::set<const Function *>ProtoFunctions;
256 
257   /// Add types to TypeEntries.
258   /// @{
259   /// Add types to TypeEntries and DIToIdMap.
260   uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
261   /// 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);
268   void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,
269                       bool SeenPointer);
270   void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
271   void visitSubroutineType(
272       const DISubroutineType *STy, bool ForSubprog,
273       const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
274       uint32_t &TypeId);
275   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);
282   void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
283                         bool CheckPointer, bool SeenPointer);
284   void visitMapDefType(const DIType *Ty, uint32_t &TypeId);
285   /// @}
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 
295   /// Generate types and variables for globals.
296   void processGlobals(bool ProcessingMapDef);
297 
298   /// Generate types for function prototypes.
299   void processFuncPrototypes(const Function *);
300 
301   /// Generate one field relocation record.
302   void generateFieldReloc(const MCSymbol *ORSym, DIType *RootTy,
303                           StringRef AccessPattern);
304 
305   /// Populating unprocessed struct type.
306   unsigned populateStructType(const DIType *Ty);
307 
308   /// Process relocation instructions.
309   void processReloc(const MachineOperand &MO);
310 
311   /// 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 
320 protected:
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 
327 public:
328   BTFDebug(AsmPrinter *AP);
329 
330   ///
331   bool InstLower(const MachineInstr *MI, MCInst &OutMI);
332 
333   /// 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
362