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