LLDB mainline
AppleObjCRuntimeV2.h
Go to the documentation of this file.
1//===-- AppleObjCRuntimeV2.h ------------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
10#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
11
12#include <map>
13#include <memory>
14#include <mutex>
15#include <optional>
16
17#include "AppleObjCRuntime.h"
18#include "lldb/lldb-private.h"
19
21
22#include "llvm/ADT/BitVector.h"
23
25
26namespace lldb_private {
27
29public:
30 ~AppleObjCRuntimeV2() override = default;
31
32 static void Initialize();
33
34 static void Terminate();
35
37 CreateInstance(Process *process, lldb::LanguageType language);
38
39 static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v2"; }
40
42
43 static char ID;
44
45 bool isA(const void *ClassID) const override {
46 return ClassID == &ID || AppleObjCRuntime::isA(ClassID);
47 }
48
49 static bool classof(const LanguageRuntime *runtime) {
50 return runtime->isA(&ID);
51 }
52
54 lldb::DynamicValueType use_dynamic,
55 TypeAndOrName &class_type_or_name,
56 Address &address,
57 Value::ValueType &value_type) override;
58
59 llvm::Expected<std::unique_ptr<UtilityFunction>>
60 CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override;
61
62 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
63
66 }
67
68 size_t GetByteOffsetForIvar(CompilerType &parent_ast_type,
69 const char *ivar_name) override;
70
72
74
76
77 DeclVendor *GetDeclVendor() override;
78
80
82
83 bool IsTaggedPointer(lldb::addr_t ptr) override;
84
86 return m_tagged_pointer_vendor_up.get();
87 }
88
90
91 /// Returns the base address for relative method list selector strings.
94 }
95
96 void SetRelativeSelectorBaseAddr(lldb::addr_t relative_selector_base) {
97 m_relative_selector_base = relative_selector_base;
98 }
99
101 lldb::addr_t &cf_false) override;
102
103 void ModulesDidLoad(const ModuleList &module_list) override;
104
105 bool IsSharedCacheImageLoaded(uint16_t image_index);
106
107 std::optional<uint64_t> GetSharedCacheImageHeaderVersion();
108
110
111protected:
113 CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
114 bool throw_bp) override;
115
116private:
118 public:
120
121 bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
122 RemoteNXMapTable &hash_table);
123
124 void UpdateSignature(const RemoteNXMapTable &hash_table);
125
126 protected:
127 uint32_t m_count = 0;
128 uint32_t m_num_buckets = 0;
130 };
131
133 public:
134 static NonPointerISACache *
136 const lldb::ModuleSP &objc_module_sp);
137
139
140 private:
142 const lldb::ModuleSP &objc_module_sp,
143 uint64_t objc_debug_isa_class_mask,
144 uint64_t objc_debug_isa_magic_mask,
145 uint64_t objc_debug_isa_magic_value,
146 uint64_t objc_debug_indexed_isa_magic_mask,
147 uint64_t objc_debug_indexed_isa_magic_value,
148 uint64_t objc_debug_indexed_isa_index_mask,
149 uint64_t objc_debug_indexed_isa_index_shift,
150 lldb::addr_t objc_indexed_classes);
151
152 bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
153
155 std::map<ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
160
166
167 std::vector<lldb::addr_t> m_indexed_isa_cache;
168
169 friend class AppleObjCRuntimeV2;
170
173 };
174
177 public:
178 ~TaggedPointerVendorV2() override = default;
179
180 static TaggedPointerVendorV2 *
182 const lldb::ModuleSP &objc_module_sp);
183
184 protected:
186
188 : TaggedPointerVendor(), m_runtime(runtime) {}
189
190 private:
194 };
195
197 public:
198 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
199
201 GetClassDescriptor(lldb::addr_t ptr) override;
202
203 protected:
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;
221
223
225 const TaggedPointerVendorRuntimeAssisted &) = delete;
228 };
229
232 public:
234 GetClassDescriptor(lldb::addr_t ptr) override;
235
236 protected:
238 AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
239 uint64_t objc_debug_taggedpointer_ext_mask,
240 uint32_t objc_debug_taggedpointer_slot_shift,
241 uint32_t objc_debug_taggedpointer_ext_slot_shift,
242 uint32_t objc_debug_taggedpointer_slot_mask,
243 uint32_t objc_debug_taggedpointer_ext_slot_mask,
244 uint32_t objc_debug_taggedpointer_payload_lshift,
245 uint32_t objc_debug_taggedpointer_payload_rshift,
246 uint32_t objc_debug_taggedpointer_ext_payload_lshift,
247 uint32_t objc_debug_taggedpointer_ext_payload_rshift,
248 lldb::addr_t objc_debug_taggedpointer_classes,
249 lldb::addr_t objc_debug_taggedpointer_ext_classes);
250
252
253 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
254 typedef Cache::iterator CacheIterator;
262
264
268 };
269
271 public:
272 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
273
275 GetClassDescriptor(lldb::addr_t ptr) override;
276
277 protected:
279 : TaggedPointerVendorV2(runtime) {}
280
282
286 };
287
291 uint32_t m_num_found;
292
293 DescriptorMapUpdateResult(bool ran, bool retry, uint32_t found) {
294 m_update_ran = ran;
295
296 m_retry_update = retry;
297
298 m_num_found = found;
299 }
300
301 static DescriptorMapUpdateResult Fail() { return {false, false, 0}; }
302
303 static DescriptorMapUpdateResult Success(uint32_t found) {
304 return {true, false, found};
305 }
306
307 static DescriptorMapUpdateResult Retry() { return {false, true, 0}; }
308 };
309
310 /// Abstraction to read the Objective-C class info.
312 public:
314 std::mutex &GetMutex() { return m_mutex; }
315
316 protected:
317 /// The lifetime of this object is tied to that of the runtime.
319 std::mutex m_mutex;
320 };
321
322 /// We can read the class info from the Objective-C runtime using
323 /// gdb_objc_realized_classes, objc_copyRealizedClassList or
324 /// objc_getRealizedClassList_trylock. The RealizedClassList variants are
325 /// preferred because they include lazily named classes, but they are not
326 /// always available or safe to call.
327 ///
328 /// We potentially need more than one helper for the same process, because we
329 /// may need to use gdb_objc_realized_classes until dyld is initialized and
330 /// then switch over to objc_copyRealizedClassList or
331 /// objc_getRealizedClassList_trylock for lazily named classes.
333 public:
335 : ClassInfoExtractor(runtime) {}
336
339
340 private:
341 enum Helper {
345 };
346
347 /// Compute which helper to use. If dyld is not yet fully initialized we
348 /// must use gdb_objc_realized_classes. Otherwise, we prefer
349 /// objc_getRealizedClassList_trylock and objc_copyRealizedClassList
350 /// respectively, depending on availability.
351 Helper ComputeHelper(ExecutionContext &exe_ctx) const;
352
354 Helper helper);
356
357 std::unique_ptr<UtilityFunction>
359 std::string code, std::string name);
360
362 std::unique_ptr<UtilityFunction> utility_function;
364 };
365
369 };
370
371 /// Abstraction to read the Objective-C class info from the shared cache.
373 public:
375 : ClassInfoExtractor(runtime) {}
376
378
379 private:
381
382 std::unique_ptr<UtilityFunction>
384
385 std::unique_ptr<UtilityFunction> m_utility_function;
387 };
388
390 public:
391 static std::unique_ptr<SharedCacheImageHeaders>
393
395
396 bool IsImageLoaded(uint16_t image_index);
397
398 uint64_t GetVersion();
399
400 private:
402 lldb::addr_t headerInfoRWs_ptr, uint32_t count,
403 uint32_t entsize)
404 : m_runtime(runtime), m_headerInfoRWs_ptr(headerInfoRWs_ptr),
405 m_loaded_images(count, false), m_version(0), m_count(count),
406 m_entsize(entsize), m_needs_update(true) {}
407 llvm::Error UpdateIfNeeded();
408
411 llvm::BitVector m_loaded_images;
412 uint64_t m_version;
413 uint32_t m_count;
414 uint32_t m_entsize;
416 };
417
418 AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
419
421
423
424 /// Update the generation count of realized classes. This is not an exact
425 /// count but rather a value that is incremented when new classes are realized
426 /// or destroyed. Unlike the count in gdb_objc_realized_classes, it will
427 /// change when lazily named classes get realized.
429
431 uint32_t num_class_infos);
432
437 };
438
441
444
446
447 bool HasSymbol(ConstString Name);
448
453 return m_non_pointer_isa_cache_up.get();
454 }
455
456 friend class ClassDescriptorV2;
457
459
462
463 std::unique_ptr<DeclVendor> m_decl_vendor_up;
472 std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up;
473 std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up;
477 std::optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
479 std::unique_ptr<SharedCacheImageHeaders> m_shared_cache_image_headers_up;
480};
481
482} // namespace lldb_private
483
484#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
A section + offset based address class.
Definition: Address.h:62
Abstraction to read the Objective-C class info.
AppleObjCRuntimeV2 & m_runtime
The lifetime of this object is tied to that of the runtime.
We can read the class info from the Objective-C runtime using gdb_objc_realized_classes,...
UtilityFunction * GetClassInfoUtilityFunction(ExecutionContext &exe_ctx, Helper helper)
Helper ComputeHelper(ExecutionContext &exe_ctx) const
Compute which helper to use.
std::unique_ptr< UtilityFunction > GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx, Helper helper, std::string code, std::string name)
void UpdateSignature(const RemoteNXMapTable &hash_table)
bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa)
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa)
static NonPointerISACache * CreateInstance(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp)
NonPointerISACache(const NonPointerISACache &)=delete
const NonPointerISACache & operator=(const NonPointerISACache &)=delete
std::map< ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP > m_cache
Abstraction to read the Objective-C class info from the shared cache.
UtilityFunction * GetClassInfoUtilityFunction(ExecutionContext &exe_ctx)
std::unique_ptr< UtilityFunction > GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx)
SharedCacheImageHeaders(AppleObjCRuntimeV2 &runtime, lldb::addr_t headerInfoRWs_ptr, uint32_t count, uint32_t entsize)
static std::unique_ptr< SharedCacheImageHeaders > CreateSharedCacheImageHeaders(AppleObjCRuntimeV2 &runtime)
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
std::map< uint8_t, ObjCLanguageRuntime::ClassDescriptorSP > Cache
const TaggedPointerVendorExtended & operator=(const TaggedPointerVendorExtended &)=delete
TaggedPointerVendorExtended(const TaggedPointerVendorExtended &)=delete
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
const TaggedPointerVendorLegacy & operator=(const TaggedPointerVendorLegacy &)=delete
TaggedPointerVendorLegacy(const TaggedPointerVendorLegacy &)=delete
const TaggedPointerVendorRuntimeAssisted & operator=(const TaggedPointerVendorRuntimeAssisted &)=delete
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
TaggedPointerVendorRuntimeAssisted(const TaggedPointerVendorRuntimeAssisted &)=delete
std::map< uint8_t, ObjCLanguageRuntime::ClassDescriptorSP > Cache
TaggedPointerVendorV2(const TaggedPointerVendorV2 &)=delete
static TaggedPointerVendorV2 * CreateInstance(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp)
const TaggedPointerVendorV2 & operator=(const TaggedPointerVendorV2 &)=delete
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override
bool IsTaggedPointer(lldb::addr_t ptr) override
uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data, uint32_t num_class_infos)
bool RealizedClassGenerationCountChanged()
Update the generation count of realized classes.
void SetRelativeSelectorBaseAddr(lldb::addr_t relative_selector_base)
static llvm::StringRef GetPluginNameStatic()
EncodingToTypeSP GetEncodingToType() override
~AppleObjCRuntimeV2() override=default
TaggedPointerVendor * GetTaggedPointerVendor() override
NonPointerISACache * GetNonPointerIsaCache()
size_t GetByteOffsetForIvar(CompilerType &parent_ast_type, const char *ivar_name) override
StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc) override
Language runtime plugins can use this API to report language-specific runtime information about this ...
SharedCacheClassInfoExtractor m_shared_cache_class_info_extractor
DynamicClassInfoExtractor m_dynamic_class_info_extractor
ObjCRuntimeVersions GetRuntimeVersion() const override
ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override
static bool classof(const LanguageRuntime *runtime)
bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, Value::ValueType &value_type) override
bool isA(const void *ClassID) const override
std::unique_ptr< SharedCacheImageHeaders > m_shared_cache_image_headers_up
lldb::addr_t LookupRuntimeSymbol(ConstString name) override
ClassDescriptorSP GetClassDescriptor(ValueObject &valobj) override
void ModulesDidLoad(const ModuleList &module_list) override
Called when modules have been loaded in the process.
bool IsSharedCacheImageLoaded(uint16_t image_index)
lldb::addr_t GetRelativeSelectorBaseAddr()
Returns the base address for relative method list selector strings.
std::optional< std::pair< lldb::addr_t, lldb::addr_t > > m_CFBoolean_values
llvm::StringRef GetPluginName() override
std::unique_ptr< DeclVendor > m_decl_vendor_up
std::unique_ptr< TaggedPointerVendor > m_tagged_pointer_vendor_up
std::unique_ptr< NonPointerISACache > m_non_pointer_isa_cache_up
void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false) override
lldb::BreakpointResolverSP CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp, bool throw_bp) override
LanguageRuntime * GetPreferredLanguageRuntime(ValueObject &in_value) override
Return the preferred language runtime instance, which in most cases will be the current instance.
std::optional< uint64_t > GetSharedCacheImageHeaderVersion()
void WarnIfNoClassesCached(SharedCacheWarningReason reason)
static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language)
bool isA(const void *ClassID) const override
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
A uniqued constant string class.
Definition: ConstString.h:40
An data extractor class.
Definition: DataExtractor.h:48
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
virtual bool isA(const void *ClassID) const
A collection class for Module objects.
Definition: ModuleList.h:103
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
std::shared_ptr< EncodingToType > EncodingToTypeSP
A plug-in interface definition class for debugging a process.
Definition: Process.h:343
std::shared_ptr< Object > ObjectSP
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
Sometimes you can find the name of the type corresponding to an object, but we don't have debug infor...
Definition: Type.h:779
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
ValueType
Type that describes Value::m_value.
Definition: Value.h:41
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::BreakpointResolver > BreakpointResolverSP
Definition: lldb-forward.h:328
std::weak_ptr< lldb_private::Module > ModuleWP
Definition: lldb-forward.h:374
LanguageType
Programming language type.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
Definition: lldb-forward.h:321
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373
static DescriptorMapUpdateResult Success(uint32_t found)
DescriptorMapUpdateResult(bool ran, bool retry, uint32_t found)