1642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//===-- AppleObjCRuntimeV2.cpp --------------------------------------*- C++ -*-===//
2642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//
3642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//                     The LLVM Compiler Infrastructure
4642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//
5642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// This file is distributed under the University of Illinois Open Source
6642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// License. See LICENSE.TXT for details.
7642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//
8642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//===----------------------------------------------------------------------===//
9642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h"
11642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
1258513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include <string>
1358513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include <vector>
1458513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include <stdint.h>
1558513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
1658513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include "lldb/lldb-enumerations.h"
1758513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include "lldb/Core/ClangForward.h"
1858513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include "lldb/Symbol/ClangASTType.h"
19324067bc91877dbbd6ec3a8663914fa3dbb7e3c9Jim Ingham
2058513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include "lldb/Core/ClangForward.h"
21642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Core/ConstString.h"
22642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Core/Error.h"
23b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Core/Log.h"
24642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Core/Module.h"
25642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Core/PluginManager.h"
26642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Core/Scalar.h"
2749ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Section.h"
28b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Core/StreamString.h"
299540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan#include "lldb/Core/Timer.h"
30d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata#include "lldb/Core/ValueObjectVariable.h"
31b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Expression/ClangFunction.h"
322eac2b9b61bfbe6079bab86e879263d63046ac0aJim Ingham#include "lldb/Expression/ClangUtilityFunction.h"
33642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Symbol/ClangASTContext.h"
346fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan#include "lldb/Symbol/ObjectFile.h"
3549ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Symbol/Symbol.h"
36c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan#include "lldb/Symbol/TypeList.h"
37d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata#include "lldb/Symbol/VariableList.h"
38b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/ExecutionContext.h"
39642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Target/Process.h"
40642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Target/RegisterContext.h"
41642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Target/Target.h"
42642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Target/Thread.h"
43642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
4458513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include "AppleObjCRuntimeV2.h"
45c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan#include "AppleObjCTypeVendor.h"
4658513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham#include "AppleObjCTrampolineHandler.h"
4758513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
48642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include <vector>
49642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
50642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamusing namespace lldb;
51642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamusing namespace lldb_private;
52642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
53ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton// 2 second timeout when running utility functions
54ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#define UTILITY_FUNCTION_TIMEOUT_USEC 2*1000*1000
55ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham
56ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstatic const char *g_get_dynamic_class_info_name = "__lldb_apple_objc_v2_get_dynamic_class_info";
57ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton// Testing using the new C++11 raw string literals. If this breaks GCC then we will
58ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton// need to revert to the code above...
59ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstatic const char *g_get_dynamic_class_info_body = R"(
60ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
61ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonextern "C"
62ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
63ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    size_t strlen(const char *);
64ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    char *strncpy (char * s1, const char * s2, size_t n);
65ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int printf(const char * format, ...);
66ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
67ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
68ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#ifdef ENABLE_DEBUG_PRINTF
69ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
70ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#else
71ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#define DEBUG_PRINTF(fmt, ...)
72ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#endif
73ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
74ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytontypedef struct _NXMapTable {
75ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    void *prototype;
76ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    unsigned num_classes;
77ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    unsigned num_buckets_minus_one;
78ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    void *buckets;
79ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton} NXMapTable;
80ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
81ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#define NX_MAPNOTAKEY   ((void *)(-1))
82ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
83ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytontypedef struct BucketInfo
84ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
85ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const char *name_ptr;
86ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Class isa;
87ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton} BucketInfo;
88ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
89ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstruct ClassInfo
90ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
91ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Class isa;
92ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t hash;
93ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton} __attribute__((__packed__));
94ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
95ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonuint32_t
962e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton__lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,
972e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                             void *class_infos_ptr,
982e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                             uint32_t class_infos_byte_size)
99ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
100ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    DEBUG_PRINTF ("gdb_objc_realized_classes_ptr = %p\n", gdb_objc_realized_classes_ptr);
101ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
102ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
103ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const NXMapTable *grc = (const NXMapTable *)gdb_objc_realized_classes_ptr;
104ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (grc)
105ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
106ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        const unsigned num_classes = grc->num_classes;
107ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (class_infos_ptr)
108ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
109ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
110ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
111ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            BucketInfo *buckets = (BucketInfo *)grc->buckets;
112ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
113ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            uint32_t idx = 0;
114ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i)
115ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            {
116ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (buckets[i].name_ptr != NX_MAPNOTAKEY)
117ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                {
118ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    if (idx < max_class_infos)
119ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    {
120ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        const char *s = buckets[i].name_ptr;
121ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        uint32_t h = 5381;
122ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        for (unsigned char c = *s; c; c = *++s)
123ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                            h = ((h << 5) + h) + c;
124ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        class_infos[idx].hash = h;
125ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        class_infos[idx].isa = buckets[i].isa;
126ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    }
127ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    ++idx;
128ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                }
129ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            }
130ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (idx < max_class_infos)
131ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            {
132ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                class_infos[idx].isa = NULL;
133ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                class_infos[idx].hash = 0;
134ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            }
135ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
136ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return num_classes;
137ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
138ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return 0;
139ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
140ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
141ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton)";
142ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
143ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstatic const char *g_get_shared_cache_class_info_name = "__lldb_apple_objc_v2_get_shared_cache_class_info";
144ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton// Testing using the new C++11 raw string literals. If this breaks GCC then we will
145ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton// need to revert to the code above...
146ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstatic const char *g_get_shared_cache_class_info_body = R"(
147ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
148ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonextern "C"
149ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
150ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const char *class_getName(void *objc_class);
151ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    size_t strlen(const char *);
152ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    char *strncpy (char * s1, const char * s2, size_t n);
153ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int printf(const char * format, ...);
154ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
155ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
156ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
157ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#ifdef ENABLE_DEBUG_PRINTF
158ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
159ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#else
160ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#define DEBUG_PRINTF(fmt, ...)
161ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#endif
162ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
163ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
164ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstruct objc_classheader_t {
165ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int32_t clsOffset;
166ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int32_t hiOffset;
167ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton};
168ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
169ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstruct objc_clsopt_t {
170ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t capacity;
171ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t occupied;
172ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t shift;
173ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t mask;
174ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t zero;
175ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t unused;
176ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint64_t salt;
177ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t scramble[256];
178ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint8_t tab[0]; // tab[mask+1]
179ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    //  uint8_t checkbytes[capacity];
180ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    //  int32_t offset[capacity];
181ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    //  objc_classheader_t clsOffsets[capacity];
182ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    //  uint32_t duplicateCount;
183ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    //  objc_classheader_t duplicateOffsets[duplicateCount];
184ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton};
185ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
186ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstruct objc_opt_t {
187ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t version;
188ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int32_t selopt_offset;
189ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int32_t headeropt_offset;
190ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int32_t clsopt_offset;
191ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton};
192ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
193ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonstruct ClassInfo
194ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
195ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Class isa;
196ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t hash;
197ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}  __attribute__((__packed__));
198ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
199ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonuint32_t
2002e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton__lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
2012e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                  void *class_infos_ptr,
2022e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                  uint32_t class_infos_byte_size)
203ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
204ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t idx = 0;
205ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
206ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
207ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    DEBUG_PRINTF ("class_infos_byte_size = %u (%zu class infos)\n", class_infos_byte_size, (size_t)(class_infos_byte_size/sizeof(ClassInfo)));
208ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (objc_opt_ro_ptr)
209ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
210ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
211ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt->version);
212ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt->selopt_offset);
213ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
214ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
215ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (objc_opt->version == 12)
216ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
217ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const objc_clsopt_t* clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
218ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
219ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
220ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            int32_t zeroOffset = 16;
221ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
222ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
223ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const objc_classheader_t *classOffsets = (const objc_classheader_t *)(offsets + clsopt->capacity);
224ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
225ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
226ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
227ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            for (uint32_t i=0; i<clsopt->capacity; ++i)
228ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            {
229ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                const int32_t clsOffset = classOffsets[i].clsOffset;
230ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (clsOffset & 1)
231ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    continue; // duplicate
232ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                else if (clsOffset == zeroOffset)
233ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    continue; // zero offset
234ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
235ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (class_infos && idx < max_class_infos)
236ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                {
237ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
238ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    const char *name = class_getName (class_infos[idx].isa);
239ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
240ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    // Hash the class name so we don't have to read it
241ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    const char *s = name;
242ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    uint32_t h = 5381;
243ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    for (unsigned char c = *s; c; c = *++s)
244ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        h = ((h << 5) + h) + c;
245ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    class_infos[idx].hash = h;
246ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                }
247ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                ++idx;
248ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            }
249ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
250ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
251ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const uint32_t duplicate_count = *duplicate_count_ptr;
252ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);
253ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
254ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
255ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            for (uint32_t i=0; i<duplicate_count; ++i)
256ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            {
257ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                const int32_t clsOffset = duplicateClassOffsets[i].clsOffset;
258ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (clsOffset & 1)
259ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    continue; // duplicate
260ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                else if (clsOffset == zeroOffset)
261ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    continue; // zero offset
262ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
263ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (class_infos && idx < max_class_infos)
264ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                {
265ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
266ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    const char *name = class_getName (class_infos[idx].isa);
267ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
268ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    // Hash the class name so we don't have to read it
269ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    const char *s = name;
270ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    uint32_t h = 5381;
271ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    for (unsigned char c = *s; c; c = *++s)
272ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        h = ((h << 5) + h) + c;
273ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    class_infos[idx].hash = h;
274ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                }
275ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                ++idx;
276ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            }
277ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
278ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        DEBUG_PRINTF ("%u class_infos\n", idx);
279ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        DEBUG_PRINTF ("done\n");
280ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
281ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return idx;
282ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
283ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
284ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
285ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton)";
286ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
287d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatastatic uint64_t
288d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataExtractRuntimeGlobalSymbol (Process* process,
289d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                            ConstString name,
290d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                            const ModuleSP &module_sp,
291d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                            Error& error,
292d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                            bool read_value = true,
293d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                            uint8_t byte_size = 0,
294d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                            uint64_t default_value = LLDB_INVALID_ADDRESS,
295d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                            SymbolType sym_type = lldb::eSymbolTypeData)
296d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
297d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (!process)
298d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
299d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        error.SetErrorString("no process");
300d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return default_value;
301d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
302d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (!module_sp)
303d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
304d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        error.SetErrorString("no module");
305d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return default_value;
306d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
307d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (!byte_size)
308d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        byte_size = process->GetAddressByteSize();
309d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
310d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (symbol)
311d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
312d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        lldb::addr_t symbol_load_addr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
313d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (symbol_load_addr != LLDB_INVALID_ADDRESS)
314d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        {
315d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            if (read_value)
316d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size, default_value, error);
317d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            else
318d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                return symbol_load_addr;
319d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        }
320d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        else
321d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        {
322d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            error.SetErrorString("symbol address invalid");
323d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            return default_value;
324d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        }
325d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
326d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    else
327d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
328d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        error.SetErrorString("no symbol");
329d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return default_value;
330d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
331d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
332d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
333ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
3349540568d3120dae0ef61a64fcc0410c1778fbb88Sean CallananAppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
3359540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan                                        const ModuleSP &objc_module_sp) :
3366e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    AppleObjCRuntime (process),
337ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_class_info_function(),
338ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_class_info_code(),
339ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_class_info_args (LLDB_INVALID_ADDRESS),
340ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
341ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_shared_cache_class_info_function(),
342ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_shared_cache_class_info_code(),
343ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
344ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
34590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_type_vendor_ap (),
34690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
34790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_hash_signature (),
348c62f5ab9b1c977dac97c94d4105cc9daca04fd5aSean Callanan    m_has_object_getClass (false),
349d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    m_loaded_objc_opt (false),
350d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this,objc_module_sp)),
351d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    m_tagged_pointer_vendor_ap(TaggedPointerVendor::CreateInstance(*this,objc_module_sp))
352f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan{
353249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton    static const ConstString g_gdb_object_getClass("gdb_object_getClass");
354249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton    m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
355f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan}
356f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan
35781a96aa6242f7b559770f5dc62316253cb8cb0d4Greg ClaytonAppleObjCRuntimeV2::~AppleObjCRuntimeV2()
35881a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton{
35981a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton}
36081a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton
361e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Inghambool
362d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
363249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton                                              DynamicValueType use_dynamic,
364c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton                                              TypeAndOrName &class_type_or_name,
365c0fa53324d62a48257c092a3347d6e7236aa3152Greg Clayton                                              Address &address)
366ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham{
367ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    // The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
368b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg Clayton    assert (in_value.GetProcessSP().get() == m_process);
369b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg Clayton    assert (m_process != NULL);
3701a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata
3711a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    class_type_or_name.Clear();
372b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg Clayton
373ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    // Make sure we can have a dynamic value before starting...
374ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    if (CouldHaveDynamicValue (in_value))
375ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    {
376ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham        // First job, pull out the address at 0 offset from the object  That will be the ISA pointer.
377ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor (in_value));
378ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        if (objc_class_sp)
379ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham        {
380ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            const addr_t object_ptr = in_value.GetPointerValue();
381ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            address.SetRawAddress(object_ptr);
382ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham
383ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            ConstString class_name (objc_class_sp->GetClassName());
384ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            class_type_or_name.SetName(class_name);
385ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            TypeSP type_sp (objc_class_sp->GetType());
386ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            if (type_sp)
387ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                class_type_or_name.SetTypeSP (type_sp);
388ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham            else
389ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham            {
390ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                type_sp = LookupInCompleteClassCache (class_name);
391ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                if (type_sp)
392ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham                {
393ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    objc_class_sp->SetType (type_sp);
394ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    class_type_or_name.SetTypeSP (type_sp);
395ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham                }
396ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham            }
397ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham        }
398ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton    }
3991a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    return class_type_or_name.IsEmpty() == false;
400b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham}
401b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham
402642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//------------------------------------------------------------------
403642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// Static Functions
404642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//------------------------------------------------------------------
4056e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonLanguageRuntime *
406249f4c468f1aae726d5a30db12243e590e7ec010Greg ClaytonAppleObjCRuntimeV2::CreateInstance (Process *process, LanguageType language)
407642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{
408642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham    // FIXME: This should be a MacOS or iOS process, and we need to look for the OBJC section to make
409642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham    // sure we aren't using the V1 runtime.
410642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham    if (language == eLanguageTypeObjC)
4112eac2b9b61bfbe6079bab86e879263d63046ac0aJim Ingham    {
412f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan        ModuleSP objc_module_sp;
413f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan
414b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton        if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == eAppleObjC_V2)
415f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan            return new AppleObjCRuntimeV2 (process, objc_module_sp);
4162eac2b9b61bfbe6079bab86e879263d63046ac0aJim Ingham        else
4172eac2b9b61bfbe6079bab86e879263d63046ac0aJim Ingham            return NULL;
4182eac2b9b61bfbe6079bab86e879263d63046ac0aJim Ingham    }
419642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham    else
420642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham        return NULL;
421642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham}
422642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
423642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamvoid
424642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamAppleObjCRuntimeV2::Initialize()
425642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{
4260e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    PluginManager::RegisterPlugin (GetPluginNameStatic(),
4270e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton                                   "Apple Objective C Language Runtime - Version 2",
428642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham                                   CreateInstance);
429642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham}
430642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
431642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamvoid
432642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamAppleObjCRuntimeV2::Terminate()
433642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{
434642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham    PluginManager::UnregisterPlugin (CreateInstance);
435642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham}
436642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
4370e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString
4380e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonAppleObjCRuntimeV2::GetPluginNameStatic()
4390e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton{
4400e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    static ConstString g_name("apple-objc-v2");
4410e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return g_name;
4420e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton}
4430e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton
4440e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton
445642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//------------------------------------------------------------------
446642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// PluginInterface protocol
447642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//------------------------------------------------------------------
4480e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString
449642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamAppleObjCRuntimeV2::GetPluginName()
450642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{
4510e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return GetPluginNameStatic();
452642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham}
453642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
454642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamuint32_t
455642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamAppleObjCRuntimeV2::GetPluginVersion()
456642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{
457642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham    return 1;
458642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham}
459642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
4603df164e694d4e03905f8725c46b68b8dcc104debJim InghamBreakpointResolverSP
4613df164e694d4e03905f8725c46b68b8dcc104debJim InghamAppleObjCRuntimeV2::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
46229756d452be39535ded2cff50d9db4df46fe6400Sean Callanan{
4633df164e694d4e03905f8725c46b68b8dcc104debJim Ingham    BreakpointResolverSP resolver_sp;
464c105362e1fd33664939811569dc4a540959e7db7Jim Ingham
4654722b10307668368bf0f12fa6b8691e4f4cb5488Jim Ingham    if (throw_bp)
4663df164e694d4e03905f8725c46b68b8dcc104debJim Ingham        resolver_sp.reset (new BreakpointResolverName (bkpt,
4673df164e694d4e03905f8725c46b68b8dcc104debJim Ingham                                                       "objc_exception_throw",
4683df164e694d4e03905f8725c46b68b8dcc104debJim Ingham                                                       eFunctionNameTypeBase,
4693df164e694d4e03905f8725c46b68b8dcc104debJim Ingham                                                       Breakpoint::Exact,
4703df164e694d4e03905f8725c46b68b8dcc104debJim Ingham                                                       eLazyBoolNo));
4714722b10307668368bf0f12fa6b8691e4f4cb5488Jim Ingham    // FIXME: We don't do catch breakpoints for ObjC yet.
4724722b10307668368bf0f12fa6b8691e4f4cb5488Jim Ingham    // Should there be some way for the runtime to specify what it can do in this regard?
4733df164e694d4e03905f8725c46b68b8dcc104debJim Ingham    return resolver_sp;
47429756d452be39535ded2cff50d9db4df46fe6400Sean Callanan}
47529756d452be39535ded2cff50d9db4df46fe6400Sean Callanan
4762eac2b9b61bfbe6079bab86e879263d63046ac0aJim InghamClangUtilityFunction *
4772eac2b9b61bfbe6079bab86e879263d63046ac0aJim InghamAppleObjCRuntimeV2::CreateObjectChecker(const char *name)
47829756d452be39535ded2cff50d9db4df46fe6400Sean Callanan{
479ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham    char check_function_code[2048];
480f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan
4810d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton    int len = 0;
482f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan    if (m_has_object_getClass)
483f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan    {
4840d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton        len = ::snprintf (check_function_code,
4850d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton                          sizeof(check_function_code),
486ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "extern \"C\" void *gdb_object_getClass(void *);                                          \n"
487ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "extern \"C\"  int printf(const char *format, ...);                                       \n"
488ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "extern \"C\" void                                                                        \n"
489ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector)                                    \n"
490ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "{                                                                                        \n"
491ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   if ($__lldb_arg_obj == (void *)0)                                                     \n"
492ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "       return; // nil is ok                                                              \n"
493ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   if (!gdb_object_getClass($__lldb_arg_obj))                                            \n"
494ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "       *((volatile int *)0) = 'ocgc';                                                    \n"
495ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   else if ($__lldb_arg_selector != (void *)0)                                           \n"
496ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   {                                                                                     \n"
497ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "        signed char responds = (signed char) [(id) $__lldb_arg_obj                       \n"
498ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "                                                respondsToSelector:                      \n"
499ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "                                       (struct objc_selector *) $__lldb_arg_selector];   \n"
500ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "       if (responds == (signed char) 0)                                                  \n"
501ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "           *((volatile int *)0) = 'ocgc';                                                \n"
502ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   }                                                                                     \n"
503ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "}                                                                                        \n",
5040d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton                          name);
505f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan    }
506f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan    else
507f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan    {
5080d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton        len = ::snprintf (check_function_code,
5090d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton                          sizeof(check_function_code),
510ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "extern \"C\" void *gdb_class_getClass(void *);                                           \n"
511ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "extern \"C\"  int printf(const char *format, ...);                                       \n"
512ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "extern \"C\"  void                                                                       \n"
513ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector)                                    \n"
514ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "{                                                                                        \n"
515ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   if ($__lldb_arg_obj == (void *)0)                                                     \n"
516ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "       return; // nil is ok                                                              \n"
517ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "    void **$isa_ptr = (void **)$__lldb_arg_obj;                                          \n"
518ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "    if (*$isa_ptr == (void *)0 || !gdb_class_getClass(*$isa_ptr))                        \n"
519ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "       *((volatile int *)0) = 'ocgc';                                                    \n"
520ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   else if ($__lldb_arg_selector != (void *)0)                                           \n"
521ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   {                                                                                     \n"
522ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "        signed char responds = (signed char) [(id) $__lldb_arg_obj                       \n"
523ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "                                                respondsToSelector:                      \n"
524ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "                                        (struct objc_selector *) $__lldb_arg_selector];  \n"
525ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "       if (responds == (signed char) 0)                                                  \n"
526ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "           *((volatile int *)0) = 'ocgc';                                                \n"
527ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "   }                                                                                     \n"
528ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham                          "}                                                                                        \n",
5290d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton                          name);
530f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan    }
53129756d452be39535ded2cff50d9db4df46fe6400Sean Callanan
5323e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs    assert (len < (int)sizeof(check_function_code));
5330d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton
5340d62dfd4974eb23f550f992e594894b96c5696d1Greg Clayton    return new ClangUtilityFunction(check_function_code, name);
53529756d452be39535ded2cff50d9db4df46fe6400Sean Callanan}
53658513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
53758513667f6765aa8db13cdc4abd500340c1cac80Jim Inghamsize_t
53858513667f6765aa8db13cdc4abd500340c1cac80Jim InghamAppleObjCRuntimeV2::GetByteOffsetForIvar (ClangASTType &parent_ast_type, const char *ivar_name)
53958513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham{
540b302b2f50e079b11a12ebafc29104c198f4f15e4Greg Clayton    const char *class_name = parent_ast_type.GetConstTypeName().AsCString();
54158513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
54258513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    if (!class_name || *class_name == '\0' || !ivar_name || *ivar_name == '\0')
54358513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham        return LLDB_INVALID_IVAR_OFFSET;
54458513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
54558513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    std::string buffer("OBJC_IVAR_$_");
54658513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    buffer.append (class_name);
54758513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    buffer.push_back ('.');
54858513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    buffer.append (ivar_name);
54958513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    ConstString ivar_const_str (buffer.c_str());
55058513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
55158513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    SymbolContextList sc_list;
552249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton    Target &target = m_process->GetTarget();
55358513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
554a1dfecfa891e0d08373776f555b3c992467a21afSean Callanan    target.GetImages().FindSymbolsWithNameAndType(ivar_const_str, eSymbolTypeObjCIVar, sc_list);
55558513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
55658513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    SymbolContext ivar_offset_symbol;
55758513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    if (sc_list.GetSize() != 1
55858513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham        || !sc_list.GetContextAtIndex(0, ivar_offset_symbol)
55958513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham        || ivar_offset_symbol.symbol == NULL)
56058513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham        return LLDB_INVALID_IVAR_OFFSET;
56158513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
5620c31d3d3a4a1d00d53346d8a23b0519f47e55d1fGreg Clayton    addr_t ivar_offset_address = ivar_offset_symbol.symbol->GetAddress().GetLoadAddress (&target);
56358513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
56458513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    Error error;
56558513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
56658513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    uint32_t ivar_offset = m_process->ReadUnsignedIntegerFromMemory (ivar_offset_address,
56758513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham                                                                     4,
56858513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham                                                                     LLDB_INVALID_IVAR_OFFSET,
56958513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham                                                                     error);
57058513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    return ivar_offset;
57158513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham}
57258513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
573d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
574d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata// tagged pointers are special not-a-real-pointer values that contain both type and value information
575d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata// this routine attempts to check with as little computational effort as possible whether something
576d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata// could possibly be a tagged pointer - false positives are possible but false negatives shouldn't
5770c3d6d6eb941a60b44fbf49e879601d4e5ccebbaEnrico Granatabool
578249f4c468f1aae726d5a30db12243e590e7ec010Greg ClaytonAppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr)
5790c3d6d6eb941a60b44fbf49e879601d4e5ccebbaEnrico Granata{
580d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (!m_tagged_pointer_vendor_ap)
581d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return false;
582d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return m_tagged_pointer_vendor_ap->IsPossibleTaggedPointer(ptr);
5830c3d6d6eb941a60b44fbf49e879601d4e5ccebbaEnrico Granata}
5840c3d6d6eb941a60b44fbf49e879601d4e5ccebbaEnrico Granata
5856fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callananclass RemoteNXMapTable
5866fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan{
5876fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callananpublic:
58890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
58990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    RemoteNXMapTable () :
59090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_count (0),
59190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_num_buckets_minus_one (0),
59290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_buckets_ptr (LLDB_INVALID_ADDRESS),
59390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_process (NULL),
59490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_end_iterator (*this, -1),
59590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_load_addr (LLDB_INVALID_ADDRESS),
59690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_map_pair_size (0),
59790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_invalid_key (0)
5986fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    {
59990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
60090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
601ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    void
602ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Dump ()
603ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
604fe21d4f351f560921e615a6677afe1c057aa7f28Matt Kopec        printf ("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
605ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        printf ("RemoteNXMapTable.m_count = %u\n", m_count);
606ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        printf ("RemoteNXMapTable.m_num_buckets_minus_one = %u\n", m_num_buckets_minus_one);
607fe21d4f351f560921e615a6677afe1c057aa7f28Matt Kopec        printf ("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
608ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
609ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
61090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    bool
61190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    ParseHeader (Process* process, lldb::addr_t load_addr)
61290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
61390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_process = process;
61490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_load_addr = load_addr;
61590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_map_pair_size = m_process->GetAddressByteSize() * 2;
61690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_invalid_key = m_process->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX;
6176fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        Error err;
6186fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
61990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        // This currently holds true for all platforms we support, but we might
62090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        // need to change this to use get the actualy byte size of "unsigned"
62190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        // from the target AST...
62290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        const uint32_t unsigned_byte_size = sizeof(uint32_t);
62390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        // Skip the prototype as we don't need it (const struct +NXMapTablePrototype *prototype)
6246fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
62590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        bool success = true;
62690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (load_addr == LLDB_INVALID_ADDRESS)
62790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            success = false;
62890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        else
62990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        {
63090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
63190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
63290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            // unsigned count;
63390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            m_count = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
63490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (m_count)
63590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            {
63690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                cursor += unsigned_byte_size;
63790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
63890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                // unsigned nbBucketsMinusOne;
63990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
64090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                cursor += unsigned_byte_size;
64190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
64290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                // void *buckets;
64390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
64490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
64590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
64690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            }
64790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        }
6486fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
64990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (!success)
65090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        {
65190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            m_count = 0;
65290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            m_num_buckets_minus_one = 0;
65390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            m_buckets_ptr = LLDB_INVALID_ADDRESS;
65490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        }
65590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        return success;
6566fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    }
6576fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6586fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    // const_iterator mimics NXMapState and its code comes from NXInitMapState and NXNextMapState.
6596fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA> element;
6606fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6616fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    friend class const_iterator;
6626fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    class const_iterator
6636fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    {
6646fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    public:
6656fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        const_iterator (RemoteNXMapTable &parent, int index) : m_parent(parent), m_index(index)
6666fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
6676fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            AdvanceToValidIndex();
6686fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
6696fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6706fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        const_iterator (const const_iterator &rhs) : m_parent(rhs.m_parent), m_index(rhs.m_index)
6716fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
6726fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            // AdvanceToValidIndex() has been called by rhs already.
6736fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
6746fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6756fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        const_iterator &operator=(const const_iterator &rhs)
6766fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
6776fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            // AdvanceToValidIndex() has been called by rhs already.
6786fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            assert (&m_parent == &rhs.m_parent);
6796fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            m_index = rhs.m_index;
6806fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            return *this;
6816fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
6826fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6836fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        bool operator==(const const_iterator &rhs) const
6846fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
6856fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            if (&m_parent != &rhs.m_parent)
6866fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                return false;
6876fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            if (m_index != rhs.m_index)
6886fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                return false;
6896fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6906fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            return true;
6916fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
6926fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6936fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        bool operator!=(const const_iterator &rhs) const
6946fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
6956fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            return !(operator==(rhs));
6966fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
6976fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
6986fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        const_iterator &operator++()
6996fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
7006fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            AdvanceToValidIndex();
7016fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            return *this;
7026fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
7036fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
7046fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        const element operator*() const
7056fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
7066fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            if (m_index == -1)
7076fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            {
7086fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                // TODO find a way to make this an error, but not an assert
7096fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                return element();
7106fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            }
7116fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
71290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
71390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            size_t map_pair_size = m_parent.m_map_pair_size;
71490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
7156fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
71690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            Error err;
7176fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
71890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
7196fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            if (!err.Success())
7206fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                return element();
72190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
7226fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            if (!err.Success())
7236fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                return element();
7246fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
7256fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            std::string key_string;
7266fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
72790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
7286fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            if (!err.Success())
7296fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                return element();
7306fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
7316fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            return element(ConstString(key_string.c_str()), (ObjCLanguageRuntime::ObjCISA)value);
7326fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
7336fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    private:
7346fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        void AdvanceToValidIndex ()
7356fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
7366fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            if (m_index == -1)
7376fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                return;
7386fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
73990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
74090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            const size_t map_pair_size = m_parent.m_map_pair_size;
74190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            const lldb::addr_t invalid_key = m_parent.m_invalid_key;
74290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            Error err;
7436fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
7446fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            while (m_index--)
7456fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            {
746be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton                lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
74790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
7486fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
7496fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                if (!err.Success())
7506fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                {
7516fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                    m_index = -1;
7526fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                    return;
7536fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                }
7546fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
75590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                if (key != invalid_key)
7566fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan                    return;
7576fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan            }
7586fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        }
7596fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        RemoteNXMapTable   &m_parent;
7606fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        int                 m_index;
7616fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    };
7626fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
7636fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    const_iterator begin ()
7646fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    {
76590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        return const_iterator(*this, m_num_buckets_minus_one + 1);
7666fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    }
7676fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
7686fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    const_iterator end ()
7696fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    {
7706fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        return m_end_iterator;
7716fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    }
7726fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
77390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    uint32_t
77490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    GetCount () const
77590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
77690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        return m_count;
77790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
77890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
77990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    uint32_t
78090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    GetBucketCount () const
78190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
78290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        return m_num_buckets_minus_one;
78390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
78490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
78590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    lldb::addr_t
78690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    GetBucketDataPointer () const
78790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
78890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        return m_buckets_ptr;
78990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
790ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
791ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    lldb::addr_t
792ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    GetTableLoadAddress() const
793ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
794ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return m_load_addr;
795ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
79690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
7976fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callananprivate:
7986fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    // contents of _NXMapTable struct
79990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    uint32_t m_count;
80090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    uint32_t m_num_buckets_minus_one;
80190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    lldb::addr_t m_buckets_ptr;
80290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    lldb_private::Process *m_process;
80390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    const_iterator m_end_iterator;
80490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    lldb::addr_t m_load_addr;
80590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    size_t m_map_pair_size;
80690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    lldb::addr_t m_invalid_key;
8076fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan};
8086fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
80990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
81090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
81190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg ClaytonAppleObjCRuntimeV2::HashTableSignature::HashTableSignature() :
81290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_count (0),
81390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_num_buckets (0),
81490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_buckets_ptr (0)
81590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton{
81690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton}
81790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
81890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Claytonvoid
81990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg ClaytonAppleObjCRuntimeV2::HashTableSignature::UpdateSignature (const RemoteNXMapTable &hash_table)
82090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton{
82190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_count = hash_table.GetCount();
82290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_num_buckets = hash_table.GetBucketCount();
82390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    m_buckets_ptr = hash_table.GetBucketDataPointer();
82490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton}
82590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
82690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Claytonbool
82790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg ClaytonAppleObjCRuntimeV2::HashTableSignature::NeedsUpdate (Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
82890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton{
82990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    if (!hash_table.ParseHeader(process, runtime->GetISAHashTablePointer ()))
83090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
83190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        return false; // Failed to parse the header, no need to update anything
83290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
83390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
83490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    // Check with out current signature and return true if the count,
83590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    // number of buckets or the hash table address changes.
83690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    if (m_count == hash_table.GetCount() &&
83790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_num_buckets == hash_table.GetBucketCount() &&
83890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        m_buckets_ptr == hash_table.GetBucketDataPointer())
83990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
84090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        // Hash table hasn't changed
84190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        return false;
84290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
84390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    // Hash table data has changed, we need to update
84490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    return true;
84590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton}
84690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
8472e045fc8de471b2338909d5f4a8e934deb067fa0Greg Claytonclass ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
8486fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan{
8496fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callananpublic:
8502e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    friend class lldb_private::AppleObjCRuntimeV2;
8512e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
8522e045fc8de471b2338909d5f4a8e934deb067fa0Greg Claytonprivate:
8532e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    // The constructor should only be invoked by the runtime as it builds its caches
8542e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    // or populates them.  A ClassDescriptorV2 should only ever exist in a cache.
8552e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    ClassDescriptorV2 (AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa, const char *name) :
8562e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        m_runtime (runtime),
8572e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        m_objc_class_ptr (isa),
8582e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        m_name (name)
8592e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    {
8602e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    }
8612e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
8622e045fc8de471b2338909d5f4a8e934deb067fa0Greg Claytonpublic:
8632e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    virtual ConstString
8642e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    GetClassName ()
8656fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    {
8662e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        if (!m_name)
8676fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan        {
8682e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            lldb_private::Process *process = m_runtime.GetProcess();
86965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
87090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (process)
871be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            {
872102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton                std::unique_ptr<objc_class_t> objc_class;
873102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton                std::unique_ptr<class_ro_t> class_ro;
874102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton                std::unique_ptr<class_rw_t> class_rw;
875be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
87690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                if (!Read_objc_class(process, objc_class))
87765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                    return m_name;
87890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                if (!Read_class_row(process, *objc_class, class_ro, class_rw))
87965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                    return m_name;
880be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
88165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                m_name = ConstString(class_ro->m_name.c_str());
882be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            }
883be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        }
884a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return m_name;
885a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
886a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
887a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual ObjCLanguageRuntime::ClassDescriptorSP
888a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetSuperclass ()
889a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
89090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        lldb_private::Process *process = m_runtime.GetProcess();
89165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
89290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (!process)
893a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan            return ObjCLanguageRuntime::ClassDescriptorSP();
894c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
895102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<objc_class_t> objc_class;
89665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
89790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (!Read_objc_class(process, objc_class))
89865529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            return ObjCLanguageRuntime::ClassDescriptorSP();
89965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
900d387b462eecb908af265ecc7006781b4532073adGreg Clayton        return m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(objc_class->m_superclass);
901a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
902a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
903a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual bool
904a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    IsValid ()
905a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
90665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        return true;    // any Objective-C v2 runtime class descriptor we vend is valid
907a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
908a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
90912fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata    // a custom descriptor is used for tagged pointers
910a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual bool
91112fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata    GetTaggedPointerInfo (uint64_t* info_bits = NULL,
912d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                          uint64_t* value_bits = NULL,
913d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                          uint64_t* payload = NULL)
914a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
91512fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata        return false;
916a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
917a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
918a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual uint64_t
919a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetInstanceSize ()
920a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
92190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        lldb_private::Process *process = m_runtime.GetProcess();
922c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
92390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (process)
924be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        {
925102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<objc_class_t> objc_class;
926102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<class_ro_t> class_ro;
927102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<class_rw_t> class_rw;
928be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
92990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (!Read_objc_class(process, objc_class))
93065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                return 0;
93190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (!Read_class_row(process, *objc_class, class_ro, class_rw))
93265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                return 0;
933be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
93465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            return class_ro->m_instanceSize;
935be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        }
93665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
93765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        return 0;
938a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
939a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
940a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual ObjCLanguageRuntime::ObjCISA
941a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetISA ()
94265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    {
943be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        return m_objc_class_ptr;
944a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
945a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
9464d0fa042181391e4fde953ebb5600d93022b3331Enrico Granata    virtual bool
947d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan    Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
948d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan              std::function <bool (const char *, const char *)> const &instance_method_func,
949d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan              std::function <bool (const char *, const char *)> const &class_method_func,
950d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan              std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
95181a5a09e76cfc1f110c0416e372f9f6cc27d79cfSean Callanan    {
95290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        lldb_private::Process *process = m_runtime.GetProcess();
95365529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
954102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<objc_class_t> objc_class;
955102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<class_ro_t> class_ro;
956102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<class_rw_t> class_rw;
957d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
95890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (!Read_objc_class(process, objc_class))
95965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            return 0;
96090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (!Read_class_row(process, *objc_class, class_ro, class_rw))
96165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            return 0;
962d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
963d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan        static ConstString NSObject_name("NSObject");
964d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
965d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan        if (m_name != NSObject_name && superclass_func)
96665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            superclass_func(objc_class->m_superclass);
967d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
968d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan        if (instance_method_func)
969d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        {
970102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<method_list_t> base_method_list;
971d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
972d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan            base_method_list.reset(new method_list_t);
97390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
974d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan                return false;
975d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
97690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (base_method_list->m_entsize != method_t::GetSize(process))
977d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan                return false;
978d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
979102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton            std::unique_ptr<method_t> method;
980d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan            method.reset(new method_t);
981d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
982d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan            for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
983d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan            {
98490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                method->Read(process, base_method_list->m_first_ptr + (i * base_method_list->m_entsize));
985d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
986d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
987d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                    break;
988d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan            }
989d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        }
990d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
991d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan        if (class_method_func)
992d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan        {
993c07d1993157ac8251084e11b9df23b6169e99ac3Sean Callanan            ClassDescriptorV2 metaclass(m_runtime, objc_class->m_isa, NULL); // The metaclass is not in the cache
994d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
995d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan            // We don't care about the metaclass's superclass, or its class methods.  Its instance methods are
996d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan            // our class methods.
997d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
998bc92c019bdd23c468d19f6ac486e00564b32ef6aSean Callanan            metaclass.Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> (nullptr),
999bc92c019bdd23c468d19f6ac486e00564b32ef6aSean Callanan                               class_method_func,
1000d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                               std::function <bool (const char *, const char *)> (nullptr),
1001d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                               std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> (nullptr));
1002d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        }
1003d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1004d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        if (ivar_func)
1005d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        {
100681a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton            ivar_list_t ivar_list;
100781a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton            if (!ivar_list.Read(process, class_ro->m_ivars_ptr))
1008d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                return false;
1009d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
101081a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton            if (ivar_list.m_entsize != ivar_t::GetSize(process))
1011d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                return false;
1012d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
101381a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton            ivar_t ivar;
1014d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
101581a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton            for (uint32_t i = 0, e = ivar_list.m_count; i < e; ++i)
1016d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            {
101781a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton                ivar.Read(process, ivar_list.m_first_ptr + (i * ivar_list.m_entsize));
1018d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
101981a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton                if (ivar_func(ivar.m_name.c_str(), ivar.m_type.c_str(), ivar.m_offset_ptr, ivar.m_size))
1020d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                    break;
1021d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            }
1022d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan        }
1023d123b989d453c70244b04d4c9ef7792214e9010aSean Callanan
1024d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        return true;
102581a5a09e76cfc1f110c0416e372f9f6cc27d79cfSean Callanan    }
102681a5a09e76cfc1f110c0416e372f9f6cc27d79cfSean Callanan
1027a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual
1028a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    ~ClassDescriptorV2 ()
1029c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    {
1030c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    }
1031d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1032a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callananprivate:
10334d0fa042181391e4fde953ebb5600d93022b3331Enrico Granata    static const uint32_t RW_REALIZED = (1 << 31);
1034c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1035c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    struct objc_class_t {
1036c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        ObjCLanguageRuntime::ObjCISA    m_isa;              // The class's metaclass.
1037c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        ObjCLanguageRuntime::ObjCISA    m_superclass;
1038be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_cache_ptr;
1039be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_vtable_ptr;
1040be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_data_ptr;
1041c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        uint8_t                         m_flags;
1042d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1043be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        objc_class_t () :
1044be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_isa (0),
1045be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_superclass (0),
1046be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_cache_ptr (0),
1047be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_vtable_ptr (0),
1048be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_data_ptr (0),
1049be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_flags (0)
1050be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        {
1051be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        }
1052be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
1053be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        void
1054be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        Clear()
1055be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        {
1056be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_isa = 0;
1057be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_superclass = 0;
1058be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_cache_ptr = 0;
1059be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_vtable_ptr = 0;
1060be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_data_ptr = 0;
1061be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_flags = 0;
1062be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        }
1063be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
106490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        bool Read(Process *process, lldb::addr_t addr)
1065d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        {
106690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            size_t ptr_size = process->GetAddressByteSize();
1067d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1068d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            size_t objc_class_size = ptr_size   // uintptr_t isa;
1069be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size   // Class superclass;
1070be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size   // void *cache;
1071be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size   // IMP *vtable;
1072be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size;  // uintptr_t data_NEVER_USE;
1073d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1074d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            DataBufferHeap objc_class_buf (objc_class_size, '\0');
1075d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            Error error;
1076d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
107790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            process->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size, error);
1078d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            if (error.Fail())
1079d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            {
1080d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan                return false;
1081d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            }
1082d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
108390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size, process->GetByteOrder(), process->GetAddressByteSize());
1084d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
108536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t cursor = 0;
1086d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1087be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_isa           = extractor.GetAddress_unchecked(&cursor);   // uintptr_t isa;
1088be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_superclass    = extractor.GetAddress_unchecked(&cursor);   // Class superclass;
1089be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_cache_ptr     = extractor.GetAddress_unchecked(&cursor);   // void *cache;
1090be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_vtable_ptr    = extractor.GetAddress_unchecked(&cursor);   // IMP *vtable;
1091d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            lldb::addr_t data_NEVER_USE = extractor.GetAddress_unchecked(&cursor);   // uintptr_t data_NEVER_USE;
1092d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1093be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_flags         = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3);
1094be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_data_ptr      = data_NEVER_USE & ~(lldb::addr_t)3;
1095d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1096d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            return true;
1097d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        }
1098c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    };
1099c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1100c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    struct class_ro_t {
1101c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        uint32_t                        m_flags;
1102c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        uint32_t                        m_instanceStart;
1103c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        uint32_t                        m_instanceSize;
1104c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        uint32_t                        m_reserved;
1105c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1106be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_ivarLayout_ptr;
1107be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_name_ptr;
1108be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_baseMethods_ptr;
1109be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_baseProtocols_ptr;
1110be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_ivars_ptr;
1111c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1112be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_weakIvarLayout_ptr;
1113be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_baseProperties_ptr;
1114d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
111565529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        std::string                     m_name;
111665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
111790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        bool Read(Process *process, lldb::addr_t addr)
1118d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        {
111990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            size_t ptr_size = process->GetAddressByteSize();
1120d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1121be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            size_t size = sizeof(uint32_t)             // uint32_t flags;
1122be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + sizeof(uint32_t)                         // uint32_t instanceStart;
1123be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + sizeof(uint32_t)                         // uint32_t instanceSize;
1124be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + (ptr_size == 8 ? sizeof(uint32_t) : 0)   // uint32_t reserved; // __LP64__ only
1125be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size                                 // const uint8_t *ivarLayout;
1126be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size                                 // const char *name;
1127be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size                                 // const method_list_t *baseMethods;
1128be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size                                 // const protocol_list_t *baseProtocols;
1129be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size                                 // const ivar_list_t *ivars;
1130be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size                                 // const uint8_t *weakIvarLayout;
1131be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size;                                // const property_list_t *baseProperties;
1132d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1133d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            DataBufferHeap buffer (size, '\0');
1134d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            Error error;
1135d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
113690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            process->ReadMemory(addr, buffer.GetBytes(), size, error);
1137d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            if (error.Fail())
1138d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            {
1139d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan                return false;
1140d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            }
1141d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
114290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
1143d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
114436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t cursor = 0;
1145d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1146d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_flags             = extractor.GetU32_unchecked(&cursor);
1147d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_instanceStart     = extractor.GetU32_unchecked(&cursor);
1148d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_instanceSize      = extractor.GetU32_unchecked(&cursor);
1149d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            if (ptr_size == 8)
1150d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan                m_reserved      = extractor.GetU32_unchecked(&cursor);
1151d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            else
1152d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan                m_reserved      = 0;
1153be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_ivarLayout_ptr     = extractor.GetAddress_unchecked(&cursor);
1154be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_name_ptr           = extractor.GetAddress_unchecked(&cursor);
1155be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_baseMethods_ptr    = extractor.GetAddress_unchecked(&cursor);
1156be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_baseProtocols_ptr  = extractor.GetAddress_unchecked(&cursor);
1157be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_ivars_ptr          = extractor.GetAddress_unchecked(&cursor);
1158be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_weakIvarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
1159be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_baseProperties_ptr = extractor.GetAddress_unchecked(&cursor);
1160d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
116165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            DataBufferHeap name_buf(1024, '\0');
116265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
116390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            process->ReadCStringFromMemory(m_name_ptr, (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
116465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
116565529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            if (error.Fail())
116665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            {
116765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                return false;
116865529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            }
116965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
117065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            m_name.assign((char*)name_buf.GetBytes());
117165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
1172d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            return true;
1173d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        }
1174c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    };
1175c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1176c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    struct class_rw_t {
1177c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        uint32_t                        m_flags;
1178c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        uint32_t                        m_version;
1179c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1180be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_ro_ptr;
1181c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        union {
1182be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            lldb::addr_t                m_method_list_ptr;
1183be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            lldb::addr_t                m_method_lists_ptr;
1184c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        };
1185be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_properties_ptr;
1186be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t                    m_protocols_ptr;
1187c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1188c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        ObjCLanguageRuntime::ObjCISA    m_firstSubclass;
1189c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan        ObjCLanguageRuntime::ObjCISA    m_nextSiblingClass;
1190d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
119190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        bool Read(Process *process, lldb::addr_t addr)
1192d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        {
119390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            size_t ptr_size = process->GetAddressByteSize();
1194d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1195d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            size_t size = sizeof(uint32_t)  // uint32_t flags;
1196be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + sizeof(uint32_t)  // uint32_t version;
1197be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size          // const class_ro_t *ro;
1198be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size          // union { method_list_t **method_lists; method_list_t *method_list; };
1199be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size          // struct chained_property_list *properties;
1200be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size          // const protocol_list_t **protocols;
1201be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size          // Class firstSubclass;
1202be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size;         // Class nextSiblingClass;
1203d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1204d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            DataBufferHeap buffer (size, '\0');
1205d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            Error error;
1206d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
120790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            process->ReadMemory(addr, buffer.GetBytes(), size, error);
1208d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            if (error.Fail())
1209d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            {
1210d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan                return false;
1211d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            }
1212d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
121390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
1214d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
121536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t cursor = 0;
1216d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1217d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_flags             = extractor.GetU32_unchecked(&cursor);
1218d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_version           = extractor.GetU32_unchecked(&cursor);
121936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            m_ro_ptr            = extractor.GetAddress_unchecked(&cursor);
122036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            m_method_list_ptr   = extractor.GetAddress_unchecked(&cursor);
122136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            m_properties_ptr    = extractor.GetAddress_unchecked(&cursor);
1222d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_firstSubclass     = extractor.GetAddress_unchecked(&cursor);
1223d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_nextSiblingClass  = extractor.GetAddress_unchecked(&cursor);
1224d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1225d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            return true;
1226d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        }
1227c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan    };
1228c3b0aa959395671385aa1f4c8201d8a484079f1dSean Callanan
1229d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan    struct method_list_t
1230d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan    {
1231d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        uint32_t        m_entsize;
1232d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        uint32_t        m_count;
1233be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t    m_first_ptr;
1234d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
123590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        bool Read(Process *process, lldb::addr_t addr)
1236be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        {
1237d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            size_t size = sizeof(uint32_t)  // uint32_t entsize_NEVER_USE;
1238be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + sizeof(uint32_t); // uint32_t count;
1239d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1240d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            DataBufferHeap buffer (size, '\0');
1241d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            Error error;
1242d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
124390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            process->ReadMemory(addr, buffer.GetBytes(), size, error);
1244d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            if (error.Fail())
1245d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            {
1246d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan                return false;
1247d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            }
1248d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
124990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
1250d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
125136da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t cursor = 0;
1252d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1253d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_entsize   = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
1254d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_count     = extractor.GetU32_unchecked(&cursor);
1255be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_first_ptr  = addr + cursor;
1256d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1257d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            return true;
1258d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        }
1259d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan    };
1260d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1261d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan    struct method_t
1262d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan    {
1263be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t    m_name_ptr;
1264be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t    m_types_ptr;
1265be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        lldb::addr_t    m_imp_ptr;
1266d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1267d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        std::string     m_name;
1268d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        std::string     m_types;
1269d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
127090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        static size_t GetSize(Process *process)
12712a5ca48974884c1344e3eff4a60ae63e05fa8ea7Sean Callanan        {
127290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            size_t ptr_size = process->GetAddressByteSize();
1273be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
12742a5ca48974884c1344e3eff4a60ae63e05fa8ea7Sean Callanan            return ptr_size     // SEL name;
1275be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size   // const char *types;
1276be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            + ptr_size;  // IMP imp;
12772a5ca48974884c1344e3eff4a60ae63e05fa8ea7Sean Callanan        }
12782a5ca48974884c1344e3eff4a60ae63e05fa8ea7Sean Callanan
127990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        bool Read(Process *process, lldb::addr_t addr)
1280d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        {
128190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            size_t size = GetSize(process);
1282d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1283d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            DataBufferHeap buffer (size, '\0');
1284d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            Error error;
1285d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
128690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            process->ReadMemory(addr, buffer.GetBytes(), size, error);
1287d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            if (error.Fail())
1288d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            {
1289d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan                return false;
1290d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            }
1291d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
129290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
1293d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
129436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t cursor = 0;
1295d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1296be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_name_ptr   = extractor.GetAddress_unchecked(&cursor);
1297be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_types_ptr  = extractor.GetAddress_unchecked(&cursor);
1298be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            m_imp_ptr    = extractor.GetAddress_unchecked(&cursor);
1299d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1300d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            const size_t buffer_size = 1024;
1301d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            size_t count;
1302d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1303d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            DataBufferHeap string_buf(buffer_size, 0);
1304d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
130590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            count = process->ReadCStringFromMemory(m_name_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
1306d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_name.assign((char*)string_buf.GetBytes(), count);
1307d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
130890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            count = process->ReadCStringFromMemory(m_types_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
1309d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            m_types.assign((char*)string_buf.GetBytes(), count);
1310d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan
1311d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan            return true;
1312d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan        }
1313d83ecab0aeb229504737e34b2f03c07fcb967480Sean Callanan    };
131465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
1315d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    struct ivar_list_t
1316d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    {
1317d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        uint32_t        m_entsize;
1318d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        uint32_t        m_count;
1319d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        lldb::addr_t    m_first_ptr;
1320d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1321d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        bool Read(Process *process, lldb::addr_t addr)
1322d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        {
1323d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            size_t size = sizeof(uint32_t)  // uint32_t entsize;
1324d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                        + sizeof(uint32_t); // uint32_t count;
1325d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1326d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            DataBufferHeap buffer (size, '\0');
1327d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            Error error;
1328d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1329d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            process->ReadMemory(addr, buffer.GetBytes(), size, error);
1330d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            if (error.Fail())
1331d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            {
1332d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                return false;
1333d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            }
1334d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1335d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
1336d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
133736da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t cursor = 0;
1338d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1339d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_entsize   = extractor.GetU32_unchecked(&cursor);
1340d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_count     = extractor.GetU32_unchecked(&cursor);
1341d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_first_ptr = addr + cursor;
1342d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1343d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            return true;
1344d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        }
1345d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    };
1346d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1347d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    struct ivar_t
1348d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    {
1349d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        lldb::addr_t    m_offset_ptr;
1350d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        lldb::addr_t    m_name_ptr;
1351d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        lldb::addr_t    m_type_ptr;
1352d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        uint32_t        m_alignment;
1353d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        uint32_t        m_size;
1354d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1355d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        std::string     m_name;
1356d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        std::string     m_type;
1357d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1358d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        static size_t GetSize(Process *process)
1359d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        {
1360d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            size_t ptr_size = process->GetAddressByteSize();
1361d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1362d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            return ptr_size             // uintptr_t *offset;
1363d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                 + ptr_size             // const char *name;
1364d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                 + ptr_size             // const char *type;
1365d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                 + sizeof(uint32_t)     // uint32_t alignment;
1366d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                 + sizeof(uint32_t);    // uint32_t size;
1367d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        }
1368d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1369d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        bool Read(Process *process, lldb::addr_t addr)
1370d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        {
1371d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            size_t size = GetSize(process);
1372d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1373d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            DataBufferHeap buffer (size, '\0');
1374d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            Error error;
1375d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1376d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            process->ReadMemory(addr, buffer.GetBytes(), size, error);
1377d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            if (error.Fail())
1378d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            {
1379d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                return false;
1380d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            }
1381d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1382d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
1383d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
138436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t cursor = 0;
1385d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1386d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
1387d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_name_ptr   = extractor.GetAddress_unchecked(&cursor);
1388d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_type_ptr   = extractor.GetAddress_unchecked(&cursor);
1389d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_alignment  = extractor.GetU32_unchecked(&cursor);
1390d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_size       = extractor.GetU32_unchecked(&cursor);
1391d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1392d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            const size_t buffer_size = 1024;
1393d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            size_t count;
1394d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1395d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            DataBufferHeap string_buf(buffer_size, 0);
1396d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1397d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            count = process->ReadCStringFromMemory(m_name_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
1398d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_name.assign((char*)string_buf.GetBytes(), count);
1399d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1400d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            count = process->ReadCStringFromMemory(m_type_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
1401d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            m_type.assign((char*)string_buf.GetBytes(), count);
1402d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1403d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            return true;
1404d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        }
1405d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    };
1406d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
1407102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton    bool Read_objc_class (Process* process, std::unique_ptr<objc_class_t> &objc_class)
140865529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    {
140965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        objc_class.reset(new objc_class_t);
141065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
141190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        bool ret = objc_class->Read (process, m_objc_class_ptr);
141265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
141365529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        if (!ret)
141465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            objc_class.reset();
141565529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
141665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        return ret;
141765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    }
141865529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
1419102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton    bool Read_class_row (Process* process, const objc_class_t &objc_class, std::unique_ptr<class_ro_t> &class_ro, std::unique_ptr<class_rw_t> &class_rw)
142065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    {
142165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        class_ro.reset();
142265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        class_rw.reset();
142365529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
142465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        Error error;
142590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        uint32_t class_row_t_flags = process->ReadUnsignedIntegerFromMemory(objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
142665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        if (!error.Success())
142765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            return false;
1428be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
142965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        if (class_row_t_flags & RW_REALIZED)
143065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        {
143165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            class_rw.reset(new class_rw_t);
143265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
143390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (!class_rw->Read(process, objc_class.m_data_ptr))
143465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            {
143565529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                class_rw.reset();
143665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                return false;
143765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            }
143865529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
143965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            class_ro.reset(new class_ro_t);
144065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
144190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (!class_ro->Read(process, class_rw->m_ro_ptr))
144265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            {
144365529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                class_rw.reset();
144465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                class_ro.reset();
144565529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                return false;
144665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            }
144765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        }
144865529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        else
144965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        {
145065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            class_ro.reset(new class_ro_t);
145165529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
145290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (!class_ro->Read(process, objc_class.m_data_ptr))
145365529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            {
145465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                class_ro.reset();
145565529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan                return false;
145665529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan            }
145765529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        }
145865529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan
145965529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan        return true;
146065529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    }
1461be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
146265529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    AppleObjCRuntimeV2 &m_runtime;          // The runtime, so we can read information lazily.
146365529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    lldb::addr_t        m_objc_class_ptr;   // The address of the objc_class_t.  (I.e., objects of this class type have this as their ISA)
146465529e3a02d91c25a779d8bac0c5bcd97c503ebdSean Callanan    ConstString         m_name;             // May be NULL
1465a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan};
1466a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1467d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata// tagged pointer descriptor
1468a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callananclass ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor
1469a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan{
1470a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callananpublic:
1471d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    ClassDescriptorV2Tagged (ConstString class_name,
1472d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                             uint64_t payload)
1473a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1474d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_name = class_name;
1475d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (!m_name)
1476a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        {
1477d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            m_valid = false;
1478a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan            return;
1479a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        }
1480a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        m_valid = true;
1481d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_payload = payload;
1482d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_info_bits = (m_payload & 0xF0ULL) >> 4;
1483d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8;
1484d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
1485d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
1486d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    ClassDescriptorV2Tagged (ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp,
1487d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                             uint64_t payload)
1488d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
1489d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (!actual_class_sp)
1490a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        {
1491a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan            m_valid = false;
1492d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            return;
1493a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        }
1494d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_name = actual_class_sp->GetClassName();
1495d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (!m_name)
1496a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        {
1497d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            m_valid = false;
1498d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            return;
1499a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        }
1500d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_valid = true;
1501d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_payload = payload;
1502d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_info_bits = (m_payload & 0x0FULL);
1503d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_value_bits = (m_payload & ~0x0FULL) >> 4;
1504a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1505a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1506a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual ConstString
1507a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetClassName ()
1508a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1509a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return m_name;
1510a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1511a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1512a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual ObjCLanguageRuntime::ClassDescriptorSP
1513a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetSuperclass ()
1514a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1515a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        // tagged pointers can represent a class that has a superclass, but since that information is not
1516a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        // stored in the object itself, we would have to query the runtime to discover the hierarchy
1517a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        // for the time being, we skip this step in the interest of static discovery
15183dc2a5b732ae161b8ae51d376a8f0060a7d9e2a8Enrico Granata        return ObjCLanguageRuntime::ClassDescriptorSP();
1519a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1520a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1521a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual bool
1522a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    IsValid ()
1523a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1524a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return m_valid;
1525a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1526a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1527a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual bool
1528a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    IsKVO ()
1529a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1530a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return false; // tagged pointers are not KVO'ed
1531a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1532a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1533a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual bool
1534a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    IsCFType ()
1535a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1536a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return false; // tagged pointers are not CF objects
1537a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1538a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1539a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual bool
154012fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata    GetTaggedPointerInfo (uint64_t* info_bits = NULL,
1541d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                          uint64_t* value_bits = NULL,
1542d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                          uint64_t* payload = NULL)
1543a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
154412fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata        if (info_bits)
154512fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata            *info_bits = GetInfoBits();
154612fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata        if (value_bits)
154712fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata            *value_bits = GetValueBits();
1548d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (payload)
1549d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            *payload = GetPayload();
155012fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata        return true;
1551a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1552a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1553a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual uint64_t
1554a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetInstanceSize ()
1555a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1556a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return (IsValid() ? m_pointer_size : 0);
1557a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1558a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1559a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual ObjCLanguageRuntime::ObjCISA
1560a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetISA ()
1561a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1562a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return 0; // tagged pointers have no ISA
1563a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1564a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1565a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    // these calls are not part of any formal tagged pointers specification
1566a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual uint64_t
1567a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetValueBits ()
1568a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1569a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return (IsValid() ? m_value_bits : 0);
1570a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1571a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1572a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    virtual uint64_t
1573a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    GetInfoBits ()
1574a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1575a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan        return (IsValid() ? m_info_bits : 0);
1576a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1577a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1578d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    virtual uint64_t
1579d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    GetPayload ()
1580a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    {
1581d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return (IsValid() ? m_payload : 0);
1582a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    }
1583a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1584d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    virtual
1585d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    ~ClassDescriptorV2Tagged ()
1586d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {}
1587d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
1588a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callananprivate:
1589a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    ConstString m_name;
1590a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    uint8_t m_pointer_size;
1591a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    bool m_valid;
1592a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    uint64_t m_info_bits;
1593a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan    uint64_t m_value_bits;
1594d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    uint64_t m_payload;
1595d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
1596a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan};
1597a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
1598a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean CallananObjCLanguageRuntime::ClassDescriptorSP
1599d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::GetClassDescriptor (ObjCISA isa)
1600d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
1601d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
1602d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (m_non_pointer_isa_cache_ap.get())
1603d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        class_descriptor_sp = m_non_pointer_isa_cache_ap->GetClassDescriptor(isa);
1604d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (!class_descriptor_sp)
1605d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
1606d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return class_descriptor_sp;
1607d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
1608d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
1609d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataObjCLanguageRuntime::ClassDescriptorSP
1610a510437e795477e5f629263d3d191d982c991733Greg ClaytonAppleObjCRuntimeV2::GetClassDescriptor (ValueObject& valobj)
1611a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan{
1612be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    ClassDescriptorSP objc_class_sp;
1613a510437e795477e5f629263d3d191d982c991733Greg Clayton    // if we get an invalid VO (which might still happen when playing around
1614a510437e795477e5f629263d3d191d982c991733Greg Clayton    // with pointers returned by the expression parser, don't consider this
1615a510437e795477e5f629263d3d191d982c991733Greg Clayton    // a valid ObjC object)
161652f792329be5db8e38961350589e97e8f2823acdGreg Clayton    if (valobj.GetClangType().IsValid())
1617be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    {
1618a510437e795477e5f629263d3d191d982c991733Greg Clayton        addr_t isa_pointer = valobj.GetPointerValue();
1619a510437e795477e5f629263d3d191d982c991733Greg Clayton
1620a510437e795477e5f629263d3d191d982c991733Greg Clayton        // tagged pointer
1621a510437e795477e5f629263d3d191d982c991733Greg Clayton        if (IsTaggedPointer(isa_pointer))
1622a510437e795477e5f629263d3d191d982c991733Greg Clayton        {
1623d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            return m_tagged_pointer_vendor_ap->GetClassDescriptor(isa_pointer);
1624a510437e795477e5f629263d3d191d982c991733Greg Clayton        }
1625be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        else
1626a510437e795477e5f629263d3d191d982c991733Greg Clayton        {
1627a510437e795477e5f629263d3d191d982c991733Greg Clayton            ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
1628a510437e795477e5f629263d3d191d982c991733Greg Clayton
1629a510437e795477e5f629263d3d191d982c991733Greg Clayton            Process *process = exe_ctx.GetProcessPtr();
1630a510437e795477e5f629263d3d191d982c991733Greg Clayton            if (process)
1631a510437e795477e5f629263d3d191d982c991733Greg Clayton            {
1632a510437e795477e5f629263d3d191d982c991733Greg Clayton                Error error;
1633a510437e795477e5f629263d3d191d982c991733Greg Clayton                ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
1634a510437e795477e5f629263d3d191d982c991733Greg Clayton                if (isa != LLDB_INVALID_ADDRESS)
1635ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                {
1636d387b462eecb908af265ecc7006781b4532073adGreg Clayton                    objc_class_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA (isa);
1637ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    if (isa && !objc_class_sp)
1638ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    {
1639952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton                        Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1640ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                        if (log)
16415f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                            log->Printf("0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%" PRIx64,
1642ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                        isa_pointer,
1643ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                        isa);
1644ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    }
1645ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                }
1646a510437e795477e5f629263d3d191d982c991733Greg Clayton            }
1647a510437e795477e5f629263d3d191d982c991733Greg Clayton        }
1648be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    }
1649be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    return objc_class_sp;
1650a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan}
1651a0d8a78a18afe2f83480141a71c1f3f182aa2cc5Sean Callanan
165290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Claytonlldb::addr_t
165390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg ClaytonAppleObjCRuntimeV2::GetISAHashTablePointer ()
16546fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan{
165590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
165690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
165790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        Process *process = GetProcess();
16586fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
165990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        ModuleSP objc_module_sp(GetObjCModule());
16604e0557ff031f14b3cde50269844503fda1622420Sean Callanan
16614e0557ff031f14b3cde50269844503fda1622420Sean Callanan        if (!objc_module_sp)
16624e0557ff031f14b3cde50269844503fda1622420Sean Callanan            return LLDB_INVALID_ADDRESS;
16636fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan
166490c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
166590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
166690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_objc_realized_classes, lldb::eSymbolTypeData);
166790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        if (symbol)
166890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        {
166990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
167090c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton
167190c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
167290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            {
167390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton                Error error;
167493e269368c0568c572d5b42a4783532832b3b93cGreg Clayton                m_isa_hash_table_ptr = process->ReadPointerFromMemory(gdb_objc_realized_classes_ptr, error);
167590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton            }
167690c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton        }
167790c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
167890c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    return m_isa_hash_table_ptr;
167990c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton}
1680a510437e795477e5f629263d3d191d982c991733Greg Clayton
1681ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonbool
1682ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonAppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table)
1683ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
1684ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Process *process = GetProcess();
1685ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1686ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (process == NULL)
1687ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
16882e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1689952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1690ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1691ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ExecutionContext exe_ctx;
1692ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1693ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
1694ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1695ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (!thread_sp)
1696ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1697ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1698ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    thread_sp->CalculateExecutionContext(exe_ctx);
1699ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
1700ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1701ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (!ast)
1702ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1703ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1704ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Address function_address;
1705ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1706ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    StreamString errors;
17072e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1708ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const uint32_t addr_size = process->GetAddressByteSize();
17092e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1710ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Error err;
1711ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1712ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Read the total number of classes from the hash table
1713ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const uint32_t num_classes = hash_table.GetCount();
1714ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (num_classes == 0)
1715ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
1716ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (log)
1717ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            log->Printf ("No dynamic classes found in gdb_objc_realized_classes.");
1718ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1719ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
1720ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1721ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Make some types for our arguments
172252f792329be5db8e38961350589e97e8f2823acdGreg Clayton    ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
172352f792329be5db8e38961350589e97e8f2823acdGreg Clayton    ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
1724ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1725ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (!m_get_class_info_code.get())
1726ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
1727ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_get_class_info_code.reset (new ClangUtilityFunction (g_get_dynamic_class_info_body,
1728ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                               g_get_dynamic_class_info_name));
1729ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1730ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
1731ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1732ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (!m_get_class_info_code->Install(errors, exe_ctx))
1733ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
1734ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
1735ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
1736ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            m_get_class_info_code.reset();
1737ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
1738ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
1739ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1740ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (m_get_class_info_code.get())
1741ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        function_address.SetOffset(m_get_class_info_code->StartAddress());
1742ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    else
1743ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
17442e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1745ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ValueList arguments;
1746ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1747ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Next make the runner function for our implementation utility function.
1748ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (!m_get_class_info_function.get())
1749ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
1750ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        Value value;
1751ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        value.SetValueType (Value::eValueTypeScalar);
175252f792329be5db8e38961350589e97e8f2823acdGreg Clayton//        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
175352f792329be5db8e38961350589e97e8f2823acdGreg Clayton        value.SetClangType (clang_void_pointer_type);
1754ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        arguments.PushValue (value);
1755ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        arguments.PushValue (value);
1756ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1757ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        value.SetValueType (Value::eValueTypeScalar);
175852f792329be5db8e38961350589e97e8f2823acdGreg Clayton//        value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
175952f792329be5db8e38961350589e97e8f2823acdGreg Clayton        value.SetClangType (clang_uint32_t_type);
1760ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        arguments.PushValue (value);
17612e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1762ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_get_class_info_function.reset(new ClangFunction (*m_process,
1763ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                           clang_uint32_t_type,
1764ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                           function_address,
1765ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                           arguments));
1766ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1767ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (m_get_class_info_function.get() == NULL)
1768ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            return false;
17692e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1770ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
1771ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1772ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        unsigned num_errors = m_get_class_info_function->CompileFunction(errors);
1773ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (num_errors)
1774ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
1775ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
1776ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf ("Error compiling function: \"%s\".", errors.GetData());
1777ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            return false;
1778ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
1779ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1780ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
1781ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1782ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (!m_get_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
1783ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
1784ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
1785ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
1786ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            return false;
1787ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
1788ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
1789ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    else
1790ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
1791ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        arguments = m_get_class_info_function->GetArgumentValues ();
1792ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
1793ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
17942e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    const uint32_t class_info_byte_size = addr_size + 4;
1795ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
1796ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
17972e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                            ePermissionsReadable | ePermissionsWritable,
17982e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                            err);
1799ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1800ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (class_infos_addr == LLDB_INVALID_ADDRESS)
1801ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
18022e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1803ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Mutex::Locker locker(m_get_class_info_args_mutex);
18042e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1805ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Fill in our function argument values
1806ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
1807ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
1808ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
1809ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1810ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    bool success = false;
1811ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1812ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    errors.Clear();
1813ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1814ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Write our function arguments into the process so we can run our function
1815ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (m_get_class_info_function->WriteFunctionArguments (exe_ctx,
1816ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                           m_get_class_info_args,
1817ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                           function_address,
1818ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                           arguments,
1819ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                           errors))
1820ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
1821ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool stop_others = true;
1822ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool try_all_threads = false;
1823ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool unwind_on_error = true;
1824ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool ignore_breakpoints = true;
1825ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1826ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        Value return_value;
1827ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return_value.SetValueType (Value::eValueTypeScalar);
182852f792329be5db8e38961350589e97e8f2823acdGreg Clayton        //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
182952f792329be5db8e38961350589e97e8f2823acdGreg Clayton        return_value.SetClangType (clang_uint32_t_type);
1830ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return_value.GetScalar() = 0;
1831ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1832ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
1833ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1834ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        // Run the function
1835ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        ExecutionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
1836ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               &m_get_class_info_args,
1837ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               errors,
1838ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               stop_others,
1839ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               UTILITY_FUNCTION_TIMEOUT_USEC,
1840ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               try_all_threads,
1841ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               unwind_on_error,
1842ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               ignore_breakpoints,
1843ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                               return_value);
1844ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1845ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (results == eExecutionCompleted)
1846ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
1847ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            // The result is the number of ClassInfo structures that were filled in
1848ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            uint32_t num_class_infos = return_value.GetScalar().ULong();
1849f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata            if (log)
1850f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata                log->Printf("Discovered %u ObjC classes\n",num_class_infos);
1851ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (num_class_infos > 0)
1852ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            {
1853ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                // Read the ClassInfo structures
1854ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
1855ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (process->ReadMemory(class_infos_addr, buffer.GetBytes(), buffer.GetByteSize(), err) == buffer.GetByteSize())
1856ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                {
18572e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                    DataExtractor class_infos_data (buffer.GetBytes(),
18582e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                    buffer.GetByteSize(),
18592e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                    process->GetByteOrder(),
18602e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                    addr_size);
18619bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton                    ParseClassInfoArray (class_infos_data, num_class_infos);
1862ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                }
18639540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan            }
1864ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            success = true;
1865ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
1866ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        else
1867ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
1868ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
1869ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
18702e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        }
1871ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
1872ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    else
1873ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
1874ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (log)
1875ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
1876ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
18772e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1878ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Deallocate the memory we allocated for the ClassInfo array
1879ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    process->DeallocateMemory(class_infos_addr);
1880ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1881ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return success;
1882ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
1883ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
18842e045fc8de471b2338909d5f4a8e934deb067fa0Greg Claytonvoid
18859bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg ClaytonAppleObjCRuntimeV2::ParseClassInfoArray (const DataExtractor &data, uint32_t num_class_infos)
18862e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton{
18879bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton    // Parses an array of "num_class_infos" packed ClassInfo structures:
18889bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton    //
18899bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton    //    struct ClassInfo
18909bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton    //    {
18919bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton    //        Class isa;
18929bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton    //        uint32_t hash;
18939bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton    //    } __attribute__((__packed__));
18949bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton
1895952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
18962e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
18972e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    // Iterate through all ClassInfo structures
18982e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    lldb::offset_t offset = 0;
18992e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    for (uint32_t i=0; i<num_class_infos; ++i)
19002e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    {
19012e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        ObjCISA isa = data.GetPointer(&offset);
19022e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
19032e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        if (isa == 0)
19042e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        {
19052e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            if (log)
19062e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                log->Printf("AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
19072e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            continue;
19082e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        }
19092e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        // Check if we already know about this ISA, if we do, the info will
19102e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        // never change, so we can just skip it.
19112e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        if (ISAIsCached(isa))
19122e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        {
19132e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            offset += 4;
19142e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        }
19152e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        else
19162e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        {
19172e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            // Read the 32 bit hash for the class name
19182e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            const uint32_t name_hash = data.GetU32(&offset);
19192e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            ClassDescriptorSP descriptor_sp (new ClassDescriptorV2(*this, isa, NULL));
19202e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            AddClass (isa, descriptor_sp, name_hash);
19212e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            if (log && log->GetVerbose())
19222e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64 ", hash=0x%8.8x", isa, name_hash);
19232e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        }
19242e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    }
19252e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton}
19262e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1927ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonbool
19282e045fc8de471b2338909d5f4a8e934deb067fa0Greg ClaytonAppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
1929ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
1930ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Process *process = GetProcess();
1931ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1932ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (process == NULL)
1933ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1934ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1935952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
1936ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1937ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ExecutionContext exe_ctx;
1938ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1939ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
1940ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1941ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (!thread_sp)
1942ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1943ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1944ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    thread_sp->CalculateExecutionContext(exe_ctx);
1945ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
1946ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1947ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (!ast)
1948ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1949ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1950ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Address function_address;
1951ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1952ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    StreamString errors;
1953ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1954ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const uint32_t addr_size = process->GetAddressByteSize();
1955ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1956ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Error err;
1957ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
19582e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
19592e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
19602e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
19612e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        return false;
19622e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton
1963ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Read the total number of classes from the hash table
19642e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    const uint32_t num_classes = 16*1024;
1965ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (num_classes == 0)
1966ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
1967ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (log)
19682e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            log->Printf ("No dynamic classes found in gdb_objc_realized_classes_addr.");
1969ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1970ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
1971ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1972ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Make some types for our arguments
197352f792329be5db8e38961350589e97e8f2823acdGreg Clayton    ClangASTType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
197452f792329be5db8e38961350589e97e8f2823acdGreg Clayton    ClangASTType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
1975ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
19762e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    if (!m_get_shared_cache_class_info_code.get())
1977ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
19782e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        m_get_shared_cache_class_info_code.reset (new ClangUtilityFunction (g_get_shared_cache_class_info_body,
19792e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                                            g_get_shared_cache_class_info_name));
1980ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1981ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
1982ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
19832e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
1984ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
1985ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
1986ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
19872e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            m_get_shared_cache_class_info_code.reset();
1988ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
1989ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
1990ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
19912e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    if (m_get_shared_cache_class_info_code.get())
19922e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        function_address.SetOffset(m_get_shared_cache_class_info_code->StartAddress());
1993ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    else
1994ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
1995ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1996ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ValueList arguments;
1997ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
1998ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Next make the runner function for our implementation utility function.
19992e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    if (!m_get_shared_cache_class_info_function.get())
2000ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
2001ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        Value value;
2002ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        value.SetValueType (Value::eValueTypeScalar);
200352f792329be5db8e38961350589e97e8f2823acdGreg Clayton        //value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
200452f792329be5db8e38961350589e97e8f2823acdGreg Clayton        value.SetClangType (clang_void_pointer_type);
2005ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        arguments.PushValue (value);
2006ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        arguments.PushValue (value);
2007ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2008ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        value.SetValueType (Value::eValueTypeScalar);
200952f792329be5db8e38961350589e97e8f2823acdGreg Clayton        //value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
201052f792329be5db8e38961350589e97e8f2823acdGreg Clayton        value.SetClangType (clang_uint32_t_type);
2011ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        arguments.PushValue (value);
2012ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
20132e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
20142e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                                        clang_uint32_t_type,
20152e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                                        function_address,
20162e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                                        arguments));
2017ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
20182e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        if (m_get_shared_cache_class_info_function.get() == NULL)
2019ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            return false;
2020ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2021ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
2022ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
20232e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        unsigned num_errors = m_get_shared_cache_class_info_function->CompileFunction(errors);
2024ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (num_errors)
2025ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
2026ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
2027ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf ("Error compiling function: \"%s\".", errors.GetData());
2028ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            return false;
2029ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
2030ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2031ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
2032ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
20332e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        if (!m_get_shared_cache_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
2034ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
2035ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
2036ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
2037ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            return false;
2038ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
2039ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
2040ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    else
2041ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
20422e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        arguments = m_get_shared_cache_class_info_function->GetArgumentValues ();
2043ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
2044ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2045ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const uint32_t class_info_byte_size = addr_size + 4;
2046ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
20472e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
20482e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                             ePermissionsReadable | ePermissionsWritable,
20492e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton                                                             err);
2050ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2051ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (class_infos_addr == LLDB_INVALID_ADDRESS)
2052ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
2053ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
20542e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    Mutex::Locker locker(m_get_shared_cache_class_info_args_mutex);
2055ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2056ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Fill in our function argument values
20572e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton    arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
2058ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
2059ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
2060ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2061ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    bool success = false;
2062ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2063ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    errors.Clear();
2064ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2065ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Write our function arguments into the process so we can run our function
2066ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (m_get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
2067ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                        m_get_shared_cache_class_info_args,
2068ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                        function_address,
2069ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                        arguments,
2070ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                        errors))
2071ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
2072ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool stop_others = true;
2073ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool try_all_threads = false;
2074ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool unwind_on_error = true;
2075ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        bool ignore_breakpoints = true;
2076ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2077ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        Value return_value;
2078ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return_value.SetValueType (Value::eValueTypeScalar);
207952f792329be5db8e38961350589e97e8f2823acdGreg Clayton        //return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
208052f792329be5db8e38961350589e97e8f2823acdGreg Clayton        return_value.SetClangType (clang_uint32_t_type);
2081ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return_value.GetScalar() = 0;
2082ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2083ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        errors.Clear();
2084ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2085ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        // Run the function
2086ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        ExecutionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
2087ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            &m_get_shared_cache_class_info_args,
2088ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            errors,
2089ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            stop_others,
2090ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            UTILITY_FUNCTION_TIMEOUT_USEC,
2091ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            try_all_threads,
2092ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            unwind_on_error,
2093ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            ignore_breakpoints,
2094ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                                                            return_value);
2095ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2096ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (results == eExecutionCompleted)
2097ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
2098ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            // The result is the number of ClassInfo structures that were filled in
2099ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            uint32_t num_class_infos = return_value.GetScalar().ULong();
2100f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata            if (log)
2101f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata                log->Printf("Discovered %u ObjC classes in shared cache\n",num_class_infos);
2102ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (num_class_infos > 0)
21039540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan            {
2104ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                // Read the ClassInfo structures
2105ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
2106ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (process->ReadMemory(class_infos_addr,
2107ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                        buffer.GetBytes(),
2108ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                        buffer.GetByteSize(),
2109ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                        err) == buffer.GetByteSize())
2110ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                {
2111ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    DataExtractor class_infos_data (buffer.GetBytes(),
2112ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                    buffer.GetByteSize(),
2113ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                    process->GetByteOrder(),
2114ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                                                    addr_size);
2115ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
21169bf4c4add7b7b0a173afe0b3246ce3dfa795dcbbGreg Clayton                    ParseClassInfoArray (class_infos_data, num_class_infos);
2117ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                }
21189540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan            }
2119ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            success = true;
2120ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
2121ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        else
2122ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
2123ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log)
2124ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
2125ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
2126ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
2127ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    else
2128ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
2129ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (log)
2130ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
2131ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
2132ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2133ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Deallocate the memory we allocated for the ClassInfo array
2134ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    process->DeallocateMemory(class_infos_addr);
2135ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2136ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return success;
2137ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
2138ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2139ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2140ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonbool
2141ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonAppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table)
2142ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
2143952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
2144ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2145ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Process *process = GetProcess();
2146ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2147ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (process == NULL)
2148ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return false;
2149ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2150ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint32_t num_map_table_isas = 0;
2151ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2152ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ModuleSP objc_module_sp(GetObjCModule());
2153ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2154ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (objc_module_sp)
2155ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
2156ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        for (RemoteNXMapTable::element elt : hash_table)
2157ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
2158ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            ++num_map_table_isas;
21599540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan
2160ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (ISAIsCached(elt.second))
2161ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                continue;
21629540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan
2163ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
21649540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan
2165ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (log && log->GetVerbose())
2166ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
21679540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan
2168ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            AddClass (elt.second, descriptor_sp, elt.first.AsCString());
2169ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
2170ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
2171ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2172ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return num_map_table_isas > 0;
2173ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
2174ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2175ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonlldb::addr_t
2176ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonAppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress()
2177ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
2178ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Process *process = GetProcess();
2179ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2180ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (process)
2181ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
2182ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        ModuleSP objc_module_sp(GetObjCModule());
21839540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan
2184ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (objc_module_sp)
21859540568d3120dae0ef61a64fcc0410c1778fbb88Sean Callanan        {
2186ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            ObjectFile *objc_object = objc_module_sp->GetObjectFile();
2187a510437e795477e5f629263d3d191d982c991733Greg Clayton
2188ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            if (objc_object)
2189a510437e795477e5f629263d3d191d982c991733Greg Clayton            {
21907940069905bee0b2e5f0661bf37c9f906ddf8603Greg Clayton                SectionList *section_list = objc_module_sp->GetSectionList();
2191a510437e795477e5f629263d3d191d982c991733Greg Clayton
2192ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (section_list)
2193a510437e795477e5f629263d3d191d982c991733Greg Clayton                {
2194ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
2195c62f5ab9b1c977dac97c94d4105cc9daca04fd5aSean Callanan
2196ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    if (text_segment_sp)
2197a510437e795477e5f629263d3d191d982c991733Greg Clayton                    {
2198ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
2199a510437e795477e5f629263d3d191d982c991733Greg Clayton
2200ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        if (objc_opt_section_sp)
2201a510437e795477e5f629263d3d191d982c991733Greg Clayton                        {
2202ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                            return objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
2203a510437e795477e5f629263d3d191d982c991733Greg Clayton                        }
2204a510437e795477e5f629263d3d191d982c991733Greg Clayton                    }
2205a510437e795477e5f629263d3d191d982c991733Greg Clayton                }
2206a510437e795477e5f629263d3d191d982c991733Greg Clayton            }
2207ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
2208ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
2209ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return LLDB_INVALID_ADDRESS;
2210ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
2211ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2212ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonvoid
2213ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonAppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
2214ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
2215ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
2216ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2217ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    // Else we need to check with our process to see when the map was updated.
2218ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Process *process = GetProcess();
2219ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2220ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (process)
2221ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
2222ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        RemoteNXMapTable hash_table;
2223ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2224ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        // Update the process stop ID that indicates the last time we updated the
2225ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        // map, wether it was successful or not.
2226ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_isa_to_descriptor_stop_id = process->GetStopID();
2227ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2228ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
2229ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            return;
2230ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2231ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_hash_signature.UpdateSignature (hash_table);
2232ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2233ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        // Grab the dynamicly loaded objc classes from the hash table in memory
22342e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        UpdateISAToDescriptorMapDynamic(hash_table);
2235ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
2236ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        // Now get the objc classes that are baked into the Objective C runtime
22372e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        // in the shared cache, but only once per process as this data never
22382e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton        // changes
2239ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (!m_loaded_objc_opt)
22402e045fc8de471b2338909d5f4a8e934deb067fa0Greg Clayton            UpdateISAToDescriptorMapSharedCache();
22416fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    }
224290c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    else
224390c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    {
2244ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_isa_to_descriptor_stop_id = UINT32_MAX;
224590c6cd5764ed78d4b45606f6ee648c71ec298c03Greg Clayton    }
2246afb7c85df796f74262917e44dd68f668dade3911Enrico Granata}
2247afb7c85df796f74262917e44dd68f668dade3911Enrico Granata
2248a510437e795477e5f629263d3d191d982c991733Greg Clayton
2249be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton// TODO: should we have a transparent_kvo parameter here to say if we
2250441f08ca9d17fad237b93a71aeab9dad74ea1258Enrico Granata// want to replace the KVO swizzled class with the actual user-level type?
2251afb7c85df796f74262917e44dd68f668dade3911Enrico GranataConstString
22526e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonAppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
2253afb7c85df796f74262917e44dd68f668dade3911Enrico Granata{
22540c3d6d6eb941a60b44fbf49e879601d4e5ccebbaEnrico Granata    if (isa == g_objc_Tagged_ISA)
2255249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton    {
2256249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton        static const ConstString g_objc_tagged_isa_name ("_lldb_Tagged_ObjC_ISA");
2257249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton        return g_objc_tagged_isa_name;
2258249f4c468f1aae726d5a30db12243e590e7ec010Greg Clayton    }
2259f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (isa == g_objc_Tagged_ISA_NSAtom)
2260f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
2261f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
2262f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return g_objc_tagged_isa_nsatom_name;
2263f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
2264f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (isa == g_objc_Tagged_ISA_NSNumber)
2265f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
2266f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
2267f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return g_objc_tagged_isa_nsnumber_name;
2268f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
2269f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (isa == g_objc_Tagged_ISA_NSDateTS)
2270f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
2271f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
2272f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return g_objc_tagged_isa_nsdatets_name;
2273f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
2274f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (isa == g_objc_Tagged_ISA_NSManagedObject)
2275f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
2276f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
2277f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return g_objc_tagged_isa_nsmanagedobject_name;
2278f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
2279f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (isa == g_objc_Tagged_ISA_NSDate)
2280f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
2281f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
2282f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return g_objc_tagged_isa_nsdate_name;
2283f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
2284be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    return ObjCLanguageRuntime::GetActualTypeName(isa);
2285ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata}
2286ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata
2287c718b9652bb1a7aea5d133123fcc8bc87277002cSean CallananTypeVendor *
2288c718b9652bb1a7aea5d133123fcc8bc87277002cSean CallananAppleObjCRuntimeV2::GetTypeVendor()
2289ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata{
2290c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan    if (!m_type_vendor_ap.get())
2291c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan        m_type_vendor_ap.reset(new AppleObjCTypeVendor(*this));
2292ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata
2293c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan    return m_type_vendor_ap.get();
2294ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata}
2295d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2296d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callananlldb::addr_t
2297d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean CallananAppleObjCRuntimeV2::LookupRuntimeSymbol (const ConstString &name)
2298d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan{
2299d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    lldb::addr_t ret = LLDB_INVALID_ADDRESS;
2300d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2301d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    const char *name_cstr = name.AsCString();
2302d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2303d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    if (name_cstr)
2304d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    {
2305d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        llvm::StringRef name_strref(name_cstr);
2306d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2307d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
2308967a99733b4246892250519bd4f14c8290c1988dSean Callanan        static const llvm::StringRef class_prefix("OBJC_CLASS_$_");
2309d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2310d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        if (name_strref.startswith(ivar_prefix))
2311d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        {
2312d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            llvm::StringRef ivar_skipped_prefix = name_strref.substr(ivar_prefix.size());
2313d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar = ivar_skipped_prefix.split('.');
2314d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2315d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            if (class_and_ivar.first.size() && class_and_ivar.second.size())
2316d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            {
2317d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                const ConstString class_name_cs(class_and_ivar.first);
2318d387b462eecb908af265ecc7006781b4532073adGreg Clayton                ClassDescriptorSP descriptor = ObjCLanguageRuntime::GetClassDescriptorFromClassName(class_name_cs);
2319d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2320d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                if (descriptor)
2321d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                {
2322d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                    const ConstString ivar_name_cs(class_and_ivar.second);
2323d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                    const char *ivar_name_cstr = ivar_name_cs.AsCString();
2324d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2325b9db9d5bb01963774f28540dbe2c5a11f586ff29Daniel Malea                    auto ivar_func = [&ret, ivar_name_cstr](const char *name, const char *type, lldb::addr_t offset_addr, uint64_t size) -> lldb::addr_t
2326d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                    {
2327d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                        if (!strcmp(name, ivar_name_cstr))
2328d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                        {
2329d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                            ret = offset_addr;
2330d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                            return true;
2331d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                        }
2332d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                        return false;
2333d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                    };
2334d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2335d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                    descriptor->Describe(std::function<void (ObjCISA)>(nullptr),
2336d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                                         std::function<bool (const char *, const char *)>(nullptr),
2337d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                                         std::function<bool (const char *, const char *)>(nullptr),
2338d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                                         ivar_func);
2339d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan                }
2340d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan            }
2341d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan        }
2342967a99733b4246892250519bd4f14c8290c1988dSean Callanan        else if (name_strref.startswith(class_prefix))
2343967a99733b4246892250519bd4f14c8290c1988dSean Callanan        {
2344967a99733b4246892250519bd4f14c8290c1988dSean Callanan            llvm::StringRef class_skipped_prefix = name_strref.substr(class_prefix.size());
2345967a99733b4246892250519bd4f14c8290c1988dSean Callanan            const ConstString class_name_cs(class_skipped_prefix);
23466a25e5571a5b4173aae6fa6d0baffc75f5f8ecd2Sean Callanan            ClassDescriptorSP descriptor = GetClassDescriptorFromClassName(class_name_cs);
2347967a99733b4246892250519bd4f14c8290c1988dSean Callanan
2348967a99733b4246892250519bd4f14c8290c1988dSean Callanan            if (descriptor)
2349967a99733b4246892250519bd4f14c8290c1988dSean Callanan                ret = descriptor->GetISA();
2350967a99733b4246892250519bd4f14c8290c1988dSean Callanan        }
2351967a99733b4246892250519bd4f14c8290c1988dSean Callanan    }
2352d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan
2353d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan    return ret;
2354d27e543e9c5f81ef1288afbc9e48de2da5976a8aSean Callanan}
2355d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2356d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::NonPointerISACache*
2357d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::NonPointerISACache::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
2358d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2359d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    Process* process(runtime.GetProcess());
2360d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2361d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    Error error;
2362d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2363d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol(process,
2364d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                ConstString("objc_debug_isa_magic_mask"),
2365d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                objc_module_sp,
2366d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                error);
2367d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2368d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return NULL;
2369d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2370d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_isa_magic_value = ExtractRuntimeGlobalSymbol(process,
2371d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                 ConstString("objc_debug_isa_magic_value"),
2372d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                 objc_module_sp,
2373d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                 error);
2374d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2375d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return NULL;
2376d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2377d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_isa_class_mask = ExtractRuntimeGlobalSymbol(process,
2378d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                ConstString("objc_debug_isa_class_mask"),
2379d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                objc_module_sp,
2380d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                error);
2381d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2382d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return NULL;
2383d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2384d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    // 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, ...)
2385d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2386d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return new NonPointerISACache(runtime,
2387d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                  objc_debug_isa_class_mask,
2388d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                  objc_debug_isa_magic_mask,
2389d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                  objc_debug_isa_magic_value);
2390d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2391d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2392d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendor*
2393d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendor::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
2394d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2395d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    Process* process(runtime.GetProcess());
2396d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2397d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    Error error;
2398d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2399d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_taggedpointer_mask = ExtractRuntimeGlobalSymbol(process,
2400d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                    ConstString("objc_debug_taggedpointer_mask"),
2401d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                    objc_module_sp,
2402d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                    error);
2403d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2404d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return new TaggedPointerVendorLegacy(runtime);
2405d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2406d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_taggedpointer_slot_shift = ExtractRuntimeGlobalSymbol(process,
2407d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          ConstString("objc_debug_taggedpointer_slot_shift"),
2408d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          objc_module_sp,
2409d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          error,
2410d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          true,
2411d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          4);
2412d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2413d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return new TaggedPointerVendorLegacy(runtime);
2414d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2415d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_taggedpointer_slot_mask = ExtractRuntimeGlobalSymbol(process,
2416d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          ConstString("objc_debug_taggedpointer_slot_mask"),
2417d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          objc_module_sp,
2418d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          error,
2419d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          true,
2420d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                          4);
2421d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2422d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return new TaggedPointerVendorLegacy(runtime);
2423d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2424d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_taggedpointer_payload_lshift = ExtractRuntimeGlobalSymbol(process,
2425d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              ConstString("objc_debug_taggedpointer_payload_lshift"),
2426d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              objc_module_sp,
2427d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              error,
2428d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              true,
2429d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              4);
2430d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2431d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return new TaggedPointerVendorLegacy(runtime);
2432d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2433d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_taggedpointer_payload_rshift = ExtractRuntimeGlobalSymbol(process,
2434d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              ConstString("objc_debug_taggedpointer_payload_rshift"),
2435d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              objc_module_sp,
2436d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              error,
2437d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              true,
2438d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                              4);
2439d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2440d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return new TaggedPointerVendorLegacy(runtime);
2441d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2442d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto objc_debug_taggedpointer_classes = ExtractRuntimeGlobalSymbol(process,
2443d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                       ConstString("objc_debug_taggedpointer_classes"),
2444d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                       objc_module_sp,
2445d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                       error,
2446d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                       false);
2447d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (error.Fail())
2448d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return new TaggedPointerVendorLegacy(runtime);
2449d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2450d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2451d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    // we might want to have some rules to outlaw these values (e.g if the table's address is zero)
2452d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2453d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return new TaggedPointerVendorRuntimeAssisted(runtime,
2454d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                  objc_debug_taggedpointer_mask,
2455d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                  objc_debug_taggedpointer_slot_shift,
2456d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                  objc_debug_taggedpointer_slot_mask,
2457d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                  objc_debug_taggedpointer_payload_lshift,
2458d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                  objc_debug_taggedpointer_payload_rshift,
2459d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                  objc_debug_taggedpointer_classes);
2460d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2461d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2462d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatabool
2463d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendorLegacy::IsPossibleTaggedPointer (lldb::addr_t ptr)
2464d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2465d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return (ptr & 1);
2466d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2467d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2468d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata// we use the version of Foundation to make assumptions about the ObjC runtime on a target
2469d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatauint32_t
2470d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetFoundationVersion (Target &target)
2471d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2472d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    const ModuleList& modules = target.GetImages();
2473d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    uint32_t major = UINT32_MAX;
2474d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    for (uint32_t idx = 0; idx < modules.GetSize(); idx++)
2475d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
2476d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx);
2477d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (!module_sp)
2478d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            continue;
2479d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (strcmp(module_sp->GetFileSpec().GetFilename().AsCString(""),"Foundation") == 0)
2480d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        {
2481d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            module_sp->GetVersion(&major,1);
2482d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            break;
2483d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        }
2484d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
2485d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return major;
2486d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2487d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2488d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataObjCLanguageRuntime::ClassDescriptorSP
2489d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor (lldb::addr_t ptr)
2490d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2491d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (!IsPossibleTaggedPointer(ptr))
2492d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return ObjCLanguageRuntime::ClassDescriptorSP();
2493d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2494d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    Process* process(m_runtime.GetProcess());
2495d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2496d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (m_Foundation_version == 0)
2497d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_Foundation_version = GetFoundationVersion(process->GetTarget());
2498d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2499d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (m_Foundation_version == UINT32_MAX)
2500d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return ObjCLanguageRuntime::ClassDescriptorSP();
2501d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2502d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    uint64_t class_bits = (ptr & 0xE) >> 1;
2503d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    ConstString name;
2504d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2505d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    // TODO: make a table
2506d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (m_Foundation_version >= 900)
2507d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
2508d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        switch (class_bits)
2509d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        {
2510d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 0:
2511d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSAtom");
2512d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2513d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 3:
2514d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSNumber");
2515d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2516d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 4:
2517d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSDateTS");
2518d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2519d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 5:
2520d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSManagedObject");
2521d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2522d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 6:
2523d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSDate");
2524d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2525d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            default:
2526d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                return ObjCLanguageRuntime::ClassDescriptorSP();
2527d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        }
2528d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
2529d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    else
2530d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
2531d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        switch (class_bits)
2532d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        {
2533d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 1:
2534d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSNumber");
2535d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2536d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 5:
2537d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSManagedObject");
2538d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2539d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 6:
2540d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSDate");
2541d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2542d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            case 7:
2543d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                name = ConstString("NSDateTS");
2544d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                break;
2545d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            default:
2546d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                return ObjCLanguageRuntime::ClassDescriptorSP();
2547d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        }
2548d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
2549d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return ClassDescriptorSP(new ClassDescriptorV2Tagged(name,ptr));
2550d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2551d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2552d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::TaggedPointerVendorRuntimeAssisted (AppleObjCRuntimeV2& runtime,
2553d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                                            uint64_t objc_debug_taggedpointer_mask,
2554d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                                            uint32_t objc_debug_taggedpointer_slot_shift,
2555d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                                            uint32_t objc_debug_taggedpointer_slot_mask,
2556d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                                            uint32_t objc_debug_taggedpointer_payload_lshift,
2557d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                                            uint32_t objc_debug_taggedpointer_payload_rshift,
2558d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                                                            lldb::addr_t objc_debug_taggedpointer_classes) :
2559d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataTaggedPointerVendor(runtime),
2560d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_cache(),
2561d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask),
2562d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_taggedpointer_slot_shift(objc_debug_taggedpointer_slot_shift),
2563d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_taggedpointer_slot_mask(objc_debug_taggedpointer_slot_mask),
2564d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_taggedpointer_payload_lshift(objc_debug_taggedpointer_payload_lshift),
2565d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_taggedpointer_payload_rshift(objc_debug_taggedpointer_payload_rshift),
2566d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_taggedpointer_classes(objc_debug_taggedpointer_classes)
2567d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2568d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2569d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2570d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatabool
2571d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::IsPossibleTaggedPointer (lldb::addr_t ptr)
2572d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2573d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return (ptr & m_objc_debug_taggedpointer_mask) != 0;
2574d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2575d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2576d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataObjCLanguageRuntime::ClassDescriptorSP
2577d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor (lldb::addr_t ptr)
2578d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2579d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    ClassDescriptorSP actual_class_descriptor_sp;
2580d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    uint64_t data_payload;
2581d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2582d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (!IsPossibleTaggedPointer(ptr))
2583d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return ObjCLanguageRuntime::ClassDescriptorSP();
2584d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2585d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) & m_objc_debug_taggedpointer_slot_mask;
2586d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2587d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    CacheIterator iterator = m_cache.find(slot),
2588d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    end = m_cache.end();
2589d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (iterator != end)
2590d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
2591d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        actual_class_descriptor_sp = iterator->second;
2592d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
2593d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    else
2594d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
2595d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        Process* process(m_runtime.GetProcess());
2596d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_classes;
2597d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        Error error;
2598d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
2599d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (error.Fail() || slot_data == 0 || slot_data == LLDB_INVALID_ADDRESS)
2600884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec            return nullptr;
2601d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        actual_class_descriptor_sp = m_runtime.GetClassDescriptor(slot_data);
2602d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        if (!actual_class_descriptor_sp)
2603d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata            return ObjCLanguageRuntime::ClassDescriptorSP();
2604d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_cache[slot] = actual_class_descriptor_sp;
2605d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
2606d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2607d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_payload_lshift) >> m_objc_debug_taggedpointer_payload_rshift);
2608d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2609d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
2610d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2611d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2612d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache (AppleObjCRuntimeV2& runtime,
2613d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                            uint64_t objc_debug_isa_class_mask,
2614d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                            uint64_t objc_debug_isa_magic_mask,
2615d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata                                                            uint64_t objc_debug_isa_magic_value) :
2616d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_runtime(runtime),
2617d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_cache(),
2618d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
2619d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
2620d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatam_objc_debug_isa_magic_value(objc_debug_isa_magic_value)
2621d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2622d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2623d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2624d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataObjCLanguageRuntime::ClassDescriptorSP
2625d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor (ObjCISA isa)
2626d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2627d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    ObjCISA real_isa = 0;
2628d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (EvaluateNonPointerISA(isa, real_isa) == false)
2629d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return ObjCLanguageRuntime::ClassDescriptorSP();
2630d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto cache_iter = m_cache.find(real_isa);
2631d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (cache_iter != m_cache.end())
2632d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return cache_iter->second;
2633d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    auto descriptor_sp = m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(real_isa);
2634d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if (descriptor_sp) // cache only positive matches since the table might grow
2635d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        m_cache[real_isa] = descriptor_sp;
2636d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return descriptor_sp;
2637d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2638d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata
2639d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granatabool
2640d9661be3c9f884d9a7a78174038387edd04c5d93Enrico GranataAppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA (ObjCISA isa, ObjCISA& ret_isa)
2641d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata{
2642d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if ( (isa & ~m_objc_debug_isa_class_mask) == 0)
2643d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return false;
2644d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    if ( (isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value)
2645d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    {
2646d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        ret_isa = isa & m_objc_debug_isa_class_mask;
2647d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata        return (ret_isa != 0); // this is a pointer so 0 is not a valid value
2648d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    }
2649d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata    return false;
2650d9661be3c9f884d9a7a78174038387edd04c5d93Enrico Granata}
2651