1 //===-- AppleObjCRuntimeV2.h ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_AppleObjCRuntimeV2_h_
11 #define liblldb_AppleObjCRuntimeV2_h_
12 
13 // C Includes
14 // C++ Includes
15 
16 #include <map>
17 #include <memory>
18 
19 // Other libraries and framework includes
20 // Project includes
21 #include "lldb/lldb-private.h"
22 #include "lldb/Target/ObjCLanguageRuntime.h"
23 #include "AppleObjCRuntime.h"
24 
25 class RemoteNXMapTable;
26 
27 namespace lldb_private {
28 
29 class AppleObjCRuntimeV2 :
30         public AppleObjCRuntime
31 {
32 public:
33     virtual ~AppleObjCRuntimeV2();
34 
35     // These are generic runtime functions:
36     virtual bool
37     GetDynamicTypeAndAddress (ValueObject &in_value,
38                               lldb::DynamicValueType use_dynamic,
39                               TypeAndOrName &class_type_or_name,
40                               Address &address);
41 
42     virtual ClangUtilityFunction *
43     CreateObjectChecker (const char *);
44 
45 
46     //------------------------------------------------------------------
47     // Static Functions
48     //------------------------------------------------------------------
49     static void
50     Initialize();
51 
52     static void
53     Terminate();
54 
55     static lldb_private::LanguageRuntime *
56     CreateInstance (Process *process, lldb::LanguageType language);
57 
58     static lldb_private::ConstString
59     GetPluginNameStatic();
60 
61     //------------------------------------------------------------------
62     // PluginInterface protocol
63     //------------------------------------------------------------------
64     virtual ConstString
65     GetPluginName();
66 
67     virtual uint32_t
68     GetPluginVersion();
69 
70     virtual ObjCRuntimeVersions
GetRuntimeVersion()71     GetRuntimeVersion ()
72     {
73         return eAppleObjC_V2;
74     }
75 
76     virtual size_t
77     GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
78 
79     virtual void
80     UpdateISAToDescriptorMapIfNeeded();
81 
82     // none of these are valid ISAs - we use them to infer the type
83     // of tagged pointers - if we have something meaningful to say
84     // we report an actual type - otherwise, we just say tagged
85     // there is no connection between the values here and the tagged pointers map
86     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
87     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
88     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
89     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
90     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject = 5;
91     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
92 
93     virtual ConstString
94     GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa);
95 
96     virtual ClassDescriptorSP
97     GetClassDescriptor (ValueObject& in_value);
98 
99     virtual ClassDescriptorSP
100     GetClassDescriptor (ObjCISA isa);
101 
102     virtual TypeVendor *
103     GetTypeVendor();
104 
105     virtual lldb::addr_t
106     LookupRuntimeSymbol (const ConstString &name);
107 
108 protected:
109     virtual lldb::BreakpointResolverSP
110     CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
111 
112 private:
113 
114     class HashTableSignature
115     {
116     public:
117         HashTableSignature ();
118 
119         bool
120         NeedsUpdate (Process *process,
121                      AppleObjCRuntimeV2 *runtime,
122                      RemoteNXMapTable &hash_table);
123 
124         void
125         UpdateSignature (const RemoteNXMapTable &hash_table);
126     protected:
127         uint32_t m_count;
128         uint32_t m_num_buckets;
129         lldb::addr_t m_buckets_ptr;
130     };
131 
132     class NonPointerISACache
133     {
134     public:
135         static NonPointerISACache*
136         CreateInstance (AppleObjCRuntimeV2& runtime,
137                         const lldb::ModuleSP& objc_module_sp);
138 
139 
140         ObjCLanguageRuntime::ClassDescriptorSP
141         GetClassDescriptor (ObjCISA isa);
142     private:
143         NonPointerISACache (AppleObjCRuntimeV2& runtime,
144                             uint64_t objc_debug_isa_class_mask,
145                             uint64_t objc_debug_isa_magic_mask,
146                             uint64_t objc_debug_isa_magic_value);
147 
148         bool
149         EvaluateNonPointerISA (ObjCISA isa, ObjCISA& ret_isa);
150 
151         AppleObjCRuntimeV2&                                         m_runtime;
152         std::map<ObjCISA,ObjCLanguageRuntime::ClassDescriptorSP>    m_cache;
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;
156 
157         DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
158     };
159 
160     class TaggedPointerVendor
161     {
162     public:
163         static TaggedPointerVendor*
164         CreateInstance (AppleObjCRuntimeV2& runtime,
165                         const lldb::ModuleSP& objc_module_sp);
166 
167         virtual bool
168         IsPossibleTaggedPointer (lldb::addr_t ptr) = 0;
169 
170         virtual ObjCLanguageRuntime::ClassDescriptorSP
171         GetClassDescriptor (lldb::addr_t ptr) = 0;
172 
173         virtual
~TaggedPointerVendor()174         ~TaggedPointerVendor () { }
175     protected:
176         AppleObjCRuntimeV2&                                         m_runtime;
177 
TaggedPointerVendor(AppleObjCRuntimeV2 & runtime)178         TaggedPointerVendor (AppleObjCRuntimeV2& runtime) :
179         m_runtime(runtime)
180         {
181         }
182     private:
183 
184         DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor);
185     };
186 
187     class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendor
188     {
189     public:
190         virtual bool
191         IsPossibleTaggedPointer (lldb::addr_t ptr);
192 
193         virtual ObjCLanguageRuntime::ClassDescriptorSP
194         GetClassDescriptor (lldb::addr_t ptr);
195     protected:
196         TaggedPointerVendorRuntimeAssisted (AppleObjCRuntimeV2& runtime,
197                                              uint64_t objc_debug_taggedpointer_mask,
198                                              uint32_t objc_debug_taggedpointer_slot_shift,
199                                              uint32_t objc_debug_taggedpointer_slot_mask,
200                                              uint32_t objc_debug_taggedpointer_payload_lshift,
201                                              uint32_t objc_debug_taggedpointer_payload_rshift,
202                                              lldb::addr_t objc_debug_taggedpointer_classes);
203 
204         typedef std::map<uint8_t,ObjCLanguageRuntime::ClassDescriptorSP> Cache;
205         typedef Cache::iterator CacheIterator;
206         Cache                                                       m_cache;
207         uint64_t                                                    m_objc_debug_taggedpointer_mask;
208         uint32_t                                                    m_objc_debug_taggedpointer_slot_shift;
209         uint32_t                                                    m_objc_debug_taggedpointer_slot_mask;
210         uint32_t                                                    m_objc_debug_taggedpointer_payload_lshift;
211         uint32_t                                                    m_objc_debug_taggedpointer_payload_rshift;
212         lldb::addr_t                                                m_objc_debug_taggedpointer_classes;
213 
214         friend class AppleObjCRuntimeV2::TaggedPointerVendor;
215 
216         DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
217     };
218 
219     class TaggedPointerVendorLegacy : public TaggedPointerVendor
220     {
221     public:
222         virtual bool
223         IsPossibleTaggedPointer (lldb::addr_t ptr);
224 
225         virtual ObjCLanguageRuntime::ClassDescriptorSP
226         GetClassDescriptor (lldb::addr_t ptr);
227     protected:
TaggedPointerVendorLegacy(AppleObjCRuntimeV2 & runtime)228         TaggedPointerVendorLegacy (AppleObjCRuntimeV2& runtime) :
229         TaggedPointerVendor (runtime),
230         m_Foundation_version(0)
231         {
232         }
233 
234         static uint32_t
235         GetFoundationVersion (Target& target);
236 
237         uint32_t m_Foundation_version;
238 
239         friend class AppleObjCRuntimeV2::TaggedPointerVendor;
240 
241         DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
242     };
243 
244     AppleObjCRuntimeV2 (Process *process,
245                         const lldb::ModuleSP &objc_module_sp);
246 
247     bool
248     IsTaggedPointer(lldb::addr_t ptr);
249 
250     lldb::addr_t
251     GetISAHashTablePointer ();
252 
253     bool
254     UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table);
255 
256     bool
257     UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
258 
259     void
260     ParseClassInfoArray (const lldb_private::DataExtractor &data,
261                          uint32_t num_class_infos);
262 
263     bool
264     UpdateISAToDescriptorMapSharedCache ();
265 
266     lldb::addr_t
267     GetSharedCacheReadOnlyAddress();
268 
269     std::unique_ptr<ClangFunction>            m_get_class_info_function;
270     std::unique_ptr<ClangUtilityFunction>     m_get_class_info_code;
271     lldb::addr_t                            m_get_class_info_args;
272     Mutex                                   m_get_class_info_args_mutex;
273 
274     std::unique_ptr<ClangFunction>            m_get_shared_cache_class_info_function;
275     std::unique_ptr<ClangUtilityFunction>     m_get_shared_cache_class_info_code;
276     lldb::addr_t                            m_get_shared_cache_class_info_args;
277     Mutex                                   m_get_shared_cache_class_info_args_mutex;
278 
279     std::unique_ptr<TypeVendor>               m_type_vendor_ap;
280     lldb::addr_t                            m_isa_hash_table_ptr;
281     HashTableSignature                      m_hash_signature;
282     bool                                    m_has_object_getClass;
283     bool                                    m_loaded_objc_opt;
284     std::unique_ptr<NonPointerISACache>       m_non_pointer_isa_cache_ap;
285     std::unique_ptr<TaggedPointerVendor>    m_tagged_pointer_vendor_ap;
286 };
287 
288 } // namespace lldb_private
289 
290 #endif  // liblldb_AppleObjCRuntimeV2_h_
291