1 //===- BTFDebug.h -----------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file contains support for writing BTF debug info. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H 15 #define LLVM_LIB_TARGET_BPF_BTFDEBUG_H 16 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/CodeGen/DebugHandlerBase.h" 19 #include <unordered_map> 20 #include "BTF.h" 21 22 namespace llvm { 23 24 class AsmPrinter; 25 class BTFDebug; 26 class DIType; 27 class MCStreamer; 28 class MCSymbol; 29 class MachineFunction; 30 31 /// The base class for BTF type generation. 32 class BTFTypeBase { 33 protected: 34 uint8_t Kind; 35 bool IsCompleted; 36 uint32_t Id; 37 struct BTF::CommonType BTFType; 38 39 public: 40 BTFTypeBase() : IsCompleted(false) {} 41 virtual ~BTFTypeBase() = default; 42 void setId(uint32_t Id) { this->Id = Id; } 43 uint32_t getId() { return Id; } 44 uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; } 45 /// Get the size of this BTF type entry. 46 virtual uint32_t getSize() { return BTF::CommonTypeSize; } 47 /// Complete BTF type generation after all related DebugInfo types 48 /// have been visited so their BTF type id's are available 49 /// for cross referece. 50 virtual void completeType(BTFDebug &BDebug) {} 51 /// Emit types for this BTF type entry. 52 virtual void emitType(MCStreamer &OS); 53 }; 54 55 /// Handle several derived types include pointer, const, 56 /// volatile, typedef and restrict. 57 class BTFTypeDerived : public BTFTypeBase { 58 const DIDerivedType *DTy; 59 bool NeedsFixup; 60 61 public: 62 BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup); 63 void completeType(BTFDebug &BDebug); 64 void emitType(MCStreamer &OS); 65 void setPointeeType(uint32_t PointeeType); 66 }; 67 68 /// Handle struct or union forward declaration. 69 class BTFTypeFwd : public BTFTypeBase { 70 StringRef Name; 71 72 public: 73 BTFTypeFwd(StringRef Name, bool IsUnion); 74 void completeType(BTFDebug &BDebug); 75 void emitType(MCStreamer &OS); 76 }; 77 78 /// Handle int type. 79 class BTFTypeInt : public BTFTypeBase { 80 StringRef Name; 81 uint32_t IntVal; ///< Encoding, offset, bits 82 83 public: 84 BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, 85 StringRef TypeName); 86 uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); } 87 void completeType(BTFDebug &BDebug); 88 void emitType(MCStreamer &OS); 89 }; 90 91 /// Handle enumerate type. 92 class BTFTypeEnum : public BTFTypeBase { 93 const DICompositeType *ETy; 94 std::vector<struct BTF::BTFEnum> EnumValues; 95 96 public: 97 BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues); 98 uint32_t getSize() { 99 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize; 100 } 101 void completeType(BTFDebug &BDebug); 102 void emitType(MCStreamer &OS); 103 }; 104 105 /// Handle array type. 106 class BTFTypeArray : public BTFTypeBase { 107 const DIType *ElemTyNoQual; 108 uint32_t ElemSize; 109 struct BTF::BTFArray ArrayInfo; 110 uint32_t ElemTypeNoQual; 111 112 public: 113 BTFTypeArray(const DIType *Ty, uint32_t ElemTypeId, 114 uint32_t ElemSize, uint32_t NumElems); 115 uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; } 116 void completeType(BTFDebug &BDebug); 117 void emitType(MCStreamer &OS); 118 void getLocInfo(uint32_t Loc, uint32_t &LocOffset, uint32_t &ElementTypeId); 119 }; 120 121 /// Handle struct/union type. 122 class BTFTypeStruct : public BTFTypeBase { 123 const DICompositeType *STy; 124 bool HasBitField; 125 std::vector<struct BTF::BTFMember> Members; 126 std::vector<uint32_t> MemberTypeNoQual; 127 128 public: 129 BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, 130 uint32_t NumMembers); 131 uint32_t getSize() { 132 return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize; 133 } 134 void completeType(BTFDebug &BDebug); 135 void emitType(MCStreamer &OS); 136 std::string getName(); 137 void getMemberInfo(uint32_t Loc, uint32_t &Offset, uint32_t &MemberType); 138 uint32_t getStructSize(); 139 }; 140 141 /// Handle function pointer. 142 class BTFTypeFuncProto : public BTFTypeBase { 143 const DISubroutineType *STy; 144 std::unordered_map<uint32_t, StringRef> FuncArgNames; 145 std::vector<struct BTF::BTFParam> Parameters; 146 147 public: 148 BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, 149 const std::unordered_map<uint32_t, StringRef> &FuncArgNames); 150 uint32_t getSize() { 151 return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize; 152 } 153 void completeType(BTFDebug &BDebug); 154 void emitType(MCStreamer &OS); 155 }; 156 157 /// Handle subprogram 158 class BTFTypeFunc : public BTFTypeBase { 159 StringRef Name; 160 161 public: 162 BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId); 163 uint32_t getSize() { return BTFTypeBase::getSize(); } 164 void completeType(BTFDebug &BDebug); 165 void emitType(MCStreamer &OS); 166 }; 167 168 /// Handle variable instances 169 class BTFKindVar : public BTFTypeBase { 170 StringRef Name; 171 uint32_t Info; 172 173 public: 174 BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo); 175 uint32_t getSize() { return BTFTypeBase::getSize() + 4; } 176 void completeType(BTFDebug &BDebug); 177 void emitType(MCStreamer &OS); 178 }; 179 180 /// Handle data sections 181 class BTFKindDataSec : public BTFTypeBase { 182 AsmPrinter *Asm; 183 std::string Name; 184 std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars; 185 186 public: 187 BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName); 188 uint32_t getSize() { 189 return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size(); 190 } 191 void addVar(uint32_t Id, const MCSymbol *Sym, uint32_t Size) { 192 Vars.push_back(std::make_tuple(Id, Sym, Size)); 193 } 194 std::string getName() { return Name; } 195 void completeType(BTFDebug &BDebug); 196 void emitType(MCStreamer &OS); 197 }; 198 199 /// String table. 200 class BTFStringTable { 201 /// String table size in bytes. 202 uint32_t Size; 203 /// A mapping from string table offset to the index 204 /// of the Table. It is used to avoid putting 205 /// duplicated strings in the table. 206 std::unordered_map<uint32_t, uint32_t> OffsetToIdMap; 207 /// A vector of strings to represent the string table. 208 std::vector<std::string> Table; 209 210 public: 211 BTFStringTable() : Size(0) {} 212 uint32_t getSize() { return Size; } 213 std::vector<std::string> &getTable() { return Table; } 214 /// Add a string to the string table and returns its offset 215 /// in the table. 216 uint32_t addString(StringRef S); 217 }; 218 219 /// Represent one func and its type id. 220 struct BTFFuncInfo { 221 const MCSymbol *Label; ///< Func MCSymbol 222 uint32_t TypeId; ///< Type id referring to .BTF type section 223 }; 224 225 /// Represent one line info. 226 struct BTFLineInfo { 227 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo 228 uint32_t FileNameOff; ///< file name offset in the .BTF string table 229 uint32_t LineOff; ///< line offset in the .BTF string table 230 uint32_t LineNum; ///< the line number 231 uint32_t ColumnNum; ///< the column number 232 }; 233 234 /// Represent one offset relocation. 235 struct BTFOffsetReloc { 236 const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc 237 uint32_t TypeID; ///< Type ID 238 uint32_t OffsetNameOff; ///< The string to traverse types 239 }; 240 241 /// Represent one extern relocation. 242 struct BTFExternReloc { 243 const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc 244 uint32_t ExternNameOff; ///< The extern variable name 245 }; 246 247 /// Collect and emit BTF information. 248 class BTFDebug : public DebugHandlerBase { 249 MCStreamer &OS; 250 bool SkipInstruction; 251 bool LineInfoGenerated; 252 uint32_t SecNameOff; 253 uint32_t ArrayIndexTypeId; 254 bool MapDefNotCollected; 255 BTFStringTable StringTable; 256 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries; 257 std::unordered_map<const DIType *, uint32_t> DIToIdMap; 258 std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable; 259 std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable; 260 std::map<uint32_t, std::vector<BTFOffsetReloc>> OffsetRelocTable; 261 std::map<uint32_t, std::vector<BTFExternReloc>> ExternRelocTable; 262 StringMap<std::vector<std::string>> FileContent; 263 std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries; 264 std::vector<BTFTypeStruct *> StructTypes; 265 std::vector<BTFTypeArray *> ArrayTypes; 266 std::map<std::string, int64_t> AccessOffsets; 267 std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>> 268 FixupDerivedTypes; 269 270 /// Add types to TypeEntries. 271 /// @{ 272 /// Add types to TypeEntries and DIToIdMap. 273 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty); 274 /// Add types to TypeEntries only and return type id. 275 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry); 276 /// @} 277 278 /// IR type visiting functions. 279 /// @{ 280 void visitTypeEntry(const DIType *Ty); 281 void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer, 282 bool SeenPointer); 283 void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId); 284 void visitSubroutineType( 285 const DISubroutineType *STy, bool ForSubprog, 286 const std::unordered_map<uint32_t, StringRef> &FuncArgNames, 287 uint32_t &TypeId); 288 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion, 289 uint32_t &TypeId); 290 void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId); 291 void visitStructType(const DICompositeType *STy, bool IsStruct, 292 uint32_t &TypeId); 293 void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId); 294 void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId); 295 void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, 296 bool CheckPointer, bool SeenPointer); 297 void visitMapDefType(const DIType *Ty, uint32_t &TypeId); 298 /// @} 299 300 /// Get the file content for the subprogram. Certain lines of the file 301 /// later may be put into string table and referenced by line info. 302 std::string populateFileContent(const DISubprogram *SP); 303 304 /// Construct a line info. 305 void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line, 306 uint32_t Column); 307 308 /// Generate types and variables for globals. 309 void processGlobals(bool ProcessingMapDef); 310 311 /// Generate one offset relocation record. 312 void generateOffsetReloc(const MachineInstr *MI, const MCSymbol *ORSym, 313 DIType *RootTy, StringRef AccessPattern); 314 315 /// Set the to-be-traversed Struct/Array Type based on TypeId. 316 void setTypeFromId(uint32_t TypeId, BTFTypeStruct **PrevStructType, 317 BTFTypeArray **PrevArrayType); 318 319 /// Populating unprocessed struct type. 320 unsigned populateStructType(const DIType *Ty); 321 322 /// Process LD_imm64 instructions. 323 void processLDimm64(const MachineInstr *MI); 324 325 /// Emit common header of .BTF and .BTF.ext sections. 326 void emitCommonHeader(); 327 328 /// Emit the .BTF section. 329 void emitBTFSection(); 330 331 /// Emit the .BTF.ext section. 332 void emitBTFExtSection(); 333 334 protected: 335 /// Gather pre-function debug information. 336 void beginFunctionImpl(const MachineFunction *MF) override; 337 338 /// Post process after all instructions in this function are processed. 339 void endFunctionImpl(const MachineFunction *MF) override; 340 341 public: 342 BTFDebug(AsmPrinter *AP); 343 344 /// 345 bool InstLower(const MachineInstr *MI, MCInst &OutMI); 346 347 /// Get the special array index type id. 348 uint32_t getArrayIndexTypeId() { 349 assert(ArrayIndexTypeId); 350 return ArrayIndexTypeId; 351 } 352 353 /// Add string to the string table. 354 size_t addString(StringRef S) { return StringTable.addString(S); } 355 356 /// Get the type id for a particular DIType. 357 uint32_t getTypeId(const DIType *Ty) { 358 assert(Ty && "Invalid null Type"); 359 assert(DIToIdMap.find(Ty) != DIToIdMap.end() && 360 "DIType not added in the BDIToIdMap"); 361 return DIToIdMap[Ty]; 362 } 363 364 void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {} 365 366 /// Process beginning of an instruction. 367 void beginInstruction(const MachineInstr *MI) override; 368 369 /// Complete all the types and emit the BTF sections. 370 void endModule() override; 371 }; 372 373 } // end namespace llvm 374 375 #endif 376