in Source/PLCrashAsyncSymbolication.c [178:243]
static void objc_symbol_callback (bool isClassMethod, plcrash_async_macho_string_t *className, plcrash_async_macho_string_t *methodName, pl_vm_address_t imp, void *ctx) {
struct symbol_lookup_ctx *lookup_ctx = ctx;
plcrash_error_t err;
/* Skip this match if a better match has already been found */
if (lookup_ctx->found && imp < lookup_ctx->symbol_address)
return;
/* Get the string data. */
pl_vm_size_t classNameLength;
const char *classNamePtr;
if ((err = plcrash_async_macho_string_get_length(className, &classNameLength)) != PLCRASH_ESUCCESS) {
PLCF_DEBUG("plcrash_async_macho_string_get_length(className) error %d", err);
return;
}
if ((err = plcrash_async_macho_string_get_pointer(className, &classNamePtr)) != PLCRASH_ESUCCESS) {
PLCF_DEBUG("plcrash_async_macho_string_get_pointer(className) error %d", err);
return;
}
pl_vm_size_t methodNameLength;
const char *methodNamePtr;
if ((err = plcrash_async_macho_string_get_length(methodName, &methodNameLength)) != PLCRASH_ESUCCESS) {
PLCF_DEBUG("plcrash_async_macho_string_get_length(methodName) error %d", err);
return;
}
if ((err = plcrash_async_macho_string_get_pointer(methodName, &methodNamePtr)) != PLCRASH_ESUCCESS) {
PLCF_DEBUG("plcrash_async_macho_string_get_pointer(methodName) error %d", err);
return;
}
/* Write out the symbol name; we set the limit with room for a terminating NULL */
int limit = SYMBOL_NAME_BUFLEN - 1;
int cursor = 0;
append_char(lookup_ctx->buffer, isClassMethod ? '+' : '-', &cursor, limit);
append_char(lookup_ctx->buffer, '[', &cursor, limit);
for (pl_vm_size_t i = 0; i < classNameLength; i++) {
bool success = append_char(lookup_ctx->buffer, classNamePtr[i], &cursor, limit);
if (!success)
break;
}
append_char(lookup_ctx->buffer, ' ', &cursor, limit);
for (pl_vm_size_t i = 0; i < methodNameLength; i++) {
bool success = append_char(lookup_ctx->buffer, methodNamePtr[i], &cursor, limit);
if (!success)
break;
}
append_char(lookup_ctx->buffer, ']', &cursor, limit);
/* NULL terminate */
append_char(lookup_ctx->buffer, '\0', &cursor, limit+1);
/* Save the address. */
lookup_ctx->symbol_address = imp;
/* Mark as found */
lookup_ctx->found = true;
}