1 //===-- AppleObjCRuntimeV2.h ------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_AppleObjCRuntimeV2_h_
10 #define liblldb_AppleObjCRuntimeV2_h_
16 #include "AppleObjCRuntime.h"
17 #include "lldb/lldb-private.h"
19 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
21 class RemoteNXMapTable;
23 namespace lldb_private {
25 class AppleObjCRuntimeV2 : public AppleObjCRuntime {
27 ~AppleObjCRuntimeV2() override = default;
30 static void Initialize();
32 static void Terminate();
34 static lldb_private::LanguageRuntime *
35 CreateInstance(Process *process, lldb::LanguageType language);
37 static lldb_private::ConstString GetPluginNameStatic();
41 bool isA(const void *ClassID) const override {
42 return ClassID == &ID || AppleObjCRuntime::isA(ClassID);
45 static bool classof(const LanguageRuntime *runtime) {
46 return runtime->isA(&ID);
49 // These are generic runtime functions:
50 bool GetDynamicTypeAndAddress(ValueObject &in_value,
51 lldb::DynamicValueType use_dynamic,
52 TypeAndOrName &class_type_or_name,
54 Value::ValueType &value_type) override;
56 UtilityFunction *CreateObjectChecker(const char *) override;
58 // PluginInterface protocol
59 ConstString GetPluginName() override;
61 uint32_t GetPluginVersion() override;
63 ObjCRuntimeVersions GetRuntimeVersion() const override {
64 return ObjCRuntimeVersions::eAppleObjC_V2;
67 size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
68 const char *ivar_name) override;
70 void UpdateISAToDescriptorMapIfNeeded() override;
72 ConstString GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) override;
74 ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override;
76 ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override;
78 DeclVendor *GetDeclVendor() override;
80 lldb::addr_t LookupRuntimeSymbol(ConstString name) override;
82 EncodingToTypeSP GetEncodingToType() override;
84 bool IsTaggedPointer(lldb::addr_t ptr) override;
86 TaggedPointerVendor *GetTaggedPointerVendor() override {
87 return m_tagged_pointer_vendor_up.get();
90 lldb::addr_t GetTaggedPointerObfuscator();
92 void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
93 lldb::addr_t &cf_false) override;
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 =
105 static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
108 lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
110 bool throw_bp) override;
113 class HashTableSignature {
115 HashTableSignature();
117 bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
118 RemoteNXMapTable &hash_table);
120 void UpdateSignature(const RemoteNXMapTable &hash_table);
124 uint32_t m_num_buckets;
125 lldb::addr_t m_buckets_ptr;
128 class NonPointerISACache {
130 static NonPointerISACache *
131 CreateInstance(AppleObjCRuntimeV2 &runtime,
132 const lldb::ModuleSP &objc_module_sp);
134 ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa);
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);
148 bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
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;
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;
163 std::vector<lldb::addr_t> m_indexed_isa_cache;
165 friend class AppleObjCRuntimeV2;
167 DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
170 class TaggedPointerVendorV2
171 : public ObjCLanguageRuntime::TaggedPointerVendor {
173 ~TaggedPointerVendorV2() override = default;
175 static TaggedPointerVendorV2 *
176 CreateInstance(AppleObjCRuntimeV2 &runtime,
177 const lldb::ModuleSP &objc_module_sp);
180 AppleObjCRuntimeV2 &m_runtime;
182 TaggedPointerVendorV2(AppleObjCRuntimeV2 &runtime)
183 : TaggedPointerVendor(), m_runtime(runtime) {}
186 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
189 class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
191 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
193 ObjCLanguageRuntime::ClassDescriptorSP
194 GetClassDescriptor(lldb::addr_t ptr) override;
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);
205 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
206 typedef Cache::iterator CacheIterator;
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;
215 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
217 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
220 class TaggedPointerVendorExtended
221 : public TaggedPointerVendorRuntimeAssisted {
223 ObjCLanguageRuntime::ClassDescriptorSP
224 GetClassDescriptor(lldb::addr_t ptr) override;
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);
241 bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr);
243 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
244 typedef Cache::iterator CacheIterator;
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;
253 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
255 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
258 class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
260 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
262 ObjCLanguageRuntime::ClassDescriptorSP
263 GetClassDescriptor(lldb::addr_t ptr) override;
266 TaggedPointerVendorLegacy(AppleObjCRuntimeV2 &runtime)
267 : TaggedPointerVendorV2(runtime) {}
269 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
271 DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
274 struct DescriptorMapUpdateResult {
276 uint32_t m_num_found;
278 DescriptorMapUpdateResult(bool ran, uint32_t found) {
283 static DescriptorMapUpdateResult Fail() { return {false, 0}; }
285 static DescriptorMapUpdateResult Success(uint32_t found) {
286 return {true, found};
290 AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
292 ObjCISA GetPointerISA(ObjCISA isa);
294 lldb::addr_t GetISAHashTablePointer();
296 bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
298 DescriptorMapUpdateResult
299 UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
301 uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
302 uint32_t num_class_infos);
304 DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
306 enum class SharedCacheWarningReason {
307 eExpressionExecutionFailure,
308 eNotEnoughClassesRead
311 void WarnIfNoClassesCached(SharedCacheWarningReason reason);
313 lldb::addr_t GetSharedCacheReadOnlyAddress();
315 bool GetCFBooleanValuesIfNeeded();
317 friend class ClassDescriptorV2;
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;
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;
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;
340 } // namespace lldb_private
342 #endif // liblldb_AppleObjCRuntimeV2_h_