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