1 //===-- SymbolFileCTF.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 #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 11 12 #include <map> 13 #include <optional> 14 #include <vector> 15 16 #include "CTFTypes.h" 17 #include "lldb/Symbol/CompileUnit.h" 18 #include "lldb/Symbol/SymbolFile.h" 19 20 namespace lldb_private { 21 22 class SymbolFileCTF : public lldb_private::SymbolFileCommon { 23 /// LLVM RTTI support. 24 static char ID; 25 26 public: 27 /// LLVM RTTI support. 28 /// \{ 29 bool isA(const void *ClassID) const override { 30 return ClassID == &ID || SymbolFileCommon::isA(ClassID); 31 } 32 static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } 33 /// \} 34 35 SymbolFileCTF(lldb::ObjectFileSP objfile_sp); 36 37 static void Initialize(); 38 39 static void Terminate(); 40 41 static llvm::StringRef GetPluginNameStatic() { return "CTF"; } 42 43 static llvm::StringRef GetPluginDescriptionStatic(); 44 45 static lldb_private::SymbolFile * 46 CreateInstance(lldb::ObjectFileSP objfile_sp); 47 48 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 49 50 uint32_t CalculateAbilities() override; 51 52 void InitializeObject() override; 53 54 lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { 55 return lldb::eLanguageTypeUnknown; 56 } 57 58 bool ParseHeader(); 59 60 size_t ParseFunctions(CompileUnit &comp_unit) override; 61 62 size_t ParseObjects(CompileUnit &comp_unit); 63 64 bool ParseLineTable(CompileUnit &comp_unit) override { return false; } 65 66 bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } 67 68 bool ParseSupportFiles(CompileUnit &comp_unit, 69 SupportFileList &support_files) override { 70 return false; 71 } 72 73 size_t ParseTypes(CompileUnit &cu) override; 74 75 bool ParseImportedModules( 76 const SymbolContext &sc, 77 std::vector<lldb_private::SourceModule> &imported_modules) override { 78 return false; 79 } 80 81 size_t ParseBlocksRecursive(Function &func) override { return 0; } 82 83 size_t ParseVariablesForContext(const SymbolContext &sc) override; 84 85 uint32_t CalculateNumCompileUnits() override { return 0; } 86 87 lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; 88 89 Type *ResolveTypeUID(lldb::user_id_t type_uid) override; 90 std::optional<ArrayInfo> GetDynamicArrayInfoForUID( 91 lldb::user_id_t type_uid, 92 const lldb_private::ExecutionContext *exe_ctx) override { 93 return std::nullopt; 94 } 95 96 bool CompleteType(CompilerType &compiler_type) override; 97 98 uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, 99 lldb::SymbolContextItem resolve_scope, 100 lldb_private::SymbolContext &sc) override; 101 102 void AddSymbols(Symtab &symtab) override; 103 104 void GetTypes(lldb_private::SymbolContextScope *sc_scope, 105 lldb::TypeClass type_mask, 106 lldb_private::TypeList &type_list) override {} 107 108 void FindTypes(const lldb_private::TypeQuery &match, 109 lldb_private::TypeResults &results) override; 110 111 void FindTypesByRegex(const lldb_private::RegularExpression ®ex, 112 uint32_t max_matches, lldb_private::TypeMap &types); 113 114 void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, 115 const lldb_private::CompilerDeclContext &parent_decl_ctx, 116 bool include_inlines, 117 lldb_private::SymbolContextList &sc_list) override; 118 119 void FindFunctions(const lldb_private::RegularExpression ®ex, 120 bool include_inlines, 121 lldb_private::SymbolContextList &sc_list) override; 122 123 void 124 FindGlobalVariables(lldb_private::ConstString name, 125 const lldb_private::CompilerDeclContext &parent_decl_ctx, 126 uint32_t max_matches, 127 lldb_private::VariableList &variables) override; 128 129 void FindGlobalVariables(const lldb_private::RegularExpression ®ex, 130 uint32_t max_matches, 131 lldb_private::VariableList &variables) override; 132 133 enum TypeKind : uint32_t { 134 eUnknown = 0, 135 eInteger = 1, 136 eFloat = 2, 137 ePointer = 3, 138 eArray = 4, 139 eFunction = 5, 140 eStruct = 6, 141 eUnion = 7, 142 eEnum = 8, 143 eForward = 9, 144 eTypedef = 10, 145 eVolatile = 11, 146 eConst = 12, 147 eRestrict = 13, 148 eSlice = 14, 149 }; 150 151 private: 152 enum Flags : uint32_t { 153 eFlagCompress = (1u << 0), 154 eFlagNewFuncInfo = (1u << 1), 155 eFlagIdxSorted = (1u << 2), 156 eFlagDynStr = (1u << 3), 157 }; 158 159 enum IntEncoding : uint32_t { 160 eSigned = 0x1, 161 eChar = 0x2, 162 eBool = 0x4, 163 eVarArgs = 0x8, 164 }; 165 166 struct ctf_preamble_t { 167 uint16_t magic; 168 uint8_t version; 169 uint8_t flags; 170 }; 171 172 struct ctf_header_t { 173 ctf_preamble_t preamble; 174 uint32_t parlabel; 175 uint32_t parname; 176 uint32_t lbloff; 177 uint32_t objtoff; 178 uint32_t funcoff; 179 uint32_t typeoff; 180 uint32_t stroff; 181 uint32_t strlen; 182 }; 183 184 struct ctf_type_t { 185 uint32_t name; 186 uint32_t info; 187 union { 188 uint32_t size; 189 uint32_t type; 190 }; 191 uint32_t lsizehi; 192 uint32_t lsizelo; 193 }; 194 195 struct ctf_stype_t { 196 uint32_t name; 197 uint32_t info; 198 union { 199 uint32_t size; 200 uint32_t type; 201 }; 202 203 bool IsLargeType() const { return size == 0xffff; } 204 uint32_t GetStructSize() const { 205 if (IsLargeType()) 206 return sizeof(ctf_type_t); 207 return sizeof(ctf_stype_t); 208 } 209 uint32_t GetType() const { return type; } 210 uint32_t GetSize() const { return size; } 211 }; 212 213 llvm::Expected<std::unique_ptr<CTFType>> ParseType(lldb::offset_t &offset, 214 lldb::user_id_t uid); 215 216 llvm::Expected<lldb::TypeSP> CreateType(CTFType *ctf_type); 217 llvm::Expected<lldb::TypeSP> CreateInteger(const CTFInteger &ctf_integer); 218 llvm::Expected<lldb::TypeSP> CreateModifier(const CTFModifier &ctf_modifier); 219 llvm::Expected<lldb::TypeSP> CreateTypedef(const CTFTypedef &ctf_typedef); 220 llvm::Expected<lldb::TypeSP> CreateArray(const CTFArray &ctf_array); 221 llvm::Expected<lldb::TypeSP> CreateEnum(const CTFEnum &ctf_enum); 222 llvm::Expected<lldb::TypeSP> CreateFunction(const CTFFunction &ctf_function); 223 llvm::Expected<lldb::TypeSP> CreateRecord(const CTFRecord &ctf_record); 224 llvm::Expected<lldb::TypeSP> CreateForward(const CTFForward &ctf_forward); 225 226 llvm::StringRef ReadString(lldb::offset_t offset) const; 227 228 std::vector<uint16_t> GetFieldSizes(lldb::offset_t field_offset, 229 uint32_t fields, uint32_t struct_size); 230 231 DataExtractor m_data; 232 233 /// The start offset of the CTF body into m_data. If the body is uncompressed, 234 /// m_data contains the header and the body and the body starts after the 235 /// header. If the body is compressed, m_data only contains the body and the 236 /// offset is zero. 237 lldb::offset_t m_body_offset = 0; 238 239 TypeSystemClang *m_ast; 240 lldb::CompUnitSP m_comp_unit_sp; 241 242 std::optional<ctf_header_t> m_header; 243 244 /// Parsed CTF types. 245 llvm::DenseMap<lldb::user_id_t, std::unique_ptr<CTFType>> m_ctf_types; 246 247 /// Parsed LLDB types. 248 llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types; 249 250 /// To complete types, we need a way to map (imcomplete) compiler types back 251 /// to parsed CTF types. 252 llvm::DenseMap<lldb::opaque_compiler_type_t, const CTFType *> 253 m_compiler_types; 254 255 std::vector<lldb::FunctionSP> m_functions; 256 std::vector<lldb::VariableSP> m_variables; 257 258 static constexpr uint16_t g_ctf_magic = 0xcff1; 259 static constexpr uint8_t g_ctf_version = 4; 260 static constexpr uint16_t g_ctf_field_threshold = 0x2000; 261 }; 262 } // namespace lldb_private 263 264 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 265