1 //===- BTFDebug.h -----------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file contains support for writing BTF debug info.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H
15 #define LLVM_LIB_TARGET_BPF_BTFDEBUG_H
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/CodeGen/DebugHandlerBase.h"
19 #include <unordered_map>
29 class MachineFunction
;
31 /// The base class for BTF type generation.
37 struct BTF::CommonType BTFType
;
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
);
55 /// Handle several derived types include pointer, const,
56 /// volatile, typedef and restrict.
57 class BTFTypeDerived
: public BTFTypeBase
{
58 const DIDerivedType
*DTy
;
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
);
68 /// Handle struct or union forward declaration.
69 class BTFTypeFwd
: public BTFTypeBase
{
73 BTFTypeFwd(StringRef Name
, bool IsUnion
);
74 void completeType(BTFDebug
&BDebug
);
75 void emitType(MCStreamer
&OS
);
79 class BTFTypeInt
: public BTFTypeBase
{
81 uint32_t IntVal
; ///< Encoding, offset, bits
84 BTFTypeInt(uint32_t Encoding
, uint32_t SizeInBits
, uint32_t OffsetInBits
,
86 uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); }
87 void completeType(BTFDebug
&BDebug
);
88 void emitType(MCStreamer
&OS
);
91 /// Handle enumerate type.
92 class BTFTypeEnum
: public BTFTypeBase
{
93 const DICompositeType
*ETy
;
94 std::vector
<struct BTF::BTFEnum
> EnumValues
;
97 BTFTypeEnum(const DICompositeType
*ETy
, uint32_t NumValues
);
99 return BTFTypeBase::getSize() + EnumValues
.size() * BTF::BTFEnumSize
;
101 void completeType(BTFDebug
&BDebug
);
102 void emitType(MCStreamer
&OS
);
105 /// Handle array type.
106 class BTFTypeArray
: public BTFTypeBase
{
107 struct BTF::BTFArray ArrayInfo
;
110 BTFTypeArray(uint32_t ElemTypeId
, uint32_t NumElems
);
111 uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize
; }
112 void completeType(BTFDebug
&BDebug
);
113 void emitType(MCStreamer
&OS
);
116 /// Handle struct/union type.
117 class BTFTypeStruct
: public BTFTypeBase
{
118 const DICompositeType
*STy
;
120 std::vector
<struct BTF::BTFMember
> Members
;
123 BTFTypeStruct(const DICompositeType
*STy
, bool IsStruct
, bool HasBitField
,
124 uint32_t NumMembers
);
126 return BTFTypeBase::getSize() + Members
.size() * BTF::BTFMemberSize
;
128 void completeType(BTFDebug
&BDebug
);
129 void emitType(MCStreamer
&OS
);
130 std::string
getName();
133 /// Handle function pointer.
134 class BTFTypeFuncProto
: public BTFTypeBase
{
135 const DISubroutineType
*STy
;
136 std::unordered_map
<uint32_t, StringRef
> FuncArgNames
;
137 std::vector
<struct BTF::BTFParam
> Parameters
;
140 BTFTypeFuncProto(const DISubroutineType
*STy
, uint32_t NumParams
,
141 const std::unordered_map
<uint32_t, StringRef
> &FuncArgNames
);
143 return BTFTypeBase::getSize() + Parameters
.size() * BTF::BTFParamSize
;
145 void completeType(BTFDebug
&BDebug
);
146 void emitType(MCStreamer
&OS
);
149 /// Handle subprogram
150 class BTFTypeFunc
: public BTFTypeBase
{
154 BTFTypeFunc(StringRef FuncName
, uint32_t ProtoTypeId
);
155 uint32_t getSize() { return BTFTypeBase::getSize(); }
156 void completeType(BTFDebug
&BDebug
);
157 void emitType(MCStreamer
&OS
);
160 /// Handle variable instances
161 class BTFKindVar
: public BTFTypeBase
{
166 BTFKindVar(StringRef VarName
, uint32_t TypeId
, uint32_t VarInfo
);
167 uint32_t getSize() { return BTFTypeBase::getSize() + 4; }
168 void completeType(BTFDebug
&BDebug
);
169 void emitType(MCStreamer
&OS
);
172 /// Handle data sections
173 class BTFKindDataSec
: public BTFTypeBase
{
176 std::vector
<std::tuple
<uint32_t, const MCSymbol
*, uint32_t>> Vars
;
179 BTFKindDataSec(AsmPrinter
*AsmPrt
, std::string SecName
);
181 return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize
* Vars
.size();
183 void addVar(uint32_t Id
, const MCSymbol
*Sym
, uint32_t Size
) {
184 Vars
.push_back(std::make_tuple(Id
, Sym
, Size
));
186 std::string
getName() { return Name
; }
187 void completeType(BTFDebug
&BDebug
);
188 void emitType(MCStreamer
&OS
);
192 class BTFStringTable
{
193 /// String table size in bytes.
195 /// A mapping from string table offset to the index
196 /// of the Table. It is used to avoid putting
197 /// duplicated strings in the table.
198 std::map
<uint32_t, uint32_t> OffsetToIdMap
;
199 /// A vector of strings to represent the string table.
200 std::vector
<std::string
> Table
;
203 BTFStringTable() : Size(0) {}
204 uint32_t getSize() { return Size
; }
205 std::vector
<std::string
> &getTable() { return Table
; }
206 /// Add a string to the string table and returns its offset
208 uint32_t addString(StringRef S
);
211 /// Represent one func and its type id.
213 const MCSymbol
*Label
; ///< Func MCSymbol
214 uint32_t TypeId
; ///< Type id referring to .BTF type section
217 /// Represent one line info.
219 MCSymbol
*Label
; ///< MCSymbol identifying insn for the lineinfo
220 uint32_t FileNameOff
; ///< file name offset in the .BTF string table
221 uint32_t LineOff
; ///< line offset in the .BTF string table
222 uint32_t LineNum
; ///< the line number
223 uint32_t ColumnNum
; ///< the column number
226 /// Represent one offset relocation.
227 struct BTFFieldReloc
{
228 const MCSymbol
*Label
; ///< MCSymbol identifying insn for the reloc
229 uint32_t TypeID
; ///< Type ID
230 uint32_t OffsetNameOff
; ///< The string to traverse types
231 uint32_t RelocKind
; ///< What to patch the instruction
234 /// Represent one extern relocation.
235 struct BTFExternReloc
{
236 const MCSymbol
*Label
; ///< MCSymbol identifying insn for the reloc
237 uint32_t ExternNameOff
; ///< The extern variable name
240 /// Collect and emit BTF information.
241 class BTFDebug
: public DebugHandlerBase
{
243 bool SkipInstruction
;
244 bool LineInfoGenerated
;
246 uint32_t ArrayIndexTypeId
;
247 bool MapDefNotCollected
;
248 BTFStringTable StringTable
;
249 std::vector
<std::unique_ptr
<BTFTypeBase
>> TypeEntries
;
250 std::unordered_map
<const DIType
*, uint32_t> DIToIdMap
;
251 std::map
<uint32_t, std::vector
<BTFFuncInfo
>> FuncInfoTable
;
252 std::map
<uint32_t, std::vector
<BTFLineInfo
>> LineInfoTable
;
253 std::map
<uint32_t, std::vector
<BTFFieldReloc
>> FieldRelocTable
;
254 std::map
<uint32_t, std::vector
<BTFExternReloc
>> ExternRelocTable
;
255 StringMap
<std::vector
<std::string
>> FileContent
;
256 std::map
<std::string
, std::unique_ptr
<BTFKindDataSec
>> DataSecEntries
;
257 std::vector
<BTFTypeStruct
*> StructTypes
;
258 std::map
<std::string
, uint32_t> PatchImms
;
259 std::map
<StringRef
, std::pair
<bool, std::vector
<BTFTypeDerived
*>>>
262 /// Add types to TypeEntries.
264 /// Add types to TypeEntries and DIToIdMap.
265 uint32_t addType(std::unique_ptr
<BTFTypeBase
> TypeEntry
, const DIType
*Ty
);
266 /// Add types to TypeEntries only and return type id.
267 uint32_t addType(std::unique_ptr
<BTFTypeBase
> TypeEntry
);
270 /// IR type visiting functions.
272 void visitTypeEntry(const DIType
*Ty
);
273 void visitTypeEntry(const DIType
*Ty
, uint32_t &TypeId
, bool CheckPointer
,
275 void visitBasicType(const DIBasicType
*BTy
, uint32_t &TypeId
);
276 void visitSubroutineType(
277 const DISubroutineType
*STy
, bool ForSubprog
,
278 const std::unordered_map
<uint32_t, StringRef
> &FuncArgNames
,
280 void visitFwdDeclType(const DICompositeType
*CTy
, bool IsUnion
,
282 void visitCompositeType(const DICompositeType
*CTy
, uint32_t &TypeId
);
283 void visitStructType(const DICompositeType
*STy
, bool IsStruct
,
285 void visitArrayType(const DICompositeType
*ATy
, uint32_t &TypeId
);
286 void visitEnumType(const DICompositeType
*ETy
, uint32_t &TypeId
);
287 void visitDerivedType(const DIDerivedType
*DTy
, uint32_t &TypeId
,
288 bool CheckPointer
, bool SeenPointer
);
289 void visitMapDefType(const DIType
*Ty
, uint32_t &TypeId
);
292 /// Get the file content for the subprogram. Certain lines of the file
293 /// later may be put into string table and referenced by line info.
294 std::string
populateFileContent(const DISubprogram
*SP
);
296 /// Construct a line info.
297 void constructLineInfo(const DISubprogram
*SP
, MCSymbol
*Label
, uint32_t Line
,
300 /// Generate types and variables for globals.
301 void processGlobals(bool ProcessingMapDef
);
303 /// Generate one offset relocation record.
304 void generateFieldReloc(const MachineInstr
*MI
, const MCSymbol
*ORSym
,
305 DIType
*RootTy
, StringRef AccessPattern
);
307 /// Populating unprocessed struct type.
308 unsigned populateStructType(const DIType
*Ty
);
310 /// Process LD_imm64 instructions.
311 void processLDimm64(const MachineInstr
*MI
);
313 /// Emit common header of .BTF and .BTF.ext sections.
314 void emitCommonHeader();
316 /// Emit the .BTF section.
317 void emitBTFSection();
319 /// Emit the .BTF.ext section.
320 void emitBTFExtSection();
323 /// Gather pre-function debug information.
324 void beginFunctionImpl(const MachineFunction
*MF
) override
;
326 /// Post process after all instructions in this function are processed.
327 void endFunctionImpl(const MachineFunction
*MF
) override
;
330 BTFDebug(AsmPrinter
*AP
);
333 bool InstLower(const MachineInstr
*MI
, MCInst
&OutMI
);
335 /// Get the special array index type id.
336 uint32_t getArrayIndexTypeId() {
337 assert(ArrayIndexTypeId
);
338 return ArrayIndexTypeId
;
341 /// Add string to the string table.
342 size_t addString(StringRef S
) { return StringTable
.addString(S
); }
344 /// Get the type id for a particular DIType.
345 uint32_t getTypeId(const DIType
*Ty
) {
346 assert(Ty
&& "Invalid null Type");
347 assert(DIToIdMap
.find(Ty
) != DIToIdMap
.end() &&
348 "DIType not added in the BDIToIdMap");
349 return DIToIdMap
[Ty
];
352 void setSymbolSize(const MCSymbol
*Symbol
, uint64_t Size
) override
{}
354 /// Process beginning of an instruction.
355 void beginInstruction(const MachineInstr
*MI
) override
;
357 /// Complete all the types and emit the BTF sections.
358 void endModule() override
;
361 } // end namespace llvm