LLDB  mainline
AppleObjCRuntimeV2.cpp
Go to the documentation of this file.
1 //===-- AppleObjCRuntimeV2.cpp --------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 
12 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/Module.h"
16 #include "lldb/Core/Section.h"
22 #include "lldb/Host/OptionParser.h"
29 #include "lldb/Symbol/ObjectFile.h"
30 #include "lldb/Symbol/Symbol.h"
31 #include "lldb/Symbol/TypeList.h"
33 #include "lldb/Target/ABI.h"
36 #include "lldb/Target/Platform.h"
37 #include "lldb/Target/Process.h"
40 #include "lldb/Target/Target.h"
41 #include "lldb/Target/Thread.h"
43 #include "lldb/Utility/LLDBLog.h"
44 #include "lldb/Utility/Log.h"
45 #include "lldb/Utility/Scalar.h"
46 #include "lldb/Utility/Status.h"
47 #include "lldb/Utility/Stream.h"
49 #include "lldb/Utility/Timer.h"
50 #include "lldb/lldb-enumerations.h"
51 
53 #include "AppleObjCDeclVendor.h"
54 #include "AppleObjCRuntimeV2.h"
57 
58 #include "clang/AST/ASTContext.h"
59 #include "clang/AST/DeclObjC.h"
60 #include "clang/Basic/TargetInfo.h"
61 #include "llvm/ADT/ScopeExit.h"
62 
63 #include <cstdint>
64 #include <memory>
65 #include <string>
66 #include <vector>
67 
68 using namespace lldb;
69 using namespace lldb_private;
70 
71 char AppleObjCRuntimeV2::ID = 0;
72 
73 static const char *g_get_dynamic_class_info_name =
74  "__lldb_apple_objc_v2_get_dynamic_class_info";
75 
76 static const char *g_get_dynamic_class_info_body = R"(
77 
78 extern "C"
79 {
80  size_t strlen(const char *);
81  char *strncpy (char * s1, const char * s2, size_t n);
82  int printf(const char * format, ...);
83 }
84 #define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
85 
86 typedef struct _NXMapTable {
87  void *prototype;
88  unsigned num_classes;
89  unsigned num_buckets_minus_one;
90  void *buckets;
91 } NXMapTable;
92 
93 #define NX_MAPNOTAKEY ((void *)(-1))
94 
95 typedef struct BucketInfo
96 {
97  const char *name_ptr;
98  Class isa;
99 } BucketInfo;
100 
101 struct ClassInfo
102 {
103  Class isa;
104  uint32_t hash;
105 } __attribute__((__packed__));
106 
107 uint32_t
108 __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,
109  void *class_infos_ptr,
110  uint32_t class_infos_byte_size,
111  uint32_t should_log)
112 {
113  DEBUG_PRINTF ("gdb_objc_realized_classes_ptr = %p\n", gdb_objc_realized_classes_ptr);
114  DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
115  DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
116  const NXMapTable *grc = (const NXMapTable *)gdb_objc_realized_classes_ptr;
117  if (grc)
118  {
119  const unsigned num_classes = grc->num_classes;
120  DEBUG_PRINTF ("num_classes = %u\n", grc->num_classes);
121  if (class_infos_ptr)
122  {
123  const unsigned num_buckets_minus_one = grc->num_buckets_minus_one;
124  DEBUG_PRINTF ("num_buckets_minus_one = %u\n", num_buckets_minus_one);
125 
126  const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
127  DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
128 
129  ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
130  BucketInfo *buckets = (BucketInfo *)grc->buckets;
131 
132  uint32_t idx = 0;
133  for (unsigned i=0; i<=num_buckets_minus_one; ++i)
134  {
135  if (buckets[i].name_ptr != NX_MAPNOTAKEY)
136  {
137  if (idx < max_class_infos)
138  {
139  const char *s = buckets[i].name_ptr;
140  uint32_t h = 5381;
141  for (unsigned char c = *s; c; c = *++s)
142  h = ((h << 5) + h) + c;
143  class_infos[idx].hash = h;
144  class_infos[idx].isa = buckets[i].isa;
145  DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, buckets[i].name_ptr);
146  }
147  ++idx;
148  }
149  }
150  if (idx < max_class_infos)
151  {
152  class_infos[idx].isa = NULL;
153  class_infos[idx].hash = 0;
154  }
155  }
156  return num_classes;
157  }
158  return 0;
159 }
160 
161 )";
162 
163 static const char *g_get_dynamic_class_info2_name =
164  "__lldb_apple_objc_v2_get_dynamic_class_info2";
165 
166 static const char *g_get_dynamic_class_info2_body = R"(
167 
168 extern "C" {
169  int printf(const char * format, ...);
170  void free(void *ptr);
171  Class* objc_copyRealizedClassList_nolock(unsigned int *outCount);
172  const char* objc_debug_class_getNameRaw(Class cls);
173 }
174 
175 #define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
176 
177 struct ClassInfo
178 {
179  Class isa;
180  uint32_t hash;
181 } __attribute__((__packed__));
182 
183 uint32_t
184 __lldb_apple_objc_v2_get_dynamic_class_info2(void *gdb_objc_realized_classes_ptr,
185  void *class_infos_ptr,
186  uint32_t class_infos_byte_size,
187  uint32_t should_log)
188 {
189  DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
190  DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
191 
192  const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
193  DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
194 
195  ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
196 
197  uint32_t count = 0;
198  Class* realized_class_list = objc_copyRealizedClassList_nolock(&count);
199  DEBUG_PRINTF ("count = %u\n", count);
200 
201  uint32_t idx = 0;
202  for (uint32_t i=0; i<count; ++i)
203  {
204  if (idx < max_class_infos)
205  {
206  Class isa = realized_class_list[i];
207  const char *name_ptr = objc_debug_class_getNameRaw(isa);
208  if (!name_ptr)
209  continue;
210  const char *s = name_ptr;
211  uint32_t h = 5381;
212  for (unsigned char c = *s; c; c = *++s)
213  h = ((h << 5) + h) + c;
214  class_infos[idx].hash = h;
215  class_infos[idx].isa = isa;
216  DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name_ptr);
217  }
218  idx++;
219  }
220 
221  if (idx < max_class_infos)
222  {
223  class_infos[idx].isa = NULL;
224  class_infos[idx].hash = 0;
225  }
226 
227  free(realized_class_list);
228  return count;
229 }
230 )";
231 
232 static const char *g_get_dynamic_class_info3_name =
233  "__lldb_apple_objc_v2_get_dynamic_class_info3";
234 
235 static const char *g_get_dynamic_class_info3_body = R"(
236 
237 extern "C" {
238  int printf(const char * format, ...);
239  void free(void *ptr);
240  size_t objc_getRealizedClassList_trylock(Class *buffer, size_t len);
241  const char* objc_debug_class_getNameRaw(Class cls);
242  const char* class_getName(Class cls);
243 }
244 
245 #define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
246 
247 struct ClassInfo
248 {
249  Class isa;
250  uint32_t hash;
251 } __attribute__((__packed__));
252 
253 uint32_t
254 __lldb_apple_objc_v2_get_dynamic_class_info3(void *gdb_objc_realized_classes_ptr,
255  void *class_infos_ptr,
256  uint32_t class_infos_byte_size,
257  void *class_buffer,
258  uint32_t class_buffer_len,
259  uint32_t should_log)
260 {
261  DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
262  DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
263 
264  const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
265  DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
266 
267  ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
268 
269  Class *realized_class_list = (Class*)class_buffer;
270 
271  uint32_t count = objc_getRealizedClassList_trylock(realized_class_list,
272  class_buffer_len);
273  DEBUG_PRINTF ("count = %u\n", count);
274 
275  uint32_t idx = 0;
276  for (uint32_t i=0; i<count; ++i)
277  {
278  if (idx < max_class_infos)
279  {
280  Class isa = realized_class_list[i];
281  const char *name_ptr = objc_debug_class_getNameRaw(isa);
282  if (!name_ptr) {
283  class_getName(isa); // Realize name of lazy classes.
284  name_ptr = objc_debug_class_getNameRaw(isa);
285  }
286  if (!name_ptr)
287  continue;
288  const char *s = name_ptr;
289  uint32_t h = 5381;
290  for (unsigned char c = *s; c; c = *++s)
291  h = ((h << 5) + h) + c;
292  class_infos[idx].hash = h;
293  class_infos[idx].isa = isa;
294  DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name_ptr);
295  }
296  idx++;
297  }
298 
299  if (idx < max_class_infos)
300  {
301  class_infos[idx].isa = NULL;
302  class_infos[idx].hash = 0;
303  }
304 
305  return count;
306 }
307 )";
308 
309 // We'll substitute in class_getName or class_getNameRaw depending
310 // on which is present.
311 static const char *g_shared_cache_class_name_funcptr = R"(
312 extern "C"
313 {
314  const char *%s(void *objc_class);
315  const char *(*class_name_lookup_func)(void *) = %s;
316 }
317 )";
318 
320  "__lldb_apple_objc_v2_get_shared_cache_class_info";
321 
322 static const char *g_get_shared_cache_class_info_body = R"(
323 
324 extern "C"
325 {
326  size_t strlen(const char *);
327  char *strncpy (char * s1, const char * s2, size_t n);
328  int printf(const char * format, ...);
329 }
330 
331 #define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
332 
333 
334 struct objc_classheader_t {
335  int32_t clsOffset;
336  int32_t hiOffset;
337 };
338 
339 struct objc_classheader_v16_t {
340  uint64_t isDuplicate : 1,
341  objectCacheOffset : 47, // Offset from the shared cache base
342  dylibObjCIndex : 16;
343 };
344 
345 struct objc_clsopt_t {
346  uint32_t capacity;
347  uint32_t occupied;
348  uint32_t shift;
349  uint32_t mask;
350  uint32_t zero;
351  uint32_t unused;
352  uint64_t salt;
353  uint32_t scramble[256];
354  uint8_t tab[0]; // tab[mask+1]
355  // uint8_t checkbytes[capacity];
356  // int32_t offset[capacity];
357  // objc_classheader_t clsOffsets[capacity];
358  // uint32_t duplicateCount;
359  // objc_classheader_t duplicateOffsets[duplicateCount];
360 };
361 
362 struct objc_clsopt_v16_t {
363  uint32_t version;
364  uint32_t capacity;
365  uint32_t occupied;
366  uint32_t shift;
367  uint32_t mask;
368  uint32_t zero;
369  uint64_t salt;
370  uint32_t scramble[256];
371  uint8_t tab[0]; // tab[mask+1]
372  // uint8_t checkbytes[capacity];
373  // int32_t offset[capacity];
374  // objc_classheader_t clsOffsets[capacity];
375  // uint32_t duplicateCount;
376  // objc_classheader_t duplicateOffsets[duplicateCount];
377 };
378 
379 struct objc_opt_t {
380  uint32_t version;
381  int32_t selopt_offset;
382  int32_t headeropt_offset;
383  int32_t clsopt_offset;
384 };
385 
386 struct objc_opt_v14_t {
387  uint32_t version;
388  uint32_t flags;
389  int32_t selopt_offset;
390  int32_t headeropt_offset;
391  int32_t clsopt_offset;
392 };
393 
394 struct objc_opt_v16_t {
395  uint32_t version;
396  uint32_t flags;
397  int32_t selopt_offset;
398  int32_t headeropt_ro_offset;
399  int32_t unused_clsopt_offset;
400  int32_t unused_protocolopt_offset;
401  int32_t headeropt_rw_offset;
402  int32_t unused_protocolopt2_offset;
403  int32_t largeSharedCachesClassOffset;
404  int32_t largeSharedCachesProtocolOffset;
405  uint64_t relativeMethodSelectorBaseAddressCacheOffset;
406 };
407 
408 struct ClassInfo
409 {
410  Class isa;
411  uint32_t hash;
412 } __attribute__((__packed__));
413 
414 uint32_t
415 __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
416  void *shared_cache_base_ptr,
417  void *class_infos_ptr,
418  uint64_t *relative_selector_offset,
419  uint32_t class_infos_byte_size,
420  uint32_t should_log)
421 {
422  *relative_selector_offset = 0;
423  uint32_t idx = 0;
424  DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
425  DEBUG_PRINTF ("shared_cache_base_ptr = %p\n", shared_cache_base_ptr);
426  DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
427  DEBUG_PRINTF ("class_infos_byte_size = %u (%llu class infos)\n", class_infos_byte_size, (uint64_t)(class_infos_byte_size/sizeof(ClassInfo)));
428  if (objc_opt_ro_ptr)
429  {
430  const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
431  const objc_opt_v14_t* objc_opt_v14 = (objc_opt_v14_t*)objc_opt_ro_ptr;
432  const objc_opt_v16_t* objc_opt_v16 = (objc_opt_v16_t*)objc_opt_ro_ptr;
433  if (objc_opt->version >= 16)
434  {
435  *relative_selector_offset = objc_opt_v16->relativeMethodSelectorBaseAddressCacheOffset;
436  DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v16->version);
437  DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v16->flags);
438  DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt_v16->selopt_offset);
439  DEBUG_PRINTF ("objc_opt->headeropt_ro_offset = %d\n", objc_opt_v16->headeropt_ro_offset);
440  DEBUG_PRINTF ("objc_opt->relativeMethodSelectorBaseAddressCacheOffset = %d\n", *relative_selector_offset);
441  }
442  else if (objc_opt->version >= 14)
443  {
444  DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v14->version);
445  DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v14->flags);
446  DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt_v14->selopt_offset);
447  DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt_v14->headeropt_offset);
448  DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt_v14->clsopt_offset);
449  }
450  else
451  {
452  DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt->version);
453  DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt->selopt_offset);
454  DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
455  DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
456  }
457 
458  if (objc_opt->version == 16)
459  {
460  const objc_clsopt_v16_t* clsopt = (const objc_clsopt_v16_t*)((uint8_t *)objc_opt + objc_opt_v16->largeSharedCachesClassOffset);
461  const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
462 
463  DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
464 
465  ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
466 
467  const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
468  const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
469  const objc_classheader_v16_t *classOffsets = (const objc_classheader_v16_t *)(offsets + clsopt->capacity);
470 
471  DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
472  DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
473  DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
474 
475  for (uint32_t i=0; i<clsopt->capacity; ++i)
476  {
477  const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
478  DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
479 
480  if (classOffsets[i].isDuplicate) {
481  DEBUG_PRINTF("isDuplicate = true\n");
482  continue; // duplicate
483  }
484 
485  if (objectCacheOffset == 0) {
486  DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
487  continue; // invalid offset
488  }
489 
490  if (class_infos && idx < max_class_infos)
491  {
492  class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
493 
494  // Lookup the class name.
495  const char *name = class_name_lookup_func(class_infos[idx].isa);
496  DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
497 
498  // Hash the class name so we don't have to read it.
499  const char *s = name;
500  uint32_t h = 5381;
501  for (unsigned char c = *s; c; c = *++s)
502  {
503  // class_getName demangles swift names and the hash must
504  // be calculated on the mangled name. hash==0 means lldb
505  // will fetch the mangled name and compute the hash in
506  // ParseClassInfoArray.
507  if (c == '.')
508  {
509  h = 0;
510  break;
511  }
512  h = ((h << 5) + h) + c;
513  }
514  class_infos[idx].hash = h;
515  }
516  else
517  {
518  DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
519  }
520  ++idx;
521  }
522 
523  const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
524  const uint32_t duplicate_count = *duplicate_count_ptr;
525  const objc_classheader_v16_t *duplicateClassOffsets = (const objc_classheader_v16_t *)(&duplicate_count_ptr[1]);
526 
527  DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
528  DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
529 
530  for (uint32_t i=0; i<duplicate_count; ++i)
531  {
532  const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
533  DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
534 
535  if (classOffsets[i].isDuplicate) {
536  DEBUG_PRINTF("isDuplicate = true\n");
537  continue; // duplicate
538  }
539 
540  if (objectCacheOffset == 0) {
541  DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
542  continue; // invalid offset
543  }
544 
545  if (class_infos && idx < max_class_infos)
546  {
547  class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
548 
549  // Lookup the class name.
550  const char *name = class_name_lookup_func(class_infos[idx].isa);
551  DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
552 
553  // Hash the class name so we don't have to read it.
554  const char *s = name;
555  uint32_t h = 5381;
556  for (unsigned char c = *s; c; c = *++s)
557  {
558  // class_getName demangles swift names and the hash must
559  // be calculated on the mangled name. hash==0 means lldb
560  // will fetch the mangled name and compute the hash in
561  // ParseClassInfoArray.
562  if (c == '.')
563  {
564  h = 0;
565  break;
566  }
567  h = ((h << 5) + h) + c;
568  }
569  class_infos[idx].hash = h;
570  }
571  }
572  }
573  else if (objc_opt->version >= 12 && objc_opt->version <= 15)
574  {
575  const objc_clsopt_t* clsopt = NULL;
576  if (objc_opt->version >= 14)
577  clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt_v14 + objc_opt_v14->clsopt_offset);
578  else
579  clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
580  const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
581  DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
582  ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
583  int32_t invalidEntryOffset = 0;
584  // this is safe to do because the version field order is invariant
585  if (objc_opt->version == 12)
586  invalidEntryOffset = 16;
587  const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
588  const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
589  const objc_classheader_t *classOffsets = (const objc_classheader_t *)(offsets + clsopt->capacity);
590  DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
591  DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
592  DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
593  DEBUG_PRINTF("invalidEntryOffset = %d\n", invalidEntryOffset);
594  for (uint32_t i=0; i<clsopt->capacity; ++i)
595  {
596  const int32_t clsOffset = classOffsets[i].clsOffset;
597  DEBUG_PRINTF("clsOffset[%u] = %u\n", i, clsOffset);
598  if (clsOffset & 1)
599  {
600  DEBUG_PRINTF("clsOffset & 1\n");
601  continue; // duplicate
602  }
603  else if (clsOffset == invalidEntryOffset)
604  {
605  DEBUG_PRINTF("clsOffset == invalidEntryOffset\n");
606  continue; // invalid offset
607  }
608 
609  if (class_infos && idx < max_class_infos)
610  {
611  class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
612  const char *name = class_name_lookup_func (class_infos[idx].isa);
613  DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
614  // Hash the class name so we don't have to read it
615  const char *s = name;
616  uint32_t h = 5381;
617  for (unsigned char c = *s; c; c = *++s)
618  {
619  // class_getName demangles swift names and the hash must
620  // be calculated on the mangled name. hash==0 means lldb
621  // will fetch the mangled name and compute the hash in
622  // ParseClassInfoArray.
623  if (c == '.')
624  {
625  h = 0;
626  break;
627  }
628  h = ((h << 5) + h) + c;
629  }
630  class_infos[idx].hash = h;
631  }
632  else
633  {
634  DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
635  }
636  ++idx;
637  }
638 
639  const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
640  const uint32_t duplicate_count = *duplicate_count_ptr;
641  const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);
642  DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
643  DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
644  for (uint32_t i=0; i<duplicate_count; ++i)
645  {
646  const int32_t clsOffset = duplicateClassOffsets[i].clsOffset;
647  if (clsOffset & 1)
648  continue; // duplicate
649  else if (clsOffset == invalidEntryOffset)
650  continue; // invalid offset
651 
652  if (class_infos && idx < max_class_infos)
653  {
654  class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
655  const char *name = class_name_lookup_func (class_infos[idx].isa);
656  DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
657  // Hash the class name so we don't have to read it
658  const char *s = name;
659  uint32_t h = 5381;
660  for (unsigned char c = *s; c; c = *++s)
661  {
662  // class_getName demangles swift names and the hash must
663  // be calculated on the mangled name. hash==0 means lldb
664  // will fetch the mangled name and compute the hash in
665  // ParseClassInfoArray.
666  if (c == '.')
667  {
668  h = 0;
669  break;
670  }
671  h = ((h << 5) + h) + c;
672  }
673  class_infos[idx].hash = h;
674  }
675  ++idx;
676  }
677  }
678  DEBUG_PRINTF ("%u class_infos\n", idx);
679  DEBUG_PRINTF ("done\n");
680  }
681  return idx;
682 }
683 
684 
685 )";
686 
687 static uint64_t
689  const ModuleSP &module_sp, Status &error,
690  bool read_value = true, uint8_t byte_size = 0,
691  uint64_t default_value = LLDB_INVALID_ADDRESS,
692  SymbolType sym_type = lldb::eSymbolTypeData) {
693  if (!process) {
694  error.SetErrorString("no process");
695  return default_value;
696  }
697 
698  if (!module_sp) {
699  error.SetErrorString("no module");
700  return default_value;
701  }
702 
703  if (!byte_size)
704  byte_size = process->GetAddressByteSize();
705  const Symbol *symbol =
706  module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
707 
708  if (!symbol || !symbol->ValueIsAddress()) {
709  error.SetErrorString("no symbol");
710  return default_value;
711  }
712 
713  lldb::addr_t symbol_load_addr =
714  symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
715  if (symbol_load_addr == LLDB_INVALID_ADDRESS) {
716  error.SetErrorString("symbol address invalid");
717  return default_value;
718  }
719 
720  if (read_value)
721  return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size,
722  default_value, error);
723  return symbol_load_addr;
724 }
725 
726 static void RegisterObjCExceptionRecognizer(Process *process);
727 
728 AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
729  const ModuleSP &objc_module_sp)
730  : AppleObjCRuntime(process), m_objc_module_sp(objc_module_sp),
731  m_dynamic_class_info_extractor(*this),
732  m_shared_cache_class_info_extractor(*this), m_decl_vendor_up(),
733  m_tagged_pointer_obfuscator(LLDB_INVALID_ADDRESS),
734  m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
735  m_relative_selector_base(LLDB_INVALID_ADDRESS), m_hash_signature(),
736  m_has_object_getClass(false), m_has_objc_copyRealizedClassList(false),
737  m_has_objc_getRealizedClassList_trylock(false), m_loaded_objc_opt(false),
738  m_non_pointer_isa_cache_up(),
739  m_tagged_pointer_vendor_up(
740  TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
741  m_encoding_to_type_sp(), m_CFBoolean_values(),
742  m_realized_class_generation_count(0) {
743  static const ConstString g_gdb_object_getClass("gdb_object_getClass");
744  m_has_object_getClass = HasSymbol(g_gdb_object_getClass);
745  static const ConstString g_objc_copyRealizedClassList(
746  "_ZL33objc_copyRealizedClassList_nolockPj");
747  static const ConstString g_objc_getRealizedClassList_trylock(
748  "_objc_getRealizedClassList_trylock");
749  m_has_objc_copyRealizedClassList = HasSymbol(g_objc_copyRealizedClassList);
751  HasSymbol(g_objc_getRealizedClassList_trylock);
754 }
755 
757  ValueObject &in_value, lldb::DynamicValueType use_dynamic,
758  TypeAndOrName &class_type_or_name, Address &address,
759  Value::ValueType &value_type) {
760  // We should never get here with a null process...
761  assert(m_process != nullptr);
762 
763  // The Runtime is attached to a particular process, you shouldn't pass in a
764  // value from another process. Note, however, the process might be NULL (e.g.
765  // if the value was made with SBTarget::EvaluateExpression...) in which case
766  // it is sufficient if the target's match:
767 
768  Process *process = in_value.GetProcessSP().get();
769  if (process)
770  assert(process == m_process);
771  else
772  assert(in_value.GetTargetSP().get() == m_process->CalculateTarget().get());
773 
774  class_type_or_name.Clear();
775  value_type = Value::ValueType::Scalar;
776 
777  // Make sure we can have a dynamic value before starting...
778  if (CouldHaveDynamicValue(in_value)) {
779  // First job, pull out the address at 0 offset from the object That will
780  // be the ISA pointer.
781  ClassDescriptorSP objc_class_sp(GetNonKVOClassDescriptor(in_value));
782  if (objc_class_sp) {
783  const addr_t object_ptr = in_value.GetPointerValue();
784  address.SetRawAddress(object_ptr);
785 
786  ConstString class_name(objc_class_sp->GetClassName());
787  class_type_or_name.SetName(class_name);
788  TypeSP type_sp(objc_class_sp->GetType());
789  if (type_sp)
790  class_type_or_name.SetTypeSP(type_sp);
791  else {
792  type_sp = LookupInCompleteClassCache(class_name);
793  if (type_sp) {
794  objc_class_sp->SetType(type_sp);
795  class_type_or_name.SetTypeSP(type_sp);
796  } else {
797  // try to go for a CompilerType at least
798  if (auto *vendor = GetDeclVendor()) {
799  auto types = vendor->FindTypes(class_name, /*max_matches*/ 1);
800  if (!types.empty())
801  class_type_or_name.SetCompilerType(types.front());
802  }
803  }
804  }
805  }
806  }
807  return !class_type_or_name.IsEmpty();
808 }
809 
810 // Static Functions
812  LanguageType language) {
813  // FIXME: This should be a MacOS or iOS process, and we need to look for the
814  // OBJC section to make
815  // sure we aren't using the V1 runtime.
816  if (language == eLanguageTypeObjC) {
817  ModuleSP objc_module_sp;
818 
819  if (AppleObjCRuntime::GetObjCVersion(process, objc_module_sp) ==
821  return new AppleObjCRuntimeV2(process, objc_module_sp);
822  return nullptr;
823  }
824  return nullptr;
825 }
826 
829  false,
830  "verbose",
831  'v',
833  nullptr,
834  {},
835  0,
836  eArgTypeNone,
837  "Print ivar and method information in detail"}};
838 
840 public:
841  class CommandOptions : public Options {
842  public:
843  CommandOptions() : Options(), m_verbose(false, false) {}
844 
845  ~CommandOptions() override = default;
846 
847  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
848  ExecutionContext *execution_context) override {
849  Status error;
850  const int short_option = m_getopt_table[option_idx].val;
851  switch (short_option) {
852  case 'v':
853  m_verbose.SetCurrentValue(true);
854  m_verbose.SetOptionWasSet();
855  break;
856 
857  default:
858  error.SetErrorStringWithFormat("unrecognized short option '%c'",
859  short_option);
860  break;
861  }
862 
863  return error;
864  }
865 
866  void OptionParsingStarting(ExecutionContext *execution_context) override {
867  m_verbose.Clear();
868  }
869 
870  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
871  return llvm::makeArrayRef(g_objc_classtable_dump_options);
872  }
873 
875  };
876 
878  : CommandObjectParsed(interpreter, "dump",
879  "Dump information on Objective-C classes "
880  "known to the current process.",
881  "language objc class-table dump",
882  eCommandRequiresProcess |
883  eCommandProcessMustBeLaunched |
884  eCommandProcessMustBePaused),
885  m_options() {
887  CommandArgumentData index_arg;
888 
889  // Define the first (and only) variant of this arg.
892 
893  // There is only one variant this argument could be; put it into the
894  // argument entry.
895  arg.push_back(index_arg);
896 
897  // Push the data for the first argument into the m_arguments vector.
898  m_arguments.push_back(arg);
899  }
900 
901  ~CommandObjectObjC_ClassTable_Dump() override = default;
902 
903  Options *GetOptions() override { return &m_options; }
904 
905 protected:
906  bool DoExecute(Args &command, CommandReturnObject &result) override {
907  std::unique_ptr<RegularExpression> regex_up;
908  switch (command.GetArgumentCount()) {
909  case 0:
910  break;
911  case 1: {
912  regex_up =
913  std::make_unique<RegularExpression>(command.GetArgumentAtIndex(0));
914  if (!regex_up->IsValid()) {
915  result.AppendError(
916  "invalid argument - please provide a valid regular expression");
918  return false;
919  }
920  break;
921  }
922  default: {
923  result.AppendError("please provide 0 or 1 arguments");
925  return false;
926  }
927  }
928 
929  Process *process = m_exe_ctx.GetProcessPtr();
930  ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
931  if (objc_runtime) {
932  auto iterators_pair = objc_runtime->GetDescriptorIteratorPair();
933  auto iterator = iterators_pair.first;
934  auto &std_out = result.GetOutputStream();
935  for (; iterator != iterators_pair.second; iterator++) {
936  if (iterator->second) {
937  const char *class_name =
938  iterator->second->GetClassName().AsCString("<unknown>");
939  if (regex_up && class_name &&
940  !regex_up->Execute(llvm::StringRef(class_name)))
941  continue;
942  std_out.Printf("isa = 0x%" PRIx64, iterator->first);
943  std_out.Printf(" name = %s", class_name);
944  std_out.Printf(" instance size = %" PRIu64,
945  iterator->second->GetInstanceSize());
946  std_out.Printf(" num ivars = %" PRIuPTR,
947  (uintptr_t)iterator->second->GetNumIVars());
948  if (auto superclass = iterator->second->GetSuperclass()) {
949  std_out.Printf(" superclass = %s",
950  superclass->GetClassName().AsCString("<unknown>"));
951  }
952  std_out.Printf("\n");
953  if (m_options.m_verbose) {
954  for (size_t i = 0; i < iterator->second->GetNumIVars(); i++) {
955  auto ivar = iterator->second->GetIVarAtIndex(i);
956  std_out.Printf(
957  " ivar name = %s type = %s size = %" PRIu64
958  " offset = %" PRId32 "\n",
959  ivar.m_name.AsCString("<unknown>"),
960  ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
961  ivar.m_size, ivar.m_offset);
962  }
963 
964  iterator->second->Describe(
965  nullptr,
966  [&std_out](const char *name, const char *type) -> bool {
967  std_out.Printf(" instance method name = %s type = %s\n",
968  name, type);
969  return false;
970  },
971  [&std_out](const char *name, const char *type) -> bool {
972  std_out.Printf(" class method name = %s type = %s\n", name,
973  type);
974  return false;
975  },
976  nullptr);
977  }
978  } else {
979  if (regex_up && !regex_up->Execute(llvm::StringRef()))
980  continue;
981  std_out.Printf("isa = 0x%" PRIx64 " has no associated class.\n",
982  iterator->first);
983  }
984  }
986  return true;
987  }
988  result.AppendError("current process has no Objective-C runtime loaded");
990  return false;
991  }
992 
994 };
995 
997  : public CommandObjectParsed {
998 public:
1001  interpreter, "info", "Dump information on a tagged pointer.",
1002  "language objc tagged-pointer info",
1003  eCommandRequiresProcess | eCommandProcessMustBeLaunched |
1004  eCommandProcessMustBePaused) {
1006  CommandArgumentData index_arg;
1007 
1008  // Define the first (and only) variant of this arg.
1009  index_arg.arg_type = eArgTypeAddress;
1010  index_arg.arg_repetition = eArgRepeatPlus;
1011 
1012  // There is only one variant this argument could be; put it into the
1013  // argument entry.
1014  arg.push_back(index_arg);
1015 
1016  // Push the data for the first argument into the m_arguments vector.
1017  m_arguments.push_back(arg);
1018  }
1019 
1020  ~CommandObjectMultiwordObjC_TaggedPointer_Info() override = default;
1021 
1022 protected:
1023  bool DoExecute(Args &command, CommandReturnObject &result) override {
1024  if (command.GetArgumentCount() == 0) {
1025  result.AppendError("this command requires arguments");
1027  return false;
1028  }
1029 
1030  Process *process = m_exe_ctx.GetProcessPtr();
1031  ExecutionContext exe_ctx(process);
1032 
1033  ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
1034  if (!objc_runtime) {
1035  result.AppendError("current process has no Objective-C runtime loaded");
1037  return false;
1038  }
1039 
1040  ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor =
1041  objc_runtime->GetTaggedPointerVendor();
1042  if (!tagged_ptr_vendor) {
1043  result.AppendError("current process has no tagged pointer support");
1045  return false;
1046  }
1047 
1048  for (size_t i = 0; i < command.GetArgumentCount(); i++) {
1049  const char *arg_str = command.GetArgumentAtIndex(i);
1050  if (!arg_str)
1051  continue;
1052 
1053  Status error;
1055  &exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error);
1056  if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
1057  result.AppendErrorWithFormatv(
1058  "could not convert '{0}' to a valid address\n", arg_str);
1060  return false;
1061  }
1062 
1063  if (!tagged_ptr_vendor->IsPossibleTaggedPointer(arg_addr)) {
1064  result.GetOutputStream().Format("{0:x16} is not tagged\n", arg_addr);
1065  continue;
1066  }
1067 
1068  auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr);
1069  if (!descriptor_sp) {
1070  result.AppendErrorWithFormatv(
1071  "could not get class descriptor for {0:x16}\n", arg_addr);
1073  return false;
1074  }
1075 
1076  uint64_t info_bits = 0;
1077  uint64_t value_bits = 0;
1078  uint64_t payload = 0;
1079  if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits,
1080  &payload)) {
1081  result.GetOutputStream().Format(
1082  "{0:x} is tagged\n"
1083  "\tpayload = {1:x16}\n"
1084  "\tvalue = {2:x16}\n"
1085  "\tinfo bits = {3:x16}\n"
1086  "\tclass = {4}\n",
1087  arg_addr, payload, value_bits, info_bits,
1088  descriptor_sp->GetClassName().AsCString("<unknown>"));
1089  } else {
1090  result.GetOutputStream().Format("{0:x16} is not tagged\n", arg_addr);
1091  }
1092  }
1093 
1095  return true;
1096  }
1097 };
1098 
1100 public:
1103  interpreter, "class-table",
1104  "Commands for operating on the Objective-C class table.",
1105  "class-table <subcommand> [<subcommand-options>]") {
1106  LoadSubCommand(
1107  "dump",
1108  CommandObjectSP(new CommandObjectObjC_ClassTable_Dump(interpreter)));
1109  }
1110 
1111  ~CommandObjectMultiwordObjC_ClassTable() override = default;
1112 };
1113 
1115 public:
1118  interpreter, "tagged-pointer",
1119  "Commands for operating on Objective-C tagged pointers.",
1120  "class-table <subcommand> [<subcommand-options>]") {
1121  LoadSubCommand(
1122  "info",
1123  CommandObjectSP(
1125  }
1126 
1127  ~CommandObjectMultiwordObjC_TaggedPointer() override = default;
1128 };
1129 
1131 public:
1134  interpreter, "objc",
1135  "Commands for operating on the Objective-C language runtime.",
1136  "objc <subcommand> [<subcommand-options>]") {
1137  LoadSubCommand("class-table",
1138  CommandObjectSP(
1139  new CommandObjectMultiwordObjC_ClassTable(interpreter)));
1140  LoadSubCommand("tagged-pointer",
1141  CommandObjectSP(new CommandObjectMultiwordObjC_TaggedPointer(
1142  interpreter)));
1143  }
1144 
1145  ~CommandObjectMultiwordObjC() override = default;
1146 };
1147 
1150  GetPluginNameStatic(), "Apple Objective-C Language Runtime - Version 2",
1152  [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
1153  return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
1154  },
1156 }
1157 
1160 }
1161 
1162 BreakpointResolverSP
1164  bool catch_bp, bool throw_bp) {
1165  BreakpointResolverSP resolver_sp;
1166 
1167  if (throw_bp)
1168  resolver_sp = std::make_shared<BreakpointResolverName>(
1169  bkpt, std::get<1>(GetExceptionThrowLocation()).AsCString(),
1170  eFunctionNameTypeBase, eLanguageTypeUnknown, Breakpoint::Exact, 0,
1171  eLazyBoolNo);
1172  // FIXME: We don't do catch breakpoints for ObjC yet.
1173  // Should there be some way for the runtime to specify what it can do in this
1174  // regard?
1175  return resolver_sp;
1176 }
1177 
1178 llvm::Expected<std::unique_ptr<UtilityFunction>>
1180  ExecutionContext &exe_ctx) {
1181  char check_function_code[2048];
1182 
1183  int len = 0;
1184  if (m_has_object_getClass) {
1185  len = ::snprintf(check_function_code, sizeof(check_function_code), R"(
1186  extern "C" void *gdb_object_getClass(void *);
1187  extern "C" int printf(const char *format, ...);
1188  extern "C" void
1189  %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) {
1190  if ($__lldb_arg_obj == (void *)0)
1191  return; // nil is ok
1192  if (!gdb_object_getClass($__lldb_arg_obj)) {
1193  *((volatile int *)0) = 'ocgc';
1194  } else if ($__lldb_arg_selector != (void *)0) {
1195  signed char $responds = (signed char)
1196  [(id)$__lldb_arg_obj respondsToSelector:
1197  (void *) $__lldb_arg_selector];
1198  if ($responds == (signed char) 0)
1199  *((volatile int *)0) = 'ocgc';
1200  }
1201  })",
1202  name.c_str());
1203  } else {
1204  len = ::snprintf(check_function_code, sizeof(check_function_code), R"(
1205  extern "C" void *gdb_class_getClass(void *);
1206  extern "C" int printf(const char *format, ...);
1207  extern "C" void
1208  %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) {
1209  if ($__lldb_arg_obj == (void *)0)
1210  return; // nil is ok
1211  void **$isa_ptr = (void **)$__lldb_arg_obj;
1212  if (*$isa_ptr == (void *)0 ||
1213  !gdb_class_getClass(*$isa_ptr))
1214  *((volatile int *)0) = 'ocgc';
1215  else if ($__lldb_arg_selector != (void *)0) {
1216  signed char $responds = (signed char)
1217  [(id)$__lldb_arg_obj respondsToSelector:
1218  (void *) $__lldb_arg_selector];
1219  if ($responds == (signed char) 0)
1220  *((volatile int *)0) = 'ocgc';
1221  }
1222  })",
1223  name.c_str());
1224  }
1225 
1226  assert(len < (int)sizeof(check_function_code));
1228 
1229  return GetTargetRef().CreateUtilityFunction(check_function_code, name,
1230  eLanguageTypeC, exe_ctx);
1231 }
1232 
1234  const char *ivar_name) {
1235  uint32_t ivar_offset = LLDB_INVALID_IVAR_OFFSET;
1236 
1237  ConstString class_name = parent_ast_type.GetTypeName();
1238  if (!class_name.IsEmpty() && ivar_name && ivar_name[0]) {
1239  // Make the objective C V2 mangled name for the ivar offset from the class
1240  // name and ivar name
1241  std::string buffer("OBJC_IVAR_$_");
1242  buffer.append(class_name.AsCString());
1243  buffer.push_back('.');
1244  buffer.append(ivar_name);
1245  ConstString ivar_const_str(buffer.c_str());
1246 
1247  // Try to get the ivar offset address from the symbol table first using the
1248  // name we created above
1249  SymbolContextList sc_list;
1250  Target &target = m_process->GetTarget();
1251  target.GetImages().FindSymbolsWithNameAndType(ivar_const_str,
1252  eSymbolTypeObjCIVar, sc_list);
1253 
1254  addr_t ivar_offset_address = LLDB_INVALID_ADDRESS;
1255 
1256  Status error;
1257  SymbolContext ivar_offset_symbol;
1258  if (sc_list.GetSize() == 1 &&
1259  sc_list.GetContextAtIndex(0, ivar_offset_symbol)) {
1260  if (ivar_offset_symbol.symbol)
1261  ivar_offset_address =
1262  ivar_offset_symbol.symbol->GetLoadAddress(&target);
1263  }
1264 
1265  // If we didn't get the ivar offset address from the symbol table, fall
1266  // back to getting it from the runtime
1267  if (ivar_offset_address == LLDB_INVALID_ADDRESS)
1268  ivar_offset_address = LookupRuntimeSymbol(ivar_const_str);
1269 
1270  if (ivar_offset_address != LLDB_INVALID_ADDRESS)
1272  ivar_offset_address, 4, LLDB_INVALID_IVAR_OFFSET, error);
1273  }
1274  return ivar_offset;
1275 }
1276 
1277 // tagged pointers are special not-a-real-pointer values that contain both type
1278 // and value information this routine attempts to check with as little
1279 // computational effort as possible whether something could possibly be a
1280 // tagged pointer - false positives are possible but false negatives shouldn't
1283  return false;
1284  return m_tagged_pointer_vendor_up->IsPossibleTaggedPointer(ptr);
1285 }
1286 
1288 public:
1289  RemoteNXMapTable() : m_end_iterator(*this, -1) {}
1290 
1291  void Dump() {
1292  printf("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
1293  printf("RemoteNXMapTable.m_count = %u\n", m_count);
1294  printf("RemoteNXMapTable.m_num_buckets_minus_one = %u\n",
1295  m_num_buckets_minus_one);
1296  printf("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
1297  }
1298 
1299  bool ParseHeader(Process *process, lldb::addr_t load_addr) {
1300  m_process = process;
1301  m_load_addr = load_addr;
1302  m_map_pair_size = m_process->GetAddressByteSize() * 2;
1303  m_invalid_key =
1304  m_process->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX;
1305  Status err;
1306 
1307  // This currently holds true for all platforms we support, but we might
1308  // need to change this to use get the actually byte size of "unsigned" from
1309  // the target AST...
1310  const uint32_t unsigned_byte_size = sizeof(uint32_t);
1311  // Skip the prototype as we don't need it (const struct
1312  // +NXMapTablePrototype *prototype)
1313 
1314  bool success = true;
1315  if (load_addr == LLDB_INVALID_ADDRESS)
1316  success = false;
1317  else {
1318  lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
1319 
1320  // unsigned count;
1321  m_count = m_process->ReadUnsignedIntegerFromMemory(
1322  cursor, unsigned_byte_size, 0, err);
1323  if (m_count) {
1324  cursor += unsigned_byte_size;
1325 
1326  // unsigned nbBucketsMinusOne;
1327  m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(
1328  cursor, unsigned_byte_size, 0, err);
1329  cursor += unsigned_byte_size;
1330 
1331  // void *buckets;
1332  m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
1333 
1334  success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
1335  }
1336  }
1337 
1338  if (!success) {
1339  m_count = 0;
1340  m_num_buckets_minus_one = 0;
1341  m_buckets_ptr = LLDB_INVALID_ADDRESS;
1342  }
1343  return success;
1344  }
1345 
1346  // const_iterator mimics NXMapState and its code comes from NXInitMapState
1347  // and NXNextMapState.
1348  typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA> element;
1349 
1350  friend class const_iterator;
1352  public:
1353  const_iterator(RemoteNXMapTable &parent, int index)
1354  : m_parent(parent), m_index(index) {
1355  AdvanceToValidIndex();
1356  }
1357 
1359  : m_parent(rhs.m_parent), m_index(rhs.m_index) {
1360  // AdvanceToValidIndex() has been called by rhs already.
1361  }
1362 
1364  // AdvanceToValidIndex() has been called by rhs already.
1365  assert(&m_parent == &rhs.m_parent);
1366  m_index = rhs.m_index;
1367  return *this;
1368  }
1369 
1370  bool operator==(const const_iterator &rhs) const {
1371  if (&m_parent != &rhs.m_parent)
1372  return false;
1373  if (m_index != rhs.m_index)
1374  return false;
1375 
1376  return true;
1377  }
1378 
1379  bool operator!=(const const_iterator &rhs) const {
1380  return !(operator==(rhs));
1381  }
1382 
1384  AdvanceToValidIndex();
1385  return *this;
1386  }
1387 
1388  const element operator*() const {
1389  if (m_index == -1) {
1390  // TODO find a way to make this an error, but not an assert
1391  return element();
1392  }
1393 
1394  lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
1395  size_t map_pair_size = m_parent.m_map_pair_size;
1396  lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
1397 
1398  Status err;
1399 
1400  lldb::addr_t key =
1401  m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
1402  if (!err.Success())
1403  return element();
1404  lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(
1405  pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
1406  if (!err.Success())
1407  return element();
1408 
1409  std::string key_string;
1410 
1411  m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
1412  if (!err.Success())
1413  return element();
1414 
1415  return element(ConstString(key_string.c_str()),
1417  }
1418 
1419  private:
1421  if (m_index == -1)
1422  return;
1423 
1424  const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
1425  const size_t map_pair_size = m_parent.m_map_pair_size;
1426  const lldb::addr_t invalid_key = m_parent.m_invalid_key;
1427  Status err;
1428 
1429  while (m_index--) {
1430  lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
1431  lldb::addr_t key =
1432  m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
1433 
1434  if (!err.Success()) {
1435  m_index = -1;
1436  return;
1437  }
1438 
1439  if (key != invalid_key)
1440  return;
1441  }
1442  }
1444  int m_index;
1445  };
1446 
1448  return const_iterator(*this, m_num_buckets_minus_one + 1);
1449  }
1450 
1451  const_iterator end() { return m_end_iterator; }
1452 
1453  uint32_t GetCount() const { return m_count; }
1454 
1455  uint32_t GetBucketCount() const { return m_num_buckets_minus_one; }
1456 
1457  lldb::addr_t GetBucketDataPointer() const { return m_buckets_ptr; }
1458 
1459  lldb::addr_t GetTableLoadAddress() const { return m_load_addr; }
1460 
1461 private:
1462  // contents of _NXMapTable struct
1463  uint32_t m_count = 0;
1464  uint32_t m_num_buckets_minus_one = 0;
1466  lldb_private::Process *m_process = nullptr;
1469  size_t m_map_pair_size = 0;
1470  lldb::addr_t m_invalid_key = 0;
1471 };
1472 
1474 
1476  const RemoteNXMapTable &hash_table) {
1477  m_count = hash_table.GetCount();
1478  m_num_buckets = hash_table.GetBucketCount();
1479  m_buckets_ptr = hash_table.GetBucketDataPointer();
1480 }
1481 
1483  Process *process, AppleObjCRuntimeV2 *runtime,
1484  RemoteNXMapTable &hash_table) {
1485  if (!hash_table.ParseHeader(process, runtime->GetISAHashTablePointer())) {
1486  return false; // Failed to parse the header, no need to update anything
1487  }
1488 
1489  // Check with out current signature and return true if the count, number of
1490  // buckets or the hash table address changes.
1491  if (m_count == hash_table.GetCount() &&
1492  m_num_buckets == hash_table.GetBucketCount() &&
1493  m_buckets_ptr == hash_table.GetBucketDataPointer()) {
1494  // Hash table hasn't changed
1495  return false;
1496  }
1497  // Hash table data has changed, we need to update
1498  return true;
1499 }
1500 
1503  ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
1504  if (auto *non_pointer_isa_cache = GetNonPointerIsaCache())
1505  class_descriptor_sp = non_pointer_isa_cache->GetClassDescriptor(isa);
1506  if (!class_descriptor_sp)
1507  class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
1508  return class_descriptor_sp;
1509 }
1510 
1513  ClassDescriptorSP objc_class_sp;
1514  if (valobj.IsBaseClass()) {
1515  ValueObject *parent = valobj.GetParent();
1516  // if I am my own parent, bail out of here fast..
1517  if (parent && parent != &valobj) {
1518  ClassDescriptorSP parent_descriptor_sp = GetClassDescriptor(*parent);
1519  if (parent_descriptor_sp)
1520  return parent_descriptor_sp->GetSuperclass();
1521  }
1522  return nullptr;
1523  }
1524  // if we get an invalid VO (which might still happen when playing around with
1525  // pointers returned by the expression parser, don't consider this a valid
1526  // ObjC object)
1527  if (!valobj.GetCompilerType().IsValid())
1528  return objc_class_sp;
1529  addr_t isa_pointer = valobj.GetPointerValue();
1530 
1531  // tagged pointer
1532  if (IsTaggedPointer(isa_pointer))
1533  return m_tagged_pointer_vendor_up->GetClassDescriptor(isa_pointer);
1534  ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
1535 
1536  Process *process = exe_ctx.GetProcessPtr();
1537  if (!process)
1538  return objc_class_sp;
1539 
1540  Status error;
1541  ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
1542  if (isa == LLDB_INVALID_ADDRESS)
1543  return objc_class_sp;
1544 
1545  objc_class_sp = GetClassDescriptorFromISA(isa);
1546  if (!objc_class_sp) {
1547  if (ABISP abi_sp = process->GetABI())
1548  isa = abi_sp->FixCodeAddress(isa);
1549  objc_class_sp = GetClassDescriptorFromISA(isa);
1550  }
1551 
1552  if (isa && !objc_class_sp) {
1554  LLDB_LOGF(log,
1555  "0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
1556  "not in class descriptor cache 0x%" PRIx64,
1557  isa_pointer, isa);
1558  }
1559  return objc_class_sp;
1560 }
1561 
1565 
1566  Process *process = GetProcess();
1567  ModuleSP objc_module_sp(GetObjCModule());
1568 
1569  if (!objc_module_sp)
1570  return LLDB_INVALID_ADDRESS;
1571 
1572  static ConstString g_gdb_objc_obfuscator(
1573  "objc_debug_taggedpointer_obfuscator");
1574 
1575  const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
1576  g_gdb_objc_obfuscator, lldb::eSymbolTypeAny);
1577  if (symbol) {
1578  lldb::addr_t g_gdb_obj_obfuscator_ptr =
1579  symbol->GetLoadAddress(&process->GetTarget());
1580 
1581  if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS) {
1582  Status error;
1584  process->ReadPointerFromMemory(g_gdb_obj_obfuscator_ptr, error);
1585  }
1586  }
1587  // If we don't have a correct value at this point, there must be no
1588  // obfuscation.
1591 
1593 }
1594 
1597  Process *process = GetProcess();
1598 
1599  ModuleSP objc_module_sp(GetObjCModule());
1600 
1601  if (!objc_module_sp)
1602  return LLDB_INVALID_ADDRESS;
1603 
1604  static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
1605 
1606  const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
1607  g_gdb_objc_realized_classes, lldb::eSymbolTypeAny);
1608  if (symbol) {
1609  lldb::addr_t gdb_objc_realized_classes_ptr =
1610  symbol->GetLoadAddress(&process->GetTarget());
1611 
1612  if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS) {
1613  Status error;
1615  gdb_objc_realized_classes_ptr, error);
1616  }
1617  }
1618  }
1619  return m_isa_hash_table_ptr;
1620 }
1621 
1622 std::unique_ptr<UtilityFunction>
1624  ExecutionContext &exe_ctx, Helper helper, std::string code,
1625  std::string name) {
1627 
1628  LLDB_LOG(log, "Creating utility function {0}", name);
1629 
1630  TypeSystemClang *ast =
1632  if (!ast)
1633  return {};
1634 
1635  auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
1636  std::move(code), std::move(name), eLanguageTypeC, exe_ctx);
1637  if (!utility_fn_or_error) {
1639  log, utility_fn_or_error.takeError(),
1640  "Failed to get utility function for dynamic info extractor: {0}");
1641  return {};
1642  }
1643 
1644  // Make some types for our arguments.
1645  CompilerType clang_uint32_t_type =
1647  CompilerType clang_void_pointer_type =
1649 
1650  // Make the runner function for our implementation utility function.
1651  ValueList arguments;
1652  Value value;
1654  value.SetCompilerType(clang_void_pointer_type);
1655  arguments.PushValue(value);
1656  arguments.PushValue(value);
1658  value.SetCompilerType(clang_uint32_t_type);
1659  arguments.PushValue(value);
1660 
1661  // objc_getRealizedClassList_trylock takes an additional buffer and length.
1662  if (helper == Helper::objc_getRealizedClassList_trylock) {
1663  value.SetCompilerType(clang_void_pointer_type);
1664  arguments.PushValue(value);
1665  value.SetCompilerType(clang_uint32_t_type);
1666  arguments.PushValue(value);
1667  }
1668 
1669  arguments.PushValue(value);
1670 
1671  std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
1672 
1673  Status error;
1674  utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
1675  exe_ctx.GetThreadSP(), error);
1676 
1677  if (error.Fail()) {
1678  LLDB_LOG(log,
1679  "Failed to make function caller for implementation lookup: {0}.",
1680  error.AsCString());
1681  return {};
1682  }
1683 
1684  return utility_fn;
1685 }
1686 
1689  ExecutionContext &exe_ctx, Helper helper) {
1690  switch (helper) {
1691  case gdb_objc_realized_classes: {
1692  if (!m_gdb_objc_realized_classes_helper.utility_function)
1693  m_gdb_objc_realized_classes_helper.utility_function =
1694  GetClassInfoUtilityFunctionImpl(exe_ctx, helper,
1697  return m_gdb_objc_realized_classes_helper.utility_function.get();
1698  }
1699  case objc_copyRealizedClassList: {
1700  if (!m_objc_copyRealizedClassList_helper.utility_function)
1701  m_objc_copyRealizedClassList_helper.utility_function =
1702  GetClassInfoUtilityFunctionImpl(exe_ctx, helper,
1705  return m_objc_copyRealizedClassList_helper.utility_function.get();
1706  }
1707  case objc_getRealizedClassList_trylock: {
1708  if (!m_objc_getRealizedClassList_trylock_helper.utility_function)
1709  m_objc_getRealizedClassList_trylock_helper.utility_function =
1710  GetClassInfoUtilityFunctionImpl(exe_ctx, helper,
1713  return m_objc_getRealizedClassList_trylock_helper.utility_function.get();
1714  }
1715  }
1716  llvm_unreachable("Unexpected helper");
1717 }
1718 
1719 lldb::addr_t &
1721  switch (helper) {
1722  case gdb_objc_realized_classes:
1723  return m_gdb_objc_realized_classes_helper.args;
1724  case objc_copyRealizedClassList:
1725  return m_objc_copyRealizedClassList_helper.args;
1726  case objc_getRealizedClassList_trylock:
1727  return m_objc_getRealizedClassList_trylock_helper.args;
1728  }
1729  llvm_unreachable("Unexpected helper");
1730 }
1731 
1734  ExecutionContext &exe_ctx) const {
1735  if (!m_runtime.m_has_objc_copyRealizedClassList &&
1736  !m_runtime.m_has_objc_getRealizedClassList_trylock)
1738 
1739  if (Process *process = m_runtime.GetProcess()) {
1740  if (DynamicLoader *loader = process->GetDynamicLoader()) {
1741  if (loader->IsFullyInitialized()) {
1742  switch (exe_ctx.GetTargetRef().GetDynamicClassInfoHelper()) {
1744  [[clang::fallthrough]];
1746  if (m_runtime.m_has_objc_getRealizedClassList_trylock)
1748  [[clang::fallthrough]];
1750  if (m_runtime.m_has_objc_copyRealizedClassList)
1752  [[clang::fallthrough]];
1755  }
1756  }
1757  }
1758  }
1759 
1761 }
1762 
1763 std::unique_ptr<UtilityFunction>
1767 
1768  LLDB_LOG(log, "Creating utility function {0}",
1770 
1771  TypeSystemClang *ast =
1773  if (!ast)
1774  return {};
1775 
1776  // If the inferior objc.dylib has the class_getNameRaw function, use that in
1777  // our jitted expression. Else fall back to the old class_getName.
1778  static ConstString g_class_getName_symbol_name("class_getName");
1779  static ConstString g_class_getNameRaw_symbol_name(
1780  "objc_debug_class_getNameRaw");
1781 
1782  ConstString class_name_getter_function_name =
1783  m_runtime.HasSymbol(g_class_getNameRaw_symbol_name)
1784  ? g_class_getNameRaw_symbol_name
1785  : g_class_getName_symbol_name;
1786 
1787  // Substitute in the correct class_getName / class_getNameRaw function name,
1788  // concatenate the two parts of our expression text. The format string has
1789  // two %s's, so provide the name twice.
1790  std::string shared_class_expression;
1791  llvm::raw_string_ostream(shared_class_expression)
1792  << llvm::format(g_shared_cache_class_name_funcptr,
1793  class_name_getter_function_name.AsCString(),
1794  class_name_getter_function_name.AsCString());
1795 
1796  shared_class_expression += g_get_shared_cache_class_info_body;
1797 
1798  auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
1799  std::move(shared_class_expression), g_get_shared_cache_class_info_name,
1800  eLanguageTypeC, exe_ctx);
1801 
1802  if (!utility_fn_or_error) {
1804  log, utility_fn_or_error.takeError(),
1805  "Failed to get utility function for shared class info extractor: {0}");
1806  return nullptr;
1807  }
1808 
1809  // Make some types for our arguments.
1810  CompilerType clang_uint32_t_type =
1812  CompilerType clang_void_pointer_type =
1814  CompilerType clang_uint64_t_pointer_type =
1816  .GetPointerType();
1817 
1818  // Next make the function caller for our implementation utility function.
1819  ValueList arguments;
1820  Value value;
1822  value.SetCompilerType(clang_void_pointer_type);
1823  arguments.PushValue(value);
1824  arguments.PushValue(value);
1825  arguments.PushValue(value);
1826 
1828  value.SetCompilerType(clang_uint64_t_pointer_type);
1829  arguments.PushValue(value);
1830 
1832  value.SetCompilerType(clang_uint32_t_type);
1833  arguments.PushValue(value);
1834  arguments.PushValue(value);
1835 
1836  std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
1837 
1838  Status error;
1839  utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
1840  exe_ctx.GetThreadSP(), error);
1841 
1842  if (error.Fail()) {
1843  LLDB_LOG(log,
1844  "Failed to make function caller for implementation lookup: {0}.",
1845  error.AsCString());
1846  return {};
1847  }
1848 
1849  return utility_fn;
1850 }
1851 
1854  ExecutionContext &exe_ctx) {
1855  if (!m_utility_function)
1856  m_utility_function = GetClassInfoUtilityFunctionImpl(exe_ctx);
1857  return m_utility_function.get();
1858 }
1859 
1862  RemoteNXMapTable &hash_table) {
1863  Process *process = m_runtime.GetProcess();
1864  if (process == nullptr)
1866 
1867  uint32_t num_class_infos = 0;
1868 
1870 
1871  ExecutionContext exe_ctx;
1872 
1873  ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
1874 
1875  if (!thread_sp)
1877 
1878  thread_sp->CalculateExecutionContext(exe_ctx);
1879  TypeSystemClang *ast =
1881 
1882  if (!ast)
1884 
1885  Address function_address;
1886 
1887  const uint32_t addr_size = process->GetAddressByteSize();
1888 
1889  Status err;
1890 
1891  // Compute which helper we're going to use for this update.
1892  const DynamicClassInfoExtractor::Helper helper = ComputeHelper(exe_ctx);
1893 
1894  // Read the total number of classes from the hash table
1895  const uint32_t num_classes =
1897  ? hash_table.GetCount()
1898  : m_runtime.m_realized_class_generation_count;
1899  if (num_classes == 0) {
1900  LLDB_LOGF(log, "No dynamic classes found.");
1902  }
1903 
1904  UtilityFunction *get_class_info_code =
1905  GetClassInfoUtilityFunction(exe_ctx, helper);
1906  if (!get_class_info_code) {
1907  // The callee will have already logged a useful error message.
1909  }
1910 
1911  FunctionCaller *get_class_info_function =
1912  get_class_info_code->GetFunctionCaller();
1913 
1914  if (!get_class_info_function) {
1915  LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
1917  }
1918 
1919  ValueList arguments = get_class_info_function->GetArgumentValues();
1920 
1921  DiagnosticManager diagnostics;
1922 
1923  const uint32_t class_info_byte_size = addr_size + 4;
1924  const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
1925  lldb::addr_t class_infos_addr = process->AllocateMemory(
1926  class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
1927 
1928  if (class_infos_addr == LLDB_INVALID_ADDRESS) {
1929  LLDB_LOGF(log,
1930  "unable to allocate %" PRIu32
1931  " bytes in process for shared cache read",
1932  class_infos_byte_size);
1934  }
1935 
1936  auto deallocate_class_infos = llvm::make_scope_exit([&] {
1937  // Deallocate the memory we allocated for the ClassInfo array
1938  if (class_infos_addr != LLDB_INVALID_ADDRESS)
1939  process->DeallocateMemory(class_infos_addr);
1940  });
1941 
1942  lldb::addr_t class_buffer_addr = LLDB_INVALID_ADDRESS;
1943  const uint32_t class_byte_size = addr_size;
1944  const uint32_t class_buffer_len = num_classes;
1945  const uint32_t class_buffer_byte_size = class_buffer_len * class_byte_size;
1946  if (helper == Helper::objc_getRealizedClassList_trylock) {
1947  class_buffer_addr = process->AllocateMemory(
1948  class_buffer_byte_size, ePermissionsReadable | ePermissionsWritable,
1949  err);
1950  if (class_buffer_addr == LLDB_INVALID_ADDRESS) {
1951  LLDB_LOGF(log,
1952  "unable to allocate %" PRIu32
1953  " bytes in process for shared cache read",
1954  class_buffer_byte_size);
1956  }
1957  }
1958 
1959  auto deallocate_class_buffer = llvm::make_scope_exit([&] {
1960  // Deallocate the memory we allocated for the Class array
1961  if (class_buffer_addr != LLDB_INVALID_ADDRESS)
1962  process->DeallocateMemory(class_buffer_addr);
1963  });
1964 
1965  std::lock_guard<std::mutex> guard(m_mutex);
1966 
1967  // Fill in our function argument values
1968  uint32_t index = 0;
1969  arguments.GetValueAtIndex(index++)->GetScalar() =
1970  hash_table.GetTableLoadAddress();
1971  arguments.GetValueAtIndex(index++)->GetScalar() = class_infos_addr;
1972  arguments.GetValueAtIndex(index++)->GetScalar() = class_infos_byte_size;
1973 
1974  if (class_buffer_addr != LLDB_INVALID_ADDRESS) {
1975  arguments.GetValueAtIndex(index++)->GetScalar() = class_buffer_addr;
1976  arguments.GetValueAtIndex(index++)->GetScalar() = class_buffer_byte_size;
1977  }
1978 
1979  // Only dump the runtime classes from the expression evaluation if the log is
1980  // verbose:
1981  Log *type_log = GetLog(LLDBLog::Types);
1982  bool dump_log = type_log && type_log->GetVerbose();
1983 
1984  arguments.GetValueAtIndex(index++)->GetScalar() = dump_log ? 1 : 0;
1985 
1986  bool success = false;
1987 
1988  diagnostics.Clear();
1989 
1990  // Write our function arguments into the process so we can run our function
1991  if (get_class_info_function->WriteFunctionArguments(
1992  exe_ctx, GetClassInfoArgs(helper), arguments, diagnostics)) {
1993  EvaluateExpressionOptions options;
1994  options.SetUnwindOnError(true);
1995  options.SetTryAllThreads(false);
1996  options.SetStopOthers(true);
1997  options.SetIgnoreBreakpoints(true);
1998  options.SetTimeout(process->GetUtilityExpressionTimeout());
1999  options.SetIsForUtilityExpr(true);
2000 
2001  CompilerType clang_uint32_t_type =
2003 
2004  Value return_value;
2005  return_value.SetValueType(Value::ValueType::Scalar);
2006  return_value.SetCompilerType(clang_uint32_t_type);
2007  return_value.GetScalar() = 0;
2008 
2009  diagnostics.Clear();
2010 
2011  // Run the function
2012  ExpressionResults results = get_class_info_function->ExecuteFunction(
2013  exe_ctx, &GetClassInfoArgs(helper), options, diagnostics, return_value);
2014 
2015  if (results == eExpressionCompleted) {
2016  // The result is the number of ClassInfo structures that were filled in
2017  num_class_infos = return_value.GetScalar().ULong();
2018  LLDB_LOG(log, "Discovered {0} Objective-C classes", num_class_infos);
2019  if (num_class_infos > 0) {
2020  // Read the ClassInfo structures
2021  DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
2022  if (process->ReadMemory(class_infos_addr, buffer.GetBytes(),
2023  buffer.GetByteSize(),
2024  err) == buffer.GetByteSize()) {
2025  DataExtractor class_infos_data(buffer.GetBytes(),
2026  buffer.GetByteSize(),
2027  process->GetByteOrder(), addr_size);
2028  m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
2029  }
2030  }
2031  success = true;
2032  } else {
2033  if (log) {
2034  LLDB_LOGF(log, "Error evaluating our find class name function.");
2035  diagnostics.Dump(log);
2036  }
2037  }
2038  } else {
2039  if (log) {
2040  LLDB_LOGF(log, "Error writing function arguments.");
2041  diagnostics.Dump(log);
2042  }
2043  }
2044 
2045  return DescriptorMapUpdateResult(success, num_class_infos);
2046 }
2047 
2049  uint32_t num_class_infos) {
2050  // Parses an array of "num_class_infos" packed ClassInfo structures:
2051  //
2052  // struct ClassInfo
2053  // {
2054  // Class isa;
2055  // uint32_t hash;
2056  // } __attribute__((__packed__));
2057 
2058  Log *log = GetLog(LLDBLog::Types);
2059  bool should_log = log && log->GetVerbose();
2060 
2061  uint32_t num_parsed = 0;
2062 
2063  // Iterate through all ClassInfo structures
2064  lldb::offset_t offset = 0;
2065  for (uint32_t i = 0; i < num_class_infos; ++i) {
2066  ObjCISA isa = data.GetAddress(&offset);
2067 
2068  if (isa == 0) {
2069  if (should_log)
2070  LLDB_LOGF(
2071  log, "AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
2072  continue;
2073  }
2074  // Check if we already know about this ISA, if we do, the info will never
2075  // change, so we can just skip it.
2076  if (ISAIsCached(isa)) {
2077  if (should_log)
2078  LLDB_LOGF(log,
2079  "AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
2080  ", ignoring this class info",
2081  isa);
2082  offset += 4;
2083  } else {
2084  // Read the 32 bit hash for the class name
2085  const uint32_t name_hash = data.GetU32(&offset);
2086  ClassDescriptorSP descriptor_sp(
2087  new ClassDescriptorV2(*this, isa, nullptr));
2088 
2089  // The code in g_get_shared_cache_class_info_body sets the value of the
2090  // hash to 0 to signal a demangled symbol. We use class_getName() in that
2091  // code to find the class name, but this returns a demangled name for
2092  // Swift symbols. For those symbols, recompute the hash here by reading
2093  // their name from the runtime.
2094  if (name_hash)
2095  AddClass(isa, descriptor_sp, name_hash);
2096  else
2097  AddClass(isa, descriptor_sp,
2098  descriptor_sp->GetClassName().AsCString(nullptr));
2099  num_parsed++;
2100  if (should_log)
2101  LLDB_LOGF(log,
2102  "AppleObjCRuntimeV2 added isa=0x%" PRIx64
2103  ", hash=0x%8.8x, name=%s",
2104  isa, name_hash,
2105  descriptor_sp->GetClassName().AsCString("<unknown>"));
2106  }
2107  }
2108  if (should_log)
2109  LLDB_LOGF(log, "AppleObjCRuntimeV2 parsed %" PRIu32 " class infos",
2110  num_parsed);
2111  return num_parsed;
2112 }
2113 
2115  if (!m_objc_module_sp)
2116  return false;
2117  if (const Symbol *symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType(
2118  Name, lldb::eSymbolTypeCode)) {
2119  if (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())
2120  return true;
2121  }
2122  return false;
2123 }
2124 
2127  Process *process = m_runtime.GetProcess();
2128  if (process == nullptr)
2130 
2132 
2133  ExecutionContext exe_ctx;
2134 
2135  ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
2136 
2137  if (!thread_sp)
2139 
2140  thread_sp->CalculateExecutionContext(exe_ctx);
2141  TypeSystemClang *ast =
2143 
2144  if (!ast)
2146 
2147  Address function_address;
2148 
2149  const uint32_t addr_size = process->GetAddressByteSize();
2150 
2151  Status err;
2152 
2153  uint32_t num_class_infos = 0;
2154 
2155  const lldb::addr_t objc_opt_ptr = m_runtime.GetSharedCacheReadOnlyAddress();
2156  const lldb::addr_t shared_cache_base_addr =
2157  m_runtime.GetSharedCacheBaseAddress();
2158 
2159  if (objc_opt_ptr == LLDB_INVALID_ADDRESS ||
2160  shared_cache_base_addr == LLDB_INVALID_ADDRESS)
2162 
2163  // The number of entries to pre-allocate room for.
2164  // Each entry is (addrsize + 4) bytes
2165  const uint32_t max_num_classes = 163840;
2166 
2167  UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx);
2168  if (!get_class_info_code) {
2169  // The callee will have already logged a useful error message.
2171  }
2172 
2173  FunctionCaller *get_shared_cache_class_info_function =
2174  get_class_info_code->GetFunctionCaller();
2175 
2176  if (!get_shared_cache_class_info_function) {
2177  LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
2179  }
2180 
2181  ValueList arguments =
2182  get_shared_cache_class_info_function->GetArgumentValues();
2183 
2184  DiagnosticManager diagnostics;
2185 
2186  const uint32_t class_info_byte_size = addr_size + 4;
2187  const uint32_t class_infos_byte_size = max_num_classes * class_info_byte_size;
2188  lldb::addr_t class_infos_addr = process->AllocateMemory(
2189  class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
2190  const uint32_t relative_selector_offset_addr_size = 64;
2191  lldb::addr_t relative_selector_offset_addr =
2192  process->AllocateMemory(relative_selector_offset_addr_size,
2193  ePermissionsReadable | ePermissionsWritable, err);
2194 
2195  if (class_infos_addr == LLDB_INVALID_ADDRESS) {
2196  LLDB_LOGF(log,
2197  "unable to allocate %" PRIu32
2198  " bytes in process for shared cache read",
2199  class_infos_byte_size);
2201  }
2202 
2203  std::lock_guard<std::mutex> guard(m_mutex);
2204 
2205  // Fill in our function argument values
2206  arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
2207  arguments.GetValueAtIndex(1)->GetScalar() = shared_cache_base_addr;
2208  arguments.GetValueAtIndex(2)->GetScalar() = class_infos_addr;
2209  arguments.GetValueAtIndex(3)->GetScalar() = relative_selector_offset_addr;
2210  arguments.GetValueAtIndex(4)->GetScalar() = class_infos_byte_size;
2211  // Only dump the runtime classes from the expression evaluation if the log is
2212  // verbose:
2213  Log *type_log = GetLog(LLDBLog::Types);
2214  bool dump_log = type_log && type_log->GetVerbose();
2215 
2216  arguments.GetValueAtIndex(5)->GetScalar() = dump_log ? 1 : 0;
2217 
2218  bool success = false;
2219 
2220  diagnostics.Clear();
2221 
2222  // Write our function arguments into the process so we can run our function
2223  if (get_shared_cache_class_info_function->WriteFunctionArguments(
2224  exe_ctx, m_args, arguments, diagnostics)) {
2225  EvaluateExpressionOptions options;
2226  options.SetUnwindOnError(true);
2227  options.SetTryAllThreads(false);
2228  options.SetStopOthers(true);
2229  options.SetIgnoreBreakpoints(true);
2230  options.SetTimeout(process->GetUtilityExpressionTimeout());
2231  options.SetIsForUtilityExpr(true);
2232 
2233  CompilerType clang_uint32_t_type =
2235 
2236  Value return_value;
2237  return_value.SetValueType(Value::ValueType::Scalar);
2238  return_value.SetCompilerType(clang_uint32_t_type);
2239  return_value.GetScalar() = 0;
2240 
2241  diagnostics.Clear();
2242 
2243  // Run the function
2244  ExpressionResults results =
2245  get_shared_cache_class_info_function->ExecuteFunction(
2246  exe_ctx, &m_args, options, diagnostics, return_value);
2247 
2248  if (results == eExpressionCompleted) {
2249  // The result is the number of ClassInfo structures that were filled in
2250  num_class_infos = return_value.GetScalar().ULong();
2251  LLDB_LOG(log, "Discovered {0} Objective-C classes in the shared cache",
2252  num_class_infos);
2253  // Assert if there were more classes than we pre-allocated
2254  // room for.
2255  assert(num_class_infos <= max_num_classes);
2256  if (num_class_infos > 0) {
2257  if (num_class_infos > max_num_classes) {
2258  num_class_infos = max_num_classes;
2259 
2260  success = false;
2261  } else {
2262  success = true;
2263  }
2264 
2265  // Read the relative selector offset.
2266  DataBufferHeap relative_selector_offset_buffer(64, 0);
2267  if (process->ReadMemory(relative_selector_offset_addr,
2268  relative_selector_offset_buffer.GetBytes(),
2269  relative_selector_offset_buffer.GetByteSize(),
2270  err) ==
2271  relative_selector_offset_buffer.GetByteSize()) {
2272  DataExtractor relative_selector_offset_data(
2273  relative_selector_offset_buffer.GetBytes(),
2274  relative_selector_offset_buffer.GetByteSize(),
2275  process->GetByteOrder(), addr_size);
2276  lldb::offset_t offset = 0;
2277  uint64_t relative_selector_offset =
2278  relative_selector_offset_data.GetU64(&offset);
2279  if (relative_selector_offset > 0) {
2280  // The offset is relative to the objc_opt struct.
2281  m_runtime.SetRelativeSelectorBaseAddr(objc_opt_ptr +
2282  relative_selector_offset);
2283  }
2284  }
2285 
2286  // Read the ClassInfo structures
2287  DataBufferHeap class_infos_buffer(
2288  num_class_infos * class_info_byte_size, 0);
2289  if (process->ReadMemory(class_infos_addr, class_infos_buffer.GetBytes(),
2290  class_infos_buffer.GetByteSize(),
2291  err) == class_infos_buffer.GetByteSize()) {
2292  DataExtractor class_infos_data(class_infos_buffer.GetBytes(),
2293  class_infos_buffer.GetByteSize(),
2294  process->GetByteOrder(), addr_size);
2295 
2296  m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
2297  }
2298  } else {
2299  success = true;
2300  }
2301  } else {
2302  if (log) {
2303  LLDB_LOGF(log, "Error evaluating our find class name function.");
2304  diagnostics.Dump(log);
2305  }
2306  }
2307  } else {
2308  if (log) {
2309  LLDB_LOGF(log, "Error writing function arguments.");
2310  diagnostics.Dump(log);
2311  }
2312  }
2313 
2314  // Deallocate the memory we allocated for the ClassInfo array
2315  process->DeallocateMemory(class_infos_addr);
2316 
2317  return DescriptorMapUpdateResult(success, num_class_infos);
2318 }
2319 
2321  Process *process = GetProcess();
2322 
2323  if (process) {
2324  ModuleSP objc_module_sp(GetObjCModule());
2325 
2326  if (objc_module_sp) {
2327  ObjectFile *objc_object = objc_module_sp->GetObjectFile();
2328 
2329  if (objc_object) {
2330  SectionList *section_list = objc_module_sp->GetSectionList();
2331 
2332  if (section_list) {
2333  SectionSP text_segment_sp(
2334  section_list->FindSectionByName(ConstString("__TEXT")));
2335 
2336  if (text_segment_sp) {
2337  SectionSP objc_opt_section_sp(
2338  text_segment_sp->GetChildren().FindSectionByName(
2339  ConstString("__objc_opt_ro")));
2340 
2341  if (objc_opt_section_sp) {
2342  return objc_opt_section_sp->GetLoadBaseAddress(
2343  &process->GetTarget());
2344  }
2345  }
2346  }
2347  }
2348  }
2349  }
2350  return LLDB_INVALID_ADDRESS;
2351 }
2352 
2355  if (!info)
2356  return LLDB_INVALID_ADDRESS;
2357 
2358  StructuredData::Dictionary *info_dict = info->GetAsDictionary();
2359  if (!info_dict)
2360  return LLDB_INVALID_ADDRESS;
2361 
2362  StructuredData::ObjectSP value =
2363  info_dict->GetValueForKey("shared_cache_base_address");
2364  if (!value)
2365  return LLDB_INVALID_ADDRESS;
2366 
2367  return value->GetIntegerValue(LLDB_INVALID_ADDRESS);
2368 }
2369 
2372 
2374 
2375  // Else we need to check with our process to see when the map was updated.
2376  Process *process = GetProcess();
2377 
2378  if (process) {
2379  RemoteNXMapTable hash_table;
2380 
2381  // Update the process stop ID that indicates the last time we updated the
2382  // map, whether it was successful or not.
2384 
2385  // Ask the runtime is the realized class generation count changed. Unlike
2386  // the hash table, this accounts for lazily named classes.
2387  const bool class_count_changed = RealizedClassGenerationCountChanged();
2388 
2389  if (!m_hash_signature.NeedsUpdate(process, this, hash_table) &&
2390  !class_count_changed)
2391  return;
2392 
2393  m_hash_signature.UpdateSignature(hash_table);
2394 
2395  // Grab the dynamically loaded Objective-C classes from memory.
2396  DescriptorMapUpdateResult dynamic_update_result =
2398 
2399  // Now get the objc classes that are baked into the Objective-C runtime in
2400  // the shared cache, but only once per process as this data never changes
2401  if (!m_loaded_objc_opt) {
2402  // it is legitimately possible for the shared cache to be empty - in that
2403  // case, the dynamic hash table will contain all the class information we
2404  // need; the situation we're trying to detect is one where we aren't
2405  // seeing class information from the runtime - in order to detect that
2406  // vs. just the shared cache being empty or sparsely populated, we set an
2407  // arbitrary (very low) threshold for the number of classes that we want
2408  // to see in a "good" scenario - anything below that is suspicious
2409  // (Foundation alone has thousands of classes)
2410  const uint32_t num_classes_to_warn_at = 500;
2411 
2412  DescriptorMapUpdateResult shared_cache_update_result =
2414 
2415  LLDB_LOGF(log,
2416  "attempted to read objc class data - results: "
2417  "[dynamic_update]: ran: %s, count: %" PRIu32
2418  " [shared_cache_update]: ran: %s, count: %" PRIu32,
2419  dynamic_update_result.m_update_ran ? "yes" : "no",
2420  dynamic_update_result.m_num_found,
2421  shared_cache_update_result.m_update_ran ? "yes" : "no",
2422  shared_cache_update_result.m_num_found);
2423 
2424  // warn if:
2425  // - we could not run either expression
2426  // - we found fewer than num_classes_to_warn_at classes total
2427  if ((!shared_cache_update_result.m_update_ran) ||
2428  (!dynamic_update_result.m_update_ran))
2431  else if (dynamic_update_result.m_num_found +
2432  shared_cache_update_result.m_num_found <
2433  num_classes_to_warn_at)
2435  else
2436  m_loaded_objc_opt = true;
2437  }
2438  } else {
2440  }
2441 }
2442 
2444  Process *process = GetProcess();
2445  if (!process)
2446  return false;
2447 
2448  Status error;
2449  uint64_t objc_debug_realized_class_generation_count =
2451  process, ConstString("objc_debug_realized_class_generation_count"),
2452  GetObjCModule(), error);
2453  if (error.Fail())
2454  return false;
2455 
2457  objc_debug_realized_class_generation_count)
2458  return false;
2459 
2461  LLDB_LOG(log,
2462  "objc_debug_realized_class_generation_count changed from {0} to {1}",
2464  objc_debug_realized_class_generation_count);
2465 
2467  objc_debug_realized_class_generation_count;
2468 
2469  return true;
2470 }
2471 
2472 static bool DoesProcessHaveSharedCache(Process &process) {
2473  PlatformSP platform_sp = process.GetTarget().GetPlatform();
2474  if (!platform_sp)
2475  return true; // this should not happen
2476 
2477  llvm::StringRef platform_plugin_name_sr = platform_sp->GetPluginName();
2478  if (platform_plugin_name_sr.endswith("-simulator"))
2479  return false;
2480 
2481  return true;
2482 }
2483 
2485  SharedCacheWarningReason reason) {
2487  // Simulators do not have the objc_opt_ro class table so don't actually
2488  // complain to the user
2489  return;
2490  }
2491 
2492  Debugger &debugger(GetProcess()->GetTarget().GetDebugger());
2493  switch (reason) {
2495  Debugger::ReportWarning("could not find Objective-C class data in "
2496  "the process. This may reduce the quality of type "
2497  "information available.\n",
2498  debugger.GetID(), &m_no_classes_cached_warning);
2499  break;
2502  "could not execute support code to read "
2503  "Objective-C class data in the process. This may "
2504  "reduce the quality of type information available.\n",
2505  debugger.GetID(), &m_no_classes_cached_warning);
2506  break;
2507  }
2508 }
2509 
2511  if (!m_objc_module_sp)
2512  return;
2513 
2514  ObjectFile *object_file = m_objc_module_sp->GetObjectFile();
2515  if (!object_file)
2516  return;
2517 
2518  if (!object_file->IsInMemory())
2519  return;
2520 
2521  Target &target = GetProcess()->GetTarget();
2522  Debugger &debugger = target.GetDebugger();
2523 
2524  std::string buffer;
2525  llvm::raw_string_ostream os(buffer);
2526 
2527  os << "libobjc.A.dylib is being read from process memory. This "
2528  "indicates that LLDB could not ";
2529  if (PlatformSP platform_sp = target.GetPlatform()) {
2530  if (platform_sp->IsHost()) {
2531  os << "read from the host's in-memory shared cache";
2532  } else {
2533  os << "find the on-disk shared cache for this device";
2534  }
2535  } else {
2536  os << "read from the shared cache";
2537  }
2538  os << ". This will likely reduce debugging performance.\n";
2539 
2540  Debugger::ReportWarning(os.str(), debugger.GetID(),
2542 }
2543 
2545  if (!m_decl_vendor_up)
2546  m_decl_vendor_up = std::make_unique<AppleObjCDeclVendor>(*this);
2547 
2548  return m_decl_vendor_up.get();
2549 }
2550 
2553 
2554  const char *name_cstr = name.AsCString();
2555 
2556  if (name_cstr) {
2557  llvm::StringRef name_strref(name_cstr);
2558 
2559  llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
2560  llvm::StringRef class_prefix("OBJC_CLASS_$_");
2561 
2562  if (name_strref.startswith(ivar_prefix)) {
2563  llvm::StringRef ivar_skipped_prefix =
2564  name_strref.substr(ivar_prefix.size());
2565  std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar =
2566  ivar_skipped_prefix.split('.');
2567 
2568  if (class_and_ivar.first.size() && class_and_ivar.second.size()) {
2569  const ConstString class_name_cs(class_and_ivar.first);
2570  ClassDescriptorSP descriptor =
2572 
2573  if (descriptor) {
2574  const ConstString ivar_name_cs(class_and_ivar.second);
2575  const char *ivar_name_cstr = ivar_name_cs.AsCString();
2576 
2577  auto ivar_func = [&ret,
2578  ivar_name_cstr](const char *name, const char *type,
2579  lldb::addr_t offset_addr,
2580  uint64_t size) -> lldb::addr_t {
2581  if (!strcmp(name, ivar_name_cstr)) {
2582  ret = offset_addr;
2583  return true;
2584  }
2585  return false;
2586  };
2587 
2588  descriptor->Describe(
2589  std::function<void(ObjCISA)>(nullptr),
2590  std::function<bool(const char *, const char *)>(nullptr),
2591  std::function<bool(const char *, const char *)>(nullptr),
2592  ivar_func);
2593  }
2594  }
2595  } else if (name_strref.startswith(class_prefix)) {
2596  llvm::StringRef class_skipped_prefix =
2597  name_strref.substr(class_prefix.size());
2598  const ConstString class_name_cs(class_skipped_prefix);
2599  ClassDescriptorSP descriptor =
2600  GetClassDescriptorFromClassName(class_name_cs);
2601 
2602  if (descriptor)
2603  ret = descriptor->GetISA();
2604  }
2605  }
2606 
2607  return ret;
2608 }
2609 
2612  AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp) {
2613  Process *process(runtime.GetProcess());
2614 
2615  Status error;
2616 
2617  Log *log = GetLog(LLDBLog::Types);
2618 
2619  auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol(
2620  process, ConstString("objc_debug_isa_magic_mask"), objc_module_sp, error);
2621  if (error.Fail())
2622  return nullptr;
2623 
2624  auto objc_debug_isa_magic_value = ExtractRuntimeGlobalSymbol(
2625  process, ConstString("objc_debug_isa_magic_value"), objc_module_sp,
2626  error);
2627  if (error.Fail())
2628  return nullptr;
2629 
2630  auto objc_debug_isa_class_mask = ExtractRuntimeGlobalSymbol(
2631  process, ConstString("objc_debug_isa_class_mask"), objc_module_sp, error);
2632  if (error.Fail())
2633  return nullptr;
2634 
2635  if (log)
2636  log->PutCString("AOCRT::NPI: Found all the non-indexed ISA masks");
2637 
2638  bool foundError = false;
2639  auto objc_debug_indexed_isa_magic_mask = ExtractRuntimeGlobalSymbol(
2640  process, ConstString("objc_debug_indexed_isa_magic_mask"), objc_module_sp,
2641  error);
2642  foundError |= error.Fail();
2643 
2644  auto objc_debug_indexed_isa_magic_value = ExtractRuntimeGlobalSymbol(
2645  process, ConstString("objc_debug_indexed_isa_magic_value"),
2646  objc_module_sp, error);
2647  foundError |= error.Fail();
2648 
2649  auto objc_debug_indexed_isa_index_mask = ExtractRuntimeGlobalSymbol(
2650  process, ConstString("objc_debug_indexed_isa_index_mask"), objc_module_sp,
2651  error);
2652  foundError |= error.Fail();
2653 
2654  auto objc_debug_indexed_isa_index_shift = ExtractRuntimeGlobalSymbol(
2655  process, ConstString("objc_debug_indexed_isa_index_shift"),
2656  objc_module_sp, error);
2657  foundError |= error.Fail();
2658 
2659  auto objc_indexed_classes =
2660  ExtractRuntimeGlobalSymbol(process, ConstString("objc_indexed_classes"),
2661  objc_module_sp, error, false);
2662  foundError |= error.Fail();
2663 
2664  if (log)
2665  log->PutCString("AOCRT::NPI: Found all the indexed ISA masks");
2666 
2667  // we might want to have some rules to outlaw these other values (e.g if the
2668  // mask is zero but the value is non-zero, ...)
2669 
2670  return new NonPointerISACache(
2671  runtime, objc_module_sp, objc_debug_isa_class_mask,
2672  objc_debug_isa_magic_mask, objc_debug_isa_magic_value,
2673  objc_debug_indexed_isa_magic_mask, objc_debug_indexed_isa_magic_value,
2674  objc_debug_indexed_isa_index_mask, objc_debug_indexed_isa_index_shift,
2675  foundError ? 0 : objc_indexed_classes);
2676 }
2677 
2680  AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp) {
2681  Process *process(runtime.GetProcess());
2682 
2683  Status error;
2684 
2685  auto objc_debug_taggedpointer_mask = ExtractRuntimeGlobalSymbol(
2686  process, ConstString("objc_debug_taggedpointer_mask"), objc_module_sp,
2687  error);
2688  if (error.Fail())
2689  return new TaggedPointerVendorLegacy(runtime);
2690 
2691  auto objc_debug_taggedpointer_slot_shift = ExtractRuntimeGlobalSymbol(
2692  process, ConstString("objc_debug_taggedpointer_slot_shift"),
2693  objc_module_sp, error, true, 4);
2694  if (error.Fail())
2695  return new TaggedPointerVendorLegacy(runtime);
2696 
2697  auto objc_debug_taggedpointer_slot_mask = ExtractRuntimeGlobalSymbol(
2698  process, ConstString("objc_debug_taggedpointer_slot_mask"),
2699  objc_module_sp, error, true, 4);
2700  if (error.Fail())
2701  return new TaggedPointerVendorLegacy(runtime);
2702 
2703  auto objc_debug_taggedpointer_payload_lshift = ExtractRuntimeGlobalSymbol(
2704  process, ConstString("objc_debug_taggedpointer_payload_lshift"),
2705  objc_module_sp, error, true, 4);
2706  if (error.Fail())
2707  return new TaggedPointerVendorLegacy(runtime);
2708 
2709  auto objc_debug_taggedpointer_payload_rshift = ExtractRuntimeGlobalSymbol(
2710  process, ConstString("objc_debug_taggedpointer_payload_rshift"),
2711  objc_module_sp, error, true, 4);
2712  if (error.Fail())
2713  return new TaggedPointerVendorLegacy(runtime);
2714 
2715  auto objc_debug_taggedpointer_classes = ExtractRuntimeGlobalSymbol(
2716  process, ConstString("objc_debug_taggedpointer_classes"), objc_module_sp,
2717  error, false);
2718  if (error.Fail())
2719  return new TaggedPointerVendorLegacy(runtime);
2720 
2721  // try to detect the "extended tagged pointer" variables - if any are
2722  // missing, use the non-extended vendor
2723  do {
2724  auto objc_debug_taggedpointer_ext_mask = ExtractRuntimeGlobalSymbol(
2725  process, ConstString("objc_debug_taggedpointer_ext_mask"),
2726  objc_module_sp, error);
2727  if (error.Fail())
2728  break;
2729 
2730  auto objc_debug_taggedpointer_ext_slot_shift = ExtractRuntimeGlobalSymbol(
2731  process, ConstString("objc_debug_taggedpointer_ext_slot_shift"),
2732  objc_module_sp, error, true, 4);
2733  if (error.Fail())
2734  break;
2735 
2736  auto objc_debug_taggedpointer_ext_slot_mask = ExtractRuntimeGlobalSymbol(
2737  process, ConstString("objc_debug_taggedpointer_ext_slot_mask"),
2738  objc_module_sp, error, true, 4);
2739  if (error.Fail())
2740  break;
2741 
2742  auto objc_debug_taggedpointer_ext_classes = ExtractRuntimeGlobalSymbol(
2743  process, ConstString("objc_debug_taggedpointer_ext_classes"),
2744  objc_module_sp, error, false);
2745  if (error.Fail())
2746  break;
2747 
2748  auto objc_debug_taggedpointer_ext_payload_lshift =
2750  process, ConstString("objc_debug_taggedpointer_ext_payload_lshift"),
2751  objc_module_sp, error, true, 4);
2752  if (error.Fail())
2753  break;
2754 
2755  auto objc_debug_taggedpointer_ext_payload_rshift =
2757  process, ConstString("objc_debug_taggedpointer_ext_payload_rshift"),
2758  objc_module_sp, error, true, 4);
2759  if (error.Fail())
2760  break;
2761 
2762  return new TaggedPointerVendorExtended(
2763  runtime, objc_debug_taggedpointer_mask,
2764  objc_debug_taggedpointer_ext_mask, objc_debug_taggedpointer_slot_shift,
2765  objc_debug_taggedpointer_ext_slot_shift,
2766  objc_debug_taggedpointer_slot_mask,
2767  objc_debug_taggedpointer_ext_slot_mask,
2768  objc_debug_taggedpointer_payload_lshift,
2769  objc_debug_taggedpointer_payload_rshift,
2770  objc_debug_taggedpointer_ext_payload_lshift,
2771  objc_debug_taggedpointer_ext_payload_rshift,
2772  objc_debug_taggedpointer_classes, objc_debug_taggedpointer_ext_classes);
2773  } while (false);
2774 
2775  // we might want to have some rules to outlaw these values (e.g if the
2776  // table's address is zero)
2777 
2779  runtime, objc_debug_taggedpointer_mask,
2780  objc_debug_taggedpointer_slot_shift, objc_debug_taggedpointer_slot_mask,
2781  objc_debug_taggedpointer_payload_lshift,
2782  objc_debug_taggedpointer_payload_rshift,
2783  objc_debug_taggedpointer_classes);
2784 }
2785 
2787  lldb::addr_t ptr) {
2788  return (ptr & 1);
2789 }
2790 
2793  lldb::addr_t ptr) {
2794  if (!IsPossibleTaggedPointer(ptr))
2796 
2797  uint32_t foundation_version = m_runtime.GetFoundationVersion();
2798 
2799  if (foundation_version == LLDB_INVALID_MODULE_VERSION)
2801 
2802  uint64_t class_bits = (ptr & 0xE) >> 1;
2803  ConstString name;
2804 
2805  static ConstString g_NSAtom("NSAtom");
2806  static ConstString g_NSNumber("NSNumber");
2807  static ConstString g_NSDateTS("NSDateTS");
2808  static ConstString g_NSManagedObject("NSManagedObject");
2809  static ConstString g_NSDate("NSDate");
2810 
2811  if (foundation_version >= 900) {
2812  switch (class_bits) {
2813  case 0:
2814  name = g_NSAtom;
2815  break;
2816  case 3:
2817  name = g_NSNumber;
2818  break;
2819  case 4:
2820  name = g_NSDateTS;
2821  break;
2822  case 5:
2823  name = g_NSManagedObject;
2824  break;
2825  case 6:
2826  name = g_NSDate;
2827  break;
2828  default:
2830  }
2831  } else {
2832  switch (class_bits) {
2833  case 1:
2834  name = g_NSNumber;
2835  break;
2836  case 5:
2837  name = g_NSManagedObject;
2838  break;
2839  case 6:
2840  name = g_NSDate;
2841  break;
2842  case 7:
2843  name = g_NSDateTS;
2844  break;
2845  default:
2847  }
2848  }
2849 
2850  lldb::addr_t unobfuscated = ptr ^ m_runtime.GetTaggedPointerObfuscator();
2851  return ClassDescriptorSP(new ClassDescriptorV2Tagged(name, unobfuscated));
2852 }
2853 
2856  AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
2857  uint32_t objc_debug_taggedpointer_slot_shift,
2858  uint32_t objc_debug_taggedpointer_slot_mask,
2859  uint32_t objc_debug_taggedpointer_payload_lshift,
2860  uint32_t objc_debug_taggedpointer_payload_rshift,
2861  lldb::addr_t objc_debug_taggedpointer_classes)
2862  : TaggedPointerVendorV2(runtime), m_cache(),
2863  m_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask),
2864  m_objc_debug_taggedpointer_slot_shift(
2865  objc_debug_taggedpointer_slot_shift),
2866  m_objc_debug_taggedpointer_slot_mask(objc_debug_taggedpointer_slot_mask),
2867  m_objc_debug_taggedpointer_payload_lshift(
2868  objc_debug_taggedpointer_payload_lshift),
2869  m_objc_debug_taggedpointer_payload_rshift(
2870  objc_debug_taggedpointer_payload_rshift),
2871  m_objc_debug_taggedpointer_classes(objc_debug_taggedpointer_classes) {}
2872 
2875  return (ptr & m_objc_debug_taggedpointer_mask) != 0;
2876 }
2877 
2880  lldb::addr_t ptr) {
2881  ClassDescriptorSP actual_class_descriptor_sp;
2882  uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
2883 
2884  if (!IsPossibleTaggedPointer(unobfuscated))
2886 
2887  uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) &
2888  m_objc_debug_taggedpointer_slot_mask;
2889 
2890  CacheIterator iterator = m_cache.find(slot), end = m_cache.end();
2891  if (iterator != end) {
2892  actual_class_descriptor_sp = iterator->second;
2893  } else {
2894  Process *process(m_runtime.GetProcess());
2895  uintptr_t slot_ptr = slot * process->GetAddressByteSize() +
2896  m_objc_debug_taggedpointer_classes;
2897  Status error;
2898  uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
2899  if (error.Fail() || slot_data == 0 ||
2900  slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
2901  return nullptr;
2902  actual_class_descriptor_sp =
2903  m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
2904  if (!actual_class_descriptor_sp) {
2905  if (ABISP abi_sp = process->GetABI()) {
2906  ObjCISA fixed_isa = abi_sp->FixCodeAddress((ObjCISA)slot_data);
2907  actual_class_descriptor_sp =
2908  m_runtime.GetClassDescriptorFromISA(fixed_isa);
2909  }
2910  }
2911  if (!actual_class_descriptor_sp)
2913  m_cache[slot] = actual_class_descriptor_sp;
2914  }
2915 
2916  uint64_t data_payload =
2917  ((unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
2918  m_objc_debug_taggedpointer_payload_rshift);
2919  int64_t data_payload_signed =
2920  ((int64_t)(unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
2921  m_objc_debug_taggedpointer_payload_rshift);
2923  actual_class_descriptor_sp, data_payload, data_payload_signed));
2924 }
2925 
2927  AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask,
2928  uint64_t objc_debug_taggedpointer_ext_mask,
2929  uint32_t objc_debug_taggedpointer_slot_shift,
2930  uint32_t objc_debug_taggedpointer_ext_slot_shift,
2931  uint32_t objc_debug_taggedpointer_slot_mask,
2932  uint32_t objc_debug_taggedpointer_ext_slot_mask,
2933  uint32_t objc_debug_taggedpointer_payload_lshift,
2934  uint32_t objc_debug_taggedpointer_payload_rshift,
2935  uint32_t objc_debug_taggedpointer_ext_payload_lshift,
2936  uint32_t objc_debug_taggedpointer_ext_payload_rshift,
2937  lldb::addr_t objc_debug_taggedpointer_classes,
2938  lldb::addr_t objc_debug_taggedpointer_ext_classes)
2940  runtime, objc_debug_taggedpointer_mask,
2941  objc_debug_taggedpointer_slot_shift,
2942  objc_debug_taggedpointer_slot_mask,
2943  objc_debug_taggedpointer_payload_lshift,
2944  objc_debug_taggedpointer_payload_rshift,
2945  objc_debug_taggedpointer_classes),
2946  m_ext_cache(),
2947  m_objc_debug_taggedpointer_ext_mask(objc_debug_taggedpointer_ext_mask),
2948  m_objc_debug_taggedpointer_ext_slot_shift(
2949  objc_debug_taggedpointer_ext_slot_shift),
2950  m_objc_debug_taggedpointer_ext_slot_mask(
2951  objc_debug_taggedpointer_ext_slot_mask),
2952  m_objc_debug_taggedpointer_ext_payload_lshift(
2953  objc_debug_taggedpointer_ext_payload_lshift),
2954  m_objc_debug_taggedpointer_ext_payload_rshift(
2955  objc_debug_taggedpointer_ext_payload_rshift),
2956  m_objc_debug_taggedpointer_ext_classes(
2957  objc_debug_taggedpointer_ext_classes) {}
2958 
2961  if (!IsPossibleTaggedPointer(ptr))
2962  return false;
2963 
2964  if (m_objc_debug_taggedpointer_ext_mask == 0)
2965  return false;
2966 
2967  return ((ptr & m_objc_debug_taggedpointer_ext_mask) ==
2968  m_objc_debug_taggedpointer_ext_mask);
2969 }
2970 
2973  lldb::addr_t ptr) {
2974  ClassDescriptorSP actual_class_descriptor_sp;
2975  uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
2976 
2977  if (!IsPossibleTaggedPointer(unobfuscated))
2979 
2980  if (!IsPossibleExtendedTaggedPointer(unobfuscated))
2982 
2983  uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) &
2984  m_objc_debug_taggedpointer_ext_slot_mask;
2985 
2986  CacheIterator iterator = m_ext_cache.find(slot), end = m_ext_cache.end();
2987  if (iterator != end) {
2988  actual_class_descriptor_sp = iterator->second;
2989  } else {
2990  Process *process(m_runtime.GetProcess());
2991  uintptr_t slot_ptr = slot * process->GetAddressByteSize() +
2992  m_objc_debug_taggedpointer_ext_classes;
2993  Status error;
2994  uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
2995  if (error.Fail() || slot_data == 0 ||
2996  slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
2997  return nullptr;
2998  actual_class_descriptor_sp =
2999  m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
3000  if (!actual_class_descriptor_sp)
3002  m_ext_cache[slot] = actual_class_descriptor_sp;
3003  }
3004 
3005  uint64_t data_payload = (((uint64_t)unobfuscated
3006  << m_objc_debug_taggedpointer_ext_payload_lshift) >>
3007  m_objc_debug_taggedpointer_ext_payload_rshift);
3008  int64_t data_payload_signed =
3009  ((int64_t)((int64_t)unobfuscated
3010  << m_objc_debug_taggedpointer_ext_payload_lshift) >>
3011  m_objc_debug_taggedpointer_ext_payload_rshift);
3012 
3014  actual_class_descriptor_sp, data_payload, data_payload_signed));
3015 }
3016 
3018  AppleObjCRuntimeV2 &runtime, const ModuleSP &objc_module_sp,
3019  uint64_t objc_debug_isa_class_mask, uint64_t objc_debug_isa_magic_mask,
3020  uint64_t objc_debug_isa_magic_value,
3021  uint64_t objc_debug_indexed_isa_magic_mask,
3022  uint64_t objc_debug_indexed_isa_magic_value,
3023  uint64_t objc_debug_indexed_isa_index_mask,
3024  uint64_t objc_debug_indexed_isa_index_shift,
3025  lldb::addr_t objc_indexed_classes)
3026  : m_runtime(runtime), m_cache(), m_objc_module_wp(objc_module_sp),
3027  m_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
3028  m_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
3029  m_objc_debug_isa_magic_value(objc_debug_isa_magic_value),
3030  m_objc_debug_indexed_isa_magic_mask(objc_debug_indexed_isa_magic_mask),
3031  m_objc_debug_indexed_isa_magic_value(objc_debug_indexed_isa_magic_value),
3032  m_objc_debug_indexed_isa_index_mask(objc_debug_indexed_isa_index_mask),
3033  m_objc_debug_indexed_isa_index_shift(objc_debug_indexed_isa_index_shift),
3034  m_objc_indexed_classes(objc_indexed_classes), m_indexed_isa_cache() {}
3035 
3038  ObjCISA real_isa = 0;
3039  if (!EvaluateNonPointerISA(isa, real_isa))
3041  auto cache_iter = m_cache.find(real_isa);
3042  if (cache_iter != m_cache.end())
3043  return cache_iter->second;
3044  auto descriptor_sp =
3045  m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(real_isa);
3046  if (descriptor_sp) // cache only positive matches since the table might grow
3047  m_cache[real_isa] = descriptor_sp;
3048  return descriptor_sp;
3049 }
3050 
3052  ObjCISA isa, ObjCISA &ret_isa) {
3053  Log *log = GetLog(LLDBLog::Types);
3054 
3055  LLDB_LOGF(log, "AOCRT::NPI Evaluate(isa = 0x%" PRIx64 ")", (uint64_t)isa);
3056 
3057  if ((isa & ~m_objc_debug_isa_class_mask) == 0)
3058  return false;
3059 
3060  // If all of the indexed ISA variables are set, then its possible that this
3061  // ISA is indexed, and we should first try to get its value using the index.
3062  // Note, we check these variables first as the ObjC runtime will set at least
3063  // one of their values to 0 if they aren't needed.
3064  if (m_objc_debug_indexed_isa_magic_mask &&
3065  m_objc_debug_indexed_isa_magic_value &&
3066  m_objc_debug_indexed_isa_index_mask &&
3067  m_objc_debug_indexed_isa_index_shift && m_objc_indexed_classes) {
3068  if ((isa & ~m_objc_debug_indexed_isa_index_mask) == 0)
3069  return false;
3070 
3071  if ((isa & m_objc_debug_indexed_isa_magic_mask) ==
3072  m_objc_debug_indexed_isa_magic_value) {
3073  // Magic bits are correct, so try extract the index.
3074  uintptr_t index = (isa & m_objc_debug_indexed_isa_index_mask) >>
3075  m_objc_debug_indexed_isa_index_shift;
3076  // If the index is out of bounds of the length of the array then check if
3077  // the array has been updated. If that is the case then we should try
3078  // read the count again, and update the cache if the count has been
3079  // updated.
3080  if (index > m_indexed_isa_cache.size()) {
3081  LLDB_LOGF(log,
3082  "AOCRT::NPI (index = %" PRIu64
3083  ") exceeds cache (size = %" PRIu64 ")",
3084  (uint64_t)index, (uint64_t)m_indexed_isa_cache.size());
3085 
3086  Process *process(m_runtime.GetProcess());
3087 
3088  ModuleSP objc_module_sp(m_objc_module_wp.lock());
3089  if (!objc_module_sp)
3090  return false;
3091 
3092  Status error;
3093  auto objc_indexed_classes_count = ExtractRuntimeGlobalSymbol(
3094  process, ConstString("objc_indexed_classes_count"), objc_module_sp,
3095  error);
3096  if (error.Fail())
3097  return false;
3098 
3099  LLDB_LOGF(log, "AOCRT::NPI (new class count = %" PRIu64 ")",
3100  (uint64_t)objc_indexed_classes_count);
3101 
3102  if (objc_indexed_classes_count > m_indexed_isa_cache.size()) {
3103  // Read the class entries we don't have. We should just read all of
3104  // them instead of just the one we need as then we can cache those we
3105  // may need later.
3106  auto num_new_classes =
3107  objc_indexed_classes_count - m_indexed_isa_cache.size();
3108  const uint32_t addr_size = process->GetAddressByteSize();
3109  DataBufferHeap buffer(num_new_classes * addr_size, 0);
3110 
3111  lldb::addr_t last_read_class =
3112  m_objc_indexed_classes + (m_indexed_isa_cache.size() * addr_size);
3113  size_t bytes_read = process->ReadMemory(
3114  last_read_class, buffer.GetBytes(), buffer.GetByteSize(), error);
3115  if (error.Fail() || bytes_read != buffer.GetByteSize())
3116  return false;
3117 
3118  LLDB_LOGF(log, "AOCRT::NPI (read new classes count = %" PRIu64 ")",
3119  (uint64_t)num_new_classes);
3120 
3121  // Append the new entries to the existing cache.
3122  DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(),
3123  process->GetByteOrder(),
3124  process->GetAddressByteSize());
3125 
3126  lldb::offset_t offset = 0;
3127  for (unsigned i = 0; i != num_new_classes; ++i)
3128  m_indexed_isa_cache.push_back(data.GetAddress(&offset));
3129  }
3130  }
3131 
3132  // If the index is still out of range then this isn't a pointer.
3133  if (index > m_indexed_isa_cache.size())
3134  return false;
3135 
3136  LLDB_LOGF(log, "AOCRT::NPI Evaluate(ret_isa = 0x%" PRIx64 ")",
3137  (uint64_t)m_indexed_isa_cache[index]);
3138 
3139  ret_isa = m_indexed_isa_cache[index];
3140  return (ret_isa != 0); // this is a pointer so 0 is not a valid value
3141  }
3142 
3143  return false;
3144  }
3145 
3146  // Definitely not an indexed ISA, so try to use a mask to extract the pointer
3147  // from the ISA.
3148  if ((isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value) {
3149  ret_isa = isa & m_objc_debug_isa_class_mask;
3150  return (ret_isa != 0); // this is a pointer so 0 is not a valid value
3151  }
3152  return false;
3153 }
3154 
3156  if (!m_encoding_to_type_sp)
3158  std::make_shared<AppleObjCTypeEncodingParser>(*this);
3159  return m_encoding_to_type_sp;
3160 }
3161 
3164  ObjCISA ret = isa;
3165 
3166  if (auto *non_pointer_isa_cache = GetNonPointerIsaCache())
3167  non_pointer_isa_cache->EvaluateNonPointerISA(isa, ret);
3168 
3169  return ret;
3170 }
3171 
3173  if (m_CFBoolean_values)
3174  return true;
3175 
3176  static ConstString g_dunder_kCFBooleanFalse("__kCFBooleanFalse");
3177  static ConstString g_dunder_kCFBooleanTrue("__kCFBooleanTrue");
3178  static ConstString g_kCFBooleanFalse("kCFBooleanFalse");
3179  static ConstString g_kCFBooleanTrue("kCFBooleanTrue");
3180 
3181  std::function<lldb::addr_t(ConstString, ConstString)> get_symbol =
3182  [this](ConstString sym, ConstString real_sym) -> lldb::addr_t {
3183  SymbolContextList sc_list;
3185  sym, lldb::eSymbolTypeData, sc_list);
3186  if (sc_list.GetSize() == 1) {
3187  SymbolContext sc;
3188  sc_list.GetContextAtIndex(0, sc);
3189  if (sc.symbol)
3190  return sc.symbol->GetLoadAddress(&GetProcess()->GetTarget());
3191  }
3193  real_sym, lldb::eSymbolTypeData, sc_list);
3194  if (sc_list.GetSize() != 1)
3195  return LLDB_INVALID_ADDRESS;
3196 
3197  SymbolContext sc;
3198  sc_list.GetContextAtIndex(0, sc);
3199  if (!sc.symbol)
3200  return LLDB_INVALID_ADDRESS;
3201 
3202  lldb::addr_t addr = sc.symbol->GetLoadAddress(&GetProcess()->GetTarget());
3203  Status error;
3204  addr = GetProcess()->ReadPointerFromMemory(addr, error);
3205  if (error.Fail())
3206  return LLDB_INVALID_ADDRESS;
3207  return addr;
3208  };
3209 
3210  lldb::addr_t false_addr = get_symbol(g_dunder_kCFBooleanFalse, g_kCFBooleanFalse);
3211  lldb::addr_t true_addr = get_symbol(g_dunder_kCFBooleanTrue, g_kCFBooleanTrue);
3212 
3213  return (m_CFBoolean_values = {false_addr, true_addr}).operator bool();
3214 }
3215 
3217  lldb::addr_t &cf_false) {
3219  cf_true = m_CFBoolean_values->second;
3220  cf_false = m_CFBoolean_values->first;
3221  } else
3222  this->AppleObjCRuntime::GetValuesForGlobalCFBooleans(cf_true, cf_false);
3223 }
3224 
3225 #pragma mark Frame recognizers
3226 
3228 public:
3229  ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp) {
3230  ThreadSP thread_sp = frame_sp->GetThread();
3231  ProcessSP process_sp = thread_sp->GetProcess();
3232 
3233  const lldb::ABISP &abi = process_sp->GetABI();
3234  if (!abi)
3235  return;
3236 
3237  TypeSystemClang *clang_ast_context =
3238  ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
3239  if (!clang_ast_context)
3240  return;
3241  CompilerType voidstar =
3242  clang_ast_context->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
3243 
3244  ValueList args;
3245  Value input_value;
3246  input_value.SetCompilerType(voidstar);
3247  args.PushValue(input_value);
3248 
3249  if (!abi->GetArgumentValues(*thread_sp, args))
3250  return;
3251 
3252  addr_t exception_addr = args.GetValueAtIndex(0)->GetScalar().ULongLong();
3253 
3254  Value value(exception_addr);
3255  value.SetCompilerType(voidstar);
3256  exception = ValueObjectConstResult::Create(frame_sp.get(), value,
3257  ConstString("exception"));
3259  *exception, eValueTypeVariableArgument);
3260  exception = exception->GetDynamicValue(eDynamicDontRunTarget);
3261 
3262  m_arguments = ValueObjectListSP(new ValueObjectList());
3263  m_arguments->Append(exception);
3264 
3265  m_stop_desc = "hit Objective-C exception";
3266  }
3267 
3268  ValueObjectSP exception;
3269 
3270  lldb::ValueObjectSP GetExceptionObject() override { return exception; }
3271 };
3272 
3274  lldb::RecognizedStackFrameSP
3275  RecognizeFrame(lldb::StackFrameSP frame) override {
3276  return lldb::RecognizedStackFrameSP(
3278  };
3279  std::string GetName() override {
3280  return "ObjC Exception Throw StackFrame Recognizer";
3281  }
3282 };
3283 
3285  FileSpec module;
3286  ConstString function;
3287  std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
3288  std::vector<ConstString> symbols = {function};
3289 
3291  StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
3292  module.GetFilename(), symbols,
3293  /*first_instruction_only*/ true);
3294 }
lldb_private::StackFrameRecognizer
Definition: StackFrameRecognizer.h:55
RemoteNXMapTable::const_iterator::operator=
const_iterator & operator=(const const_iterator &rhs)
Definition: AppleObjCRuntimeV2.cpp:1363
RemoteNXMapTable::const_iterator::const_iterator
const_iterator(const const_iterator &rhs)
Definition: AppleObjCRuntimeV2.cpp:1358
lldb_private::Scalar::ULong
unsigned long ULong(unsigned long fail_value=0) const
Definition: Scalar.cpp:326
lldb_private::eArgRepeatOptional
@ eArgRepeatOptional
Definition: lldb-private-enumerations.h:96
lldb_private::UtilityFunction::GetFunctionCaller
FunctionCaller * GetFunctionCaller()
Definition: UtilityFunction.h:111
lldb_private::LLDBLog::Types
@ Types
lldb_private::Target::GetFrameRecognizerManager
StackFrameRecognizerManager & GetFrameRecognizerManager()
Definition: Target.h:1427
lldb_private::Stream::Format
void Format(const char *format, Args &&... args)
Definition: Stream.h:309
lldb_private::CommandObjectParsed
Definition: CommandObject.h:389
lldb_private::ValueObjectList
A collection of ValueObject values that.
Definition: ValueObjectList.h:23
CommandObjectObjC_ClassTable_Dump::m_options
CommandOptions m_options
Definition: AppleObjCRuntimeV2.cpp:993
lldb_private::TargetProperties::GetDynamicClassInfoHelper
DynamicClassInfoHelper GetDynamicClassInfoHelper() const
Definition: Target.cpp:4333
lldb_private::Value::ValueType::Scalar
@ Scalar
A raw scalar value.
lldb_private::TypeAndOrName::IsEmpty
bool IsEmpty() const
Definition: Type.cpp:791
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::AppleObjCRuntimeV2::GetClassDescriptorFromISA
ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override
Definition: AppleObjCRuntimeV2.cpp:1502
CommandObjectObjC_ClassTable_Dump::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *execution_context) override
Definition: AppleObjCRuntimeV2.cpp:866
lldb::eSymbolTypeObjCIVar
@ eSymbolTypeObjCIVar
Definition: lldb-enumerations.h:648
lldb_private::AppleObjCRuntimeV2::HashTableSignature::m_buckets_ptr
lldb::addr_t m_buckets_ptr
Definition: AppleObjCRuntimeV2.h:128
lldb_private::DataBufferHeap::GetByteSize
lldb::offset_t GetByteSize() const override
Definition: DataBufferHeap.cpp:43
lldb_private::SectionList::FindSectionByName
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
Definition: Section.cpp:546
lldb_private::AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache
NonPointerISACache(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp, uint64_t objc_debug_isa_class_mask, uint64_t objc_debug_isa_magic_mask, uint64_t objc_debug_isa_magic_value, uint64_t objc_debug_indexed_isa_magic_mask, uint64_t objc_debug_indexed_isa_magic_value, uint64_t objc_debug_indexed_isa_index_mask, uint64_t objc_debug_indexed_isa_index_shift, lldb::addr_t objc_indexed_classes)
ObjCExceptionRecognizedStackFrame
Definition: AppleObjCRuntimeV2.cpp:3227
lldb_private::AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::GetClassInfoUtilityFunctionImpl
std::unique_ptr< UtilityFunction > GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx)
Definition: AppleObjCRuntimeV2.cpp:1765
lldb_private::AppleObjCRuntimeV2::GetTaggedPointerObfuscator
lldb::addr_t GetTaggedPointerObfuscator()
Definition: AppleObjCRuntimeV2.cpp:1562
Scalar.h
g_get_dynamic_class_info3_body
static const char * g_get_dynamic_class_info3_body
Definition: AppleObjCRuntimeV2.cpp:235
lldb_private::StructuredData::Dictionary
Definition: StructuredData.h:352
lldb_private::ExecutionContext::GetThreadSP
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
Definition: ExecutionContext.h:464
lldb::eArgTypeAddress
@ eArgTypeAddress
Definition: lldb-enumerations.h:516
lldb_private::Process::AllocateMemory
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process.
Definition: Process.cpp:2263
lldb_private::ObjCLanguageRuntime::TaggedPointerVendor
Definition: ObjCLanguageRuntime.h:185
lldb_private::Process::DeallocateMemory
Status DeallocateMemory(lldb::addr_t ptr)
The public interface to deallocating memory in the process.
Definition: Process.cpp:2334
lldb_private::DataExtractor::GetAddress
uint64_t GetAddress(lldb::offset_t *offset_ptr) const
Extract an address from *offset_ptr.
Definition: DataExtractor.cpp:649
UNUSED_IF_ASSERT_DISABLED
#define UNUSED_IF_ASSERT_DISABLED(x)
Definition: lldb-defines.h:126
lldb_private::Log::GetVerbose
bool GetVerbose() const
Definition: Log.cpp:301
lldb_private::ObjCLanguageRuntime::GetNonKVOClassDescriptor
ClassDescriptorSP GetNonKVOClassDescriptor(ValueObject &in_value)
Definition: ObjCLanguageRuntime.cpp:281
lldb::eSymbolTypeCode
@ eSymbolTypeCode
Definition: lldb-enumerations.h:622
lldb_private::Process::ReadMemory
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
Definition: Process.cpp:1922
lldb_private::AppleObjCRuntimeV2::GetPointerISA
ObjCISA GetPointerISA(ObjCISA isa)
Definition: AppleObjCRuntimeV2.cpp:3163
FunctionCaller.h
lldb_private::Debugger::ReportWarning
static void ReportWarning(std::string message, llvm::Optional< lldb::user_id_t > debugger_id=llvm::None, std::once_flag *once=nullptr)
Report warning events.
Definition: Debugger.cpp:1365
lldb_private::EvaluateExpressionOptions::SetTimeout
void SetTimeout(const Timeout< std::micro > &timeout)
Definition: Target.h:345
lldb_private::AppleObjCRuntimeV2::GetClassDescriptor
ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override
Definition: AppleObjCRuntimeV2.cpp:1512
CommandObjectMultiwordObjC::CommandObjectMultiwordObjC
CommandObjectMultiwordObjC(CommandInterpreter &interpreter)
Definition: AppleObjCRuntimeV2.cpp:1132
lldb_private::AppleObjCRuntimeV2::SharedCacheWarningReason
SharedCacheWarningReason
Definition: AppleObjCRuntimeV2.h:397
lldb_private::AppleObjCRuntimeV2::HashTableSignature::m_num_buckets
uint32_t m_num_buckets
Definition: AppleObjCRuntimeV2.h:127
lldb_private::AppleObjCRuntimeV2::DescriptorMapUpdateResult
Definition: AppleObjCRuntimeV2.h:287
lldb_private::ObjCLanguageRuntime::GetTaggedPointerVendor
virtual TaggedPointerVendor * GetTaggedPointerVendor()
Definition: ObjCLanguageRuntime.h:219
lldb_private::ObjCLanguageRuntime
Definition: ObjCLanguageRuntime.h:35
lldb_private::StructuredData::Dictionary::GetValueForKey
ObjectSP GetValueForKey(llvm::StringRef key) const
Definition: StructuredData.h:389
lldb_private::TypeAndOrName::SetName
void SetName(ConstString type_name)
Definition: Type.cpp:769
CommandObjectMultiwordObjC_TaggedPointer_Info
Definition: AppleObjCRuntimeV2.cpp:996
RemoteNXMapTable::begin
const_iterator begin()
Definition: AppleObjCRuntimeV2.cpp:1447
lldb_private::Value
Definition: Value.h:38
lldb_private::ObjCLanguageRuntime::ClassDescriptorSP
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
Definition: ObjCLanguageRuntime.h:45
lldb_private::Symbol
Definition: Symbol.h:20
lldb_private::Value::SetValueType
void SetValueType(ValueType value_type)
Definition: Value.h:89
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap
DescriptorMapUpdateResult UpdateISAToDescriptorMap(RemoteNXMapTable &hash_table)
Definition: AppleObjCRuntimeV2.cpp:1861
lldb_private::Symbol::ValueIsAddress
bool ValueIsAddress() const
Definition: Symbol.cpp:117
lldb_private::ExecutionContext::GetProcessPtr
Process * GetProcessPtr() const
Returns a pointer to the process object.
Definition: ExecutionContext.cpp:206
lldb_private::DiagnosticManager::Dump
void Dump(Log *log)
Definition: DiagnosticManager.cpp:18
CommandObjectMultiwordObjC_TaggedPointer_Info::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: AppleObjCRuntimeV2.cpp:1023
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::CacheIterator
Cache::iterator CacheIterator
Definition: AppleObjCRuntimeV2.h:212
lldb_private::AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans
void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false) override
Definition: AppleObjCRuntimeV2.cpp:3216
ObjCExceptionThrowFrameRecognizer
Definition: AppleObjCRuntimeV2.cpp:3273
lldb::ExpressionResults
ExpressionResults
The results of expression evaluation.
Definition: lldb-enumerations.h:270
lldb_private::OptionParser::eNoArgument
@ eNoArgument
Definition: OptionParser.h:35
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
Definition: AppleObjCRuntimeV2.cpp:2792
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::ComputeHelper
Helper ComputeHelper(ExecutionContext &exe_ctx) const
Compute which helper to use.
Definition: AppleObjCRuntimeV2.cpp:1733
lldb_private::AppleObjCRuntimeV2::NonPointerISACache::CreateInstance
static NonPointerISACache * CreateInstance(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp)
Definition: AppleObjCRuntimeV2.cpp:2611
lldb_private::OptionValueBoolean
Definition: OptionValueBoolean.h:16
lldb_private::AppleObjCRuntimeV2::m_tagged_pointer_obfuscator
lldb::addr_t m_tagged_pointer_obfuscator
Definition: AppleObjCRuntimeV2.h:427
lldb_private::TypeAndOrName::SetCompilerType
void SetCompilerType(CompilerType compiler_type)
Definition: Type.cpp:785
lldb_private::ValueObjectRecognizerSynthesizedValue::Create
static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type)
Definition: StackFrameRecognizer.h:148
lldb_private::AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress
lldb::addr_t GetSharedCacheReadOnlyAddress()
Definition: AppleObjCRuntimeV2.cpp:2320
lldb_private::ObjCLanguageRuntime::GetClassDescriptorFromClassName
virtual ClassDescriptorSP GetClassDescriptorFromClassName(ConstString class_name)
Definition: ObjCLanguageRuntime.cpp:249
lldb_private::ObjCLanguageRuntime::Get
static ObjCLanguageRuntime * Get(Process &process)
Definition: ObjCLanguageRuntime.h:214
lldb_private::ValueList::GetValueAtIndex
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:669
RemoteNXMapTable::element
std::pair< ConstString, ObjCLanguageRuntime::ObjCISA > element
Definition: AppleObjCRuntimeV2.cpp:1348
RemoteNXMapTable::const_iterator
Definition: AppleObjCRuntimeV2.cpp:1351
lldb_private::AppleObjCRuntimeV2::m_objc_module_sp
lldb::ModuleSP m_objc_module_sp
Definition: AppleObjCRuntimeV2.h:421
RemoteNXMapTable::const_iterator::operator==
bool operator==(const const_iterator &rhs) const
Definition: AppleObjCRuntimeV2.cpp:1370
lldb_private::ObjCLanguageRuntime::GetClassDescriptorFromISA
virtual ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa)
Definition: ObjCLanguageRuntime.cpp:296
lldb_private::ProcessProperties::GetUtilityExpressionTimeout
std::chrono::seconds GetUtilityExpressionTimeout() const
Definition: Process.cpp:308
lldb_private::AppleObjCRuntimeV2::IsTaggedPointer
bool IsTaggedPointer(lldb::addr_t ptr) override
Definition: AppleObjCRuntimeV2.cpp:1281
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:344
lldb_private::ClassDescriptorV2Tagged
Definition: AppleObjCClassDescriptorV2.h:245
lldb_private::Process
Definition: Process.h:338
lldb_private::ObjCLanguageRuntime::EncodingToTypeSP
std::shared_ptr< EncodingToType > EncodingToTypeSP
Definition: ObjCLanguageRuntime.h:221
CommandObjectObjC_ClassTable_Dump::GetOptions
Options * GetOptions() override
Definition: AppleObjCRuntimeV2.cpp:903
CommandObjectObjC_ClassTable_Dump::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: AppleObjCRuntimeV2.cpp:906
lldb_private::TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize
CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override
Definition: TypeSystemClang.cpp:796
lldb_private::AppleObjCRuntimeV2::DescriptorMapUpdateResult::Success
static DescriptorMapUpdateResult Success(uint32_t found)
Definition: AppleObjCRuntimeV2.h:298
lldb_private::EvaluateExpressionOptions::SetIsForUtilityExpr
void SetIsForUtilityExpr(bool b)
Definition: Target.h:432
Module.h
lldb_private::Process::GetThreadList
ThreadList & GetThreadList()
Definition: Process.h:2086
lldb_private::CommandObject::CommandArgumentData
Used to build individual command argument lists.
Definition: CommandObject.h:91
lldb_private::AppleObjCRuntimeV2::HashTableSignature::UpdateSignature
void UpdateSignature(const RemoteNXMapTable &hash_table)
Definition: AppleObjCRuntimeV2.cpp:1475
lldb_private::Process::GetTarget
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1219
lldb_private::AppleObjCRuntimeV2
Definition: AppleObjCRuntimeV2.h:25
lldb_private::eDynamicClassInfoHelperRealizedClassesStruct
@ eDynamicClassInfoHelperRealizedClassesStruct
Definition: Target.h:70
lldb_private::EvaluateExpressionOptions
Definition: Target.h:277
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::gdb_objc_realized_classes
@ gdb_objc_realized_classes
Definition: AppleObjCRuntimeV2.h:335
lldb_private::ValueObject::GetPointerValue
lldb::addr_t GetPointerValue(AddressType *address_type=nullptr)
Definition: ValueObject.cpp:1436
RemoteNXMapTable::Dump
void Dump()
Definition: AppleObjCRuntimeV2.cpp:1291
lldb::LanguageType
LanguageType
Programming language type.
Definition: lldb-enumerations.h:436
lldb_private::ObjCLanguageRuntime::GetBreakpointExceptionPrecondition
static lldb::BreakpointPreconditionSP GetBreakpointExceptionPrecondition(lldb::LanguageType language, bool throw_bp)
Definition: ObjCLanguageRuntime.cpp:379
lldb::eSymbolTypeData
@ eSymbolTypeData
Definition: lldb-enumerations.h:624
lldb_private::SymbolContextList
Definition: SymbolContext.h:379
lldb_private::AppleObjCRuntimeV2::m_no_classes_cached_warning
std::once_flag m_no_classes_cached_warning
Definition: AppleObjCRuntimeV2.h:438
lldb_private::AppleObjCRuntimeV2::m_isa_hash_table_ptr
lldb::addr_t m_isa_hash_table_ptr
Definition: AppleObjCRuntimeV2.h:428
lldb_private::SymbolContextList::GetContextAtIndex
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
Definition: SymbolContext.cpp:1258
OptionArgParser.h
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:192
lldb_private::FileSpec::GetFilename
const ConstString & GetFilename() const
Filename string const get accessor.
Definition: FileSpec.h:239
lldb_private::SectionList
Definition: Section.h:34
lldb_private::AppleObjCRuntimeV2::CreateInstance
static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language)
Definition: AppleObjCRuntimeV2.cpp:811
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::ValueList
Definition: Value.h:157
CommandObjectMultiwordObjC_TaggedPointer
Definition: AppleObjCRuntimeV2.cpp:1114
lldb_private::CommandObject::CommandArgumentData::arg_repetition
ArgumentRepetitionType arg_repetition
Definition: CommandObject.h:93
lldb_private::eDynamicClassInfoHelperGetRealizedClassList
@ eDynamicClassInfoHelperGetRealizedClassList
Definition: Target.h:72
RemoteNXMapTable
Definition: AppleObjCRuntimeV2.cpp:1287
g_get_shared_cache_class_info_body
static const char * g_get_shared_cache_class_info_body
Definition: AppleObjCRuntimeV2.cpp:322
lldb_private::Args
Definition: Args.h:33
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunction
UtilityFunction * GetClassInfoUtilityFunction(ExecutionContext &exe_ctx, Helper helper)
Definition: AppleObjCRuntimeV2.cpp:1688
lldb_private::ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2
@ eAppleObjC_V2
lldb_private::AppleObjCRuntimeV2::m_shared_cache_class_info_extractor
SharedCacheClassInfoExtractor m_shared_cache_class_info_extractor
Definition: AppleObjCRuntimeV2.h:424
lldb_private::TypeAndOrName::Clear
void Clear()
Definition: Type.cpp:795
lldb_private::eArgRepeatPlus
@ eArgRepeatPlus
Definition: lldb-private-enumerations.h:97
lldb_private::Target::GetDebugger
Debugger & GetDebugger()
Definition: Target.h:1030
CommandReturnObject.h
Debugger.h
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::Target
Definition: Target.h:469
lldb_private::CommandReturnObject::AppendErrorWithFormatv
void AppendErrorWithFormatv(const char *format, Args &&... args)
Definition: CommandReturnObject.h:130
Section.h
lldb_private::DataExtractor::GetU64
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
Definition: DataExtractor.cpp:474
lldb_private::AppleObjCRuntimeV2::Terminate
static void Terminate()
Definition: AppleObjCRuntimeV2.cpp:1158
ABI.h
lldb_private::AppleObjCRuntimeV2::m_CFBoolean_values
llvm::Optional< std::pair< lldb::addr_t, lldb::addr_t > > m_CFBoolean_values
Definition: AppleObjCRuntimeV2.h:440
lldb_private::Target::GetImages
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:947
lldb_private::AppleObjCRuntimeV2::LookupRuntimeSymbol
lldb::addr_t LookupRuntimeSymbol(ConstString name) override
Definition: AppleObjCRuntimeV2.cpp:2551
RemoteNXMapTable::GetCount
uint32_t GetCount() const
Definition: AppleObjCRuntimeV2.cpp:1453
RemoteNXMapTable::const_iterator::operator*
const element operator*() const
Definition: AppleObjCRuntimeV2.cpp:1388
Process.h
RemoteNXMapTable::const_iterator::m_parent
RemoteNXMapTable & m_parent
Definition: AppleObjCRuntimeV2.cpp:1443
lldb_private::AppleObjCRuntimeV2::m_has_objc_getRealizedClassList_trylock
bool m_has_objc_getRealizedClassList_trylock
Definition: AppleObjCRuntimeV2.h:433
lldb_private::Value::SetCompilerType
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:251
lldb_private::AppleObjCRuntimeV2::m_has_object_getClass
bool m_has_object_getClass
Definition: AppleObjCRuntimeV2.h:431
lldb_private::AppleObjCRuntime::m_objc_module_wp
lldb::ModuleWP m_objc_module_wp
Definition: AppleObjCRuntime.h:127
AppleObjCDeclVendor.h
lldb_private::ModuleList::FindSymbolsWithNameAndType
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
Definition: ModuleList.cpp:509
lldb_private::AppleObjCRuntimeV2::NonPointerISACache
Definition: AppleObjCRuntimeV2.h:131
Target.h
lldb_private::AppleObjCRuntimeV2::SharedCacheWarningReason::eNotEnoughClassesRead
@ eNotEnoughClassesRead
lldb_private::ValueObject::GetProcessSP
lldb::ProcessSP GetProcessSP() const
Definition: ValueObject.h:338
lldb_private::Value::GetScalar
const Scalar & GetScalar() const
Definition: Value.h:112
lldb_private::Target::GetPlatform
lldb::PlatformSP GetPlatform()
Definition: Target.h:1403
ObjCExceptionThrowFrameRecognizer::RecognizeFrame
lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) override
Definition: AppleObjCRuntimeV2.cpp:3275
lldb_private::operator==
bool operator==(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1016
lldb_private::AppleObjCRuntimeV2::m_no_expanded_cache_warning
std::once_flag m_no_expanded_cache_warning
Definition: AppleObjCRuntimeV2.h:439
Platform.h
lldb_private::FileSpec
Definition: FileSpec.h:55
lldb_private::CommandObjectMultiword
Definition: CommandObjectMultiword.h:19
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::ObjCLanguageRuntime::LookupInCompleteClassCache
lldb::TypeSP LookupInCompleteClassCache(ConstString &name)
Definition: ObjCLanguageRuntime.cpp:109
lldb::eSymbolTypeAny
@ eSymbolTypeAny
Definition: lldb-enumerations.h:619
lldb_private::SymbolContext::symbol
Symbol * symbol
The Symbol for a given query.
Definition: SymbolContext.h:323
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:287
ObjCExceptionRecognizedStackFrame::GetExceptionObject
lldb::ValueObjectSP GetExceptionObject() override
Definition: AppleObjCRuntimeV2.cpp:3270
lldb_private::ValueList::PushValue
void PushValue(const Value &value)
Definition: Value.cpp:665
lldb_private::AppleObjCRuntimeV2::m_encoding_to_type_sp
EncodingToTypeSP m_encoding_to_type_sp
Definition: AppleObjCRuntimeV2.h:437
lldb_private::AppleObjCRuntimeV2::ClassDescriptorV2
friend class ClassDescriptorV2
Definition: AppleObjCRuntimeV2.h:419
lldb::eDynamicDontRunTarget
@ eDynamicDontRunTarget
Definition: lldb-enumerations.h:497
lldb_private::Options
Definition: Options.h:57
ID
static char ID
Definition: IRDynamicChecks.cpp:33
ObjCExceptionThrowFrameRecognizer::GetName
std::string GetName() override
Definition: AppleObjCRuntimeV2.cpp:3279
lldb_private::PluginManager::UnregisterPlugin
static bool UnregisterPlugin(ABICreateInstance create_callback)
Definition: PluginManager.cpp:293
lldb_private::FunctionCaller::WriteFunctionArguments
bool WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager)
Insert the default function argument struct.
Definition: FunctionCaller.cpp:117
lldb_private::AppleObjCRuntimeV2::m_has_objc_copyRealizedClassList
bool m_has_objc_copyRealizedClassList
Definition: AppleObjCRuntimeV2.h:432
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::AppleObjCRuntimeV2::GetPluginNameStatic
static llvm::StringRef GetPluginNameStatic()
Definition: AppleObjCRuntimeV2.h:36
lldb_private::Scalar::ULongLong
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:334
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::TaggedPointerVendorRuntimeAssisted
TaggedPointerVendorRuntimeAssisted(AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask, uint32_t objc_debug_taggedpointer_slot_shift, uint32_t objc_debug_taggedpointer_slot_mask, uint32_t objc_debug_taggedpointer_payload_lshift, uint32_t objc_debug_taggedpointer_payload_rshift, lldb::addr_t objc_debug_taggedpointer_classes)
Definition: AppleObjCRuntimeV2.cpp:2855
Log.h
lldb_private::AppleObjCRuntimeV2::m_loaded_objc_opt
bool m_loaded_objc_opt
Definition: AppleObjCRuntimeV2.h:434
lldb_private::AppleObjCRuntimeV2::GetISAHashTablePointer
lldb::addr_t GetISAHashTablePointer()
Definition: AppleObjCRuntimeV2.cpp:1595
lldb_private::AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA
bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa)
Definition: AppleObjCRuntimeV2.cpp:3051
RemoteNXMapTable::const_iterator::operator!=
bool operator!=(const const_iterator &rhs) const
Definition: AppleObjCRuntimeV2.cpp:1379
TypeSystemClang.h
lldb_private::ConstString::IsEmpty
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:303
lldb_private::ValueObject::IsBaseClass
virtual bool IsBaseClass()
Definition: ValueObject.h:398
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorExtended::IsPossibleExtendedTaggedPointer
bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr)
Definition: AppleObjCRuntimeV2.cpp:2960
lldb_private::AppleObjCRuntime::GetObjCVersion
static ObjCRuntimeVersions GetObjCVersion(Process *process, lldb::ModuleSP &objc_module_sp)
Definition: AppleObjCRuntime.cpp:372
lldb_private::AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate
bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
Definition: AppleObjCRuntimeV2.cpp:1482
lldb_private::Runtime::m_process
Process * m_process
Definition: Runtime.h:29
lldb_private::CommandReturnObject::SetStatus
void SetStatus(lldb::ReturnStatus status)
Definition: CommandReturnObject.cpp:127
CommandObjectObjC_ClassTable_Dump::CommandOptions::m_verbose
OptionValueBoolean m_verbose
Definition: AppleObjCRuntimeV2.cpp:874
RemoteNXMapTable::const_iterator::const_iterator
const_iterator(RemoteNXMapTable &parent, int index)
Definition: AppleObjCRuntimeV2.cpp:1353
lldb_private::StructuredData::ObjectSP
std::shared_ptr< Object > ObjectSP
Definition: StructuredData.h:59
lldb::eExpressionCompleted
@ eExpressionCompleted
Definition: lldb-enumerations.h:271
lldb_private::eDynamicClassInfoHelperAuto
@ eDynamicClassInfoHelperAuto
Definition: Target.h:69
lldb_private::AppleObjCRuntime::CouldHaveDynamicValue
bool CouldHaveDynamicValue(ValueObject &in_value) override
Definition: AppleObjCRuntime.cpp:262
StreamString.h
lldb_private::LLDBLog::Process
@ Process
lldb_private::Symbol::GetAddressRef
Address & GetAddressRef()
Definition: Symbol.h:57
lldb_private::Breakpoint::Exact
@ Exact
Definition: Breakpoint.h:89
lldb_private::CommandReturnObject::GetOutputStream
Stream & GetOutputStream()
Definition: CommandReturnObject.h:46
lldb_private::FunctionCaller::GetArgumentValues
ValueList GetArgumentValues() const
Definition: FunctionCaller.h:286
lldb_private::ObjCLanguageRuntime::GetDescriptorIteratorPair
std::pair< ISAToDescriptorIterator, ISAToDescriptorIterator > GetDescriptorIteratorPair(bool update_if_needed=true)
Definition: ObjCLanguageRuntime.cpp:228
LLDB_OPT_SET_ALL
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:101
RemoteNXMapTable::GetTableLoadAddress
lldb::addr_t GetTableLoadAddress() const
Definition: AppleObjCRuntimeV2.cpp:1459
lldb_private::Target::CreateUtilityFunction
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateUtilityFunction(std::string expression, std::string name, lldb::LanguageType language, ExecutionContext &exe_ctx)
Creates and installs a UtilityFunction for the given language.
Definition: Target.cpp:2414
ExtractRuntimeGlobalSymbol
static uint64_t ExtractRuntimeGlobalSymbol(Process *process, ConstString name, const ModuleSP &module_sp, Status &error, bool read_value=true, uint8_t byte_size=0, uint64_t default_value=LLDB_INVALID_ADDRESS, SymbolType sym_type=lldb::eSymbolTypeData)
Definition: AppleObjCRuntimeV2.cpp:688
lldb_private::AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa)
Definition: AppleObjCRuntimeV2.cpp:3037
lldb_private::Process::GetAddressByteSize
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3366
lldb::eEncodingUint
@ eEncodingUint
unsigned integer
Definition: lldb-enumerations.h:148
lldb_private::SymbolContextList::GetSize
uint32_t GetSize() const
Get accessor for a symbol context list size.
Definition: SymbolContext.cpp:1274
lldb_private::ConstString
Definition: ConstString.h:39
lldb_private::AppleObjCRuntimeV2::HashTableSignature::m_count
uint32_t m_count
Definition: AppleObjCRuntimeV2.h:126
lldb-enumerations.h
Timer.h
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted
Definition: AppleObjCRuntimeV2.h:195
ObjCExceptionRecognizedStackFrame::ObjCExceptionRecognizedStackFrame
ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp)
Definition: AppleObjCRuntimeV2.cpp:3229
lldb_private::AppleObjCRuntimeV2::GetNonPointerIsaCache
NonPointerISACache * GetNonPointerIsaCache()
Definition: AppleObjCRuntimeV2.h:412
lldb_private::AppleObjCRuntimeV2::CreateExceptionResolver
lldb::BreakpointResolverSP CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp, bool throw_bp) override
Definition: AppleObjCRuntimeV2.cpp:1163
lldb_private::EvaluateExpressionOptions::SetTryAllThreads
void SetTryAllThreads(bool try_others=true)
Definition: Target.h:357
lldb_private::AppleObjCRuntimeV2::WarnIfNoClassesCached
void WarnIfNoClassesCached(SharedCacheWarningReason reason)
Definition: AppleObjCRuntimeV2.cpp:2484
CommandObjectObjC_ClassTable_Dump
Definition: AppleObjCRuntimeV2.cpp:839
lldb::eArgTypeRegularExpression
@ eArgTypeRegularExpression
Definition: lldb-enumerations.h:569
lldb_private::Value::ValueType
ValueType
Type that describes Value::m_value.
Definition: Value.h:41
lldb_private::AppleObjCRuntimeV2::m_decl_vendor_up
std::unique_ptr< DeclVendor > m_decl_vendor_up
Definition: AppleObjCRuntimeV2.h:426
CommandObjectObjC_ClassTable_Dump::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
Definition: AppleObjCRuntimeV2.cpp:847
lldb_private::AppleObjCRuntime
Definition: AppleObjCRuntime.h:23
lldb_private::CommandInterpreter
Definition: CommandInterpreter.h:214
lldb_private::DynamicLoader
Definition: DynamicLoader.h:52
LLDB_SCOPED_TIMER
#define LLDB_SCOPED_TIMER()
Definition: Timer.h:83
lldb::eBasicTypeVoid
@ eBasicTypeVoid
Definition: lldb-enumerations.h:749
CommandObjectMultiword.h
CommandObjectObjC_ClassTable_Dump::CommandObjectObjC_ClassTable_Dump
CommandObjectObjC_ClassTable_Dump(CommandInterpreter &interpreter)
Definition: AppleObjCRuntimeV2.cpp:877
lldb::eReturnStatusFailed
@ eReturnStatusFailed
Definition: lldb-enumerations.h:265
lldb_private::AppleObjCRuntime::GetObjCModule
lldb::ModuleSP GetObjCModule()
Definition: AppleObjCRuntime.cpp:218
lldb_private::ValueObject::GetParent
virtual ValueObject * GetParent()
Definition: ValueObject.h:753
lldb::DynamicValueType
DynamicValueType
Definition: lldb-enumerations.h:494
lldb_private::Debugger
Definition: Debugger.h:74
CommandObjectMultiwordObjC_TaggedPointer::CommandObjectMultiwordObjC_TaggedPointer
CommandObjectMultiwordObjC_TaggedPointer(CommandInterpreter &interpreter)
Definition: AppleObjCRuntimeV2.cpp:1116
lldb_private::ValueObject::GetExecutionContextRef
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:330
lldb_private::LanguageRuntime
Definition: LanguageRuntime.h:60
lldb::eValueTypeVariableArgument
@ eValueTypeVariableArgument
function argument variables
Definition: lldb-enumerations.h:319
lldb_private::CommandObject::CommandArgumentData::arg_type
lldb::CommandArgumentType arg_type
Definition: CommandObject.h:92
lldb_private::AppleObjCRuntimeV2::m_realized_class_generation_count
uint64_t m_realized_class_generation_count
Definition: AppleObjCRuntimeV2.h:441
lldb::eLanguageTypeObjC
@ eLanguageTypeObjC
Objective-C.
Definition: lldb-enumerations.h:453
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
CommandObjectMultiwordObjC
Definition: AppleObjCRuntimeV2.cpp:1130
lldb_private::Runtime::GetTargetRef
Target & GetTargetRef()
Definition: Runtime.h:23
LLDB_INVALID_IVAR_OFFSET
#define LLDB_INVALID_IVAR_OFFSET
Definition: lldb-defines.h:76
lldb_private::ObjCLanguageRuntime::ISAIsCached
bool ISAIsCached(ObjCISA isa) const
Definition: ObjCLanguageRuntime.h:329
lldb_private::ObjCLanguageRuntime::AddClass
bool AddClass(ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
Definition: ObjCLanguageRuntime.h:333
lldb_private::EvaluateExpressionOptions::SetUnwindOnError
void SetUnwindOnError(bool unwind=false)
Definition: Target.h:324
Thread.h
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorLegacy::IsPossibleTaggedPointer
bool IsPossibleTaggedPointer(lldb::addr_t ptr) override
Definition: AppleObjCRuntimeV2.cpp:2786
lldb_private::AppleObjCRuntime::GetExceptionThrowLocation
static std::tuple< FileSpec, ConstString > GetExceptionThrowLocation()
Definition: AppleObjCRuntime.cpp:604
lldb::SymbolType
SymbolType
Symbol types.
Definition: lldb-enumerations.h:618
CompilerType.h
RemoteNXMapTable::m_end_iterator
const_iterator m_end_iterator
Definition: AppleObjCRuntimeV2.cpp:1467
VariableList.h
lldb_private::CompilerType::IsValid
bool IsValid() const
Definition: CompilerType.h:72
lldb_private::AppleObjCRuntime::GetValuesForGlobalCFBooleans
virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false)
Definition: AppleObjCRuntime.cpp:339
lldb_private::ObjCLanguageRuntime::m_isa_to_descriptor_stop_id
uint32_t m_isa_to_descriptor_stop_id
Definition: ObjCLanguageRuntime.h:436
DoesProcessHaveSharedCache
static bool DoesProcessHaveSharedCache(Process &process)
Definition: AppleObjCRuntimeV2.cpp:2472
ObjCExceptionRecognizedStackFrame::exception
ValueObjectSP exception
Definition: AppleObjCRuntimeV2.cpp:3268
ObjectFile.h
lldb_private::StackFrameRecognizerManager::AddRecognizer
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef< ConstString > symbols, bool first_instruction_only=true)
lldb_private::UserID::GetID
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47
UtilityFunction.h
lldb_private::Address::SetRawAddress
void SetRawAddress(lldb::addr_t addr)
Definition: Address.h:444
g_shared_cache_class_name_funcptr
static const char * g_shared_cache_class_name_funcptr
Definition: AppleObjCRuntimeV2.cpp:311
RegisterObjCExceptionRecognizer
static void RegisterObjCExceptionRecognizer(Process *process)
Definition: AppleObjCRuntimeV2.cpp:3284
g_get_dynamic_class_info_name
static const char * g_get_dynamic_class_info_name
Definition: AppleObjCRuntimeV2.cpp:73
lldb_private::AppleObjCRuntimeV2::HashTableSignature::HashTableSignature
HashTableSignature()
ValueObjectConstResult.h
AppleObjCRuntimeV2.h
lldb_private::eDynamicClassInfoHelperCopyRealizedClassList
@ eDynamicClassInfoHelperCopyRealizedClassList
Definition: Target.h:71
lldb_private::Process::CalculateTarget
lldb::TargetSP CalculateTarget() override
Definition: Process.cpp:4210
TypeList.h
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::objc_getRealizedClassList_trylock
@ objc_getRealizedClassList_trylock
Definition: AppleObjCRuntimeV2.h:337
lldb_private::EvaluateExpressionOptions::SetIgnoreBreakpoints
void SetIgnoreBreakpoints(bool ignore=false)
Definition: Target.h:328
Symbol.h
RemoteNXMapTable::GetBucketCount
uint32_t GetBucketCount() const
Definition: AppleObjCRuntimeV2.cpp:1455
lldb_private::ObjCLanguageRuntime::TaggedPointerVendor::GetClassDescriptor
virtual ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr)=0
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
Definition: AppleObjCRuntimeV2.cpp:2972
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::Helper
Helper
Definition: AppleObjCRuntimeV2.h:334
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunctionImpl
std::unique_ptr< UtilityFunction > GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx, Helper helper, std::string code, std::string name)
Definition: AppleObjCRuntimeV2.cpp:1623
lldb_private::Status
Definition: Status.h:44
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
lldb_private::CompilerType::GetPointerType
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
Definition: CompilerType.cpp:407
lldb_private::Args::GetArgumentAtIndex
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition: Args.cpp:264
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::IsPossibleTaggedPointer
bool IsPossibleTaggedPointer(lldb::addr_t ptr) override
Definition: AppleObjCRuntimeV2.cpp:2874
lldb::eLanguageTypeUnknown
@ eLanguageTypeUnknown
Unknown or invalid language value.
Definition: lldb-enumerations.h:437
lldb_private::CommandReturnObject
Definition: CommandReturnObject.h:26
uint32_t
DebuggerEvents.h
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
g_get_dynamic_class_info2_body
static const char * g_get_dynamic_class_info2_body
Definition: AppleObjCRuntimeV2.cpp:166
CommandObject.h
lldb::eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishResult
Definition: lldb-enumerations.h:261
lldb_private::ObjCLanguageRuntime::TaggedPointerVendor::IsPossibleTaggedPointer
virtual bool IsPossibleTaggedPointer(lldb::addr_t ptr)=0
lldb_private::DeclVendor
Definition: DeclVendor.h:20
AppleObjCTypeEncodingParser.h
lldb_private::Runtime::GetProcess
Process * GetProcess()
Definition: Runtime.h:22
lldb_private::Address
Definition: Address.h:59
CommandObjectObjC_ClassTable_Dump::CommandOptions::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: AppleObjCRuntimeV2.cpp:870
lldb::eArgTypeNone
@ eArgTypeNone
Definition: lldb-enumerations.h:595
lldb_private::TypeAndOrName::SetTypeSP
void SetTypeSP(lldb::TypeSP type_sp)
Definition: Type.cpp:777
lldb_private::StructuredData::Object::GetAsDictionary
Dictionary * GetAsDictionary()
Definition: StructuredData.h:91
g_get_shared_cache_class_info_name
static const char * g_get_shared_cache_class_info_name
Definition: AppleObjCRuntimeV2.cpp:319
lldb_private::ObjCLanguageRuntime::ObjCISA
lldb::addr_t ObjCISA
Definition: ObjCLanguageRuntime.h:43
lldb_private::CompilerType::GetTypeName
ConstString GetTypeName() const
Definition: CompilerType.cpp:277
lldb_private::Address::GetLoadAddress
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:311
lldb_private::DiagnosticManager
Definition: DiagnosticManager.h:93
lldb_private::AppleObjCRuntimeV2::CreateObjectChecker
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override
Definition: AppleObjCRuntimeV2.cpp:1179
lldb_private::AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::GetClassInfoUtilityFunction
UtilityFunction * GetClassInfoUtilityFunction(ExecutionContext &exe_ctx)
Definition: AppleObjCRuntimeV2.cpp:1853
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
lldb_private::ValueObject::GetCompilerType
CompilerType GetCompilerType()
Definition: ValueObject.h:352
ObjCLanguageRuntime.h
CommandObjectMultiwordObjC_TaggedPointer_Info::CommandObjectMultiwordObjC_TaggedPointer_Info
CommandObjectMultiwordObjC_TaggedPointer_Info(CommandInterpreter &interpreter)
Definition: AppleObjCRuntimeV2.cpp:999
lldb_private::RecognizedStackFrame
Definition: StackFrameRecognizer.h:30
g_get_dynamic_class_info3_name
static const char * g_get_dynamic_class_info3_name
Definition: AppleObjCRuntimeV2.cpp:232
lldb_private::AppleObjCRuntimeV2::SharedCacheWarningReason::eExpressionExecutionFailure
@ eExpressionExecutionFailure
lldb_private::ScratchTypeSystemClang::GetForTarget
static TypeSystemClang * GetForTarget(Target &target, llvm::Optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
Definition: TypeSystemClang.cpp:9851
lldb_private::AppleObjCRuntimeV2::GetByteOffsetForIvar
size_t GetByteOffsetForIvar(CompilerType &parent_qual_type, const char *ivar_name) override
Definition: AppleObjCRuntimeV2.cpp:1233
lldb_private::DataExtractor::GetU32
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
Definition: DataExtractor.cpp:425
PluginManager.h
lldb_private::AppleObjCRuntimeV2::m_tagged_pointer_vendor_up
std::unique_ptr< TaggedPointerVendor > m_tagged_pointer_vendor_up
Definition: AppleObjCRuntimeV2.h:436
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorV2
Definition: AppleObjCRuntimeV2.h:174
RemoteNXMapTable::ParseHeader
bool ParseHeader(Process *process, lldb::addr_t load_addr)
Definition: AppleObjCRuntimeV2.cpp:1299
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:337
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private::ValueObjectConstResult::Create
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
Definition: ValueObjectConstResult.cpp:28
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::AppleObjCRuntimeV2::GetEncodingToType
EncodingToTypeSP GetEncodingToType() override
Definition: AppleObjCRuntimeV2.cpp:3155
DiagnosticManager.h
RemoteNXMapTable::const_iterator::m_index
int m_index
Definition: AppleObjCRuntimeV2.cpp:1444
lldb_private::DiagnosticManager::Clear
void Clear()
Definition: DiagnosticManager.h:95
lldb_private::ExecutionContext::GetTargetRef
Target & GetTargetRef() const
Returns a reference to the target object.
Definition: ExecutionContext.cpp:224
Status.h
lldb_private::AppleObjCRuntimeV2::DescriptorMapUpdateResult::Fail
static DescriptorMapUpdateResult Fail()
Definition: AppleObjCRuntimeV2.h:296
lldb_private::PluginManager::RegisterPlugin
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
Definition: PluginManager.cpp:287
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoArgs
lldb::addr_t & GetClassInfoArgs(Helper helper)
Definition: AppleObjCRuntimeV2.cpp:1720
OptionParser.h
lldb_private::AppleObjCRuntimeV2::m_hash_signature
HashTableSignature m_hash_signature
Definition: AppleObjCRuntimeV2.h:430
lldb::eLanguageTypeC
@ eLanguageTypeC
Non-standardized C, such as K&R.
Definition: lldb-enumerations.h:439
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance
static TaggedPointerVendorV2 * CreateInstance(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp)
Definition: AppleObjCRuntimeV2.cpp:2679
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::AppleObjCRuntimeV2::m_dynamic_class_info_extractor
DynamicClassInfoExtractor m_dynamic_class_info_extractor
Definition: AppleObjCRuntimeV2.h:423
lldb_private::AppleObjCRuntimeV2::DynamicClassInfoExtractor::objc_copyRealizedClassList
@ objc_copyRealizedClassList
Definition: AppleObjCRuntimeV2.h:336
lldb_private::ObjectFile::IsInMemory
bool IsInMemory() const
Returns true if the object file exists only in memory.
Definition: ObjectFile.h:677
lldb_private::OptionDefinition
Definition: OptionDefinition.h:20
lldb_private::FunctionCaller::ExecuteFunction
lldb::ExpressionResults ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager, Value &results)
Run the function this FunctionCaller was created with.
Definition: FunctionCaller.cpp:313
g_get_dynamic_class_info_body
static const char * g_get_dynamic_class_info_body
Definition: AppleObjCRuntimeV2.cpp:76
lldb_private::TypeSystemClang::GetBasicType
CompilerType GetBasicType(lldb::BasicType type)
Definition: TypeSystemClang.cpp:931
RemoteNXMapTable::GetBucketDataPointer
lldb::addr_t GetBucketDataPointer() const
Definition: AppleObjCRuntimeV2.cpp:1457
lldb_private::AppleObjCRuntimeV2::GetSharedCacheBaseAddress
lldb::addr_t GetSharedCacheBaseAddress()
Definition: AppleObjCRuntimeV2.cpp:2353
lldb_private::TypeSystemClang
A TypeSystem implementation based on Clang.
Definition: TypeSystemClang.h:106
ConstString.h
lldb_private::ValueObject::GetTargetSP
lldb::TargetSP GetTargetSP() const
Definition: ValueObject.h:334
CommandObjectObjC_ClassTable_Dump::CommandOptions
Definition: AppleObjCRuntimeV2.cpp:841
lldb_private::Process::GetABI
const lldb::ABISP & GetABI()
Definition: Process.cpp:1483
CommandObjectMultiwordObjC_ClassTable
Definition: AppleObjCRuntimeV2.cpp:1099
ValueObjectVariable.h
g_objc_classtable_dump_options
static constexpr OptionDefinition g_objc_classtable_dump_options[]
Definition: AppleObjCRuntimeV2.cpp:827
CommandObjectMultiwordObjC_ClassTable::CommandObjectMultiwordObjC_ClassTable
CommandObjectMultiwordObjC_ClassTable(CommandInterpreter &interpreter)
Definition: AppleObjCRuntimeV2.cpp:1101
AppleObjCClassDescriptorV2.h
lldb_private::Process::ReadUnsignedIntegerFromMemory
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
Definition: Process.cpp:2063
Stream.h
lldb_private::Process::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3362
lldb_private::Process::GetSharedCacheInfo
virtual lldb_private::StructuredData::ObjectSP GetSharedCacheInfo()
Definition: Process.h:1320
lldb_private::Log
Definition: Log.h:115
g_get_dynamic_class_info2_name
static const char * g_get_dynamic_class_info2_name
Definition: AppleObjCRuntimeV2.cpp:163
OptionValueBoolean.h
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorLegacy
Definition: AppleObjCRuntimeV2.h:269
lldb_private::Process::ReadPointerFromMemory
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2085
lldb_private::EvaluateExpressionOptions::SetStopOthers
void SetStopOthers(bool stop_others=true)
Definition: Target.h:361
lldb_private::TypeAndOrName
Sometimes you can find the name of the type corresponding to an object, but we don't have debug infor...
Definition: Type.h:397
lldb_private::AppleObjCRuntimeV2::WarnIfNoExpandedSharedCache
void WarnIfNoExpandedSharedCache()
Definition: AppleObjCRuntimeV2.cpp:2510
lldb_private::AppleObjCRuntimeV2::AppleObjCRuntimeV2
AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp)
Definition: AppleObjCRuntimeV2.cpp:728
lldb_private::Symbol::GetLoadAddress
lldb::addr_t GetLoadAddress(Target *target) const
Definition: Symbol.cpp:493
lldb_private::AppleObjCRuntimeV2::DescriptorMapUpdateResult::m_update_ran
bool m_update_ran
Definition: AppleObjCRuntimeV2.h:288
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended
TaggedPointerVendorExtended(AppleObjCRuntimeV2 &runtime, uint64_t objc_debug_taggedpointer_mask, uint64_t objc_debug_taggedpointer_ext_mask, uint32_t objc_debug_taggedpointer_slot_shift, uint32_t objc_debug_taggedpointer_ext_slot_shift, uint32_t objc_debug_taggedpointer_slot_mask, uint32_t objc_debug_taggedpointer_ext_slot_mask, uint32_t objc_debug_taggedpointer_payload_lshift, uint32_t objc_debug_taggedpointer_payload_rshift, uint32_t objc_debug_taggedpointer_ext_payload_lshift, uint32_t objc_debug_taggedpointer_ext_payload_rshift, lldb::addr_t objc_debug_taggedpointer_classes, lldb::addr_t objc_debug_taggedpointer_ext_classes)
Definition: AppleObjCRuntimeV2.cpp:2926
lldb_private::CommandObject::CommandArgumentEntry
std::vector< CommandArgumentData > CommandArgumentEntry
Definition: CommandObject.h:106
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
lldb_private::AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded
bool GetCFBooleanValuesIfNeeded()
Definition: AppleObjCRuntimeV2.cpp:3172
lldb_private::AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap
DescriptorMapUpdateResult UpdateISAToDescriptorMap()
Definition: AppleObjCRuntimeV2.cpp:2126
lldb_private::Process::GetStopID
uint32_t GetStopID() const
Definition: Process.h:1378
lldb_private::CommandReturnObject::AppendError
void void AppendError(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:100
lldb_private::AppleObjCRuntimeV2::GetDeclVendor
DeclVendor * GetDeclVendor() override
Definition: AppleObjCRuntimeV2.cpp:2544
lldb_private::Args::GetArgumentCount
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.h:116
DynamicLoader.h
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb_private::AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded
void UpdateISAToDescriptorMapIfNeeded() override
Definition: AppleObjCRuntimeV2.cpp:2370
lldb
Definition: SBAddress.h:15
lldb_private::ThreadList::GetExpressionExecutionThread
lldb::ThreadSP GetExpressionExecutionThread()
Definition: ThreadList.cpp:60
StackFrameRecognizer.h
RegisterContext.h
LLDB_LOG_ERROR
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:360
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
Definition: AppleObjCRuntimeV2.cpp:2879
LLDBLog.h
lldb_private::AppleObjCRuntimeV2::RealizedClassGenerationCountChanged
bool RealizedClassGenerationCountChanged()
Update the generation count of realized classes.
Definition: AppleObjCRuntimeV2.cpp:2443
lldb_private::AppleObjCRuntimeV2::DescriptorMapUpdateResult::m_num_found
uint32_t m_num_found
Definition: AppleObjCRuntimeV2.h:289
lldb_private::ObjectFile
Definition: ObjectFile.h:60
ExecutionContext.h
LLDB_INVALID_MODULE_VERSION
#define LLDB_INVALID_MODULE_VERSION
Definition: lldb-defines.h:78
CommandObjectObjC_ClassTable_Dump::CommandOptions::CommandOptions
CommandOptions()
Definition: AppleObjCRuntimeV2.cpp:843
UINT64_MAX
#define UINT64_MAX
Definition: lldb-defines.h:23
lldb_private::AppleObjCRuntimeV2::TaggedPointerVendorExtended
Definition: AppleObjCRuntimeV2.h:229
lldb_private::UtilityFunction
Definition: UtilityFunction.h:30
lldb_private::AppleObjCRuntimeV2::HasSymbol
bool HasSymbol(ConstString Name)
Definition: AppleObjCRuntimeV2.cpp:2114
lldb_private::AppleObjCRuntimeV2::GetDynamicTypeAndAddress
bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, Value::ValueType &value_type) override
Definition: AppleObjCRuntimeV2.cpp:756
RemoteNXMapTable::RemoteNXMapTable
RemoteNXMapTable()
Definition: AppleObjCRuntimeV2.cpp:1289
AppleObjCTrampolineHandler.h
RemoteNXMapTable::end
const_iterator end()
Definition: AppleObjCRuntimeV2.cpp:1451
lldb_private::FunctionCaller
Definition: FunctionCaller.h:56
lldb_private::AppleObjCRuntimeV2::ParseClassInfoArray
uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data, uint32_t num_class_infos)
Definition: AppleObjCRuntimeV2.cpp:2048
lldb_private::Log::PutCString
void PutCString(const char *cstr)
Definition: Log.cpp:134
RemoteNXMapTable::const_iterator::AdvanceToValidIndex
void AdvanceToValidIndex()
Definition: AppleObjCRuntimeV2.cpp:1420
lldb_private::AppleObjCRuntimeV2::Initialize
static void Initialize()
Definition: AppleObjCRuntimeV2.cpp:1148
RemoteNXMapTable::const_iterator::operator++
const_iterator & operator++()
Definition: AppleObjCRuntimeV2.cpp:1383
lldb_private::OptionArgParser::ToAddress
static lldb::addr_t ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error)
Definition: OptionArgParser.cpp:142