28 #define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME, 45 case dwarf::DW_TAG_pointer_type:
46 Kind = BTF::BTF_KIND_PTR;
48 case dwarf::DW_TAG_const_type:
49 Kind = BTF::BTF_KIND_CONST;
51 case dwarf::DW_TAG_volatile_type:
52 Kind = BTF::BTF_KIND_VOLATILE;
54 case dwarf::DW_TAG_typedef:
55 Kind = BTF::BTF_KIND_TYPEDEF;
57 case dwarf::DW_TAG_restrict_type:
58 Kind = BTF::BTF_KIND_RESTRICT;
72 assert((
Kind == BTF::BTF_KIND_PTR ||
Kind == BTF::BTF_KIND_CONST ||
73 Kind == BTF::BTF_KIND_VOLATILE) &&
74 "Invalid null basetype");
85 Kind = BTF::BTF_KIND_FWD;
102 case dwarf::DW_ATE_boolean:
105 case dwarf::DW_ATE_signed:
106 case dwarf::DW_ATE_signed_char:
109 case dwarf::DW_ATE_unsigned:
110 case dwarf::DW_ATE_unsigned_char:
117 Kind = BTF::BTF_KIND_INT;
120 IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits;
134 Kind = BTF::BTF_KIND_ENUM;
143 for (
const auto Element : Elements) {
144 const auto *Enum = cast<DIEnumerator>(Element);
149 BTFEnum.
Val =
static_cast<uint32_t>(Enum->getValue());
150 EnumValues.push_back(BTFEnum);
156 for (
const auto &Enum : EnumValues) {
163 Kind = BTF::BTF_KIND_ARRAY;
189 if (!ArraySizeInBits) {
193 while (!BaseTypeSize) {
194 const auto *DDTy = cast<DIDerivedType>(
BaseType);
195 BaseType = DDTy->getBaseType().resolve();
197 BaseTypeSize = BaseType->getSizeInBits();
213 : STy(STy), HasBitField(HasBitField) {
214 Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION;
224 for (
const auto *Element : Elements) {
226 const auto *DDTy = cast<DIDerivedType>(Element);
230 uint8_t BitFieldSize = DDTy->isBitField() ? DDTy->getSizeInBits() : 0;
231 BTFMember.
Offset = BitFieldSize << 24 | DDTy->getOffsetInBits();
233 BTFMember.
Offset = DDTy->getOffsetInBits();
235 BTFMember.
Type = BDebug.
getTypeId(DDTy->getBaseType().resolve());
236 Members.push_back(BTFMember);
242 for (
const auto &Member : Members) {
257 const std::unordered_map<uint32_t, StringRef> &FuncArgNames)
258 : STy(STy), FuncArgNames(FuncArgNames) {
259 Kind = BTF::BTF_KIND_FUNC_PROTO;
265 auto RetType = Elements[0].resolve();
271 for (
unsigned I = 1,
N = Elements.
size();
I <
N; ++
I) {
273 auto Element = Elements[
I].resolve();
281 Parameters.push_back(Param);
287 for (
const auto &Param : Parameters) {
295 Kind = BTF::BTF_KIND_FUNC;
308 for (
auto &OffsetM : OffsetToIdMap) {
309 if (Table[OffsetM.second] == S)
310 return OffsetM.first;
314 OffsetToIdMap[
Offset] = Table.size();
322 LineInfoGenerated(
false), SecNameOff(0), ArrayIndexTypeId(0) {
326 void BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry,
328 TypeEntry->setId(TypeEntries.size() + 1);
329 DIToIdMap[Ty] = TypeEntry->getId();
330 TypeEntries.push_back(std::move(TypeEntry));
333 uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
334 TypeEntry->setId(TypeEntries.size() + 1);
336 TypeEntries.push_back(std::move(TypeEntry));
340 void BTFDebug::visitBasicType(
const DIBasicType *BTy) {
343 if (Encoding != dwarf::DW_ATE_boolean && Encoding != dwarf::DW_ATE_signed &&
344 Encoding != dwarf::DW_ATE_signed_char &&
345 Encoding != dwarf::DW_ATE_unsigned &&
346 Encoding != dwarf::DW_ATE_unsigned_char)
351 auto TypeEntry = llvm::make_unique<BTFTypeInt>(
353 addType(std::move(TypeEntry), BTy);
357 void BTFDebug::visitSubroutineType(
359 const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
370 auto TypeEntry = llvm::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames);
372 TypeId = addType(std::move(TypeEntry));
374 addType(std::move(TypeEntry), STy);
377 for (
const auto Element : Elements) {
378 visitTypeEntry(Element.resolve());
383 void BTFDebug::visitStructType(
const DICompositeType *CTy,
bool IsStruct) {
390 bool HasBitField =
false;
391 for (
const auto *Element : Elements) {
392 auto E = cast<DIDerivedType>(Element);
393 if (
E->isBitField()) {
400 llvm::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen);
401 addType(std::move(TypeEntry), CTy);
404 for (
const auto *Element : Elements)
405 visitTypeEntry(cast<DIDerivedType>(Element));
409 auto TypeEntry = llvm::make_unique<BTFTypeArray>(CTy);
410 addType(std::move(TypeEntry), CTy);
414 if (!ArrayIndexTypeId) {
415 auto TypeEntry = llvm::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32,
416 0,
"__ARRAY_SIZE_TYPE__");
417 ArrayIndexTypeId = addType(std::move(TypeEntry));
430 auto TypeEntry = llvm::make_unique<BTFTypeEnum>(CTy, VLen);
431 addType(std::move(TypeEntry), CTy);
436 void BTFDebug::visitFwdDeclType(
const DICompositeType *CTy,
bool IsUnion) {
437 auto TypeEntry = llvm::make_unique<BTFTypeFwd>(CTy->
getName(), IsUnion);
438 addType(std::move(TypeEntry), CTy);
444 if (
Tag == dwarf::DW_TAG_structure_type ||
Tag == dwarf::DW_TAG_union_type) {
447 visitFwdDeclType(CTy,
Tag == dwarf::DW_TAG_union_type);
449 visitStructType(CTy,
Tag == dwarf::DW_TAG_structure_type);
450 }
else if (
Tag == dwarf::DW_TAG_array_type)
452 else if (
Tag == dwarf::DW_TAG_enumeration_type)
460 if (Tag == dwarf::DW_TAG_pointer_type || Tag == dwarf::DW_TAG_typedef ||
461 Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
462 Tag == dwarf::DW_TAG_restrict_type) {
463 auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy,
Tag);
464 addType(std::move(TypeEntry), DTy);
465 }
else if (Tag != dwarf::DW_TAG_member) {
471 visitTypeEntry(DTy->getBaseType().
resolve());
474 void BTFDebug::visitTypeEntry(
const DIType *Ty) {
475 if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end())
479 if (
const auto *BTy = dyn_cast<DIBasicType>(Ty))
481 else if (
const auto *STy = dyn_cast<DISubroutineType>(Ty))
482 visitSubroutineType(STy,
false, std::unordered_map<uint32_t, StringRef>(),
484 else if (
const auto *CTy = dyn_cast<DICompositeType>(Ty))
485 visitCompositeType(CTy);
486 else if (
const auto *DTy = dyn_cast<DIDerivedType>(Ty))
487 visitDerivedType(DTy);
493 std::string BTFDebug::populateFileContent(
const DISubprogram *
SP) {
495 std::string FileName;
497 if (
File->getDirectory().size())
498 FileName =
File->getDirectory().str() +
"/" +
File->getFilename().str();
500 FileName =
File->getFilename();
503 if (FileContent.
find(FileName) != FileContent.
end())
506 std::vector<std::string> Content;
508 Content.push_back(Line);
512 std::istringstream InputString(
Source.getValue());
513 while (std::getline(InputString, Line))
514 Content.push_back(Line);
516 std::ifstream InputFile(FileName);
517 while (std::getline(InputFile, Line))
518 Content.push_back(Line);
521 FileContent[FileName] = Content;
527 std::string FileName = populateFileContent(SP);
530 LineInfo.
Label = Label;
533 if (Line < FileContent[FileName].
size())
539 LineInfoTable[SecNameOff].push_back(LineInfo);
542 void BTFDebug::emitCommonHeader() {
549 void BTFDebug::emitBTFSection() {
558 for (
const auto &TypeEntry : TypeEntries)
559 TypeLen += TypeEntry->getSize();
560 StrLen = StringTable.
getSize();
568 for (
const auto &TypeEntry : TypeEntries)
569 TypeEntry->emitType(OS);
573 for (
const auto &S : StringTable.
getTable()) {
577 StringOffset += S.size() + 1;
581 void BTFDebug::emitBTFExtSection() {
591 for (
const auto &FuncSec : FuncInfoTable) {
595 for (
const auto &LineSec : LineInfoTable) {
608 for (
const auto &FuncSec : FuncInfoTable) {
609 OS.
AddComment(
"FuncInfo section string offset=" +
613 for (
const auto &FuncInfo : FuncSec.second) {
622 for (
const auto &LineSec : LineInfoTable) {
623 OS.
AddComment(
"LineInfo section string offset=" +
627 for (
const auto &LineInfo : LineSec.second) {
633 OS.
EmitIntValue(LineInfo.LineNum << 10 | LineInfo.ColumnNum, 4);
640 auto *
Unit = SP->getUnit();
643 SkipInstruction =
true;
646 SkipInstruction =
false;
651 std::unordered_map<uint32_t, StringRef> FuncArgNames;
652 for (
const DINode *DN : SP->getRetainedNodes()) {
653 if (
const auto *DV = dyn_cast<DILocalVariable>(DN)) {
654 visitTypeEntry(DV->getType().resolve());
665 visitSubroutineType(SP->getType(),
true, FuncArgNames, ProtoTypeId);
669 llvm::make_unique<BTFTypeFunc>(SP->
getName(), ProtoTypeId);
670 uint32_t FuncTypeId = addType(std::move(FuncTypeEntry));
675 FuncInfo.
Label = FuncLabel;
676 FuncInfo.
TypeId = FuncTypeId;
680 assert(SectionELF &&
"Null section for Function Label");
685 FuncInfoTable[SecNameOff].push_back(FuncInfo);
689 SkipInstruction =
false;
690 LineInfoGenerated =
false;
703 unsigned NumDefs = 0;
720 if (LineInfoGenerated ==
false) {
723 constructLineInfo(S, FuncLabel, S->getLine(), 0);
724 LineInfoGenerated =
true;
735 auto SP = DL.
get()->getScope()->getSubprogram();
738 LineInfoGenerated =
true;
746 for (
const auto *GVE : CUNode->getGlobalVariables()) {
753 for (
const auto &TypeEntry : TypeEntries)
754 TypeEntry->completeType(*
this);
Instances of this class represent a uniqued identifier for a section in the current translation unit...
uint64_t getOffsetInBits() const
void endFunctionImpl(const MachineFunction *MF) override
Post process after all instructions in this function are processed.
DILocation * get() const
Get the underlying DILocation.
Represent one func and its type id.
BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId)
uint32_t ColumnNum
the column number
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
This class represents lattice values for constants.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
A Module instance is used to store all the information related to an LLVM module. ...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
DITypeRef getBaseType() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
uint32_t getArrayIndexTypeId()
Get the special array index type id.
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues)
iterator find(StringRef Key)
BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, StringRef TypeName)
BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag)
void completeType(BTFDebug &BDebug)
Represent a BTF array.
bool isMetaInstruction() const
Return true if this instruction doesn't produce any output in the form of executable instructions...
bool isForwardDecl() const
static const char * BTFKindStr[]
uint32_t Offset
BitOffset or BitFieldSize+BitOffset.
StringRef getName() const
Tagged DWARF-like metadata node.
DINodeArray getElements() const
uint32_t Type
Member type.
MCContext & getContext() const
DebugLoc PrevInstLoc
Previous instruction's location information.
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
uint32_t ElemType
Element type.
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
virtual void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
void completeType(BTFDebug &BDebug)
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
BTF_KIND_ENUM is followed by multiple "struct BTFEnum".
uint32_t roundupToBytes(uint32_t NumBits)
BTFTypeArray(const DICompositeType *ATy)
uint64_t getSizeInBits() const
const char * getSymbolName() const
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
Context object for machine code objects.
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
void completeType(BTFDebug &BDebug)
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
MCSymbol * getFunctionBegin() const
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers...
BTF_KIND_FUNC_PROTO are followed by multiple "struct BTFParam".
void endModule() override
Complete all the types and emit the BTF sections.
void resolve()
Resolve a unique, unresolved node.
BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, uint32_t NumMembers)
Represent either a struct or a union.
Streaming machine code generation interface.
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
void completeType(BTFDebug &BDebug)
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
DISubprogram * getSubprogram() const
Get the attached subprogram.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
struct BTF::CommonType BTFType
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
AsmPrinter * Asm
Target of debug info emission.
Collect and emit BTF information.
This class is intended to be used as a driving class for all asm writers.
uint32_t NameOff
Member name offset in the string table.
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
void EmitLabelReference(const MCSymbol *Label, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label" where the size in bytes of the directive is specified by Size and L...
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
BTF_KIND_STRUCT and BTF_KIND_UNION are followed by multiple "struct BTFMember".
uint32_t NameOff
Type name offset in the string table.
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
std::vector< std::string > & getTable()
uint32_t LineNum
the line number
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
StringRef getName() const
int32_t Val
Enum member value.
uint32_t NameOff
Enum name offset in the string table.
void completeType(BTFDebug &BDebug)
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
MCSymbol * Label
MCSymbol identifying insn for the lineinfo.
static Twine utohexstr(const uint64_t &Val)
uint32_t getTypeId(const DIType *Ty)
Get the type id for a particular DIType.
uint32_t IndexType
Index type.
void completeType(BTFDebug &BDebug)
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
This file contains support for writing BTF debug info.
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
void completeType(BTFDebug &BDebug)
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
amdgpu Simplify well known AMD library false Value Value * Arg
uint32_t Nelems
Number of elements for this array.
Type array for a subprogram.
Representation of each machine instruction.
uint32_t addString(StringRef S)
Add a string to the string table and returns its offset in the table.
Max # of struct/union/enum members or func args.
unsigned getEncoding() const
BTFTypeFwd(StringRef Name, bool IsUnion)
Represent a struct/union forward declaration.
StringRef getName() const
Return a constant reference to the value's name.
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
iterator_range< debug_compile_units_iterator > debug_compile_units() const
Return an iterator for all DICompileUnits listed in this Module's llvm.dbg.cu named metadata node and...
This represents a section on linux, lots of unix variants and some bare metal systems.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Base class for debug information backends.
BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, const std::unordered_map< uint32_t, StringRef > &FuncArgNames)
The Func kind represents both subprogram and pointee of function pointers.
const MCSymbol * Label
Func MCSymbol.
const Module * getModule() const
uint32_t FileNameOff
file name offset in the .BTF string table
size_t addString(StringRef S)
Add string to the string table.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const std::string to_string(const T &Value)
DITypeRef getType() const
void completeType(BTFDebug &BDebug)
Complete BTF type generation after all related DebugInfo types have been visited so their BTF type id...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
DITypeRefArray getTypeArray() const
MachineModuleInfo * MMI
Collected machine module information.
StringRef - Represent a constant reference to a string, i.e.
uint32_t Info
"Info" bits arrangement: Bits 0-15: vlen (e.g.
const MachineOperand & getOperand(unsigned i) const
void emitType(MCStreamer &OS)
Emit types for this BTF type entry.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
uint32_t TypeId
Type id referring to .BTF type section.
StringRef getSectionName() const
uint32_t LineOff
line offset in the .BTF string table
Basic type, like 'int' or 'float'.