1*06c3fb27SDimitry Andric //===-- SymbolFileCTF.h -----------------------------------------*- C++ -*-===// 2*06c3fb27SDimitry Andric // 3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06c3fb27SDimitry Andric // 7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 8*06c3fb27SDimitry Andric 9*06c3fb27SDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 10*06c3fb27SDimitry Andric #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 11*06c3fb27SDimitry Andric 12*06c3fb27SDimitry Andric #include <map> 13*06c3fb27SDimitry Andric #include <optional> 14*06c3fb27SDimitry Andric #include <vector> 15*06c3fb27SDimitry Andric 16*06c3fb27SDimitry Andric #include "lldb/Symbol/CompileUnit.h" 17*06c3fb27SDimitry Andric #include "lldb/Symbol/SymbolFile.h" 18*06c3fb27SDimitry Andric 19*06c3fb27SDimitry Andric namespace lldb_private { 20*06c3fb27SDimitry Andric 21*06c3fb27SDimitry Andric class SymbolFileCTF : public lldb_private::SymbolFileCommon { 22*06c3fb27SDimitry Andric /// LLVM RTTI support. 23*06c3fb27SDimitry Andric static char ID; 24*06c3fb27SDimitry Andric 25*06c3fb27SDimitry Andric public: 26*06c3fb27SDimitry Andric /// LLVM RTTI support. 27*06c3fb27SDimitry Andric /// \{ 28*06c3fb27SDimitry Andric bool isA(const void *ClassID) const override { 29*06c3fb27SDimitry Andric return ClassID == &ID || SymbolFileCommon::isA(ClassID); 30*06c3fb27SDimitry Andric } 31*06c3fb27SDimitry Andric static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } 32*06c3fb27SDimitry Andric /// \} 33*06c3fb27SDimitry Andric 34*06c3fb27SDimitry Andric SymbolFileCTF(lldb::ObjectFileSP objfile_sp); 35*06c3fb27SDimitry Andric 36*06c3fb27SDimitry Andric static void Initialize(); 37*06c3fb27SDimitry Andric 38*06c3fb27SDimitry Andric static void Terminate(); 39*06c3fb27SDimitry Andric 40*06c3fb27SDimitry Andric static llvm::StringRef GetPluginNameStatic() { return "CTF"; } 41*06c3fb27SDimitry Andric 42*06c3fb27SDimitry Andric static llvm::StringRef GetPluginDescriptionStatic(); 43*06c3fb27SDimitry Andric 44*06c3fb27SDimitry Andric static lldb_private::SymbolFile * 45*06c3fb27SDimitry Andric CreateInstance(lldb::ObjectFileSP objfile_sp); 46*06c3fb27SDimitry Andric 47*06c3fb27SDimitry Andric llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 48*06c3fb27SDimitry Andric 49*06c3fb27SDimitry Andric uint32_t CalculateAbilities() override; 50*06c3fb27SDimitry Andric 51*06c3fb27SDimitry Andric void InitializeObject() override; 52*06c3fb27SDimitry Andric 53*06c3fb27SDimitry Andric lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { 54*06c3fb27SDimitry Andric return lldb::eLanguageTypeUnknown; 55*06c3fb27SDimitry Andric } 56*06c3fb27SDimitry Andric 57*06c3fb27SDimitry Andric bool ParseHeader(); 58*06c3fb27SDimitry Andric 59*06c3fb27SDimitry Andric size_t ParseFunctions(CompileUnit &comp_unit) override; 60*06c3fb27SDimitry Andric 61*06c3fb27SDimitry Andric size_t ParseObjects(CompileUnit &comp_unit); 62*06c3fb27SDimitry Andric 63*06c3fb27SDimitry Andric bool ParseLineTable(CompileUnit &comp_unit) override { return false; } 64*06c3fb27SDimitry Andric 65*06c3fb27SDimitry Andric bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } 66*06c3fb27SDimitry Andric 67*06c3fb27SDimitry Andric bool ParseSupportFiles(CompileUnit &comp_unit, 68*06c3fb27SDimitry Andric FileSpecList &support_files) override { 69*06c3fb27SDimitry Andric return false; 70*06c3fb27SDimitry Andric } 71*06c3fb27SDimitry Andric 72*06c3fb27SDimitry Andric size_t ParseTypes(CompileUnit &cu) override; 73*06c3fb27SDimitry Andric 74*06c3fb27SDimitry Andric bool ParseImportedModules( 75*06c3fb27SDimitry Andric const SymbolContext &sc, 76*06c3fb27SDimitry Andric std::vector<lldb_private::SourceModule> &imported_modules) override { 77*06c3fb27SDimitry Andric return false; 78*06c3fb27SDimitry Andric } 79*06c3fb27SDimitry Andric 80*06c3fb27SDimitry Andric size_t ParseBlocksRecursive(Function &func) override { return 0; } 81*06c3fb27SDimitry Andric 82*06c3fb27SDimitry Andric size_t ParseVariablesForContext(const SymbolContext &sc) override; 83*06c3fb27SDimitry Andric 84*06c3fb27SDimitry Andric uint32_t CalculateNumCompileUnits() override { return 0; } 85*06c3fb27SDimitry Andric 86*06c3fb27SDimitry Andric lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; 87*06c3fb27SDimitry Andric 88*06c3fb27SDimitry Andric lldb::TypeSP GetTypeForUID(lldb::user_id_t type_uid); 89*06c3fb27SDimitry Andric void AddTypeForUID(lldb::user_id_t type_uid, lldb::TypeSP type); 90*06c3fb27SDimitry Andric 91*06c3fb27SDimitry Andric Type *ResolveTypeUID(lldb::user_id_t type_uid) override; 92*06c3fb27SDimitry Andric std::optional<ArrayInfo> GetDynamicArrayInfoForUID( 93*06c3fb27SDimitry Andric lldb::user_id_t type_uid, 94*06c3fb27SDimitry Andric const lldb_private::ExecutionContext *exe_ctx) override { 95*06c3fb27SDimitry Andric return std::nullopt; 96*06c3fb27SDimitry Andric } 97*06c3fb27SDimitry Andric 98*06c3fb27SDimitry Andric bool CompleteType(CompilerType &compiler_type) override { return false; } 99*06c3fb27SDimitry Andric 100*06c3fb27SDimitry Andric uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, 101*06c3fb27SDimitry Andric lldb::SymbolContextItem resolve_scope, 102*06c3fb27SDimitry Andric lldb_private::SymbolContext &sc) override; 103*06c3fb27SDimitry Andric 104*06c3fb27SDimitry Andric void AddSymbols(Symtab &symtab) override; 105*06c3fb27SDimitry Andric 106*06c3fb27SDimitry Andric void GetTypes(lldb_private::SymbolContextScope *sc_scope, 107*06c3fb27SDimitry Andric lldb::TypeClass type_mask, 108*06c3fb27SDimitry Andric lldb_private::TypeList &type_list) override {} 109*06c3fb27SDimitry Andric 110*06c3fb27SDimitry Andric void 111*06c3fb27SDimitry Andric FindTypes(lldb_private::ConstString name, 112*06c3fb27SDimitry Andric const lldb_private::CompilerDeclContext &parent_decl_ctx, 113*06c3fb27SDimitry Andric uint32_t max_matches, 114*06c3fb27SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 115*06c3fb27SDimitry Andric lldb_private::TypeMap &types) override; 116*06c3fb27SDimitry Andric 117*06c3fb27SDimitry Andric void FindTypesByRegex(const lldb_private::RegularExpression ®ex, 118*06c3fb27SDimitry Andric uint32_t max_matches, lldb_private::TypeMap &types); 119*06c3fb27SDimitry Andric 120*06c3fb27SDimitry Andric void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, 121*06c3fb27SDimitry Andric const lldb_private::CompilerDeclContext &parent_decl_ctx, 122*06c3fb27SDimitry Andric bool include_inlines, 123*06c3fb27SDimitry Andric lldb_private::SymbolContextList &sc_list) override; 124*06c3fb27SDimitry Andric 125*06c3fb27SDimitry Andric void FindFunctions(const lldb_private::RegularExpression ®ex, 126*06c3fb27SDimitry Andric bool include_inlines, 127*06c3fb27SDimitry Andric lldb_private::SymbolContextList &sc_list) override; 128*06c3fb27SDimitry Andric 129*06c3fb27SDimitry Andric void 130*06c3fb27SDimitry Andric FindGlobalVariables(lldb_private::ConstString name, 131*06c3fb27SDimitry Andric const lldb_private::CompilerDeclContext &parent_decl_ctx, 132*06c3fb27SDimitry Andric uint32_t max_matches, 133*06c3fb27SDimitry Andric lldb_private::VariableList &variables) override; 134*06c3fb27SDimitry Andric 135*06c3fb27SDimitry Andric void FindGlobalVariables(const lldb_private::RegularExpression ®ex, 136*06c3fb27SDimitry Andric uint32_t max_matches, 137*06c3fb27SDimitry Andric lldb_private::VariableList &variables) override; 138*06c3fb27SDimitry Andric 139*06c3fb27SDimitry Andric enum TypeKind : uint32_t { 140*06c3fb27SDimitry Andric eUnknown = 0, 141*06c3fb27SDimitry Andric eInteger = 1, 142*06c3fb27SDimitry Andric eFloat = 2, 143*06c3fb27SDimitry Andric ePointer = 3, 144*06c3fb27SDimitry Andric eArray = 4, 145*06c3fb27SDimitry Andric eFunction = 5, 146*06c3fb27SDimitry Andric eStruct = 6, 147*06c3fb27SDimitry Andric eUnion = 7, 148*06c3fb27SDimitry Andric eEnum = 8, 149*06c3fb27SDimitry Andric eForward = 9, 150*06c3fb27SDimitry Andric eTypedef = 10, 151*06c3fb27SDimitry Andric eVolatile = 11, 152*06c3fb27SDimitry Andric eConst = 12, 153*06c3fb27SDimitry Andric eRestrict = 13, 154*06c3fb27SDimitry Andric eSlice = 14, 155*06c3fb27SDimitry Andric }; 156*06c3fb27SDimitry Andric 157*06c3fb27SDimitry Andric private: 158*06c3fb27SDimitry Andric enum Flags : uint32_t { 159*06c3fb27SDimitry Andric eFlagCompress = (1u << 0), 160*06c3fb27SDimitry Andric eFlagNewFuncInfo = (1u << 1), 161*06c3fb27SDimitry Andric eFlagIdxSorted = (1u << 2), 162*06c3fb27SDimitry Andric eFlagDynStr = (1u << 3), 163*06c3fb27SDimitry Andric }; 164*06c3fb27SDimitry Andric 165*06c3fb27SDimitry Andric enum IntEncoding : uint32_t { 166*06c3fb27SDimitry Andric eSigned = 0x1, 167*06c3fb27SDimitry Andric eChar = 0x2, 168*06c3fb27SDimitry Andric eBool = 0x4, 169*06c3fb27SDimitry Andric eVarArgs = 0x8, 170*06c3fb27SDimitry Andric }; 171*06c3fb27SDimitry Andric 172*06c3fb27SDimitry Andric struct ctf_preamble_t { 173*06c3fb27SDimitry Andric uint16_t magic; 174*06c3fb27SDimitry Andric uint8_t version; 175*06c3fb27SDimitry Andric uint8_t flags; 176*06c3fb27SDimitry Andric }; 177*06c3fb27SDimitry Andric 178*06c3fb27SDimitry Andric struct ctf_header_t { 179*06c3fb27SDimitry Andric ctf_preamble_t preamble; 180*06c3fb27SDimitry Andric uint32_t parlabel; 181*06c3fb27SDimitry Andric uint32_t parname; 182*06c3fb27SDimitry Andric uint32_t lbloff; 183*06c3fb27SDimitry Andric uint32_t objtoff; 184*06c3fb27SDimitry Andric uint32_t funcoff; 185*06c3fb27SDimitry Andric uint32_t typeoff; 186*06c3fb27SDimitry Andric uint32_t stroff; 187*06c3fb27SDimitry Andric uint32_t strlen; 188*06c3fb27SDimitry Andric }; 189*06c3fb27SDimitry Andric 190*06c3fb27SDimitry Andric struct ctf_type_t { 191*06c3fb27SDimitry Andric uint32_t name; 192*06c3fb27SDimitry Andric uint32_t info; 193*06c3fb27SDimitry Andric union { 194*06c3fb27SDimitry Andric uint32_t size; 195*06c3fb27SDimitry Andric uint32_t type; 196*06c3fb27SDimitry Andric }; 197*06c3fb27SDimitry Andric uint32_t lsizehi; 198*06c3fb27SDimitry Andric uint32_t lsizelo; 199*06c3fb27SDimitry Andric }; 200*06c3fb27SDimitry Andric 201*06c3fb27SDimitry Andric struct ctf_stype_t { 202*06c3fb27SDimitry Andric uint32_t name; 203*06c3fb27SDimitry Andric uint32_t info; 204*06c3fb27SDimitry Andric union { 205*06c3fb27SDimitry Andric uint32_t size; 206*06c3fb27SDimitry Andric uint32_t type; 207*06c3fb27SDimitry Andric }; 208*06c3fb27SDimitry Andric 209*06c3fb27SDimitry Andric bool IsLargeType() const { return size == 0xffff; } 210*06c3fb27SDimitry Andric uint32_t GetStructSize() const { 211*06c3fb27SDimitry Andric if (IsLargeType()) 212*06c3fb27SDimitry Andric return sizeof(ctf_type_t); 213*06c3fb27SDimitry Andric return sizeof(ctf_stype_t); 214*06c3fb27SDimitry Andric } 215*06c3fb27SDimitry Andric uint32_t GetType() const { return type; } 216*06c3fb27SDimitry Andric uint32_t GetSize() const { return size; } 217*06c3fb27SDimitry Andric }; 218*06c3fb27SDimitry Andric 219*06c3fb27SDimitry Andric struct ctf_member_t { 220*06c3fb27SDimitry Andric uint32_t name; 221*06c3fb27SDimitry Andric uint32_t type; 222*06c3fb27SDimitry Andric uint16_t offset; 223*06c3fb27SDimitry Andric uint16_t padding; 224*06c3fb27SDimitry Andric }; 225*06c3fb27SDimitry Andric 226*06c3fb27SDimitry Andric struct ctf_array_t { 227*06c3fb27SDimitry Andric uint32_t contents; 228*06c3fb27SDimitry Andric uint32_t index; 229*06c3fb27SDimitry Andric uint32_t nelems; 230*06c3fb27SDimitry Andric }; 231*06c3fb27SDimitry Andric 232*06c3fb27SDimitry Andric struct ctf_enum_t { 233*06c3fb27SDimitry Andric uint32_t name; 234*06c3fb27SDimitry Andric int32_t value; 235*06c3fb27SDimitry Andric }; 236*06c3fb27SDimitry Andric 237*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> ParseType(lldb::offset_t &offset, 238*06c3fb27SDimitry Andric lldb::user_id_t uid, 239*06c3fb27SDimitry Andric llvm::StringRef name, uint32_t kind, 240*06c3fb27SDimitry Andric uint32_t variable_length, 241*06c3fb27SDimitry Andric uint32_t type, uint32_t size); 242*06c3fb27SDimitry Andric 243*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> ParseInteger(lldb::offset_t &offset, 244*06c3fb27SDimitry Andric lldb::user_id_t uid, 245*06c3fb27SDimitry Andric llvm::StringRef name); 246*06c3fb27SDimitry Andric 247*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> ParseModifierType(lldb::offset_t &offset, 248*06c3fb27SDimitry Andric lldb::user_id_t uid, 249*06c3fb27SDimitry Andric uint32_t kind, uint32_t type); 250*06c3fb27SDimitry Andric 251*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> ParseTypedef(lldb::offset_t &offset, 252*06c3fb27SDimitry Andric lldb::user_id_t uid, 253*06c3fb27SDimitry Andric llvm::StringRef name, 254*06c3fb27SDimitry Andric uint32_t type); 255*06c3fb27SDimitry Andric 256*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> 257*06c3fb27SDimitry Andric ParseArray(lldb::offset_t &offset, lldb::user_id_t uid, llvm::StringRef name); 258*06c3fb27SDimitry Andric 259*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> ParseEnum(lldb::offset_t &offset, 260*06c3fb27SDimitry Andric lldb::user_id_t uid, 261*06c3fb27SDimitry Andric llvm::StringRef name, 262*06c3fb27SDimitry Andric uint32_t elements, uint32_t size); 263*06c3fb27SDimitry Andric 264*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> ParseFunction(lldb::offset_t &offset, 265*06c3fb27SDimitry Andric lldb::user_id_t uid, 266*06c3fb27SDimitry Andric llvm::StringRef name, 267*06c3fb27SDimitry Andric uint32_t num_args, uint32_t type); 268*06c3fb27SDimitry Andric 269*06c3fb27SDimitry Andric llvm::Expected<lldb::TypeSP> ParseRecord(lldb::offset_t &offset, 270*06c3fb27SDimitry Andric lldb::user_id_t uid, 271*06c3fb27SDimitry Andric llvm::StringRef name, uint32_t kind, 272*06c3fb27SDimitry Andric uint32_t fields, uint32_t size); 273*06c3fb27SDimitry Andric 274*06c3fb27SDimitry Andric llvm::StringRef ReadString(lldb::offset_t offset) const; 275*06c3fb27SDimitry Andric 276*06c3fb27SDimitry Andric std::vector<uint16_t> GetFieldSizes(lldb::offset_t field_offset, 277*06c3fb27SDimitry Andric uint32_t fields, uint32_t struct_size); 278*06c3fb27SDimitry Andric 279*06c3fb27SDimitry Andric DataExtractor m_data; 280*06c3fb27SDimitry Andric 281*06c3fb27SDimitry Andric /// The start offset of the CTF body into m_data. If the body is uncompressed, 282*06c3fb27SDimitry Andric /// m_data contains the header and the body and the body starts after the 283*06c3fb27SDimitry Andric /// header. If the body is compressed, m_data only contains the body and the 284*06c3fb27SDimitry Andric /// offset is zero. 285*06c3fb27SDimitry Andric lldb::offset_t m_body_offset = 0; 286*06c3fb27SDimitry Andric 287*06c3fb27SDimitry Andric TypeSystemClang *m_ast; 288*06c3fb27SDimitry Andric lldb::CompUnitSP m_comp_unit_sp; 289*06c3fb27SDimitry Andric 290*06c3fb27SDimitry Andric std::optional<ctf_header_t> m_header; 291*06c3fb27SDimitry Andric std::vector<lldb::TypeSP> m_types; 292*06c3fb27SDimitry Andric std::vector<lldb::FunctionSP> m_functions; 293*06c3fb27SDimitry Andric std::vector<lldb::VariableSP> m_variables; 294*06c3fb27SDimitry Andric 295*06c3fb27SDimitry Andric static constexpr uint16_t g_ctf_magic = 0xcff1; 296*06c3fb27SDimitry Andric static constexpr uint8_t g_ctf_version = 4; 297*06c3fb27SDimitry Andric }; 298*06c3fb27SDimitry Andric } // namespace lldb_private 299*06c3fb27SDimitry Andric 300*06c3fb27SDimitry Andric #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 301