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
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;
36  bool IsCompleted;
37  uint32_t Id;
38  struct BTF::CommonType BTFType;
39
40public:
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.
58class BTFTypeDerived : public BTFTypeBase {
59  const DIDerivedType *DTy;
60  bool NeedsFixup;
61
62public:
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.
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 {
108  struct BTF::BTFArray ArrayInfo;
109
110public:
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.
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);
131  std::string getName();
132};
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:
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
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
192/// 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.
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
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
227/// Represent one field relocation.
228struct 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.
236class 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
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
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