Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/BPF/BTFDebug.cpp
Line
Count
Source (jump to first uncovered line)
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/MC/MCContext.h"
21
#include "llvm/MC/MCObjectFileInfo.h"
22
#include "llvm/MC/MCSectionELF.h"
23
#include "llvm/MC/MCStreamer.h"
24
#include "llvm/Support/LineIterator.h"
25
26
using namespace llvm;
27
28
static const char *BTFKindStr[] = {
29
#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
30
#include "BTF.def"
31
};
32
33
/// Emit a BTF common type.
34
592
void BTFTypeBase::emitType(MCStreamer &OS) {
35
592
  OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) +
36
592
                ")");
37
592
  OS.EmitIntValue(BTFType.NameOff, 4);
38
592
  OS.AddComment("0x" + Twine::utohexstr(BTFType.Info));
39
592
  OS.EmitIntValue(BTFType.Info, 4);
40
592
  OS.EmitIntValue(BTFType.Size, 4);
41
592
}
42
43
BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag,
44
                               bool NeedsFixup)
45
128
    : DTy(DTy), NeedsFixup(NeedsFixup) {
46
128
  switch (Tag) {
47
128
  case dwarf::DW_TAG_pointer_type:
48
51
    Kind = BTF::BTF_KIND_PTR;
49
51
    break;
50
128
  case dwarf::DW_TAG_const_type:
51
19
    Kind = BTF::BTF_KIND_CONST;
52
19
    break;
53
128
  case dwarf::DW_TAG_volatile_type:
54
38
    Kind = BTF::BTF_KIND_VOLATILE;
55
38
    break;
56
128
  case dwarf::DW_TAG_typedef:
57
18
    Kind = BTF::BTF_KIND_TYPEDEF;
58
18
    break;
59
128
  case dwarf::DW_TAG_restrict_type:
60
2
    Kind = BTF::BTF_KIND_RESTRICT;
61
2
    break;
62
128
  default:
63
0
    llvm_unreachable("Unknown DIDerivedType Tag");
64
128
  }
65
128
  BTFType.Info = Kind << 24;
66
128
}
67
68
168
void BTFTypeDerived::completeType(BTFDebug &BDebug) {
69
168
  if (IsCompleted)
70
40
    return;
71
128
  IsCompleted = true;
72
128
73
128
  BTFType.NameOff = BDebug.addString(DTy->getName());
74
128
75
128
  if (NeedsFixup)
76
4
    return;
77
124
78
124
  // The base type for PTR/CONST/VOLATILE could be void.
79
124
  const DIType *ResolvedType = DTy->getBaseType();
80
124
  if (!ResolvedType) {
81
10
    assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||
82
10
            Kind == BTF::BTF_KIND_VOLATILE) &&
83
10
           "Invalid null basetype");
84
10
    BTFType.Type = 0;
85
114
  } else {
86
114
    BTFType.Type = BDebug.getTypeId(ResolvedType);
87
114
  }
88
124
}
89
90
128
void BTFTypeDerived::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
91
92
4
void BTFTypeDerived::setPointeeType(uint32_t PointeeType) {
93
4
  BTFType.Type = PointeeType;
94
4
}
95
96
/// Represent a struct/union forward declaration.
97
6
BTFTypeFwd::BTFTypeFwd(StringRef Name, bool IsUnion) : Name(Name) {
98
6
  Kind = BTF::BTF_KIND_FWD;
99
6
  BTFType.Info = IsUnion << 31 | Kind << 24;
100
6
  BTFType.Type = 0;
101
6
}
102
103
10
void BTFTypeFwd::completeType(BTFDebug &BDebug) {
104
10
  if (IsCompleted)
105
4
    return;
106
6
  IsCompleted = true;
107
6
108
6
  BTFType.NameOff = BDebug.addString(Name);
109
6
}
110
111
6
void BTFTypeFwd::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
112
113
BTFTypeInt::BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits,
114
                       uint32_t OffsetInBits, StringRef TypeName)
115
163
    : Name(TypeName) {
116
163
  // Translate IR int encoding to BTF int encoding.
117
163
  uint8_t BTFEncoding;
118
163
  switch (Encoding) {
119
163
  case dwarf::DW_ATE_boolean:
120
0
    BTFEncoding = BTF::INT_BOOL;
121
0
    break;
122
163
  case dwarf::DW_ATE_signed:
123
132
  case dwarf::DW_ATE_signed_char:
124
132
    BTFEncoding = BTF::INT_SIGNED;
125
132
    break;
126
132
  case dwarf::DW_ATE_unsigned:
127
31
  case dwarf::DW_ATE_unsigned_char:
128
31
    BTFEncoding = 0;
129
31
    break;
130
31
  default:
131
0
    llvm_unreachable("Unknown BTFTypeInt Encoding");
132
163
  }
133
163
134
163
  Kind = BTF::BTF_KIND_INT;
135
163
  BTFType.Info = Kind << 24;
136
163
  BTFType.Size = roundupToBytes(SizeInBits);
137
163
  IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
138
163
}
139
140
244
void BTFTypeInt::completeType(BTFDebug &BDebug) {
141
244
  if (IsCompleted)
142
81
    return;
143
163
  IsCompleted = true;
144
163
145
163
  BTFType.NameOff = BDebug.addString(Name);
146
163
}
147
148
163
void BTFTypeInt::emitType(MCStreamer &OS) {
149
163
  BTFTypeBase::emitType(OS);
150
163
  OS.AddComment("0x" + Twine::utohexstr(IntVal));
151
163
  OS.EmitIntValue(IntVal, 4);
152
163
}
153
154
4
BTFTypeEnum::BTFTypeEnum(const DICompositeType *ETy, uint32_t VLen) : ETy(ETy) {
155
4
  Kind = BTF::BTF_KIND_ENUM;
156
4
  BTFType.Info = Kind << 24 | VLen;
157
4
  BTFType.Size = roundupToBytes(ETy->getSizeInBits());
158
4
}
159
160
4
void BTFTypeEnum::completeType(BTFDebug &BDebug) {
161
4
  if (IsCompleted)
162
0
    return;
163
4
  IsCompleted = true;
164
4
165
4
  BTFType.NameOff = BDebug.addString(ETy->getName());
166
4
167
4
  DINodeArray Elements = ETy->getElements();
168
8
  for (const auto Element : Elements) {
169
8
    const auto *Enum = cast<DIEnumerator>(Element);
170
8
171
8
    struct BTF::BTFEnum BTFEnum;
172
8
    BTFEnum.NameOff = BDebug.addString(Enum->getName());
173
8
    // BTF enum value is 32bit, enforce it.
174
8
    BTFEnum.Val = static_cast<uint32_t>(Enum->getValue());
175
8
    EnumValues.push_back(BTFEnum);
176
8
  }
177
4
}
178
179
4
void BTFTypeEnum::emitType(MCStreamer &OS) {
180
4
  BTFTypeBase::emitType(OS);
181
8
  for (const auto &Enum : EnumValues) {
182
8
    OS.EmitIntValue(Enum.NameOff, 4);
183
8
    OS.EmitIntValue(Enum.Val, 4);
184
8
  }
185
4
}
186
187
BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t ElemSize,
188
                           uint32_t NumElems)
189
20
    : ElemSize(ElemSize) {
190
20
  Kind = BTF::BTF_KIND_ARRAY;
191
20
  BTFType.NameOff = 0;
192
20
  BTFType.Info = Kind << 24;
193
20
  BTFType.Size = 0;
194
20
195
20
  ArrayInfo.ElemType = ElemTypeId;
196
20
  ArrayInfo.Nelems = NumElems;
197
20
}
198
199
/// Represent a BTF array.
200
28
void BTFTypeArray::completeType(BTFDebug &BDebug) {
201
28
  if (IsCompleted)
202
8
    return;
203
20
  IsCompleted = true;
204
20
205
20
  // The IR does not really have a type for the index.
206
20
  // A special type for array index should have been
207
20
  // created during initial type traversal. Just
208
20
  // retrieve that type id.
209
20
  ArrayInfo.IndexType = BDebug.getArrayIndexTypeId();
210
20
}
211
212
20
void BTFTypeArray::emitType(MCStreamer &OS) {
213
20
  BTFTypeBase::emitType(OS);
214
20
  OS.EmitIntValue(ArrayInfo.ElemType, 4);
215
20
  OS.EmitIntValue(ArrayInfo.IndexType, 4);
216
20
  OS.EmitIntValue(ArrayInfo.Nelems, 4);
217
20
}
218
219
void BTFTypeArray::getLocInfo(uint32_t Loc, uint32_t &LocOffset,
220
4
                              uint32_t &ElementTypeId) {
221
4
  ElementTypeId = ArrayInfo.ElemType;
222
4
  LocOffset = Loc * ElemSize;
223
4
}
224
225
/// Represent either a struct or a union.
226
BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct,
227
                             bool HasBitField, uint32_t Vlen)
228
51
    : STy(STy), HasBitField(HasBitField) {
229
51
  Kind = IsStruct ? 
BTF::BTF_KIND_STRUCT44
:
BTF::BTF_KIND_UNION7
;
230
51
  BTFType.Size = roundupToBytes(STy->getSizeInBits());
231
51
  BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;
232
51
}
233
234
97
void BTFTypeStruct::completeType(BTFDebug &BDebug) {
235
97
  if (IsCompleted)
236
46
    return;
237
51
  IsCompleted = true;
238
51
239
51
  BTFType.NameOff = BDebug.addString(STy->getName());
240
51
241
51
  // Add struct/union members.
242
51
  const DINodeArray Elements = STy->getElements();
243
90
  for (const auto *Element : Elements) {
244
90
    struct BTF::BTFMember BTFMember;
245
90
    const auto *DDTy = cast<DIDerivedType>(Element);
246
90
247
90
    BTFMember.NameOff = BDebug.addString(DDTy->getName());
248
90
    if (HasBitField) {
249
10
      uint8_t BitFieldSize = DDTy->isBitField() ? 
DDTy->getSizeInBits()6
:
04
;
250
10
      BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
251
80
    } else {
252
80
      BTFMember.Offset = DDTy->getOffsetInBits();
253
80
    }
254
90
    BTFMember.Type = BDebug.getTypeId(DDTy->getBaseType());
255
90
    Members.push_back(BTFMember);
256
90
  }
257
51
}
258
259
51
void BTFTypeStruct::emitType(MCStreamer &OS) {
260
51
  BTFTypeBase::emitType(OS);
261
90
  for (const auto &Member : Members) {
262
90
    OS.EmitIntValue(Member.NameOff, 4);
263
90
    OS.EmitIntValue(Member.Type, 4);
264
90
    OS.AddComment("0x" + Twine::utohexstr(Member.Offset));
265
90
    OS.EmitIntValue(Member.Offset, 4);
266
90
  }
267
51
}
268
269
4
std::string BTFTypeStruct::getName() { return STy->getName(); }
270
271
void BTFTypeStruct::getMemberInfo(uint32_t Loc, uint32_t &MemberOffset,
272
23
                                  uint32_t &MemberType) {
273
23
  MemberType = Members[Loc].Type;
274
23
  MemberOffset =
275
23
      HasBitField ? 
Members[Loc].Offset & 0xffffff0
: Members[Loc].Offset;
276
23
}
277
278
13
uint32_t BTFTypeStruct::getStructSize() { return STy->getSizeInBits() >> 3; }
279
280
/// The Func kind represents both subprogram and pointee of function
281
/// pointers. If the FuncName is empty, it represents a pointee of function
282
/// pointer. Otherwise, it represents a subprogram. The func arg names
283
/// are empty for pointee of function pointer case, and are valid names
284
/// for subprogram.
285
BTFTypeFuncProto::BTFTypeFuncProto(
286
    const DISubroutineType *STy, uint32_t VLen,
287
    const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
288
72
    : STy(STy), FuncArgNames(FuncArgNames) {
289
72
  Kind = BTF::BTF_KIND_FUNC_PROTO;
290
72
  BTFType.Info = (Kind << 24) | VLen;
291
72
}
292
293
151
void BTFTypeFuncProto::completeType(BTFDebug &BDebug) {
294
151
  if (IsCompleted)
295
79
    return;
296
72
  IsCompleted = true;
297
72
298
72
  DITypeRefArray Elements = STy->getTypeArray();
299
72
  auto RetType = Elements[0];
300
72
  BTFType.Type = RetType ? 
BDebug.getTypeId(RetType)60
:
012
;
301
72
  BTFType.NameOff = 0;
302
72
303
72
  // For null parameter which is typically the last one
304
72
  // to represent the vararg, encode the NameOff/Type to be 0.
305
117
  for (unsigned I = 1, N = Elements.size(); I < N; 
++I45
) {
306
45
    struct BTF::BTFParam Param;
307
45
    auto Element = Elements[I];
308
45
    if (Element) {
309
45
      Param.NameOff = BDebug.addString(FuncArgNames[I]);
310
45
      Param.Type = BDebug.getTypeId(Element);
311
45
    } else {
312
0
      Param.NameOff = 0;
313
0
      Param.Type = 0;
314
0
    }
315
45
    Parameters.push_back(Param);
316
45
  }
317
72
}
318
319
72
void BTFTypeFuncProto::emitType(MCStreamer &OS) {
320
72
  BTFTypeBase::emitType(OS);
321
72
  for (const auto &Param : Parameters) {
322
45
    OS.EmitIntValue(Param.NameOff, 4);
323
45
    OS.EmitIntValue(Param.Type, 4);
324
45
  }
325
72
}
326
327
BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId)
328
64
    : Name(FuncName) {
329
64
  Kind = BTF::BTF_KIND_FUNC;
330
64
  BTFType.Info = Kind << 24;
331
64
  BTFType.Type = ProtoTypeId;
332
64
}
333
334
143
void BTFTypeFunc::completeType(BTFDebug &BDebug) {
335
143
  if (IsCompleted)
336
79
    return;
337
64
  IsCompleted = true;
338
64
339
64
  BTFType.NameOff = BDebug.addString(Name);
340
64
}
341
342
64
void BTFTypeFunc::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
343
344
BTFKindVar::BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
345
52
    : Name(VarName) {
346
52
  Kind = BTF::BTF_KIND_VAR;
347
52
  BTFType.Info = Kind << 24;
348
52
  BTFType.Type = TypeId;
349
52
  Info = VarInfo;
350
52
}
351
352
52
void BTFKindVar::completeType(BTFDebug &BDebug) {
353
52
  BTFType.NameOff = BDebug.addString(Name);
354
52
}
355
356
52
void BTFKindVar::emitType(MCStreamer &OS) {
357
52
  BTFTypeBase::emitType(OS);
358
52
  OS.EmitIntValue(Info, 4);
359
52
}
360
361
BTFKindDataSec::BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
362
32
    : Asm(AsmPrt), Name(SecName) {
363
32
  Kind = BTF::BTF_KIND_DATASEC;
364
32
  BTFType.Info = Kind << 24;
365
32
  BTFType.Size = 0;
366
32
}
367
368
32
void BTFKindDataSec::completeType(BTFDebug &BDebug) {
369
32
  BTFType.NameOff = BDebug.addString(Name);
370
32
  BTFType.Info |= Vars.size();
371
32
}
372
373
32
void BTFKindDataSec::emitType(MCStreamer &OS) {
374
32
  BTFTypeBase::emitType(OS);
375
32
376
52
  for (const auto &V : Vars) {
377
52
    OS.EmitIntValue(std::get<0>(V), 4);
378
52
    Asm->EmitLabelReference(std::get<1>(V), 4);
379
52
    OS.EmitIntValue(std::get<2>(V), 4);
380
52
  }
381
32
}
382
383
1.07k
uint32_t BTFStringTable::addString(StringRef S) {
384
1.07k
  // Check whether the string already exists.
385
3.86k
  for (auto &OffsetM : OffsetToIdMap) {
386
3.86k
    if (Table[OffsetM.second] == S)
387
288
      return OffsetM.first;
388
3.86k
  }
389
1.07k
  // Not find, add to the string table.
390
1.07k
  uint32_t Offset = Size;
391
787
  OffsetToIdMap[Offset] = Table.size();
392
787
  Table.push_back(S);
393
787
  Size += S.size() + 1;
394
787
  return Offset;
395
1.07k
}
396
397
BTFDebug::BTFDebug(AsmPrinter *AP)
398
    : DebugHandlerBase(AP), OS(*Asm->OutStreamer), SkipInstruction(false),
399
      LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0),
400
136
      MapDefNotCollected(true) {
401
136
  addString("\0");
402
136
}
403
404
uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
405
358
                           const DIType *Ty) {
406
358
  TypeEntry->setId(TypeEntries.size() + 1);
407
358
  uint32_t Id = TypeEntry->getId();
408
358
  DIToIdMap[Ty] = Id;
409
358
  TypeEntries.push_back(std::move(TypeEntry));
410
358
  return Id;
411
358
}
412
413
234
uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
414
234
  TypeEntry->setId(TypeEntries.size() + 1);
415
234
  uint32_t Id = TypeEntry->getId();
416
234
  TypeEntries.push_back(std::move(TypeEntry));
417
234
  return Id;
418
234
}
419
420
145
void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
421
145
  // Only int types are supported in BTF.
422
145
  uint32_t Encoding = BTy->getEncoding();
423
145
  if (Encoding != dwarf::DW_ATE_boolean && Encoding != dwarf::DW_ATE_signed &&
424
145
      
Encoding != dwarf::DW_ATE_signed_char41
&&
425
145
      
Encoding != dwarf::DW_ATE_unsigned13
&&
426
145
      
Encoding != dwarf::DW_ATE_unsigned_char2
)
427
0
    return;
428
145
429
145
  // Create a BTF type instance for this DIBasicType and put it into
430
145
  // DIToIdMap for cross-type reference check.
431
145
  auto TypeEntry = llvm::make_unique<BTFTypeInt>(
432
145
      Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
433
145
  TypeId = addType(std::move(TypeEntry), BTy);
434
145
}
435
436
/// Handle subprogram or subroutine types.
437
void BTFDebug::visitSubroutineType(
438
    const DISubroutineType *STy, bool ForSubprog,
439
    const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
440
72
    uint32_t &TypeId) {
441
72
  DITypeRefArray Elements = STy->getTypeArray();
442
72
  uint32_t VLen = Elements.size() - 1;
443
72
  if (VLen > BTF::MAX_VLEN)
444
0
    return;
445
72
446
72
  // Subprogram has a valid non-zero-length name, and the pointee of
447
72
  // a function pointer has an empty name. The subprogram type will
448
72
  // not be added to DIToIdMap as it should not be referenced by
449
72
  // any other types.
450
72
  auto TypeEntry = llvm::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames);
451
72
  if (ForSubprog)
452
64
    TypeId = addType(std::move(TypeEntry)); // For subprogram
453
8
  else
454
8
    TypeId = addType(std::move(TypeEntry), STy); // For func ptr
455
72
456
72
  // Visit return type and func arg types.
457
117
  for (const auto Element : Elements) {
458
117
    visitTypeEntry(Element);
459
117
  }
460
72
}
461
462
/// Handle structure/union types.
463
void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
464
49
                               uint32_t &TypeId) {
465
49
  const DINodeArray Elements = CTy->getElements();
466
49
  uint32_t VLen = Elements.size();
467
49
  if (VLen > BTF::MAX_VLEN)
468
0
    return;
469
49
470
49
  // Check whether we have any bitfield members or not
471
49
  bool HasBitField = false;
472
80
  for (const auto *Element : Elements) {
473
80
    auto E = cast<DIDerivedType>(Element);
474
80
    if (E->isBitField()) {
475
4
      HasBitField = true;
476
4
      break;
477
4
    }
478
80
  }
479
49
480
49
  auto TypeEntry =
481
49
      llvm::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
482
49
  StructTypes.push_back(TypeEntry.get());
483
49
  TypeId = addType(std::move(TypeEntry), CTy);
484
49
485
49
  // Visit all struct members.
486
49
  for (const auto *Element : Elements)
487
86
    visitTypeEntry(cast<DIDerivedType>(Element));
488
49
}
489
490
18
void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
491
18
  // Visit array element type.
492
18
  uint32_t ElemTypeId, ElemSize;
493
18
  const DIType *ElemType = CTy->getBaseType();
494
18
  visitTypeEntry(ElemType, ElemTypeId, false, false);
495
18
  ElemSize = ElemType->getSizeInBits() >> 3;
496
18
497
18
  if (!CTy->getSizeInBits()) {
498
4
    auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemTypeId, 0, 0);
499
4
    ArrayTypes.push_back(TypeEntry.get());
500
4
    ElemTypeId = addType(std::move(TypeEntry), CTy);
501
14
  } else {
502
14
    // Visit array dimensions.
503
14
    DINodeArray Elements = CTy->getElements();
504
30
    for (int I = Elements.size() - 1; I >= 0; 
--I16
) {
505
16
      if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
506
16
        if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
507
16
          const DISubrange *SR = cast<DISubrange>(Element);
508
16
          auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
509
16
          int64_t Count = CI->getSExtValue();
510
16
511
16
          auto TypeEntry =
512
16
              llvm::make_unique<BTFTypeArray>(ElemTypeId, ElemSize, Count);
513
16
          ArrayTypes.push_back(TypeEntry.get());
514
16
          if (I == 0)
515
14
            ElemTypeId = addType(std::move(TypeEntry), CTy);
516
2
          else
517
2
            ElemTypeId = addType(std::move(TypeEntry));
518
16
          ElemSize = ElemSize * Count;
519
16
        }
520
16
    }
521
14
  }
522
18
523
18
  // The array TypeId is the type id of the outermost dimension.
524
18
  TypeId = ElemTypeId;
525
18
526
18
  // The IR does not have a type for array index while BTF wants one.
527
18
  // So create an array index type if there is none.
528
18
  if (!ArrayIndexTypeId) {
529
18
    auto TypeEntry = llvm::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
530
18
                                                   0, "__ARRAY_SIZE_TYPE__");
531
18
    ArrayIndexTypeId = addType(std::move(TypeEntry));
532
18
  }
533
18
}
534
535
4
void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) {
536
4
  DINodeArray Elements = CTy->getElements();
537
4
  uint32_t VLen = Elements.size();
538
4
  if (VLen > BTF::MAX_VLEN)
539
0
    return;
540
4
541
4
  auto TypeEntry = llvm::make_unique<BTFTypeEnum>(CTy, VLen);
542
4
  TypeId = addType(std::move(TypeEntry), CTy);
543
4
  // No need to visit base type as BTF does not encode it.
544
4
}
545
546
/// Handle structure/union forward declarations.
547
void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
548
4
                                uint32_t &TypeId) {
549
4
  auto TypeEntry = llvm::make_unique<BTFTypeFwd>(CTy->getName(), IsUnion);
550
4
  TypeId = addType(std::move(TypeEntry), CTy);
551
4
}
552
553
/// Handle structure, union, array and enumeration types.
554
void BTFDebug::visitCompositeType(const DICompositeType *CTy,
555
75
                                  uint32_t &TypeId) {
556
75
  auto Tag = CTy->getTag();
557
75
  if (Tag == dwarf::DW_TAG_structure_type || 
Tag == dwarf::DW_TAG_union_type29
) {
558
53
    // Handle forward declaration differently as it does not have members.
559
53
    if (CTy->isForwardDecl())
560
4
      visitFwdDeclType(CTy, Tag == dwarf::DW_TAG_union_type, TypeId);
561
49
    else
562
49
      visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId);
563
53
  } else 
if (22
Tag == dwarf::DW_TAG_array_type22
)
564
18
    visitArrayType(CTy, TypeId);
565
4
  else if (Tag == dwarf::DW_TAG_enumeration_type)
566
4
    visitEnumType(CTy, TypeId);
567
75
}
568
569
/// Handle pointer, typedef, const, volatile, restrict and member types.
570
void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
571
214
                                bool CheckPointer, bool SeenPointer) {
572
214
  unsigned Tag = DTy->getTag();
573
214
574
214
  /// Try to avoid chasing pointees, esp. structure pointees which may
575
214
  /// unnecessary bring in a lot of types.
576
214
  if (CheckPointer && 
!SeenPointer14
) {
577
14
    SeenPointer = Tag == dwarf::DW_TAG_pointer_type;
578
14
  }
579
214
580
214
  if (CheckPointer && 
SeenPointer14
) {
581
8
    const DIType *Base = DTy->getBaseType();
582
8
    if (Base) {
583
8
      if (const auto *CTy = dyn_cast<DICompositeType>(Base)) {
584
8
        auto CTag = CTy->getTag();
585
8
        if ((CTag == dwarf::DW_TAG_structure_type ||
586
8
             
CTag == dwarf::DW_TAG_union_type0
) &&
587
8
            !CTy->isForwardDecl()) {
588
4
          /// Find a candidate, generate a fixup. Later on the struct/union
589
4
          /// pointee type will be replaced with either a real type or
590
4
          /// a forward declaration.
591
4
          auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy, Tag, true);
592
4
          auto &Fixup = FixupDerivedTypes[CTy->getName()];
593
4
          Fixup.first = CTag == dwarf::DW_TAG_union_type;
594
4
          Fixup.second.push_back(TypeEntry.get());
595
4
          TypeId = addType(std::move(TypeEntry), DTy);
596
4
          return;
597
4
        }
598
210
      }
599
8
    }
600
8
  }
601
210
602
210
  if (Tag == dwarf::DW_TAG_pointer_type || 
Tag == dwarf::DW_TAG_typedef163
||
603
210
      
Tag == dwarf::DW_TAG_const_type145
||
Tag == dwarf::DW_TAG_volatile_type126
||
604
210
      
Tag == dwarf::DW_TAG_restrict_type88
) {
605
124
    auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy, Tag, false);
606
124
    TypeId = addType(std::move(TypeEntry), DTy);
607
124
  } else 
if (86
Tag != dwarf::DW_TAG_member86
) {
608
0
    return;
609
0
  }
610
210
611
210
  // Visit base type of pointer, typedef, const, volatile, restrict or
612
210
  // struct/union member.
613
210
  uint32_t TempTypeId = 0;
614
210
  if (Tag == dwarf::DW_TAG_member)
615
86
    visitTypeEntry(DTy->getBaseType(), TempTypeId, true, false);
616
124
  else
617
124
    visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer);
618
210
}
619
620
void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId,
621
599
                              bool CheckPointer, bool SeenPointer) {
622
599
  if (!Ty || 
DIToIdMap.find(Ty) != DIToIdMap.end()577
) {
623
157
    TypeId = DIToIdMap[Ty];
624
157
    return;
625
157
  }
626
442
627
442
  if (const auto *BTy = dyn_cast<DIBasicType>(Ty))
628
145
    visitBasicType(BTy, TypeId);
629
297
  else if (const auto *STy = dyn_cast<DISubroutineType>(Ty))
630
8
    visitSubroutineType(STy, false, std::unordered_map<uint32_t, StringRef>(),
631
8
                        TypeId);
632
289
  else if (const auto *CTy = dyn_cast<DICompositeType>(Ty))
633
75
    visitCompositeType(CTy, TypeId);
634
214
  else if (const auto *DTy = dyn_cast<DIDerivedType>(Ty))
635
214
    visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer);
636
214
  else
637
214
    
llvm_unreachable0
("Unknown DIType");
638
442
}
639
640
242
void BTFDebug::visitTypeEntry(const DIType *Ty) {
641
242
  uint32_t TypeId;
642
242
  visitTypeEntry(Ty, TypeId, false, false);
643
242
}
644
645
2
void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) {
646
2
  if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
647
0
    TypeId = DIToIdMap[Ty];
648
0
    return;
649
0
  }
650
2
651
2
  // MapDef type is a struct type
652
2
  const auto *CTy = dyn_cast<DICompositeType>(Ty);
653
2
  if (!CTy)
654
0
    return;
655
2
656
2
  auto Tag = CTy->getTag();
657
2
  if (Tag != dwarf::DW_TAG_structure_type || CTy->isForwardDecl())
658
0
    return;
659
2
660
2
  // Record this type
661
2
  const DINodeArray Elements = CTy->getElements();
662
2
  bool HasBitField = false;
663
4
  for (const auto *Element : Elements) {
664
4
    auto E = cast<DIDerivedType>(Element);
665
4
    if (E->isBitField()) {
666
0
      HasBitField = true;
667
0
      break;
668
0
    }
669
4
  }
670
2
671
2
  auto TypeEntry =
672
2
      llvm::make_unique<BTFTypeStruct>(CTy, true, HasBitField, Elements.size());
673
2
  StructTypes.push_back(TypeEntry.get());
674
2
  TypeId = addType(std::move(TypeEntry), CTy);
675
2
676
2
  // Visit all struct members
677
4
  for (const auto *Element : Elements) {
678
4
    const auto *MemberType = cast<DIDerivedType>(Element);
679
4
    visitTypeEntry(MemberType->getBaseType());
680
4
  }
681
2
}
682
683
/// Read file contents from the actual file or from the source
684
197
std::string BTFDebug::populateFileContent(const DISubprogram *SP) {
685
197
  auto File = SP->getFile();
686
197
  std::string FileName;
687
197
688
197
  if (!File->getFilename().startswith("/") && 
File->getDirectory().size()195
)
689
195
    FileName = File->getDirectory().str() + "/" + File->getFilename().str();
690
2
  else
691
2
    FileName = File->getFilename();
692
197
693
197
  // No need to populate the contends if it has been populated!
694
197
  if (FileContent.find(FileName) != FileContent.end())
695
135
    return FileName;
696
62
697
62
  std::vector<std::string> Content;
698
62
  std::string Line;
699
62
  Content.push_back(Line); // Line 0 for empty string
700
62
701
62
  std::unique_ptr<MemoryBuffer> Buf;
702
62
  auto Source = File->getSource();
703
62
  if (Source)
704
4
    Buf = MemoryBuffer::getMemBufferCopy(*Source);
705
58
  else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
706
0
               MemoryBuffer::getFile(FileName))
707
0
    Buf = std::move(*BufOrErr);
708
62
  if (Buf)
709
8
    
for (line_iterator I(*Buf, false), E; 4
I != E;
++I4
)
710
4
      Content.push_back(*I);
711
62
712
62
  FileContent[FileName] = Content;
713
62
  return FileName;
714
62
}
715
716
void BTFDebug::constructLineInfo(const DISubprogram *SP, MCSymbol *Label,
717
197
                                 uint32_t Line, uint32_t Column) {
718
197
  std::string FileName = populateFileContent(SP);
719
197
  BTFLineInfo LineInfo;
720
197
721
197
  LineInfo.Label = Label;
722
197
  LineInfo.FileNameOff = addString(FileName);
723
197
  // If file content is not available, let LineOff = 0.
724
197
  if (Line < FileContent[FileName].size())
725
16
    LineInfo.LineOff = addString(FileContent[FileName][Line]);
726
181
  else
727
181
    LineInfo.LineOff = 0;
728
197
  LineInfo.LineNum = Line;
729
197
  LineInfo.ColumnNum = Column;
730
197
  LineInfoTable[SecNameOff].push_back(LineInfo);
731
197
}
732
733
194
void BTFDebug::emitCommonHeader() {
734
194
  OS.AddComment("0x" + Twine::utohexstr(BTF::MAGIC));
735
194
  OS.EmitIntValue(BTF::MAGIC, 2);
736
194
  OS.EmitIntValue(BTF::VERSION, 1);
737
194
  OS.EmitIntValue(0, 1);
738
194
}
739
740
132
void BTFDebug::emitBTFSection() {
741
132
  // Do not emit section if no types and only "" string.
742
132
  if (!TypeEntries.size() && 
StringTable.getSize() == 10
)
743
0
    return;
744
132
745
132
  MCContext &Ctx = OS.getContext();
746
132
  OS.SwitchSection(Ctx.getELFSection(".BTF", ELF::SHT_PROGBITS, 0));
747
132
748
132
  // Emit header.
749
132
  emitCommonHeader();
750
132
  OS.EmitIntValue(BTF::HeaderSize, 4);
751
132
752
132
  uint32_t TypeLen = 0, StrLen;
753
132
  for (const auto &TypeEntry : TypeEntries)
754
592
    TypeLen += TypeEntry->getSize();
755
132
  StrLen = StringTable.getSize();
756
132
757
132
  OS.EmitIntValue(0, 4);
758
132
  OS.EmitIntValue(TypeLen, 4);
759
132
  OS.EmitIntValue(TypeLen, 4);
760
132
  OS.EmitIntValue(StrLen, 4);
761
132
762
132
  // Emit type table.
763
132
  for (const auto &TypeEntry : TypeEntries)
764
592
    TypeEntry->emitType(OS);
765
132
766
132
  // Emit string table.
767
132
  uint32_t StringOffset = 0;
768
783
  for (const auto &S : StringTable.getTable()) {
769
783
    OS.AddComment("string offset=" + std::to_string(StringOffset));
770
783
    OS.EmitBytes(S);
771
783
    OS.EmitBytes(StringRef("\0", 1));
772
783
    StringOffset += S.size() + 1;
773
783
  }
774
132
}
775
776
132
void BTFDebug::emitBTFExtSection() {
777
132
  // Do not emit section if empty FuncInfoTable and LineInfoTable.
778
132
  if (!FuncInfoTable.size() && 
!LineInfoTable.size()70
&&
779
132
      
!OffsetRelocTable.size()70
&&
!ExternRelocTable.size()70
)
780
70
    return;
781
62
782
62
  MCContext &Ctx = OS.getContext();
783
62
  OS.SwitchSection(Ctx.getELFSection(".BTF.ext", ELF::SHT_PROGBITS, 0));
784
62
785
62
  // Emit header.
786
62
  emitCommonHeader();
787
62
  OS.EmitIntValue(BTF::ExtHeaderSize, 4);
788
62
789
62
  // Account for FuncInfo/LineInfo record size as well.
790
62
  uint32_t FuncLen = 4, LineLen = 4;
791
62
  // Do not account for optional OffsetReloc/ExternReloc.
792
62
  uint32_t OffsetRelocLen = 0, ExternRelocLen = 0;
793
62
  for (const auto &FuncSec : FuncInfoTable) {
794
62
    FuncLen += BTF::SecFuncInfoSize;
795
62
    FuncLen += FuncSec.second.size() * BTF::BPFFuncInfoSize;
796
62
  }
797
62
  for (const auto &LineSec : LineInfoTable) {
798
62
    LineLen += BTF::SecLineInfoSize;
799
62
    LineLen += LineSec.second.size() * BTF::BPFLineInfoSize;
800
62
  }
801
62
  for (const auto &OffsetRelocSec : OffsetRelocTable) {
802
13
    OffsetRelocLen += BTF::SecOffsetRelocSize;
803
13
    OffsetRelocLen += OffsetRelocSec.second.size() * BTF::BPFOffsetRelocSize;
804
13
  }
805
62
  for (const auto &ExternRelocSec : ExternRelocTable) {
806
6
    ExternRelocLen += BTF::SecExternRelocSize;
807
6
    ExternRelocLen += ExternRelocSec.second.size() * BTF::BPFExternRelocSize;
808
6
  }
809
62
810
62
  if (OffsetRelocLen)
811
13
    OffsetRelocLen += 4;
812
62
  if (ExternRelocLen)
813
6
    ExternRelocLen += 4;
814
62
815
62
  OS.EmitIntValue(0, 4);
816
62
  OS.EmitIntValue(FuncLen, 4);
817
62
  OS.EmitIntValue(FuncLen, 4);
818
62
  OS.EmitIntValue(LineLen, 4);
819
62
  OS.EmitIntValue(FuncLen + LineLen, 4);
820
62
  OS.EmitIntValue(OffsetRelocLen, 4);
821
62
  OS.EmitIntValue(FuncLen + LineLen + OffsetRelocLen, 4);
822
62
  OS.EmitIntValue(ExternRelocLen, 4);
823
62
824
62
  // Emit func_info table.
825
62
  OS.AddComment("FuncInfo");
826
62
  OS.EmitIntValue(BTF::BPFFuncInfoSize, 4);
827
62
  for (const auto &FuncSec : FuncInfoTable) {
828
62
    OS.AddComment("FuncInfo section string offset=" +
829
62
                  std::to_string(FuncSec.first));
830
62
    OS.EmitIntValue(FuncSec.first, 4);
831
62
    OS.EmitIntValue(FuncSec.second.size(), 4);
832
64
    for (const auto &FuncInfo : FuncSec.second) {
833
64
      Asm->EmitLabelReference(FuncInfo.Label, 4);
834
64
      OS.EmitIntValue(FuncInfo.TypeId, 4);
835
64
    }
836
62
  }
837
62
838
62
  // Emit line_info table.
839
62
  OS.AddComment("LineInfo");
840
62
  OS.EmitIntValue(BTF::BPFLineInfoSize, 4);
841
62
  for (const auto &LineSec : LineInfoTable) {
842
62
    OS.AddComment("LineInfo section string offset=" +
843
62
                  std::to_string(LineSec.first));
844
62
    OS.EmitIntValue(LineSec.first, 4);
845
62
    OS.EmitIntValue(LineSec.second.size(), 4);
846
197
    for (const auto &LineInfo : LineSec.second) {
847
197
      Asm->EmitLabelReference(LineInfo.Label, 4);
848
197
      OS.EmitIntValue(LineInfo.FileNameOff, 4);
849
197
      OS.EmitIntValue(LineInfo.LineOff, 4);
850
197
      OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " +
851
197
                    std::to_string(LineInfo.ColumnNum));
852
197
      OS.EmitIntValue(LineInfo.LineNum << 10 | LineInfo.ColumnNum, 4);
853
197
    }
854
62
  }
855
62
856
62
  // Emit offset reloc table.
857
62
  if (OffsetRelocLen) {
858
13
    OS.AddComment("OffsetReloc");
859
13
    OS.EmitIntValue(BTF::BPFOffsetRelocSize, 4);
860
13
    for (const auto &OffsetRelocSec : OffsetRelocTable) {
861
13
      OS.AddComment("Offset reloc section string offset=" +
862
13
                    std::to_string(OffsetRelocSec.first));
863
13
      OS.EmitIntValue(OffsetRelocSec.first, 4);
864
13
      OS.EmitIntValue(OffsetRelocSec.second.size(), 4);
865
13
      for (const auto &OffsetRelocInfo : OffsetRelocSec.second) {
866
13
        Asm->EmitLabelReference(OffsetRelocInfo.Label, 4);
867
13
        OS.EmitIntValue(OffsetRelocInfo.TypeID, 4);
868
13
        OS.EmitIntValue(OffsetRelocInfo.OffsetNameOff, 4);
869
13
      }
870
13
    }
871
13
  }
872
62
873
62
  // Emit extern reloc table.
874
62
  if (ExternRelocLen) {
875
6
    OS.AddComment("ExternReloc");
876
6
    OS.EmitIntValue(BTF::BPFExternRelocSize, 4);
877
6
    for (const auto &ExternRelocSec : ExternRelocTable) {
878
6
      OS.AddComment("Extern reloc section string offset=" +
879
6
                    std::to_string(ExternRelocSec.first));
880
6
      OS.EmitIntValue(ExternRelocSec.first, 4);
881
6
      OS.EmitIntValue(ExternRelocSec.second.size(), 4);
882
6
      for (const auto &ExternRelocInfo : ExternRelocSec.second) {
883
6
        Asm->EmitLabelReference(ExternRelocInfo.Label, 4);
884
6
        OS.EmitIntValue(ExternRelocInfo.ExternNameOff, 4);
885
6
      }
886
6
    }
887
6
  }
888
62
}
889
890
64
void BTFDebug::beginFunctionImpl(const MachineFunction *MF) {
891
64
  auto *SP = MF->getFunction().getSubprogram();
892
64
  auto *Unit = SP->getUnit();
893
64
894
64
  if (Unit->getEmissionKind() == DICompileUnit::NoDebug) {
895
0
    SkipInstruction = true;
896
0
    return;
897
0
  }
898
64
  SkipInstruction = false;
899
64
900
64
  // Collect MapDef types. Map definition needs to collect
901
64
  // pointee types. Do it first. Otherwise, for the following
902
64
  // case:
903
64
  //    struct m { ...};
904
64
  //    struct t {
905
64
  //      struct m *key;
906
64
  //    };
907
64
  //    foo(struct t *arg);
908
64
  //
909
64
  //    struct mapdef {
910
64
  //      ...
911
64
  //      struct m *key;
912
64
  //      ...
913
64
  //    } __attribute__((section(".maps"))) hash_map;
914
64
  //
915
64
  // If subroutine foo is traversed first, a type chain
916
64
  // "ptr->struct m(fwd)" will be created and later on
917
64
  // when traversing mapdef, since "ptr->struct m" exists,
918
64
  // the traversal of "struct m" will be omitted.
919
64
  if (MapDefNotCollected) {
920
62
    processGlobals(true);
921
62
    MapDefNotCollected = false;
922
62
  }
923
64
924
64
  // Collect all types locally referenced in this function.
925
64
  // Use RetainedNodes so we can collect all argument names
926
64
  // even if the argument is not used.
927
64
  std::unordered_map<uint32_t, StringRef> FuncArgNames;
928
64
  for (const DINode *DN : SP->getRetainedNodes()) {
929
49
    if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
930
49
      // Collect function arguments for subprogram func type.
931
49
      uint32_t Arg = DV->getArg();
932
49
      if (Arg) {
933
35
        visitTypeEntry(DV->getType());
934
35
        FuncArgNames[Arg] = DV->getName();
935
35
      }
936
49
    }
937
49
  }
938
64
939
64
  // Construct subprogram func proto type.
940
64
  uint32_t ProtoTypeId;
941
64
  visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId);
942
64
943
64
  // Construct subprogram func type
944
64
  auto FuncTypeEntry =
945
64
      llvm::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId);
946
64
  uint32_t FuncTypeId = addType(std::move(FuncTypeEntry));
947
64
948
64
  for (const auto &TypeEntry : TypeEntries)
949
250
    TypeEntry->completeType(*this);
950
64
951
64
  // Construct funcinfo and the first lineinfo for the function.
952
64
  MCSymbol *FuncLabel = Asm->getFunctionBegin();
953
64
  BTFFuncInfo FuncInfo;
954
64
  FuncInfo.Label = FuncLabel;
955
64
  FuncInfo.TypeId = FuncTypeId;
956
64
  if (FuncLabel->isInSection()) {
957
64
    MCSection &Section = FuncLabel->getSection();
958
64
    const MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(&Section);
959
64
    assert(SectionELF && "Null section for Function Label");
960
64
    SecNameOff = addString(SectionELF->getSectionName());
961
64
  } else {
962
0
    SecNameOff = addString(".text");
963
0
  }
964
64
  FuncInfoTable[SecNameOff].push_back(FuncInfo);
965
64
}
966
967
64
void BTFDebug::endFunctionImpl(const MachineFunction *MF) {
968
64
  SkipInstruction = false;
969
64
  LineInfoGenerated = false;
970
64
  SecNameOff = 0;
971
64
}
972
973
/// On-demand populate struct types as requested from abstract member
974
/// accessing.
975
13
unsigned BTFDebug::populateStructType(const DIType *Ty) {
976
13
  unsigned Id;
977
13
  visitTypeEntry(Ty, Id, false, false);
978
13
  for (const auto &TypeEntry : TypeEntries)
979
87
    TypeEntry->completeType(*this);
980
13
  return Id;
981
13
}
982
983
// Find struct/array debuginfo types given a type id.
984
void BTFDebug::setTypeFromId(uint32_t TypeId, BTFTypeStruct **PrevStructType,
985
40
                             BTFTypeArray **PrevArrayType) {
986
66
  for (const auto &StructType : StructTypes) {
987
66
    if (StructType->getId() == TypeId) {
988
23
      *PrevStructType = StructType;
989
23
      return;
990
23
    }
991
66
  }
992
40
  
for (const auto &ArrayType : ArrayTypes)17
{
993
8
    if (ArrayType->getId() == TypeId) {
994
4
      *PrevArrayType = ArrayType;
995
4
      return;
996
4
    }
997
8
  }
998
17
}
999
1000
/// Generate a struct member offset relocation.
1001
void BTFDebug::generateOffsetReloc(const MachineInstr *MI,
1002
                                   const MCSymbol *ORSym, DIType *RootTy,
1003
13
                                   StringRef AccessPattern) {
1004
13
  BTFTypeStruct *PrevStructType = nullptr;
1005
13
  BTFTypeArray *PrevArrayType = nullptr;
1006
13
  unsigned RootId = populateStructType(RootTy);
1007
13
  setTypeFromId(RootId, &PrevStructType, &PrevArrayType);
1008
13
  unsigned RootTySize = PrevStructType->getStructSize();
1009
13
1010
13
  BTFOffsetReloc OffsetReloc;
1011
13
  OffsetReloc.Label = ORSym;
1012
13
  OffsetReloc.OffsetNameOff = addString(AccessPattern.drop_back());
1013
13
  OffsetReloc.TypeID = RootId;
1014
13
1015
13
  uint32_t Start = 0, End = 0, Offset = 0;
1016
13
  bool FirstAccess = true;
1017
80
  for (auto C : AccessPattern) {
1018
80
    if (C != ':') {
1019
40
      End++;
1020
40
    } else {
1021
40
      std::string SubStr = AccessPattern.substr(Start, End - Start);
1022
40
      int Loc = std::stoi(SubStr);
1023
40
1024
40
      if (FirstAccess) {
1025
13
        Offset = Loc * RootTySize;
1026
13
        FirstAccess = false;
1027
27
      } else if (PrevStructType) {
1028
23
        uint32_t MemberOffset, MemberTypeId;
1029
23
        PrevStructType->getMemberInfo(Loc, MemberOffset, MemberTypeId);
1030
23
1031
23
        Offset += MemberOffset >> 3;
1032
23
        PrevStructType = nullptr;
1033
23
        setTypeFromId(MemberTypeId, &PrevStructType, &PrevArrayType);
1034
23
      } else 
if (4
PrevArrayType4
) {
1035
4
        uint32_t LocOffset, ElementTypeId;
1036
4
        PrevArrayType->getLocInfo(Loc, LocOffset, ElementTypeId);
1037
4
1038
4
        Offset += LocOffset;
1039
4
        PrevArrayType = nullptr;
1040
4
        setTypeFromId(ElementTypeId, &PrevStructType, &PrevArrayType);
1041
4
      }
1042
40
      Start = End + 1;
1043
40
      End = Start;
1044
40
    }
1045
80
  }
1046
13
  AccessOffsets[RootTy->getName().str() + ":" + AccessPattern.str()] = Offset;
1047
13
  OffsetRelocTable[SecNameOff].push_back(OffsetReloc);
1048
13
}
1049
1050
59
void BTFDebug::processLDimm64(const MachineInstr *MI) {
1051
59
  // If the insn is an LD_imm64, the following two cases
1052
59
  // will generate an .BTF.ext record.
1053
59
  //
1054
59
  // If the insn is "r2 = LD_imm64 @__BTF_...",
1055
59
  // add this insn into the .BTF.ext OffsetReloc subsection.
1056
59
  // Relocation looks like:
1057
59
  //  . SecName:
1058
59
  //    . InstOffset
1059
59
  //    . TypeID
1060
59
  //    . OffSetNameOff
1061
59
  // Later, the insn is replaced with "r2 = <offset>"
1062
59
  // where "<offset>" equals to the offset based on current
1063
59
  // type definitions.
1064
59
  //
1065
59
  // If the insn is "r2 = LD_imm64 @VAR" and VAR is
1066
59
  // a patchable external global, add this insn into the .BTF.ext
1067
59
  // ExternReloc subsection.
1068
59
  // Relocation looks like:
1069
59
  //  . SecName:
1070
59
  //    . InstOffset
1071
59
  //    . ExternNameOff
1072
59
  // Later, the insn is replaced with "r2 = <value>" or
1073
59
  // "LD_imm64 r2, <value>" where "<value>" = 0.
1074
59
1075
59
  // check whether this is a candidate or not
1076
59
  const MachineOperand &MO = MI->getOperand(1);
1077
59
  if (MO.isGlobal()) {
1078
59
    const GlobalValue *GVal = MO.getGlobal();
1079
59
    auto *GVar = dyn_cast<GlobalVariable>(GVal);
1080
59
    if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) {
1081
13
      MCSymbol *ORSym = OS.getContext().createTempSymbol();
1082
13
      OS.EmitLabel(ORSym);
1083
13
1084
13
      MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
1085
13
      DIType *Ty = dyn_cast<DIType>(MDN);
1086
13
      generateOffsetReloc(MI, ORSym, Ty, GVar->getName());
1087
46
    } else if (GVar && !GVar->hasInitializer() && 
GVar->hasExternalLinkage()8
&&
1088
46
               
GVar->getSection() == BPFCoreSharedInfo::PatchableExtSecName8
) {
1089
6
      MCSymbol *ORSym = OS.getContext().createTempSymbol();
1090
6
      OS.EmitLabel(ORSym);
1091
6
1092
6
      BTFExternReloc ExternReloc;
1093
6
      ExternReloc.Label = ORSym;
1094
6
      ExternReloc.ExternNameOff = addString(GVar->getName());
1095
6
      ExternRelocTable[SecNameOff].push_back(ExternReloc);
1096
6
    }
1097
59
  }
1098
59
}
1099
1100
457
void BTFDebug::beginInstruction(const MachineInstr *MI) {
1101
457
  DebugHandlerBase::beginInstruction(MI);
1102
457
1103
457
  if (SkipInstruction || MI->isMetaInstruction() ||
1104
457
      
MI->getFlag(MachineInstr::FrameSetup)375
)
1105
82
    return;
1106
375
1107
375
  if (MI->isInlineAsm()) {
1108
0
    // Count the number of register definitions to find the asm string.
1109
0
    unsigned NumDefs = 0;
1110
0
    for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
1111
0
         ++NumDefs)
1112
0
      ;
1113
0
1114
0
    // Skip this inline asm instruction if the asmstr is empty.
1115
0
    const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
1116
0
    if (AsmStr[0] == 0)
1117
0
      return;
1118
375
  }
1119
375
1120
375
  if (MI->getOpcode() == BPF::LD_imm64)
1121
59
    processLDimm64(MI);
1122
375
1123
375
  // Skip this instruction if no DebugLoc or the DebugLoc
1124
375
  // is the same as the previous instruction.
1125
375
  const DebugLoc &DL = MI->getDebugLoc();
1126
375
  if (!DL || 
PrevInstLoc == DL309
) {
1127
205
    // This instruction will be skipped, no LineInfo has
1128
205
    // been generated, construct one based on function signature.
1129
205
    if (LineInfoGenerated == false) {
1130
27
      auto *S = MI->getMF()->getFunction().getSubprogram();
1131
27
      MCSymbol *FuncLabel = Asm->getFunctionBegin();
1132
27
      constructLineInfo(S, FuncLabel, S->getLine(), 0);
1133
27
      LineInfoGenerated = true;
1134
27
    }
1135
205
1136
205
    return;
1137
205
  }
1138
170
1139
170
  // Create a temporary label to remember the insn for lineinfo.
1140
170
  MCSymbol *LineSym = OS.getContext().createTempSymbol();
1141
170
  OS.EmitLabel(LineSym);
1142
170
1143
170
  // Construct the lineinfo.
1144
170
  auto SP = DL.get()->getScope()->getSubprogram();
1145
170
  constructLineInfo(SP, LineSym, DL.getLine(), DL.getCol());
1146
170
1147
170
  LineInfoGenerated = true;
1148
170
  PrevInstLoc = DL;
1149
170
}
1150
1151
264
void BTFDebug::processGlobals(bool ProcessingMapDef) {
1152
264
  // Collect all types referenced by globals.
1153
264
  const Module *M = MMI->getModule();
1154
278
  for (const GlobalVariable &Global : M->globals()) {
1155
278
    // Ignore external globals for now.
1156
278
    if (!Global.hasInitializer() && 
Global.hasExternalLinkage()42
)
1157
42
      continue;
1158
236
1159
236
    // Decide the section name.
1160
236
    StringRef SecName;
1161
236
    if (Global.hasSection()) {
1162
52
      SecName = Global.getSection();
1163
184
    } else {
1164
184
      // data, bss, or readonly sections
1165
184
      if (Global.isConstant())
1166
12
        SecName = ".rodata";
1167
172
      else
1168
172
        SecName = Global.getInitializer()->isZeroValue() ? 
".bss"156
:
".data"16
;
1169
184
    }
1170
236
1171
236
    if (ProcessingMapDef != SecName.startswith(".maps"))
1172
118
      continue;
1173
118
1174
118
    SmallVector<DIGlobalVariableExpression *, 1> GVs;
1175
118
    Global.getDebugInfo(GVs);
1176
118
    uint32_t GVTypeId = 0;
1177
118
    for (auto *GVE : GVs) {
1178
118
      if (SecName.startswith(".maps"))
1179
2
        visitMapDefType(GVE->getVariable()->getType(), GVTypeId);
1180
116
      else
1181
116
        visitTypeEntry(GVE->getVariable()->getType(), GVTypeId, false, false);
1182
118
      break;
1183
118
    }
1184
118
1185
118
    // Only support the following globals:
1186
118
    //  . static variables
1187
118
    //  . non-static global variables with section attributes
1188
118
    // Essentially means:
1189
118
    //  . .bcc/.data/.rodata DataSec entities only contain static data
1190
118
    //  . Other DataSec entities contain static or initialized global data.
1191
118
    //    Initialized global data are mostly used for finding map key/value type
1192
118
    //    id's. Whether DataSec is readonly or not can be found from
1193
118
    //    corresponding ELF section flags.
1194
118
    auto Linkage = Global.getLinkage();
1195
118
    if (Linkage != GlobalValue::InternalLinkage &&
1196
118
        
(80
Linkage != GlobalValue::ExternalLinkage80
||
!Global.hasSection()16
))
1197
66
      continue;
1198
52
1199
52
    uint32_t GVarInfo = Linkage == GlobalValue::ExternalLinkage
1200
52
                            ? 
BTF::VAR_GLOBAL_ALLOCATED14
1201
52
                            : 
BTF::VAR_STATIC38
;
1202
52
    auto VarEntry =
1203
52
        llvm::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo);
1204
52
    uint32_t VarId = addType(std::move(VarEntry));
1205
52
1206
52
    // Find or create a DataSec
1207
52
    if (DataSecEntries.find(SecName) == DataSecEntries.end()) {
1208
32
      DataSecEntries[SecName] = llvm::make_unique<BTFKindDataSec>(Asm, SecName);
1209
32
    }
1210
52
1211
52
    // Calculate symbol size
1212
52
    const DataLayout &DL = Global.getParent()->getDataLayout();
1213
52
    uint32_t Size = DL.getTypeAllocSize(Global.getType()->getElementType());
1214
52
1215
52
    DataSecEntries[SecName]->addVar(VarId, Asm->getSymbol(&Global), Size);
1216
52
  }
1217
264
}
1218
1219
/// Emit proper patchable instructions.
1220
375
bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) {
1221
375
  if (MI->getOpcode() == BPF::LD_imm64) {
1222
59
    const MachineOperand &MO = MI->getOperand(1);
1223
59
    if (MO.isGlobal()) {
1224
59
      const GlobalValue *GVal = MO.getGlobal();
1225
59
      auto *GVar = dyn_cast<GlobalVariable>(GVal);
1226
59
      if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) {
1227
13
        MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index);
1228
13
        DIType *Ty = dyn_cast<DIType>(MDN);
1229
13
        std::string TypeName = Ty->getName();
1230
13
        int64_t Imm = AccessOffsets[TypeName + ":" + GVar->getName().str()];
1231
13
1232
13
        // Emit "mov ri, <imm>" for abstract member accesses.
1233
13
        OutMI.setOpcode(BPF::MOV_ri);
1234
13
        OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1235
13
        OutMI.addOperand(MCOperand::createImm(Imm));
1236
13
        return true;
1237
46
      } else if (GVar && !GVar->hasInitializer() &&
1238
46
                 
GVar->hasExternalLinkage()8
&&
1239
46
                 
GVar->getSection() == BPFCoreSharedInfo::PatchableExtSecName8
) {
1240
6
        const IntegerType *IntTy = dyn_cast<IntegerType>(GVar->getValueType());
1241
6
        assert(IntTy);
1242
6
        // For patchable externals, emit "LD_imm64, ri, 0" if the external
1243
6
        // variable is 64bit width, emit "mov ri, 0" otherwise.
1244
6
        if (IntTy->getBitWidth() == 64)
1245
2
          OutMI.setOpcode(BPF::LD_imm64);
1246
4
        else
1247
4
          OutMI.setOpcode(BPF::MOV_ri);
1248
6
        OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1249
6
        OutMI.addOperand(MCOperand::createImm(0));
1250
6
        return true;
1251
6
      }
1252
356
    }
1253
59
  }
1254
356
  return false;
1255
356
}
1256
1257
132
void BTFDebug::endModule() {
1258
132
  // Collect MapDef globals if not collected yet.
1259
132
  if (MapDefNotCollected) {
1260
70
    processGlobals(true);
1261
70
    MapDefNotCollected = false;
1262
70
  }
1263
132
1264
132
  // Collect global types/variables except MapDef globals.
1265
132
  processGlobals(false);
1266
132
  for (auto &DataSec : DataSecEntries)
1267
32
    addType(std::move(DataSec.second));
1268
132
1269
132
  // Fixups
1270
132
  for (auto &Fixup : FixupDerivedTypes) {
1271
4
    StringRef TypeName = Fixup.first;
1272
4
    bool IsUnion = Fixup.second.first;
1273
4
1274
4
    // Search through struct types
1275
4
    uint32_t StructTypeId = 0;
1276
4
    for (const auto &StructType : StructTypes) {
1277
4
      if (StructType->getName() == TypeName) {
1278
2
        StructTypeId = StructType->getId();
1279
2
        break;
1280
2
      }
1281
4
    }
1282
4
1283
4
    if (StructTypeId == 0) {
1284
2
      auto FwdTypeEntry = llvm::make_unique<BTFTypeFwd>(TypeName, IsUnion);
1285
2
      StructTypeId = addType(std::move(FwdTypeEntry));
1286
2
    }
1287
4
1288
4
    for (auto &DType : Fixup.second.second) {
1289
4
      DType->setPointeeType(StructTypeId);
1290
4
    }
1291
4
  }
1292
132
1293
132
  // Complete BTF type cross refereences.
1294
132
  for (const auto &TypeEntry : TypeEntries)
1295
592
    TypeEntry->completeType(*this);
1296
132
1297
132
  // Emit BTF sections.
1298
132
  emitBTFSection();
1299
132
  emitBTFExtSection();
1300
132
}