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"
22 #include <unordered_map>
31 class MachineFunction
;
38 /// The base class for BTF type generation.
44 struct BTF::CommonType BTFType
;
47 BTFTypeBase() : IsCompleted(false) {}
48 virtual ~BTFTypeBase() = default;
49 void setId(uint32_t Id
) { this->Id
= Id
; }
50 uint32_t getId() { return Id
; }
51 uint32_t roundupToBytes(uint32_t NumBits
) { return (NumBits
+ 7) >> 3; }
52 /// Get the size of this BTF type entry.
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.
57 virtual void completeType(BTFDebug
&BDebug
) {}
58 /// Emit types for this BTF type entry.
59 virtual void emitType(MCStreamer
&OS
);
62 /// Handle several derived types include pointer, const,
63 /// volatile, typedef and restrict.
64 class BTFTypeDerived
: public BTFTypeBase
{
65 const DIDerivedType
*DTy
;
69 BTFTypeDerived(const DIDerivedType
*Ty
, unsigned Tag
, bool NeedsFixup
);
70 void completeType(BTFDebug
&BDebug
) override
;
71 void emitType(MCStreamer
&OS
) override
;
72 void setPointeeType(uint32_t PointeeType
);
75 /// Handle struct or union forward declaration.
76 class BTFTypeFwd
: public BTFTypeBase
{
80 BTFTypeFwd(StringRef Name
, bool IsUnion
);
81 void completeType(BTFDebug
&BDebug
) override
;
82 void emitType(MCStreamer
&OS
) override
;
86 class BTFTypeInt
: public BTFTypeBase
{
88 uint32_t IntVal
; ///< Encoding, offset, bits
91 BTFTypeInt(uint32_t Encoding
, uint32_t SizeInBits
, uint32_t OffsetInBits
,
93 uint32_t getSize() override
{ return BTFTypeBase::getSize() + sizeof(uint32_t); }
94 void completeType(BTFDebug
&BDebug
) override
;
95 void emitType(MCStreamer
&OS
) override
;
98 /// Handle enumerate type.
99 class BTFTypeEnum
: public BTFTypeBase
{
100 const DICompositeType
*ETy
;
101 std::vector
<struct BTF::BTFEnum
> EnumValues
;
104 BTFTypeEnum(const DICompositeType
*ETy
, uint32_t NumValues
);
105 uint32_t getSize() override
{
106 return BTFTypeBase::getSize() + EnumValues
.size() * BTF::BTFEnumSize
;
108 void completeType(BTFDebug
&BDebug
) override
;
109 void emitType(MCStreamer
&OS
) override
;
112 /// Handle array type.
113 class BTFTypeArray
: public BTFTypeBase
{
114 struct BTF::BTFArray ArrayInfo
;
117 BTFTypeArray(uint32_t ElemTypeId
, uint32_t NumElems
);
118 uint32_t getSize() override
{ return BTFTypeBase::getSize() + BTF::BTFArraySize
; }
119 void completeType(BTFDebug
&BDebug
) override
;
120 void emitType(MCStreamer
&OS
) override
;
123 /// Handle struct/union type.
124 class BTFTypeStruct
: public BTFTypeBase
{
125 const DICompositeType
*STy
;
127 std::vector
<struct BTF::BTFMember
> Members
;
130 BTFTypeStruct(const DICompositeType
*STy
, bool IsStruct
, bool HasBitField
,
131 uint32_t NumMembers
);
132 uint32_t getSize() override
{
133 return BTFTypeBase::getSize() + Members
.size() * BTF::BTFMemberSize
;
135 void completeType(BTFDebug
&BDebug
) override
;
136 void emitType(MCStreamer
&OS
) override
;
137 std::string
getName();
140 /// Handle function pointer.
141 class BTFTypeFuncProto
: public BTFTypeBase
{
142 const DISubroutineType
*STy
;
143 std::unordered_map
<uint32_t, StringRef
> FuncArgNames
;
144 std::vector
<struct BTF::BTFParam
> Parameters
;
147 BTFTypeFuncProto(const DISubroutineType
*STy
, uint32_t NumParams
,
148 const std::unordered_map
<uint32_t, StringRef
> &FuncArgNames
);
149 uint32_t getSize() override
{
150 return BTFTypeBase::getSize() + Parameters
.size() * BTF::BTFParamSize
;
152 void completeType(BTFDebug
&BDebug
) override
;
153 void emitType(MCStreamer
&OS
) override
;
156 /// Handle subprogram
157 class BTFTypeFunc
: public BTFTypeBase
{
161 BTFTypeFunc(StringRef FuncName
, uint32_t ProtoTypeId
, uint32_t Scope
);
162 uint32_t getSize() override
{ return BTFTypeBase::getSize(); }
163 void completeType(BTFDebug
&BDebug
) override
;
164 void emitType(MCStreamer
&OS
) override
;
167 /// Handle variable instances
168 class BTFKindVar
: public BTFTypeBase
{
173 BTFKindVar(StringRef VarName
, uint32_t TypeId
, uint32_t VarInfo
);
174 uint32_t getSize() override
{ return BTFTypeBase::getSize() + 4; }
175 void completeType(BTFDebug
&BDebug
) override
;
176 void emitType(MCStreamer
&OS
) override
;
179 /// Handle data sections
180 class BTFKindDataSec
: public BTFTypeBase
{
183 std::vector
<std::tuple
<uint32_t, const MCSymbol
*, uint32_t>> Vars
;
186 BTFKindDataSec(AsmPrinter
*AsmPrt
, std::string SecName
);
187 uint32_t getSize() override
{
188 return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize
* Vars
.size();
190 void addDataSecEntry(uint32_t Id
, const MCSymbol
*Sym
, uint32_t Size
) {
191 Vars
.push_back(std::make_tuple(Id
, Sym
, Size
));
193 std::string
getName() { return Name
; }
194 void completeType(BTFDebug
&BDebug
) override
;
195 void emitType(MCStreamer
&OS
) override
;
198 /// Handle binary floating point type.
199 class BTFTypeFloat
: public BTFTypeBase
{
203 BTFTypeFloat(uint32_t SizeInBits
, StringRef TypeName
);
204 void completeType(BTFDebug
&BDebug
) override
;
208 class BTFStringTable
{
209 /// String table size in bytes.
211 /// A mapping from string table offset to the index
212 /// of the Table. It is used to avoid putting
213 /// duplicated strings in the table.
214 std::map
<uint32_t, uint32_t> OffsetToIdMap
;
215 /// A vector of strings to represent the string table.
216 std::vector
<std::string
> Table
;
219 BTFStringTable() : Size(0) {}
220 uint32_t getSize() { return Size
; }
221 std::vector
<std::string
> &getTable() { return Table
; }
222 /// Add a string to the string table and returns its offset
224 uint32_t addString(StringRef S
);
227 /// Represent one func and its type id.
229 const MCSymbol
*Label
; ///< Func MCSymbol
230 uint32_t TypeId
; ///< Type id referring to .BTF type section
233 /// Represent one line info.
235 MCSymbol
*Label
; ///< MCSymbol identifying insn for the lineinfo
236 uint32_t FileNameOff
; ///< file name offset in the .BTF string table
237 uint32_t LineOff
; ///< line offset in the .BTF string table
238 uint32_t LineNum
; ///< the line number
239 uint32_t ColumnNum
; ///< the column number
242 /// Represent one field relocation.
243 struct BTFFieldReloc
{
244 const MCSymbol
*Label
; ///< MCSymbol identifying insn for the reloc
245 uint32_t TypeID
; ///< Type ID
246 uint32_t OffsetNameOff
; ///< The string to traverse types
247 uint32_t RelocKind
; ///< What to patch the instruction
250 /// Collect and emit BTF information.
251 class BTFDebug
: public DebugHandlerBase
{
253 bool SkipInstruction
;
254 bool LineInfoGenerated
;
256 uint32_t ArrayIndexTypeId
;
257 bool MapDefNotCollected
;
258 BTFStringTable StringTable
;
259 std::vector
<std::unique_ptr
<BTFTypeBase
>> TypeEntries
;
260 std::unordered_map
<const DIType
*, uint32_t> DIToIdMap
;
261 std::map
<uint32_t, std::vector
<BTFFuncInfo
>> FuncInfoTable
;
262 std::map
<uint32_t, std::vector
<BTFLineInfo
>> LineInfoTable
;
263 std::map
<uint32_t, std::vector
<BTFFieldReloc
>> FieldRelocTable
;
264 StringMap
<std::vector
<std::string
>> FileContent
;
265 std::map
<std::string
, std::unique_ptr
<BTFKindDataSec
>> DataSecEntries
;
266 std::vector
<BTFTypeStruct
*> StructTypes
;
267 std::map
<const GlobalVariable
*, std::pair
<int64_t, uint32_t>> PatchImms
;
268 std::map
<StringRef
, std::pair
<bool, std::vector
<BTFTypeDerived
*>>>
270 std::set
<const Function
*>ProtoFunctions
;
272 /// Add types to TypeEntries.
274 /// Add types to TypeEntries and DIToIdMap.
275 uint32_t addType(std::unique_ptr
<BTFTypeBase
> TypeEntry
, const DIType
*Ty
);
276 /// Add types to TypeEntries only and return type id.
277 uint32_t addType(std::unique_ptr
<BTFTypeBase
> TypeEntry
);
280 /// IR type visiting functions.
282 void visitTypeEntry(const DIType
*Ty
);
283 void visitTypeEntry(const DIType
*Ty
, uint32_t &TypeId
, bool CheckPointer
,
285 void visitBasicType(const DIBasicType
*BTy
, uint32_t &TypeId
);
286 void visitSubroutineType(
287 const DISubroutineType
*STy
, bool ForSubprog
,
288 const std::unordered_map
<uint32_t, StringRef
> &FuncArgNames
,
290 void visitFwdDeclType(const DICompositeType
*CTy
, bool IsUnion
,
292 void visitCompositeType(const DICompositeType
*CTy
, uint32_t &TypeId
);
293 void visitStructType(const DICompositeType
*STy
, bool IsStruct
,
295 void visitArrayType(const DICompositeType
*ATy
, uint32_t &TypeId
);
296 void visitEnumType(const DICompositeType
*ETy
, uint32_t &TypeId
);
297 void visitDerivedType(const DIDerivedType
*DTy
, uint32_t &TypeId
,
298 bool CheckPointer
, bool SeenPointer
);
299 void visitMapDefType(const DIType
*Ty
, uint32_t &TypeId
);
302 /// Get the file content for the subprogram. Certain lines of the file
303 /// later may be put into string table and referenced by line info.
304 std::string
populateFileContent(const DISubprogram
*SP
);
306 /// Construct a line info.
307 void constructLineInfo(const DISubprogram
*SP
, MCSymbol
*Label
, uint32_t Line
,
310 /// Generate types and variables for globals.
311 void processGlobals(bool ProcessingMapDef
);
313 /// Generate types for function prototypes.
314 void processFuncPrototypes(const Function
*);
316 /// Generate one field relocation record.
317 void generatePatchImmReloc(const MCSymbol
*ORSym
, uint32_t RootId
,
318 const GlobalVariable
*, bool IsAma
);
320 /// Populating unprocessed type on demand.
321 unsigned populateType(const DIType
*Ty
);
323 /// Process global variables referenced by relocation instructions
324 /// and extern function references.
325 void processGlobalValue(const MachineOperand
&MO
);
327 /// Emit common header of .BTF and .BTF.ext sections.
328 void emitCommonHeader();
330 /// Emit the .BTF section.
331 void emitBTFSection();
333 /// Emit the .BTF.ext section.
334 void emitBTFExtSection();
337 /// Gather pre-function debug information.
338 void beginFunctionImpl(const MachineFunction
*MF
) override
;
340 /// Post process after all instructions in this function are processed.
341 void endFunctionImpl(const MachineFunction
*MF
) override
;
344 BTFDebug(AsmPrinter
*AP
);
347 bool InstLower(const MachineInstr
*MI
, MCInst
&OutMI
);
349 /// Get the special array index type id.
350 uint32_t getArrayIndexTypeId() {
351 assert(ArrayIndexTypeId
);
352 return ArrayIndexTypeId
;
355 /// Add string to the string table.
356 size_t addString(StringRef S
) { return StringTable
.addString(S
); }
358 /// Get the type id for a particular DIType.
359 uint32_t getTypeId(const DIType
*Ty
) {
360 assert(Ty
&& "Invalid null Type");
361 assert(DIToIdMap
.find(Ty
) != DIToIdMap
.end() &&
362 "DIType not added in the BDIToIdMap");
363 return DIToIdMap
[Ty
];
366 void setSymbolSize(const MCSymbol
*Symbol
, uint64_t Size
) override
{}
368 /// Process beginning of an instruction.
369 void beginInstruction(const MachineInstr
*MI
) override
;
371 /// Complete all the types and emit the BTF sections.
372 void endModule() override
;
375 } // end namespace llvm