xref: /openbsd/gnu/llvm/llvm/lib/Target/BPF/BTFDebug.h (revision d415bd75)
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 <cstdint>
20 #include <map>
21 #include <set>
22 #include <unordered_map>
23 #include "BTF.h"
24 
25 namespace llvm {
26 
27 class AsmPrinter;
28 class BTFDebug;
29 class DIType;
30 class GlobalVariable;
31 class MachineFunction;
32 class MachineInstr;
33 class MachineOperand;
34 class MCInst;
35 class MCStreamer;
36 class MCSymbol;
37 
38 /// The base class for BTF type generation.
39 class BTFTypeBase {
40 protected:
41   uint8_t Kind;
42   bool IsCompleted;
43   uint32_t Id;
44   struct BTF::CommonType BTFType;
45 
46 public:
BTFTypeBase()47   BTFTypeBase() : IsCompleted(false) {}
48   virtual ~BTFTypeBase() = default;
setId(uint32_t Id)49   void setId(uint32_t Id) { this->Id = Id; }
getId()50   uint32_t getId() { return Id; }
roundupToBytes(uint32_t NumBits)51   uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }
52   /// Get the size of this BTF type entry.
getSize()53   virtual uint32_t getSize() { return BTF::CommonTypeSize; }
54   /// Complete BTF type generation after all related DebugInfo types
55   /// have been visited so their BTF type id's are available
56   /// for cross referece.
completeType(BTFDebug & BDebug)57   virtual void completeType(BTFDebug &BDebug) {}
58   /// Emit types for this BTF type entry.
59   virtual void emitType(MCStreamer &OS);
60 };
61 
62 /// Handle several derived types include pointer, const,
63 /// volatile, typedef and restrict.
64 class BTFTypeDerived : public BTFTypeBase {
65   const DIDerivedType *DTy;
66   bool NeedsFixup;
67   StringRef Name;
68 
69 public:
70   BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);
71   BTFTypeDerived(unsigned NextTypeId, unsigned Tag, StringRef Name);
72   void completeType(BTFDebug &BDebug) override;
73   void emitType(MCStreamer &OS) override;
74   void setPointeeType(uint32_t PointeeType);
75 };
76 
77 /// Handle struct or union forward declaration.
78 class BTFTypeFwd : public BTFTypeBase {
79   StringRef Name;
80 
81 public:
82   BTFTypeFwd(StringRef Name, bool IsUnion);
83   void completeType(BTFDebug &BDebug) override;
84   void emitType(MCStreamer &OS) override;
85 };
86 
87 /// Handle int type.
88 class BTFTypeInt : public BTFTypeBase {
89   StringRef Name;
90   uint32_t IntVal; ///< Encoding, offset, bits
91 
92 public:
93   BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,
94              StringRef TypeName);
getSize()95   uint32_t getSize() override { return BTFTypeBase::getSize() + sizeof(uint32_t); }
96   void completeType(BTFDebug &BDebug) override;
97   void emitType(MCStreamer &OS) override;
98 };
99 
100 /// Handle enumerate type.
101 class BTFTypeEnum : public BTFTypeBase {
102   const DICompositeType *ETy;
103   std::vector<struct BTF::BTFEnum> EnumValues;
104 
105 public:
106   BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);
getSize()107   uint32_t getSize() override {
108     return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;
109   }
110   void completeType(BTFDebug &BDebug) override;
111   void emitType(MCStreamer &OS) override;
112 };
113 
114 /// Handle array type.
115 class BTFTypeArray : public BTFTypeBase {
116   struct BTF::BTFArray ArrayInfo;
117 
118 public:
119   BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);
getSize()120   uint32_t getSize() override { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
121   void completeType(BTFDebug &BDebug) override;
122   void emitType(MCStreamer &OS) override;
123 };
124 
125 /// Handle struct/union type.
126 class BTFTypeStruct : public BTFTypeBase {
127   const DICompositeType *STy;
128   bool HasBitField;
129   std::vector<struct BTF::BTFMember> Members;
130 
131 public:
132   BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
133                 uint32_t NumMembers);
getSize()134   uint32_t getSize() override {
135     return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
136   }
137   void completeType(BTFDebug &BDebug) override;
138   void emitType(MCStreamer &OS) override;
139   std::string getName();
140 };
141 
142 /// Handle function pointer.
143 class BTFTypeFuncProto : public BTFTypeBase {
144   const DISubroutineType *STy;
145   std::unordered_map<uint32_t, StringRef> FuncArgNames;
146   std::vector<struct BTF::BTFParam> Parameters;
147 
148 public:
149   BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
150                    const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
getSize()151   uint32_t getSize() override {
152     return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
153   }
154   void completeType(BTFDebug &BDebug) override;
155   void emitType(MCStreamer &OS) override;
156 };
157 
158 /// Handle subprogram
159 class BTFTypeFunc : public BTFTypeBase {
160   StringRef Name;
161 
162 public:
163   BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope);
getSize()164   uint32_t getSize() override { return BTFTypeBase::getSize(); }
165   void completeType(BTFDebug &BDebug) override;
166   void emitType(MCStreamer &OS) override;
167 };
168 
169 /// Handle variable instances
170 class BTFKindVar : public BTFTypeBase {
171   StringRef Name;
172   uint32_t Info;
173 
174 public:
175   BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);
getSize()176   uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }
177   void completeType(BTFDebug &BDebug) override;
178   void emitType(MCStreamer &OS) override;
179 };
180 
181 /// Handle data sections
182 class BTFKindDataSec : public BTFTypeBase {
183   AsmPrinter *Asm;
184   std::string Name;
185   std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
186 
187 public:
188   BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);
getSize()189   uint32_t getSize() override {
190     return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
191   }
addDataSecEntry(uint32_t Id,const MCSymbol * Sym,uint32_t Size)192   void addDataSecEntry(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
193     Vars.push_back(std::make_tuple(Id, Sym, Size));
194   }
getName()195   std::string getName() { return Name; }
196   void completeType(BTFDebug &BDebug) override;
197   void emitType(MCStreamer &OS) override;
198 };
199 
200 /// Handle binary floating point type.
201 class BTFTypeFloat : public BTFTypeBase {
202   StringRef Name;
203 
204 public:
205   BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName);
206   void completeType(BTFDebug &BDebug) override;
207 };
208 
209 /// Handle decl tags.
210 class BTFTypeDeclTag : public BTFTypeBase {
211   uint32_t Info;
212   StringRef Tag;
213 
214 public:
215   BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag);
getSize()216   uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }
217   void completeType(BTFDebug &BDebug) override;
218   void emitType(MCStreamer &OS) override;
219 };
220 
221 /// Handle 64-bit enumerate type.
222 class BTFTypeEnum64 : public BTFTypeBase {
223   const DICompositeType *ETy;
224   std::vector<struct BTF::BTFEnum64> EnumValues;
225 
226 public:
227   BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);
getSize()228   uint32_t getSize() override {
229     return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnum64Size;
230   }
231   void completeType(BTFDebug &BDebug) override;
232   void emitType(MCStreamer &OS) override;
233 };
234 
235 class BTFTypeTypeTag : public BTFTypeBase {
236   const DIDerivedType *DTy;
237   StringRef Tag;
238 
239 public:
240   BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag);
241   BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag);
242   void completeType(BTFDebug &BDebug) override;
243 };
244 
245 /// String table.
246 class BTFStringTable {
247   /// String table size in bytes.
248   uint32_t Size;
249   /// A mapping from string table offset to the index
250   /// of the Table. It is used to avoid putting
251   /// duplicated strings in the table.
252   std::map<uint32_t, uint32_t> OffsetToIdMap;
253   /// A vector of strings to represent the string table.
254   std::vector<std::string> Table;
255 
256 public:
BTFStringTable()257   BTFStringTable() : Size(0) {}
getSize()258   uint32_t getSize() { return Size; }
getTable()259   std::vector<std::string> &getTable() { return Table; }
260   /// Add a string to the string table and returns its offset
261   /// in the table.
262   uint32_t addString(StringRef S);
263 };
264 
265 /// Represent one func and its type id.
266 struct BTFFuncInfo {
267   const MCSymbol *Label; ///< Func MCSymbol
268   uint32_t TypeId;       ///< Type id referring to .BTF type section
269 };
270 
271 /// Represent one line info.
272 struct BTFLineInfo {
273   MCSymbol *Label;      ///< MCSymbol identifying insn for the lineinfo
274   uint32_t FileNameOff; ///< file name offset in the .BTF string table
275   uint32_t LineOff;     ///< line offset in the .BTF string table
276   uint32_t LineNum;     ///< the line number
277   uint32_t ColumnNum;   ///< the column number
278 };
279 
280 /// Represent one field relocation.
281 struct BTFFieldReloc {
282   const MCSymbol *Label;  ///< MCSymbol identifying insn for the reloc
283   uint32_t TypeID;        ///< Type ID
284   uint32_t OffsetNameOff; ///< The string to traverse types
285   uint32_t RelocKind;     ///< What to patch the instruction
286 };
287 
288 /// Collect and emit BTF information.
289 class BTFDebug : public DebugHandlerBase {
290   MCStreamer &OS;
291   bool SkipInstruction;
292   bool LineInfoGenerated;
293   uint32_t SecNameOff;
294   uint32_t ArrayIndexTypeId;
295   bool MapDefNotCollected;
296   BTFStringTable StringTable;
297   std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
298   std::unordered_map<const DIType *, uint32_t> DIToIdMap;
299   std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
300   std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
301   std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable;
302   StringMap<std::vector<std::string>> FileContent;
303   std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
304   std::vector<BTFTypeStruct *> StructTypes;
305   std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms;
306   std::map<const DICompositeType *,
307            std::vector<std::pair<const DIDerivedType *, BTFTypeDerived *>>>
308       FixupDerivedTypes;
309   std::set<const Function *>ProtoFunctions;
310 
311   /// Add types to TypeEntries.
312   /// @{
313   /// Add types to TypeEntries and DIToIdMap.
314   uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
315   /// Add types to TypeEntries only and return type id.
316   uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
317   /// @}
318 
319   /// IR type visiting functions.
320   /// @{
321   void visitTypeEntry(const DIType *Ty);
322   void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,
323                       bool SeenPointer);
324   void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
325   void visitSubroutineType(
326       const DISubroutineType *STy, bool ForSubprog,
327       const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
328       uint32_t &TypeId);
329   void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
330                         uint32_t &TypeId);
331   void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);
332   void visitStructType(const DICompositeType *STy, bool IsStruct,
333                        uint32_t &TypeId);
334   void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);
335   void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);
336   void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
337                         bool CheckPointer, bool SeenPointer);
338   void visitMapDefType(const DIType *Ty, uint32_t &TypeId);
339   /// @}
340 
341   /// Check whether the type is a forward declaration candidate or not.
342   bool IsForwardDeclCandidate(const DIType *Base);
343 
344   /// Get the file content for the subprogram. Certain lines of the file
345   /// later may be put into string table and referenced by line info.
346   std::string populateFileContent(const DISubprogram *SP);
347 
348   /// Construct a line info.
349   void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line,
350                          uint32_t Column);
351 
352   /// Generate types and variables for globals.
353   void processGlobals(bool ProcessingMapDef);
354 
355   /// Generate types for function prototypes.
356   void processFuncPrototypes(const Function *);
357 
358   /// Generate types for decl annotations.
359   void processDeclAnnotations(DINodeArray Annotations, uint32_t BaseTypeId,
360                               int ComponentId);
361 
362   /// Generate types for DISubprogram and it's arguments.
363   uint32_t processDISubprogram(const DISubprogram *SP, uint32_t ProtoTypeId,
364                                uint8_t Scope);
365 
366   /// Generate BTF type_tag's. If BaseTypeId is nonnegative, the last
367   /// BTF type_tag in the chain points to BaseTypeId. Otherwise, it points to
368   /// the base type of DTy. Return the type id of the first BTF type_tag
369   /// in the chain. If no type_tag's are generated, a negative value
370   /// is returned.
371   int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId);
372 
373   /// Generate one field relocation record.
374   void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
375                              const GlobalVariable *, bool IsAma);
376 
377   /// Populating unprocessed type on demand.
378   unsigned populateType(const DIType *Ty);
379 
380   /// Process global variables referenced by relocation instructions
381   /// and extern function references.
382   void processGlobalValue(const MachineOperand &MO);
383 
384   /// Emit common header of .BTF and .BTF.ext sections.
385   void emitCommonHeader();
386 
387   /// Emit the .BTF section.
388   void emitBTFSection();
389 
390   /// Emit the .BTF.ext section.
391   void emitBTFExtSection();
392 
393 protected:
394   /// Gather pre-function debug information.
395   void beginFunctionImpl(const MachineFunction *MF) override;
396 
397   /// Post process after all instructions in this function are processed.
398   void endFunctionImpl(const MachineFunction *MF) override;
399 
400 public:
401   BTFDebug(AsmPrinter *AP);
402 
403   ///
404   bool InstLower(const MachineInstr *MI, MCInst &OutMI);
405 
406   /// Get the special array index type id.
getArrayIndexTypeId()407   uint32_t getArrayIndexTypeId() {
408     assert(ArrayIndexTypeId);
409     return ArrayIndexTypeId;
410   }
411 
412   /// Add string to the string table.
addString(StringRef S)413   size_t addString(StringRef S) { return StringTable.addString(S); }
414 
415   /// Get the type id for a particular DIType.
getTypeId(const DIType * Ty)416   uint32_t getTypeId(const DIType *Ty) {
417     assert(Ty && "Invalid null Type");
418     assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
419            "DIType not added in the BDIToIdMap");
420     return DIToIdMap[Ty];
421   }
422 
setSymbolSize(const MCSymbol * Symbol,uint64_t Size)423   void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {}
424 
425   /// Process beginning of an instruction.
426   void beginInstruction(const MachineInstr *MI) override;
427 
428   /// Complete all the types and emit the BTF sections.
429   void endModule() override;
430 };
431 
432 } // end namespace llvm
433 
434 #endif
435