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