106c3fb27SDimitry Andric //===-- SymbolFileCTF.h -----------------------------------------*- C++ -*-===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 1006c3fb27SDimitry Andric #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 1106c3fb27SDimitry Andric 1206c3fb27SDimitry Andric #include <map> 1306c3fb27SDimitry Andric #include <optional> 1406c3fb27SDimitry Andric #include <vector> 1506c3fb27SDimitry Andric 165f757f3fSDimitry Andric #include "CTFTypes.h" 1706c3fb27SDimitry Andric #include "lldb/Symbol/CompileUnit.h" 1806c3fb27SDimitry Andric #include "lldb/Symbol/SymbolFile.h" 1906c3fb27SDimitry Andric 2006c3fb27SDimitry Andric namespace lldb_private { 2106c3fb27SDimitry Andric 2206c3fb27SDimitry Andric class SymbolFileCTF : public lldb_private::SymbolFileCommon { 2306c3fb27SDimitry Andric /// LLVM RTTI support. 2406c3fb27SDimitry Andric static char ID; 2506c3fb27SDimitry Andric 2606c3fb27SDimitry Andric public: 2706c3fb27SDimitry Andric /// LLVM RTTI support. 2806c3fb27SDimitry Andric /// \{ isA(const void * ClassID)2906c3fb27SDimitry Andric bool isA(const void *ClassID) const override { 3006c3fb27SDimitry Andric return ClassID == &ID || SymbolFileCommon::isA(ClassID); 3106c3fb27SDimitry Andric } classof(const SymbolFile * obj)3206c3fb27SDimitry Andric static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } 3306c3fb27SDimitry Andric /// \} 3406c3fb27SDimitry Andric 3506c3fb27SDimitry Andric SymbolFileCTF(lldb::ObjectFileSP objfile_sp); 3606c3fb27SDimitry Andric 3706c3fb27SDimitry Andric static void Initialize(); 3806c3fb27SDimitry Andric 3906c3fb27SDimitry Andric static void Terminate(); 4006c3fb27SDimitry Andric GetPluginNameStatic()4106c3fb27SDimitry Andric static llvm::StringRef GetPluginNameStatic() { return "CTF"; } 4206c3fb27SDimitry Andric 4306c3fb27SDimitry Andric static llvm::StringRef GetPluginDescriptionStatic(); 4406c3fb27SDimitry Andric 4506c3fb27SDimitry Andric static lldb_private::SymbolFile * 4606c3fb27SDimitry Andric CreateInstance(lldb::ObjectFileSP objfile_sp); 4706c3fb27SDimitry Andric GetPluginName()4806c3fb27SDimitry Andric llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 4906c3fb27SDimitry Andric 5006c3fb27SDimitry Andric uint32_t CalculateAbilities() override; 5106c3fb27SDimitry Andric 5206c3fb27SDimitry Andric void InitializeObject() override; 5306c3fb27SDimitry Andric ParseLanguage(CompileUnit & comp_unit)5406c3fb27SDimitry Andric lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { 5506c3fb27SDimitry Andric return lldb::eLanguageTypeUnknown; 5606c3fb27SDimitry Andric } 5706c3fb27SDimitry Andric 5806c3fb27SDimitry Andric bool ParseHeader(); 5906c3fb27SDimitry Andric 6006c3fb27SDimitry Andric size_t ParseFunctions(CompileUnit &comp_unit) override; 6106c3fb27SDimitry Andric 6206c3fb27SDimitry Andric size_t ParseObjects(CompileUnit &comp_unit); 6306c3fb27SDimitry Andric ParseLineTable(CompileUnit & comp_unit)6406c3fb27SDimitry Andric bool ParseLineTable(CompileUnit &comp_unit) override { return false; } 6506c3fb27SDimitry Andric ParseDebugMacros(CompileUnit & comp_unit)6606c3fb27SDimitry Andric bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } 6706c3fb27SDimitry Andric ParseSupportFiles(CompileUnit & comp_unit,SupportFileList & support_files)6806c3fb27SDimitry Andric bool ParseSupportFiles(CompileUnit &comp_unit, 69*1db9f3b2SDimitry Andric SupportFileList &support_files) override { 7006c3fb27SDimitry Andric return false; 7106c3fb27SDimitry Andric } 7206c3fb27SDimitry Andric 7306c3fb27SDimitry Andric size_t ParseTypes(CompileUnit &cu) override; 7406c3fb27SDimitry Andric ParseImportedModules(const SymbolContext & sc,std::vector<lldb_private::SourceModule> & imported_modules)7506c3fb27SDimitry Andric bool ParseImportedModules( 7606c3fb27SDimitry Andric const SymbolContext &sc, 7706c3fb27SDimitry Andric std::vector<lldb_private::SourceModule> &imported_modules) override { 7806c3fb27SDimitry Andric return false; 7906c3fb27SDimitry Andric } 8006c3fb27SDimitry Andric ParseBlocksRecursive(Function & func)8106c3fb27SDimitry Andric size_t ParseBlocksRecursive(Function &func) override { return 0; } 8206c3fb27SDimitry Andric 8306c3fb27SDimitry Andric size_t ParseVariablesForContext(const SymbolContext &sc) override; 8406c3fb27SDimitry Andric CalculateNumCompileUnits()8506c3fb27SDimitry Andric uint32_t CalculateNumCompileUnits() override { return 0; } 8606c3fb27SDimitry Andric 8706c3fb27SDimitry Andric lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; 8806c3fb27SDimitry Andric 8906c3fb27SDimitry Andric Type *ResolveTypeUID(lldb::user_id_t type_uid) override; GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)9006c3fb27SDimitry Andric std::optional<ArrayInfo> GetDynamicArrayInfoForUID( 9106c3fb27SDimitry Andric lldb::user_id_t type_uid, 9206c3fb27SDimitry Andric const lldb_private::ExecutionContext *exe_ctx) override { 9306c3fb27SDimitry Andric return std::nullopt; 9406c3fb27SDimitry Andric } 9506c3fb27SDimitry Andric 965f757f3fSDimitry Andric bool CompleteType(CompilerType &compiler_type) override; 9706c3fb27SDimitry Andric 9806c3fb27SDimitry Andric uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, 9906c3fb27SDimitry Andric lldb::SymbolContextItem resolve_scope, 10006c3fb27SDimitry Andric lldb_private::SymbolContext &sc) override; 10106c3fb27SDimitry Andric 10206c3fb27SDimitry Andric void AddSymbols(Symtab &symtab) override; 10306c3fb27SDimitry Andric GetTypes(lldb_private::SymbolContextScope * sc_scope,lldb::TypeClass type_mask,lldb_private::TypeList & type_list)10406c3fb27SDimitry Andric void GetTypes(lldb_private::SymbolContextScope *sc_scope, 10506c3fb27SDimitry Andric lldb::TypeClass type_mask, 10606c3fb27SDimitry Andric lldb_private::TypeList &type_list) override {} 10706c3fb27SDimitry Andric 1085f757f3fSDimitry Andric void FindTypes(const lldb_private::TypeQuery &match, 1095f757f3fSDimitry Andric lldb_private::TypeResults &results) override; 11006c3fb27SDimitry Andric 11106c3fb27SDimitry Andric void FindTypesByRegex(const lldb_private::RegularExpression ®ex, 11206c3fb27SDimitry Andric uint32_t max_matches, lldb_private::TypeMap &types); 11306c3fb27SDimitry Andric 11406c3fb27SDimitry Andric void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, 11506c3fb27SDimitry Andric const lldb_private::CompilerDeclContext &parent_decl_ctx, 11606c3fb27SDimitry Andric bool include_inlines, 11706c3fb27SDimitry Andric lldb_private::SymbolContextList &sc_list) override; 11806c3fb27SDimitry Andric 11906c3fb27SDimitry Andric void FindFunctions(const lldb_private::RegularExpression ®ex, 12006c3fb27SDimitry Andric bool include_inlines, 12106c3fb27SDimitry Andric lldb_private::SymbolContextList &sc_list) override; 12206c3fb27SDimitry Andric 12306c3fb27SDimitry Andric void 12406c3fb27SDimitry Andric FindGlobalVariables(lldb_private::ConstString name, 12506c3fb27SDimitry Andric const lldb_private::CompilerDeclContext &parent_decl_ctx, 12606c3fb27SDimitry Andric uint32_t max_matches, 12706c3fb27SDimitry Andric lldb_private::VariableList &variables) override; 12806c3fb27SDimitry Andric 12906c3fb27SDimitry Andric void FindGlobalVariables(const lldb_private::RegularExpression ®ex, 13006c3fb27SDimitry Andric uint32_t max_matches, 13106c3fb27SDimitry Andric lldb_private::VariableList &variables) override; 13206c3fb27SDimitry Andric 13306c3fb27SDimitry Andric enum TypeKind : uint32_t { 13406c3fb27SDimitry Andric eUnknown = 0, 13506c3fb27SDimitry Andric eInteger = 1, 13606c3fb27SDimitry Andric eFloat = 2, 13706c3fb27SDimitry Andric ePointer = 3, 13806c3fb27SDimitry Andric eArray = 4, 13906c3fb27SDimitry Andric eFunction = 5, 14006c3fb27SDimitry Andric eStruct = 6, 14106c3fb27SDimitry Andric eUnion = 7, 14206c3fb27SDimitry Andric eEnum = 8, 14306c3fb27SDimitry Andric eForward = 9, 14406c3fb27SDimitry Andric eTypedef = 10, 14506c3fb27SDimitry Andric eVolatile = 11, 14606c3fb27SDimitry Andric eConst = 12, 14706c3fb27SDimitry Andric eRestrict = 13, 14806c3fb27SDimitry Andric eSlice = 14, 14906c3fb27SDimitry Andric }; 15006c3fb27SDimitry Andric 15106c3fb27SDimitry Andric private: 15206c3fb27SDimitry Andric enum Flags : uint32_t { 15306c3fb27SDimitry Andric eFlagCompress = (1u << 0), 15406c3fb27SDimitry Andric eFlagNewFuncInfo = (1u << 1), 15506c3fb27SDimitry Andric eFlagIdxSorted = (1u << 2), 15606c3fb27SDimitry Andric eFlagDynStr = (1u << 3), 15706c3fb27SDimitry Andric }; 15806c3fb27SDimitry Andric 15906c3fb27SDimitry Andric enum IntEncoding : uint32_t { 16006c3fb27SDimitry Andric eSigned = 0x1, 16106c3fb27SDimitry Andric eChar = 0x2, 16206c3fb27SDimitry Andric eBool = 0x4, 16306c3fb27SDimitry Andric eVarArgs = 0x8, 16406c3fb27SDimitry Andric }; 16506c3fb27SDimitry Andric 16606c3fb27SDimitry Andric struct ctf_preamble_t { 16706c3fb27SDimitry Andric uint16_t magic; 16806c3fb27SDimitry Andric uint8_t version; 16906c3fb27SDimitry Andric uint8_t flags; 17006c3fb27SDimitry Andric }; 17106c3fb27SDimitry Andric 17206c3fb27SDimitry Andric struct ctf_header_t { 17306c3fb27SDimitry Andric ctf_preamble_t preamble; 17406c3fb27SDimitry Andric uint32_t parlabel; 17506c3fb27SDimitry Andric uint32_t parname; 17606c3fb27SDimitry Andric uint32_t lbloff; 17706c3fb27SDimitry Andric uint32_t objtoff; 17806c3fb27SDimitry Andric uint32_t funcoff; 17906c3fb27SDimitry Andric uint32_t typeoff; 18006c3fb27SDimitry Andric uint32_t stroff; 18106c3fb27SDimitry Andric uint32_t strlen; 18206c3fb27SDimitry Andric }; 18306c3fb27SDimitry Andric 18406c3fb27SDimitry Andric struct ctf_type_t { 18506c3fb27SDimitry Andric uint32_t name; 18606c3fb27SDimitry Andric uint32_t info; 18706c3fb27SDimitry Andric union { 18806c3fb27SDimitry Andric uint32_t size; 18906c3fb27SDimitry Andric uint32_t type; 19006c3fb27SDimitry Andric }; 19106c3fb27SDimitry Andric uint32_t lsizehi; 19206c3fb27SDimitry Andric uint32_t lsizelo; 19306c3fb27SDimitry Andric }; 19406c3fb27SDimitry Andric 19506c3fb27SDimitry Andric struct ctf_stype_t { 19606c3fb27SDimitry Andric uint32_t name; 19706c3fb27SDimitry Andric uint32_t info; 19806c3fb27SDimitry Andric union { 19906c3fb27SDimitry Andric uint32_t size; 20006c3fb27SDimitry Andric uint32_t type; 20106c3fb27SDimitry Andric }; 20206c3fb27SDimitry Andric IsLargeTypectf_stype_t20306c3fb27SDimitry Andric bool IsLargeType() const { return size == 0xffff; } GetStructSizectf_stype_t20406c3fb27SDimitry Andric uint32_t GetStructSize() const { 20506c3fb27SDimitry Andric if (IsLargeType()) 20606c3fb27SDimitry Andric return sizeof(ctf_type_t); 20706c3fb27SDimitry Andric return sizeof(ctf_stype_t); 20806c3fb27SDimitry Andric } GetTypectf_stype_t20906c3fb27SDimitry Andric uint32_t GetType() const { return type; } GetSizectf_stype_t21006c3fb27SDimitry Andric uint32_t GetSize() const { return size; } 21106c3fb27SDimitry Andric }; 21206c3fb27SDimitry Andric 2135f757f3fSDimitry Andric llvm::Expected<std::unique_ptr<CTFType>> ParseType(lldb::offset_t &offset, 2145f757f3fSDimitry Andric lldb::user_id_t uid); 21506c3fb27SDimitry Andric 2165f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateType(CTFType *ctf_type); 2175f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateInteger(const CTFInteger &ctf_integer); 2185f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateModifier(const CTFModifier &ctf_modifier); 2195f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateTypedef(const CTFTypedef &ctf_typedef); 2205f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateArray(const CTFArray &ctf_array); 2215f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateEnum(const CTFEnum &ctf_enum); 2225f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateFunction(const CTFFunction &ctf_function); 2235f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateRecord(const CTFRecord &ctf_record); 2245f757f3fSDimitry Andric llvm::Expected<lldb::TypeSP> CreateForward(const CTFForward &ctf_forward); 22506c3fb27SDimitry Andric 22606c3fb27SDimitry Andric llvm::StringRef ReadString(lldb::offset_t offset) const; 22706c3fb27SDimitry Andric 22806c3fb27SDimitry Andric std::vector<uint16_t> GetFieldSizes(lldb::offset_t field_offset, 22906c3fb27SDimitry Andric uint32_t fields, uint32_t struct_size); 23006c3fb27SDimitry Andric 23106c3fb27SDimitry Andric DataExtractor m_data; 23206c3fb27SDimitry Andric 23306c3fb27SDimitry Andric /// The start offset of the CTF body into m_data. If the body is uncompressed, 23406c3fb27SDimitry Andric /// m_data contains the header and the body and the body starts after the 23506c3fb27SDimitry Andric /// header. If the body is compressed, m_data only contains the body and the 23606c3fb27SDimitry Andric /// offset is zero. 23706c3fb27SDimitry Andric lldb::offset_t m_body_offset = 0; 23806c3fb27SDimitry Andric 23906c3fb27SDimitry Andric TypeSystemClang *m_ast; 24006c3fb27SDimitry Andric lldb::CompUnitSP m_comp_unit_sp; 24106c3fb27SDimitry Andric 24206c3fb27SDimitry Andric std::optional<ctf_header_t> m_header; 2435f757f3fSDimitry Andric 2445f757f3fSDimitry Andric /// Parsed CTF types. 2455f757f3fSDimitry Andric llvm::DenseMap<lldb::user_id_t, std::unique_ptr<CTFType>> m_ctf_types; 2465f757f3fSDimitry Andric 2475f757f3fSDimitry Andric /// Parsed LLDB types. 2485f757f3fSDimitry Andric llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types; 2495f757f3fSDimitry Andric 2505f757f3fSDimitry Andric /// To complete types, we need a way to map (imcomplete) compiler types back 2515f757f3fSDimitry Andric /// to parsed CTF types. 2525f757f3fSDimitry Andric llvm::DenseMap<lldb::opaque_compiler_type_t, const CTFType *> 2535f757f3fSDimitry Andric m_compiler_types; 2545f757f3fSDimitry Andric 25506c3fb27SDimitry Andric std::vector<lldb::FunctionSP> m_functions; 25606c3fb27SDimitry Andric std::vector<lldb::VariableSP> m_variables; 25706c3fb27SDimitry Andric 25806c3fb27SDimitry Andric static constexpr uint16_t g_ctf_magic = 0xcff1; 25906c3fb27SDimitry Andric static constexpr uint8_t g_ctf_version = 4; 2605f757f3fSDimitry Andric static constexpr uint16_t g_ctf_field_threshold = 0x2000; 26106c3fb27SDimitry Andric }; 26206c3fb27SDimitry Andric } // namespace lldb_private 26306c3fb27SDimitry Andric 26406c3fb27SDimitry Andric #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 265