Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/BPF/BTFDebug.cpp
35269 views
1
//===- BTFDebug.cpp - BTF Generator ---------------------------------------===//
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
// This file contains support for writing BTF debug info.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "BTFDebug.h"
14
#include "BPF.h"
15
#include "BPFCORE.h"
16
#include "MCTargetDesc/BPFMCTargetDesc.h"
17
#include "llvm/BinaryFormat/ELF.h"
18
#include "llvm/CodeGen/AsmPrinter.h"
19
#include "llvm/CodeGen/MachineModuleInfo.h"
20
#include "llvm/CodeGen/MachineOperand.h"
21
#include "llvm/IR/Module.h"
22
#include "llvm/MC/MCContext.h"
23
#include "llvm/MC/MCObjectFileInfo.h"
24
#include "llvm/MC/MCSectionELF.h"
25
#include "llvm/MC/MCStreamer.h"
26
#include "llvm/Support/LineIterator.h"
27
#include "llvm/Support/MemoryBuffer.h"
28
#include "llvm/Target/TargetLoweringObjectFile.h"
29
#include <optional>
30
31
using namespace llvm;
32
33
static const char *BTFKindStr[] = {
34
#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
35
#include "llvm/DebugInfo/BTF/BTF.def"
36
};
37
38
/// Emit a BTF common type.
39
void BTFTypeBase::emitType(MCStreamer &OS) {
40
OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) +
41
")");
42
OS.emitInt32(BTFType.NameOff);
43
OS.AddComment("0x" + Twine::utohexstr(BTFType.Info));
44
OS.emitInt32(BTFType.Info);
45
OS.emitInt32(BTFType.Size);
46
}
47
48
BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag,
49
bool NeedsFixup)
50
: DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->getName()) {
51
switch (Tag) {
52
case dwarf::DW_TAG_pointer_type:
53
Kind = BTF::BTF_KIND_PTR;
54
break;
55
case dwarf::DW_TAG_const_type:
56
Kind = BTF::BTF_KIND_CONST;
57
break;
58
case dwarf::DW_TAG_volatile_type:
59
Kind = BTF::BTF_KIND_VOLATILE;
60
break;
61
case dwarf::DW_TAG_typedef:
62
Kind = BTF::BTF_KIND_TYPEDEF;
63
break;
64
case dwarf::DW_TAG_restrict_type:
65
Kind = BTF::BTF_KIND_RESTRICT;
66
break;
67
default:
68
llvm_unreachable("Unknown DIDerivedType Tag");
69
}
70
BTFType.Info = Kind << 24;
71
}
72
73
/// Used by DW_TAG_pointer_type only.
74
BTFTypeDerived::BTFTypeDerived(unsigned NextTypeId, unsigned Tag,
75
StringRef Name)
76
: DTy(nullptr), NeedsFixup(false), Name(Name) {
77
Kind = BTF::BTF_KIND_PTR;
78
BTFType.Info = Kind << 24;
79
BTFType.Type = NextTypeId;
80
}
81
82
void BTFTypeDerived::completeType(BTFDebug &BDebug) {
83
if (IsCompleted)
84
return;
85
IsCompleted = true;
86
87
BTFType.NameOff = BDebug.addString(Name);
88
89
if (NeedsFixup || !DTy)
90
return;
91
92
// The base type for PTR/CONST/VOLATILE could be void.
93
const DIType *ResolvedType = DTy->getBaseType();
94
if (!ResolvedType) {
95
assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||
96
Kind == BTF::BTF_KIND_VOLATILE) &&
97
"Invalid null basetype");
98
BTFType.Type = 0;
99
} else {
100
BTFType.Type = BDebug.getTypeId(ResolvedType);
101
}
102
}
103
104
void BTFTypeDerived::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
105
106
void BTFTypeDerived::setPointeeType(uint32_t PointeeType) {
107
BTFType.Type = PointeeType;
108
}
109
110
/// Represent a struct/union forward declaration.
111
BTFTypeFwd::BTFTypeFwd(StringRef Name, bool IsUnion) : Name(Name) {
112
Kind = BTF::BTF_KIND_FWD;
113
BTFType.Info = IsUnion << 31 | Kind << 24;
114
BTFType.Type = 0;
115
}
116
117
void BTFTypeFwd::completeType(BTFDebug &BDebug) {
118
if (IsCompleted)
119
return;
120
IsCompleted = true;
121
122
BTFType.NameOff = BDebug.addString(Name);
123
}
124
125
void BTFTypeFwd::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
126
127
BTFTypeInt::BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits,
128
uint32_t OffsetInBits, StringRef TypeName)
129
: Name(TypeName) {
130
// Translate IR int encoding to BTF int encoding.
131
uint8_t BTFEncoding;
132
switch (Encoding) {
133
case dwarf::DW_ATE_boolean:
134
BTFEncoding = BTF::INT_BOOL;
135
break;
136
case dwarf::DW_ATE_signed:
137
case dwarf::DW_ATE_signed_char:
138
BTFEncoding = BTF::INT_SIGNED;
139
break;
140
case dwarf::DW_ATE_unsigned:
141
case dwarf::DW_ATE_unsigned_char:
142
BTFEncoding = 0;
143
break;
144
default:
145
llvm_unreachable("Unknown BTFTypeInt Encoding");
146
}
147
148
Kind = BTF::BTF_KIND_INT;
149
BTFType.Info = Kind << 24;
150
BTFType.Size = roundupToBytes(SizeInBits);
151
IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
152
}
153
154
void BTFTypeInt::completeType(BTFDebug &BDebug) {
155
if (IsCompleted)
156
return;
157
IsCompleted = true;
158
159
BTFType.NameOff = BDebug.addString(Name);
160
}
161
162
void BTFTypeInt::emitType(MCStreamer &OS) {
163
BTFTypeBase::emitType(OS);
164
OS.AddComment("0x" + Twine::utohexstr(IntVal));
165
OS.emitInt32(IntVal);
166
}
167
168
BTFTypeEnum::BTFTypeEnum(const DICompositeType *ETy, uint32_t VLen,
169
bool IsSigned) : ETy(ETy) {
170
Kind = BTF::BTF_KIND_ENUM;
171
BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
172
BTFType.Size = roundupToBytes(ETy->getSizeInBits());
173
}
174
175
void BTFTypeEnum::completeType(BTFDebug &BDebug) {
176
if (IsCompleted)
177
return;
178
IsCompleted = true;
179
180
BTFType.NameOff = BDebug.addString(ETy->getName());
181
182
DINodeArray Elements = ETy->getElements();
183
for (const auto Element : Elements) {
184
const auto *Enum = cast<DIEnumerator>(Element);
185
186
struct BTF::BTFEnum BTFEnum;
187
BTFEnum.NameOff = BDebug.addString(Enum->getName());
188
// BTF enum value is 32bit, enforce it.
189
uint32_t Value;
190
if (Enum->isUnsigned())
191
Value = static_cast<uint32_t>(Enum->getValue().getZExtValue());
192
else
193
Value = static_cast<uint32_t>(Enum->getValue().getSExtValue());
194
BTFEnum.Val = Value;
195
EnumValues.push_back(BTFEnum);
196
}
197
}
198
199
void BTFTypeEnum::emitType(MCStreamer &OS) {
200
BTFTypeBase::emitType(OS);
201
for (const auto &Enum : EnumValues) {
202
OS.emitInt32(Enum.NameOff);
203
OS.emitInt32(Enum.Val);
204
}
205
}
206
207
BTFTypeEnum64::BTFTypeEnum64(const DICompositeType *ETy, uint32_t VLen,
208
bool IsSigned) : ETy(ETy) {
209
Kind = BTF::BTF_KIND_ENUM64;
210
BTFType.Info = IsSigned << 31 | Kind << 24 | VLen;
211
BTFType.Size = roundupToBytes(ETy->getSizeInBits());
212
}
213
214
void BTFTypeEnum64::completeType(BTFDebug &BDebug) {
215
if (IsCompleted)
216
return;
217
IsCompleted = true;
218
219
BTFType.NameOff = BDebug.addString(ETy->getName());
220
221
DINodeArray Elements = ETy->getElements();
222
for (const auto Element : Elements) {
223
const auto *Enum = cast<DIEnumerator>(Element);
224
225
struct BTF::BTFEnum64 BTFEnum;
226
BTFEnum.NameOff = BDebug.addString(Enum->getName());
227
uint64_t Value;
228
if (Enum->isUnsigned())
229
Value = static_cast<uint64_t>(Enum->getValue().getZExtValue());
230
else
231
Value = static_cast<uint64_t>(Enum->getValue().getSExtValue());
232
BTFEnum.Val_Lo32 = Value;
233
BTFEnum.Val_Hi32 = Value >> 32;
234
EnumValues.push_back(BTFEnum);
235
}
236
}
237
238
void BTFTypeEnum64::emitType(MCStreamer &OS) {
239
BTFTypeBase::emitType(OS);
240
for (const auto &Enum : EnumValues) {
241
OS.emitInt32(Enum.NameOff);
242
OS.AddComment("0x" + Twine::utohexstr(Enum.Val_Lo32));
243
OS.emitInt32(Enum.Val_Lo32);
244
OS.AddComment("0x" + Twine::utohexstr(Enum.Val_Hi32));
245
OS.emitInt32(Enum.Val_Hi32);
246
}
247
}
248
249
BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems) {
250
Kind = BTF::BTF_KIND_ARRAY;
251
BTFType.NameOff = 0;
252
BTFType.Info = Kind << 24;
253
BTFType.Size = 0;
254
255
ArrayInfo.ElemType = ElemTypeId;
256
ArrayInfo.Nelems = NumElems;
257
}
258
259
/// Represent a BTF array.
260
void BTFTypeArray::completeType(BTFDebug &BDebug) {
261
if (IsCompleted)
262
return;
263
IsCompleted = true;
264
265
// The IR does not really have a type for the index.
266
// A special type for array index should have been
267
// created during initial type traversal. Just
268
// retrieve that type id.
269
ArrayInfo.IndexType = BDebug.getArrayIndexTypeId();
270
}
271
272
void BTFTypeArray::emitType(MCStreamer &OS) {
273
BTFTypeBase::emitType(OS);
274
OS.emitInt32(ArrayInfo.ElemType);
275
OS.emitInt32(ArrayInfo.IndexType);
276
OS.emitInt32(ArrayInfo.Nelems);
277
}
278
279
/// Represent either a struct or a union.
280
BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct,
281
bool HasBitField, uint32_t Vlen)
282
: STy(STy), HasBitField(HasBitField) {
283
Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
284
BTFType.Size = roundupToBytes(STy->getSizeInBits());
285
BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;
286
}
287
288
void BTFTypeStruct::completeType(BTFDebug &BDebug) {
289
if (IsCompleted)
290
return;
291
IsCompleted = true;
292
293
BTFType.NameOff = BDebug.addString(STy->getName());
294
295
// Add struct/union members.
296
const DINodeArray Elements = STy->getElements();
297
for (const auto *Element : Elements) {
298
struct BTF::BTFMember BTFMember;
299
const auto *DDTy = cast<DIDerivedType>(Element);
300
301
BTFMember.NameOff = BDebug.addString(DDTy->getName());
302
if (HasBitField) {
303
uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
304
BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
305
} else {
306
BTFMember.Offset = DDTy->getOffsetInBits();
307
}
308
const auto *BaseTy = DDTy->getBaseType();
309
BTFMember.Type = BDebug.getTypeId(BaseTy);
310
Members.push_back(BTFMember);
311
}
312
}
313
314
void BTFTypeStruct::emitType(MCStreamer &OS) {
315
BTFTypeBase::emitType(OS);
316
for (const auto &Member : Members) {
317
OS.emitInt32(Member.NameOff);
318
OS.emitInt32(Member.Type);
319
OS.AddComment("0x" + Twine::utohexstr(Member.Offset));
320
OS.emitInt32(Member.Offset);
321
}
322
}
323
324
std::string BTFTypeStruct::getName() { return std::string(STy->getName()); }
325
326
/// The Func kind represents both subprogram and pointee of function
327
/// pointers. If the FuncName is empty, it represents a pointee of function
328
/// pointer. Otherwise, it represents a subprogram. The func arg names
329
/// are empty for pointee of function pointer case, and are valid names
330
/// for subprogram.
331
BTFTypeFuncProto::BTFTypeFuncProto(
332
const DISubroutineType *STy, uint32_t VLen,
333
const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
334
: STy(STy), FuncArgNames(FuncArgNames) {
335
Kind = BTF::BTF_KIND_FUNC_PROTO;
336
BTFType.Info = (Kind << 24) | VLen;
337
}
338
339
void BTFTypeFuncProto::completeType(BTFDebug &BDebug) {
340
if (IsCompleted)
341
return;
342
IsCompleted = true;
343
344
DITypeRefArray Elements = STy->getTypeArray();
345
auto RetType = Elements[0];
346
BTFType.Type = RetType ? BDebug.getTypeId(RetType) : 0;
347
BTFType.NameOff = 0;
348
349
// For null parameter which is typically the last one
350
// to represent the vararg, encode the NameOff/Type to be 0.
351
for (unsigned I = 1, N = Elements.size(); I < N; ++I) {
352
struct BTF::BTFParam Param;
353
auto Element = Elements[I];
354
if (Element) {
355
Param.NameOff = BDebug.addString(FuncArgNames[I]);
356
Param.Type = BDebug.getTypeId(Element);
357
} else {
358
Param.NameOff = 0;
359
Param.Type = 0;
360
}
361
Parameters.push_back(Param);
362
}
363
}
364
365
void BTFTypeFuncProto::emitType(MCStreamer &OS) {
366
BTFTypeBase::emitType(OS);
367
for (const auto &Param : Parameters) {
368
OS.emitInt32(Param.NameOff);
369
OS.emitInt32(Param.Type);
370
}
371
}
372
373
BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId,
374
uint32_t Scope)
375
: Name(FuncName) {
376
Kind = BTF::BTF_KIND_FUNC;
377
BTFType.Info = (Kind << 24) | Scope;
378
BTFType.Type = ProtoTypeId;
379
}
380
381
void BTFTypeFunc::completeType(BTFDebug &BDebug) {
382
if (IsCompleted)
383
return;
384
IsCompleted = true;
385
386
BTFType.NameOff = BDebug.addString(Name);
387
}
388
389
void BTFTypeFunc::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
390
391
BTFKindVar::BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
392
: Name(VarName) {
393
Kind = BTF::BTF_KIND_VAR;
394
BTFType.Info = Kind << 24;
395
BTFType.Type = TypeId;
396
Info = VarInfo;
397
}
398
399
void BTFKindVar::completeType(BTFDebug &BDebug) {
400
BTFType.NameOff = BDebug.addString(Name);
401
}
402
403
void BTFKindVar::emitType(MCStreamer &OS) {
404
BTFTypeBase::emitType(OS);
405
OS.emitInt32(Info);
406
}
407
408
BTFKindDataSec::BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
409
: Asm(AsmPrt), Name(SecName) {
410
Kind = BTF::BTF_KIND_DATASEC;
411
BTFType.Info = Kind << 24;
412
BTFType.Size = 0;
413
}
414
415
void BTFKindDataSec::completeType(BTFDebug &BDebug) {
416
BTFType.NameOff = BDebug.addString(Name);
417
BTFType.Info |= Vars.size();
418
}
419
420
void BTFKindDataSec::emitType(MCStreamer &OS) {
421
BTFTypeBase::emitType(OS);
422
423
for (const auto &V : Vars) {
424
OS.emitInt32(std::get<0>(V));
425
Asm->emitLabelReference(std::get<1>(V), 4);
426
OS.emitInt32(std::get<2>(V));
427
}
428
}
429
430
BTFTypeFloat::BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
431
: Name(TypeName) {
432
Kind = BTF::BTF_KIND_FLOAT;
433
BTFType.Info = Kind << 24;
434
BTFType.Size = roundupToBytes(SizeInBits);
435
}
436
437
void BTFTypeFloat::completeType(BTFDebug &BDebug) {
438
if (IsCompleted)
439
return;
440
IsCompleted = true;
441
442
BTFType.NameOff = BDebug.addString(Name);
443
}
444
445
BTFTypeDeclTag::BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentIdx,
446
StringRef Tag)
447
: Tag(Tag) {
448
Kind = BTF::BTF_KIND_DECL_TAG;
449
BTFType.Info = Kind << 24;
450
BTFType.Type = BaseTypeId;
451
Info = ComponentIdx;
452
}
453
454
void BTFTypeDeclTag::completeType(BTFDebug &BDebug) {
455
if (IsCompleted)
456
return;
457
IsCompleted = true;
458
459
BTFType.NameOff = BDebug.addString(Tag);
460
}
461
462
void BTFTypeDeclTag::emitType(MCStreamer &OS) {
463
BTFTypeBase::emitType(OS);
464
OS.emitInt32(Info);
465
}
466
467
BTFTypeTypeTag::BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag)
468
: DTy(nullptr), Tag(Tag) {
469
Kind = BTF::BTF_KIND_TYPE_TAG;
470
BTFType.Info = Kind << 24;
471
BTFType.Type = NextTypeId;
472
}
473
474
BTFTypeTypeTag::BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag)
475
: DTy(DTy), Tag(Tag) {
476
Kind = BTF::BTF_KIND_TYPE_TAG;
477
BTFType.Info = Kind << 24;
478
}
479
480
void BTFTypeTypeTag::completeType(BTFDebug &BDebug) {
481
if (IsCompleted)
482
return;
483
IsCompleted = true;
484
BTFType.NameOff = BDebug.addString(Tag);
485
if (DTy) {
486
const DIType *ResolvedType = DTy->getBaseType();
487
if (!ResolvedType)
488
BTFType.Type = 0;
489
else
490
BTFType.Type = BDebug.getTypeId(ResolvedType);
491
}
492
}
493
494
uint32_t BTFStringTable::addString(StringRef S) {
495
// Check whether the string already exists.
496
for (auto &OffsetM : OffsetToIdMap) {
497
if (Table[OffsetM.second] == S)
498
return OffsetM.first;
499
}
500
// Not find, add to the string table.
501
uint32_t Offset = Size;
502
OffsetToIdMap[Offset] = Table.size();
503
Table.push_back(std::string(S));
504
Size += S.size() + 1;
505
return Offset;
506
}
507
508
BTFDebug::BTFDebug(AsmPrinter *AP)
509
: DebugHandlerBase(AP), OS(*Asm->OutStreamer), SkipInstruction(false),
510
LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),
511
MapDefNotCollected(true) {
512
addString("\0");
513
}
514
515
uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
516
const DIType *Ty) {
517
TypeEntry->setId(TypeEntries.size() + 1);
518
uint32_t Id = TypeEntry->getId();
519
DIToIdMap[Ty] = Id;
520
TypeEntries.push_back(std::move(TypeEntry));
521
return Id;
522
}
523
524
uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
525
TypeEntry->setId(TypeEntries.size() + 1);
526
uint32_t Id = TypeEntry->getId();
527
TypeEntries.push_back(std::move(TypeEntry));
528
return Id;
529
}
530
531
void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
532
// Only int and binary floating point types are supported in BTF.
533
uint32_t Encoding = BTy->getEncoding();
534
std::unique_ptr<BTFTypeBase> TypeEntry;
535
switch (Encoding) {
536
case dwarf::DW_ATE_boolean:
537
case dwarf::DW_ATE_signed:
538
case dwarf::DW_ATE_signed_char:
539
case dwarf::DW_ATE_unsigned:
540
case dwarf::DW_ATE_unsigned_char:
541
// Create a BTF type instance for this DIBasicType and put it into
542
// DIToIdMap for cross-type reference check.
543
TypeEntry = std::make_unique<BTFTypeInt>(
544
Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
545
break;
546
case dwarf::DW_ATE_float:
547
TypeEntry =
548
std::make_unique<BTFTypeFloat>(BTy->getSizeInBits(), BTy->getName());
549
break;
550
default:
551
return;
552
}
553
554
TypeId = addType(std::move(TypeEntry), BTy);
555
}
556
557
/// Handle subprogram or subroutine types.
558
void BTFDebug::visitSubroutineType(
559
const DISubroutineType *STy, bool ForSubprog,
560
const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
561
uint32_t &TypeId) {
562
DITypeRefArray Elements = STy->getTypeArray();
563
uint32_t VLen = Elements.size() - 1;
564
if (VLen > BTF::MAX_VLEN)
565
return;
566
567
// Subprogram has a valid non-zero-length name, and the pointee of
568
// a function pointer has an empty name. The subprogram type will
569
// not be added to DIToIdMap as it should not be referenced by
570
// any other types.
571
auto TypeEntry = std::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames);
572
if (ForSubprog)
573
TypeId = addType(std::move(TypeEntry)); // For subprogram
574
else
575
TypeId = addType(std::move(TypeEntry), STy); // For func ptr
576
577
// Visit return type and func arg types.
578
for (const auto Element : Elements) {
579
visitTypeEntry(Element);
580
}
581
}
582
583
void BTFDebug::processDeclAnnotations(DINodeArray Annotations,
584
uint32_t BaseTypeId,
585
int ComponentIdx) {
586
if (!Annotations)
587
return;
588
589
for (const Metadata *Annotation : Annotations->operands()) {
590
const MDNode *MD = cast<MDNode>(Annotation);
591
const MDString *Name = cast<MDString>(MD->getOperand(0));
592
if (Name->getString() != "btf_decl_tag")
593
continue;
594
595
const MDString *Value = cast<MDString>(MD->getOperand(1));
596
auto TypeEntry = std::make_unique<BTFTypeDeclTag>(BaseTypeId, ComponentIdx,
597
Value->getString());
598
addType(std::move(TypeEntry));
599
}
600
}
601
602
uint32_t BTFDebug::processDISubprogram(const DISubprogram *SP,
603
uint32_t ProtoTypeId, uint8_t Scope) {
604
auto FuncTypeEntry =
605
std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope);
606
uint32_t FuncId = addType(std::move(FuncTypeEntry));
607
608
// Process argument annotations.
609
for (const DINode *DN : SP->getRetainedNodes()) {
610
if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
611
uint32_t Arg = DV->getArg();
612
if (Arg)
613
processDeclAnnotations(DV->getAnnotations(), FuncId, Arg - 1);
614
}
615
}
616
processDeclAnnotations(SP->getAnnotations(), FuncId, -1);
617
618
return FuncId;
619
}
620
621
/// Generate btf_type_tag chains.
622
int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) {
623
SmallVector<const MDString *, 4> MDStrs;
624
DINodeArray Annots = DTy->getAnnotations();
625
if (Annots) {
626
// For type with "int __tag1 __tag2 *p", the MDStrs will have
627
// content: [__tag1, __tag2].
628
for (const Metadata *Annotations : Annots->operands()) {
629
const MDNode *MD = cast<MDNode>(Annotations);
630
const MDString *Name = cast<MDString>(MD->getOperand(0));
631
if (Name->getString() != "btf_type_tag")
632
continue;
633
MDStrs.push_back(cast<MDString>(MD->getOperand(1)));
634
}
635
}
636
637
if (MDStrs.size() == 0)
638
return -1;
639
640
// With MDStrs [__tag1, __tag2], the output type chain looks like
641
// PTR -> __tag2 -> __tag1 -> BaseType
642
// In the below, we construct BTF types with the order of __tag1, __tag2
643
// and PTR.
644
unsigned TmpTypeId;
645
std::unique_ptr<BTFTypeTypeTag> TypeEntry;
646
if (BaseTypeId >= 0)
647
TypeEntry =
648
std::make_unique<BTFTypeTypeTag>(BaseTypeId, MDStrs[0]->getString());
649
else
650
TypeEntry = std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
651
TmpTypeId = addType(std::move(TypeEntry));
652
653
for (unsigned I = 1; I < MDStrs.size(); I++) {
654
const MDString *Value = MDStrs[I];
655
TypeEntry = std::make_unique<BTFTypeTypeTag>(TmpTypeId, Value->getString());
656
TmpTypeId = addType(std::move(TypeEntry));
657
}
658
return TmpTypeId;
659
}
660
661
/// Handle structure/union types.
662
void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
663
uint32_t &TypeId) {
664
const DINodeArray Elements = CTy->getElements();
665
uint32_t VLen = Elements.size();
666
if (VLen > BTF::MAX_VLEN)
667
return;
668
669
// Check whether we have any bitfield members or not
670
bool HasBitField = false;
671
for (const auto *Element : Elements) {
672
auto E = cast<DIDerivedType>(Element);
673
if (E->isBitField()) {
674
HasBitField = true;
675
break;
676
}
677
}
678
679
auto TypeEntry =
680
std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
681
StructTypes.push_back(TypeEntry.get());
682
TypeId = addType(std::move(TypeEntry), CTy);
683
684
// Check struct/union annotations
685
processDeclAnnotations(CTy->getAnnotations(), TypeId, -1);
686
687
// Visit all struct members.
688
int FieldNo = 0;
689
for (const auto *Element : Elements) {
690
const auto Elem = cast<DIDerivedType>(Element);
691
visitTypeEntry(Elem);
692
processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo);
693
FieldNo++;
694
}
695
}
696
697
void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
698
// Visit array element type.
699
uint32_t ElemTypeId;
700
const DIType *ElemType = CTy->getBaseType();
701
visitTypeEntry(ElemType, ElemTypeId, false, false);
702
703
// Visit array dimensions.
704
DINodeArray Elements = CTy->getElements();
705
for (int I = Elements.size() - 1; I >= 0; --I) {
706
if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
707
if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
708
const DISubrange *SR = cast<DISubrange>(Element);
709
auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
710
int64_t Count = CI->getSExtValue();
711
712
// For struct s { int b; char c[]; }, the c[] will be represented
713
// as an array with Count = -1.
714
auto TypeEntry =
715
std::make_unique<BTFTypeArray>(ElemTypeId,
716
Count >= 0 ? Count : 0);
717
if (I == 0)
718
ElemTypeId = addType(std::move(TypeEntry), CTy);
719
else
720
ElemTypeId = addType(std::move(TypeEntry));
721
}
722
}
723
724
// The array TypeId is the type id of the outermost dimension.
725
TypeId = ElemTypeId;
726
727
// The IR does not have a type for array index while BTF wants one.
728
// So create an array index type if there is none.
729
if (!ArrayIndexTypeId) {
730
auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
731
0, "__ARRAY_SIZE_TYPE__");
732
ArrayIndexTypeId = addType(std::move(TypeEntry));
733
}
734
}
735
736
void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) {
737
DINodeArray Elements = CTy->getElements();
738
uint32_t VLen = Elements.size();
739
if (VLen > BTF::MAX_VLEN)
740
return;
741
742
bool IsSigned = false;
743
unsigned NumBits = 32;
744
// No BaseType implies forward declaration in which case a
745
// BTFTypeEnum with Vlen = 0 is emitted.
746
if (CTy->getBaseType() != nullptr) {
747
const auto *BTy = cast<DIBasicType>(CTy->getBaseType());
748
IsSigned = BTy->getEncoding() == dwarf::DW_ATE_signed ||
749
BTy->getEncoding() == dwarf::DW_ATE_signed_char;
750
NumBits = BTy->getSizeInBits();
751
}
752
753
if (NumBits <= 32) {
754
auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen, IsSigned);
755
TypeId = addType(std::move(TypeEntry), CTy);
756
} else {
757
assert(NumBits == 64);
758
auto TypeEntry = std::make_unique<BTFTypeEnum64>(CTy, VLen, IsSigned);
759
TypeId = addType(std::move(TypeEntry), CTy);
760
}
761
// No need to visit base type as BTF does not encode it.
762
}
763
764
/// Handle structure/union forward declarations.
765
void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
766
uint32_t &TypeId) {
767
auto TypeEntry = std::make_unique<BTFTypeFwd>(CTy->getName(), IsUnion);
768
TypeId = addType(std::move(TypeEntry), CTy);
769
}
770
771
/// Handle structure, union, array and enumeration types.
772
void BTFDebug::visitCompositeType(const DICompositeType *CTy,
773
uint32_t &TypeId) {
774
auto Tag = CTy->getTag();
775
if (Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
776
// Handle forward declaration differently as it does not have members.
777
if (CTy->isForwardDecl())
778
visitFwdDeclType(CTy, Tag == dwarf::DW_TAG_union_type, TypeId);
779
else
780
visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId);
781
} else if (Tag == dwarf::DW_TAG_array_type)
782
visitArrayType(CTy, TypeId);
783
else if (Tag == dwarf::DW_TAG_enumeration_type)
784
visitEnumType(CTy, TypeId);
785
}
786
787
bool BTFDebug::IsForwardDeclCandidate(const DIType *Base) {
788
if (const auto *CTy = dyn_cast<DICompositeType>(Base)) {
789
auto CTag = CTy->getTag();
790
if ((CTag == dwarf::DW_TAG_structure_type ||
791
CTag == dwarf::DW_TAG_union_type) &&
792
!CTy->getName().empty() && !CTy->isForwardDecl())
793
return true;
794
}
795
return false;
796
}
797
798
/// Handle pointer, typedef, const, volatile, restrict and member types.
799
void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
800
bool CheckPointer, bool SeenPointer) {
801
unsigned Tag = DTy->getTag();
802
803
/// Try to avoid chasing pointees, esp. structure pointees which may
804
/// unnecessary bring in a lot of types.
805
if (CheckPointer && !SeenPointer) {
806
SeenPointer = Tag == dwarf::DW_TAG_pointer_type;
807
}
808
809
if (CheckPointer && SeenPointer) {
810
const DIType *Base = DTy->getBaseType();
811
if (Base) {
812
if (IsForwardDeclCandidate(Base)) {
813
/// Find a candidate, generate a fixup. Later on the struct/union
814
/// pointee type will be replaced with either a real type or
815
/// a forward declaration.
816
auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, true);
817
auto &Fixup = FixupDerivedTypes[cast<DICompositeType>(Base)];
818
Fixup.push_back(std::make_pair(DTy, TypeEntry.get()));
819
TypeId = addType(std::move(TypeEntry), DTy);
820
return;
821
}
822
}
823
}
824
825
if (Tag == dwarf::DW_TAG_pointer_type) {
826
int TmpTypeId = genBTFTypeTags(DTy, -1);
827
if (TmpTypeId >= 0) {
828
auto TypeDEntry =
829
std::make_unique<BTFTypeDerived>(TmpTypeId, Tag, DTy->getName());
830
TypeId = addType(std::move(TypeDEntry), DTy);
831
} else {
832
auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false);
833
TypeId = addType(std::move(TypeEntry), DTy);
834
}
835
} else if (Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type ||
836
Tag == dwarf::DW_TAG_volatile_type ||
837
Tag == dwarf::DW_TAG_restrict_type) {
838
auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false);
839
TypeId = addType(std::move(TypeEntry), DTy);
840
if (Tag == dwarf::DW_TAG_typedef)
841
processDeclAnnotations(DTy->getAnnotations(), TypeId, -1);
842
} else if (Tag != dwarf::DW_TAG_member) {
843
return;
844
}
845
846
// Visit base type of pointer, typedef, const, volatile, restrict or
847
// struct/union member.
848
uint32_t TempTypeId = 0;
849
if (Tag == dwarf::DW_TAG_member)
850
visitTypeEntry(DTy->getBaseType(), TempTypeId, true, false);
851
else
852
visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
853
}
854
855
/// Visit a type entry. CheckPointer is true if the type has
856
/// one of its predecessors as one struct/union member. SeenPointer
857
/// is true if CheckPointer is true and one of its predecessors
858
/// is a pointer. The goal of CheckPointer and SeenPointer is to
859
/// do pruning for struct/union types so some of these types
860
/// will not be emitted in BTF and rather forward declarations
861
/// will be generated.
862
void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId,
863
bool CheckPointer, bool SeenPointer) {
864
if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
865
TypeId = DIToIdMap[Ty];
866
867
// To handle the case like the following:
868
// struct t;
869
// typedef struct t _t;
870
// struct s1 { _t *c; };
871
// int test1(struct s1 *arg) { ... }
872
//
873
// struct t { int a; int b; };
874
// struct s2 { _t c; }
875
// int test2(struct s2 *arg) { ... }
876
//
877
// During traversing test1() argument, "_t" is recorded
878
// in DIToIdMap and a forward declaration fixup is created
879
// for "struct t" to avoid pointee type traversal.
880
//
881
// During traversing test2() argument, even if we see "_t" is
882
// already defined, we should keep moving to eventually
883
// bring in types for "struct t". Otherwise, the "struct s2"
884
// definition won't be correct.
885
//
886
// In the above, we have following debuginfo:
887
// {ptr, struct_member} -> typedef -> struct
888
// and BTF type for 'typedef' is generated while 'struct' may
889
// be in FixUp. But let us generalize the above to handle
890
// {different types} -> [various derived types]+ -> another type.
891
// For example,
892
// {func_param, struct_member} -> const -> ptr -> volatile -> struct
893
// We will traverse const/ptr/volatile which already have corresponding
894
// BTF types and generate type for 'struct' which might be in Fixup
895
// state.
896
if (Ty && (!CheckPointer || !SeenPointer)) {
897
if (const auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
898
while (DTy) {
899
const DIType *BaseTy = DTy->getBaseType();
900
if (!BaseTy)
901
break;
902
903
if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) {
904
DTy = dyn_cast<DIDerivedType>(BaseTy);
905
} else {
906
if (CheckPointer && DTy->getTag() == dwarf::DW_TAG_pointer_type) {
907
SeenPointer = true;
908
if (IsForwardDeclCandidate(BaseTy))
909
break;
910
}
911
uint32_t TmpTypeId;
912
visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer);
913
break;
914
}
915
}
916
}
917
}
918
919
return;
920
}
921
922
if (const auto *BTy = dyn_cast<DIBasicType>(Ty))
923
visitBasicType(BTy, TypeId);
924
else if (const auto *STy = dyn_cast<DISubroutineType>(Ty))
925
visitSubroutineType(STy, false, std::unordered_map<uint32_t, StringRef>(),
926
TypeId);
927
else if (const auto *CTy = dyn_cast<DICompositeType>(Ty))
928
visitCompositeType(CTy, TypeId);
929
else if (const auto *DTy = dyn_cast<DIDerivedType>(Ty))
930
visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
931
else
932
llvm_unreachable("Unknown DIType");
933
}
934
935
void BTFDebug::visitTypeEntry(const DIType *Ty) {
936
uint32_t TypeId;
937
visitTypeEntry(Ty, TypeId, false, false);
938
}
939
940
void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
941
if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
942
TypeId = DIToIdMap[Ty];
943
return;
944
}
945
946
// MapDef type may be a struct type or a non-pointer derived type
947
const DIType *OrigTy = Ty;
948
while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
949
auto Tag = DTy->getTag();
950
if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
951
Tag != dwarf::DW_TAG_volatile_type &&
952
Tag != dwarf::DW_TAG_restrict_type)
953
break;
954
Ty = DTy->getBaseType();
955
}
956
957
const auto *CTy = dyn_cast<DICompositeType>(Ty);
958
if (!CTy)
959
return;
960
961
auto Tag = CTy->getTag();
962
if (Tag != dwarf::DW_TAG_structure_type || CTy->isForwardDecl())
963
return;
964
965
// Visit all struct members to ensure pointee type is visited
966
const DINodeArray Elements = CTy->getElements();
967
for (const auto *Element : Elements) {
968
const auto *MemberType = cast<DIDerivedType>(Element);
969
visitTypeEntry(MemberType->getBaseType());
970
}
971
972
// Visit this type, struct or a const/typedef/volatile/restrict type
973
visitTypeEntry(OrigTy, TypeId, false, false);
974
}
975
976
/// Read file contents from the actual file or from the source
977
std::string BTFDebug::populateFileContent(const DIFile *File) {
978
std::string FileName;
979
980
if (!File->getFilename().starts_with("/") && File->getDirectory().size())
981
FileName = File->getDirectory().str() + "/" + File->getFilename().str();
982
else
983
FileName = std::string(File->getFilename());
984
985
// No need to populate the contends if it has been populated!
986
if (FileContent.contains(FileName))
987
return FileName;
988
989
std::vector<std::string> Content;
990
std::string Line;
991
Content.push_back(Line); // Line 0 for empty string
992
993
std::unique_ptr<MemoryBuffer> Buf;
994
auto Source = File->getSource();
995
if (Source)
996
Buf = MemoryBuffer::getMemBufferCopy(*Source);
997
else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
998
MemoryBuffer::getFile(FileName))
999
Buf = std::move(*BufOrErr);
1000
if (Buf)
1001
for (line_iterator I(*Buf, false), E; I != E; ++I)
1002
Content.push_back(std::string(*I));
1003
1004
FileContent[FileName] = Content;
1005
return FileName;
1006
}
1007
1008
void BTFDebug::constructLineInfo(MCSymbol *Label, const DIFile *File,
1009
uint32_t Line, uint32_t Column) {
1010
std::string FileName = populateFileContent(File);
1011
BTFLineInfo LineInfo;
1012
1013
LineInfo.Label = Label;
1014
LineInfo.FileNameOff = addString(FileName);
1015
// If file content is not available, let LineOff = 0.
1016
if (Line < FileContent[FileName].size())
1017
LineInfo.LineOff = addString(FileContent[FileName][Line]);
1018
else
1019
LineInfo.LineOff = 0;
1020
LineInfo.LineNum = Line;
1021
LineInfo.ColumnNum = Column;
1022
LineInfoTable[SecNameOff].push_back(LineInfo);
1023
}
1024
1025
void BTFDebug::emitCommonHeader() {
1026
OS.AddComment("0x" + Twine::utohexstr(BTF::MAGIC));
1027
OS.emitIntValue(BTF::MAGIC, 2);
1028
OS.emitInt8(BTF::VERSION);
1029
OS.emitInt8(0);
1030
}
1031
1032
void BTFDebug::emitBTFSection() {
1033
// Do not emit section if no types and only "" string.
1034
if (!TypeEntries.size() && StringTable.getSize() == 1)
1035
return;
1036
1037
MCContext &Ctx = OS.getContext();
1038
MCSectionELF *Sec = Ctx.getELFSection(".BTF", ELF::SHT_PROGBITS, 0);
1039
Sec->setAlignment(Align(4));
1040
OS.switchSection(Sec);
1041
1042
// Emit header.
1043
emitCommonHeader();
1044
OS.emitInt32(BTF::HeaderSize);
1045
1046
uint32_t TypeLen = 0, StrLen;
1047
for (const auto &TypeEntry : TypeEntries)
1048
TypeLen += TypeEntry->getSize();
1049
StrLen = StringTable.getSize();
1050
1051
OS.emitInt32(0);
1052
OS.emitInt32(TypeLen);
1053
OS.emitInt32(TypeLen);
1054
OS.emitInt32(StrLen);
1055
1056
// Emit type table.
1057
for (const auto &TypeEntry : TypeEntries)
1058
TypeEntry->emitType(OS);
1059
1060
// Emit string table.
1061
uint32_t StringOffset = 0;
1062
for (const auto &S : StringTable.getTable()) {
1063
OS.AddComment("string offset=" + std::to_string(StringOffset));
1064
OS.emitBytes(S);
1065
OS.emitBytes(StringRef("\0", 1));
1066
StringOffset += S.size() + 1;
1067
}
1068
}
1069
1070
void BTFDebug::emitBTFExtSection() {
1071
// Do not emit section if empty FuncInfoTable and LineInfoTable
1072
// and FieldRelocTable.
1073
if (!FuncInfoTable.size() && !LineInfoTable.size() &&
1074
!FieldRelocTable.size())
1075
return;
1076
1077
MCContext &Ctx = OS.getContext();
1078
MCSectionELF *Sec = Ctx.getELFSection(".BTF.ext", ELF::SHT_PROGBITS, 0);
1079
Sec->setAlignment(Align(4));
1080
OS.switchSection(Sec);
1081
1082
// Emit header.
1083
emitCommonHeader();
1084
OS.emitInt32(BTF::ExtHeaderSize);
1085
1086
// Account for FuncInfo/LineInfo record size as well.
1087
uint32_t FuncLen = 4, LineLen = 4;
1088
// Do not account for optional FieldReloc.
1089
uint32_t FieldRelocLen = 0;
1090
for (const auto &FuncSec : FuncInfoTable) {
1091
FuncLen += BTF::SecFuncInfoSize;
1092
FuncLen += FuncSec.second.size() * BTF::BPFFuncInfoSize;
1093
}
1094
for (const auto &LineSec : LineInfoTable) {
1095
LineLen += BTF::SecLineInfoSize;
1096
LineLen += LineSec.second.size() * BTF::BPFLineInfoSize;
1097
}
1098
for (const auto &FieldRelocSec : FieldRelocTable) {
1099
FieldRelocLen += BTF::SecFieldRelocSize;
1100
FieldRelocLen += FieldRelocSec.second.size() * BTF::BPFFieldRelocSize;
1101
}
1102
1103
if (FieldRelocLen)
1104
FieldRelocLen += 4;
1105
1106
OS.emitInt32(0);
1107
OS.emitInt32(FuncLen);
1108
OS.emitInt32(FuncLen);
1109
OS.emitInt32(LineLen);
1110
OS.emitInt32(FuncLen + LineLen);
1111
OS.emitInt32(FieldRelocLen);
1112
1113
// Emit func_info table.
1114
OS.AddComment("FuncInfo");
1115
OS.emitInt32(BTF::BPFFuncInfoSize);
1116
for (const auto &FuncSec : FuncInfoTable) {
1117
OS.AddComment("FuncInfo section string offset=" +
1118
std::to_string(FuncSec.first));
1119
OS.emitInt32(FuncSec.first);
1120
OS.emitInt32(FuncSec.second.size());
1121
for (const auto &FuncInfo : FuncSec.second) {
1122
Asm->emitLabelReference(FuncInfo.Label, 4);
1123
OS.emitInt32(FuncInfo.TypeId);
1124
}
1125
}
1126
1127
// Emit line_info table.
1128
OS.AddComment("LineInfo");
1129
OS.emitInt32(BTF::BPFLineInfoSize);
1130
for (const auto &LineSec : LineInfoTable) {
1131
OS.AddComment("LineInfo section string offset=" +
1132
std::to_string(LineSec.first));
1133
OS.emitInt32(LineSec.first);
1134
OS.emitInt32(LineSec.second.size());
1135
for (const auto &LineInfo : LineSec.second) {
1136
Asm->emitLabelReference(LineInfo.Label, 4);
1137
OS.emitInt32(LineInfo.FileNameOff);
1138
OS.emitInt32(LineInfo.LineOff);
1139
OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " +
1140
std::to_string(LineInfo.ColumnNum));
1141
OS.emitInt32(LineInfo.LineNum << 10 | LineInfo.ColumnNum);
1142
}
1143
}
1144
1145
// Emit field reloc table.
1146
if (FieldRelocLen) {
1147
OS.AddComment("FieldReloc");
1148
OS.emitInt32(BTF::BPFFieldRelocSize);
1149
for (const auto &FieldRelocSec : FieldRelocTable) {
1150
OS.AddComment("Field reloc section string offset=" +
1151
std::to_string(FieldRelocSec.first));
1152
OS.emitInt32(FieldRelocSec.first);
1153
OS.emitInt32(FieldRelocSec.second.size());
1154
for (const auto &FieldRelocInfo : FieldRelocSec.second) {
1155
Asm->emitLabelReference(FieldRelocInfo.Label, 4);
1156
OS.emitInt32(FieldRelocInfo.TypeID);
1157
OS.emitInt32(FieldRelocInfo.OffsetNameOff);
1158
OS.emitInt32(FieldRelocInfo.RelocKind);
1159
}
1160
}
1161
}
1162
}
1163
1164
void BTFDebug::beginFunctionImpl(const MachineFunction *MF) {
1165
auto *SP = MF->getFunction().getSubprogram();
1166
auto *Unit = SP->getUnit();
1167
1168
if (Unit->getEmissionKind() == DICompileUnit::NoDebug) {
1169
SkipInstruction = true;
1170
return;
1171
}
1172
SkipInstruction = false;
1173
1174
// Collect MapDef types. Map definition needs to collect
1175
// pointee types. Do it first. Otherwise, for the following
1176
// case:
1177
// struct m { ...};
1178
// struct t {
1179
// struct m *key;
1180
// };
1181
// foo(struct t *arg);
1182
//
1183
// struct mapdef {
1184
// ...
1185
// struct m *key;
1186
// ...
1187
// } __attribute__((section(".maps"))) hash_map;
1188
//
1189
// If subroutine foo is traversed first, a type chain
1190
// "ptr->struct m(fwd)" will be created and later on
1191
// when traversing mapdef, since "ptr->struct m" exists,
1192
// the traversal of "struct m" will be omitted.
1193
if (MapDefNotCollected) {
1194
processGlobals(true);
1195
MapDefNotCollected = false;
1196
}
1197
1198
// Collect all types locally referenced in this function.
1199
// Use RetainedNodes so we can collect all argument names
1200
// even if the argument is not used.
1201
std::unordered_map<uint32_t, StringRef> FuncArgNames;
1202
for (const DINode *DN : SP->getRetainedNodes()) {
1203
if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
1204
// Collect function arguments for subprogram func type.
1205
uint32_t Arg = DV->getArg();
1206
if (Arg) {
1207
visitTypeEntry(DV->getType());
1208
FuncArgNames[Arg] = DV->getName();
1209
}
1210
}
1211
}
1212
1213
// Construct subprogram func proto type.
1214
uint32_t ProtoTypeId;
1215
visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId);
1216
1217
// Construct subprogram func type
1218
uint8_t Scope = SP->isLocalToUnit() ? BTF::FUNC_STATIC : BTF::FUNC_GLOBAL;
1219
uint32_t FuncTypeId = processDISubprogram(SP, ProtoTypeId, Scope);
1220
1221
for (const auto &TypeEntry : TypeEntries)
1222
TypeEntry->completeType(*this);
1223
1224
// Construct funcinfo and the first lineinfo for the function.
1225
MCSymbol *FuncLabel = Asm->getFunctionBegin();
1226
BTFFuncInfo FuncInfo;
1227
FuncInfo.Label = FuncLabel;
1228
FuncInfo.TypeId = FuncTypeId;
1229
if (FuncLabel->isInSection()) {
1230
MCSection &Section = FuncLabel->getSection();
1231
const MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(&Section);
1232
assert(SectionELF && "Null section for Function Label");
1233
SecNameOff = addString(SectionELF->getName());
1234
} else {
1235
SecNameOff = addString(".text");
1236
}
1237
FuncInfoTable[SecNameOff].push_back(FuncInfo);
1238
}
1239
1240
void BTFDebug::endFunctionImpl(const MachineFunction *MF) {
1241
SkipInstruction = false;
1242
LineInfoGenerated = false;
1243
SecNameOff = 0;
1244
}
1245
1246
/// On-demand populate types as requested from abstract member
1247
/// accessing or preserve debuginfo type.
1248
unsigned BTFDebug::populateType(const DIType *Ty) {
1249
unsigned Id;
1250
visitTypeEntry(Ty, Id, false, false);
1251
for (const auto &TypeEntry : TypeEntries)
1252
TypeEntry->completeType(*this);
1253
return Id;
1254
}
1255
1256
/// Generate a struct member field relocation.
1257
void BTFDebug::generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
1258
const GlobalVariable *GVar, bool IsAma) {
1259
BTFFieldReloc FieldReloc;
1260
FieldReloc.Label = ORSym;
1261
FieldReloc.TypeID = RootId;
1262
1263
StringRef AccessPattern = GVar->getName();
1264
size_t FirstDollar = AccessPattern.find_first_of('$');
1265
if (IsAma) {
1266
size_t FirstColon = AccessPattern.find_first_of(':');
1267
size_t SecondColon = AccessPattern.find_first_of(':', FirstColon + 1);
1268
StringRef IndexPattern = AccessPattern.substr(FirstDollar + 1);
1269
StringRef RelocKindStr = AccessPattern.substr(FirstColon + 1,
1270
SecondColon - FirstColon);
1271
StringRef PatchImmStr = AccessPattern.substr(SecondColon + 1,
1272
FirstDollar - SecondColon);
1273
1274
FieldReloc.OffsetNameOff = addString(IndexPattern);
1275
FieldReloc.RelocKind = std::stoull(std::string(RelocKindStr));
1276
PatchImms[GVar] = std::make_pair(std::stoll(std::string(PatchImmStr)),
1277
FieldReloc.RelocKind);
1278
} else {
1279
StringRef RelocStr = AccessPattern.substr(FirstDollar + 1);
1280
FieldReloc.OffsetNameOff = addString("0");
1281
FieldReloc.RelocKind = std::stoull(std::string(RelocStr));
1282
PatchImms[GVar] = std::make_pair(RootId, FieldReloc.RelocKind);
1283
}
1284
FieldRelocTable[SecNameOff].push_back(FieldReloc);
1285
}
1286
1287
void BTFDebug::processGlobalValue(const MachineOperand &MO) {
1288
// check whether this is a candidate or not
1289
if (MO.isGlobal()) {
1290
const GlobalValue *GVal = MO.getGlobal();
1291
auto *GVar = dyn_cast<GlobalVariable>(GVal);
1292
if (!GVar) {
1293
// Not a global variable. Maybe an extern function reference.
1294
processFuncPrototypes(dyn_cast<Function>(GVal));
1295
return;
1296
}
1297
1298
if (!GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr) &&
1299
!GVar->hasAttribute(BPFCoreSharedInfo::TypeIdAttr))
1300
return;
1301
1302
MCSymbol *ORSym = OS.getContext().createTempSymbol();
1303
OS.emitLabel(ORSym);
1304
1305
MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
1306
uint32_t RootId = populateType(dyn_cast<DIType>(MDN));
1307
generatePatchImmReloc(ORSym, RootId, GVar,
1308
GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr));
1309
}
1310
}
1311
1312
void BTFDebug::beginInstruction(const MachineInstr *MI) {
1313
DebugHandlerBase::beginInstruction(MI);
1314
1315
if (SkipInstruction || MI->isMetaInstruction() ||
1316
MI->getFlag(MachineInstr::FrameSetup))
1317
return;
1318
1319
if (MI->isInlineAsm()) {
1320
// Count the number of register definitions to find the asm string.
1321
unsigned NumDefs = 0;
1322
while (true) {
1323
const MachineOperand &MO = MI->getOperand(NumDefs);
1324
if (MO.isReg() && MO.isDef()) {
1325
++NumDefs;
1326
continue;
1327
}
1328
// Skip this inline asm instruction if the asmstr is empty.
1329
const char *AsmStr = MO.getSymbolName();
1330
if (AsmStr[0] == 0)
1331
return;
1332
break;
1333
}
1334
}
1335
1336
if (MI->getOpcode() == BPF::LD_imm64) {
1337
// If the insn is "r2 = LD_imm64 @<an AmaAttr global>",
1338
// add this insn into the .BTF.ext FieldReloc subsection.
1339
// Relocation looks like:
1340
// . SecName:
1341
// . InstOffset
1342
// . TypeID
1343
// . OffSetNameOff
1344
// . RelocType
1345
// Later, the insn is replaced with "r2 = <offset>"
1346
// where "<offset>" equals to the offset based on current
1347
// type definitions.
1348
//
1349
// If the insn is "r2 = LD_imm64 @<an TypeIdAttr global>",
1350
// The LD_imm64 result will be replaced with a btf type id.
1351
processGlobalValue(MI->getOperand(1));
1352
} else if (MI->getOpcode() == BPF::CORE_LD64 ||
1353
MI->getOpcode() == BPF::CORE_LD32 ||
1354
MI->getOpcode() == BPF::CORE_ST ||
1355
MI->getOpcode() == BPF::CORE_SHIFT) {
1356
// relocation insn is a load, store or shift insn.
1357
processGlobalValue(MI->getOperand(3));
1358
} else if (MI->getOpcode() == BPF::JAL) {
1359
// check extern function references
1360
const MachineOperand &MO = MI->getOperand(0);
1361
if (MO.isGlobal()) {
1362
processFuncPrototypes(dyn_cast<Function>(MO.getGlobal()));
1363
}
1364
}
1365
1366
if (!CurMI) // no debug info
1367
return;
1368
1369
// Skip this instruction if no DebugLoc, the DebugLoc
1370
// is the same as the previous instruction or Line is 0.
1371
const DebugLoc &DL = MI->getDebugLoc();
1372
if (!DL || PrevInstLoc == DL || DL.getLine() == 0) {
1373
// This instruction will be skipped, no LineInfo has
1374
// been generated, construct one based on function signature.
1375
if (LineInfoGenerated == false) {
1376
auto *S = MI->getMF()->getFunction().getSubprogram();
1377
if (!S)
1378
return;
1379
MCSymbol *FuncLabel = Asm->getFunctionBegin();
1380
constructLineInfo(FuncLabel, S->getFile(), S->getLine(), 0);
1381
LineInfoGenerated = true;
1382
}
1383
1384
return;
1385
}
1386
1387
// Create a temporary label to remember the insn for lineinfo.
1388
MCSymbol *LineSym = OS.getContext().createTempSymbol();
1389
OS.emitLabel(LineSym);
1390
1391
// Construct the lineinfo.
1392
constructLineInfo(LineSym, DL->getFile(), DL.getLine(), DL.getCol());
1393
1394
LineInfoGenerated = true;
1395
PrevInstLoc = DL;
1396
}
1397
1398
void BTFDebug::processGlobals(bool ProcessingMapDef) {
1399
// Collect all types referenced by globals.
1400
const Module *M = MMI->getModule();
1401
for (const GlobalVariable &Global : M->globals()) {
1402
// Decide the section name.
1403
StringRef SecName;
1404
std::optional<SectionKind> GVKind;
1405
1406
if (!Global.isDeclarationForLinker())
1407
GVKind = TargetLoweringObjectFile::getKindForGlobal(&Global, Asm->TM);
1408
1409
if (Global.isDeclarationForLinker())
1410
SecName = Global.hasSection() ? Global.getSection() : "";
1411
else if (GVKind->isCommon())
1412
SecName = ".bss";
1413
else {
1414
TargetLoweringObjectFile *TLOF = Asm->TM.getObjFileLowering();
1415
MCSection *Sec = TLOF->SectionForGlobal(&Global, Asm->TM);
1416
SecName = Sec->getName();
1417
}
1418
1419
if (ProcessingMapDef != SecName.starts_with(".maps"))
1420
continue;
1421
1422
// Create a .rodata datasec if the global variable is an initialized
1423
// constant with private linkage and if it won't be in .rodata.str<#>
1424
// and .rodata.cst<#> sections.
1425
if (SecName == ".rodata" && Global.hasPrivateLinkage() &&
1426
DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
1427
// skip .rodata.str<#> and .rodata.cst<#> sections
1428
if (!GVKind->isMergeableCString() && !GVKind->isMergeableConst()) {
1429
DataSecEntries[std::string(SecName)] =
1430
std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
1431
}
1432
}
1433
1434
SmallVector<DIGlobalVariableExpression *, 1> GVs;
1435
Global.getDebugInfo(GVs);
1436
1437
// No type information, mostly internal, skip it.
1438
if (GVs.size() == 0)
1439
continue;
1440
1441
uint32_t GVTypeId = 0;
1442
DIGlobalVariable *DIGlobal = nullptr;
1443
for (auto *GVE : GVs) {
1444
DIGlobal = GVE->getVariable();
1445
if (SecName.starts_with(".maps"))
1446
visitMapDefType(DIGlobal->getType(), GVTypeId);
1447
else
1448
visitTypeEntry(DIGlobal->getType(), GVTypeId, false, false);
1449
break;
1450
}
1451
1452
// Only support the following globals:
1453
// . static variables
1454
// . non-static weak or non-weak global variables
1455
// . weak or non-weak extern global variables
1456
// Whether DataSec is readonly or not can be found from corresponding ELF
1457
// section flags. Whether a BTF_KIND_VAR is a weak symbol or not
1458
// can be found from the corresponding ELF symbol table.
1459
auto Linkage = Global.getLinkage();
1460
if (Linkage != GlobalValue::InternalLinkage &&
1461
Linkage != GlobalValue::ExternalLinkage &&
1462
Linkage != GlobalValue::WeakAnyLinkage &&
1463
Linkage != GlobalValue::WeakODRLinkage &&
1464
Linkage != GlobalValue::ExternalWeakLinkage)
1465
continue;
1466
1467
uint32_t GVarInfo;
1468
if (Linkage == GlobalValue::InternalLinkage) {
1469
GVarInfo = BTF::VAR_STATIC;
1470
} else if (Global.hasInitializer()) {
1471
GVarInfo = BTF::VAR_GLOBAL_ALLOCATED;
1472
} else {
1473
GVarInfo = BTF::VAR_GLOBAL_EXTERNAL;
1474
}
1475
1476
auto VarEntry =
1477
std::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo);
1478
uint32_t VarId = addType(std::move(VarEntry));
1479
1480
processDeclAnnotations(DIGlobal->getAnnotations(), VarId, -1);
1481
1482
// An empty SecName means an extern variable without section attribute.
1483
if (SecName.empty())
1484
continue;
1485
1486
// Find or create a DataSec
1487
if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
1488
DataSecEntries[std::string(SecName)] =
1489
std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
1490
}
1491
1492
// Calculate symbol size
1493
const DataLayout &DL = Global.getDataLayout();
1494
uint32_t Size = DL.getTypeAllocSize(Global.getValueType());
1495
1496
DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId,
1497
Asm->getSymbol(&Global), Size);
1498
1499
if (Global.hasInitializer())
1500
processGlobalInitializer(Global.getInitializer());
1501
}
1502
}
1503
1504
/// Process global variable initializer in pursuit for function
1505
/// pointers. Add discovered (extern) functions to BTF. Some (extern)
1506
/// functions might have been missed otherwise. Every symbol needs BTF
1507
/// info when linking with bpftool. Primary use case: "static"
1508
/// initialization of BPF maps.
1509
///
1510
/// struct {
1511
/// __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
1512
/// ...
1513
/// } prog_map SEC(".maps") = { .values = { extern_func } };
1514
///
1515
void BTFDebug::processGlobalInitializer(const Constant *C) {
1516
if (auto *Fn = dyn_cast<Function>(C))
1517
processFuncPrototypes(Fn);
1518
if (auto *CA = dyn_cast<ConstantAggregate>(C)) {
1519
for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I)
1520
processGlobalInitializer(CA->getOperand(I));
1521
}
1522
}
1523
1524
/// Emit proper patchable instructions.
1525
bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
1526
if (MI->getOpcode() == BPF::LD_imm64) {
1527
const MachineOperand &MO = MI->getOperand(1);
1528
if (MO.isGlobal()) {
1529
const GlobalValue *GVal = MO.getGlobal();
1530
auto *GVar = dyn_cast<GlobalVariable>(GVal);
1531
if (GVar) {
1532
// Emit "mov ri, <imm>"
1533
int64_t Imm;
1534
uint32_t Reloc;
1535
if (GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr) ||
1536
GVar->hasAttribute(BPFCoreSharedInfo::TypeIdAttr)) {
1537
Imm = PatchImms[GVar].first;
1538
Reloc = PatchImms[GVar].second;
1539
} else {
1540
return false;
1541
}
1542
1543
if (Reloc == BTF::ENUM_VALUE_EXISTENCE || Reloc == BTF::ENUM_VALUE ||
1544
Reloc == BTF::BTF_TYPE_ID_LOCAL || Reloc == BTF::BTF_TYPE_ID_REMOTE)
1545
OutMI.setOpcode(BPF::LD_imm64);
1546
else
1547
OutMI.setOpcode(BPF::MOV_ri);
1548
OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1549
OutMI.addOperand(MCOperand::createImm(Imm));
1550
return true;
1551
}
1552
}
1553
} else if (MI->getOpcode() == BPF::CORE_LD64 ||
1554
MI->getOpcode() == BPF::CORE_LD32 ||
1555
MI->getOpcode() == BPF::CORE_ST ||
1556
MI->getOpcode() == BPF::CORE_SHIFT) {
1557
const MachineOperand &MO = MI->getOperand(3);
1558
if (MO.isGlobal()) {
1559
const GlobalValue *GVal = MO.getGlobal();
1560
auto *GVar = dyn_cast<GlobalVariable>(GVal);
1561
if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) {
1562
uint32_t Imm = PatchImms[GVar].first;
1563
OutMI.setOpcode(MI->getOperand(1).getImm());
1564
if (MI->getOperand(0).isImm())
1565
OutMI.addOperand(MCOperand::createImm(MI->getOperand(0).getImm()));
1566
else
1567
OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1568
OutMI.addOperand(MCOperand::createReg(MI->getOperand(2).getReg()));
1569
OutMI.addOperand(MCOperand::createImm(Imm));
1570
return true;
1571
}
1572
}
1573
}
1574
return false;
1575
}
1576
1577
void BTFDebug::processFuncPrototypes(const Function *F) {
1578
if (!F)
1579
return;
1580
1581
const DISubprogram *SP = F->getSubprogram();
1582
if (!SP || SP->isDefinition())
1583
return;
1584
1585
// Do not emit again if already emitted.
1586
if (!ProtoFunctions.insert(F).second)
1587
return;
1588
1589
uint32_t ProtoTypeId;
1590
const std::unordered_map<uint32_t, StringRef> FuncArgNames;
1591
visitSubroutineType(SP->getType(), false, FuncArgNames, ProtoTypeId);
1592
uint32_t FuncId = processDISubprogram(SP, ProtoTypeId, BTF::FUNC_EXTERN);
1593
1594
if (F->hasSection()) {
1595
StringRef SecName = F->getSection();
1596
1597
if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
1598
DataSecEntries[std::string(SecName)] =
1599
std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
1600
}
1601
1602
// We really don't know func size, set it to 0.
1603
DataSecEntries[std::string(SecName)]->addDataSecEntry(FuncId,
1604
Asm->getSymbol(F), 0);
1605
}
1606
}
1607
1608
void BTFDebug::endModule() {
1609
// Collect MapDef globals if not collected yet.
1610
if (MapDefNotCollected) {
1611
processGlobals(true);
1612
MapDefNotCollected = false;
1613
}
1614
1615
// Collect global types/variables except MapDef globals.
1616
processGlobals(false);
1617
1618
for (auto &DataSec : DataSecEntries)
1619
addType(std::move(DataSec.second));
1620
1621
// Fixups
1622
for (auto &Fixup : FixupDerivedTypes) {
1623
const DICompositeType *CTy = Fixup.first;
1624
StringRef TypeName = CTy->getName();
1625
bool IsUnion = CTy->getTag() == dwarf::DW_TAG_union_type;
1626
1627
// Search through struct types
1628
uint32_t StructTypeId = 0;
1629
for (const auto &StructType : StructTypes) {
1630
if (StructType->getName() == TypeName) {
1631
StructTypeId = StructType->getId();
1632
break;
1633
}
1634
}
1635
1636
if (StructTypeId == 0) {
1637
auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion);
1638
StructTypeId = addType(std::move(FwdTypeEntry));
1639
}
1640
1641
for (auto &TypeInfo : Fixup.second) {
1642
const DIDerivedType *DTy = TypeInfo.first;
1643
BTFTypeDerived *BDType = TypeInfo.second;
1644
1645
int TmpTypeId = genBTFTypeTags(DTy, StructTypeId);
1646
if (TmpTypeId >= 0)
1647
BDType->setPointeeType(TmpTypeId);
1648
else
1649
BDType->setPointeeType(StructTypeId);
1650
}
1651
}
1652
1653
// Complete BTF type cross refereences.
1654
for (const auto &TypeEntry : TypeEntries)
1655
TypeEntry->completeType(*this);
1656
1657
// Emit BTF sections.
1658
emitBTFSection();
1659
emitBTFExtSection();
1660
}
1661
1662