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 /// String table. 208 class BTFStringTable { 209 /// String table size in bytes. 210 uint32_t Size; 211 /// A mapping from string table offset to the index 212 /// of the Table. It is used to avoid putting 213 /// duplicated strings in the table. 214 std::map<uint32_t, uint32_t> OffsetToIdMap; 215 /// A vector of strings to represent the string table. 216 std::vector<std::string> Table; 217 218 public: 219 BTFStringTable() : Size(0) {} 220 uint32_t getSize() { return Size; } 221 std::vector<std::string> &getTable() { return Table; } 222 /// Add a string to the string table and returns its offset 223 /// in the table. 224 uint32_t addString(StringRef S); 225 }; 226 227 /// Represent one func and its type id. 228 struct BTFFuncInfo { 229 const MCSymbol *Label; ///< Func MCSymbol 230 uint32_t TypeId; ///< Type id referring to .BTF type section 231 }; 232 233 /// Represent one line info. 234 struct BTFLineInfo { 235 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo 236 uint32_t FileNameOff; ///< file name offset in the .BTF string table 237 uint32_t LineOff; ///< line offset in the .BTF string table 238 uint32_t LineNum; ///< the line number 239 uint32_t ColumnNum; ///< the column number 240 }; 241 242 /// Represent one field relocation. 243 struct BTFFieldReloc { 244 const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc 245 uint32_t TypeID; ///< Type ID 246 uint32_t OffsetNameOff; ///< The string to traverse types 247 uint32_t RelocKind; ///< What to patch the instruction 248 }; 249 250 /// Collect and emit BTF information. 251 class BTFDebug : public DebugHandlerBase { 252 MCStreamer &OS; 253 bool SkipInstruction; 254 bool LineInfoGenerated; 255 uint32_t SecNameOff; 256 uint32_t ArrayIndexTypeId; 257 bool MapDefNotCollected; 258 BTFStringTable StringTable; 259 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries; 260 std::unordered_map<const DIType *, uint32_t> DIToIdMap; 261 std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable; 262 std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable; 263 std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable; 264 StringMap<std::vector<std::string>> FileContent; 265 std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries; 266 std::vector<BTFTypeStruct *> StructTypes; 267 std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms; 268 std::map<StringRef, std::pair<bool, std::vector<BTFTypeDerived *>>> 269 FixupDerivedTypes; 270 std::set<const Function *>ProtoFunctions; 271 272 /// Add types to TypeEntries. 273 /// @{ 274 /// Add types to TypeEntries and DIToIdMap. 275 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty); 276 /// Add types to TypeEntries only and return type id. 277 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry); 278 /// @} 279 280 /// IR type visiting functions. 281 /// @{ 282 void visitTypeEntry(const DIType *Ty); 283 void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer, 284 bool SeenPointer); 285 void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId); 286 void visitSubroutineType( 287 const DISubroutineType *STy, bool ForSubprog, 288 const std::unordered_map<uint32_t, StringRef> &FuncArgNames, 289 uint32_t &TypeId); 290 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion, 291 uint32_t &TypeId); 292 void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId); 293 void visitStructType(const DICompositeType *STy, bool IsStruct, 294 uint32_t &TypeId); 295 void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId); 296 void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId); 297 void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, 298 bool CheckPointer, bool SeenPointer); 299 void visitMapDefType(const DIType *Ty, uint32_t &TypeId); 300 /// @} 301 302 /// Get the file content for the subprogram. Certain lines of the file 303 /// later may be put into string table and referenced by line info. 304 std::string populateFileContent(const DISubprogram *SP); 305 306 /// Construct a line info. 307 void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line, 308 uint32_t Column); 309 310 /// Generate types and variables for globals. 311 void processGlobals(bool ProcessingMapDef); 312 313 /// Generate types for function prototypes. 314 void processFuncPrototypes(const Function *); 315 316 /// Generate one field relocation record. 317 void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId, 318 const GlobalVariable *, bool IsAma); 319 320 /// Populating unprocessed type on demand. 321 unsigned populateType(const DIType *Ty); 322 323 /// Process global variables referenced by relocation instructions 324 /// and extern function references. 325 void processGlobalValue(const MachineOperand &MO); 326 327 /// Emit common header of .BTF and .BTF.ext sections. 328 void emitCommonHeader(); 329 330 /// Emit the .BTF section. 331 void emitBTFSection(); 332 333 /// Emit the .BTF.ext section. 334 void emitBTFExtSection(); 335 336 protected: 337 /// Gather pre-function debug information. 338 void beginFunctionImpl(const MachineFunction *MF) override; 339 340 /// Post process after all instructions in this function are processed. 341 void endFunctionImpl(const MachineFunction *MF) override; 342 343 public: 344 BTFDebug(AsmPrinter *AP); 345 346 /// 347 bool InstLower(const MachineInstr *MI, MCInst &OutMI); 348 349 /// Get the special array index type id. 350 uint32_t getArrayIndexTypeId() { 351 assert(ArrayIndexTypeId); 352 return ArrayIndexTypeId; 353 } 354 355 /// Add string to the string table. 356 size_t addString(StringRef S) { return StringTable.addString(S); } 357 358 /// Get the type id for a particular DIType. 359 uint32_t getTypeId(const DIType *Ty) { 360 assert(Ty && "Invalid null Type"); 361 assert(DIToIdMap.find(Ty) != DIToIdMap.end() && 362 "DIType not added in the BDIToIdMap"); 363 return DIToIdMap[Ty]; 364 } 365 366 void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {} 367 368 /// Process beginning of an instruction. 369 void beginInstruction(const MachineInstr *MI) override; 370 371 /// Complete all the types and emit the BTF sections. 372 void endModule() override; 373 }; 374 375 } // end namespace llvm 376 377 #endif 378