@@ -157,6 +157,16 @@ __lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr
157
157
158
158
)" ;
159
159
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
+
160
170
static const char *g_get_shared_cache_class_info_name =
161
171
" __lldb_apple_objc_v2_get_shared_cache_class_info" ;
162
172
// 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"(
165
175
166
176
extern "C"
167
177
{
168
- const char *class_getName(void *objc_class);
169
178
size_t strlen(const char *);
170
179
char *strncpy (char * s1, const char * s2, size_t n);
171
180
int printf(const char * format, ...);
@@ -286,7 +295,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
286
295
if (class_infos && idx < max_class_infos)
287
296
{
288
297
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);
290
299
DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
291
300
// Hash the class name so we don't have to read it
292
301
const char *s = name;
@@ -329,7 +338,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
329
338
if (class_infos && idx < max_class_infos)
330
339
{
331
340
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);
333
342
DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
334
343
// Hash the class name so we don't have to read it
335
344
const char *s = name;
@@ -1589,9 +1598,46 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
1589
1598
1590
1599
if (!m_get_shared_cache_class_info_code) {
1591
1600
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
+
1592
1638
m_get_shared_cache_class_info_code.reset (
1593
1639
GetTargetRef ().GetUtilityFunctionForLanguage (
1594
- g_get_shared_cache_class_info_body , eLanguageTypeObjC,
1640
+ shared_class_expression. c_str () , eLanguageTypeObjC,
1595
1641
g_get_shared_cache_class_info_name, error));
1596
1642
if (error.Fail ()) {
1597
1643
if (log)
0 commit comments