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