[OpenACC] Implement 'device_type' for 'data' construct
[llvm-project.git] / lldb / source / Plugins / LanguageRuntime / ObjC / AppleObjCRuntime / AppleObjCRuntimeV2.h
blob2422539b13f13dd67d8b9f5a3b407b510bd402ba
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 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
10 #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H
12 #include <map>
13 #include <memory>
14 #include <mutex>
15 #include <optional>
17 #include "AppleObjCRuntime.h"
18 #include "lldb/lldb-private.h"
20 #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
22 #include "llvm/ADT/BitVector.h"
24 class RemoteNXMapTable;
26 namespace lldb_private {
28 class AppleObjCRuntimeV2 : public AppleObjCRuntime {
29 public:
30 ~AppleObjCRuntimeV2() override = default;
32 static void Initialize();
34 static void Terminate();
36 static lldb_private::LanguageRuntime *
37 CreateInstance(Process *process, lldb::LanguageType language);
39 static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v2"; }
41 LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) override;
43 static char ID;
45 bool isA(const void *ClassID) const override {
46 return ClassID == &ID || AppleObjCRuntime::isA(ClassID);
49 static bool classof(const LanguageRuntime *runtime) {
50 return runtime->isA(&ID);
53 bool GetDynamicTypeAndAddress(ValueObject &in_value,
54 lldb::DynamicValueType use_dynamic,
55 TypeAndOrName &class_type_or_name,
56 Address &address,
57 Value::ValueType &value_type) override;
59 llvm::Expected<std::unique_ptr<UtilityFunction>>
60 CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override;
62 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
64 ObjCRuntimeVersions GetRuntimeVersion() const override {
65 return ObjCRuntimeVersions::eAppleObjC_V2;
68 size_t GetByteOffsetForIvar(CompilerType &parent_ast_type,
69 const char *ivar_name) override;
71 void UpdateISAToDescriptorMapIfNeeded() override;
73 ClassDescriptorSP GetClassDescriptor(ValueObject &valobj) override;
75 ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override;
77 DeclVendor *GetDeclVendor() override;
79 lldb::addr_t LookupRuntimeSymbol(ConstString name) override;
81 EncodingToTypeSP GetEncodingToType() override;
83 bool IsTaggedPointer(lldb::addr_t ptr) override;
85 TaggedPointerVendor *GetTaggedPointerVendor() override {
86 return m_tagged_pointer_vendor_up.get();
89 lldb::addr_t GetTaggedPointerObfuscator();
91 /// Returns the base address for relative method list selector strings.
92 lldb::addr_t GetRelativeSelectorBaseAddr() {
93 return m_relative_selector_base;
96 void SetRelativeSelectorBaseAddr(lldb::addr_t relative_selector_base) {
97 m_relative_selector_base = relative_selector_base;
100 void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
101 lldb::addr_t &cf_false) override;
103 void ModulesDidLoad(const ModuleList &module_list) override;
105 bool IsSharedCacheImageLoaded(uint16_t image_index);
107 std::optional<uint64_t> GetSharedCacheImageHeaderVersion();
109 StructuredData::ObjectSP GetLanguageSpecificData(SymbolContext sc) override;
111 protected:
112 lldb::BreakpointResolverSP
113 CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
114 bool throw_bp) override;
116 private:
117 class HashTableSignature {
118 public:
119 HashTableSignature();
121 bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime,
122 RemoteNXMapTable &hash_table);
124 void UpdateSignature(const RemoteNXMapTable &hash_table);
126 protected:
127 uint32_t m_count = 0;
128 uint32_t m_num_buckets = 0;
129 lldb::addr_t m_buckets_ptr = 0;
132 class NonPointerISACache {
133 public:
134 static NonPointerISACache *
135 CreateInstance(AppleObjCRuntimeV2 &runtime,
136 const lldb::ModuleSP &objc_module_sp);
138 ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa);
140 private:
141 NonPointerISACache(AppleObjCRuntimeV2 &runtime,
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);
152 bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa);
154 AppleObjCRuntimeV2 &m_runtime;
155 std::map<ObjCISA, ObjCLanguageRuntime::ClassDescriptorSP> m_cache;
156 lldb::ModuleWP m_objc_module_wp;
157 uint64_t m_objc_debug_isa_class_mask;
158 uint64_t m_objc_debug_isa_magic_mask;
159 uint64_t m_objc_debug_isa_magic_value;
161 uint64_t m_objc_debug_indexed_isa_magic_mask;
162 uint64_t m_objc_debug_indexed_isa_magic_value;
163 uint64_t m_objc_debug_indexed_isa_index_mask;
164 uint64_t m_objc_debug_indexed_isa_index_shift;
165 lldb::addr_t m_objc_indexed_classes;
167 std::vector<lldb::addr_t> m_indexed_isa_cache;
169 friend class AppleObjCRuntimeV2;
171 NonPointerISACache(const NonPointerISACache &) = delete;
172 const NonPointerISACache &operator=(const NonPointerISACache &) = delete;
175 class TaggedPointerVendorV2
176 : public ObjCLanguageRuntime::TaggedPointerVendor {
177 public:
178 ~TaggedPointerVendorV2() override = default;
180 static TaggedPointerVendorV2 *
181 CreateInstance(AppleObjCRuntimeV2 &runtime,
182 const lldb::ModuleSP &objc_module_sp);
184 protected:
185 AppleObjCRuntimeV2 &m_runtime;
187 TaggedPointerVendorV2(AppleObjCRuntimeV2 &runtime)
188 : TaggedPointerVendor(), m_runtime(runtime) {}
190 private:
191 TaggedPointerVendorV2(const TaggedPointerVendorV2 &) = delete;
192 const TaggedPointerVendorV2 &
193 operator=(const TaggedPointerVendorV2 &) = delete;
196 class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendorV2 {
197 public:
198 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
200 ObjCLanguageRuntime::ClassDescriptorSP
201 GetClassDescriptor(lldb::addr_t ptr) override;
203 protected:
204 TaggedPointerVendorRuntimeAssisted(
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);
212 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
213 typedef Cache::iterator CacheIterator;
214 Cache m_cache;
215 uint64_t m_objc_debug_taggedpointer_mask;
216 uint32_t m_objc_debug_taggedpointer_slot_shift;
217 uint32_t m_objc_debug_taggedpointer_slot_mask;
218 uint32_t m_objc_debug_taggedpointer_payload_lshift;
219 uint32_t m_objc_debug_taggedpointer_payload_rshift;
220 lldb::addr_t m_objc_debug_taggedpointer_classes;
222 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
224 TaggedPointerVendorRuntimeAssisted(
225 const TaggedPointerVendorRuntimeAssisted &) = delete;
226 const TaggedPointerVendorRuntimeAssisted &
227 operator=(const TaggedPointerVendorRuntimeAssisted &) = delete;
230 class TaggedPointerVendorExtended
231 : public TaggedPointerVendorRuntimeAssisted {
232 public:
233 ObjCLanguageRuntime::ClassDescriptorSP
234 GetClassDescriptor(lldb::addr_t ptr) override;
236 protected:
237 TaggedPointerVendorExtended(
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);
251 bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr);
253 typedef std::map<uint8_t, ObjCLanguageRuntime::ClassDescriptorSP> Cache;
254 typedef Cache::iterator CacheIterator;
255 Cache m_ext_cache;
256 uint64_t m_objc_debug_taggedpointer_ext_mask;
257 uint32_t m_objc_debug_taggedpointer_ext_slot_shift;
258 uint32_t m_objc_debug_taggedpointer_ext_slot_mask;
259 uint32_t m_objc_debug_taggedpointer_ext_payload_lshift;
260 uint32_t m_objc_debug_taggedpointer_ext_payload_rshift;
261 lldb::addr_t m_objc_debug_taggedpointer_ext_classes;
263 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
265 TaggedPointerVendorExtended(const TaggedPointerVendorExtended &) = delete;
266 const TaggedPointerVendorExtended &
267 operator=(const TaggedPointerVendorExtended &) = delete;
270 class TaggedPointerVendorLegacy : public TaggedPointerVendorV2 {
271 public:
272 bool IsPossibleTaggedPointer(lldb::addr_t ptr) override;
274 ObjCLanguageRuntime::ClassDescriptorSP
275 GetClassDescriptor(lldb::addr_t ptr) override;
277 protected:
278 TaggedPointerVendorLegacy(AppleObjCRuntimeV2 &runtime)
279 : TaggedPointerVendorV2(runtime) {}
281 friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
283 TaggedPointerVendorLegacy(const TaggedPointerVendorLegacy &) = delete;
284 const TaggedPointerVendorLegacy &
285 operator=(const TaggedPointerVendorLegacy &) = delete;
288 struct DescriptorMapUpdateResult {
289 bool m_update_ran;
290 bool m_retry_update;
291 uint32_t m_num_found;
293 DescriptorMapUpdateResult(bool ran, bool retry, uint32_t found) {
294 m_update_ran = ran;
296 m_retry_update = retry;
298 m_num_found = found;
301 static DescriptorMapUpdateResult Fail() { return {false, false, 0}; }
303 static DescriptorMapUpdateResult Success(uint32_t found) {
304 return {true, false, found};
307 static DescriptorMapUpdateResult Retry() { return {false, true, 0}; }
310 /// Abstraction to read the Objective-C class info.
311 class ClassInfoExtractor {
312 public:
313 ClassInfoExtractor(AppleObjCRuntimeV2 &runtime) : m_runtime(runtime) {}
314 std::mutex &GetMutex() { return m_mutex; }
316 protected:
317 /// The lifetime of this object is tied to that of the runtime.
318 AppleObjCRuntimeV2 &m_runtime;
319 std::mutex m_mutex;
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.
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.
332 class DynamicClassInfoExtractor : public ClassInfoExtractor {
333 public:
334 DynamicClassInfoExtractor(AppleObjCRuntimeV2 &runtime)
335 : ClassInfoExtractor(runtime) {}
337 DescriptorMapUpdateResult
338 UpdateISAToDescriptorMap(RemoteNXMapTable &hash_table);
340 private:
341 enum Helper {
342 gdb_objc_realized_classes,
343 objc_copyRealizedClassList,
344 objc_getRealizedClassList_trylock
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;
353 UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx,
354 Helper helper);
355 lldb::addr_t &GetClassInfoArgs(Helper helper);
357 std::unique_ptr<UtilityFunction>
358 GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx, Helper helper,
359 std::string code, std::string name);
361 struct UtilityFunctionHelper {
362 std::unique_ptr<UtilityFunction> utility_function;
363 lldb::addr_t args = LLDB_INVALID_ADDRESS;
366 UtilityFunctionHelper m_gdb_objc_realized_classes_helper;
367 UtilityFunctionHelper m_objc_copyRealizedClassList_helper;
368 UtilityFunctionHelper m_objc_getRealizedClassList_trylock_helper;
371 /// Abstraction to read the Objective-C class info from the shared cache.
372 class SharedCacheClassInfoExtractor : public ClassInfoExtractor {
373 public:
374 SharedCacheClassInfoExtractor(AppleObjCRuntimeV2 &runtime)
375 : ClassInfoExtractor(runtime) {}
377 DescriptorMapUpdateResult UpdateISAToDescriptorMap();
379 private:
380 UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx);
382 std::unique_ptr<UtilityFunction>
383 GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx);
385 std::unique_ptr<UtilityFunction> m_utility_function;
386 lldb::addr_t m_args = LLDB_INVALID_ADDRESS;
389 class SharedCacheImageHeaders {
390 public:
391 static std::unique_ptr<SharedCacheImageHeaders>
392 CreateSharedCacheImageHeaders(AppleObjCRuntimeV2 &runtime);
394 void SetNeedsUpdate() { m_needs_update = true; }
396 bool IsImageLoaded(uint16_t image_index);
398 uint64_t GetVersion();
400 private:
401 SharedCacheImageHeaders(AppleObjCRuntimeV2 &runtime,
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();
409 AppleObjCRuntimeV2 &m_runtime;
410 lldb::addr_t m_headerInfoRWs_ptr;
411 llvm::BitVector m_loaded_images;
412 uint64_t m_version;
413 uint32_t m_count;
414 uint32_t m_entsize;
415 bool m_needs_update;
418 AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
420 ObjCISA GetPointerISA(ObjCISA isa);
422 lldb::addr_t GetISAHashTablePointer();
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.
428 bool RealizedClassGenerationCountChanged();
430 uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
431 uint32_t num_class_infos);
433 enum class SharedCacheWarningReason {
434 eExpressionUnableToRun,
435 eExpressionExecutionFailure,
436 eNotEnoughClassesRead
439 void WarnIfNoClassesCached(SharedCacheWarningReason reason);
440 void WarnIfNoExpandedSharedCache();
442 lldb::addr_t GetSharedCacheReadOnlyAddress();
443 lldb::addr_t GetSharedCacheBaseAddress();
445 bool GetCFBooleanValuesIfNeeded();
447 bool HasSymbol(ConstString Name);
449 NonPointerISACache *GetNonPointerIsaCache() {
450 if (!m_non_pointer_isa_cache_up)
451 m_non_pointer_isa_cache_up.reset(
452 NonPointerISACache::CreateInstance(*this, m_objc_module_sp));
453 return m_non_pointer_isa_cache_up.get();
456 friend class ClassDescriptorV2;
458 lldb::ModuleSP m_objc_module_sp;
460 DynamicClassInfoExtractor m_dynamic_class_info_extractor;
461 SharedCacheClassInfoExtractor m_shared_cache_class_info_extractor;
463 std::unique_ptr<DeclVendor> m_decl_vendor_up;
464 lldb::addr_t m_tagged_pointer_obfuscator;
465 lldb::addr_t m_isa_hash_table_ptr;
466 lldb::addr_t m_relative_selector_base;
467 HashTableSignature m_hash_signature;
468 bool m_has_object_getClass;
469 bool m_has_objc_copyRealizedClassList;
470 bool m_has_objc_getRealizedClassList_trylock;
471 bool m_loaded_objc_opt;
472 std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up;
473 std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up;
474 EncodingToTypeSP m_encoding_to_type_sp;
475 std::once_flag m_no_classes_cached_warning;
476 std::once_flag m_no_expanded_cache_warning;
477 std::optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
478 uint64_t m_realized_class_generation_count;
479 std::unique_ptr<SharedCacheImageHeaders> m_shared_cache_image_headers_up;
482 } // namespace lldb_private
484 #endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCRUNTIMEV2_H