1 //===- BTFDebug.h -----------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// This file contains support for writing BTF debug info. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H 16 #define LLVM_LIB_TARGET_BPF_BTFDEBUG_H 17 18 #include "llvm/ADT/StringMap.h" 19 #include "llvm/CodeGen/DebugHandlerBase.h" 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 uint32_t Id; 37 struct BTF::CommonType BTFType; 38 39 public: 40 virtual ~BTFTypeBase() = default; setId(uint32_t Id)41 void setId(uint32_t Id) { this->Id = Id; } getId()42 uint32_t getId() { return Id; } roundupToBytes(uint32_t NumBits)43 uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; } 44 /// Get the size of this BTF type entry. getSize()45 virtual uint32_t getSize() { return BTF::CommonTypeSize; } 46 /// Complete BTF type generation after all related DebugInfo types 47 /// have been visited so their BTF type id's are available 48 /// for cross referece. completeType(BTFDebug & BDebug)49 virtual void completeType(BTFDebug &BDebug) {} 50 /// Emit types for this BTF type entry. 51 virtual void emitType(MCStreamer &OS); 52 }; 53 54 /// Handle several derived types include pointer, const, 55 /// volatile, typedef and restrict. 56 class BTFTypeDerived : public BTFTypeBase { 57 const DIDerivedType *DTy; 58 59 public: 60 BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag); 61 void completeType(BTFDebug &BDebug); 62 void emitType(MCStreamer &OS); 63 }; 64 65 /// Handle struct or union forward declaration. 66 class BTFTypeFwd : public BTFTypeBase { 67 StringRef Name; 68 69 public: 70 BTFTypeFwd(StringRef Name, bool IsUnion); 71 void completeType(BTFDebug &BDebug); 72 void emitType(MCStreamer &OS); 73 }; 74 75 /// Handle int type. 76 class BTFTypeInt : public BTFTypeBase { 77 StringRef Name; 78 uint32_t IntVal; ///< Encoding, offset, bits 79 80 public: 81 BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, 82 StringRef TypeName); getSize()83 uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); } 84 void completeType(BTFDebug &BDebug); 85 void emitType(MCStreamer &OS); 86 }; 87 88 /// Handle enumerate type. 89 class BTFTypeEnum : public BTFTypeBase { 90 const DICompositeType *ETy; 91 std::vector<struct BTF::BTFEnum> EnumValues; 92 93 public: 94 BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues); getSize()95 uint32_t getSize() { 96 return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize; 97 } 98 void completeType(BTFDebug &BDebug); 99 void emitType(MCStreamer &OS); 100 }; 101 102 /// Handle array type. 103 class BTFTypeArray : public BTFTypeBase { 104 const DICompositeType *ATy; 105 struct BTF::BTFArray ArrayInfo; 106 107 public: 108 BTFTypeArray(const DICompositeType *ATy); getSize()109 uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; } 110 void completeType(BTFDebug &BDebug); 111 void emitType(MCStreamer &OS); 112 }; 113 114 /// Handle struct/union type. 115 class BTFTypeStruct : public BTFTypeBase { 116 const DICompositeType *STy; 117 bool HasBitField; 118 std::vector<struct BTF::BTFMember> Members; 119 120 public: 121 BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, 122 uint32_t NumMembers); getSize()123 uint32_t getSize() { 124 return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize; 125 } 126 void completeType(BTFDebug &BDebug); 127 void emitType(MCStreamer &OS); 128 }; 129 130 /// Handle function pointer. 131 class BTFTypeFuncProto : public BTFTypeBase { 132 const DISubroutineType *STy; 133 std::unordered_map<uint32_t, StringRef> FuncArgNames; 134 std::vector<struct BTF::BTFParam> Parameters; 135 136 public: 137 BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, 138 const std::unordered_map<uint32_t, StringRef> &FuncArgNames); getSize()139 uint32_t getSize() { 140 return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize; 141 } 142 void completeType(BTFDebug &BDebug); 143 void emitType(MCStreamer &OS); 144 }; 145 146 /// Handle subprogram 147 class BTFTypeFunc : public BTFTypeBase { 148 StringRef Name; 149 150 public: 151 BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId); getSize()152 uint32_t getSize() { return BTFTypeBase::getSize(); } 153 void completeType(BTFDebug &BDebug); 154 void emitType(MCStreamer &OS); 155 }; 156 157 /// String table. 158 class BTFStringTable { 159 /// String table size in bytes. 160 uint32_t Size; 161 /// A mapping from string table offset to the index 162 /// of the Table. It is used to avoid putting 163 /// duplicated strings in the table. 164 std::unordered_map<uint32_t, uint32_t> OffsetToIdMap; 165 /// A vector of strings to represent the string table. 166 std::vector<std::string> Table; 167 168 public: BTFStringTable()169 BTFStringTable() : Size(0) {} getSize()170 uint32_t getSize() { return Size; } getTable()171 std::vector<std::string> &getTable() { return Table; } 172 /// Add a string to the string table and returns its offset 173 /// in the table. 174 uint32_t addString(StringRef S); 175 }; 176 177 /// Represent one func and its type id. 178 struct BTFFuncInfo { 179 const MCSymbol *Label; ///< Func MCSymbol 180 uint32_t TypeId; ///< Type id referring to .BTF type section 181 }; 182 183 /// Represent one line info. 184 struct BTFLineInfo { 185 MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo 186 uint32_t FileNameOff; ///< file name offset in the .BTF string table 187 uint32_t LineOff; ///< line offset in the .BTF string table 188 uint32_t LineNum; ///< the line number 189 uint32_t ColumnNum; ///< the column number 190 }; 191 192 /// Collect and emit BTF information. 193 class BTFDebug : public DebugHandlerBase { 194 MCStreamer &OS; 195 bool SkipInstruction; 196 bool LineInfoGenerated; 197 uint32_t SecNameOff; 198 uint32_t ArrayIndexTypeId; 199 BTFStringTable StringTable; 200 std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries; 201 std::unordered_map<const DIType *, uint32_t> DIToIdMap; 202 std::unordered_map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable; 203 std::unordered_map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable; 204 StringMap<std::vector<std::string>> FileContent; 205 206 /// Add types to TypeEntries. 207 /// @{ 208 /// Add types to TypeEntries and DIToIdMap. 209 void addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty); 210 /// Add types to TypeEntries only and return type id. 211 uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry); 212 /// @} 213 214 /// IR type visiting functions. 215 /// @{ 216 void visitTypeEntry(const DIType *Ty); 217 void visitBasicType(const DIBasicType *BTy); 218 void visitSubroutineType( 219 const DISubroutineType *STy, bool ForSubprog, 220 const std::unordered_map<uint32_t, StringRef> &FuncArgNames, 221 uint32_t &TypeId); 222 void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion); 223 void visitCompositeType(const DICompositeType *CTy); 224 void visitStructType(const DICompositeType *STy, bool IsStruct); 225 void visitArrayType(const DICompositeType *ATy); 226 void visitEnumType(const DICompositeType *ETy); 227 void visitDerivedType(const DIDerivedType *DTy); 228 /// @} 229 230 /// Get the file content for the subprogram. Certain lines of the file 231 /// later may be put into string table and referenced by line info. 232 std::string populateFileContent(const DISubprogram *SP); 233 234 /// Construct a line info. 235 void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line, 236 uint32_t Column); 237 238 /// Emit common header of .BTF and .BTF.ext sections. 239 void emitCommonHeader(); 240 241 /// Emit the .BTF section. 242 void emitBTFSection(); 243 244 /// Emit the .BTF.ext section. 245 void emitBTFExtSection(); 246 247 protected: 248 /// Gather pre-function debug information. 249 void beginFunctionImpl(const MachineFunction *MF) override; 250 251 /// Post process after all instructions in this function are processed. 252 void endFunctionImpl(const MachineFunction *MF) override; 253 254 public: 255 BTFDebug(AsmPrinter *AP); 256 257 /// Get the special array index type id. getArrayIndexTypeId()258 uint32_t getArrayIndexTypeId() { 259 assert(ArrayIndexTypeId); 260 return ArrayIndexTypeId; 261 } 262 263 /// Add string to the string table. addString(StringRef S)264 size_t addString(StringRef S) { return StringTable.addString(S); } 265 266 /// Get the type id for a particular DIType. getTypeId(const DIType * Ty)267 uint32_t getTypeId(const DIType *Ty) { 268 assert(Ty && "Invalid null Type"); 269 assert(DIToIdMap.find(Ty) != DIToIdMap.end() && 270 "DIType not added in the BDIToIdMap"); 271 return DIToIdMap[Ty]; 272 } 273 setSymbolSize(const MCSymbol * Symbol,uint64_t Size)274 void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {} 275 276 /// Process beginning of an instruction. 277 void beginInstruction(const MachineInstr *MI) override; 278 279 /// Complete all the types and emit the BTF sections. 280 void endModule() override; 281 }; 282 283 } // end namespace llvm 284 285 #endif 286