示例#1
0
/**
 * Write all bytes from @a data to the file buffer. Returns true on success,
 * or false if an error occurs.
 */
bool plcrash_async_file_write (plcrash_async_file_t *file, const void *data, size_t len) {
    /* Check and update output limit */
    if (file->limit_bytes != 0 && len + file->total_bytes > file->limit_bytes) {
        return false;
    } else if (file->limit_bytes != 0) {
        file->total_bytes += len;
    }

    /* Check if the buffer will fill */
    if (file->buflen + len > sizeof(file->buffer)) {
        /* Flush the buffer */
        if (writen(file->fd, file->buffer, file->buflen) < 0) {
            return false;
        }
        
        file->buflen = 0;
    }
    
    /* Check if the new data fits within the buffer, if so, buffer it */
    if (len + file->buflen <= sizeof(file->buffer)) {
        plcrash_async_memcpy(file->buffer + file->buflen, data, len);
        file->buflen += len;
        
        return true;
        
    } else {
        /* Won't fit in the buffer, just write it */
        if (writen(file->fd, data, len) < 0) {
            return false;
        }
        
        return true;
    } 
}
/**
 * Initialize the @a thread_state using the provided context.
 *
 * @param thread_state The thread state to be initialized.
 * @param uap The context to use for cursor initialization.
 *
 * All registers will be marked as available.
 */
void plcrash_async_thread_state_mcontext_init (plcrash_async_thread_state_t *thread_state, pl_mcontext_t *mctx) {
    /*
     * Copy in the thread state. Unlike the mach thread variants, mcontext_t may only represent
     * the thread state of the host process, and we may assume that the compilation target matches the mcontext_t
     * thread type.
     */
    
#if defined(PLCRASH_ASYNC_THREAD_ARM_SUPPORT) && defined(__LP64__)
    plcrash_async_thread_state_init(thread_state, CPU_TYPE_ARM64);
    
    /* Sanity check. */
    PLCF_ASSERT(sizeof(mctx->__ss) == sizeof(thread_state->arm_state.thread.ts_64));
    
    plcrash_async_memcpy(&thread_state->arm_state.thread.ts_64, &mctx->__ss, sizeof(thread_state->arm_state.thread.ts_64));

#elif defined(PLCRASH_ASYNC_THREAD_ARM_SUPPORT)
    plcrash_async_thread_state_init(thread_state, CPU_TYPE_ARM);

    /* Sanity check. */
    PLCF_ASSERT(sizeof(mctx->__ss) == sizeof(thread_state->arm_state.thread.ts_32));

    plcrash_async_memcpy(&thread_state->arm_state.thread.ts_32, &mctx->__ss, sizeof(thread_state->arm_state.thread.ts_32));
    
#elif defined(PLCRASH_ASYNC_THREAD_X86_SUPPORT) && defined(__LP64__)
    plcrash_async_thread_state_init(thread_state, CPU_TYPE_X86_64);

    /* Sanity check. */
    PLCF_ASSERT(sizeof(mctx->__ss) == sizeof(thread_state->x86_state.thread.uts.ts64));
    PLCF_ASSERT(sizeof(mctx->__es) == sizeof(thread_state->x86_state.exception.ues.es64));
    
    plcrash_async_memcpy(&thread_state->x86_state.thread.uts.ts64, &mctx->__ss, sizeof(thread_state->x86_state.thread.uts.ts64));
    plcrash_async_memcpy(&thread_state->x86_state.exception.ues.es64, &mctx->__es, sizeof(thread_state->x86_state.exception.ues.es64));

#elif defined(PLCRASH_ASYNC_THREAD_X86_SUPPORT)
    plcrash_async_thread_state_init(thread_state, CPU_TYPE_X86);

    /* Sanity check. */
    PLCF_ASSERT(sizeof(mctx->__ss) == sizeof(thread_state->x86_state.thread.uts.ts32));
    PLCF_ASSERT(sizeof(mctx->__es) == sizeof(thread_state->x86_state.exception.ues.es32));

    plcrash_async_memcpy(&thread_state->x86_state.thread.uts.ts32, &mctx->__ss, sizeof(thread_state->x86_state.thread.uts.ts32));
    plcrash_async_memcpy(&thread_state->x86_state.exception.ues.es32, &mctx->__es, sizeof(thread_state->x86_state.exception.ues.es32));
#else
#error Add platform support
#endif

    /* Mark all registers as available */
    memset(&thread_state->valid_regs, 0xFF, sizeof(thread_state->valid_regs));
}
/**
 * Copy thread state @a source to @a dest.
 *
 * @param dest The destination to which the thread state will be copied.
 * @param source The thread state to be copied.
 *
 * @note If @a dest and @a source overlap, behavior is undefined.
 */
void plcrash_async_thread_state_copy (plcrash_async_thread_state_t *dest, const plcrash_async_thread_state_t *source) {
    plcrash_async_memcpy(dest, source, sizeof(*dest));
}