]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
Fix a memory leak in if_delgroups() introduced in r334118.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / LanguageRuntime / ObjC / AppleObjCRuntime / AppleObjCRuntimeV2.h
1 //===-- AppleObjCRuntimeV2.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 liblldb_AppleObjCRuntimeV2_h_
10 #define liblldb_AppleObjCRuntimeV2_h_
11
12 #include <map>
13 #include <memory>
14 #include <mutex>
15
16 #include "AppleObjCRuntime.h"
17 #include "lldb/lldb-private.h"
18
19 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
20
21 class RemoteNXMapTable;
22
23 namespace lldb_private {
24
25 class AppleObjCRuntimeV2 : public AppleObjCRuntime {
26 public:
27   ~AppleObjCRuntimeV2() override = default;
28
29   // Static Functions
30   static void Initialize();
31
32   static void Terminate();
33
34   static lldb_private::LanguageRuntime *
35   CreateInstance(Process *process, lldb::LanguageType language);
36
37   static lldb_private::ConstString GetPluginNameStatic();
38
39   static char ID;
40
41   bool isA(const void *ClassID) const override {
42     return ClassID == &ID || AppleObjCRuntime::isA(ClassID);
43   }
44
45   static bool classof(const LanguageRuntime *runtime) {
46     return runtime->isA(&ID);
47   }
48
49   // These are generic runtime functions:
50   bool GetDynamicTypeAndAddress(ValueObject &in_value,
51                                 lldb::DynamicValueType use_dynamic,
52                                 TypeAndOrName &class_type_or_name,
53                                 Address &address,
54                                 Value::ValueType &value_type) override;
55
56   UtilityFunction *CreateObjectChecker(const char *) override;
57
58   // PluginInterface protocol
59   ConstString GetPluginName() override;
60
61   uint32_t GetPluginVersion() override;
62
63   ObjCRuntimeVersions GetRuntimeVersion() const override {
64     return ObjCRuntimeVersions::eAppleObjC_V2;
65   }
66
67   size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
68                               const char *ivar_name) override;
69
70   void UpdateISAToDescriptorMapIfNeeded() override;
71
72   ConstString GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) override;
73
74   ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override;
75
76   ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override;
77
78   DeclVendor *GetDeclVendor() override;
79
80   lldb::addr_t LookupRuntimeSymbol(ConstString name) override;
81
82   EncodingToTypeSP GetEncodingToType() override;
83
84   bool IsTaggedPointer(lldb::addr_t ptr) override;
85
86   TaggedPointerVendor *GetTaggedPointerVendor() override {
87     return m_tagged_pointer_vendor_up.get();
88   }
89
90   lldb::addr_t GetTaggedPointerObfuscator();
91
92   void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
93                                     lldb::addr_t &cf_false) override;
94
95   // none of these are valid ISAs - we use them to infer the type
96   // of tagged pointers - if we have something meaningful to say
97   // we report an actual type - otherwise, we just say tagged
98   // there is no connection between the values here and the tagged pointers map
99   static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
100   static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
101   static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
102   static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
103   static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject =
104       5;
105   static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
106
107 protected:
108   lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
109                                                      bool catch_bp,
110                                                      bool throw_bp) override;
111
112 private:
113   class HashTableSignature {
114   public:
115     HashTableSignature();
116
117     bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
118                      RemoteNXMapTable &hash_table);
119
120     void UpdateSignature(const RemoteNXMapTable &hash_table);
121
122   protected:
123     uint32_t m_count;
124     uint32_t m_num_buckets;
125     lldb::addr_t m_buckets_ptr;
126   };
127
128   class NonPointerISACache {
129   public:
130     static NonPointerISACache *
131     CreateInstance(AppleObjCRuntimeV2 &runtime,
132                    const lldb::ModuleSP &objc_module_sp);
133
134     ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa);
135
136   private:
137     NonPointerISACache(AppleObjCRuntimeV2 &runtime,
138                        const lldb::ModuleSP &objc_module_sp,
139                        uint64_t objc_debug_isa_class_mask,
140                        uint64_t objc_debug_isa_magic_mask,
141                        uint64_t objc_debug_isa_magic_value,
142                        uint64_t objc_debug_indexed_isa_magic_mask,
143                        uint64_t objc_debug_indexed_isa_magic_value,
144                        uint64_t objc_debug_indexed_isa_index_mask,
145                        uint64_t objc_debug_indexed_isa_index_shift,
146                        lldb::addr_t objc_indexed_classes);
147
148     bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
149
150     AppleObjCRuntimeV2 &m_runtime;
151     std::map<ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
152     lldb::ModuleWP m_objc_module_wp;
153     uint64_t m_objc_debug_isa_class_mask;
154     uint64_t m_objc_debug_isa_magic_mask;
155     uint64_t m_objc_debug_isa_magic_value;
156
157     uint64_t m_objc_debug_indexed_isa_magic_mask;
158     uint64_t m_objc_debug_indexed_isa_magic_value;
159     uint64_t m_objc_debug_indexed_isa_index_mask;
160     uint64_t m_objc_debug_indexed_isa_index_shift;
161     lldb::addr_t m_objc_indexed_classes;
162
163     std::vector<lldb::addr_t> m_indexed_isa_cache;
164
165     friend class AppleObjCRuntimeV2;
166
167     DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
168   };
169
170   class TaggedPointerVendorV2
171       : public ObjCLanguageRuntime::TaggedPointerVendor {
172   public:
173     ~TaggedPointerVendorV2() override = default;
174
175     static TaggedPointerVendorV2 *
176     CreateInstance(AppleObjCRuntimeV2 &runtime,
177                    const lldb::ModuleSP &objc_module_sp);
178
179   protected:
180     AppleObjCRuntimeV2 &m_runtime;
181
182     TaggedPointerVendorV2(AppleObjCRuntimeV2 &runtime)
183         : TaggedPointerVendor(), m_runtime(runtime) {}
184
185   private:
186     DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
187   };
188
189   class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
190   public:
191     bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
192
193     ObjCLanguageRuntime::ClassDescriptorSP
194     GetClassDescriptor(lldb::addr_t ptr) override;
195
196   protected:
197     TaggedPointerVendorRuntimeAssisted(
198         AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
199         uint32_t objc_debug_taggedpointer_slot_shift,
200         uint32_t objc_debug_taggedpointer_slot_mask,
201         uint32_t objc_debug_taggedpointer_payload_lshift,
202         uint32_t objc_debug_taggedpointer_payload_rshift,
203         lldb::addr_t objc_debug_taggedpointer_classes);
204
205     typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
206     typedef Cache::iterator CacheIterator;
207     Cache m_cache;
208     uint64_t m_objc_debug_taggedpointer_mask;
209     uint32_t m_objc_debug_taggedpointer_slot_shift;
210     uint32_t m_objc_debug_taggedpointer_slot_mask;
211     uint32_t m_objc_debug_taggedpointer_payload_lshift;
212     uint32_t m_objc_debug_taggedpointer_payload_rshift;
213     lldb::addr_t m_objc_debug_taggedpointer_classes;
214
215     friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
216
217     DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
218   };
219
220   class TaggedPointerVendorExtended
221       : public TaggedPointerVendorRuntimeAssisted {
222   public:
223     ObjCLanguageRuntime::ClassDescriptorSP
224     GetClassDescriptor(lldb::addr_t ptr) override;
225
226   protected:
227     TaggedPointerVendorExtended(
228         AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
229         uint64_t objc_debug_taggedpointer_ext_mask,
230         uint32_t objc_debug_taggedpointer_slot_shift,
231         uint32_t objc_debug_taggedpointer_ext_slot_shift,
232         uint32_t objc_debug_taggedpointer_slot_mask,
233         uint32_t objc_debug_taggedpointer_ext_slot_mask,
234         uint32_t objc_debug_taggedpointer_payload_lshift,
235         uint32_t objc_debug_taggedpointer_payload_rshift,
236         uint32_t objc_debug_taggedpointer_ext_payload_lshift,
237         uint32_t objc_debug_taggedpointer_ext_payload_rshift,
238         lldb::addr_t objc_debug_taggedpointer_classes,
239         lldb::addr_t objc_debug_taggedpointer_ext_classes);
240
241     bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr);
242
243     typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
244     typedef Cache::iterator CacheIterator;
245     Cache m_ext_cache;
246     uint64_t m_objc_debug_taggedpointer_ext_mask;
247     uint32_t m_objc_debug_taggedpointer_ext_slot_shift;
248     uint32_t m_objc_debug_taggedpointer_ext_slot_mask;
249     uint32_t m_objc_debug_taggedpointer_ext_payload_lshift;
250     uint32_t m_objc_debug_taggedpointer_ext_payload_rshift;
251     lldb::addr_t m_objc_debug_taggedpointer_ext_classes;
252
253     friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
254
255     DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
256   };
257
258   class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
259   public:
260     bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
261
262     ObjCLanguageRuntime::ClassDescriptorSP
263     GetClassDescriptor(lldb::addr_t ptr) override;
264
265   protected:
266     TaggedPointerVendorLegacy(AppleObjCRuntimeV2 &runtime)
267         : TaggedPointerVendorV2(runtime) {}
268
269     friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
270
271     DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
272   };
273
274   struct DescriptorMapUpdateResult {
275     bool m_update_ran;
276     uint32_t m_num_found;
277
278     DescriptorMapUpdateResult(bool ran, uint32_t found) {
279       m_update_ran = ran;
280       m_num_found = found;
281     }
282
283     static DescriptorMapUpdateResult Fail() { return {false, 0}; }
284
285     static DescriptorMapUpdateResult Success(uint32_t found) {
286       return {true, found};
287     }
288   };
289
290   AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
291
292   ObjCISA GetPointerISA(ObjCISA isa);
293
294   lldb::addr_t GetISAHashTablePointer();
295
296   bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
297
298   DescriptorMapUpdateResult
299   UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
300
301   uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
302                                uint32_t num_class_infos);
303
304   DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
305
306   enum class SharedCacheWarningReason {
307     eExpressionExecutionFailure,
308     eNotEnoughClassesRead
309   };
310
311   void WarnIfNoClassesCached(SharedCacheWarningReason reason);
312
313   lldb::addr_t GetSharedCacheReadOnlyAddress();
314
315   bool GetCFBooleanValuesIfNeeded();
316
317   friend class ClassDescriptorV2;
318
319   std::unique_ptr<UtilityFunction> m_get_class_info_code;
320   lldb::addr_t m_get_class_info_args;
321   std::mutex m_get_class_info_args_mutex;
322
323   std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
324   lldb::addr_t m_get_shared_cache_class_info_args;
325   std::mutex m_get_shared_cache_class_info_args_mutex;
326
327   std::unique_ptr<DeclVendor> m_decl_vendor_up;
328   lldb::addr_t m_tagged_pointer_obfuscator;
329   lldb::addr_t m_isa_hash_table_ptr;
330   HashTableSignature m_hash_signature;
331   bool m_has_object_getClass;
332   bool m_loaded_objc_opt;
333   std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up;
334   std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up;
335   EncodingToTypeSP m_encoding_to_type_sp;
336   bool m_noclasses_warning_emitted;
337   llvm::Optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
338 };
339
340 } // namespace lldb_private
341
342 #endif // liblldb_AppleObjCRuntimeV2_h_