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/DebugInfo/BTF/BTF.h" 20 #include <cstdint> 21 #include <map> 22 #include <set> 23 #include <unordered_map> 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: BTFTypeBase()47 BTFTypeBase() : IsCompleted(false) {} 48 virtual ~BTFTypeBase() = default; setId(uint32_t Id)49 void setId(uint32_t Id) { this->Id = Id; } getId()50 uint32_t getId() { return Id; } roundupToBytes(uint32_t NumBits)51 uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; } 52 /// Get the size of this BTF type entry. getSize()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. completeType(BTFDebug & BDebug)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 StringRef Name; 68 69 public: 70 BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup); 71 BTFTypeDerived(unsigned NextTypeId, unsigned Tag, StringRef Name); 72 void completeType(BTFDebug &BDebug) override; 73 void emitType(MCStreamer &OS) override; 74 void setPointeeType(uint32_t PointeeType); 75 }; 76 77 /// Handle struct or union forward declaration. 78 class BTFTypeFwd : public BTFTypeBase { 79 StringRef Name; 80 81 public: 82 BTFTypeFwd(StringRef Name, bool IsUnion); 83 void completeType(BTFDebug &BDebug) override; 84 void emitType(MCStreamer &OS) override; 85 }; 86 87 /// Handle int type. 88 class BTFTypeInt : public BTFTypeBase { 89 StringRef Name; 90 uint32_t IntVal; ///< Encoding, offset, bits 91 92 public: 93 BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, 94 StringRef TypeName); getSize()95 uint32_t getSize() override { return BTFTypeBase::getSize() + sizeof(uint32_t); } 96 void completeType(BTFDebug &BDebug) override; 97 void emitType(MCStreamer &OS) override; 98 }; 99 100 /// Handle enumerate type. 101 class BTFTypeEnum : public BTFTypeBase { 102 const DICompositeType *ETy; 103 std::vector<struct BTF::BTFEnum> EnumValues; 104 105 public: 106 BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned); getSize()107 uint32_t getSize() override { 108 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize; 109 } 110 void completeType(BTFDebug &BDebug) override; 111 void emitType(MCStreamer &OS) override; 112 }; 113 114 /// Handle array type. 115 class BTFTypeArray : public BTFTypeBase { 116 struct BTF::BTFArray ArrayInfo; 117 118 public: 119 BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems); getSize()120 uint32_t getSize() override { return BTFTypeBase::getSize() + BTF::BTFArraySize; } 121 void completeType(BTFDebug &BDebug) override; 122 void emitType(MCStreamer &OS) override; 123 }; 124 125 /// Handle struct/union type. 126 class BTFTypeStruct : public BTFTypeBase { 127 const DICompositeType *STy; 128 bool HasBitField; 129 std::vector<struct BTF::BTFMember> Members; 130 131 public: 132 BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, 133 uint32_t NumMembers); getSize()134 uint32_t getSize() override { 135 return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize; 136 } 137 void completeType(BTFDebug &BDebug) override; 138 void emitType(MCStreamer &OS) override; 139 std::string getName(); 140 }; 141 142 /// Handle function pointer. 143 class BTFTypeFuncProto : public BTFTypeBase { 144 const DISubroutineType *STy; 145 std::unordered_map<uint32_t, StringRef> FuncArgNames; 146 std::vector<struct BTF::BTFParam> Parameters; 147 148 public: 149 BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, 150 const std::unordered_map<uint32_t, StringRef> &FuncArgNames); getSize()151 uint32_t getSize() override { 152 return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize; 153 } 154 void completeType(BTFDebug &BDebug) override; 155 void emitType(MCStreamer &OS) override; 156 }; 157 158 /// Handle subprogram 159 class BTFTypeFunc : public BTFTypeBase { 160 StringRef Name; 161 162 public: 163 BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope); getSize()164 uint32_t getSize() override { return BTFTypeBase::getSize(); } 165 void completeType(BTFDebug &BDebug) override; 166 void emitType(MCStreamer &OS) override; 167 }; 168 169 /// Handle variable instances 170 class BTFKindVar : public BTFTypeBase { 171 StringRef Name; 172 uint32_t Info; 173 174 public: 175 BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo); getSize()176 uint32_t getSize() override { return BTFTypeBase::getSize() + 4; } 177 void completeType(BTFDebug &BDebug) override; 178 void emitType(MCStreamer &OS) override; 179 }; 180 181 /// Handle data sections 182 class BTFKindDataSec : public BTFTypeBase { 183 AsmPrinter *Asm; 184 std::string Name; 185 std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars; 186 187 public: 188 BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName); getSize()189 uint32_t getSize() override { 190 return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size(); 191 } addDataSecEntry(uint32_t Id,const MCSymbol * Sym,uint32_t Size)192 void addDataSecEntry(uint32_t Id, const MCSymbol *Sym, uint32_t Size) { 193 Vars.push_back(std::make_tuple(Id, Sym, Size)); 194 } getName()195 std::string getName() { return Name; } 196 void completeType(BTFDebug &BDebug) override; 197 void emitType(MCStreamer &OS) override; 198 }; 199 200 /// Handle binary floating point type. 201 class BTFTypeFloat : public BTFTypeBase { 202 StringRef Name; 203 204 public: 205 BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName); 206 void completeType(BTFDebug &BDebug) override; 207 }; 208 209 /// Handle decl tags. 210 class BTFTypeDeclTag : public BTFTypeBase { 211 uint32_t Info; 212 StringRef Tag; 213 214 public: 215 BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag); getSize()216 uint32_t getSize() override { return BTFTypeBase::getSize() + 4; } 217 void completeType(BTFDebug &BDebug) override; 218 void emitType(MCStreamer &OS) override; 219 }; 220 221 /// Handle 64-bit enumerate type. 222 class BTFTypeEnum64 : public BTFTypeBase { 223 const DICompositeType *ETy; 224 std::vector<struct BTF::BTFEnum64> EnumValues; 225 226 public: 227 BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned); getSize()228 uint32_t getSize() override { 229 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnum64Size; 230 } 231 void completeType(BTFDebug &BDebug) override; 232 void emitType(MCStreamer &OS) override; 233 }; 234 235 class BTFTypeTypeTag : public BTFTypeBase { 236 const DIDerivedType *DTy; 237 StringRef Tag; 238 239 public: 240 BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag); 241 BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag); 242 void completeType(BTFDebug &BDebug) override; 243 }; 244 245 /// String table. 246 class BTFStringTable { 247 /// String table size in bytes. 248 uint32_t Size; 249 /// A mapping from string table offset to the index 250 /// of the Table. It is used to avoid putting 251 /// duplicated strings in the table. 252 std::map<uint32_t, uint32_t> OffsetToIdMap; 253 /// A vector of strings to represent the string table. 254 std::vector<std::string> Table; 255 256 public: BTFStringTable()257 BTFStringTable() : Size(0) {} getSize()258 uint32_t getSize() { return Size; } getTable()259 std::vector<std::string> &getTable() { return Table; } 260 /// Add a string to the string table and returns its offset 261 /// in the table. 262 uint32_t addString(StringRef S); 263 }; 264 265 /// Represent one func and its type id. 266 struct BTFFuncInfo { 267 const MCSymbol *Label; ///< Func MCSymbol 268 uint32_t TypeId; ///< Type id referring to .BTF type section 269 }; 270 271 /// Represent one line info. 272 struct BTFLineInfo { 273 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo 274 uint32_t FileNameOff; ///< file name offset in the .BTF string table 275 uint32_t LineOff; ///< line offset in the .BTF string table 276 uint32_t LineNum; ///< the line number 277 uint32_t ColumnNum; ///< the column number 278 }; 279 280 /// Represent one field relocation. 281 struct BTFFieldReloc { 282 const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc 283 uint32_t TypeID; ///< Type ID 284 uint32_t OffsetNameOff; ///< The string to traverse types 285 uint32_t RelocKind; ///< What to patch the instruction 286 }; 287 288 /// Collect and emit BTF information. 289 class BTFDebug : public DebugHandlerBase { 290 MCStreamer &OS; 291 bool SkipInstruction; 292 bool LineInfoGenerated; 293 uint32_t SecNameOff; 294 uint32_t ArrayIndexTypeId; 295 bool MapDefNotCollected; 296 BTFStringTable StringTable; 297 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries; 298 std::unordered_map<const DIType *, uint32_t> DIToIdMap; 299 std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable; 300 std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable; 301 std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable; 302 StringMap<std::vector<std::string>> FileContent; 303 std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries; 304 std::vector<BTFTypeStruct *> StructTypes; 305 std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms; 306 std::map<const DICompositeType *, 307 std::vector<std::pair<const DIDerivedType *, BTFTypeDerived *>>> 308 FixupDerivedTypes; 309 std::set<const Function *>ProtoFunctions; 310 311 /// Add types to TypeEntries. 312 /// @{ 313 /// Add types to TypeEntries and DIToIdMap. 314 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty); 315 /// Add types to TypeEntries only and return type id. 316 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry); 317 /// @} 318 319 /// IR type visiting functions. 320 /// @{ 321 void visitTypeEntry(const DIType *Ty); 322 void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer, 323 bool SeenPointer); 324 void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId); 325 void visitSubroutineType( 326 const DISubroutineType *STy, bool ForSubprog, 327 const std::unordered_map<uint32_t, StringRef> &FuncArgNames, 328 uint32_t &TypeId); 329 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion, 330 uint32_t &TypeId); 331 void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId); 332 void visitStructType(const DICompositeType *STy, bool IsStruct, 333 uint32_t &TypeId); 334 void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId); 335 void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId); 336 void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, 337 bool CheckPointer, bool SeenPointer); 338 void visitMapDefType(const DIType *Ty, uint32_t &TypeId); 339 /// @} 340 341 /// Check whether the type is a forward declaration candidate or not. 342 bool IsForwardDeclCandidate(const DIType *Base); 343 344 /// Get the file content for the subprogram. Certain lines of the file 345 /// later may be put into string table and referenced by line info. 346 std::string populateFileContent(const DIFile *File); 347 348 /// Construct a line info. 349 void constructLineInfo(MCSymbol *Label, const DIFile *File, uint32_t Line, 350 uint32_t Column); 351 352 /// Generate types and variables for globals. 353 void processGlobals(bool ProcessingMapDef); 354 355 /// Process global variable initializer in pursuit for function 356 /// pointers. 357 void processGlobalInitializer(const Constant *C); 358 359 /// Generate types for function prototypes. 360 void processFuncPrototypes(const Function *); 361 362 /// Generate types for decl annotations. 363 void processDeclAnnotations(DINodeArray Annotations, uint32_t BaseTypeId, 364 int ComponentId); 365 366 /// Generate types for DISubprogram and it's arguments. 367 uint32_t processDISubprogram(const DISubprogram *SP, uint32_t ProtoTypeId, 368 uint8_t Scope); 369 370 /// Generate BTF type_tag's. If BaseTypeId is nonnegative, the last 371 /// BTF type_tag in the chain points to BaseTypeId. Otherwise, it points to 372 /// the base type of DTy. Return the type id of the first BTF type_tag 373 /// in the chain. If no type_tag's are generated, a negative value 374 /// is returned. 375 int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId); 376 377 /// Generate one field relocation record. 378 void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId, 379 const GlobalVariable *, bool IsAma); 380 381 /// Populating unprocessed type on demand. 382 unsigned populateType(const DIType *Ty); 383 384 /// Process global variables referenced by relocation instructions 385 /// and extern function references. 386 void processGlobalValue(const MachineOperand &MO); 387 388 /// Emit common header of .BTF and .BTF.ext sections. 389 void emitCommonHeader(); 390 391 /// Emit the .BTF section. 392 void emitBTFSection(); 393 394 /// Emit the .BTF.ext section. 395 void emitBTFExtSection(); 396 397 protected: 398 /// Gather pre-function debug information. 399 void beginFunctionImpl(const MachineFunction *MF) override; 400 401 /// Post process after all instructions in this function are processed. 402 void endFunctionImpl(const MachineFunction *MF) override; 403 404 public: 405 BTFDebug(AsmPrinter *AP); 406 407 /// 408 bool InstLower(const MachineInstr *MI, MCInst &OutMI); 409 410 /// Get the special array index type id. getArrayIndexTypeId()411 uint32_t getArrayIndexTypeId() { 412 assert(ArrayIndexTypeId); 413 return ArrayIndexTypeId; 414 } 415 416 /// Add string to the string table. addString(StringRef S)417 size_t addString(StringRef S) { return StringTable.addString(S); } 418 419 /// Get the type id for a particular DIType. getTypeId(const DIType * Ty)420 uint32_t getTypeId(const DIType *Ty) { 421 assert(Ty && "Invalid null Type"); 422 assert(DIToIdMap.find(Ty) != DIToIdMap.end() && 423 "DIType not added in the BDIToIdMap"); 424 return DIToIdMap[Ty]; 425 } 426 427 /// Process beginning of an instruction. 428 void beginInstruction(const MachineInstr *MI) override; 429 430 /// Complete all the types and emit the BTF sections. 431 void endModule() override; 432 }; 433 434 } // end namespace llvm 435 436 #endif 437