blob: 1442dc3123ee7b247cff4cbd1004d1b573c7cd79 [file] [log] [blame]
Yonghong Song7b410ac2018-12-19 16:40:25 +00001//===- BTFDebug.cpp - BTF Generator ---------------------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Yonghong Song7b410ac2018-12-19 16:40:25 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file contains support for writing BTF debug info.
10//
11//===----------------------------------------------------------------------===//
12
13#include "BTFDebug.h"
14#include "llvm/BinaryFormat/ELF.h"
15#include "llvm/CodeGen/AsmPrinter.h"
16#include "llvm/CodeGen/MachineModuleInfo.h"
17#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCObjectFileInfo.h"
19#include "llvm/MC/MCSectionELF.h"
20#include "llvm/MC/MCStreamer.h"
Fangrui Song83db8872019-04-02 16:15:46 +000021#include "llvm/Support/LineIterator.h"
Yonghong Song7b410ac2018-12-19 16:40:25 +000022
23using namespace llvm;
24
25static const char *BTFKindStr[] = {
26#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME,
27#include "BTF.def"
28};
29
30/// Emit a BTF common type.
31void BTFTypeBase::emitType(MCStreamer &OS) {
32 OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) +
33 ")");
34 OS.EmitIntValue(BTFType.NameOff, 4);
35 OS.AddComment("0x" + Twine::utohexstr(BTFType.Info));
36 OS.EmitIntValue(BTFType.Info, 4);
37 OS.EmitIntValue(BTFType.Size, 4);
38}
39
40BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag)
41 : DTy(DTy) {
42 switch (Tag) {
43 case dwarf::DW_TAG_pointer_type:
44 Kind = BTF::BTF_KIND_PTR;
45 break;
46 case dwarf::DW_TAG_const_type:
47 Kind = BTF::BTF_KIND_CONST;
48 break;
49 case dwarf::DW_TAG_volatile_type:
50 Kind = BTF::BTF_KIND_VOLATILE;
51 break;
52 case dwarf::DW_TAG_typedef:
53 Kind = BTF::BTF_KIND_TYPEDEF;
54 break;
55 case dwarf::DW_TAG_restrict_type:
56 Kind = BTF::BTF_KIND_RESTRICT;
57 break;
58 default:
59 llvm_unreachable("Unknown DIDerivedType Tag");
60 }
61 BTFType.Info = Kind << 24;
62}
63
64void BTFTypeDerived::completeType(BTFDebug &BDebug) {
65 BTFType.NameOff = BDebug.addString(DTy->getName());
66
67 // The base type for PTR/CONST/VOLATILE could be void.
Fangrui Songda82ce92019-05-07 02:06:37 +000068 const DIType *ResolvedType = DTy->getBaseType();
Yonghong Song7b410ac2018-12-19 16:40:25 +000069 if (!ResolvedType) {
70 assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||
71 Kind == BTF::BTF_KIND_VOLATILE) &&
72 "Invalid null basetype");
73 BTFType.Type = 0;
74 } else {
75 BTFType.Type = BDebug.getTypeId(ResolvedType);
76 }
77}
78
79void BTFTypeDerived::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
80
81/// Represent a struct/union forward declaration.
82BTFTypeFwd::BTFTypeFwd(StringRef Name, bool IsUnion) : Name(Name) {
83 Kind = BTF::BTF_KIND_FWD;
84 BTFType.Info = IsUnion << 31 | Kind << 24;
85 BTFType.Type = 0;
86}
87
88void BTFTypeFwd::completeType(BTFDebug &BDebug) {
89 BTFType.NameOff = BDebug.addString(Name);
90}
91
92void BTFTypeFwd::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
93
94BTFTypeInt::BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits,
95 uint32_t OffsetInBits, StringRef TypeName)
96 : Name(TypeName) {
97 // Translate IR int encoding to BTF int encoding.
98 uint8_t BTFEncoding;
99 switch (Encoding) {
100 case dwarf::DW_ATE_boolean:
101 BTFEncoding = BTF::INT_BOOL;
102 break;
103 case dwarf::DW_ATE_signed:
104 case dwarf::DW_ATE_signed_char:
105 BTFEncoding = BTF::INT_SIGNED;
106 break;
107 case dwarf::DW_ATE_unsigned:
108 case dwarf::DW_ATE_unsigned_char:
109 BTFEncoding = 0;
110 break;
111 default:
112 llvm_unreachable("Unknown BTFTypeInt Encoding");
113 }
114
115 Kind = BTF::BTF_KIND_INT;
116 BTFType.Info = Kind << 24;
117 BTFType.Size = roundupToBytes(SizeInBits);
118 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
119}
120
121void BTFTypeInt::completeType(BTFDebug &BDebug) {
122 BTFType.NameOff = BDebug.addString(Name);
123}
124
125void BTFTypeInt::emitType(MCStreamer &OS) {
126 BTFTypeBase::emitType(OS);
127 OS.AddComment("0x" + Twine::utohexstr(IntVal));
128 OS.EmitIntValue(IntVal, 4);
129}
130
131BTFTypeEnum::BTFTypeEnum(const DICompositeType *ETy, uint32_t VLen) : ETy(ETy) {
132 Kind = BTF::BTF_KIND_ENUM;
133 BTFType.Info = Kind << 24 | VLen;
134 BTFType.Size = roundupToBytes(ETy->getSizeInBits());
135}
136
137void BTFTypeEnum::completeType(BTFDebug &BDebug) {
138 BTFType.NameOff = BDebug.addString(ETy->getName());
139
140 DINodeArray Elements = ETy->getElements();
141 for (const auto Element : Elements) {
142 const auto *Enum = cast<DIEnumerator>(Element);
143
144 struct BTF::BTFEnum BTFEnum;
145 BTFEnum.NameOff = BDebug.addString(Enum->getName());
146 // BTF enum value is 32bit, enforce it.
147 BTFEnum.Val = static_cast<uint32_t>(Enum->getValue());
148 EnumValues.push_back(BTFEnum);
149 }
150}
151
152void BTFTypeEnum::emitType(MCStreamer &OS) {
153 BTFTypeBase::emitType(OS);
154 for (const auto &Enum : EnumValues) {
155 OS.EmitIntValue(Enum.NameOff, 4);
156 OS.EmitIntValue(Enum.Val, 4);
157 }
158}
159
Yonghong Song360a4e2c2019-03-28 21:59:49 +0000160BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000161 Kind = BTF::BTF_KIND_ARRAY;
Yonghong Song360a4e2c2019-03-28 21:59:49 +0000162 BTFType.NameOff = 0;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000163 BTFType.Info = Kind << 24;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000164 BTFType.Size = 0;
165
Yonghong Song360a4e2c2019-03-28 21:59:49 +0000166 ArrayInfo.ElemType = ElemTypeId;
167 ArrayInfo.Nelems = NumElems;
168}
169
170/// Represent a BTF array.
171void BTFTypeArray::completeType(BTFDebug &BDebug) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000172
173 // The IR does not really have a type for the index.
174 // A special type for array index should have been
175 // created during initial type traversal. Just
176 // retrieve that type id.
177 ArrayInfo.IndexType = BDebug.getArrayIndexTypeId();
Yonghong Song7b410ac2018-12-19 16:40:25 +0000178}
179
180void BTFTypeArray::emitType(MCStreamer &OS) {
181 BTFTypeBase::emitType(OS);
182 OS.EmitIntValue(ArrayInfo.ElemType, 4);
183 OS.EmitIntValue(ArrayInfo.IndexType, 4);
184 OS.EmitIntValue(ArrayInfo.Nelems, 4);
185}
186
187/// Represent either a struct or a union.
188BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct,
189 bool HasBitField, uint32_t Vlen)
190 : STy(STy), HasBitField(HasBitField) {
191 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
192 BTFType.Size = roundupToBytes(STy->getSizeInBits());
193 BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen;
194}
195
196void BTFTypeStruct::completeType(BTFDebug &BDebug) {
197 BTFType.NameOff = BDebug.addString(STy->getName());
198
199 // Add struct/union members.
200 const DINodeArray Elements = STy->getElements();
201 for (const auto *Element : Elements) {
202 struct BTF::BTFMember BTFMember;
203 const auto *DDTy = cast<DIDerivedType>(Element);
204
205 BTFMember.NameOff = BDebug.addString(DDTy->getName());
206 if (HasBitField) {
207 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
208 BTFMember.Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
209 } else {
210 BTFMember.Offset = DDTy->getOffsetInBits();
211 }
Fangrui Songda82ce92019-05-07 02:06:37 +0000212 BTFMember.Type = BDebug.getTypeId(DDTy->getBaseType());
Yonghong Song7b410ac2018-12-19 16:40:25 +0000213 Members.push_back(BTFMember);
214 }
215}
216
217void BTFTypeStruct::emitType(MCStreamer &OS) {
218 BTFTypeBase::emitType(OS);
219 for (const auto &Member : Members) {
220 OS.EmitIntValue(Member.NameOff, 4);
221 OS.EmitIntValue(Member.Type, 4);
222 OS.AddComment("0x" + Twine::utohexstr(Member.Offset));
223 OS.EmitIntValue(Member.Offset, 4);
224 }
225}
226
227/// The Func kind represents both subprogram and pointee of function
228/// pointers. If the FuncName is empty, it represents a pointee of function
229/// pointer. Otherwise, it represents a subprogram. The func arg names
230/// are empty for pointee of function pointer case, and are valid names
231/// for subprogram.
232BTFTypeFuncProto::BTFTypeFuncProto(
233 const DISubroutineType *STy, uint32_t VLen,
234 const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
235 : STy(STy), FuncArgNames(FuncArgNames) {
236 Kind = BTF::BTF_KIND_FUNC_PROTO;
237 BTFType.Info = (Kind << 24) | VLen;
238}
239
240void BTFTypeFuncProto::completeType(BTFDebug &BDebug) {
241 DITypeRefArray Elements = STy->getTypeArray();
Fangrui Songda82ce92019-05-07 02:06:37 +0000242 auto RetType = Elements[0];
Yonghong Song7b410ac2018-12-19 16:40:25 +0000243 BTFType.Type = RetType ? BDebug.getTypeId(RetType) : 0;
244 BTFType.NameOff = 0;
245
246 // For null parameter which is typically the last one
247 // to represent the vararg, encode the NameOff/Type to be 0.
248 for (unsigned I = 1, N = Elements.size(); I < N; ++I) {
249 struct BTF::BTFParam Param;
Fangrui Songda82ce92019-05-07 02:06:37 +0000250 auto Element = Elements[I];
Yonghong Song7b410ac2018-12-19 16:40:25 +0000251 if (Element) {
252 Param.NameOff = BDebug.addString(FuncArgNames[I]);
253 Param.Type = BDebug.getTypeId(Element);
254 } else {
255 Param.NameOff = 0;
256 Param.Type = 0;
257 }
258 Parameters.push_back(Param);
259 }
260}
261
262void BTFTypeFuncProto::emitType(MCStreamer &OS) {
263 BTFTypeBase::emitType(OS);
264 for (const auto &Param : Parameters) {
265 OS.EmitIntValue(Param.NameOff, 4);
266 OS.EmitIntValue(Param.Type, 4);
267 }
268}
269
270BTFTypeFunc::BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId)
271 : Name(FuncName) {
272 Kind = BTF::BTF_KIND_FUNC;
273 BTFType.Info = Kind << 24;
274 BTFType.Type = ProtoTypeId;
275}
276
277void BTFTypeFunc::completeType(BTFDebug &BDebug) {
278 BTFType.NameOff = BDebug.addString(Name);
279}
280
281void BTFTypeFunc::emitType(MCStreamer &OS) { BTFTypeBase::emitType(OS); }
282
Yonghong Song6db6b562019-03-16 15:36:31 +0000283BTFKindVar::BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo)
284 : Name(VarName) {
285 Kind = BTF::BTF_KIND_VAR;
286 BTFType.Info = Kind << 24;
287 BTFType.Type = TypeId;
288 Info = VarInfo;
289}
290
291void BTFKindVar::completeType(BTFDebug &BDebug) {
292 BTFType.NameOff = BDebug.addString(Name);
293}
294
295void BTFKindVar::emitType(MCStreamer &OS) {
296 BTFTypeBase::emitType(OS);
297 OS.EmitIntValue(Info, 4);
298}
299
300BTFKindDataSec::BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName)
301 : Asm(AsmPrt), Name(SecName) {
302 Kind = BTF::BTF_KIND_DATASEC;
303 BTFType.Info = Kind << 24;
304 BTFType.Size = 0;
305}
306
307void BTFKindDataSec::completeType(BTFDebug &BDebug) {
308 BTFType.NameOff = BDebug.addString(Name);
309 BTFType.Info |= Vars.size();
310}
311
312void BTFKindDataSec::emitType(MCStreamer &OS) {
313 BTFTypeBase::emitType(OS);
314
315 for (const auto &V : Vars) {
316 OS.EmitIntValue(std::get<0>(V), 4);
317 Asm->EmitLabelReference(std::get<1>(V), 4);
318 OS.EmitIntValue(std::get<2>(V), 4);
319 }
320}
321
Yonghong Song7b410ac2018-12-19 16:40:25 +0000322uint32_t BTFStringTable::addString(StringRef S) {
323 // Check whether the string already exists.
324 for (auto &OffsetM : OffsetToIdMap) {
325 if (Table[OffsetM.second] == S)
326 return OffsetM.first;
327 }
328 // Not find, add to the string table.
329 uint32_t Offset = Size;
330 OffsetToIdMap[Offset] = Table.size();
331 Table.push_back(S);
332 Size += S.size() + 1;
333 return Offset;
334}
335
336BTFDebug::BTFDebug(AsmPrinter *AP)
337 : DebugHandlerBase(AP), OS(*Asm->OutStreamer), SkipInstruction(false),
338 LineInfoGenerated(false), SecNameOff(0), ArrayIndexTypeId(0) {
339 addString("\0");
340}
341
Yonghong Song6db6b562019-03-16 15:36:31 +0000342uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
343 const DIType *Ty) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000344 TypeEntry->setId(TypeEntries.size() + 1);
Yonghong Song6db6b562019-03-16 15:36:31 +0000345 uint32_t Id = TypeEntry->getId();
346 DIToIdMap[Ty] = Id;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000347 TypeEntries.push_back(std::move(TypeEntry));
Yonghong Song6db6b562019-03-16 15:36:31 +0000348 return Id;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000349}
350
351uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
352 TypeEntry->setId(TypeEntries.size() + 1);
353 uint32_t Id = TypeEntry->getId();
354 TypeEntries.push_back(std::move(TypeEntry));
355 return Id;
356}
357
Yonghong Song6db6b562019-03-16 15:36:31 +0000358void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000359 // Only int types are supported in BTF.
360 uint32_t Encoding = BTy->getEncoding();
361 if (Encoding != dwarf::DW_ATE_boolean && Encoding != dwarf::DW_ATE_signed &&
362 Encoding != dwarf::DW_ATE_signed_char &&
363 Encoding != dwarf::DW_ATE_unsigned &&
364 Encoding != dwarf::DW_ATE_unsigned_char)
365 return;
366
367 // Create a BTF type instance for this DIBasicType and put it into
368 // DIToIdMap for cross-type reference check.
369 auto TypeEntry = llvm::make_unique<BTFTypeInt>(
370 Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
Yonghong Song6db6b562019-03-16 15:36:31 +0000371 TypeId = addType(std::move(TypeEntry), BTy);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000372}
373
374/// Handle subprogram or subroutine types.
375void BTFDebug::visitSubroutineType(
376 const DISubroutineType *STy, bool ForSubprog,
377 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
378 uint32_t &TypeId) {
379 DITypeRefArray Elements = STy->getTypeArray();
380 uint32_t VLen = Elements.size() - 1;
381 if (VLen > BTF::MAX_VLEN)
382 return;
383
384 // Subprogram has a valid non-zero-length name, and the pointee of
385 // a function pointer has an empty name. The subprogram type will
386 // not be added to DIToIdMap as it should not be referenced by
387 // any other types.
388 auto TypeEntry = llvm::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames);
389 if (ForSubprog)
390 TypeId = addType(std::move(TypeEntry)); // For subprogram
391 else
Yonghong Song6db6b562019-03-16 15:36:31 +0000392 TypeId = addType(std::move(TypeEntry), STy); // For func ptr
Yonghong Song7b410ac2018-12-19 16:40:25 +0000393
394 // Visit return type and func arg types.
395 for (const auto Element : Elements) {
Fangrui Songda82ce92019-05-07 02:06:37 +0000396 visitTypeEntry(Element);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000397 }
398}
399
400/// Handle structure/union types.
Yonghong Song6db6b562019-03-16 15:36:31 +0000401void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
402 uint32_t &TypeId) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000403 const DINodeArray Elements = CTy->getElements();
404 uint32_t VLen = Elements.size();
405 if (VLen > BTF::MAX_VLEN)
406 return;
407
408 // Check whether we have any bitfield members or not
409 bool HasBitField = false;
410 for (const auto *Element : Elements) {
411 auto E = cast<DIDerivedType>(Element);
412 if (E->isBitField()) {
413 HasBitField = true;
414 break;
415 }
416 }
417
418 auto TypeEntry =
419 llvm::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
Yonghong Song6db6b562019-03-16 15:36:31 +0000420 TypeId = addType(std::move(TypeEntry), CTy);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000421
422 // Visit all struct members.
423 for (const auto *Element : Elements)
424 visitTypeEntry(cast<DIDerivedType>(Element));
425}
426
Yonghong Song6db6b562019-03-16 15:36:31 +0000427void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) {
Yonghong Song360a4e2c2019-03-28 21:59:49 +0000428 // Visit array element type.
429 uint32_t ElemTypeId;
Fangrui Songda82ce92019-05-07 02:06:37 +0000430 visitTypeEntry(CTy->getBaseType(), ElemTypeId);
Yonghong Song360a4e2c2019-03-28 21:59:49 +0000431
432 if (!CTy->getSizeInBits()) {
433 auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemTypeId, 0);
434 ElemTypeId = addType(std::move(TypeEntry), CTy);
435 } else {
436 // Visit array dimensions.
437 DINodeArray Elements = CTy->getElements();
438 for (int I = Elements.size() - 1; I >= 0; --I) {
439 if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
440 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
441 const DISubrange *SR = cast<DISubrange>(Element);
442 auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
443 int64_t Count = CI->getSExtValue();
444
445 auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemTypeId, Count);
446 if (I == 0)
447 ElemTypeId = addType(std::move(TypeEntry), CTy);
448 else
449 ElemTypeId = addType(std::move(TypeEntry));
450 }
451 }
452 }
453
454 // The array TypeId is the type id of the outermost dimension.
455 TypeId = ElemTypeId;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000456
457 // The IR does not have a type for array index while BTF wants one.
458 // So create an array index type if there is none.
459 if (!ArrayIndexTypeId) {
460 auto TypeEntry = llvm::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
461 0, "__ARRAY_SIZE_TYPE__");
462 ArrayIndexTypeId = addType(std::move(TypeEntry));
463 }
Yonghong Song7b410ac2018-12-19 16:40:25 +0000464}
465
Yonghong Song6db6b562019-03-16 15:36:31 +0000466void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000467 DINodeArray Elements = CTy->getElements();
468 uint32_t VLen = Elements.size();
469 if (VLen > BTF::MAX_VLEN)
470 return;
471
472 auto TypeEntry = llvm::make_unique<BTFTypeEnum>(CTy, VLen);
Yonghong Song6db6b562019-03-16 15:36:31 +0000473 TypeId = addType(std::move(TypeEntry), CTy);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000474 // No need to visit base type as BTF does not encode it.
475}
476
477/// Handle structure/union forward declarations.
Yonghong Song6db6b562019-03-16 15:36:31 +0000478void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
479 uint32_t &TypeId) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000480 auto TypeEntry = llvm::make_unique<BTFTypeFwd>(CTy->getName(), IsUnion);
Yonghong Song6db6b562019-03-16 15:36:31 +0000481 TypeId = addType(std::move(TypeEntry), CTy);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000482}
483
484/// Handle structure, union, array and enumeration types.
Yonghong Song6db6b562019-03-16 15:36:31 +0000485void BTFDebug::visitCompositeType(const DICompositeType *CTy,
486 uint32_t &TypeId) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000487 auto Tag = CTy->getTag();
488 if (Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
489 // Handle forward declaration differently as it does not have members.
490 if (CTy->isForwardDecl())
Yonghong Song6db6b562019-03-16 15:36:31 +0000491 visitFwdDeclType(CTy, Tag == dwarf::DW_TAG_union_type, TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000492 else
Yonghong Song6db6b562019-03-16 15:36:31 +0000493 visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000494 } else if (Tag == dwarf::DW_TAG_array_type)
Yonghong Song6db6b562019-03-16 15:36:31 +0000495 visitArrayType(CTy, TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000496 else if (Tag == dwarf::DW_TAG_enumeration_type)
Yonghong Song6db6b562019-03-16 15:36:31 +0000497 visitEnumType(CTy, TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000498}
499
500/// Handle pointer, typedef, const, volatile, restrict and member types.
Yonghong Song6db6b562019-03-16 15:36:31 +0000501void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000502 unsigned Tag = DTy->getTag();
503
504 if (Tag == dwarf::DW_TAG_pointer_type || Tag == dwarf::DW_TAG_typedef ||
505 Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
506 Tag == dwarf::DW_TAG_restrict_type) {
507 auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy, Tag);
Yonghong Song6db6b562019-03-16 15:36:31 +0000508 TypeId = addType(std::move(TypeEntry), DTy);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000509 } else if (Tag != dwarf::DW_TAG_member) {
510 return;
511 }
512
513 // Visit base type of pointer, typedef, const, volatile, restrict or
514 // struct/union member.
Yonghong Songded9a442019-03-22 01:30:50 +0000515 uint32_t TempTypeId = 0;
Fangrui Songda82ce92019-05-07 02:06:37 +0000516 visitTypeEntry(DTy->getBaseType(), TempTypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000517}
518
Yonghong Song6db6b562019-03-16 15:36:31 +0000519void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId) {
520 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) {
521 TypeId = DIToIdMap[Ty];
Yonghong Song7b410ac2018-12-19 16:40:25 +0000522 return;
Yonghong Song6db6b562019-03-16 15:36:31 +0000523 }
Yonghong Song7b410ac2018-12-19 16:40:25 +0000524
Yonghong Song7b410ac2018-12-19 16:40:25 +0000525 if (const auto *BTy = dyn_cast<DIBasicType>(Ty))
Yonghong Song6db6b562019-03-16 15:36:31 +0000526 visitBasicType(BTy, TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000527 else if (const auto *STy = dyn_cast<DISubroutineType>(Ty))
528 visitSubroutineType(STy, false, std::unordered_map<uint32_t, StringRef>(),
529 TypeId);
530 else if (const auto *CTy = dyn_cast<DICompositeType>(Ty))
Yonghong Song6db6b562019-03-16 15:36:31 +0000531 visitCompositeType(CTy, TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000532 else if (const auto *DTy = dyn_cast<DIDerivedType>(Ty))
Yonghong Song6db6b562019-03-16 15:36:31 +0000533 visitDerivedType(DTy, TypeId);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000534 else
535 llvm_unreachable("Unknown DIType");
536}
537
Yonghong Song6db6b562019-03-16 15:36:31 +0000538void BTFDebug::visitTypeEntry(const DIType *Ty) {
539 uint32_t TypeId;
540 visitTypeEntry(Ty, TypeId);
541}
542
Yonghong Song7b410ac2018-12-19 16:40:25 +0000543/// Read file contents from the actual file or from the source
544std::string BTFDebug::populateFileContent(const DISubprogram *SP) {
545 auto File = SP->getFile();
546 std::string FileName;
547
Yonghong Songfa365402019-02-02 05:54:59 +0000548 if (!File->getFilename().startswith("/") && File->getDirectory().size())
Yonghong Song7b410ac2018-12-19 16:40:25 +0000549 FileName = File->getDirectory().str() + "/" + File->getFilename().str();
550 else
551 FileName = File->getFilename();
552
553 // No need to populate the contends if it has been populated!
554 if (FileContent.find(FileName) != FileContent.end())
555 return FileName;
556
557 std::vector<std::string> Content;
558 std::string Line;
559 Content.push_back(Line); // Line 0 for empty string
560
Fangrui Song83db8872019-04-02 16:15:46 +0000561 std::unique_ptr<MemoryBuffer> Buf;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000562 auto Source = File->getSource();
Fangrui Song83db8872019-04-02 16:15:46 +0000563 if (Source)
564 Buf = MemoryBuffer::getMemBufferCopy(*Source);
565 else if (ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
566 MemoryBuffer::getFile(FileName))
567 Buf = std::move(*BufOrErr);
568 if (Buf)
569 for (line_iterator I(*Buf, false), E; I != E; ++I)
570 Content.push_back(*I);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000571
572 FileContent[FileName] = Content;
573 return FileName;
574}
575
576void BTFDebug::constructLineInfo(const DISubprogram *SP, MCSymbol *Label,
577 uint32_t Line, uint32_t Column) {
578 std::string FileName = populateFileContent(SP);
579 BTFLineInfo LineInfo;
580
581 LineInfo.Label = Label;
582 LineInfo.FileNameOff = addString(FileName);
583 // If file content is not available, let LineOff = 0.
584 if (Line < FileContent[FileName].size())
585 LineInfo.LineOff = addString(FileContent[FileName][Line]);
586 else
587 LineInfo.LineOff = 0;
588 LineInfo.LineNum = Line;
589 LineInfo.ColumnNum = Column;
590 LineInfoTable[SecNameOff].push_back(LineInfo);
591}
592
593void BTFDebug::emitCommonHeader() {
594 OS.AddComment("0x" + Twine::utohexstr(BTF::MAGIC));
595 OS.EmitIntValue(BTF::MAGIC, 2);
596 OS.EmitIntValue(BTF::VERSION, 1);
597 OS.EmitIntValue(0, 1);
598}
599
600void BTFDebug::emitBTFSection() {
Yonghong Songd82247c2019-03-05 01:01:21 +0000601 // Do not emit section if no types and only "" string.
602 if (!TypeEntries.size() && StringTable.getSize() == 1)
603 return;
604
Yonghong Song7b410ac2018-12-19 16:40:25 +0000605 MCContext &Ctx = OS.getContext();
606 OS.SwitchSection(Ctx.getELFSection(".BTF", ELF::SHT_PROGBITS, 0));
607
608 // Emit header.
609 emitCommonHeader();
610 OS.EmitIntValue(BTF::HeaderSize, 4);
611
612 uint32_t TypeLen = 0, StrLen;
613 for (const auto &TypeEntry : TypeEntries)
614 TypeLen += TypeEntry->getSize();
615 StrLen = StringTable.getSize();
616
617 OS.EmitIntValue(0, 4);
618 OS.EmitIntValue(TypeLen, 4);
619 OS.EmitIntValue(TypeLen, 4);
620 OS.EmitIntValue(StrLen, 4);
621
622 // Emit type table.
623 for (const auto &TypeEntry : TypeEntries)
624 TypeEntry->emitType(OS);
625
626 // Emit string table.
627 uint32_t StringOffset = 0;
628 for (const auto &S : StringTable.getTable()) {
629 OS.AddComment("string offset=" + std::to_string(StringOffset));
630 OS.EmitBytes(S);
631 OS.EmitBytes(StringRef("\0", 1));
632 StringOffset += S.size() + 1;
633 }
634}
635
636void BTFDebug::emitBTFExtSection() {
Yonghong Songd82247c2019-03-05 01:01:21 +0000637 // Do not emit section if empty FuncInfoTable and LineInfoTable.
638 if (!FuncInfoTable.size() && !LineInfoTable.size())
639 return;
640
Yonghong Song7b410ac2018-12-19 16:40:25 +0000641 MCContext &Ctx = OS.getContext();
642 OS.SwitchSection(Ctx.getELFSection(".BTF.ext", ELF::SHT_PROGBITS, 0));
643
644 // Emit header.
645 emitCommonHeader();
646 OS.EmitIntValue(BTF::ExtHeaderSize, 4);
647
648 // Account for FuncInfo/LineInfo record size as well.
649 uint32_t FuncLen = 4, LineLen = 4;
650 for (const auto &FuncSec : FuncInfoTable) {
651 FuncLen += BTF::SecFuncInfoSize;
652 FuncLen += FuncSec.second.size() * BTF::BPFFuncInfoSize;
653 }
654 for (const auto &LineSec : LineInfoTable) {
655 LineLen += BTF::SecLineInfoSize;
656 LineLen += LineSec.second.size() * BTF::BPFLineInfoSize;
657 }
658
659 OS.EmitIntValue(0, 4);
660 OS.EmitIntValue(FuncLen, 4);
661 OS.EmitIntValue(FuncLen, 4);
662 OS.EmitIntValue(LineLen, 4);
663
664 // Emit func_info table.
665 OS.AddComment("FuncInfo");
666 OS.EmitIntValue(BTF::BPFFuncInfoSize, 4);
667 for (const auto &FuncSec : FuncInfoTable) {
668 OS.AddComment("FuncInfo section string offset=" +
669 std::to_string(FuncSec.first));
670 OS.EmitIntValue(FuncSec.first, 4);
671 OS.EmitIntValue(FuncSec.second.size(), 4);
672 for (const auto &FuncInfo : FuncSec.second) {
673 Asm->EmitLabelReference(FuncInfo.Label, 4);
674 OS.EmitIntValue(FuncInfo.TypeId, 4);
675 }
676 }
677
678 // Emit line_info table.
679 OS.AddComment("LineInfo");
680 OS.EmitIntValue(BTF::BPFLineInfoSize, 4);
681 for (const auto &LineSec : LineInfoTable) {
682 OS.AddComment("LineInfo section string offset=" +
683 std::to_string(LineSec.first));
684 OS.EmitIntValue(LineSec.first, 4);
685 OS.EmitIntValue(LineSec.second.size(), 4);
686 for (const auto &LineInfo : LineSec.second) {
687 Asm->EmitLabelReference(LineInfo.Label, 4);
688 OS.EmitIntValue(LineInfo.FileNameOff, 4);
689 OS.EmitIntValue(LineInfo.LineOff, 4);
690 OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " +
691 std::to_string(LineInfo.ColumnNum));
692 OS.EmitIntValue(LineInfo.LineNum << 10 | LineInfo.ColumnNum, 4);
693 }
694 }
695}
696
697void BTFDebug::beginFunctionImpl(const MachineFunction *MF) {
698 auto *SP = MF->getFunction().getSubprogram();
699 auto *Unit = SP->getUnit();
700
701 if (Unit->getEmissionKind() == DICompileUnit::NoDebug) {
702 SkipInstruction = true;
703 return;
704 }
705 SkipInstruction = false;
706
707 // Collect all types locally referenced in this function.
708 // Use RetainedNodes so we can collect all argument names
709 // even if the argument is not used.
710 std::unordered_map<uint32_t, StringRef> FuncArgNames;
711 for (const DINode *DN : SP->getRetainedNodes()) {
712 if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000713 // Collect function arguments for subprogram func type.
714 uint32_t Arg = DV->getArg();
Yonghong Songcacac052019-03-15 05:51:25 +0000715 if (Arg) {
Fangrui Songda82ce92019-05-07 02:06:37 +0000716 visitTypeEntry(DV->getType());
Yonghong Song7b410ac2018-12-19 16:40:25 +0000717 FuncArgNames[Arg] = DV->getName();
Yonghong Songcacac052019-03-15 05:51:25 +0000718 }
Yonghong Song7b410ac2018-12-19 16:40:25 +0000719 }
720 }
721
722 // Construct subprogram func proto type.
723 uint32_t ProtoTypeId;
724 visitSubroutineType(SP->getType(), true, FuncArgNames, ProtoTypeId);
725
726 // Construct subprogram func type
727 auto FuncTypeEntry =
728 llvm::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId);
729 uint32_t FuncTypeId = addType(std::move(FuncTypeEntry));
730
731 // Construct funcinfo and the first lineinfo for the function.
732 MCSymbol *FuncLabel = Asm->getFunctionBegin();
733 BTFFuncInfo FuncInfo;
734 FuncInfo.Label = FuncLabel;
735 FuncInfo.TypeId = FuncTypeId;
736 if (FuncLabel->isInSection()) {
737 MCSection &Section = FuncLabel->getSection();
738 const MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(&Section);
739 assert(SectionELF && "Null section for Function Label");
740 SecNameOff = addString(SectionELF->getSectionName());
741 } else {
742 SecNameOff = addString(".text");
743 }
744 FuncInfoTable[SecNameOff].push_back(FuncInfo);
745}
746
747void BTFDebug::endFunctionImpl(const MachineFunction *MF) {
748 SkipInstruction = false;
749 LineInfoGenerated = false;
750 SecNameOff = 0;
751}
752
753void BTFDebug::beginInstruction(const MachineInstr *MI) {
754 DebugHandlerBase::beginInstruction(MI);
755
756 if (SkipInstruction || MI->isMetaInstruction() ||
757 MI->getFlag(MachineInstr::FrameSetup))
758 return;
759
760 if (MI->isInlineAsm()) {
761 // Count the number of register definitions to find the asm string.
762 unsigned NumDefs = 0;
763 for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
764 ++NumDefs)
765 ;
766
767 // Skip this inline asm instruction if the asmstr is empty.
768 const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
769 if (AsmStr[0] == 0)
770 return;
771 }
772
773 // Skip this instruction if no DebugLoc or the DebugLoc
774 // is the same as the previous instruction.
775 const DebugLoc &DL = MI->getDebugLoc();
776 if (!DL || PrevInstLoc == DL) {
777 // This instruction will be skipped, no LineInfo has
778 // been generated, construct one based on function signature.
779 if (LineInfoGenerated == false) {
780 auto *S = MI->getMF()->getFunction().getSubprogram();
781 MCSymbol *FuncLabel = Asm->getFunctionBegin();
782 constructLineInfo(S, FuncLabel, S->getLine(), 0);
783 LineInfoGenerated = true;
784 }
785
786 return;
787 }
788
789 // Create a temporary label to remember the insn for lineinfo.
790 MCSymbol *LineSym = OS.getContext().createTempSymbol();
791 OS.EmitLabel(LineSym);
792
793 // Construct the lineinfo.
794 auto SP = DL.get()->getScope()->getSubprogram();
795 constructLineInfo(SP, LineSym, DL.getLine(), DL.getCol());
796
797 LineInfoGenerated = true;
798 PrevInstLoc = DL;
799}
800
Yonghong Song6db6b562019-03-16 15:36:31 +0000801void BTFDebug::processGlobals() {
Yonghong Song7b410ac2018-12-19 16:40:25 +0000802 // Collect all types referenced by globals.
803 const Module *M = MMI->getModule();
Yonghong Songcacac052019-03-15 05:51:25 +0000804 for (const GlobalVariable &Global : M->globals()) {
805 // Ignore external globals for now.
Yonghong Song44ed2862019-03-15 17:39:10 +0000806 if (!Global.hasInitializer() && Global.hasExternalLinkage())
Yonghong Songcacac052019-03-15 05:51:25 +0000807 continue;
808
809 SmallVector<DIGlobalVariableExpression *, 1> GVs;
810 Global.getDebugInfo(GVs);
Yonghong Song6db6b562019-03-16 15:36:31 +0000811 uint32_t GVTypeId = 0;
Yonghong Songcacac052019-03-15 05:51:25 +0000812 for (auto *GVE : GVs) {
Fangrui Songda82ce92019-05-07 02:06:37 +0000813 visitTypeEntry(GVE->getVariable()->getType(), GVTypeId);
Yonghong Song6db6b562019-03-16 15:36:31 +0000814 break;
Yonghong Song7b410ac2018-12-19 16:40:25 +0000815 }
Yonghong Song6db6b562019-03-16 15:36:31 +0000816
817 // Only support the following globals:
818 // . static variables
819 // . non-static global variables with section attributes
820 // Essentially means:
821 // . .bcc/.data/.rodata DataSec entities only contain static data
822 // . Other DataSec entities contain static or initialized global data.
823 // Initialized global data are mostly used for finding map key/value type
824 // id's. Whether DataSec is readonly or not can be found from
825 // corresponding ELF section flags.
826 auto Linkage = Global.getLinkage();
827 if (Linkage != GlobalValue::InternalLinkage &&
828 (Linkage != GlobalValue::ExternalLinkage || !Global.hasSection()))
829 continue;
830
831 uint32_t GVarInfo = Linkage == GlobalValue::ExternalLinkage
832 ? BTF::VAR_GLOBAL_ALLOCATED
833 : BTF::VAR_STATIC;
834 auto VarEntry =
835 llvm::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo);
836 uint32_t VarId = addType(std::move(VarEntry));
837
838 // Decide the section name.
839 std::string SecName;
840 if (Global.hasSection()) {
841 SecName = Global.getSection().str();
842 } else {
843 // data, bss, or readonly sections
844 if (Global.isConstant())
845 SecName += ".rodata";
846 else
847 SecName += Global.getInitializer()->isZeroValue() ? ".bss" : ".data";
848 }
849
850 // Find or create a DataSec
851 if (DataSecEntries.find(SecName) == DataSecEntries.end()) {
852 DataSecEntries[SecName] = llvm::make_unique<BTFKindDataSec>(Asm, SecName);
853 }
854
855 // Calculate symbol size
856 const DataLayout &DL = Global.getParent()->getDataLayout();
857 uint32_t Size = DL.getTypeAllocSize(Global.getType()->getElementType());
858
859 DataSecEntries[SecName]->addVar(VarId, Asm->getSymbol(&Global), Size);
Yonghong Song7b410ac2018-12-19 16:40:25 +0000860 }
861
Yonghong Song6db6b562019-03-16 15:36:31 +0000862 for (auto &DataSec : DataSecEntries)
863 addType(std::move(DataSec.second));
864}
865
866void BTFDebug::endModule() {
867 // Collect all global types/variables.
868 processGlobals();
869
Yonghong Song7b410ac2018-12-19 16:40:25 +0000870 // Complete BTF type cross refereences.
871 for (const auto &TypeEntry : TypeEntries)
872 TypeEntry->completeType(*this);
873
874 // Emit BTF sections.
875 emitBTFSection();
876 emitBTFExtSection();
877}