xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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 &regex,
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 &regex,
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 &regex,
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