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 liblldb_AppleObjCRuntimeV2_h_
10 #define liblldb_AppleObjCRuntimeV2_h_
11 
12 #include <map>
13 #include <memory>
14 #include <mutex>
15 
16 #include "AppleObjCRuntime.h"
18 #include "lldb/lldb-private.h"
19 
20 class RemoteNXMapTable;
21 
22 namespace lldb_private {
23 
25 public:
26  ~AppleObjCRuntimeV2() override = default;
27 
28  // Static Functions
29  static void Initialize();
30 
31  static void Terminate();
32 
34  CreateInstance(Process *process, lldb::LanguageType language);
35 
37 
38  static bool classof(const ObjCLanguageRuntime *runtime) {
39  switch (runtime->GetRuntimeVersion()) {
41  return true;
42  default:
43  return false;
44  }
45  }
46 
47  // These are generic runtime functions:
49  lldb::DynamicValueType use_dynamic,
50  TypeAndOrName &class_type_or_name,
51  Address &address,
52  Value::ValueType &value_type) override;
53 
54  UtilityFunction *CreateObjectChecker(const char *) override;
55 
56  // PluginInterface protocol
57  ConstString GetPluginName() override;
58 
59  uint32_t GetPluginVersion() override;
60 
63  }
64 
65  size_t GetByteOffsetForIvar(CompilerType &parent_qual_type,
66  const char *ivar_name) override;
67 
68  void UpdateISAToDescriptorMapIfNeeded() override;
69 
71 
73 
75 
76  DeclVendor *GetDeclVendor() override;
77 
79 
81 
82  bool IsTaggedPointer(lldb::addr_t ptr) override;
83 
85  return m_tagged_pointer_vendor_up.get();
86  }
87 
89 
91  lldb::addr_t &cf_false) override;
92 
93  // none of these are valid ISAs - we use them to infer the type
94  // of tagged pointers - if we have something meaningful to say
95  // we report an actual type - otherwise, we just say tagged
96  // there is no connection between the values here and the tagged pointers map
102  5;
104 
105 protected:
106  lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
107  bool catch_bp,
108  bool throw_bp) override;
109 
110 private:
111  class HashTableSignature {
112  public:
113  HashTableSignature();
114 
115  bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
116  RemoteNXMapTable &hash_table);
117 
118  void UpdateSignature(const RemoteNXMapTable &hash_table);
119 
120  protected:
121  uint32_t m_count;
122  uint32_t m_num_buckets;
123  lldb::addr_t m_buckets_ptr;
124  };
125 
126  class NonPointerISACache {
127  public:
128  static NonPointerISACache *
130  const lldb::ModuleSP &objc_module_sp);
131 
133 
134  private:
135  NonPointerISACache(AppleObjCRuntimeV2 &runtime,
136  const lldb::ModuleSP &objc_module_sp,
137  uint64_t objc_debug_isa_class_mask,
138  uint64_t objc_debug_isa_magic_mask,
139  uint64_t objc_debug_isa_magic_value,
140  uint64_t objc_debug_indexed_isa_magic_mask,
141  uint64_t objc_debug_indexed_isa_magic_value,
142  uint64_t objc_debug_indexed_isa_index_mask,
143  uint64_t objc_debug_indexed_isa_index_shift,
144  lldb::addr_t objc_indexed_classes);
145 
146  bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
147 
148  AppleObjCRuntimeV2 &m_runtime;
149  std::map<ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
150  lldb::ModuleWP m_objc_module_wp;
151  uint64_t m_objc_debug_isa_class_mask;
152  uint64_t m_objc_debug_isa_magic_mask;
153  uint64_t m_objc_debug_isa_magic_value;
154 
155  uint64_t m_objc_debug_indexed_isa_magic_mask;
156  uint64_t m_objc_debug_indexed_isa_magic_value;
157  uint64_t m_objc_debug_indexed_isa_index_mask;
158  uint64_t m_objc_debug_indexed_isa_index_shift;
159  lldb::addr_t m_objc_indexed_classes;
160 
161  std::vector<lldb::addr_t> m_indexed_isa_cache;
162 
163  friend class AppleObjCRuntimeV2;
164 
165  DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
166  };
167 
168  class TaggedPointerVendorV2
170  public:
171  ~TaggedPointerVendorV2() override = default;
172 
173  static TaggedPointerVendorV2 *
175  const lldb::ModuleSP &objc_module_sp);
176 
177  protected:
178  AppleObjCRuntimeV2 &m_runtime;
179 
180  TaggedPointerVendorV2(AppleObjCRuntimeV2 &runtime)
181  : TaggedPointerVendor(), m_runtime(runtime) {}
182 
183  private:
184  DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorV2);
185  };
186 
187  class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
188  public:
189  bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
190 
192  GetClassDescriptor(lldb::addr_t ptr) override;
193 
194  protected:
195  TaggedPointerVendorRuntimeAssisted(
196  AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
197  uint32_t objc_debug_taggedpointer_slot_shift,
198  uint32_t objc_debug_taggedpointer_slot_mask,
199  uint32_t objc_debug_taggedpointer_payload_lshift,
200  uint32_t objc_debug_taggedpointer_payload_rshift,
201  lldb::addr_t objc_debug_taggedpointer_classes);
202 
203  typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
204  typedef Cache::iterator CacheIterator;
205  Cache m_cache;
206  uint64_t m_objc_debug_taggedpointer_mask;
207  uint32_t m_objc_debug_taggedpointer_slot_shift;
208  uint32_t m_objc_debug_taggedpointer_slot_mask;
209  uint32_t m_objc_debug_taggedpointer_payload_lshift;
210  uint32_t m_objc_debug_taggedpointer_payload_rshift;
211  lldb::addr_t m_objc_debug_taggedpointer_classes;
212 
213  friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
214 
215  DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
216  };
217 
218  class TaggedPointerVendorExtended
219  : public TaggedPointerVendorRuntimeAssisted {
220  public:
222  GetClassDescriptor(lldb::addr_t ptr) override;
223 
224  protected:
225  TaggedPointerVendorExtended(
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 
239  bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr);
240 
241  typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
242  typedef Cache::iterator CacheIterator;
243  Cache m_ext_cache;
244  uint64_t m_objc_debug_taggedpointer_ext_mask;
245  uint32_t m_objc_debug_taggedpointer_ext_slot_shift;
246  uint32_t m_objc_debug_taggedpointer_ext_slot_mask;
247  uint32_t m_objc_debug_taggedpointer_ext_payload_lshift;
248  uint32_t m_objc_debug_taggedpointer_ext_payload_rshift;
249  lldb::addr_t m_objc_debug_taggedpointer_ext_classes;
250 
251  friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
252 
253  DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
254  };
255 
256  class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
257  public:
258  bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
259 
261  GetClassDescriptor(lldb::addr_t ptr) override;
262 
263  protected:
264  TaggedPointerVendorLegacy(AppleObjCRuntimeV2 &runtime)
265  : TaggedPointerVendorV2(runtime) {}
266 
267  friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
268 
269  DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
270  };
271 
272  struct DescriptorMapUpdateResult {
273  bool m_update_ran;
274  uint32_t m_num_found;
275 
276  DescriptorMapUpdateResult(bool ran, uint32_t found) {
277  m_update_ran = ran;
278  m_num_found = found;
279  }
280 
281  static DescriptorMapUpdateResult Fail() { return {false, 0}; }
282 
283  static DescriptorMapUpdateResult Success(uint32_t found) {
284  return {true, found};
285  }
286  };
287 
288  AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
289 
290  ObjCISA GetPointerISA(ObjCISA isa);
291 
292  lldb::addr_t GetISAHashTablePointer();
293 
294  bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
295 
296  DescriptorMapUpdateResult
297  UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
298 
299  uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
300  uint32_t num_class_infos);
301 
302  DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
303 
304  enum class SharedCacheWarningReason {
305  eExpressionExecutionFailure,
306  eNotEnoughClassesRead
307  };
308 
309  void WarnIfNoClassesCached(SharedCacheWarningReason reason);
310 
311  lldb::addr_t GetSharedCacheReadOnlyAddress();
312 
313  bool GetCFBooleanValuesIfNeeded();
314 
315  friend class ClassDescriptorV2;
316 
317  std::unique_ptr<UtilityFunction> m_get_class_info_code;
318  lldb::addr_t m_get_class_info_args;
319  std::mutex m_get_class_info_args_mutex;
320 
321  std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
322  lldb::addr_t m_get_shared_cache_class_info_args;
323  std::mutex m_get_shared_cache_class_info_args_mutex;
324 
325  std::unique_ptr<DeclVendor> m_decl_vendor_up;
326  lldb::addr_t m_tagged_pointer_obfuscator;
327  lldb::addr_t m_isa_hash_table_ptr;
328  HashTableSignature m_hash_signature;
329  bool m_has_object_getClass;
330  bool m_loaded_objc_opt;
331  std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up;
332  std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up;
333  EncodingToTypeSP m_encoding_to_type_sp;
334  bool m_noclasses_warning_emitted;
335  llvm::Optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
336 };
337 
338 } // namespace lldb_private
339 
340 #endif // liblldb_AppleObjCRuntimeV2_h_
ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override
An data extractor class.
Definition: DataExtractor.h:47
TaggedPointerVendor * GetTaggedPointerVendor() override
lldb::addr_t LookupRuntimeSymbol(ConstString name) override
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
UtilityFunction * CreateObjectChecker(const char *) override
Sometimes you can find the name of the type corresponding to an object, but we don&#39;t have debug infor...
Definition: Type.h:396
ObjCRuntimeVersions GetRuntimeVersion() const override
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition: Breakpoint.h:78
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject
static bool classof(const ObjCLanguageRuntime *runtime)
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
EncodingToTypeSP GetEncodingToType() override
lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override
~AppleObjCRuntimeV2() override=default
LanguageType
Programming language type.
size_t GetByteOffsetForIvar(CompilerType &parent_qual_type, const char *ivar_name) override
ConstString GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) override
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
bool IsTaggedPointer(lldb::addr_t ptr) override
A section + offset based address class.
Definition: Address.h:80
static lldb_private::ConstString GetPluginNameStatic()
uint64_t addr_t
Definition: lldb-types.h:83
A uniqued constant string class.
Definition: ConstString.h:38
bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, Value::ValueType &value_type) override
DISALLOW_COPY_AND_ASSIGN(ObjCLanguageRuntime)
static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language)
void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false) override
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom
virtual ObjCRuntimeVersions GetRuntimeVersion() const
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
std::shared_ptr< EncodingToType > EncodingToTypeSP
ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override