1343171Sdim//===- BTFDebug.h -----------------------------------------------*- C++ -*-===// 2343171Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343171Sdim// 7343171Sdim//===----------------------------------------------------------------------===// 8343171Sdim/// 9343171Sdim/// \file 10343171Sdim/// This file contains support for writing BTF debug info. 11343171Sdim/// 12343171Sdim//===----------------------------------------------------------------------===// 13343171Sdim 14343171Sdim#ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H 15343171Sdim#define LLVM_LIB_TARGET_BPF_BTFDEBUG_H 16343171Sdim 17343171Sdim#include "llvm/ADT/StringMap.h" 18343171Sdim#include "llvm/CodeGen/DebugHandlerBase.h" 19360784Sdim#include <set> 20343171Sdim#include <unordered_map> 21343171Sdim#include "BTF.h" 22343171Sdim 23343171Sdimnamespace llvm { 24343171Sdim 25343171Sdimclass AsmPrinter; 26343171Sdimclass BTFDebug; 27343171Sdimclass DIType; 28343171Sdimclass MCStreamer; 29343171Sdimclass MCSymbol; 30343171Sdimclass MachineFunction; 31343171Sdim 32343171Sdim/// The base class for BTF type generation. 33343171Sdimclass BTFTypeBase { 34343171Sdimprotected: 35343171Sdim uint8_t Kind; 36353358Sdim bool IsCompleted; 37343171Sdim uint32_t Id; 38343171Sdim struct BTF::CommonType BTFType; 39343171Sdim 40343171Sdimpublic: 41353358Sdim BTFTypeBase() : IsCompleted(false) {} 42343171Sdim virtual ~BTFTypeBase() = default; 43343171Sdim void setId(uint32_t Id) { this->Id = Id; } 44343171Sdim uint32_t getId() { return Id; } 45343171Sdim uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; } 46343171Sdim /// Get the size of this BTF type entry. 47343171Sdim virtual uint32_t getSize() { return BTF::CommonTypeSize; } 48343171Sdim /// Complete BTF type generation after all related DebugInfo types 49343171Sdim /// have been visited so their BTF type id's are available 50343171Sdim /// for cross referece. 51343171Sdim virtual void completeType(BTFDebug &BDebug) {} 52343171Sdim /// Emit types for this BTF type entry. 53343171Sdim virtual void emitType(MCStreamer &OS); 54343171Sdim}; 55343171Sdim 56343171Sdim/// Handle several derived types include pointer, const, 57343171Sdim/// volatile, typedef and restrict. 58343171Sdimclass BTFTypeDerived : public BTFTypeBase { 59343171Sdim const DIDerivedType *DTy; 60353358Sdim bool NeedsFixup; 61343171Sdim 62343171Sdimpublic: 63353358Sdim BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup); 64343171Sdim void completeType(BTFDebug &BDebug); 65343171Sdim void emitType(MCStreamer &OS); 66353358Sdim void setPointeeType(uint32_t PointeeType); 67343171Sdim}; 68343171Sdim 69343171Sdim/// Handle struct or union forward declaration. 70343171Sdimclass BTFTypeFwd : public BTFTypeBase { 71343171Sdim StringRef Name; 72343171Sdim 73343171Sdimpublic: 74343171Sdim BTFTypeFwd(StringRef Name, bool IsUnion); 75343171Sdim void completeType(BTFDebug &BDebug); 76343171Sdim void emitType(MCStreamer &OS); 77343171Sdim}; 78343171Sdim 79343171Sdim/// Handle int type. 80343171Sdimclass BTFTypeInt : public BTFTypeBase { 81343171Sdim StringRef Name; 82343171Sdim uint32_t IntVal; ///< Encoding, offset, bits 83343171Sdim 84343171Sdimpublic: 85343171Sdim BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, 86343171Sdim StringRef TypeName); 87343171Sdim uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); } 88343171Sdim void completeType(BTFDebug &BDebug); 89343171Sdim void emitType(MCStreamer &OS); 90343171Sdim}; 91343171Sdim 92343171Sdim/// Handle enumerate type. 93343171Sdimclass BTFTypeEnum : public BTFTypeBase { 94343171Sdim const DICompositeType *ETy; 95343171Sdim std::vector<struct BTF::BTFEnum> EnumValues; 96343171Sdim 97343171Sdimpublic: 98343171Sdim BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues); 99343171Sdim uint32_t getSize() { 100343171Sdim return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize; 101343171Sdim } 102343171Sdim void completeType(BTFDebug &BDebug); 103343171Sdim void emitType(MCStreamer &OS); 104343171Sdim}; 105343171Sdim 106343171Sdim/// Handle array type. 107343171Sdimclass BTFTypeArray : public BTFTypeBase { 108343171Sdim struct BTF::BTFArray ArrayInfo; 109343171Sdim 110343171Sdimpublic: 111360784Sdim BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems); 112343171Sdim uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; } 113343171Sdim void completeType(BTFDebug &BDebug); 114343171Sdim void emitType(MCStreamer &OS); 115343171Sdim}; 116343171Sdim 117343171Sdim/// Handle struct/union type. 118343171Sdimclass BTFTypeStruct : public BTFTypeBase { 119343171Sdim const DICompositeType *STy; 120343171Sdim bool HasBitField; 121343171Sdim std::vector<struct BTF::BTFMember> Members; 122343171Sdim 123343171Sdimpublic: 124343171Sdim BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, 125343171Sdim uint32_t NumMembers); 126343171Sdim uint32_t getSize() { 127343171Sdim return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize; 128343171Sdim } 129343171Sdim void completeType(BTFDebug &BDebug); 130343171Sdim void emitType(MCStreamer &OS); 131353358Sdim std::string getName(); 132343171Sdim}; 133343171Sdim 134343171Sdim/// Handle function pointer. 135343171Sdimclass BTFTypeFuncProto : public BTFTypeBase { 136343171Sdim const DISubroutineType *STy; 137343171Sdim std::unordered_map<uint32_t, StringRef> FuncArgNames; 138343171Sdim std::vector<struct BTF::BTFParam> Parameters; 139343171Sdim 140343171Sdimpublic: 141343171Sdim BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, 142343171Sdim const std::unordered_map<uint32_t, StringRef> &FuncArgNames); 143343171Sdim uint32_t getSize() { 144343171Sdim return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize; 145343171Sdim } 146343171Sdim void completeType(BTFDebug &BDebug); 147343171Sdim void emitType(MCStreamer &OS); 148343171Sdim}; 149343171Sdim 150343171Sdim/// Handle subprogram 151343171Sdimclass BTFTypeFunc : public BTFTypeBase { 152343171Sdim StringRef Name; 153343171Sdim 154343171Sdimpublic: 155360784Sdim BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope); 156343171Sdim uint32_t getSize() { return BTFTypeBase::getSize(); } 157343171Sdim void completeType(BTFDebug &BDebug); 158343171Sdim void emitType(MCStreamer &OS); 159343171Sdim}; 160343171Sdim 161353358Sdim/// Handle variable instances 162353358Sdimclass BTFKindVar : public BTFTypeBase { 163353358Sdim StringRef Name; 164353358Sdim uint32_t Info; 165353358Sdim 166353358Sdimpublic: 167353358Sdim BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo); 168353358Sdim uint32_t getSize() { return BTFTypeBase::getSize() + 4; } 169353358Sdim void completeType(BTFDebug &BDebug); 170353358Sdim void emitType(MCStreamer &OS); 171353358Sdim}; 172353358Sdim 173353358Sdim/// Handle data sections 174353358Sdimclass BTFKindDataSec : public BTFTypeBase { 175353358Sdim AsmPrinter *Asm; 176353358Sdim std::string Name; 177353358Sdim std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars; 178353358Sdim 179353358Sdimpublic: 180353358Sdim BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName); 181353358Sdim uint32_t getSize() { 182353358Sdim return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size(); 183353358Sdim } 184353358Sdim void addVar(uint32_t Id, const MCSymbol *Sym, uint32_t Size) { 185353358Sdim Vars.push_back(std::make_tuple(Id, Sym, Size)); 186353358Sdim } 187353358Sdim std::string getName() { return Name; } 188353358Sdim void completeType(BTFDebug &BDebug); 189353358Sdim void emitType(MCStreamer &OS); 190353358Sdim}; 191353358Sdim 192343171Sdim/// String table. 193343171Sdimclass BTFStringTable { 194343171Sdim /// String table size in bytes. 195343171Sdim uint32_t Size; 196343171Sdim /// A mapping from string table offset to the index 197343171Sdim /// of the Table. It is used to avoid putting 198343171Sdim /// duplicated strings in the table. 199360784Sdim std::map<uint32_t, uint32_t> OffsetToIdMap; 200343171Sdim /// A vector of strings to represent the string table. 201343171Sdim std::vector<std::string> Table; 202343171Sdim 203343171Sdimpublic: 204343171Sdim BTFStringTable() : Size(0) {} 205343171Sdim uint32_t getSize() { return Size; } 206343171Sdim std::vector<std::string> &getTable() { return Table; } 207343171Sdim /// Add a string to the string table and returns its offset 208343171Sdim /// in the table. 209343171Sdim uint32_t addString(StringRef S); 210343171Sdim}; 211343171Sdim 212343171Sdim/// Represent one func and its type id. 213343171Sdimstruct BTFFuncInfo { 214343171Sdim const MCSymbol *Label; ///< Func MCSymbol 215343171Sdim uint32_t TypeId; ///< Type id referring to .BTF type section 216343171Sdim}; 217343171Sdim 218343171Sdim/// Represent one line info. 219343171Sdimstruct BTFLineInfo { 220343171Sdim MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo 221343171Sdim uint32_t FileNameOff; ///< file name offset in the .BTF string table 222343171Sdim uint32_t LineOff; ///< line offset in the .BTF string table 223343171Sdim uint32_t LineNum; ///< the line number 224343171Sdim uint32_t ColumnNum; ///< the column number 225343171Sdim}; 226343171Sdim 227360784Sdim/// Represent one field relocation. 228360784Sdimstruct BTFFieldReloc { 229353358Sdim const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc 230353358Sdim uint32_t TypeID; ///< Type ID 231353358Sdim uint32_t OffsetNameOff; ///< The string to traverse types 232360784Sdim uint32_t RelocKind; ///< What to patch the instruction 233353358Sdim}; 234353358Sdim 235343171Sdim/// Collect and emit BTF information. 236343171Sdimclass BTFDebug : public DebugHandlerBase { 237343171Sdim MCStreamer &OS; 238343171Sdim bool SkipInstruction; 239343171Sdim bool LineInfoGenerated; 240343171Sdim uint32_t SecNameOff; 241343171Sdim uint32_t ArrayIndexTypeId; 242353358Sdim bool MapDefNotCollected; 243343171Sdim BTFStringTable StringTable; 244343171Sdim std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries; 245343171Sdim std::unordered_map<const DIType *, uint32_t> DIToIdMap; 246353358Sdim std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable; 247353358Sdim std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable; 248360784Sdim std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable; 249343171Sdim StringMap<std::vector<std::string>> FileContent; 250353358Sdim std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries; 251353358Sdim std::vector<BTFTypeStruct *> StructTypes; 252360784Sdim std::map<std::string, uint32_t> PatchImms; 253353358Sdim std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>> 254353358Sdim FixupDerivedTypes; 255360784Sdim std::set<const Function *>ProtoFunctions; 256343171Sdim 257343171Sdim /// Add types to TypeEntries. 258343171Sdim /// @{ 259343171Sdim /// Add types to TypeEntries and DIToIdMap. 260353358Sdim uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty); 261343171Sdim /// Add types to TypeEntries only and return type id. 262343171Sdim uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry); 263343171Sdim /// @} 264343171Sdim 265343171Sdim /// IR type visiting functions. 266343171Sdim /// @{ 267343171Sdim void visitTypeEntry(const DIType *Ty); 268353358Sdim void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer, 269353358Sdim bool SeenPointer); 270353358Sdim void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId); 271343171Sdim void visitSubroutineType( 272343171Sdim const DISubroutineType *STy, bool ForSubprog, 273343171Sdim const std::unordered_map<uint32_t, StringRef> &FuncArgNames, 274343171Sdim uint32_t &TypeId); 275353358Sdim void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion, 276353358Sdim uint32_t &TypeId); 277353358Sdim void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId); 278353358Sdim void visitStructType(const DICompositeType *STy, bool IsStruct, 279353358Sdim uint32_t &TypeId); 280353358Sdim void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId); 281353358Sdim void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId); 282353358Sdim void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, 283353358Sdim bool CheckPointer, bool SeenPointer); 284353358Sdim void visitMapDefType(const DIType *Ty, uint32_t &TypeId); 285343171Sdim /// @} 286343171Sdim 287343171Sdim /// Get the file content for the subprogram. Certain lines of the file 288343171Sdim /// later may be put into string table and referenced by line info. 289343171Sdim std::string populateFileContent(const DISubprogram *SP); 290343171Sdim 291343171Sdim /// Construct a line info. 292343171Sdim void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line, 293343171Sdim uint32_t Column); 294343171Sdim 295353358Sdim /// Generate types and variables for globals. 296353358Sdim void processGlobals(bool ProcessingMapDef); 297353358Sdim 298360784Sdim /// Generate types for function prototypes. 299360784Sdim void processFuncPrototypes(const Function *); 300353358Sdim 301360784Sdim /// Generate one field relocation record. 302360784Sdim void generateFieldReloc(const MCSymbol *ORSym, DIType *RootTy, 303360784Sdim StringRef AccessPattern); 304353358Sdim 305353358Sdim /// Populating unprocessed struct type. 306353358Sdim unsigned populateStructType(const DIType *Ty); 307353358Sdim 308360784Sdim /// Process relocation instructions. 309360784Sdim void processReloc(const MachineOperand &MO); 310353358Sdim 311343171Sdim /// Emit common header of .BTF and .BTF.ext sections. 312343171Sdim void emitCommonHeader(); 313343171Sdim 314343171Sdim /// Emit the .BTF section. 315343171Sdim void emitBTFSection(); 316343171Sdim 317343171Sdim /// Emit the .BTF.ext section. 318343171Sdim void emitBTFExtSection(); 319343171Sdim 320343171Sdimprotected: 321343171Sdim /// Gather pre-function debug information. 322343171Sdim void beginFunctionImpl(const MachineFunction *MF) override; 323343171Sdim 324343171Sdim /// Post process after all instructions in this function are processed. 325343171Sdim void endFunctionImpl(const MachineFunction *MF) override; 326343171Sdim 327343171Sdimpublic: 328343171Sdim BTFDebug(AsmPrinter *AP); 329343171Sdim 330353358Sdim /// 331353358Sdim bool InstLower(const MachineInstr *MI, MCInst &OutMI); 332353358Sdim 333343171Sdim /// Get the special array index type id. 334343171Sdim uint32_t getArrayIndexTypeId() { 335343171Sdim assert(ArrayIndexTypeId); 336343171Sdim return ArrayIndexTypeId; 337343171Sdim } 338343171Sdim 339343171Sdim /// Add string to the string table. 340343171Sdim size_t addString(StringRef S) { return StringTable.addString(S); } 341343171Sdim 342343171Sdim /// Get the type id for a particular DIType. 343343171Sdim uint32_t getTypeId(const DIType *Ty) { 344343171Sdim assert(Ty && "Invalid null Type"); 345343171Sdim assert(DIToIdMap.find(Ty) != DIToIdMap.end() && 346343171Sdim "DIType not added in the BDIToIdMap"); 347343171Sdim return DIToIdMap[Ty]; 348343171Sdim } 349343171Sdim 350343171Sdim void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {} 351343171Sdim 352343171Sdim /// Process beginning of an instruction. 353343171Sdim void beginInstruction(const MachineInstr *MI) override; 354343171Sdim 355343171Sdim /// Complete all the types and emit the BTF sections. 356343171Sdim void endModule() override; 357343171Sdim}; 358343171Sdim 359343171Sdim} // end namespace llvm 360343171Sdim 361343171Sdim#endif 362