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