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