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