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