1 //===-- AppleObjCRuntimeV2.h ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_AppleObjCRuntimeV2_h_
11 #define liblldb_AppleObjCRuntimeV2_h_
19 // Other libraries and framework includes
21 #include "AppleObjCRuntime.h"
22 #include "lldb/Target/ObjCLanguageRuntime.h"
23 #include "lldb/lldb-private.h"
25 class RemoteNXMapTable;
27 namespace lldb_private {
29 class AppleObjCRuntimeV2 : public AppleObjCRuntime {
31 ~AppleObjCRuntimeV2() override = default;
33 //------------------------------------------------------------------
35 //------------------------------------------------------------------
36 static void Initialize();
38 static void Terminate();
40 static lldb_private::LanguageRuntime *
41 CreateInstance(Process *process, lldb::LanguageType language);
43 static lldb_private::ConstString GetPluginNameStatic();
45 static bool classof(const ObjCLanguageRuntime *runtime) {
46 switch (runtime->GetRuntimeVersion()) {
47 case ObjCRuntimeVersions::eAppleObjC_V2:
54 // These are generic runtime functions:
55 bool GetDynamicTypeAndAddress(ValueObject &in_value,
56 lldb::DynamicValueType use_dynamic,
57 TypeAndOrName &class_type_or_name,
59 Value::ValueType &value_type) override;
61 UtilityFunction *CreateObjectChecker(const char *) override;
63 //------------------------------------------------------------------
64 // PluginInterface protocol
65 //------------------------------------------------------------------
66 ConstString GetPluginName() override;
68 uint32_t GetPluginVersion() override;
70 ObjCRuntimeVersions GetRuntimeVersion() const override {
71 return ObjCRuntimeVersions::eAppleObjC_V2;
74 size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
75 const char *ivar_name) override;
77 void UpdateISAToDescriptorMapIfNeeded() override;
79 ConstString GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) override;
81 ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override;
83 ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override;
85 DeclVendor *GetDeclVendor() override;
87 lldb::addr_t LookupRuntimeSymbol(const ConstString &name) override;
89 EncodingToTypeSP GetEncodingToType() override;
91 bool IsTaggedPointer(lldb::addr_t ptr) override;
93 TaggedPointerVendor *GetTaggedPointerVendor() override {
94 return m_tagged_pointer_vendor_ap.get();
97 lldb::addr_t GetTaggedPointerObfuscator();
99 void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
100 lldb::addr_t &cf_false) override;
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 =
112 static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
115 lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
117 bool throw_bp) override;
120 class HashTableSignature {
122 HashTableSignature();
124 bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
125 RemoteNXMapTable &hash_table);
127 void UpdateSignature(const RemoteNXMapTable &hash_table);
131 uint32_t m_num_buckets;
132 lldb::addr_t m_buckets_ptr;
135 class NonPointerISACache {
137 static NonPointerISACache *
138 CreateInstance(AppleObjCRuntimeV2 &runtime,
139 const lldb::ModuleSP &objc_module_sp);
141 ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa);
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);
155 bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
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;
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;
170 std::vector<lldb::addr_t> m_indexed_isa_cache;
172 friend class AppleObjCRuntimeV2;
174 DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
177 class TaggedPointerVendorV2
178 : public ObjCLanguageRuntime::TaggedPointerVendor {
180 ~TaggedPointerVendorV2() override = default;
182 static TaggedPointerVendorV2 *
183 CreateInstance(AppleObjCRuntimeV2 &runtime,
184 const lldb::ModuleSP &objc_module_sp);
187 AppleObjCRuntimeV2 &m_runtime;
189 TaggedPointerVendorV2(AppleObjCRuntimeV2 &runtime)
190 : TaggedPointerVendor(), m_runtime(runtime) {}
193 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
196 class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
198 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
200 ObjCLanguageRuntime::ClassDescriptorSP
201 GetClassDescriptor(lldb::addr_t ptr) override;
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);
212 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
213 typedef Cache::iterator CacheIterator;
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;
222 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
224 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
227 class TaggedPointerVendorExtended
228 : public TaggedPointerVendorRuntimeAssisted {
230 ObjCLanguageRuntime::ClassDescriptorSP
231 GetClassDescriptor(lldb::addr_t ptr) override;
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);
248 bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr);
250 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
251 typedef Cache::iterator CacheIterator;
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;
260 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
262 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
265 class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
267 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
269 ObjCLanguageRuntime::ClassDescriptorSP
270 GetClassDescriptor(lldb::addr_t ptr) override;
273 TaggedPointerVendorLegacy(AppleObjCRuntimeV2 &runtime)
274 : TaggedPointerVendorV2(runtime) {}
276 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
278 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
281 struct DescriptorMapUpdateResult {
283 uint32_t m_num_found;
285 DescriptorMapUpdateResult(bool ran, uint32_t found) {
290 static DescriptorMapUpdateResult Fail() { return {false, 0}; }
292 static DescriptorMapUpdateResult Success(uint32_t found) {
293 return {true, found};
297 AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
299 ObjCISA GetPointerISA(ObjCISA isa);
301 lldb::addr_t GetISAHashTablePointer();
303 bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
305 DescriptorMapUpdateResult
306 UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
308 uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
309 uint32_t num_class_infos);
311 DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
313 enum class SharedCacheWarningReason {
314 eExpressionExecutionFailure,
315 eNotEnoughClassesRead
318 void WarnIfNoClassesCached(SharedCacheWarningReason reason);
320 lldb::addr_t GetSharedCacheReadOnlyAddress();
322 bool GetCFBooleanValuesIfNeeded();
324 friend class ClassDescriptorV2;
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;
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;
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;
347 } // namespace lldb_private
349 #endif // liblldb_AppleObjCRuntimeV2_h_