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