58#include "clang/AST/ASTContext.h"
59#include "clang/AST/DeclObjC.h"
60#include "clang/Basic/TargetInfo.h"
61#include "llvm/ADT/ScopeExit.h"
74 "__lldb_apple_objc_v2_get_dynamic_class_info";
80 size_t strlen(const char *);
81 char *strncpy (char * s1, const char * s2, size_t n);
82 int printf(const char * format, ...);
84#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
86typedef struct _NXMapTable {
89 unsigned num_buckets_minus_one;
93#define NX_MAPNOTAKEY ((void *)(-1))
95typedef struct BucketInfo
105} __attribute__((__packed__));
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,
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;
119 const unsigned num_classes = grc->num_classes;
120 DEBUG_PRINTF ("num_classes = %u\n", grc->num_classes);
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);
126 const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
127 DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
129 ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
130 BucketInfo *buckets = (BucketInfo *)grc->buckets;
133 for (unsigned i=0; i<=num_buckets_minus_one; ++i)
135 if (buckets[i].name_ptr != NX_MAPNOTAKEY)
137 if (idx < max_class_infos)
139 const char *s = buckets[i].name_ptr;
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);
150 if (idx < max_class_infos)
152 class_infos[idx].isa = NULL;
153 class_infos[idx].hash = 0;
164 "__lldb_apple_objc_v2_get_dynamic_class_info2";
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);
175#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
181} __attribute__((__packed__));
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,
189 DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
190 DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
192 const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
193 DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
195 ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
198 Class* realized_class_list = objc_copyRealizedClassList_nolock(&count);
199 DEBUG_PRINTF ("count = %u\n", count);
202 for (uint32_t i=0; i<count; ++i)
204 if (idx < max_class_infos)
206 Class isa = realized_class_list[i];
207 const char *name_ptr = objc_debug_class_getNameRaw(isa);
210 const char *s = name_ptr;
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);
221 if (idx < max_class_infos)
223 class_infos[idx].isa = NULL;
224 class_infos[idx].hash = 0;
227 free(realized_class_list);
233 "__lldb_apple_objc_v2_get_dynamic_class_info3";
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);
245#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
251} __attribute__((__packed__));
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,
258 uint32_t class_buffer_len,
261 DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
262 DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
264 const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
265 DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
267 ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
269 Class *realized_class_list = (Class*)class_buffer;
271 uint32_t count = objc_getRealizedClassList_trylock(realized_class_list,
273 DEBUG_PRINTF ("count = %u\n", count);
276 for (uint32_t i=0; i<count; ++i)
278 if (idx < max_class_infos)
280 Class isa = realized_class_list[i];
281 const char *name_ptr = objc_debug_class_getNameRaw(isa);
283 class_getName(isa); // Realize name of lazy classes.
284 name_ptr = objc_debug_class_getNameRaw(isa);
288 const char *s = name_ptr;
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);
299 if (idx < max_class_infos)
301 class_infos[idx].isa = NULL;
302 class_infos[idx].hash = 0;
314 const char *%s(void *objc_class);
315 const char *(*class_name_lookup_func)(void *) = %s;
320 "__lldb_apple_objc_v2_get_shared_cache_class_info";
326 size_t strlen(const char *);
327 char *strncpy (char * s1, const char * s2, size_t n);
328 int printf(const char * format, ...);
331#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
334struct objc_classheader_t {
339struct objc_classheader_v16_t {
340 uint64_t isDuplicate : 1,
341 objectCacheOffset : 47, // Offset from the shared cache base
345struct objc_clsopt_t {
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];
362struct objc_clsopt_v16_t {
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];
381 int32_t selopt_offset;
382 int32_t headeropt_offset;
383 int32_t clsopt_offset;
386struct objc_opt_v14_t {
389 int32_t selopt_offset;
390 int32_t headeropt_offset;
391 int32_t clsopt_offset;
394struct objc_opt_v16_t {
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;
412} __attribute__((__packed__));
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,
422 *relative_selector_offset = 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)));
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)
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);
442 else if (objc_opt->version >= 14)
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);
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);
458 if (objc_opt->version == 16)
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);
463 DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
465 ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
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);
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);
475 for (uint32_t i=0; i<clsopt->capacity; ++i)
477 const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
478 DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
480 if (classOffsets[i].isDuplicate) {
481 DEBUG_PRINTF("isDuplicate = true\n");
482 continue; // duplicate
485 if (objectCacheOffset == 0) {
486 DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
487 continue; // invalid offset
490 if (class_infos && idx < max_class_infos)
492 class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
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);
498 // Hash the class name so we don't have to read it.
499 const char *s = name;
501 for (unsigned char c = *s; c; c = *++s)
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.
512 h = ((h << 5) + h) + c;
514 class_infos[idx].hash = h;
518 DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
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]);
527 DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
528 DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
530 for (uint32_t i=0; i<duplicate_count; ++i)
532 const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
533 DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
535 if (classOffsets[i].isDuplicate) {
536 DEBUG_PRINTF("isDuplicate = true\n");
537 continue; // duplicate
540 if (objectCacheOffset == 0) {
541 DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
542 continue; // invalid offset
545 if (class_infos && idx < max_class_infos)
547 class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
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);
553 // Hash the class name so we don't have to read it.
554 const char *s = name;
556 for (unsigned char c = *s; c; c = *++s)
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.
567 h = ((h << 5) + h) + c;
569 class_infos[idx].hash = h;
573 else if (objc_opt->version >= 12 && objc_opt->version <= 15)
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);
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)
596 const int32_t clsOffset = classOffsets[i].clsOffset;
597 DEBUG_PRINTF("clsOffset[%u] = %u\n", i, clsOffset);
600 DEBUG_PRINTF("clsOffset & 1\n");
601 continue; // duplicate
603 else if (clsOffset == invalidEntryOffset)
605 DEBUG_PRINTF("clsOffset == invalidEntryOffset\n");
606 continue; // invalid offset
609 if (class_infos && idx < max_class_infos)
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;
617 for (unsigned char c = *s; c; c = *++s)
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.
628 h = ((h << 5) + h) + c;
630 class_infos[idx].hash = h;
634 DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
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)
646 const int32_t clsOffset = duplicateClassOffsets[i].clsOffset;
648 continue; // duplicate
649 else if (clsOffset == invalidEntryOffset)
650 continue; // invalid offset
652 if (class_infos && idx < max_class_infos)
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;
660 for (unsigned char c = *s; c; c = *++s)
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.
671 h = ((h << 5) + h) + c;
673 class_infos[idx].hash = h;
678 DEBUG_PRINTF ("%u class_infos\n", idx);
679 DEBUG_PRINTF ("done\n");
690 bool read_value =
true, uint8_t byte_size = 0,
694 error.SetErrorString(
"no process");
695 return default_value;
699 error.SetErrorString(
"no module");
700 return default_value;
709 error.SetErrorString(
"no symbol");
710 return default_value;
716 error.SetErrorString(
"symbol address invalid");
717 return default_value;
722 default_value,
error);
723 return symbol_load_addr;
729 const ModuleSP &objc_module_sp)
731 m_dynamic_class_info_extractor(*this),
732 m_shared_cache_class_info_extractor(*this), m_decl_vendor_up(),
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(
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");
745 static const ConstString g_objc_copyRealizedClassList(
746 "_ZL33objc_copyRealizedClassList_nolockPj");
747 static const ConstString g_objc_getRealizedClassList_trylock(
748 "_objc_getRealizedClassList_trylock");
751 HasSymbol(g_objc_getRealizedClassList_trylock);
774 class_type_or_name.
Clear();
786 ConstString class_name(objc_class_sp->GetClassName());
787 class_type_or_name.
SetName(class_name);
788 TypeSP type_sp(objc_class_sp->GetType());
794 objc_class_sp->SetType(type_sp);
799 auto types = vendor->FindTypes(class_name, 1);
807 return !class_type_or_name.
IsEmpty();
817 ModuleSP objc_module_sp;
837 "Print ivar and method information in detail"}};
850 const int short_option = m_getopt_table[option_idx].val;
851 switch (short_option) {
853 m_verbose.SetCurrentValue(
true);
854 m_verbose.SetOptionWasSet();
858 error.SetErrorStringWithFormat(
"unrecognized short option '%c'",
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),
895 arg.push_back(index_arg);
898 m_arguments.push_back(arg);
907 std::unique_ptr<RegularExpression> regex_up;
914 if (!regex_up->IsValid()) {
916 "invalid argument - please provide a valid regular expression");
923 result.
AppendError(
"please provide 0 or 1 arguments");
929 Process *process = m_exe_ctx.GetProcessPtr();
933 auto iterator = iterators_pair.first;
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)))
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>"));
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);
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);
964 iterator->second->Describe(
966 [&std_out](
const char *name,
const char *type) ->
bool {
967 std_out.Printf(
" instance method name = %s type = %s\n",
971 [&std_out](
const char *name,
const char *type) ->
bool {
972 std_out.Printf(
" class method name = %s type = %s\n", name,
979 if (regex_up && !regex_up->Execute(llvm::StringRef()))
981 std_out.Printf(
"isa = 0x%" PRIx64
" has no associated class.\n",
988 result.
AppendError(
"current process has no Objective-C runtime loaded");
1001 interpreter,
"info",
"Dump information on a tagged pointer.",
1002 "language objc tagged-pointer info",
1003 eCommandRequiresProcess | eCommandProcessMustBeLaunched |
1004 eCommandProcessMustBePaused) {
1014 arg.push_back(index_arg);
1017 m_arguments.push_back(arg);
1025 result.
AppendError(
"this command requires arguments");
1030 Process *process = m_exe_ctx.GetProcessPtr();
1034 if (!objc_runtime) {
1035 result.
AppendError(
"current process has no Objective-C runtime loaded");
1042 if (!tagged_ptr_vendor) {
1043 result.
AppendError(
"current process has no tagged pointer support");
1058 "could not convert '{0}' to a valid address\n", arg_str);
1069 if (!descriptor_sp) {
1071 "could not get class descriptor for {0:x16}\n", arg_addr);
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,
1083 "\tpayload = {1:x16}\n"
1084 "\tvalue = {2:x16}\n"
1085 "\tinfo bits = {3:x16}\n"
1087 arg_addr, payload, value_bits, info_bits,
1088 descriptor_sp->GetClassName().AsCString(
"<unknown>"));
1103 interpreter,
"class-table",
1104 "Commands for operating on the Objective-C class table.",
1105 "class-table <subcommand> [<subcommand-options>]") {
1118 interpreter,
"tagged-pointer",
1119 "Commands for operating on Objective-C tagged pointers.",
1120 "class-table <subcommand> [<subcommand-options>]") {
1134 interpreter,
"objc",
1135 "Commands for operating on the Objective-C language runtime.",
1136 "objc <subcommand> [<subcommand-options>]") {
1137 LoadSubCommand(
"class-table",
1140 LoadSubCommand(
"tagged-pointer",
1164 bool catch_bp,
bool throw_bp) {
1165 BreakpointResolverSP resolver_sp;
1168 resolver_sp = std::make_shared<BreakpointResolverName>(
1178llvm::Expected<std::unique_ptr<UtilityFunction>>
1181 char check_function_code[2048];
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, ...);
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';
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, ...);
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';
1226 assert(len < (int)
sizeof(check_function_code));
1234 const char *ivar_name) {
1238 if (!class_name.
IsEmpty() && ivar_name && ivar_name[0]) {
1241 std::string buffer(
"OBJC_IVAR_$_");
1243 buffer.push_back(
'.');
1244 buffer.append(ivar_name);
1260 if (ivar_offset_symbol.
symbol)
1261 ivar_offset_address =
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);
1300 m_process = process;
1301 m_load_addr = load_addr;
1314 bool success =
true;
1318 lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
1321 m_count = m_process->ReadUnsignedIntegerFromMemory(
1322 cursor, unsigned_byte_size, 0, err);
1324 cursor += unsigned_byte_size;
1327 m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(
1328 cursor, unsigned_byte_size, 0, err);
1329 cursor += unsigned_byte_size;
1332 m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
1340 m_num_buckets_minus_one = 0;
1348 typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA>
element;
1354 : m_parent(parent), m_index(index) {
1355 AdvanceToValidIndex();
1359 : m_parent(rhs.m_parent), m_index(rhs.m_index) {
1365 assert(&m_parent == &rhs.
m_parent);
1384 AdvanceToValidIndex();
1389 if (m_index == -1) {
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);
1401 m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
1404 lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(
1405 pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
1409 std::string key_string;
1411 m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
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;
1430 lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
1432 m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
1439 if (key != invalid_key)
1469 size_t m_map_pair_size = 0;
1491 if (m_count == hash_table.
GetCount() &&
1505 class_descriptor_sp = non_pointer_isa_cache->GetClassDescriptor(isa);
1506 if (!class_descriptor_sp)
1508 return class_descriptor_sp;
1517 if (parent && parent != &valobj) {
1519 if (parent_descriptor_sp)
1520 return parent_descriptor_sp->GetSuperclass();
1528 return objc_class_sp;
1538 return objc_class_sp;
1543 return objc_class_sp;
1546 if (!objc_class_sp) {
1547 if (ABISP abi_sp = process->
GetABI())
1548 isa = abi_sp->FixCodeAddress(isa);
1552 if (isa && !objc_class_sp) {
1555 "0x%" PRIx64
": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
1556 "not in class descriptor cache 0x%" PRIx64,
1559 return objc_class_sp;
1569 if (!objc_module_sp)
1573 "objc_debug_taggedpointer_obfuscator");
1575 const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
1601 if (!objc_module_sp)
1604 static ConstString g_gdb_objc_realized_classes(
"gdb_objc_realized_classes");
1606 const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
1615 gdb_objc_realized_classes_ptr,
error);
1622std::unique_ptr<UtilityFunction>
1628 LLDB_LOG(log,
"Creating utility function {0}", name);
1630 TypeSystemClangSP scratch_ts_sp =
1637 if (!utility_fn_or_error) {
1639 log, utility_fn_or_error.takeError(),
1640 "Failed to get utility function for dynamic info extractor: {0}");
1646 scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(
eEncodingUint, 32);
1662 if (helper == Helper::objc_getRealizedClassList_trylock) {
1671 std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
1674 utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
1679 "Failed to make function caller for implementation lookup: {0}.",
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();
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();
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();
1716 llvm_unreachable(
"Unexpected 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;
1729 llvm_unreachable(
"Unexpected helper");
1735 if (!m_runtime.m_has_objc_copyRealizedClassList &&
1736 !m_runtime.m_has_objc_getRealizedClassList_trylock)
1739 if (
Process *process = m_runtime.GetProcess()) {
1741 if (loader->IsFullyInitialized()) {
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]];
1763std::unique_ptr<UtilityFunction>
1768 LLDB_LOG(log,
"Creating utility function {0}",
1771 TypeSystemClangSP scratch_ts_sp =
1778 static ConstString g_class_getName_symbol_name(
"class_getName");
1779 static ConstString g_class_getNameRaw_symbol_name(
1780 "objc_debug_class_getNameRaw");
1783 m_runtime.HasSymbol(g_class_getNameRaw_symbol_name)
1784 ? g_class_getNameRaw_symbol_name
1785 : g_class_getName_symbol_name;
1790 std::string shared_class_expression;
1791 llvm::raw_string_ostream(shared_class_expression)
1793 class_name_getter_function_name.
AsCString(),
1794 class_name_getter_function_name.
AsCString());
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}");
1811 scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(
eEncodingUint, 32);
1815 scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(
eEncodingUint, 64)
1836 std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
1839 utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
1844 "Failed to make function caller for implementation lookup: {0}.",
1855 if (!m_utility_function)
1856 m_utility_function = GetClassInfoUtilityFunctionImpl(exe_ctx);
1857 return m_utility_function.get();
1863 Process *process = m_runtime.GetProcess();
1864 if (process ==
nullptr)
1878 if (!thread_sp->SafeToCallFunctions())
1881 thread_sp->CalculateExecutionContext(exe_ctx);
1882 TypeSystemClangSP scratch_ts_sp =
1901 : m_runtime.m_realized_class_generation_count;
1902 if (num_classes == 0) {
1903 LLDB_LOGF(log,
"No dynamic classes found.");
1908 GetClassInfoUtilityFunction(exe_ctx, helper);
1909 if (!get_class_info_code) {
1917 if (!get_class_info_function) {
1918 LLDB_LOGF(log,
"Failed to get implementation lookup function caller.");
1926 const uint32_t class_info_byte_size = addr_size + 4;
1927 const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
1929 class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
1933 "unable to allocate %" PRIu32
1934 " bytes in process for shared cache read",
1935 class_infos_byte_size);
1939 auto deallocate_class_infos = llvm::make_scope_exit([&] {
1946 const uint32_t class_byte_size = addr_size;
1947 const uint32_t class_buffer_len = num_classes;
1948 const uint32_t class_buffer_byte_size = class_buffer_len * class_byte_size;
1949 if (helper == Helper::objc_getRealizedClassList_trylock) {
1951 class_buffer_byte_size, ePermissionsReadable | ePermissionsWritable,
1955 "unable to allocate %" PRIu32
1956 " bytes in process for shared cache read",
1957 class_buffer_byte_size);
1962 auto deallocate_class_buffer = llvm::make_scope_exit([&] {
1968 std::lock_guard<std::mutex> guard(m_mutex);
1985 bool dump_log = type_log && type_log->
GetVerbose();
1989 bool success =
false;
1991 diagnostics.
Clear();
1995 exe_ctx, GetClassInfoArgs(helper), arguments, diagnostics)) {
2005 scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(
eEncodingUint, 32);
2012 diagnostics.
Clear();
2016 exe_ctx, &GetClassInfoArgs(helper), options, diagnostics, return_value);
2021 LLDB_LOG(log,
"Discovered {0} Objective-C classes", num_class_infos);
2022 if (num_class_infos > 0) {
2024 DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
2025 if (process->
ReadMemory(class_infos_addr, buffer.GetBytes(),
2031 m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
2037 LLDB_LOGF(log,
"Error evaluating our find class name function.");
2038 diagnostics.
Dump(log);
2043 LLDB_LOGF(log,
"Error writing function arguments.");
2044 diagnostics.
Dump(log);
2068 for (
uint32_t i = 0; i < num_class_infos; ++i) {
2074 log,
"AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
2082 "AppleObjCRuntimeV2 found cached isa=0x%" PRIx64
2083 ", ignoring this class info",
2098 AddClass(isa, descriptor_sp, name_hash);
2101 descriptor_sp->GetClassName().AsCString(
nullptr));
2105 "AppleObjCRuntimeV2 added isa=0x%" PRIx64
2106 ", hash=0x%8.8x, name=%s",
2108 descriptor_sp->GetClassName().AsCString(
"<unknown>"));
2112 LLDB_LOGF(log,
"AppleObjCRuntimeV2 parsed %" PRIu32
" class infos",
2122 if (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())
2130 Process *process = m_runtime.GetProcess();
2131 if (process ==
nullptr)
2143 if (!thread_sp->SafeToCallFunctions())
2146 thread_sp->CalculateExecutionContext(exe_ctx);
2147 TypeSystemClangSP scratch_ts_sp =
2161 const lldb::addr_t objc_opt_ptr = m_runtime.GetSharedCacheReadOnlyAddress();
2163 m_runtime.GetSharedCacheBaseAddress();
2171 const uint32_t max_num_classes = 163840;
2173 UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx);
2174 if (!get_class_info_code) {
2182 if (!get_shared_cache_class_info_function) {
2183 LLDB_LOGF(log,
"Failed to get implementation lookup function caller.");
2192 const uint32_t class_info_byte_size = addr_size + 4;
2193 const uint32_t class_infos_byte_size = max_num_classes * class_info_byte_size;
2195 class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
2196 const uint32_t relative_selector_offset_addr_size = 64;
2199 ePermissionsReadable | ePermissionsWritable, err);
2203 "unable to allocate %" PRIu32
2204 " bytes in process for shared cache read",
2205 class_infos_byte_size);
2209 std::lock_guard<std::mutex> guard(m_mutex);
2220 bool dump_log = type_log && type_log->
GetVerbose();
2224 bool success =
false;
2226 diagnostics.
Clear();
2230 exe_ctx, m_args, arguments, diagnostics)) {
2240 scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(
eEncodingUint, 32);
2247 diagnostics.
Clear();
2252 exe_ctx, &m_args, options, diagnostics, return_value);
2257 LLDB_LOG(log,
"Discovered {0} Objective-C classes in the shared cache",
2261 assert(num_class_infos <= max_num_classes);
2262 if (num_class_infos > 0) {
2263 if (num_class_infos > max_num_classes) {
2264 num_class_infos = max_num_classes;
2273 if (process->
ReadMemory(relative_selector_offset_addr,
2274 relative_selector_offset_buffer.GetBytes(),
2279 relative_selector_offset_buffer.GetBytes(),
2283 uint64_t relative_selector_offset =
2284 relative_selector_offset_data.
GetU64(&offset);
2285 if (relative_selector_offset > 0) {
2287 m_runtime.SetRelativeSelectorBaseAddr(objc_opt_ptr +
2288 relative_selector_offset);
2294 num_class_infos * class_info_byte_size, 0);
2295 if (process->
ReadMemory(class_infos_addr, class_infos_buffer.GetBytes(),
2298 DataExtractor class_infos_data(class_infos_buffer.GetBytes(),
2302 m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
2309 LLDB_LOGF(log,
"Error evaluating our find class name function.");
2310 diagnostics.
Dump(log);
2315 LLDB_LOGF(log,
"Error writing function arguments.");
2316 diagnostics.
Dump(log);
2332 if (objc_module_sp) {
2333 ObjectFile *objc_object = objc_module_sp->GetObjectFile();
2336 SectionList *section_list = objc_module_sp->GetSectionList();
2339 SectionSP text_segment_sp(
2342 if (text_segment_sp) {
2343 SectionSP objc_opt_section_sp(
2344 text_segment_sp->GetChildren().FindSectionByName(
2347 if (objc_opt_section_sp) {
2348 return objc_opt_section_sp->GetLoadBaseAddress(
2396 !class_count_changed)
2416 const uint32_t num_classes_to_warn_at = 500;
2422 "attempted to read objc class data - results: "
2423 "[dynamic_update]: ran: %s, retry: %s, count: %" PRIu32
2424 " [shared_cache_update]: ran: %s, retry: %s, count: %" PRIu32,
2428 shared_cache_update_result.
m_update_ran ?
"yes" :
"no",
2444 num_classes_to_warn_at)
2460 uint64_t objc_debug_realized_class_generation_count =
2462 process,
ConstString(
"objc_debug_realized_class_generation_count"),
2468 objc_debug_realized_class_generation_count)
2473 "objc_debug_realized_class_generation_count changed from {0} to {1}",
2475 objc_debug_realized_class_generation_count);
2478 objc_debug_realized_class_generation_count;
2488 llvm::StringRef platform_plugin_name_sr = platform_sp->GetPluginName();
2489 if (platform_plugin_name_sr.endswith(
"-simulator"))
2507 "the process. This may reduce the quality of type "
2508 "information available.\n",
2513 "could not execute support code to read "
2514 "Objective-C class data in the process. This may "
2515 "reduce the quality of type information available.\n",
2520 "could not execute support code to read Objective-C class data because "
2521 "it's not yet safe to do so, and will be retried later.\n",
2522 debugger.
GetID(),
nullptr);
2542 llvm::raw_string_ostream os(buffer);
2544 os <<
"libobjc.A.dylib is being read from process memory. This "
2545 "indicates that LLDB could not ";
2546 if (PlatformSP platform_sp = target.
GetPlatform()) {
2547 if (platform_sp->IsHost()) {
2548 os <<
"read from the host's in-memory shared cache";
2550 os <<
"find the on-disk shared cache for this device";
2553 os <<
"read from the shared cache";
2555 os <<
". This will likely reduce debugging performance.\n";
2571 const char *name_cstr = name.
AsCString();
2574 llvm::StringRef name_strref(name_cstr);
2576 llvm::StringRef ivar_prefix(
"OBJC_IVAR_$_");
2577 llvm::StringRef class_prefix(
"OBJC_CLASS_$_");
2579 if (name_strref.startswith(ivar_prefix)) {
2580 llvm::StringRef ivar_skipped_prefix =
2581 name_strref.substr(ivar_prefix.size());
2582 std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar =
2583 ivar_skipped_prefix.split(
'.');
2585 if (class_and_ivar.first.size() && class_and_ivar.second.size()) {
2586 const ConstString class_name_cs(class_and_ivar.first);
2591 const ConstString ivar_name_cs(class_and_ivar.second);
2592 const char *ivar_name_cstr = ivar_name_cs.
AsCString();
2594 auto ivar_func = [&ret,
2595 ivar_name_cstr](
const char *name,
const char *type,
2598 if (!strcmp(name, ivar_name_cstr)) {
2605 descriptor->Describe(
2606 std::function<
void(
ObjCISA)>(
nullptr),
2607 std::function<
bool(
const char *,
const char *)>(
nullptr),
2608 std::function<
bool(
const char *,
const char *)>(
nullptr),
2612 }
else if (name_strref.startswith(class_prefix)) {
2613 llvm::StringRef class_skipped_prefix =
2614 name_strref.substr(class_prefix.size());
2615 const ConstString class_name_cs(class_skipped_prefix);
2620 ret = descriptor->GetISA();
2642 process,
ConstString(
"objc_debug_isa_magic_value"), objc_module_sp,
2653 log->
PutCString(
"AOCRT::NPI: Found all the non-indexed ISA masks");
2655 bool foundError =
false;
2657 process,
ConstString(
"objc_debug_indexed_isa_magic_mask"), objc_module_sp,
2659 foundError |=
error.Fail();
2662 process,
ConstString(
"objc_debug_indexed_isa_magic_value"),
2663 objc_module_sp,
error);
2664 foundError |=
error.Fail();
2667 process,
ConstString(
"objc_debug_indexed_isa_index_mask"), objc_module_sp,
2669 foundError |=
error.Fail();
2672 process,
ConstString(
"objc_debug_indexed_isa_index_shift"),
2673 objc_module_sp,
error);
2674 foundError |=
error.Fail();
2676 auto objc_indexed_classes =
2678 objc_module_sp,
error,
false);
2679 foundError |=
error.Fail();
2682 log->
PutCString(
"AOCRT::NPI: Found all the indexed ISA masks");
2688 runtime, objc_module_sp, objc_debug_isa_class_mask,
2689 objc_debug_isa_magic_mask, objc_debug_isa_magic_value,
2690 objc_debug_indexed_isa_magic_mask, objc_debug_indexed_isa_magic_value,
2691 objc_debug_indexed_isa_index_mask, objc_debug_indexed_isa_index_shift,
2692 foundError ? 0 : objc_indexed_classes);
2703 process,
ConstString(
"objc_debug_taggedpointer_mask"), objc_module_sp,
2709 process,
ConstString(
"objc_debug_taggedpointer_slot_shift"),
2710 objc_module_sp,
error,
true, 4);
2715 process,
ConstString(
"objc_debug_taggedpointer_slot_mask"),
2716 objc_module_sp,
error,
true, 4);
2721 process,
ConstString(
"objc_debug_taggedpointer_payload_lshift"),
2722 objc_module_sp,
error,
true, 4);
2727 process,
ConstString(
"objc_debug_taggedpointer_payload_rshift"),
2728 objc_module_sp,
error,
true, 4);
2733 process,
ConstString(
"objc_debug_taggedpointer_classes"), objc_module_sp,
2742 process,
ConstString(
"objc_debug_taggedpointer_ext_mask"),
2743 objc_module_sp,
error);
2748 process,
ConstString(
"objc_debug_taggedpointer_ext_slot_shift"),
2749 objc_module_sp,
error,
true, 4);
2754 process,
ConstString(
"objc_debug_taggedpointer_ext_slot_mask"),
2755 objc_module_sp,
error,
true, 4);
2760 process,
ConstString(
"objc_debug_taggedpointer_ext_classes"),
2761 objc_module_sp,
error,
false);
2765 auto objc_debug_taggedpointer_ext_payload_lshift =
2767 process,
ConstString(
"objc_debug_taggedpointer_ext_payload_lshift"),
2768 objc_module_sp,
error,
true, 4);
2772 auto objc_debug_taggedpointer_ext_payload_rshift =
2774 process,
ConstString(
"objc_debug_taggedpointer_ext_payload_rshift"),
2775 objc_module_sp,
error,
true, 4);
2780 runtime, objc_debug_taggedpointer_mask,
2781 objc_debug_taggedpointer_ext_mask, objc_debug_taggedpointer_slot_shift,
2782 objc_debug_taggedpointer_ext_slot_shift,
2783 objc_debug_taggedpointer_slot_mask,
2784 objc_debug_taggedpointer_ext_slot_mask,
2785 objc_debug_taggedpointer_payload_lshift,
2786 objc_debug_taggedpointer_payload_rshift,
2787 objc_debug_taggedpointer_ext_payload_lshift,
2788 objc_debug_taggedpointer_ext_payload_rshift,
2789 objc_debug_taggedpointer_classes, objc_debug_taggedpointer_ext_classes);
2796 runtime, objc_debug_taggedpointer_mask,
2797 objc_debug_taggedpointer_slot_shift, objc_debug_taggedpointer_slot_mask,
2798 objc_debug_taggedpointer_payload_lshift,
2799 objc_debug_taggedpointer_payload_rshift,
2800 objc_debug_taggedpointer_classes);
2811 if (!IsPossibleTaggedPointer(ptr))
2814 uint32_t foundation_version = m_runtime.GetFoundationVersion();
2819 uint64_t class_bits = (ptr & 0xE) >> 1;
2825 static ConstString g_NSManagedObject(
"NSManagedObject");
2828 if (foundation_version >= 900) {
2829 switch (class_bits) {
2840 name = g_NSManagedObject;
2849 switch (class_bits) {
2854 name = g_NSManagedObject;
2867 lldb::addr_t unobfuscated = ptr ^ m_runtime.GetTaggedPointerObfuscator();
2874 uint32_t objc_debug_taggedpointer_slot_shift,
2875 uint32_t objc_debug_taggedpointer_slot_mask,
2876 uint32_t objc_debug_taggedpointer_payload_lshift,
2877 uint32_t objc_debug_taggedpointer_payload_rshift,
2880 m_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask),
2881 m_objc_debug_taggedpointer_slot_shift(
2882 objc_debug_taggedpointer_slot_shift),
2883 m_objc_debug_taggedpointer_slot_mask(objc_debug_taggedpointer_slot_mask),
2884 m_objc_debug_taggedpointer_payload_lshift(
2885 objc_debug_taggedpointer_payload_lshift),
2886 m_objc_debug_taggedpointer_payload_rshift(
2887 objc_debug_taggedpointer_payload_rshift),
2888 m_objc_debug_taggedpointer_classes(objc_debug_taggedpointer_classes) {}
2892 return (ptr & m_objc_debug_taggedpointer_mask) != 0;
2899 uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
2901 if (!IsPossibleTaggedPointer(unobfuscated))
2904 uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) &
2905 m_objc_debug_taggedpointer_slot_mask;
2907 CacheIterator iterator = m_cache.find(slot), end = m_cache.end();
2908 if (iterator != end) {
2909 actual_class_descriptor_sp = iterator->second;
2911 Process *process(m_runtime.GetProcess());
2913 m_objc_debug_taggedpointer_classes;
2916 if (
error.Fail() || slot_data == 0 ||
2919 actual_class_descriptor_sp =
2920 m_runtime.GetClassDescriptorFromISA((
ObjCISA)slot_data);
2921 if (!actual_class_descriptor_sp) {
2922 if (ABISP abi_sp = process->
GetABI()) {
2924 actual_class_descriptor_sp =
2925 m_runtime.GetClassDescriptorFromISA(fixed_isa);
2928 if (!actual_class_descriptor_sp)
2930 m_cache[slot] = actual_class_descriptor_sp;
2933 uint64_t data_payload =
2934 ((unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
2935 m_objc_debug_taggedpointer_payload_rshift);
2936 int64_t data_payload_signed =
2937 ((int64_t)(unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
2938 m_objc_debug_taggedpointer_payload_rshift);
2940 actual_class_descriptor_sp, data_payload, data_payload_signed));
2945 uint64_t objc_debug_taggedpointer_ext_mask,
2946 uint32_t objc_debug_taggedpointer_slot_shift,
2947 uint32_t objc_debug_taggedpointer_ext_slot_shift,
2948 uint32_t objc_debug_taggedpointer_slot_mask,
2949 uint32_t objc_debug_taggedpointer_ext_slot_mask,
2950 uint32_t objc_debug_taggedpointer_payload_lshift,
2951 uint32_t objc_debug_taggedpointer_payload_rshift,
2952 uint32_t objc_debug_taggedpointer_ext_payload_lshift,
2953 uint32_t objc_debug_taggedpointer_ext_payload_rshift,
2957 runtime, objc_debug_taggedpointer_mask,
2958 objc_debug_taggedpointer_slot_shift,
2959 objc_debug_taggedpointer_slot_mask,
2960 objc_debug_taggedpointer_payload_lshift,
2961 objc_debug_taggedpointer_payload_rshift,
2962 objc_debug_taggedpointer_classes),
2964 m_objc_debug_taggedpointer_ext_mask(objc_debug_taggedpointer_ext_mask),
2965 m_objc_debug_taggedpointer_ext_slot_shift(
2966 objc_debug_taggedpointer_ext_slot_shift),
2967 m_objc_debug_taggedpointer_ext_slot_mask(
2968 objc_debug_taggedpointer_ext_slot_mask),
2969 m_objc_debug_taggedpointer_ext_payload_lshift(
2970 objc_debug_taggedpointer_ext_payload_lshift),
2971 m_objc_debug_taggedpointer_ext_payload_rshift(
2972 objc_debug_taggedpointer_ext_payload_rshift),
2973 m_objc_debug_taggedpointer_ext_classes(
2974 objc_debug_taggedpointer_ext_classes) {}
2978 if (!IsPossibleTaggedPointer(ptr))
2981 if (m_objc_debug_taggedpointer_ext_mask == 0)
2984 return ((ptr & m_objc_debug_taggedpointer_ext_mask) ==
2985 m_objc_debug_taggedpointer_ext_mask);
2992 uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
2994 if (!IsPossibleTaggedPointer(unobfuscated))
2997 if (!IsPossibleExtendedTaggedPointer(unobfuscated))
3000 uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) &
3001 m_objc_debug_taggedpointer_ext_slot_mask;
3003 CacheIterator iterator = m_ext_cache.find(slot), end = m_ext_cache.end();
3004 if (iterator != end) {
3005 actual_class_descriptor_sp = iterator->second;
3007 Process *process(m_runtime.GetProcess());
3009 m_objc_debug_taggedpointer_ext_classes;
3012 if (
error.Fail() || slot_data == 0 ||
3015 actual_class_descriptor_sp =
3016 m_runtime.GetClassDescriptorFromISA((
ObjCISA)slot_data);
3017 if (!actual_class_descriptor_sp)
3019 m_ext_cache[slot] = actual_class_descriptor_sp;
3022 uint64_t data_payload = (((uint64_t)unobfuscated
3023 << m_objc_debug_taggedpointer_ext_payload_lshift) >>
3024 m_objc_debug_taggedpointer_ext_payload_rshift);
3025 int64_t data_payload_signed =
3026 ((int64_t)((int64_t)unobfuscated
3027 << m_objc_debug_taggedpointer_ext_payload_lshift) >>
3028 m_objc_debug_taggedpointer_ext_payload_rshift);
3031 actual_class_descriptor_sp, data_payload, data_payload_signed));
3036 uint64_t objc_debug_isa_class_mask, uint64_t objc_debug_isa_magic_mask,
3037 uint64_t objc_debug_isa_magic_value,
3038 uint64_t objc_debug_indexed_isa_magic_mask,
3039 uint64_t objc_debug_indexed_isa_magic_value,
3040 uint64_t objc_debug_indexed_isa_index_mask,
3041 uint64_t objc_debug_indexed_isa_index_shift,
3044 m_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
3045 m_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
3046 m_objc_debug_isa_magic_value(objc_debug_isa_magic_value),
3047 m_objc_debug_indexed_isa_magic_mask(objc_debug_indexed_isa_magic_mask),
3048 m_objc_debug_indexed_isa_magic_value(objc_debug_indexed_isa_magic_value),
3049 m_objc_debug_indexed_isa_index_mask(objc_debug_indexed_isa_index_mask),
3050 m_objc_debug_indexed_isa_index_shift(objc_debug_indexed_isa_index_shift),
3051 m_objc_indexed_classes(objc_indexed_classes), m_indexed_isa_cache() {}
3056 if (!EvaluateNonPointerISA(isa, real_isa))
3058 auto cache_iter = m_cache.find(real_isa);
3059 if (cache_iter != m_cache.end())
3060 return cache_iter->second;
3061 auto descriptor_sp =
3062 m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(real_isa);
3064 m_cache[real_isa] = descriptor_sp;
3065 return descriptor_sp;
3072 LLDB_LOGF(log,
"AOCRT::NPI Evaluate(isa = 0x%" PRIx64
")", (uint64_t)isa);
3074 if ((isa & ~m_objc_debug_isa_class_mask) == 0)
3081 if (m_objc_debug_indexed_isa_magic_mask &&
3082 m_objc_debug_indexed_isa_magic_value &&
3083 m_objc_debug_indexed_isa_index_mask &&
3084 m_objc_debug_indexed_isa_index_shift && m_objc_indexed_classes) {
3085 if ((isa & ~m_objc_debug_indexed_isa_index_mask) == 0)
3088 if ((isa & m_objc_debug_indexed_isa_magic_mask) ==
3089 m_objc_debug_indexed_isa_magic_value) {
3091 uintptr_t index = (isa & m_objc_debug_indexed_isa_index_mask) >>
3092 m_objc_debug_indexed_isa_index_shift;
3097 if (index > m_indexed_isa_cache.size()) {
3099 "AOCRT::NPI (index = %" PRIu64
3100 ") exceeds cache (size = %" PRIu64
")",
3101 (uint64_t)index, (uint64_t)m_indexed_isa_cache.size());
3103 Process *process(m_runtime.GetProcess());
3106 if (!objc_module_sp)
3111 process,
ConstString(
"objc_indexed_classes_count"), objc_module_sp,
3116 LLDB_LOGF(log,
"AOCRT::NPI (new class count = %" PRIu64
")",
3117 (uint64_t)objc_indexed_classes_count);
3119 if (objc_indexed_classes_count > m_indexed_isa_cache.size()) {
3123 auto num_new_classes =
3124 objc_indexed_classes_count - m_indexed_isa_cache.size();
3129 m_objc_indexed_classes + (m_indexed_isa_cache.size() * addr_size);
3135 LLDB_LOGF(log,
"AOCRT::NPI (read new classes count = %" PRIu64
")",
3136 (uint64_t)num_new_classes);
3144 for (
unsigned i = 0; i != num_new_classes; ++i)
3145 m_indexed_isa_cache.push_back(data.
GetAddress(&offset));
3150 if (index > m_indexed_isa_cache.size())
3153 LLDB_LOGF(log,
"AOCRT::NPI Evaluate(ret_isa = 0x%" PRIx64
")",
3154 (uint64_t)m_indexed_isa_cache[index]);
3156 ret_isa = m_indexed_isa_cache[index];
3157 return (ret_isa != 0);
3165 if ((isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value) {
3166 ret_isa = isa & m_objc_debug_isa_class_mask;
3167 return (ret_isa != 0);
3175 std::make_shared<AppleObjCTypeEncodingParser>(*
this);
3184 non_pointer_isa_cache->EvaluateNonPointerISA(isa, ret);
3193 static ConstString g_dunder_kCFBooleanFalse(
"__kCFBooleanFalse");
3194 static ConstString g_dunder_kCFBooleanTrue(
"__kCFBooleanTrue");
3195 static ConstString g_kCFBooleanFalse(
"kCFBooleanFalse");
3196 static ConstString g_kCFBooleanTrue(
"kCFBooleanTrue");
3227 lldb::addr_t false_addr = get_symbol(g_dunder_kCFBooleanFalse, g_kCFBooleanFalse);
3228 lldb::addr_t true_addr = get_symbol(g_dunder_kCFBooleanTrue, g_kCFBooleanTrue);
3242#pragma mark Frame recognizers
3247 ThreadSP thread_sp = frame_sp->GetThread();
3248 ProcessSP process_sp = thread_sp->GetProcess();
3250 const lldb::ABISP &abi = process_sp->GetABI();
3254 TypeSystemClangSP scratch_ts_sp =
3266 if (!abi->GetArgumentValues(*thread_sp, args))
3271 Value value(exception_addr);
3280 m_arguments->Append(exception);
3282 m_stop_desc =
"hit Objective-C exception";
3291 lldb::RecognizedStackFrameSP
3293 return lldb::RecognizedStackFrameSP(
3297 return "ObjC Exception Throw StackFrame Recognizer";
3305 std::vector<ConstString> symbols = {function};
static const char * g_get_dynamic_class_info_name
static void RegisterObjCExceptionRecognizer(Process *process)
static const char * g_get_dynamic_class_info3_body
static const char * g_get_dynamic_class_info2_body
static const char * g_get_shared_cache_class_info_name
static const char * g_get_dynamic_class_info3_name
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)
static constexpr OptionDefinition g_objc_classtable_dump_options[]
static const char * g_get_shared_cache_class_info_body
static const char * g_shared_cache_class_name_funcptr
static const char * g_get_dynamic_class_info_body
static const char * g_get_dynamic_class_info2_name
static bool DoesProcessHaveSharedCache(Process &process)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_SCOPED_TIMER()
CommandObjectMultiwordObjC_ClassTable(CommandInterpreter &interpreter)
~CommandObjectMultiwordObjC_ClassTable() override=default
~CommandObjectMultiwordObjC_TaggedPointer_Info() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectMultiwordObjC_TaggedPointer_Info(CommandInterpreter &interpreter)
CommandObjectMultiwordObjC_TaggedPointer(CommandInterpreter &interpreter)
~CommandObjectMultiwordObjC_TaggedPointer() override=default
~CommandObjectMultiwordObjC() override=default
CommandObjectMultiwordObjC(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
~CommandOptions() override=default
OptionValueBoolean m_verbose
Options * GetOptions() override
~CommandObjectObjC_ClassTable_Dump() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectObjC_ClassTable_Dump(CommandInterpreter &interpreter)
lldb::ValueObjectSP GetExceptionObject() override
ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp)
lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) override
std::string GetName() override
bool operator==(const const_iterator &rhs) const
const_iterator & operator++()
void AdvanceToValidIndex()
const_iterator & operator=(const const_iterator &rhs)
RemoteNXMapTable & m_parent
const_iterator(RemoteNXMapTable &parent, int index)
const element operator*() const
bool operator!=(const const_iterator &rhs) const
const_iterator(const const_iterator &rhs)
bool ParseHeader(Process *process, lldb::addr_t load_addr)
std::pair< ConstString, ObjCLanguageRuntime::ObjCISA > element
lldb::addr_t GetTableLoadAddress() const
const_iterator m_end_iterator
uint32_t GetCount() const
lldb::addr_t GetBucketDataPointer() const
uint32_t GetBucketCount() const
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
void SetRawAddress(lldb::addr_t addr)
void UpdateSignature(const RemoteNXMapTable &hash_table)
bool NeedsUpdate(Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
lldb::addr_t m_buckets_ptr
bool EvaluateNonPointerISA(ObjCISA isa, ObjCISA &ret_isa)
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(ObjCISA isa)
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)
static NonPointerISACache * CreateInstance(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp)
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
Cache::iterator CacheIterator
bool IsPossibleExtendedTaggedPointer(lldb::addr_t ptr)
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)
bool IsPossibleTaggedPointer(lldb::addr_t ptr) override
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
Cache::iterator CacheIterator
ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr) override
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)
bool IsPossibleTaggedPointer(lldb::addr_t ptr) override
static TaggedPointerVendorV2 * CreateInstance(AppleObjCRuntimeV2 &runtime, const lldb::ModuleSP &objc_module_sp)
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override
bool m_has_objc_getRealizedClassList_trylock
bool IsTaggedPointer(lldb::addr_t ptr) override
uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data, uint32_t num_class_infos)
bool RealizedClassGenerationCountChanged()
Update the generation count of realized classes.
static llvm::StringRef GetPluginNameStatic()
EncodingToTypeSP GetEncodingToType() override
ObjCISA GetPointerISA(ObjCISA isa)
AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp)
NonPointerISACache * GetNonPointerIsaCache()
std::once_flag m_no_expanded_cache_warning
size_t GetByteOffsetForIvar(CompilerType &parent_qual_type, const char *ivar_name) override
lldb::addr_t m_isa_hash_table_ptr
HashTableSignature m_hash_signature
bool m_has_object_getClass
SharedCacheClassInfoExtractor m_shared_cache_class_info_extractor
DynamicClassInfoExtractor m_dynamic_class_info_extractor
lldb::addr_t GetISAHashTablePointer()
ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa) override
bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, Value::ValueType &value_type) override
ClassDescriptorSP GetClassDescriptor(ValueObject &in_value) override
@ eExpressionExecutionFailure
friend class ClassDescriptorV2
lldb::addr_t LookupRuntimeSymbol(ConstString name) override
bool HasSymbol(ConstString Name)
EncodingToTypeSP m_encoding_to_type_sp
lldb::addr_t GetSharedCacheBaseAddress()
std::once_flag m_no_classes_cached_warning
std::optional< std::pair< lldb::addr_t, lldb::addr_t > > m_CFBoolean_values
std::unique_ptr< DeclVendor > m_decl_vendor_up
uint64_t m_realized_class_generation_count
lldb::addr_t GetTaggedPointerObfuscator()
void WarnIfNoExpandedSharedCache()
lldb::addr_t m_tagged_pointer_obfuscator
std::unique_ptr< TaggedPointerVendor > m_tagged_pointer_vendor_up
bool GetCFBooleanValuesIfNeeded()
lldb::addr_t GetSharedCacheReadOnlyAddress()
void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false) override
void UpdateISAToDescriptorMapIfNeeded() override
lldb::BreakpointResolverSP CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp, bool throw_bp) override
lldb::ModuleSP m_objc_module_sp
void WarnIfNoClassesCached(SharedCacheWarningReason reason)
static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language)
DeclVendor * GetDeclVendor() override
bool m_has_objc_copyRealizedClassList
virtual void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false)
lldb::ModuleWP m_objc_module_wp
static std::tuple< FileSpec, ConstString > GetExceptionThrowLocation()
static ObjCRuntimeVersions GetObjCVersion(Process *process, lldb::ModuleSP &objc_module_sp)
lldb::ModuleSP GetObjCModule()
bool CouldHaveDynamicValue(ValueObject &in_value) override
A command line argument class.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
std::vector< CommandArgumentData > CommandArgumentEntry
void AppendErrorWithFormatv(const char *format, Args &&... args)
void void AppendError(llvm::StringRef in_string)
void SetStatus(lldb::ReturnStatus status)
Stream & GetOutputStream()
Generic representation of a type in a programming language.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
ConstString GetTypeName(bool BaseOnly=false) const
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
bool IsEmpty() const
Test for empty string.
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::offset_t GetByteSize() const override
A class to manage flag bits.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
A plug-in interface definition class for dynamic loaders.
void SetUnwindOnError(bool unwind=false)
void SetTryAllThreads(bool try_others=true)
void SetTimeout(const Timeout< std::micro > &timeout)
void SetStopOthers(bool stop_others=true)
void SetIsForUtilityExpr(bool b)
void SetIgnoreBreakpoints(bool ignore=false)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
Target & GetTargetRef() const
Returns a reference to the target object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
const ConstString & GetFilename() const
Filename string const get accessor.
Encapsulates a function that can be called.
ValueList GetArgumentValues() const
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.
bool WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager)
Insert the default function argument struct.
void PutCString(const char *cstr)
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
virtual bool IsPossibleTaggedPointer(lldb::addr_t ptr)=0
virtual ObjCLanguageRuntime::ClassDescriptorSP GetClassDescriptor(lldb::addr_t ptr)=0
uint32_t m_isa_to_descriptor_stop_id
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
bool AddClass(ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
std::pair< ISAToDescriptorIterator, ISAToDescriptorIterator > GetDescriptorIteratorPair(bool update_if_needed=true)
virtual TaggedPointerVendor * GetTaggedPointerVendor()
lldb::TypeSP LookupInCompleteClassCache(ConstString &name)
ClassDescriptorSP GetNonKVOClassDescriptor(ValueObject &in_value)
virtual ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa)
bool ISAIsCached(ObjCISA isa) const
static ObjCLanguageRuntime * Get(Process &process)
virtual ClassDescriptorSP GetClassDescriptorFromClassName(ConstString class_name)
static lldb::BreakpointPreconditionSP GetBreakpointExceptionPrecondition(lldb::LanguageType language, bool throw_bp)
std::shared_ptr< EncodingToType > EncodingToTypeSP
A plug-in interface definition class for object file parsers.
bool IsInMemory() const
Returns true if the object file exists only in memory.
A command line option parsing protocol class.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
std::chrono::seconds GetUtilityExpressionTimeout() const
A plug-in interface definition class for debugging a process.
ThreadList & GetThreadList()
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process.
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
lldb::TargetSP CalculateTarget() override
virtual lldb_private::StructuredData::ObjectSP GetSharedCacheInfo()
lldb::ByteOrder GetByteOrder() const
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.
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Status DeallocateMemory(lldb::addr_t ptr)
The public interface to deallocating memory in the process.
uint32_t GetAddressByteSize() const
uint32_t GetStopID() const
const lldb::ABISP & GetABI()
Target & GetTarget()
Get the target object pointer for this module.
This class provides extra information about a stack frame that was provided by a specific stack frame...
unsigned long long ULongLong(unsigned long long fail_value=0) const
unsigned long ULong(unsigned long fail_value=0) const
static lldb::TypeSystemClangSP GetForTarget(Target &target, std::optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef< ConstString > symbols, bool first_instruction_only=true)
A base class for frame recognizers.
bool Success() const
Test for success condition.
void Format(const char *format, Args &&... args)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
ObjectSP GetValueForKey(llvm::StringRef key) const
Dictionary * GetAsDictionary()
std::shared_ptr< Object > ObjectSP
Defines a list of symbol context objects.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Symbol * symbol
The Symbol for a given query.
lldb::addr_t GetLoadAddress(Target *target) const
bool ValueIsAddress() const
Address & GetAddressRef()
DynamicClassInfoHelper GetDynamicClassInfoHelper() const
StackFrameRecognizerManager & GetFrameRecognizerManager()
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.
lldb::PlatformSP GetPlatform()
const ModuleList & GetImages() const
Get accessor for the images for this process.
lldb::ThreadSP GetExpressionExecutionThread()
Sometimes you can find the name of the type corresponding to an object, but we don't have debug infor...
void SetName(ConstString type_name)
void SetCompilerType(CompilerType compiler_type)
void SetTypeSP(lldb::TypeSP type_sp)
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
FunctionCaller * GetFunctionCaller()
void PushValue(const Value &value)
Value * GetValueAtIndex(size_t idx)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
A collection of ValueObject values that.
static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type)
lldb::addr_t GetPointerValue(AddressType *address_type=nullptr)
CompilerType GetCompilerType()
lldb::ProcessSP GetProcessSP() const
virtual bool IsBaseClass()
lldb::TargetSP GetTargetSP() const
virtual ValueObject * GetParent()
const ExecutionContextRef & GetExecutionContextRef() const
const Scalar & GetScalar() const
ValueType
Type that describes Value::m_value.
@ Scalar
A raw scalar value.
void SetCompilerType(const CompilerType &compiler_type)
void SetValueType(ValueType value_type)
#define LLDB_INVALID_MODULE_VERSION
#define UNUSED_IF_ASSERT_DISABLED(x)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_IVAR_OFFSET
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
@ eDynamicClassInfoHelperCopyRealizedClassList
@ eDynamicClassInfoHelperGetRealizedClassList
@ eDynamicClassInfoHelperAuto
@ eDynamicClassInfoHelperRealizedClassesStruct
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
ExpressionResults
The results of expression evaluation.
@ eEncodingUint
unsigned integer
@ eReturnStatusSuccessFinishResult
@ eArgTypeRegularExpression
bool LLDB_API operator==(const SBAddress &lhs, const SBAddress &rhs)
@ eValueTypeVariableArgument
function argument variables
static DescriptorMapUpdateResult Fail()
static DescriptorMapUpdateResult Success(uint32_t found)
static DescriptorMapUpdateResult Retry()
Used to build individual command argument lists.
ArgumentRepetitionType arg_repetition
lldb::CommandArgumentType arg_type
static lldb::addr_t ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error_ptr)
Try to parse an address.
lldb::user_id_t GetID() const
Get accessor for the user ID.