265 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H10#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H11 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 20namespace lldb_private {21 22class SymbolFileCTF : public lldb_private::SymbolFileCommon {23 /// LLVM RTTI support.24 static char ID;25 26public: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 void124 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 151private: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 the235 /// header. If the body is compressed, m_data only contains the body and the236 /// 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 back251 /// 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_private263 264#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H265