plcrash_error_t plcrash_async_thread_state_mach_thread_init()

in Source/PLCrashAsyncThread.c [169:223]


plcrash_error_t plcrash_async_thread_state_mach_thread_init (plcrash_async_thread_state_t *thread_state, thread_t thread) {
    mach_msg_type_number_t state_count;
    kern_return_t kr;
    
#if defined(PLCRASH_ASYNC_THREAD_ARM_SUPPORT)
    /* Fetch the thread state */
    state_count = ARM_UNIFIED_THREAD_STATE_COUNT;
    kr = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE, (thread_state_t) &thread_state->arm_state.thread, &state_count);
    if (kr != KERN_SUCCESS) {
        PLCF_DEBUG("Fetch of ARM thread state failed with Mach error: %d", kr);
        return PLCRASH_EINTERNAL;
    }
    
    /* Platform meta-data */
    thread_state->stack_direction = PLCRASH_ASYNC_THREAD_STACK_DIRECTION_DOWN;
    if (thread_state->arm_state.thread.ash.flavor == ARM_THREAD_STATE64) {
        thread_state->greg_size = 8;
    } else {
        thread_state->greg_size = 4;
    }

#elif defined(PLCRASH_ASYNC_THREAD_X86_SUPPORT)
    /* Fetch the thread state */
    state_count = x86_THREAD_STATE_COUNT;
    kr = thread_get_state(thread, x86_THREAD_STATE, (thread_state_t) &thread_state->x86_state.thread, &state_count);
    if (kr != KERN_SUCCESS) {
        PLCF_DEBUG("Fetch of x86 thread state failed with Mach error: %d", kr);
        return PLCRASH_EINTERNAL;
    }
    
    /* Fetch the exception state */
    state_count = x86_EXCEPTION_STATE_COUNT;
    kr = thread_get_state(thread, x86_EXCEPTION_STATE, (thread_state_t) &thread_state->x86_state.exception, &state_count);
    if (kr != KERN_SUCCESS) {
        PLCF_DEBUG("Fetch of x86 exception state failed with Mach error: %d", kr);
        return PLCRASH_EINTERNAL;
    }
    
    /* Platform meta-data */
    thread_state->stack_direction = PLCRASH_ASYNC_THREAD_STACK_DIRECTION_DOWN;
    if (thread_state->x86_state.thread.tsh.flavor == x86_THREAD_STATE64) {
        thread_state->greg_size = 8;
    } else {
        thread_state->greg_size = 4;
    }

#else
#error Add platform support
#endif

    /* Mark all registers as available */
    memset(&thread_state->valid_regs, 0xFF, sizeof(thread_state->valid_regs));

    return PLCRASH_ESUCCESS;
}