@@ -157,6 +157,16 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr
157157
158158)" ;
159159
160+ // We'll substitute in class_getName or class_getNameRaw depending
161+ // on which is present.
162+ static const char *g_shared_cache_class_name_funcptr = R"(
163+ extern "C"
164+ {
165+ const char *%s(void *objc_class);
166+ const char *(*class_name_lookup_func)(void *) = %s;
167+ }
168+ )" ;
169+
160170static const char *g_get_shared_cache_class_info_name =
161171 " __lldb_apple_objc_v2_get_shared_cache_class_info" ;
162172// Testing using the new C++11 raw string literals. If this breaks GCC then we
@@ -165,7 +175,6 @@ static const char *g_get_shared_cache_class_info_body = R"(
165175
166176extern "C"
167177{
168- const char *class_getName(void *objc_class);
169178 size_t strlen(const char *);
170179 char *strncpy (char * s1, const char * s2, size_t n);
171180 int printf(const char * format, ...);
@@ -286,7 +295,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
286295 if (class_infos && idx < max_class_infos)
287296 {
288297 class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
289- const char *name = class_getName (class_infos[idx].isa);
298+ const char *name = class_name_lookup_func (class_infos[idx].isa);
290299 DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
291300 // Hash the class name so we don't have to read it
292301 const char *s = name;
@@ -329,7 +338,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
329338 if (class_infos && idx < max_class_infos)
330339 {
331340 class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
332- const char *name = class_getName (class_infos[idx].isa);
341+ const char *name = class_name_lookup_func (class_infos[idx].isa);
333342 DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
334343 // Hash the class name so we don't have to read it
335344 const char *s = name;
@@ -1589,9 +1598,46 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
15891598
15901599 if (!m_get_shared_cache_class_info_code) {
15911600 Status error;
1601+
1602+ // If the inferior objc.dylib has the class_getNameRaw function,
1603+ // use that in our jitted expression. Else fall back to the old
1604+ // class_getName.
1605+ static ConstString g_class_getName_symbol_name (" class_getName" );
1606+ static ConstString g_class_getNameRaw_symbol_name (" class_getNameRaw" );
1607+ ConstString class_name_getter_function_name = g_class_getName_symbol_name;
1608+
1609+ ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get (*process);
1610+ if (objc_runtime) {
1611+ const ModuleList &images = process->GetTarget ().GetImages ();
1612+ std::lock_guard<std::recursive_mutex> guard (images.GetMutex ());
1613+ for (size_t i = 0 ; i < images.GetSize (); ++i) {
1614+ lldb::ModuleSP mod_sp = images.GetModuleAtIndexUnlocked (i);
1615+ if (objc_runtime->IsModuleObjCLibrary (mod_sp)) {
1616+ const Symbol *symbol =
1617+ mod_sp->FindFirstSymbolWithNameAndType (g_class_getNameRaw_symbol_name,
1618+ lldb::eSymbolTypeCode);
1619+ if (symbol &&
1620+ (symbol->ValueIsAddress () || symbol->GetAddressRef ().IsValid ())) {
1621+ class_name_getter_function_name = g_class_getNameRaw_symbol_name;
1622+ }
1623+ }
1624+ }
1625+ }
1626+
1627+ // Substitute in the correct class_getName / class_getNameRaw function name,
1628+ // concatenate the two parts of our expression text. The format string
1629+ // has two %s's, so provide the name twice.
1630+ char *class_name_func_ptr_expr = nullptr ;
1631+ asprintf (&class_name_func_ptr_expr, g_shared_cache_class_name_funcptr,
1632+ class_name_getter_function_name.AsCString (),
1633+ class_name_getter_function_name.AsCString ());
1634+ std::string shared_class_expression = class_name_func_ptr_expr;
1635+ shared_class_expression += g_get_shared_cache_class_info_body;
1636+ free (class_name_func_ptr_expr);
1637+
15921638 m_get_shared_cache_class_info_code.reset (
15931639 GetTargetRef ().GetUtilityFunctionForLanguage (
1594- g_get_shared_cache_class_info_body , eLanguageTypeObjC,
1640+ shared_class_expression. c_str () , eLanguageTypeObjC,
15951641 g_get_shared_cache_class_info_name, error));
15961642 if (error.Fail ()) {
15971643 if (log)
0 commit comments