]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / source / Plugins / LanguageRuntime / ObjC / AppleObjCRuntime / AppleObjCRuntimeV2.cpp
1 //===-- AppleObjCRuntimeV2.cpp ----------------------------------*- 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 // C Includes
11 #include <stdint.h>
12
13 // C++ Includes
14 #include <string>
15 #include <vector>
16
17 // Other libraries and framework includes
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/DeclObjC.h"
20
21 // Project includes
22 #include "lldb/lldb-enumerations.h"
23 #include "lldb/Core/ClangForward.h"
24 #include "lldb/Symbol/CompilerType.h"
25
26 #include "lldb/Core/ClangForward.h"
27 #include "lldb/Core/ConstString.h"
28 #include "lldb/Core/Debugger.h"
29 #include "lldb/Core/Error.h"
30 #include "lldb/Core/Log.h"
31 #include "lldb/Core/Module.h"
32 #include "lldb/Core/PluginManager.h"
33 #include "lldb/Core/Scalar.h"
34 #include "lldb/Core/Section.h"
35 #include "lldb/Core/Stream.h"
36 #include "lldb/Core/StreamString.h"
37 #include "lldb/Core/Timer.h"
38 #include "lldb/Core/ValueObjectVariable.h"
39 #include "lldb/Expression/DiagnosticManager.h"
40 #include "lldb/Expression/FunctionCaller.h"
41 #include "lldb/Expression/UtilityFunction.h"
42 #include "lldb/Host/StringConvert.h"
43 #include "lldb/Interpreter/CommandObject.h"
44 #include "lldb/Interpreter/CommandObjectMultiword.h"
45 #include "lldb/Interpreter/CommandReturnObject.h"
46 #include "lldb/Interpreter/OptionValueBoolean.h"
47 #include "lldb/Symbol/ClangASTContext.h"
48 #include "lldb/Symbol/ObjectFile.h"
49 #include "lldb/Symbol/Symbol.h"
50 #include "lldb/Symbol/TypeList.h"
51 #include "lldb/Symbol/VariableList.h"
52 #include "lldb/Target/ExecutionContext.h"
53 #include "lldb/Target/Platform.h"
54 #include "lldb/Target/Process.h"
55 #include "lldb/Target/RegisterContext.h"
56 #include "lldb/Target/Target.h"
57 #include "lldb/Target/Thread.h"
58
59 #include "AppleObjCRuntimeV2.h"
60 #include "AppleObjCClassDescriptorV2.h"
61 #include "AppleObjCTypeEncodingParser.h"
62 #include "AppleObjCDeclVendor.h"
63 #include "AppleObjCTrampolineHandler.h"
64
65
66 using namespace lldb;
67 using namespace lldb_private;
68
69 // 2 second timeout when running utility functions
70 #define UTILITY_FUNCTION_TIMEOUT_USEC 2*1000*1000
71
72 static const char *g_get_dynamic_class_info_name = "__lldb_apple_objc_v2_get_dynamic_class_info";
73 // Testing using the new C++11 raw string literals. If this breaks GCC then we will
74 // need to revert to the code above...
75 static const char *g_get_dynamic_class_info_body = R"(
76
77 extern "C"
78 {
79     size_t strlen(const char *);
80     char *strncpy (char * s1, const char * s2, size_t n);
81     int printf(const char * format, ...);
82 }
83 #define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
84
85 typedef struct _NXMapTable {
86     void *prototype;
87     unsigned num_classes;
88     unsigned num_buckets_minus_one;
89     void *buckets;
90 } NXMapTable;
91
92 #define NX_MAPNOTAKEY   ((void *)(-1))
93
94 typedef struct BucketInfo
95 {
96     const char *name_ptr;
97     Class isa;
98 } BucketInfo;
99
100 struct ClassInfo
101 {
102     Class isa;
103     uint32_t hash;
104 } __attribute__((__packed__));
105
106 uint32_t
107 __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,
108                                              void *class_infos_ptr,
109                                              uint32_t class_infos_byte_size,
110                                              uint32_t should_log)
111 {
112     DEBUG_PRINTF ("gdb_objc_realized_classes_ptr = %p\n", gdb_objc_realized_classes_ptr);
113     DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
114     DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
115     const NXMapTable *grc = (const NXMapTable *)gdb_objc_realized_classes_ptr;
116     if (grc)
117     {
118         const unsigned num_classes = grc->num_classes;
119         if (class_infos_ptr)
120         {
121             const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
122             ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
123             BucketInfo *buckets = (BucketInfo *)grc->buckets;
124             
125             uint32_t idx = 0;
126             for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i)
127             {
128                 if (buckets[i].name_ptr != NX_MAPNOTAKEY)
129                 {
130                     if (idx < max_class_infos)
131                     {
132                         const char *s = buckets[i].name_ptr;
133                         uint32_t h = 5381;
134                         for (unsigned char c = *s; c; c = *++s)
135                             h = ((h << 5) + h) + c;
136                         class_infos[idx].hash = h;
137                         class_infos[idx].isa = buckets[i].isa;
138                     }
139                     ++idx;
140                 }
141             }
142             if (idx < max_class_infos)
143             {
144                 class_infos[idx].isa = NULL;
145                 class_infos[idx].hash = 0;
146             }
147         }
148         return num_classes;
149     }
150     return 0;
151 }
152
153 )";
154
155 static const char *g_get_shared_cache_class_info_name = "__lldb_apple_objc_v2_get_shared_cache_class_info";
156 // Testing using the new C++11 raw string literals. If this breaks GCC then we will
157 // need to revert to the code above...
158 static const char *g_get_shared_cache_class_info_body = R"(
159
160 extern "C"
161 {
162     const char *class_getName(void *objc_class);
163     size_t strlen(const char *);
164     char *strncpy (char * s1, const char * s2, size_t n);
165     int printf(const char * format, ...);
166 }
167
168 #define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
169
170
171 struct objc_classheader_t {
172     int32_t clsOffset;
173     int32_t hiOffset;
174 };
175
176 struct objc_clsopt_t {
177     uint32_t capacity;
178     uint32_t occupied;
179     uint32_t shift;
180     uint32_t mask;
181     uint32_t zero;
182     uint32_t unused;
183     uint64_t salt;
184     uint32_t scramble[256];
185     uint8_t tab[0]; // tab[mask+1]
186     //  uint8_t checkbytes[capacity];
187     //  int32_t offset[capacity];
188     //  objc_classheader_t clsOffsets[capacity];
189     //  uint32_t duplicateCount;
190     //  objc_classheader_t duplicateOffsets[duplicateCount];
191 };
192
193 struct objc_opt_t {
194     uint32_t version;
195     int32_t selopt_offset;
196     int32_t headeropt_offset;
197     int32_t clsopt_offset;
198 };
199
200 struct objc_opt_v14_t {
201     uint32_t version;
202     uint32_t flags;
203     int32_t selopt_offset;
204     int32_t headeropt_offset;
205     int32_t clsopt_offset;
206 };
207
208 struct ClassInfo
209 {
210     Class isa;
211     uint32_t hash;
212 }  __attribute__((__packed__));
213
214 uint32_t
215 __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
216                                                   void *class_infos_ptr,
217                                                   uint32_t class_infos_byte_size,
218                                                   uint32_t should_log)
219 {
220     uint32_t idx = 0;
221     DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
222     DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
223     DEBUG_PRINTF ("class_infos_byte_size = %u (%llu class infos)\n", class_infos_byte_size, (uint64_t)(class_infos_byte_size/sizeof(ClassInfo)));
224     if (objc_opt_ro_ptr)
225     {
226         const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
227         const objc_opt_v14_t* objc_opt_v14 = (objc_opt_v14_t*)objc_opt_ro_ptr;
228         const bool is_v14_format = objc_opt->version >= 14;
229         if (is_v14_format)
230         {
231             DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v14->version);
232             DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v14->flags);
233             DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt_v14->selopt_offset);
234             DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt_v14->headeropt_offset);
235             DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt_v14->clsopt_offset);
236         }
237         else
238         {
239             DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt->version);
240             DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt->selopt_offset);
241             DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
242             DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
243         }
244         if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14 || objc_opt->version == 15)
245         {
246             const objc_clsopt_t* clsopt = NULL;
247             if (is_v14_format)
248                 clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt_v14 + objc_opt_v14->clsopt_offset);
249             else
250                 clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
251             const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
252             DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
253             ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
254             int32_t invalidEntryOffset = 0;
255             // this is safe to do because the version field order is invariant
256             if (objc_opt->version == 12)
257                 invalidEntryOffset = 16;
258             const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
259             const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
260             const objc_classheader_t *classOffsets = (const objc_classheader_t *)(offsets + clsopt->capacity);
261             DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
262             DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
263             DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
264             DEBUG_PRINTF("invalidEntryOffset = %d\n", invalidEntryOffset);
265             for (uint32_t i=0; i<clsopt->capacity; ++i)
266             {
267                 const int32_t clsOffset = classOffsets[i].clsOffset;
268                 DEBUG_PRINTF("clsOffset[%u] = %u\n", i, clsOffset);
269                 if (clsOffset & 1)
270                 {
271                     DEBUG_PRINTF("clsOffset & 1\n");
272                     continue; // duplicate
273                 }
274                 else if (clsOffset == invalidEntryOffset)
275                 {
276                     DEBUG_PRINTF("clsOffset == invalidEntryOffset\n");
277                     continue; // invalid offset
278                 }
279                 
280                 if (class_infos && idx < max_class_infos)
281                 {
282                     class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
283                     const char *name = class_getName (class_infos[idx].isa);
284                     DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
285                     // Hash the class name so we don't have to read it
286                     const char *s = name;
287                     uint32_t h = 5381;
288                     for (unsigned char c = *s; c; c = *++s)
289                         h = ((h << 5) + h) + c;
290                     class_infos[idx].hash = h;
291                 }
292                 else
293                 {
294                     DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
295                 }
296                 ++idx;
297             }
298             
299             const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
300             const uint32_t duplicate_count = *duplicate_count_ptr;
301             const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);
302             DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
303             DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
304             for (uint32_t i=0; i<duplicate_count; ++i)
305             {
306                 const int32_t clsOffset = duplicateClassOffsets[i].clsOffset;
307                 if (clsOffset & 1)
308                     continue; // duplicate
309                 else if (clsOffset == invalidEntryOffset)
310                     continue; // invalid offset
311                 
312                 if (class_infos && idx < max_class_infos)
313                 {
314                     class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
315                     const char *name = class_getName (class_infos[idx].isa);
316                     DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
317                     // Hash the class name so we don't have to read it
318                     const char *s = name;
319                     uint32_t h = 5381;
320                     for (unsigned char c = *s; c; c = *++s)
321                         h = ((h << 5) + h) + c;
322                     class_infos[idx].hash = h;
323                 }
324                 ++idx;
325             }
326         }
327         DEBUG_PRINTF ("%u class_infos\n", idx);
328         DEBUG_PRINTF ("done\n");
329     }
330     return idx;
331 }
332
333
334 )";
335
336 static uint64_t
337 ExtractRuntimeGlobalSymbol (Process* process,
338                             ConstString name,
339                             const ModuleSP &module_sp,
340                             Error& error,
341                             bool read_value = true,
342                             uint8_t byte_size = 0,
343                             uint64_t default_value = LLDB_INVALID_ADDRESS,
344                             SymbolType sym_type = lldb::eSymbolTypeData)
345 {
346     if (!process)
347     {
348         error.SetErrorString("no process");
349         return default_value;
350     }
351     if (!module_sp)
352     {
353         error.SetErrorString("no module");
354         return default_value;
355     }
356     if (!byte_size)
357         byte_size = process->GetAddressByteSize();
358     const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
359     if (symbol && symbol->ValueIsAddress())
360     {
361         lldb::addr_t symbol_load_addr = symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
362         if (symbol_load_addr != LLDB_INVALID_ADDRESS)
363         {
364             if (read_value)
365                 return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size, default_value, error);
366             else
367                 return symbol_load_addr;
368         }
369         else
370         {
371             error.SetErrorString("symbol address invalid");
372             return default_value;
373         }
374     }
375     else
376     {
377         error.SetErrorString("no symbol");
378         return default_value;
379     }
380 }
381
382 AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, const ModuleSP &objc_module_sp)
383     : AppleObjCRuntime(process),
384       m_get_class_info_code(),
385       m_get_class_info_args(LLDB_INVALID_ADDRESS),
386       m_get_class_info_args_mutex(),
387       m_get_shared_cache_class_info_code(),
388       m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
389       m_get_shared_cache_class_info_args_mutex(),
390       m_decl_vendor_ap(),
391       m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
392       m_hash_signature(),
393       m_has_object_getClass(false),
394       m_loaded_objc_opt(false),
395       m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this, objc_module_sp)),
396       m_tagged_pointer_vendor_ap(TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
397       m_encoding_to_type_sp(),
398       m_noclasses_warning_emitted(false)
399 {
400     static const ConstString g_gdb_object_getClass("gdb_object_getClass");
401     m_has_object_getClass =
402         (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
403 }
404
405 bool
406 AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
407                                               DynamicValueType use_dynamic, 
408                                               TypeAndOrName &class_type_or_name, 
409                                               Address &address,
410                                               Value::ValueType &value_type)
411 {
412     // We should never get here with a null process...
413     assert (m_process != NULL);
414
415     // The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
416     // Note, however, the process might be NULL (e.g. if the value was made with SBTarget::EvaluateExpression...)
417     // in which case it is sufficient if the target's match:
418     
419     Process *process = in_value.GetProcessSP().get();
420     if (process)
421         assert (process == m_process);
422     else
423         assert (in_value.GetTargetSP().get() == m_process->CalculateTarget().get());
424     
425     class_type_or_name.Clear();
426     value_type = Value::ValueType::eValueTypeScalar;
427
428     // Make sure we can have a dynamic value before starting...
429     if (CouldHaveDynamicValue (in_value))
430     {
431         // First job, pull out the address at 0 offset from the object  That will be the ISA pointer.
432         ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor (in_value));
433         if (objc_class_sp)
434         {
435             const addr_t object_ptr = in_value.GetPointerValue();
436             address.SetRawAddress(object_ptr);
437
438             ConstString class_name (objc_class_sp->GetClassName());
439             class_type_or_name.SetName(class_name);
440             TypeSP type_sp (objc_class_sp->GetType());
441             if (type_sp)
442                 class_type_or_name.SetTypeSP (type_sp);
443             else
444             {
445                 type_sp = LookupInCompleteClassCache (class_name);
446                 if (type_sp)
447                 {
448                     objc_class_sp->SetType (type_sp);
449                     class_type_or_name.SetTypeSP (type_sp);
450                 }
451                 else
452                 {
453                     // try to go for a CompilerType at least
454                     DeclVendor* vendor = GetDeclVendor();
455                     if (vendor)
456                     {
457                         std::vector<clang::NamedDecl*> decls;
458                         if (vendor->FindDecls(class_name, false, 1, decls) && decls.size())
459                             class_type_or_name.SetCompilerType(ClangASTContext::GetTypeForDecl(decls[0]));
460                     }
461                 }
462             }
463         }
464     }    
465     return class_type_or_name.IsEmpty() == false;
466 }
467
468 //------------------------------------------------------------------
469 // Static Functions
470 //------------------------------------------------------------------
471 LanguageRuntime *
472 AppleObjCRuntimeV2::CreateInstance (Process *process, LanguageType language)
473 {
474     // FIXME: This should be a MacOS or iOS process, and we need to look for the OBJC section to make
475     // sure we aren't using the V1 runtime.
476     if (language == eLanguageTypeObjC)
477     {
478         ModuleSP objc_module_sp;
479         
480         if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == ObjCRuntimeVersions::eAppleObjC_V2)
481             return new AppleObjCRuntimeV2 (process, objc_module_sp);
482         else
483             return NULL;
484     }
485     else
486         return NULL;
487 }
488
489 class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed
490 {
491 public:
492     class CommandOptions : public Options
493     {
494     public:
495         CommandOptions (CommandInterpreter &interpreter) :
496         Options(interpreter),
497         m_verbose(false,false)
498         {}
499         
500         ~CommandOptions() override = default;
501
502         Error
503         SetOptionValue(uint32_t option_idx, const char *option_arg) override
504         {
505             Error error;
506             const int short_option = m_getopt_table[option_idx].val;
507             switch (short_option)
508             {
509                 case 'v':
510                     m_verbose.SetCurrentValue(true);
511                     m_verbose.SetOptionWasSet();
512                     break;
513                     
514                 default:
515                     error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
516                     break;
517             }
518             
519             return error;
520         }
521         
522         void
523         OptionParsingStarting() override
524         {
525             m_verbose.Clear();
526         }
527         
528         const OptionDefinition*
529         GetDefinitions() override
530         {
531             return g_option_table;
532         }
533
534         OptionValueBoolean m_verbose;
535         static OptionDefinition g_option_table[];
536     };
537
538     CommandObjectObjC_ClassTable_Dump (CommandInterpreter &interpreter) :
539     CommandObjectParsed (interpreter,
540                          "dump",
541                          "Dump information on Objective-C classes known to the current process.",
542                          "language objc class-table dump",
543                          eCommandRequiresProcess       |
544                          eCommandProcessMustBeLaunched |
545                          eCommandProcessMustBePaused   ),
546     m_options(interpreter)
547     {
548         CommandArgumentEntry arg;
549         CommandArgumentData index_arg;
550         
551         // Define the first (and only) variant of this arg.
552         index_arg.arg_type = eArgTypeRegularExpression;
553         index_arg.arg_repetition = eArgRepeatOptional;
554         
555         // There is only one variant this argument could be; put it into the argument entry.
556         arg.push_back (index_arg);
557         
558         // Push the data for the first argument into the m_arguments vector.
559         m_arguments.push_back (arg);
560     }
561
562     ~CommandObjectObjC_ClassTable_Dump() override = default;
563
564     Options *
565     GetOptions() override
566     {
567         return &m_options;
568     }
569     
570 protected:
571     bool
572     DoExecute(Args& command, CommandReturnObject &result) override
573     {
574         std::unique_ptr<RegularExpression> regex_up;
575         switch(command.GetArgumentCount())
576         {
577             case 0:
578                 break;
579             case 1:
580             {
581                 regex_up.reset(new RegularExpression());
582                 if (!regex_up->Compile(command.GetArgumentAtIndex(0)))
583                 {
584                     result.AppendError("invalid argument - please provide a valid regular expression");
585                     result.SetStatus(lldb::eReturnStatusFailed);
586                     return false;
587                 }
588                 break;
589             }
590             default:
591             {
592                 result.AppendError("please provide 0 or 1 arguments");
593                 result.SetStatus(lldb::eReturnStatusFailed);
594                 return false;
595             }
596         }
597         
598         Process *process = m_exe_ctx.GetProcessPtr();
599         ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
600         if (objc_runtime)
601         {
602             auto iterators_pair = objc_runtime->GetDescriptorIteratorPair();
603             auto iterator = iterators_pair.first;
604             auto &std_out = result.GetOutputStream();
605             for(; iterator != iterators_pair.second; iterator++)
606             {
607                 if (iterator->second)
608                 {
609                     const char* class_name = iterator->second->GetClassName().AsCString("<unknown>");
610                     if (regex_up && class_name && !regex_up->Execute(class_name))
611                         continue;
612                     std_out.Printf("isa = 0x%" PRIx64, iterator->first);
613                     std_out.Printf(" name = %s", class_name);
614                     std_out.Printf(" instance size = %" PRIu64, iterator->second->GetInstanceSize());
615                     std_out.Printf(" num ivars = %" PRIuPTR, (uintptr_t)iterator->second->GetNumIVars());
616                     if (auto superclass = iterator->second->GetSuperclass())
617                     {
618                         std_out.Printf(" superclass = %s", superclass->GetClassName().AsCString("<unknown>"));
619                     }
620                     std_out.Printf("\n");
621                     if (m_options.m_verbose)
622                     {
623                         for(size_t i = 0;
624                             i < iterator->second->GetNumIVars();
625                             i++)
626                         {
627                             auto ivar = iterator->second->GetIVarAtIndex(i);
628                             std_out.Printf("  ivar name = %s type = %s size = %" PRIu64 " offset = %" PRId32 "\n",
629                                                             ivar.m_name.AsCString("<unknown>"),
630                                                             ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
631                                                             ivar.m_size,
632                                                             ivar.m_offset);
633                         }
634                         iterator->second->Describe(nullptr,
635                                                    [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
636                                                        std_out.Printf("  instance method name = %s type = %s\n",
637                                                                       name,
638                                                                       type);
639                                                        return false;
640                                                    },
641                                                    [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
642                                                        std_out.Printf("  class method name = %s type = %s\n",
643                                                                       name,
644                                                                       type);
645                                                        return false;
646                                                    },
647                                                    nullptr);
648                     }
649                 }
650                 else
651                 {
652                     if (regex_up && !regex_up->Execute(""))
653                         continue;
654                     std_out.Printf("isa = 0x%" PRIx64 " has no associated class.\n", iterator->first);
655                 }
656             }
657             result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
658             return true;
659         }
660         else
661         {
662             result.AppendError("current process has no Objective-C runtime loaded");
663             result.SetStatus(lldb::eReturnStatusFailed);
664             return false;
665         }
666     }
667     
668     CommandOptions m_options;
669 };
670
671 OptionDefinition
672 CommandObjectObjC_ClassTable_Dump::CommandOptions::g_option_table[] =
673 {
674     { LLDB_OPT_SET_ALL, false, "verbose"        , 'v', OptionParser::eNoArgument        , nullptr, nullptr, 0, eArgTypeNone,        "Print ivar and method information in detail"},
675     { 0               , false, nullptr           ,   0, 0                  , nullptr, nullptr, 0, eArgTypeNone,        nullptr }
676 };
677
678 class CommandObjectMultiwordObjC_TaggedPointer_Info : public CommandObjectParsed
679 {
680 public:
681     CommandObjectMultiwordObjC_TaggedPointer_Info (CommandInterpreter &interpreter) :
682     CommandObjectParsed (interpreter,
683                          "info",
684                          "Dump information on a tagged pointer.",
685                          "language objc tagged-pointer info",
686                          eCommandRequiresProcess       |
687                          eCommandProcessMustBeLaunched |
688                          eCommandProcessMustBePaused   )
689     {
690         CommandArgumentEntry arg;
691         CommandArgumentData index_arg;
692         
693         // Define the first (and only) variant of this arg.
694         index_arg.arg_type = eArgTypeAddress;
695         index_arg.arg_repetition = eArgRepeatPlus;
696         
697         // There is only one variant this argument could be; put it into the argument entry.
698         arg.push_back (index_arg);
699         
700         // Push the data for the first argument into the m_arguments vector.
701         m_arguments.push_back (arg);
702     }
703
704     ~CommandObjectMultiwordObjC_TaggedPointer_Info() override = default;
705
706 protected:
707     bool
708     DoExecute(Args& command, CommandReturnObject &result) override
709     {
710         if (command.GetArgumentCount() == 0)
711         {
712             result.AppendError("this command requires arguments");
713             result.SetStatus(lldb::eReturnStatusFailed);
714             return false;
715         }
716         
717         Process *process = m_exe_ctx.GetProcessPtr();
718         ExecutionContext exe_ctx(process);
719         ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
720         if (objc_runtime)
721         {
722             ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor = objc_runtime->GetTaggedPointerVendor();
723             if (tagged_ptr_vendor)
724             {
725                 for (size_t i = 0;
726                      i < command.GetArgumentCount();
727                      i++)
728                 {
729                     const char *arg_str = command.GetArgumentAtIndex(i);
730                     if (!arg_str)
731                         continue;
732                     Error error;
733                     lldb::addr_t arg_addr = Args::StringToAddress(&exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error);
734                     if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail())
735                         continue;
736                     auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr);
737                     if (!descriptor_sp)
738                         continue;
739                     uint64_t info_bits = 0;
740                     uint64_t value_bits = 0;
741                     uint64_t payload = 0;
742                     if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, &payload))
743                     {
744                         result.GetOutputStream().Printf("0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64 "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64 "\n\tclass = %s\n",
745                                                         (uint64_t)arg_addr,
746                                                         payload,
747                                                         value_bits,
748                                                         info_bits,
749                                                         descriptor_sp->GetClassName().AsCString("<unknown>"));
750                     }
751                     else
752                     {
753                         result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n", (uint64_t)arg_addr);
754                     }
755                 }
756             }
757             else
758             {
759                 result.AppendError("current process has no tagged pointer support");
760                 result.SetStatus(lldb::eReturnStatusFailed);
761                 return false;
762             }
763             result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
764             return true;
765         }
766         else
767         {
768             result.AppendError("current process has no Objective-C runtime loaded");
769             result.SetStatus(lldb::eReturnStatusFailed);
770             return false;
771         }
772     }
773 };
774
775 class CommandObjectMultiwordObjC_ClassTable : public CommandObjectMultiword
776 {
777 public:
778     CommandObjectMultiwordObjC_ClassTable(CommandInterpreter &interpreter)
779         : CommandObjectMultiword(interpreter, "class-table", "Commands for operating on the Objective-C class table.",
780                                  "class-table <subcommand> [<subcommand-options>]")
781     {
782         LoadSubCommand ("dump",   CommandObjectSP (new CommandObjectObjC_ClassTable_Dump (interpreter)));
783     }
784
785     ~CommandObjectMultiwordObjC_ClassTable() override = default;
786 };
787
788 class CommandObjectMultiwordObjC_TaggedPointer : public CommandObjectMultiword
789 {
790 public:
791     CommandObjectMultiwordObjC_TaggedPointer(CommandInterpreter &interpreter)
792         : CommandObjectMultiword(interpreter, "tagged-pointer",
793                                  "Commands for operating on Objective-C tagged pointers.",
794                                  "class-table <subcommand> [<subcommand-options>]")
795     {
796         LoadSubCommand ("info",   CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer_Info (interpreter)));
797     }
798
799     ~CommandObjectMultiwordObjC_TaggedPointer() override = default;
800 };
801
802 class CommandObjectMultiwordObjC : public CommandObjectMultiword
803 {
804 public:
805     CommandObjectMultiwordObjC(CommandInterpreter &interpreter)
806         : CommandObjectMultiword(interpreter, "objc", "Commands for operating on the Objective-C language runtime.",
807                                  "objc <subcommand> [<subcommand-options>]")
808     {
809         LoadSubCommand ("class-table",   CommandObjectSP (new CommandObjectMultiwordObjC_ClassTable (interpreter)));
810         LoadSubCommand ("tagged-pointer",   CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer (interpreter)));
811     }
812
813     ~CommandObjectMultiwordObjC() override = default;
814 };
815
816 void
817 AppleObjCRuntimeV2::Initialize()
818 {
819     PluginManager::RegisterPlugin (GetPluginNameStatic(),
820                                    "Apple Objective C Language Runtime - Version 2",
821                                    CreateInstance,
822                                    [] (CommandInterpreter& interpreter) -> lldb::CommandObjectSP {
823                                        return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
824                                    });
825 }
826
827 void
828 AppleObjCRuntimeV2::Terminate()
829 {
830     PluginManager::UnregisterPlugin (CreateInstance);
831 }
832
833 lldb_private::ConstString
834 AppleObjCRuntimeV2::GetPluginNameStatic()
835 {
836     static ConstString g_name("apple-objc-v2");
837     return g_name;
838 }
839
840 //------------------------------------------------------------------
841 // PluginInterface protocol
842 //------------------------------------------------------------------
843 lldb_private::ConstString
844 AppleObjCRuntimeV2::GetPluginName()
845 {
846     return GetPluginNameStatic();
847 }
848
849 uint32_t
850 AppleObjCRuntimeV2::GetPluginVersion()
851 {
852     return 1;
853 }
854
855 BreakpointResolverSP
856 AppleObjCRuntimeV2::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
857 {
858     BreakpointResolverSP resolver_sp;
859     
860     if (throw_bp)
861         resolver_sp.reset (new BreakpointResolverName (bkpt,
862                                                        "objc_exception_throw",
863                                                        eFunctionNameTypeBase,
864                                                        eLanguageTypeUnknown,
865                                                        Breakpoint::Exact,
866                                                        0,
867                                                        eLazyBoolNo));
868     // FIXME: We don't do catch breakpoints for ObjC yet.
869     // Should there be some way for the runtime to specify what it can do in this regard?
870     return resolver_sp;
871 }
872
873 UtilityFunction *
874 AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
875 {
876     char check_function_code[2048];
877     
878     int len = 0;
879     if (m_has_object_getClass)
880     {
881         len = ::snprintf (check_function_code, 
882                           sizeof(check_function_code),
883                           "extern \"C\" void *gdb_object_getClass(void *);                                          \n"
884                           "extern \"C\"  int printf(const char *format, ...);                                       \n"
885                           "extern \"C\" void                                                                        \n"
886                           "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector)                                    \n"
887                           "{                                                                                        \n"
888                           "   if ($__lldb_arg_obj == (void *)0)                                                     \n"
889                           "       return; // nil is ok                                                              \n" 
890                           "   if (!gdb_object_getClass($__lldb_arg_obj))                                            \n"
891                           "       *((volatile int *)0) = 'ocgc';                                                    \n"
892                           "   else if ($__lldb_arg_selector != (void *)0)                                           \n"
893                           "   {                                                                                     \n"
894                           "        signed char responds = (signed char) [(id) $__lldb_arg_obj                       \n"
895                           "                                                respondsToSelector:                      \n"
896                           "                                       (struct objc_selector *) $__lldb_arg_selector];   \n"
897                           "       if (responds == (signed char) 0)                                                  \n"
898                           "           *((volatile int *)0) = 'ocgc';                                                \n"
899                           "   }                                                                                     \n"
900                           "}                                                                                        \n",
901                           name);
902     }
903     else
904     {
905         len = ::snprintf (check_function_code, 
906                           sizeof(check_function_code), 
907                           "extern \"C\" void *gdb_class_getClass(void *);                                           \n"
908                           "extern \"C\"  int printf(const char *format, ...);                                       \n"
909                           "extern \"C\"  void                                                                       \n"
910                           "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector)                                    \n"
911                           "{                                                                                        \n"
912                           "   if ($__lldb_arg_obj == (void *)0)                                                     \n"
913                           "       return; // nil is ok                                                              \n" 
914                           "    void **$isa_ptr = (void **)$__lldb_arg_obj;                                          \n"
915                           "    if (*$isa_ptr == (void *)0 || !gdb_class_getClass(*$isa_ptr))                        \n"
916                           "       *((volatile int *)0) = 'ocgc';                                                    \n"
917                           "   else if ($__lldb_arg_selector != (void *)0)                                           \n"
918                           "   {                                                                                     \n"
919                           "        signed char responds = (signed char) [(id) $__lldb_arg_obj                       \n"
920                           "                                                respondsToSelector:                      \n"
921                           "                                        (struct objc_selector *) $__lldb_arg_selector];  \n"
922                           "       if (responds == (signed char) 0)                                                  \n"
923                           "           *((volatile int *)0) = 'ocgc';                                                \n"
924                           "   }                                                                                     \n"
925                           "}                                                                                        \n", 
926                           name);
927     }
928     
929     assert (len < (int)sizeof(check_function_code));
930
931     Error error;
932     return GetTargetRef().GetUtilityFunctionForLanguage(check_function_code, eLanguageTypeObjC, name, error);
933 }
934
935 size_t
936 AppleObjCRuntimeV2::GetByteOffsetForIvar (CompilerType &parent_ast_type, const char *ivar_name)
937 {
938     uint32_t ivar_offset = LLDB_INVALID_IVAR_OFFSET;
939
940     const char *class_name = parent_ast_type.GetConstTypeName().AsCString();
941     if (class_name && class_name[0] && ivar_name && ivar_name[0])
942     {
943         //----------------------------------------------------------------------
944         // Make the objective C V2 mangled name for the ivar offset from the
945         // class name and ivar name
946         //----------------------------------------------------------------------
947         std::string buffer("OBJC_IVAR_$_");
948         buffer.append (class_name);
949         buffer.push_back ('.');
950         buffer.append (ivar_name);
951         ConstString ivar_const_str (buffer.c_str());
952         
953         //----------------------------------------------------------------------
954         // Try to get the ivar offset address from the symbol table first using
955         // the name we created above
956         //----------------------------------------------------------------------
957         SymbolContextList sc_list;
958         Target &target = m_process->GetTarget();
959         target.GetImages().FindSymbolsWithNameAndType(ivar_const_str, eSymbolTypeObjCIVar, sc_list);
960
961         addr_t ivar_offset_address = LLDB_INVALID_ADDRESS;
962
963         Error error;
964         SymbolContext ivar_offset_symbol;
965         if (sc_list.GetSize() == 1 && sc_list.GetContextAtIndex(0, ivar_offset_symbol))
966         {
967             if (ivar_offset_symbol.symbol)
968                 ivar_offset_address = ivar_offset_symbol.symbol->GetLoadAddress (&target);
969         }
970
971         //----------------------------------------------------------------------
972         // If we didn't get the ivar offset address from the symbol table, fall
973         // back to getting it from the runtime
974         //----------------------------------------------------------------------
975         if (ivar_offset_address == LLDB_INVALID_ADDRESS)
976             ivar_offset_address = LookupRuntimeSymbol(ivar_const_str);
977
978         if (ivar_offset_address != LLDB_INVALID_ADDRESS)
979             ivar_offset = m_process->ReadUnsignedIntegerFromMemory (ivar_offset_address,
980                                                                     4,
981                                                                     LLDB_INVALID_IVAR_OFFSET,
982                                                                     error);
983     }
984     return ivar_offset;
985 }
986
987 // tagged pointers are special not-a-real-pointer values that contain both type and value information
988 // this routine attempts to check with as little computational effort as possible whether something
989 // could possibly be a tagged pointer - false positives are possible but false negatives shouldn't
990 bool
991 AppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr)
992 {
993     if (!m_tagged_pointer_vendor_ap)
994         return false;
995     return m_tagged_pointer_vendor_ap->IsPossibleTaggedPointer(ptr);
996 }
997
998 class RemoteNXMapTable
999 {
1000 public:
1001     RemoteNXMapTable () :
1002         m_count (0),
1003         m_num_buckets_minus_one (0),
1004         m_buckets_ptr (LLDB_INVALID_ADDRESS),
1005         m_process (NULL),
1006         m_end_iterator (*this, -1),
1007         m_load_addr (LLDB_INVALID_ADDRESS),
1008         m_map_pair_size (0),
1009         m_invalid_key (0)
1010     {
1011     }
1012     
1013     void
1014     Dump ()
1015     {
1016         printf ("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
1017         printf ("RemoteNXMapTable.m_count = %u\n", m_count);
1018         printf ("RemoteNXMapTable.m_num_buckets_minus_one = %u\n", m_num_buckets_minus_one);
1019         printf ("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
1020     }
1021     
1022     bool
1023     ParseHeader (Process* process, lldb::addr_t load_addr)
1024     {
1025         m_process = process;
1026         m_load_addr = load_addr;
1027         m_map_pair_size = m_process->GetAddressByteSize() * 2;
1028         m_invalid_key = m_process->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX;
1029         Error err;
1030         
1031         // This currently holds true for all platforms we support, but we might
1032         // need to change this to use get the actually byte size of "unsigned"
1033         // from the target AST...
1034         const uint32_t unsigned_byte_size = sizeof(uint32_t);
1035         // Skip the prototype as we don't need it (const struct +NXMapTablePrototype *prototype)
1036         
1037         bool success = true;
1038         if (load_addr == LLDB_INVALID_ADDRESS)
1039             success = false;
1040         else
1041         {
1042             lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
1043                     
1044             // unsigned count;
1045             m_count = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
1046             if (m_count)
1047             {
1048                 cursor += unsigned_byte_size;
1049             
1050                 // unsigned nbBucketsMinusOne;
1051                 m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
1052                 cursor += unsigned_byte_size;
1053             
1054                 // void *buckets;
1055                 m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
1056                 
1057                 success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
1058             }
1059         }
1060         
1061         if (!success)
1062         {
1063             m_count = 0;
1064             m_num_buckets_minus_one = 0;
1065             m_buckets_ptr = LLDB_INVALID_ADDRESS;
1066         }
1067         return success;
1068     }
1069     
1070     // const_iterator mimics NXMapState and its code comes from NXInitMapState and NXNextMapState.
1071     typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA> element;
1072
1073     friend class const_iterator;
1074     class const_iterator
1075     {
1076     public:
1077         const_iterator (RemoteNXMapTable &parent, int index) : m_parent(parent), m_index(index)
1078         {
1079             AdvanceToValidIndex();
1080         }
1081         
1082         const_iterator (const const_iterator &rhs) : m_parent(rhs.m_parent), m_index(rhs.m_index)
1083         {
1084             // AdvanceToValidIndex() has been called by rhs already.
1085         }
1086         
1087         const_iterator &operator=(const const_iterator &rhs)
1088         {
1089             // AdvanceToValidIndex() has been called by rhs already.
1090             assert (&m_parent == &rhs.m_parent);
1091             m_index = rhs.m_index;
1092             return *this;
1093         }
1094         
1095         bool operator==(const const_iterator &rhs) const
1096         {
1097             if (&m_parent != &rhs.m_parent)
1098                 return false;
1099             if (m_index != rhs.m_index)
1100                 return false;
1101             
1102             return true;
1103         }
1104         
1105         bool operator!=(const const_iterator &rhs) const
1106         {
1107             return !(operator==(rhs));
1108         }
1109         
1110         const_iterator &operator++()
1111         {
1112             AdvanceToValidIndex();
1113             return *this;
1114         }
1115         
1116         const element operator*() const
1117         {
1118             if (m_index == -1)
1119             {
1120                 // TODO find a way to make this an error, but not an assert
1121                 return element();
1122             }
1123          
1124             lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
1125             size_t map_pair_size = m_parent.m_map_pair_size;
1126             lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
1127             
1128             Error err;
1129             
1130             lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
1131             if (!err.Success())
1132                 return element();
1133             lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
1134             if (!err.Success())
1135                 return element();
1136             
1137             std::string key_string;
1138             
1139             m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
1140             if (!err.Success())
1141                 return element();
1142             
1143             return element(ConstString(key_string.c_str()), (ObjCLanguageRuntime::ObjCISA)value);
1144         }
1145
1146     private:
1147         void AdvanceToValidIndex ()
1148         {
1149             if (m_index == -1)
1150                 return;
1151             
1152             const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
1153             const size_t map_pair_size = m_parent.m_map_pair_size;
1154             const lldb::addr_t invalid_key = m_parent.m_invalid_key;
1155             Error err;
1156
1157             while (m_index--)
1158             {
1159                 lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
1160                 lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
1161                 
1162                 if (!err.Success())
1163                 {
1164                     m_index = -1;
1165                     return;
1166                 }
1167                 
1168                 if (key != invalid_key)
1169                     return;
1170             }
1171         }
1172         RemoteNXMapTable   &m_parent;
1173         int                 m_index;
1174     };
1175     
1176     const_iterator begin ()
1177     {
1178         return const_iterator(*this, m_num_buckets_minus_one + 1);
1179     }
1180     
1181     const_iterator end ()
1182     {
1183         return m_end_iterator;
1184     }
1185     
1186     uint32_t
1187     GetCount () const
1188     {
1189         return m_count;
1190     }
1191     
1192     uint32_t
1193     GetBucketCount () const
1194     {
1195         return m_num_buckets_minus_one;
1196     }
1197     
1198     lldb::addr_t
1199     GetBucketDataPointer () const
1200     {
1201         return m_buckets_ptr;
1202     }
1203     
1204     lldb::addr_t
1205     GetTableLoadAddress() const
1206     {
1207         return m_load_addr;
1208     }
1209
1210 private:
1211     // contents of _NXMapTable struct
1212     uint32_t m_count;
1213     uint32_t m_num_buckets_minus_one;
1214     lldb::addr_t m_buckets_ptr;
1215     lldb_private::Process *m_process;
1216     const_iterator m_end_iterator;
1217     lldb::addr_t m_load_addr;
1218     size_t m_map_pair_size;
1219     lldb::addr_t m_invalid_key;
1220 };
1221
1222 AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() :
1223     m_count (0),
1224     m_num_buckets (0),
1225     m_buckets_ptr (0)
1226 {
1227 }
1228
1229 void
1230 AppleObjCRuntimeV2::HashTableSignature::UpdateSignature (const RemoteNXMapTable &hash_table)
1231 {
1232     m_count = hash_table.GetCount();
1233     m_num_buckets = hash_table.GetBucketCount();
1234     m_buckets_ptr = hash_table.GetBucketDataPointer();
1235 }
1236
1237 bool
1238 AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate (Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
1239 {
1240     if (!hash_table.ParseHeader(process, runtime->GetISAHashTablePointer ()))
1241     {
1242         return false; // Failed to parse the header, no need to update anything
1243     }
1244
1245     // Check with out current signature and return true if the count,
1246     // number of buckets or the hash table address changes.
1247     if (m_count == hash_table.GetCount() &&
1248         m_num_buckets == hash_table.GetBucketCount() &&
1249         m_buckets_ptr == hash_table.GetBucketDataPointer())
1250     {
1251         // Hash table hasn't changed
1252         return false;
1253     }
1254     // Hash table data has changed, we need to update
1255     return true;
1256 }
1257
1258 ObjCLanguageRuntime::ClassDescriptorSP
1259 AppleObjCRuntimeV2::GetClassDescriptorFromISA (ObjCISA isa)
1260 {
1261     ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
1262     if (m_non_pointer_isa_cache_ap.get())
1263         class_descriptor_sp = m_non_pointer_isa_cache_ap->GetClassDescriptor(isa);
1264     if (!class_descriptor_sp)
1265         class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
1266     return class_descriptor_sp;
1267 }
1268
1269 ObjCLanguageRuntime::ClassDescriptorSP
1270 AppleObjCRuntimeV2::GetClassDescriptor (ValueObject& valobj)
1271 {
1272     ClassDescriptorSP objc_class_sp;
1273     if (valobj.IsBaseClass())
1274     {
1275         ValueObject *parent = valobj.GetParent();
1276         // if I am my own parent, bail out of here fast..
1277         if (parent && parent != &valobj)
1278         {
1279             ClassDescriptorSP parent_descriptor_sp = GetClassDescriptor(*parent);
1280             if (parent_descriptor_sp)
1281                 return parent_descriptor_sp->GetSuperclass();
1282         }
1283         return nullptr;
1284     }
1285     // if we get an invalid VO (which might still happen when playing around
1286     // with pointers returned by the expression parser, don't consider this
1287     // a valid ObjC object)
1288     if (valobj.GetCompilerType().IsValid())
1289     {
1290         addr_t isa_pointer = valobj.GetPointerValue();
1291         
1292         // tagged pointer
1293         if (IsTaggedPointer(isa_pointer))
1294         {
1295             return m_tagged_pointer_vendor_ap->GetClassDescriptor(isa_pointer);
1296         }
1297         else
1298         {
1299             ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
1300             
1301             Process *process = exe_ctx.GetProcessPtr();
1302             if (process)
1303             {
1304                 Error error;
1305                 ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
1306                 if (isa != LLDB_INVALID_ADDRESS)
1307                 {
1308                     objc_class_sp = GetClassDescriptorFromISA (isa);
1309                     if (isa && !objc_class_sp)
1310                     {
1311                         Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1312                         if (log)
1313                             log->Printf("0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%" PRIx64,
1314                                         isa_pointer,
1315                                         isa);
1316                     }
1317                 }
1318             }
1319         }
1320     }
1321     return objc_class_sp;
1322 }
1323
1324 lldb::addr_t
1325 AppleObjCRuntimeV2::GetISAHashTablePointer ()
1326 {
1327     if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
1328     {
1329         Process *process = GetProcess();
1330
1331         ModuleSP objc_module_sp(GetObjCModule());
1332         
1333         if (!objc_module_sp)
1334             return LLDB_INVALID_ADDRESS;
1335
1336         static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
1337         
1338         const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_objc_realized_classes, lldb::eSymbolTypeAny);
1339         if (symbol)
1340         {
1341             lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetLoadAddress(&process->GetTarget());
1342             
1343             if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
1344             {
1345                 Error error;
1346                 m_isa_hash_table_ptr = process->ReadPointerFromMemory(gdb_objc_realized_classes_ptr, error);
1347             }
1348         }
1349     }
1350     return m_isa_hash_table_ptr;
1351 }
1352
1353 bool
1354 AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table)
1355 {
1356     Process *process = GetProcess();
1357     
1358     if (process == NULL)
1359         return false;
1360     
1361     Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1362     
1363     ExecutionContext exe_ctx;
1364     
1365     ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
1366     
1367     if (!thread_sp)
1368         return false;
1369     
1370     thread_sp->CalculateExecutionContext(exe_ctx);
1371     ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
1372     
1373     if (!ast)
1374         return false;
1375
1376     Address function_address;
1377
1378     DiagnosticManager diagnostics;
1379
1380     const uint32_t addr_size = process->GetAddressByteSize();
1381
1382     Error err;
1383     
1384     // Read the total number of classes from the hash table
1385     const uint32_t num_classes = hash_table.GetCount();
1386     if (num_classes == 0)
1387     {
1388         if (log)
1389             log->Printf ("No dynamic classes found in gdb_objc_realized_classes.");
1390         return false;
1391     }
1392     
1393     // Make some types for our arguments
1394     CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
1395     CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
1396     
1397     ValueList arguments;
1398     FunctionCaller *get_class_info_function = nullptr;
1399
1400     if (!m_get_class_info_code.get())
1401     {
1402         Error error;
1403         m_get_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_dynamic_class_info_body,
1404                                                                                    eLanguageTypeObjC,
1405                                                                                    g_get_dynamic_class_info_name,
1406                                                                                    error));
1407         if (error.Fail())
1408         {
1409             if (log)
1410                 log->Printf ("Failed to get Utility Function for implementation lookup: %s", error.AsCString());
1411             m_get_class_info_code.reset();
1412         }
1413         else
1414         {
1415             diagnostics.Clear();
1416
1417             if (!m_get_class_info_code->Install(diagnostics, exe_ctx))
1418             {
1419                 if (log)
1420                 {
1421                     log->Printf("Failed to install implementation lookup");
1422                     diagnostics.Dump(log);
1423                 }
1424                 m_get_class_info_code.reset();
1425             }
1426         }
1427         if (!m_get_class_info_code.get())
1428             return false;
1429         
1430         // Next make the runner function for our implementation utility function.
1431         Value value;
1432         value.SetValueType (Value::eValueTypeScalar);
1433         value.SetCompilerType (clang_void_pointer_type);
1434         arguments.PushValue (value);
1435         arguments.PushValue (value);
1436         
1437         value.SetValueType (Value::eValueTypeScalar);
1438         value.SetCompilerType (clang_uint32_t_type);
1439         arguments.PushValue (value);
1440         arguments.PushValue (value);
1441         
1442         get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
1443                                                                             arguments,
1444                                                                             thread_sp,
1445                                                                             error);
1446         
1447         if (error.Fail())
1448         {
1449             if (log)
1450                 log->Printf("Failed to make function caller for implementation lookup: %s.", error.AsCString());
1451             return false;
1452         }
1453     }
1454     else
1455     {
1456         get_class_info_function = m_get_class_info_code->GetFunctionCaller();
1457         if (!get_class_info_function)
1458         {
1459             if (log)
1460             {
1461                 log->Printf("Failed to get implementation lookup function caller.");
1462                 diagnostics.Dump(log);
1463             }
1464
1465             return false;
1466         }
1467         arguments = get_class_info_function->GetArgumentValues();
1468     }
1469
1470     diagnostics.Clear();
1471
1472     const uint32_t class_info_byte_size = addr_size + 4;
1473     const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
1474     lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
1475                                                             ePermissionsReadable | ePermissionsWritable,
1476                                                             err);
1477     
1478     if (class_infos_addr == LLDB_INVALID_ADDRESS)
1479         return false;
1480
1481     std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex);
1482
1483     // Fill in our function argument values
1484     arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
1485     arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
1486     arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
1487     arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
1488
1489     
1490     bool success = false;
1491
1492     diagnostics.Clear();
1493
1494     // Write our function arguments into the process so we can run our function
1495     if (get_class_info_function->WriteFunctionArguments(exe_ctx, m_get_class_info_args, arguments, diagnostics))
1496     {
1497         EvaluateExpressionOptions options;
1498         options.SetUnwindOnError(true);
1499         options.SetTryAllThreads(false);
1500         options.SetStopOthers(true);
1501         options.SetIgnoreBreakpoints(true);
1502         options.SetTimeoutUsec(UTILITY_FUNCTION_TIMEOUT_USEC);
1503         
1504         Value return_value;
1505         return_value.SetValueType (Value::eValueTypeScalar);
1506         //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
1507         return_value.SetCompilerType(clang_uint32_t_type);
1508         return_value.GetScalar() = 0;
1509
1510         diagnostics.Clear();
1511
1512         // Run the function
1513         ExpressionResults results = get_class_info_function->ExecuteFunction(exe_ctx, &m_get_class_info_args, options,
1514                                                                              diagnostics, return_value);
1515
1516         if (results == eExpressionCompleted)
1517         {
1518             // The result is the number of ClassInfo structures that were filled in
1519             uint32_t num_class_infos = return_value.GetScalar().ULong();
1520             if (log)
1521                 log->Printf("Discovered %u ObjC classes\n",num_class_infos);
1522             if (num_class_infos > 0)
1523             {
1524                 // Read the ClassInfo structures
1525                 DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
1526                 if (process->ReadMemory(class_infos_addr, buffer.GetBytes(), buffer.GetByteSize(), err) == buffer.GetByteSize())
1527                 {
1528                     DataExtractor class_infos_data (buffer.GetBytes(),
1529                                                     buffer.GetByteSize(),
1530                                                     process->GetByteOrder(),
1531                                                     addr_size);
1532                     ParseClassInfoArray (class_infos_data, num_class_infos);
1533                 }
1534             }
1535             success = true;
1536         }
1537         else
1538         {
1539             if (log)
1540             {
1541                 log->Printf("Error evaluating our find class name function.");
1542                 diagnostics.Dump(log);
1543             }
1544         }
1545     }
1546     else
1547     {
1548         if (log)
1549         {
1550             log->Printf("Error writing function arguments.");
1551             diagnostics.Dump(log);
1552         }
1553     }
1554
1555     // Deallocate the memory we allocated for the ClassInfo array
1556     process->DeallocateMemory(class_infos_addr);
1557     
1558     return success;
1559 }
1560
1561 uint32_t
1562 AppleObjCRuntimeV2::ParseClassInfoArray (const DataExtractor &data, uint32_t num_class_infos)
1563 {
1564     // Parses an array of "num_class_infos" packed ClassInfo structures:
1565     //
1566     //    struct ClassInfo
1567     //    {
1568     //        Class isa;
1569     //        uint32_t hash;
1570     //    } __attribute__((__packed__));
1571
1572     Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1573     
1574     uint32_t num_parsed = 0;
1575
1576     // Iterate through all ClassInfo structures
1577     lldb::offset_t offset = 0;
1578     for (uint32_t i=0; i<num_class_infos; ++i)
1579     {
1580         ObjCISA isa = data.GetPointer(&offset);
1581         
1582         if (isa == 0)
1583         {
1584             if (log)
1585                 log->Printf("AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
1586             continue;
1587         }
1588         // Check if we already know about this ISA, if we do, the info will
1589         // never change, so we can just skip it.
1590         if (ISAIsCached(isa))
1591         {
1592             offset += 4;
1593         }
1594         else
1595         {
1596             // Read the 32 bit hash for the class name
1597             const uint32_t name_hash = data.GetU32(&offset);
1598             ClassDescriptorSP descriptor_sp (new ClassDescriptorV2(*this, isa, NULL));
1599             AddClass (isa, descriptor_sp, name_hash);
1600             num_parsed++;
1601             if (log && log->GetVerbose())
1602                 log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64 ", hash=0x%8.8x, name=%s", isa, name_hash,descriptor_sp->GetClassName().AsCString("<unknown>"));
1603         }
1604     }
1605     return num_parsed;
1606 }
1607
1608 AppleObjCRuntimeV2::DescriptorMapUpdateResult
1609 AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
1610 {
1611     Process *process = GetProcess();
1612     
1613     if (process == NULL)
1614         return DescriptorMapUpdateResult::Fail();
1615     
1616     Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1617     
1618     ExecutionContext exe_ctx;
1619     
1620     ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
1621     
1622     if (!thread_sp)
1623         return DescriptorMapUpdateResult::Fail();
1624     
1625     thread_sp->CalculateExecutionContext(exe_ctx);
1626     ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
1627     
1628     if (!ast)
1629         return DescriptorMapUpdateResult::Fail();
1630
1631     Address function_address;
1632
1633     DiagnosticManager diagnostics;
1634
1635     const uint32_t addr_size = process->GetAddressByteSize();
1636
1637     Error err;
1638     
1639     const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
1640     
1641     if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
1642         return DescriptorMapUpdateResult::Fail();
1643     
1644     // Read the total number of classes from the hash table
1645     const uint32_t num_classes = 128*1024;
1646     if (num_classes == 0)
1647     {
1648         if (log)
1649             log->Printf ("No dynamic classes found in gdb_objc_realized_classes_addr.");
1650         return DescriptorMapUpdateResult::Fail();
1651     }
1652     
1653     // Make some types for our arguments
1654     CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
1655     CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
1656     
1657     ValueList arguments;
1658     FunctionCaller *get_shared_cache_class_info_function = nullptr;
1659     
1660     if (!m_get_shared_cache_class_info_code.get())
1661     {
1662         Error error;
1663         m_get_shared_cache_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_shared_cache_class_info_body,
1664                                                                                                 eLanguageTypeObjC,
1665                                                                                                 g_get_shared_cache_class_info_name,
1666                                                                                                 error));
1667         if (error.Fail())
1668         {
1669             if (log)
1670                 log->Printf ("Failed to get Utility function for implementation lookup: %s.", error.AsCString());
1671             m_get_shared_cache_class_info_code.reset();
1672         }
1673         else
1674         {
1675             diagnostics.Clear();
1676
1677             if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx))
1678             {
1679                 if (log)
1680                 {
1681                     log->Printf("Failed to install implementation lookup.");
1682                     diagnostics.Dump(log);
1683                 }
1684                 m_get_shared_cache_class_info_code.reset();
1685             }
1686         }
1687
1688         if (!m_get_shared_cache_class_info_code.get())
1689             return DescriptorMapUpdateResult::Fail();
1690     
1691         // Next make the function caller for our implementation utility function.
1692         Value value;
1693         value.SetValueType (Value::eValueTypeScalar);
1694         //value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
1695         value.SetCompilerType (clang_void_pointer_type);
1696         arguments.PushValue (value);
1697         arguments.PushValue (value);
1698         
1699         value.SetValueType (Value::eValueTypeScalar);
1700         //value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
1701         value.SetCompilerType (clang_uint32_t_type);
1702         arguments.PushValue (value);
1703         arguments.PushValue (value);
1704         
1705         get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
1706                                                                                                       arguments,
1707                                                                                                       thread_sp,
1708                                                                                                       error);
1709         
1710         if (get_shared_cache_class_info_function == nullptr)
1711             return DescriptorMapUpdateResult::Fail();
1712     
1713     }
1714     else
1715     {
1716         get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->GetFunctionCaller();
1717         if (get_shared_cache_class_info_function == nullptr)
1718             return DescriptorMapUpdateResult::Fail();
1719         arguments = get_shared_cache_class_info_function->GetArgumentValues();
1720     }
1721
1722     diagnostics.Clear();
1723
1724     const uint32_t class_info_byte_size = addr_size + 4;
1725     const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
1726     lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
1727                                                              ePermissionsReadable | ePermissionsWritable,
1728                                                              err);
1729     
1730     if (class_infos_addr == LLDB_INVALID_ADDRESS)
1731         return DescriptorMapUpdateResult::Fail();
1732
1733     std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex);
1734
1735     // Fill in our function argument values
1736     arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
1737     arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
1738     arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
1739     arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
1740     
1741
1742     bool success = false;
1743     bool any_found = false;
1744
1745     diagnostics.Clear();
1746
1747     // Write our function arguments into the process so we can run our function
1748     if (get_shared_cache_class_info_function->WriteFunctionArguments(exe_ctx, m_get_shared_cache_class_info_args,
1749                                                                      arguments, diagnostics))
1750     {
1751         EvaluateExpressionOptions options;
1752         options.SetUnwindOnError(true);
1753         options.SetTryAllThreads(false);
1754         options.SetStopOthers(true);
1755         options.SetIgnoreBreakpoints(true);
1756         options.SetTimeoutUsec(UTILITY_FUNCTION_TIMEOUT_USEC);
1757         
1758         Value return_value;
1759         return_value.SetValueType (Value::eValueTypeScalar);
1760         //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
1761         return_value.SetCompilerType(clang_uint32_t_type);
1762         return_value.GetScalar() = 0;
1763
1764         diagnostics.Clear();
1765
1766         // Run the function
1767         ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction(
1768             exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics, return_value);
1769
1770         if (results == eExpressionCompleted)
1771         {
1772             // The result is the number of ClassInfo structures that were filled in
1773             uint32_t num_class_infos = return_value.GetScalar().ULong();
1774             if (log)
1775                 log->Printf("Discovered %u ObjC classes in shared cache\n",num_class_infos);
1776 #ifdef LLDB_CONFIGURATION_DEBUG
1777             assert (num_class_infos <= num_classes);
1778 #endif
1779             if (num_class_infos > 0)
1780             {
1781                 if (num_class_infos > num_classes)
1782                 {
1783                     num_class_infos = num_classes;
1784                     
1785                     success = false;
1786                 }
1787                 else
1788                 {
1789                     success = true;
1790                 }
1791                 
1792                 // Read the ClassInfo structures
1793                 DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
1794                 if (process->ReadMemory(class_infos_addr,
1795                                         buffer.GetBytes(),
1796                                         buffer.GetByteSize(),
1797                                         err) == buffer.GetByteSize())
1798                 {
1799                     DataExtractor class_infos_data (buffer.GetBytes(),
1800                                                     buffer.GetByteSize(),
1801                                                     process->GetByteOrder(),
1802                                                     addr_size);
1803
1804                     any_found = (ParseClassInfoArray (class_infos_data, num_class_infos) > 0);
1805                 }
1806             }
1807             else
1808             {
1809                 success = true;
1810             }
1811         }
1812         else
1813         {
1814             if (log)
1815             {
1816                 log->Printf("Error evaluating our find class name function.");
1817                 diagnostics.Dump(log);
1818             }
1819         }
1820     }
1821     else
1822     {
1823         if (log)
1824         {
1825             log->Printf("Error writing function arguments.");
1826             diagnostics.Dump(log);
1827         }
1828     }
1829
1830     // Deallocate the memory we allocated for the ClassInfo array
1831     process->DeallocateMemory(class_infos_addr);
1832     
1833     return DescriptorMapUpdateResult(success, any_found);
1834 }
1835
1836 bool
1837 AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table)
1838 {
1839     Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1840     
1841     Process *process = GetProcess();
1842
1843     if (process == NULL)
1844         return false;
1845     
1846     uint32_t num_map_table_isas = 0;
1847     
1848     ModuleSP objc_module_sp(GetObjCModule());
1849     
1850     if (objc_module_sp)
1851     {
1852         for (RemoteNXMapTable::element elt : hash_table)
1853         {
1854             ++num_map_table_isas;
1855             
1856             if (ISAIsCached(elt.second))
1857                 continue;
1858             
1859             ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
1860             
1861             if (log && log->GetVerbose())
1862                 log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
1863             
1864             AddClass (elt.second, descriptor_sp, elt.first.AsCString());
1865         }
1866     }
1867     
1868     return num_map_table_isas > 0;
1869 }
1870
1871 lldb::addr_t
1872 AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress()
1873 {
1874     Process *process = GetProcess();
1875     
1876     if (process)
1877     {
1878         ModuleSP objc_module_sp(GetObjCModule());
1879         
1880         if (objc_module_sp)
1881         {
1882             ObjectFile *objc_object = objc_module_sp->GetObjectFile();
1883             
1884             if (objc_object)
1885             {
1886                 SectionList *section_list = objc_module_sp->GetSectionList();
1887                 
1888                 if (section_list)
1889                 {
1890                     SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
1891                     
1892                     if (text_segment_sp)
1893                     {
1894                         SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
1895                         
1896                         if (objc_opt_section_sp)
1897                         {
1898                             return objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
1899                         }
1900                     }
1901                 }
1902             }
1903         }
1904     }
1905     return LLDB_INVALID_ADDRESS;
1906 }
1907
1908 void
1909 AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
1910 {
1911     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
1912     
1913     // Else we need to check with our process to see when the map was updated.
1914     Process *process = GetProcess();
1915
1916     if (process)
1917     {
1918         RemoteNXMapTable hash_table;
1919         
1920         // Update the process stop ID that indicates the last time we updated the
1921         // map, whether it was successful or not.
1922         m_isa_to_descriptor_stop_id = process->GetStopID();
1923         
1924         if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
1925             return;
1926         
1927         m_hash_signature.UpdateSignature (hash_table);
1928
1929         // Grab the dynamically loaded objc classes from the hash table in memory
1930         UpdateISAToDescriptorMapDynamic(hash_table);
1931
1932         // Now get the objc classes that are baked into the Objective C runtime
1933         // in the shared cache, but only once per process as this data never
1934         // changes
1935         if (!m_loaded_objc_opt)
1936         {
1937             DescriptorMapUpdateResult shared_cache_update_result = UpdateISAToDescriptorMapSharedCache();
1938             if (!shared_cache_update_result.any_found)
1939                 WarnIfNoClassesCached ();
1940             else
1941                 m_loaded_objc_opt = true;
1942         }
1943     }
1944     else
1945     {
1946         m_isa_to_descriptor_stop_id = UINT32_MAX;
1947     }
1948 }
1949
1950 void
1951 AppleObjCRuntimeV2::WarnIfNoClassesCached ()
1952 {
1953     if (m_noclasses_warning_emitted)
1954         return;
1955
1956     if (m_process &&
1957         m_process->GetTarget().GetPlatform() &&
1958         m_process->GetTarget().GetPlatform()->GetPluginName().GetStringRef().endswith("-simulator"))
1959     {
1960         // Simulators do not have the objc_opt_ro class table so don't actually complain to the user
1961         m_noclasses_warning_emitted = true;
1962         return;
1963     }
1964
1965     Debugger &debugger(GetProcess()->GetTarget().GetDebugger());
1966     
1967     if (debugger.GetAsyncOutputStream())
1968     {
1969         debugger.GetAsyncOutputStream()->PutCString("warning: could not load any Objective-C class information from the dyld shared cache. This will significantly reduce the quality of type information available.\n");
1970         m_noclasses_warning_emitted = true;
1971     }
1972 }
1973
1974 // TODO: should we have a transparent_kvo parameter here to say if we
1975 // want to replace the KVO swizzled class with the actual user-level type?
1976 ConstString
1977 AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
1978 {
1979     if (isa == g_objc_Tagged_ISA)
1980     {
1981         static const ConstString g_objc_tagged_isa_name ("_lldb_Tagged_ObjC_ISA");
1982         return g_objc_tagged_isa_name;
1983     }
1984     if (isa == g_objc_Tagged_ISA_NSAtom)
1985     {
1986         static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
1987         return g_objc_tagged_isa_nsatom_name;
1988     }
1989     if (isa == g_objc_Tagged_ISA_NSNumber)
1990     {
1991         static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
1992         return g_objc_tagged_isa_nsnumber_name;
1993     }
1994     if (isa == g_objc_Tagged_ISA_NSDateTS)
1995     {
1996         static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
1997         return g_objc_tagged_isa_nsdatets_name;
1998     }
1999     if (isa == g_objc_Tagged_ISA_NSManagedObject)
2000     {
2001         static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
2002         return g_objc_tagged_isa_nsmanagedobject_name;
2003     }
2004     if (isa == g_objc_Tagged_ISA_NSDate)
2005     {
2006         static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
2007         return g_objc_tagged_isa_nsdate_name;
2008     }
2009     return ObjCLanguageRuntime::GetActualTypeName(isa);
2010 }
2011
2012 DeclVendor *
2013 AppleObjCRuntimeV2::GetDeclVendor()
2014 {
2015     if (!m_decl_vendor_ap.get())
2016         m_decl_vendor_ap.reset(new AppleObjCDeclVendor(*this));
2017     
2018     return m_decl_vendor_ap.get();
2019 }
2020
2021 lldb::addr_t
2022 AppleObjCRuntimeV2::LookupRuntimeSymbol (const ConstString &name)
2023 {
2024     lldb::addr_t ret = LLDB_INVALID_ADDRESS;
2025
2026     const char *name_cstr = name.AsCString();    
2027     
2028     if (name_cstr)
2029     {
2030         llvm::StringRef name_strref(name_cstr);
2031         
2032         static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
2033         static const llvm::StringRef class_prefix("OBJC_CLASS_$_");
2034         
2035         if (name_strref.startswith(ivar_prefix))
2036         {
2037             llvm::StringRef ivar_skipped_prefix = name_strref.substr(ivar_prefix.size());
2038             std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar = ivar_skipped_prefix.split('.');
2039             
2040             if (class_and_ivar.first.size() && class_and_ivar.second.size())
2041             {
2042                 const ConstString class_name_cs(class_and_ivar.first);
2043                 ClassDescriptorSP descriptor = ObjCLanguageRuntime::GetClassDescriptorFromClassName(class_name_cs);
2044                                 
2045                 if (descriptor)
2046                 {
2047                     const ConstString ivar_name_cs(class_and_ivar.second);
2048                     const char *ivar_name_cstr = ivar_name_cs.AsCString();
2049                     
2050                     auto ivar_func = [&ret, ivar_name_cstr](const char *name, const char *type, lldb::addr_t offset_addr, uint64_t size) -> lldb::addr_t
2051                     {
2052                         if (!strcmp(name, ivar_name_cstr))
2053                         {
2054                             ret = offset_addr;
2055                             return true;
2056                         }
2057                         return false;
2058                     };
2059
2060                     descriptor->Describe(std::function<void (ObjCISA)>(nullptr),
2061                                          std::function<bool (const char *, const char *)>(nullptr),
2062                                          std::function<bool (const char *, const char *)>(nullptr),
2063                                          ivar_func);
2064                 }
2065             }
2066         }
2067         else if (name_strref.startswith(class_prefix))
2068         {
2069             llvm::StringRef class_skipped_prefix = name_strref.substr(class_prefix.size());
2070             const ConstString class_name_cs(class_skipped_prefix);
2071             ClassDescriptorSP descriptor = GetClassDescriptorFromClassName(class_name_cs);
2072             
2073             if (descriptor)
2074                 ret = descriptor->GetISA();
2075         }
2076     }
2077     
2078     return ret;
2079 }
2080
2081 AppleObjCRuntimeV2::NonPointerISACache*
2082 AppleObjCRuntimeV2::NonPointerISACache::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
2083 {
2084     Process* process(runtime.GetProcess());
2085     
2086     Error error;
2087     
2088     auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol(process,
2089                                                                 ConstString("objc_debug_isa_magic_mask"),
2090                                                                 objc_module_sp,
2091                                                                 error);
2092     if (error.Fail())
2093         return NULL;
2094
2095     auto objc_debug_isa_magic_value = ExtractRuntimeGlobalSymbol(process,
2096                                                                  ConstString("objc_debug_isa_magic_value"),
2097                                                                  objc_module_sp,
2098                                                                  error);
2099     if (error.Fail())
2100         return NULL;
2101
2102     auto objc_debug_isa_class_mask = ExtractRuntimeGlobalSymbol(process,
2103                                                                 ConstString("objc_debug_isa_class_mask"),
2104                                                                 objc_module_sp,
2105                                                                 error);
2106     if (error.Fail())
2107         return NULL;
2108
2109     // we might want to have some rules to outlaw these other values (e.g if the mask is zero but the value is non-zero, ...)
2110     
2111     return new NonPointerISACache(runtime,
2112                                   objc_debug_isa_class_mask,
2113                                   objc_debug_isa_magic_mask,
2114                                   objc_debug_isa_magic_value);
2115 }
2116
2117 AppleObjCRuntimeV2::TaggedPointerVendorV2*
2118 AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
2119 {
2120     Process* process(runtime.GetProcess());
2121     
2122     Error error;
2123     
2124     auto objc_debug_taggedpointer_mask = ExtractRuntimeGlobalSymbol(process,
2125                                                                     ConstString("objc_debug_taggedpointer_mask"),
2126                                                                     objc_module_sp,
2127                                                                     error);
2128     if (error.Fail())
2129         return new TaggedPointerVendorLegacy(runtime);
2130     
2131     auto objc_debug_taggedpointer_slot_shift = ExtractRuntimeGlobalSymbol(process,
2132                                                                           ConstString("objc_debug_taggedpointer_slot_shift"),
2133                                                                           objc_module_sp,
2134                                                                           error,
2135                                                                           true,
2136                                                                           4);
2137     if (error.Fail())
2138         return new TaggedPointerVendorLegacy(runtime);
2139     
2140     auto objc_debug_taggedpointer_slot_mask = ExtractRuntimeGlobalSymbol(process,
2141                                                                           ConstString("objc_debug_taggedpointer_slot_mask"),
2142                                                                           objc_module_sp,
2143                                                                           error,
2144                                                                           true,
2145                                                                           4);
2146     if (error.Fail())
2147         return new TaggedPointerVendorLegacy(runtime);
2148
2149     auto objc_debug_taggedpointer_payload_lshift = ExtractRuntimeGlobalSymbol(process,
2150                                                                               ConstString("objc_debug_taggedpointer_payload_lshift"),
2151                                                                               objc_module_sp,
2152                                                                               error,
2153                                                                               true,
2154                                                                               4);
2155     if (error.Fail())
2156         return new TaggedPointerVendorLegacy(runtime);
2157     
2158     auto objc_debug_taggedpointer_payload_rshift = ExtractRuntimeGlobalSymbol(process,
2159                                                                               ConstString("objc_debug_taggedpointer_payload_rshift"),
2160                                                                               objc_module_sp,
2161                                                                               error,
2162                                                                               true,
2163                                                                               4);
2164     if (error.Fail())
2165         return new TaggedPointerVendorLegacy(runtime);
2166     
2167     auto objc_debug_taggedpointer_classes = ExtractRuntimeGlobalSymbol(process,
2168                                                                        ConstString("objc_debug_taggedpointer_classes"),
2169                                                                        objc_module_sp,
2170                                                                        error,
2171                                                                        false);
2172     if (error.Fail())
2173         return new TaggedPointerVendorLegacy(runtime);
2174
2175     // try to detect the "extended tagged pointer" variables - if any are missing, use the non-extended vendor
2176     do
2177     {
2178         auto objc_debug_taggedpointer_ext_mask = ExtractRuntimeGlobalSymbol(process,
2179                                                                             ConstString("objc_debug_taggedpointer_ext_mask"),
2180                                                                             objc_module_sp,
2181                                                                             error);
2182         if (error.Fail())
2183             break;
2184         
2185         auto objc_debug_taggedpointer_ext_slot_shift = ExtractRuntimeGlobalSymbol(process,
2186                                                                                   ConstString("objc_debug_taggedpointer_ext_slot_shift"),
2187                                                                                   objc_module_sp,
2188                                                                                   error,
2189                                                                                   true,
2190                                                                                   4);
2191         if (error.Fail())
2192             break;
2193         
2194         auto objc_debug_taggedpointer_ext_slot_mask = ExtractRuntimeGlobalSymbol(process,
2195                                                                                  ConstString("objc_debug_taggedpointer_ext_slot_mask"),
2196                                                                                  objc_module_sp,
2197                                                                                  error,
2198                                                                                  true,
2199                                                                                  4);
2200         if (error.Fail())
2201             break;
2202         
2203         auto objc_debug_taggedpointer_ext_classes = ExtractRuntimeGlobalSymbol(process,
2204                                                                                ConstString("objc_debug_taggedpointer_ext_classes"),
2205                                                                                objc_module_sp,
2206                                                                                error,
2207                                                                                false);
2208         if (error.Fail())
2209             break;
2210         
2211         auto objc_debug_taggedpointer_ext_payload_lshift = ExtractRuntimeGlobalSymbol(process,
2212                                                                                       ConstString("objc_debug_taggedpointer_ext_payload_lshift"),
2213                                                                                       objc_module_sp,
2214                                                                                       error,
2215                                                                                       true,
2216                                                                                       4);
2217         if (error.Fail())
2218             break;
2219         
2220         auto objc_debug_taggedpointer_ext_payload_rshift = ExtractRuntimeGlobalSymbol(process,
2221                                                                                       ConstString("objc_debug_taggedpointer_ext_payload_rshift"),
2222                                                                                       objc_module_sp,
2223                                                                                       error,
2224                                                                                       true,
2225                                                                                       4);
2226         if (error.Fail())
2227             break;
2228         
2229         return new TaggedPointerVendorExtended(runtime,
2230                                                objc_debug_taggedpointer_mask,
2231                                                objc_debug_taggedpointer_ext_mask,
2232                                                objc_debug_taggedpointer_slot_shift,
2233                                                objc_debug_taggedpointer_ext_slot_shift,
2234                                                objc_debug_taggedpointer_slot_mask,
2235                                                objc_debug_taggedpointer_ext_slot_mask,
2236                                                objc_debug_taggedpointer_payload_lshift,
2237                                                objc_debug_taggedpointer_payload_rshift,
2238                                                objc_debug_taggedpointer_ext_payload_lshift,
2239                                                objc_debug_taggedpointer_ext_payload_rshift,
2240                                                objc_debug_taggedpointer_classes,
2241                                                objc_debug_taggedpointer_ext_classes);
2242     } while(false);
2243     
2244     // we might want to have some rules to outlaw these values (e.g if the table's address is zero)
2245     
2246     return new TaggedPointerVendorRuntimeAssisted(runtime,
2247                                                   objc_debug_taggedpointer_mask,
2248                                                   objc_debug_taggedpointer_slot_shift,
2249                                                   objc_debug_taggedpointer_slot_mask,
2250                                                   objc_debug_taggedpointer_payload_lshift,
2251                                                   objc_debug_taggedpointer_payload_rshift,
2252                                                   objc_debug_taggedpointer_classes);
2253 }
2254
2255 bool
2256 AppleObjCRuntimeV2::TaggedPointerVendorLegacy::IsPossibleTaggedPointer (lldb::addr_t ptr)
2257 {
2258     return (ptr & 1);
2259 }
2260
2261 ObjCLanguageRuntime::ClassDescriptorSP
2262 AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor (lldb::addr_t ptr)
2263 {
2264     if (!IsPossibleTaggedPointer(ptr))
2265         return ObjCLanguageRuntime::ClassDescriptorSP();
2266
2267     uint32_t foundation_version = m_runtime.GetFoundationVersion();
2268     
2269     if (foundation_version == LLDB_INVALID_MODULE_VERSION)
2270         return ObjCLanguageRuntime::ClassDescriptorSP();
2271     
2272     uint64_t class_bits = (ptr & 0xE) >> 1;
2273     ConstString name;
2274     
2275     // TODO: make a table
2276     if (foundation_version >= 900)
2277     {
2278         switch (class_bits)
2279         {
2280             case 0:
2281                 name = ConstString("NSAtom");
2282                 break;
2283             case 3:
2284                 name = ConstString("NSNumber");
2285                 break;
2286             case 4:
2287                 name = ConstString("NSDateTS");
2288                 break;
2289             case 5:
2290                 name = ConstString("NSManagedObject");
2291                 break;
2292             case 6:
2293                 name = ConstString("NSDate");
2294                 break;
2295             default:
2296                 return ObjCLanguageRuntime::ClassDescriptorSP();
2297         }
2298     }
2299     else
2300     {
2301         switch (class_bits)
2302         {
2303             case 1:
2304                 name = ConstString("NSNumber");
2305                 break;
2306             case 5:
2307                 name = ConstString("NSManagedObject");
2308                 break;
2309             case 6:
2310                 name = ConstString("NSDate");
2311                 break;
2312             case 7:
2313                 name = ConstString("NSDateTS");
2314                 break;
2315             default:
2316                 return ObjCLanguageRuntime::ClassDescriptorSP();
2317         }
2318     }
2319     return ClassDescriptorSP(new ClassDescriptorV2Tagged(name,ptr));
2320 }
2321
2322 AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::TaggedPointerVendorRuntimeAssisted (AppleObjCRuntimeV2& runtime,
2323                                                                                             uint64_t objc_debug_taggedpointer_mask,
2324                                                                                             uint32_t objc_debug_taggedpointer_slot_shift,
2325                                                                                             uint32_t objc_debug_taggedpointer_slot_mask,
2326                                                                                             uint32_t objc_debug_taggedpointer_payload_lshift,
2327                                                                                             uint32_t objc_debug_taggedpointer_payload_rshift,
2328                                                                                             lldb::addr_t objc_debug_taggedpointer_classes) :
2329 TaggedPointerVendorV2(runtime),
2330 m_cache(),
2331 m_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask),
2332 m_objc_debug_taggedpointer_slot_shift(objc_debug_taggedpointer_slot_shift),
2333 m_objc_debug_taggedpointer_slot_mask(objc_debug_taggedpointer_slot_mask),
2334 m_objc_debug_taggedpointer_payload_lshift(objc_debug_taggedpointer_payload_lshift),
2335 m_objc_debug_taggedpointer_payload_rshift(objc_debug_taggedpointer_payload_rshift),
2336 m_objc_debug_taggedpointer_classes(objc_debug_taggedpointer_classes)
2337 {
2338 }
2339
2340 bool
2341 AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::IsPossibleTaggedPointer (lldb::addr_t ptr)
2342 {
2343     return (ptr & m_objc_debug_taggedpointer_mask) != 0;
2344 }
2345
2346 ObjCLanguageRuntime::ClassDescriptorSP
2347 AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor (lldb::addr_t ptr)
2348 {
2349     ClassDescriptorSP actual_class_descriptor_sp;
2350     uint64_t data_payload;
2351
2352     if (!IsPossibleTaggedPointer(ptr))
2353         return ObjCLanguageRuntime::ClassDescriptorSP();
2354     
2355     uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) & m_objc_debug_taggedpointer_slot_mask;
2356     
2357     CacheIterator iterator = m_cache.find(slot),
2358     end = m_cache.end();
2359     if (iterator != end)
2360     {
2361         actual_class_descriptor_sp = iterator->second;
2362     }
2363     else
2364     {
2365         Process* process(m_runtime.GetProcess());
2366         uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_classes;
2367         Error error;
2368         uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
2369         if (error.Fail() || slot_data == 0 || slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
2370             return nullptr;
2371         actual_class_descriptor_sp = m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
2372         if (!actual_class_descriptor_sp)
2373             return ObjCLanguageRuntime::ClassDescriptorSP();
2374         m_cache[slot] = actual_class_descriptor_sp;
2375     }
2376     
2377     data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_payload_lshift) >> m_objc_debug_taggedpointer_payload_rshift);
2378     
2379     return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
2380 }
2381
2382 AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended (AppleObjCRuntimeV2& runtime,
2383                                                                               uint64_t objc_debug_taggedpointer_mask,
2384                                                                               uint64_t objc_debug_taggedpointer_ext_mask,
2385                                                                               uint32_t objc_debug_taggedpointer_slot_shift,
2386                                                                               uint32_t objc_debug_taggedpointer_ext_slot_shift,
2387                                                                               uint32_t objc_debug_taggedpointer_slot_mask,
2388                                                                               uint32_t objc_debug_taggedpointer_ext_slot_mask,
2389                                                                               uint32_t objc_debug_taggedpointer_payload_lshift,
2390                                                                               uint32_t objc_debug_taggedpointer_payload_rshift,
2391                                                                               uint32_t objc_debug_taggedpointer_ext_payload_lshift,
2392                                                                               uint32_t objc_debug_taggedpointer_ext_payload_rshift,
2393                                                                               lldb::addr_t objc_debug_taggedpointer_classes,
2394                                                                               lldb::addr_t objc_debug_taggedpointer_ext_classes) :
2395 TaggedPointerVendorRuntimeAssisted(runtime,
2396                                    objc_debug_taggedpointer_mask,
2397                                    objc_debug_taggedpointer_slot_shift,
2398                                    objc_debug_taggedpointer_slot_mask,
2399                                    objc_debug_taggedpointer_payload_lshift,
2400                                    objc_debug_taggedpointer_payload_rshift,
2401                                    objc_debug_taggedpointer_classes),
2402 m_ext_cache(),
2403 m_objc_debug_taggedpointer_ext_mask(objc_debug_taggedpointer_ext_mask),
2404 m_objc_debug_taggedpointer_ext_slot_shift(objc_debug_taggedpointer_ext_slot_shift),
2405 m_objc_debug_taggedpointer_ext_slot_mask(objc_debug_taggedpointer_ext_slot_mask),
2406 m_objc_debug_taggedpointer_ext_payload_lshift(objc_debug_taggedpointer_ext_payload_lshift),
2407 m_objc_debug_taggedpointer_ext_payload_rshift(objc_debug_taggedpointer_ext_payload_rshift),
2408 m_objc_debug_taggedpointer_ext_classes(objc_debug_taggedpointer_ext_classes)
2409 {
2410 }
2411
2412 bool
2413 AppleObjCRuntimeV2::TaggedPointerVendorExtended::IsPossibleExtendedTaggedPointer (lldb::addr_t ptr)
2414 {
2415     if (!IsPossibleTaggedPointer(ptr))
2416         return false;
2417     
2418     if (m_objc_debug_taggedpointer_ext_mask == 0)
2419         return false;
2420     
2421     return ((ptr & m_objc_debug_taggedpointer_ext_mask) == m_objc_debug_taggedpointer_ext_mask);
2422 }
2423
2424 ObjCLanguageRuntime::ClassDescriptorSP
2425 AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor (lldb::addr_t ptr)
2426 {
2427     ClassDescriptorSP actual_class_descriptor_sp;
2428     uint64_t data_payload;
2429     
2430     if (!IsPossibleTaggedPointer(ptr))
2431         return ObjCLanguageRuntime::ClassDescriptorSP();
2432     
2433     if (!IsPossibleExtendedTaggedPointer(ptr))
2434         return this->TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(ptr);
2435     
2436     uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) & m_objc_debug_taggedpointer_ext_slot_mask;
2437     
2438     CacheIterator iterator = m_ext_cache.find(slot),
2439     end = m_ext_cache.end();
2440     if (iterator != end)
2441     {
2442         actual_class_descriptor_sp = iterator->second;
2443     }
2444     else
2445     {
2446         Process* process(m_runtime.GetProcess());
2447         uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_ext_classes;
2448         Error error;
2449         uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
2450         if (error.Fail() || slot_data == 0 || slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
2451             return nullptr;
2452         actual_class_descriptor_sp = m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
2453         if (!actual_class_descriptor_sp)
2454             return ObjCLanguageRuntime::ClassDescriptorSP();
2455         m_ext_cache[slot] = actual_class_descriptor_sp;
2456     }
2457     
2458     data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift);
2459     
2460     return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
2461 }
2462
2463 AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache (AppleObjCRuntimeV2& runtime,
2464                                                             uint64_t objc_debug_isa_class_mask,
2465                                                             uint64_t objc_debug_isa_magic_mask,
2466                                                             uint64_t objc_debug_isa_magic_value) :
2467 m_runtime(runtime),
2468 m_cache(),
2469 m_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
2470 m_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
2471 m_objc_debug_isa_magic_value(objc_debug_isa_magic_value)
2472 {
2473 }
2474
2475 ObjCLanguageRuntime::ClassDescriptorSP
2476 AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor (ObjCISA isa)
2477 {
2478     ObjCISA real_isa = 0;
2479     if (EvaluateNonPointerISA(isa, real_isa) == false)
2480         return ObjCLanguageRuntime::ClassDescriptorSP();
2481     auto cache_iter = m_cache.find(real_isa);
2482     if (cache_iter != m_cache.end())
2483         return cache_iter->second;
2484     auto descriptor_sp = m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(real_isa);
2485     if (descriptor_sp) // cache only positive matches since the table might grow
2486         m_cache[real_isa] = descriptor_sp;
2487     return descriptor_sp;
2488 }
2489
2490 bool
2491 AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA (ObjCISA isa, ObjCISA& ret_isa)
2492 {
2493     if ( (isa & ~m_objc_debug_isa_class_mask) == 0)
2494         return false;
2495     if ( (isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value)
2496     {
2497         ret_isa = isa & m_objc_debug_isa_class_mask;
2498         return (ret_isa != 0); // this is a pointer so 0 is not a valid value
2499     }
2500     return false;
2501 }
2502
2503 ObjCLanguageRuntime::EncodingToTypeSP
2504 AppleObjCRuntimeV2::GetEncodingToType ()
2505 {
2506     if (!m_encoding_to_type_sp)
2507         m_encoding_to_type_sp.reset(new AppleObjCTypeEncodingParser(*this));
2508     return m_encoding_to_type_sp;
2509 }
2510
2511 lldb_private::AppleObjCRuntime::ObjCISA
2512 AppleObjCRuntimeV2::GetPointerISA (ObjCISA isa)
2513 {
2514     ObjCISA ret = isa;
2515     
2516     if (m_non_pointer_isa_cache_ap)
2517         m_non_pointer_isa_cache_ap->EvaluateNonPointerISA(isa, ret);
2518     
2519     return ret;
2520 }