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 &regex,
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 &regex,
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 &regex,
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