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
23
24namespace lldb_private {
25
27public:
28 ~AppleObjCRuntimeV2() override = default;
29
30 static void Initialize();
31
32 static void Terminate();
33
35 CreateInstance(Process *process, lldb::LanguageType language);
36
37 static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v2"; }
38
39 static char ID;
40
41 bool isA(const void *ClassID) const override {
42 return ClassID == &ID || AppleObjCRuntime::isA(ClassID);
43 }
44
45 static bool classof(const LanguageRuntime *runtime) {
46 return runtime->isA(&ID);
47 }
48
50 lldb::DynamicValueType use_dynamic,
51 TypeAndOrName &class_type_or_name,
52 Address &address,
53 Value::ValueType &value_type) override;
54
55 llvm::Expected<std::unique_ptr<UtilityFunction>>
56 CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override;
57
58 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
59
62 }
63
64 size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
65 const char *ivar_name) override;
66
68
70
72
73 DeclVendor *GetDeclVendor() override;
74
76
78
79 bool IsTaggedPointer(lldb::addr_t ptr) override;
80
82 return m_tagged_pointer_vendor_up.get();
83 }
84
86
87 /// Returns the base address for relative method list selector strings.
90 }
91
92 void SetRelativeSelectorBaseAddr(lldb::addr_t relative_selector_base) {
93 m_relative_selector_base = relative_selector_base;
94 }
95
97 lldb::addr_t &cf_false) override;
98
99protected:
100 lldb::BreakpointResolverSP
101 CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
102 bool throw_bp) override;
103
104private:
106 public:
108
109 bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
110 RemoteNXMapTable &hash_table);
111
112 void UpdateSignature(const RemoteNXMapTable &hash_table);
113
114 protected:
118 };
119
121 public:
122 static NonPointerISACache *
124 const lldb::ModuleSP &objc_module_sp);
125
127
128 private:
130 const lldb::ModuleSP &objc_module_sp,
131 uint64_t objc_debug_isa_class_mask,
132 uint64_t objc_debug_isa_magic_mask,
133 uint64_t objc_debug_isa_magic_value,
134 uint64_t objc_debug_indexed_isa_magic_mask,
135 uint64_t objc_debug_indexed_isa_magic_value,
136 uint64_t objc_debug_indexed_isa_index_mask,
137 uint64_t objc_debug_indexed_isa_index_shift,
138 lldb::addr_t objc_indexed_classes);
139
140 bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
141
143 std::map<ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
144 lldb::ModuleWP m_objc_module_wp;
148
154
155 std::vector<lldb::addr_t> m_indexed_isa_cache;
156
157 friend class AppleObjCRuntimeV2;
158
161 };
162
165 public:
166 ~TaggedPointerVendorV2() override = default;
167
168 static TaggedPointerVendorV2 *
170 const lldb::ModuleSP &objc_module_sp);
171
172 protected:
174
176 : TaggedPointerVendor(), m_runtime(runtime) {}
177
178 private:
182 };
183
185 public:
186 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
187
189 GetClassDescriptor(lldb::addr_t ptr) override;
190
191 protected:
193 AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
194 uint32_t objc_debug_taggedpointer_slot_shift,
195 uint32_t objc_debug_taggedpointer_slot_mask,
196 uint32_t objc_debug_taggedpointer_payload_lshift,
197 uint32_t objc_debug_taggedpointer_payload_rshift,
198 lldb::addr_t objc_debug_taggedpointer_classes);
199
200 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
201 typedef Cache::iterator CacheIterator;
209
211
213 const TaggedPointerVendorRuntimeAssisted &) = delete;
216 };
217
220 public:
222 GetClassDescriptor(lldb::addr_t ptr) override;
223
224 protected:
226 AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
227 uint64_t objc_debug_taggedpointer_ext_mask,
228 uint32_t objc_debug_taggedpointer_slot_shift,
229 uint32_t objc_debug_taggedpointer_ext_slot_shift,
230 uint32_t objc_debug_taggedpointer_slot_mask,
231 uint32_t objc_debug_taggedpointer_ext_slot_mask,
232 uint32_t objc_debug_taggedpointer_payload_lshift,
233 uint32_t objc_debug_taggedpointer_payload_rshift,
234 uint32_t objc_debug_taggedpointer_ext_payload_lshift,
235 uint32_t objc_debug_taggedpointer_ext_payload_rshift,
236 lldb::addr_t objc_debug_taggedpointer_classes,
237 lldb::addr_t objc_debug_taggedpointer_ext_classes);
238
240
241 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
242 typedef Cache::iterator CacheIterator;
250
252
256 };
257
259 public:
260 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
261
263 GetClassDescriptor(lldb::addr_t ptr) override;
264
265 protected:
267 : TaggedPointerVendorV2(runtime) {}
268
270
274 };
275
280
281 DescriptorMapUpdateResult(bool ran, bool retry, uint32_t found) {
282 m_update_ran = ran;
283
284 m_retry_update = retry;
285
286 m_num_found = found;
287 }
288
289 static DescriptorMapUpdateResult Fail() { return {false, false, 0}; }
290
292 return {true, false, found};
293 }
294
295 static DescriptorMapUpdateResult Retry() { return {false, true, 0}; }
296 };
297
298 /// Abstraction to read the Objective-C class info.
300 public:
302 std::mutex &GetMutex() { return m_mutex; }
303
304 protected:
305 /// The lifetime of this object is tied to that of the runtime.
307 std::mutex m_mutex;
308 };
309
310 /// We can read the class info from the Objective-C runtime using
311 /// gdb_objc_realized_classes, objc_copyRealizedClassList or
312 /// objc_getRealizedClassList_trylock. The RealizedClassList variants are
313 /// preferred because they include lazily named classes, but they are not
314 /// always available or safe to call.
315 ///
316 /// We potentially need more than one helper for the same process, because we
317 /// may need to use gdb_objc_realized_classes until dyld is initialized and
318 /// then switch over to objc_copyRealizedClassList or
319 /// objc_getRealizedClassList_trylock for lazily named classes.
321 public:
323 : ClassInfoExtractor(runtime) {}
324
327
328 private:
329 enum Helper {
333 };
334
335 /// Compute which helper to use. If dyld is not yet fully initialized we
336 /// must use gdb_objc_realized_classes. Otherwise, we prefer
337 /// objc_getRealizedClassList_trylock and objc_copyRealizedClassList
338 /// respectively, depending on availability.
339 Helper ComputeHelper(ExecutionContext &exe_ctx) const;
340
342 Helper helper);
344
345 std::unique_ptr<UtilityFunction>
347 std::string code, std::string name);
348
350 std::unique_ptr<UtilityFunction> utility_function;
352 };
353
357 };
358
359 /// Abstraction to read the Objective-C class info from the shared cache.
361 public:
363 : ClassInfoExtractor(runtime) {}
364
366
367 private:
369
370 std::unique_ptr<UtilityFunction>
372
373 std::unique_ptr<UtilityFunction> m_utility_function;
375 };
376
377 AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
378
380
382
383 /// Update the generation count of realized classes. This is not an exact
384 /// count but rather a value that is incremented when new classes are realized
385 /// or destroyed. Unlike the count in gdb_objc_realized_classes, it will
386 /// change when lazily named classes get realized.
388
390 uint32_t num_class_infos);
391
396 };
397
400
403
405
406 bool HasSymbol(ConstString Name);
407
412 return m_non_pointer_isa_cache_up.get();
413 }
414
415 friend class ClassDescriptorV2;
416
417 lldb::ModuleSP m_objc_module_sp;
418
421
422 std::unique_ptr<DeclVendor> m_decl_vendor_up;
431 std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up;
432 std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up;
436 std::optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
438};
439
440} // namespace lldb_private
441
442#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
A section + offset based address class.
Definition: Address.h:59
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)
NonPointerISACache(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp, uint64_t objc_debug_isa_class_mask, uint64_t objc_debug_isa_magic_mask, uint64_t objc_debug_isa_magic_value, uint64_t objc_debug_indexed_isa_magic_mask, uint64_t objc_debug_indexed_isa_magic_value, uint64_t objc_debug_indexed_isa_index_mask, uint64_t objc_debug_indexed_isa_index_shift, lldb::addr_t objc_indexed_classes)
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)
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_qual_type, const char *ivar_name) override
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
ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override
bool isA(const void *ClassID) const override
lldb::addr_t LookupRuntimeSymbol(ConstString name) override
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
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
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
std::shared_ptr< EncodingToType > EncodingToTypeSP
A plug-in interface definition class for debugging a process.
Definition: Process.h:335
Sometimes you can find the name of the type corresponding to an object, but we don't have debug infor...
Definition: Type.h:410
"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:74
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
LanguageType
Programming language type.
uint64_t addr_t
Definition: lldb-types.h:79
static DescriptorMapUpdateResult Success(uint32_t found)
DescriptorMapUpdateResult(bool ran, bool retry, uint32_t found)