static void objc_symbol_callback()

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;
}