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_
17 #include "AppleObjCRuntime.h"
18 #include "lldb/Target/ObjCLanguageRuntime.h"
19 #include "lldb/lldb-private.h"
21 class RemoteNXMapTable;
23 namespace lldb_private {
25 class AppleObjCRuntimeV2 : public AppleObjCRuntime {
27 ~AppleObjCRuntimeV2() override = default;
29 //------------------------------------------------------------------
31 //------------------------------------------------------------------
32 static void Initialize();
34 static void Terminate();
36 static lldb_private::LanguageRuntime *
37 CreateInstance(Process *process, lldb::LanguageType language);
39 static lldb_private::ConstString GetPluginNameStatic();
41 static bool classof(const ObjCLanguageRuntime *runtime) {
42 switch (runtime->GetRuntimeVersion()) {
43 case ObjCRuntimeVersions::eAppleObjC_V2:
50 // These are generic runtime functions:
51 bool GetDynamicTypeAndAddress(ValueObject &in_value,
52 lldb::DynamicValueType use_dynamic,
53 TypeAndOrName &class_type_or_name,
55 Value::ValueType &value_type) override;
57 UtilityFunction *CreateObjectChecker(const char *) override;
59 //------------------------------------------------------------------
60 // PluginInterface protocol
61 //------------------------------------------------------------------
62 ConstString GetPluginName() override;
64 uint32_t GetPluginVersion() override;
66 ObjCRuntimeVersions GetRuntimeVersion() const override {
67 return ObjCRuntimeVersions::eAppleObjC_V2;
70 size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
71 const char *ivar_name) override;
73 void UpdateISAToDescriptorMapIfNeeded() override;
75 ConstString GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) override;
77 ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override;
79 ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override;
81 DeclVendor *GetDeclVendor() override;
83 lldb::addr_t LookupRuntimeSymbol(const ConstString &name) override;
85 EncodingToTypeSP GetEncodingToType() override;
87 bool IsTaggedPointer(lldb::addr_t ptr) override;
89 TaggedPointerVendor *GetTaggedPointerVendor() override {
90 return m_tagged_pointer_vendor_ap.get();
93 lldb::addr_t GetTaggedPointerObfuscator();
95 void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
96 lldb::addr_t &cf_false) override;
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 =
108 static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
111 lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
113 bool throw_bp) override;
116 class HashTableSignature {
118 HashTableSignature();
120 bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
121 RemoteNXMapTable &hash_table);
123 void UpdateSignature(const RemoteNXMapTable &hash_table);
127 uint32_t m_num_buckets;
128 lldb::addr_t m_buckets_ptr;
131 class NonPointerISACache {
133 static NonPointerISACache *
134 CreateInstance(AppleObjCRuntimeV2 &runtime,
135 const lldb::ModuleSP &objc_module_sp);
137 ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa);
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);
151 bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
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;
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;
166 std::vector<lldb::addr_t> m_indexed_isa_cache;
168 friend class AppleObjCRuntimeV2;
170 DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
173 class TaggedPointerVendorV2
174 : public ObjCLanguageRuntime::TaggedPointerVendor {
176 ~TaggedPointerVendorV2() override = default;
178 static TaggedPointerVendorV2 *
179 CreateInstance(AppleObjCRuntimeV2 &runtime,
180 const lldb::ModuleSP &objc_module_sp);
183 AppleObjCRuntimeV2 &m_runtime;
185 TaggedPointerVendorV2(AppleObjCRuntimeV2 &runtime)
186 : TaggedPointerVendor(), m_runtime(runtime) {}
189 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
192 class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
194 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
196 ObjCLanguageRuntime::ClassDescriptorSP
197 GetClassDescriptor(lldb::addr_t ptr) override;
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);
208 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
209 typedef Cache::iterator CacheIterator;
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;
218 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
220 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
223 class TaggedPointerVendorExtended
224 : public TaggedPointerVendorRuntimeAssisted {
226 ObjCLanguageRuntime::ClassDescriptorSP
227 GetClassDescriptor(lldb::addr_t ptr) override;
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);
244 bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr);
246 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
247 typedef Cache::iterator CacheIterator;
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;
256 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
258 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
261 class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
263 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
265 ObjCLanguageRuntime::ClassDescriptorSP
266 GetClassDescriptor(lldb::addr_t ptr) override;
269 TaggedPointerVendorLegacy(AppleObjCRuntimeV2 &runtime)
270 : TaggedPointerVendorV2(runtime) {}
272 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
274 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
277 struct DescriptorMapUpdateResult {
279 uint32_t m_num_found;
281 DescriptorMapUpdateResult(bool ran, uint32_t found) {
286 static DescriptorMapUpdateResult Fail() { return {false, 0}; }
288 static DescriptorMapUpdateResult Success(uint32_t found) {
289 return {true, found};
293 AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
295 ObjCISA GetPointerISA(ObjCISA isa);
297 lldb::addr_t GetISAHashTablePointer();
299 bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
301 DescriptorMapUpdateResult
302 UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
304 uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
305 uint32_t num_class_infos);
307 DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
309 enum class SharedCacheWarningReason {
310 eExpressionExecutionFailure,
311 eNotEnoughClassesRead
314 void WarnIfNoClassesCached(SharedCacheWarningReason reason);
316 lldb::addr_t GetSharedCacheReadOnlyAddress();
318 bool GetCFBooleanValuesIfNeeded();
320 friend class ClassDescriptorV2;
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;
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;
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;
343 } // namespace lldb_private
345 #endif // liblldb_AppleObjCRuntimeV2_h_