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