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