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