xref: /freebsd/contrib/llvm-project/llvm/lib/Target/BPF/BTFDebug.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- BTFDebug.h -----------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file contains support for writing BTF debug info.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H
150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_BPF_BTFDEBUG_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/DebugHandlerBase.h"
1906c3fb27SDimitry Andric #include "llvm/DebugInfo/BTF/BTF.h"
20e8d8bef9SDimitry Andric #include <cstdint>
21e8d8bef9SDimitry Andric #include <map>
22480093f4SDimitry Andric #include <set>
230b57cec5SDimitry Andric #include <unordered_map>
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric namespace llvm {
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric class AsmPrinter;
280b57cec5SDimitry Andric class BTFDebug;
290b57cec5SDimitry Andric class DIType;
305ffd83dbSDimitry Andric class GlobalVariable;
31e8d8bef9SDimitry Andric class MachineFunction;
32e8d8bef9SDimitry Andric class MachineInstr;
33e8d8bef9SDimitry Andric class MachineOperand;
34e8d8bef9SDimitry Andric class MCInst;
350b57cec5SDimitry Andric class MCStreamer;
360b57cec5SDimitry Andric class MCSymbol;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric /// The base class for BTF type generation.
390b57cec5SDimitry Andric class BTFTypeBase {
400b57cec5SDimitry Andric protected:
410b57cec5SDimitry Andric   uint8_t Kind;
420b57cec5SDimitry Andric   bool IsCompleted;
430b57cec5SDimitry Andric   uint32_t Id;
440b57cec5SDimitry Andric   struct BTF::CommonType BTFType;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric public:
BTFTypeBase()470b57cec5SDimitry Andric   BTFTypeBase() : IsCompleted(false) {}
480b57cec5SDimitry Andric   virtual ~BTFTypeBase() = default;
setId(uint32_t Id)490b57cec5SDimitry Andric   void setId(uint32_t Id) { this->Id = Id; }
getId()500b57cec5SDimitry Andric   uint32_t getId() { return Id; }
roundupToBytes(uint32_t NumBits)510b57cec5SDimitry Andric   uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }
520b57cec5SDimitry Andric   /// Get the size of this BTF type entry.
getSize()530b57cec5SDimitry Andric   virtual uint32_t getSize() { return BTF::CommonTypeSize; }
540b57cec5SDimitry Andric   /// Complete BTF type generation after all related DebugInfo types
550b57cec5SDimitry Andric   /// have been visited so their BTF type id's are available
560b57cec5SDimitry Andric   /// for cross referece.
completeType(BTFDebug & BDebug)570b57cec5SDimitry Andric   virtual void completeType(BTFDebug &BDebug) {}
580b57cec5SDimitry Andric   /// Emit types for this BTF type entry.
590b57cec5SDimitry Andric   virtual void emitType(MCStreamer &OS);
600b57cec5SDimitry Andric };
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric /// Handle several derived types include pointer, const,
630b57cec5SDimitry Andric /// volatile, typedef and restrict.
640b57cec5SDimitry Andric class BTFTypeDerived : public BTFTypeBase {
650b57cec5SDimitry Andric   const DIDerivedType *DTy;
660b57cec5SDimitry Andric   bool NeedsFixup;
67349cc55cSDimitry Andric   StringRef Name;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric public:
700b57cec5SDimitry Andric   BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);
71349cc55cSDimitry Andric   BTFTypeDerived(unsigned NextTypeId, unsigned Tag, StringRef Name);
725ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
735ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
740b57cec5SDimitry Andric   void setPointeeType(uint32_t PointeeType);
750b57cec5SDimitry Andric };
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric /// Handle struct or union forward declaration.
780b57cec5SDimitry Andric class BTFTypeFwd : public BTFTypeBase {
790b57cec5SDimitry Andric   StringRef Name;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric public:
820b57cec5SDimitry Andric   BTFTypeFwd(StringRef Name, bool IsUnion);
835ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
845ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
850b57cec5SDimitry Andric };
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric /// Handle int type.
880b57cec5SDimitry Andric class BTFTypeInt : public BTFTypeBase {
890b57cec5SDimitry Andric   StringRef Name;
900b57cec5SDimitry Andric   uint32_t IntVal; ///< Encoding, offset, bits
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric public:
930b57cec5SDimitry Andric   BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,
940b57cec5SDimitry Andric              StringRef TypeName);
getSize()955ffd83dbSDimitry Andric   uint32_t getSize() override { return BTFTypeBase::getSize() + sizeof(uint32_t); }
965ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
975ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
980b57cec5SDimitry Andric };
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric /// Handle enumerate type.
1010b57cec5SDimitry Andric class BTFTypeEnum : public BTFTypeBase {
1020b57cec5SDimitry Andric   const DICompositeType *ETy;
1030b57cec5SDimitry Andric   std::vector<struct BTF::BTFEnum> EnumValues;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric public:
10681ad6265SDimitry Andric   BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);
getSize()1075ffd83dbSDimitry Andric   uint32_t getSize() override {
1080b57cec5SDimitry Andric     return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;
1090b57cec5SDimitry Andric   }
1105ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
1115ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
1120b57cec5SDimitry Andric };
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric /// Handle array type.
1150b57cec5SDimitry Andric class BTFTypeArray : public BTFTypeBase {
1160b57cec5SDimitry Andric   struct BTF::BTFArray ArrayInfo;
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric public:
1198bcb0991SDimitry Andric   BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);
getSize()1205ffd83dbSDimitry Andric   uint32_t getSize() override { return BTFTypeBase::getSize() + BTF::BTFArraySize; }
1215ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
1225ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
1230b57cec5SDimitry Andric };
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric /// Handle struct/union type.
1260b57cec5SDimitry Andric class BTFTypeStruct : public BTFTypeBase {
1270b57cec5SDimitry Andric   const DICompositeType *STy;
1280b57cec5SDimitry Andric   bool HasBitField;
1290b57cec5SDimitry Andric   std::vector<struct BTF::BTFMember> Members;
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric public:
1320b57cec5SDimitry Andric   BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,
1330b57cec5SDimitry Andric                 uint32_t NumMembers);
getSize()1345ffd83dbSDimitry Andric   uint32_t getSize() override {
1350b57cec5SDimitry Andric     return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;
1360b57cec5SDimitry Andric   }
1375ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
1385ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
1390b57cec5SDimitry Andric   std::string getName();
1400b57cec5SDimitry Andric };
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric /// Handle function pointer.
1430b57cec5SDimitry Andric class BTFTypeFuncProto : public BTFTypeBase {
1440b57cec5SDimitry Andric   const DISubroutineType *STy;
1450b57cec5SDimitry Andric   std::unordered_map<uint32_t, StringRef> FuncArgNames;
1460b57cec5SDimitry Andric   std::vector<struct BTF::BTFParam> Parameters;
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric public:
1490b57cec5SDimitry Andric   BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
1500b57cec5SDimitry Andric                    const std::unordered_map<uint32_t, StringRef> &FuncArgNames);
getSize()1515ffd83dbSDimitry Andric   uint32_t getSize() override {
1520b57cec5SDimitry Andric     return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;
1530b57cec5SDimitry Andric   }
1545ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
1555ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
1560b57cec5SDimitry Andric };
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric /// Handle subprogram
1590b57cec5SDimitry Andric class BTFTypeFunc : public BTFTypeBase {
1600b57cec5SDimitry Andric   StringRef Name;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric public:
163480093f4SDimitry Andric   BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope);
getSize()1645ffd83dbSDimitry Andric   uint32_t getSize() override { return BTFTypeBase::getSize(); }
1655ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
1665ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
1670b57cec5SDimitry Andric };
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric /// Handle variable instances
1700b57cec5SDimitry Andric class BTFKindVar : public BTFTypeBase {
1710b57cec5SDimitry Andric   StringRef Name;
1720b57cec5SDimitry Andric   uint32_t Info;
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric public:
1750b57cec5SDimitry Andric   BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);
getSize()1765ffd83dbSDimitry Andric   uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }
1775ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
1785ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
1790b57cec5SDimitry Andric };
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric /// Handle data sections
1820b57cec5SDimitry Andric class BTFKindDataSec : public BTFTypeBase {
1830b57cec5SDimitry Andric   AsmPrinter *Asm;
1840b57cec5SDimitry Andric   std::string Name;
1850b57cec5SDimitry Andric   std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric public:
1880b57cec5SDimitry Andric   BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);
getSize()1895ffd83dbSDimitry Andric   uint32_t getSize() override {
1900b57cec5SDimitry Andric     return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();
1910b57cec5SDimitry Andric   }
addDataSecEntry(uint32_t Id,const MCSymbol * Sym,uint32_t Size)19223408297SDimitry Andric   void addDataSecEntry(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {
1930b57cec5SDimitry Andric     Vars.push_back(std::make_tuple(Id, Sym, Size));
1940b57cec5SDimitry Andric   }
getName()1950b57cec5SDimitry Andric   std::string getName() { return Name; }
1965ffd83dbSDimitry Andric   void completeType(BTFDebug &BDebug) override;
1975ffd83dbSDimitry Andric   void emitType(MCStreamer &OS) override;
1980b57cec5SDimitry Andric };
1990b57cec5SDimitry Andric 
20023408297SDimitry Andric /// Handle binary floating point type.
20123408297SDimitry Andric class BTFTypeFloat : public BTFTypeBase {
20223408297SDimitry Andric   StringRef Name;
20323408297SDimitry Andric 
20423408297SDimitry Andric public:
20523408297SDimitry Andric   BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName);
20623408297SDimitry Andric   void completeType(BTFDebug &BDebug) override;
20723408297SDimitry Andric };
20823408297SDimitry Andric 
209349cc55cSDimitry Andric /// Handle decl tags.
210349cc55cSDimitry Andric class BTFTypeDeclTag : public BTFTypeBase {
211349cc55cSDimitry Andric   uint32_t Info;
212349cc55cSDimitry Andric   StringRef Tag;
213349cc55cSDimitry Andric 
214349cc55cSDimitry Andric public:
215349cc55cSDimitry Andric   BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag);
getSize()216349cc55cSDimitry Andric   uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }
217349cc55cSDimitry Andric   void completeType(BTFDebug &BDebug) override;
218349cc55cSDimitry Andric   void emitType(MCStreamer &OS) override;
219349cc55cSDimitry Andric };
220349cc55cSDimitry Andric 
22181ad6265SDimitry Andric /// Handle 64-bit enumerate type.
22281ad6265SDimitry Andric class BTFTypeEnum64 : public BTFTypeBase {
22381ad6265SDimitry Andric   const DICompositeType *ETy;
22481ad6265SDimitry Andric   std::vector<struct BTF::BTFEnum64> EnumValues;
22581ad6265SDimitry Andric 
22681ad6265SDimitry Andric public:
22781ad6265SDimitry Andric   BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);
getSize()22881ad6265SDimitry Andric   uint32_t getSize() override {
22981ad6265SDimitry Andric     return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnum64Size;
23081ad6265SDimitry Andric   }
23181ad6265SDimitry Andric   void completeType(BTFDebug &BDebug) override;
23281ad6265SDimitry Andric   void emitType(MCStreamer &OS) override;
23381ad6265SDimitry Andric };
23481ad6265SDimitry Andric 
235349cc55cSDimitry Andric class BTFTypeTypeTag : public BTFTypeBase {
236349cc55cSDimitry Andric   const DIDerivedType *DTy;
237349cc55cSDimitry Andric   StringRef Tag;
238349cc55cSDimitry Andric 
239349cc55cSDimitry Andric public:
240349cc55cSDimitry Andric   BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag);
241349cc55cSDimitry Andric   BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag);
242349cc55cSDimitry Andric   void completeType(BTFDebug &BDebug) override;
243349cc55cSDimitry Andric };
244349cc55cSDimitry Andric 
2450b57cec5SDimitry Andric /// String table.
2460b57cec5SDimitry Andric class BTFStringTable {
2470b57cec5SDimitry Andric   /// String table size in bytes.
2480b57cec5SDimitry Andric   uint32_t Size;
2490b57cec5SDimitry Andric   /// A mapping from string table offset to the index
2500b57cec5SDimitry Andric   /// of the Table. It is used to avoid putting
2510b57cec5SDimitry Andric   /// duplicated strings in the table.
2528bcb0991SDimitry Andric   std::map<uint32_t, uint32_t> OffsetToIdMap;
2530b57cec5SDimitry Andric   /// A vector of strings to represent the string table.
2540b57cec5SDimitry Andric   std::vector<std::string> Table;
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric public:
BTFStringTable()2570b57cec5SDimitry Andric   BTFStringTable() : Size(0) {}
getSize()2580b57cec5SDimitry Andric   uint32_t getSize() { return Size; }
getTable()2590b57cec5SDimitry Andric   std::vector<std::string> &getTable() { return Table; }
2600b57cec5SDimitry Andric   /// Add a string to the string table and returns its offset
2610b57cec5SDimitry Andric   /// in the table.
2620b57cec5SDimitry Andric   uint32_t addString(StringRef S);
2630b57cec5SDimitry Andric };
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric /// Represent one func and its type id.
2660b57cec5SDimitry Andric struct BTFFuncInfo {
2670b57cec5SDimitry Andric   const MCSymbol *Label; ///< Func MCSymbol
2680b57cec5SDimitry Andric   uint32_t TypeId;       ///< Type id referring to .BTF type section
2690b57cec5SDimitry Andric };
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric /// Represent one line info.
2720b57cec5SDimitry Andric struct BTFLineInfo {
2730b57cec5SDimitry Andric   MCSymbol *Label;      ///< MCSymbol identifying insn for the lineinfo
2740b57cec5SDimitry Andric   uint32_t FileNameOff; ///< file name offset in the .BTF string table
2750b57cec5SDimitry Andric   uint32_t LineOff;     ///< line offset in the .BTF string table
2760b57cec5SDimitry Andric   uint32_t LineNum;     ///< the line number
2770b57cec5SDimitry Andric   uint32_t ColumnNum;   ///< the column number
2780b57cec5SDimitry Andric };
2790b57cec5SDimitry Andric 
280480093f4SDimitry Andric /// Represent one field relocation.
2818bcb0991SDimitry Andric struct BTFFieldReloc {
2820b57cec5SDimitry Andric   const MCSymbol *Label;  ///< MCSymbol identifying insn for the reloc
2830b57cec5SDimitry Andric   uint32_t TypeID;        ///< Type ID
2840b57cec5SDimitry Andric   uint32_t OffsetNameOff; ///< The string to traverse types
2858bcb0991SDimitry Andric   uint32_t RelocKind;     ///< What to patch the instruction
2860b57cec5SDimitry Andric };
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric /// Collect and emit BTF information.
2890b57cec5SDimitry Andric class BTFDebug : public DebugHandlerBase {
2900b57cec5SDimitry Andric   MCStreamer &OS;
2910b57cec5SDimitry Andric   bool SkipInstruction;
2920b57cec5SDimitry Andric   bool LineInfoGenerated;
2930b57cec5SDimitry Andric   uint32_t SecNameOff;
2940b57cec5SDimitry Andric   uint32_t ArrayIndexTypeId;
2950b57cec5SDimitry Andric   bool MapDefNotCollected;
2960b57cec5SDimitry Andric   BTFStringTable StringTable;
2970b57cec5SDimitry Andric   std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;
2980b57cec5SDimitry Andric   std::unordered_map<const DIType *, uint32_t> DIToIdMap;
2990b57cec5SDimitry Andric   std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;
3000b57cec5SDimitry Andric   std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;
3018bcb0991SDimitry Andric   std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable;
3020b57cec5SDimitry Andric   StringMap<std::vector<std::string>> FileContent;
3030b57cec5SDimitry Andric   std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;
3040b57cec5SDimitry Andric   std::vector<BTFTypeStruct *> StructTypes;
305e8d8bef9SDimitry Andric   std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms;
30681ad6265SDimitry Andric   std::map<const DICompositeType *,
30781ad6265SDimitry Andric            std::vector<std::pair<const DIDerivedType *, BTFTypeDerived *>>>
3080b57cec5SDimitry Andric       FixupDerivedTypes;
309480093f4SDimitry Andric   std::set<const Function *>ProtoFunctions;
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   /// Add types to TypeEntries.
3120b57cec5SDimitry Andric   /// @{
3130b57cec5SDimitry Andric   /// Add types to TypeEntries and DIToIdMap.
3140b57cec5SDimitry Andric   uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);
3150b57cec5SDimitry Andric   /// Add types to TypeEntries only and return type id.
3160b57cec5SDimitry Andric   uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);
3170b57cec5SDimitry Andric   /// @}
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   /// IR type visiting functions.
3200b57cec5SDimitry Andric   /// @{
3210b57cec5SDimitry Andric   void visitTypeEntry(const DIType *Ty);
3220b57cec5SDimitry Andric   void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,
3230b57cec5SDimitry Andric                       bool SeenPointer);
3240b57cec5SDimitry Andric   void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);
3250b57cec5SDimitry Andric   void visitSubroutineType(
3260b57cec5SDimitry Andric       const DISubroutineType *STy, bool ForSubprog,
3270b57cec5SDimitry Andric       const std::unordered_map<uint32_t, StringRef> &FuncArgNames,
3280b57cec5SDimitry Andric       uint32_t &TypeId);
3290b57cec5SDimitry Andric   void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
3300b57cec5SDimitry Andric                         uint32_t &TypeId);
3310b57cec5SDimitry Andric   void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);
3320b57cec5SDimitry Andric   void visitStructType(const DICompositeType *STy, bool IsStruct,
3330b57cec5SDimitry Andric                        uint32_t &TypeId);
3340b57cec5SDimitry Andric   void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);
3350b57cec5SDimitry Andric   void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);
3360b57cec5SDimitry Andric   void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
3370b57cec5SDimitry Andric                         bool CheckPointer, bool SeenPointer);
3380b57cec5SDimitry Andric   void visitMapDefType(const DIType *Ty, uint32_t &TypeId);
3390b57cec5SDimitry Andric   /// @}
3400b57cec5SDimitry Andric 
3411ac55f4cSDimitry Andric   /// Check whether the type is a forward declaration candidate or not.
3421ac55f4cSDimitry Andric   bool IsForwardDeclCandidate(const DIType *Base);
3431ac55f4cSDimitry Andric 
3440b57cec5SDimitry Andric   /// Get the file content for the subprogram. Certain lines of the file
3450b57cec5SDimitry Andric   /// later may be put into string table and referenced by line info.
346*0fca6ea1SDimitry Andric   std::string populateFileContent(const DIFile *File);
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   /// Construct a line info.
349*0fca6ea1SDimitry Andric   void constructLineInfo(MCSymbol *Label, const DIFile *File, uint32_t Line,
3500b57cec5SDimitry Andric                          uint32_t Column);
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   /// Generate types and variables for globals.
3530b57cec5SDimitry Andric   void processGlobals(bool ProcessingMapDef);
3540b57cec5SDimitry Andric 
355*0fca6ea1SDimitry Andric   /// Process global variable initializer in pursuit for function
356*0fca6ea1SDimitry Andric   /// pointers.
357*0fca6ea1SDimitry Andric   void processGlobalInitializer(const Constant *C);
358*0fca6ea1SDimitry Andric 
359480093f4SDimitry Andric   /// Generate types for function prototypes.
360480093f4SDimitry Andric   void processFuncPrototypes(const Function *);
361480093f4SDimitry Andric 
362349cc55cSDimitry Andric   /// Generate types for decl annotations.
363349cc55cSDimitry Andric   void processDeclAnnotations(DINodeArray Annotations, uint32_t BaseTypeId,
364349cc55cSDimitry Andric                               int ComponentId);
365349cc55cSDimitry Andric 
366bdd1243dSDimitry Andric   /// Generate types for DISubprogram and it's arguments.
367bdd1243dSDimitry Andric   uint32_t processDISubprogram(const DISubprogram *SP, uint32_t ProtoTypeId,
368bdd1243dSDimitry Andric                                uint8_t Scope);
369bdd1243dSDimitry Andric 
37081ad6265SDimitry Andric   /// Generate BTF type_tag's. If BaseTypeId is nonnegative, the last
37181ad6265SDimitry Andric   /// BTF type_tag in the chain points to BaseTypeId. Otherwise, it points to
37281ad6265SDimitry Andric   /// the base type of DTy. Return the type id of the first BTF type_tag
37381ad6265SDimitry Andric   /// in the chain. If no type_tag's are generated, a negative value
37481ad6265SDimitry Andric   /// is returned.
37581ad6265SDimitry Andric   int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId);
37681ad6265SDimitry Andric 
377480093f4SDimitry Andric   /// Generate one field relocation record.
3785ffd83dbSDimitry Andric   void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
3795ffd83dbSDimitry Andric                              const GlobalVariable *, bool IsAma);
3800b57cec5SDimitry Andric 
3815ffd83dbSDimitry Andric   /// Populating unprocessed type on demand.
3825ffd83dbSDimitry Andric   unsigned populateType(const DIType *Ty);
3830b57cec5SDimitry Andric 
384fe6060f1SDimitry Andric   /// Process global variables referenced by relocation instructions
385fe6060f1SDimitry Andric   /// and extern function references.
386fe6060f1SDimitry Andric   void processGlobalValue(const MachineOperand &MO);
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   /// Emit common header of .BTF and .BTF.ext sections.
3890b57cec5SDimitry Andric   void emitCommonHeader();
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   /// Emit the .BTF section.
3920b57cec5SDimitry Andric   void emitBTFSection();
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric   /// Emit the .BTF.ext section.
3950b57cec5SDimitry Andric   void emitBTFExtSection();
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric protected:
3980b57cec5SDimitry Andric   /// Gather pre-function debug information.
3990b57cec5SDimitry Andric   void beginFunctionImpl(const MachineFunction *MF) override;
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   /// Post process after all instructions in this function are processed.
4020b57cec5SDimitry Andric   void endFunctionImpl(const MachineFunction *MF) override;
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric public:
4050b57cec5SDimitry Andric   BTFDebug(AsmPrinter *AP);
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric   ///
4080b57cec5SDimitry Andric   bool InstLower(const MachineInstr *MI, MCInst &OutMI);
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric   /// Get the special array index type id.
getArrayIndexTypeId()4110b57cec5SDimitry Andric   uint32_t getArrayIndexTypeId() {
4120b57cec5SDimitry Andric     assert(ArrayIndexTypeId);
4130b57cec5SDimitry Andric     return ArrayIndexTypeId;
4140b57cec5SDimitry Andric   }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   /// Add string to the string table.
addString(StringRef S)4170b57cec5SDimitry Andric   size_t addString(StringRef S) { return StringTable.addString(S); }
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   /// Get the type id for a particular DIType.
getTypeId(const DIType * Ty)4200b57cec5SDimitry Andric   uint32_t getTypeId(const DIType *Ty) {
4210b57cec5SDimitry Andric     assert(Ty && "Invalid null Type");
4220b57cec5SDimitry Andric     assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&
4230b57cec5SDimitry Andric            "DIType not added in the BDIToIdMap");
4240b57cec5SDimitry Andric     return DIToIdMap[Ty];
4250b57cec5SDimitry Andric   }
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   /// Process beginning of an instruction.
4280b57cec5SDimitry Andric   void beginInstruction(const MachineInstr *MI) override;
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   /// Complete all the types and emit the BTF sections.
4310b57cec5SDimitry Andric   void endModule() override;
4320b57cec5SDimitry Andric };
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric } // end namespace llvm
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric #endif
437