Exemple #1
0
int before_block_exec(CPUState *env, TranslationBlock *tb) {
    uint64_t count = rr_get_guest_instr_count();
    if (!snipping && count+tb->icount > start_count) {
        sassert((oldlog = fopen(rr_nondet_log->name, "r")), 8);
        sassert(fread(&orig_last_prog_point, sizeof(RR_prog_point), 1, oldlog) == 1, 9);
        printf("Original ending prog point: ");
        rr_spit_prog_point(orig_last_prog_point);

        actual_start_count = count;
        printf("Saving snapshot at instr count %lu...\n", count);

        // Force running state
        global_state_store_running();
        printf("writing snapshot:\t%s\n", snp_name);
        QIOChannelFile* ioc =
            qio_channel_file_new_path(snp_name, O_WRONLY | O_CREAT, 0660, NULL);
        QEMUFile* snp = qemu_fopen_channel_output(QIO_CHANNEL(ioc));
        qemu_savevm_state(snp, NULL);
        qemu_fclose(snp);

        printf("Beginning cut-and-paste process at prog point:\n");
        rr_spit_prog_point(rr_prog_point());
        printf("Writing entries to %s...\n", nondet_name);
        newlog = fopen(nondet_name, "w");
        sassert(newlog, 10);
        // We'll fix this up later.
        RR_prog_point prog_point = {0};
        fwrite(&prog_point.guest_instr_count,
                sizeof(prog_point.guest_instr_count), 1, newlog);

        fseek(oldlog, ftell(rr_nondet_log->fp), SEEK_SET);

        // If there are items in the queue, then start copying the log
        // from there
        RR_log_entry *item = rr_get_queue_head();
        if (item != NULL) fseek(oldlog, item->header.file_pos, SEEK_SET);

        while (prog_point.guest_instr_count < end_count && !feof(oldlog)) {
            prog_point = copy_entry();
        }
        if (!feof(oldlog)) { // prog_point is the first one AFTER what we want
            printf("Reached end of old nondet log.\n");
        } else {
            printf("Past desired ending point for log.\n");
        }

        snipping = true;
        printf("Continuing with replay.\n");
    }

    if (snipping && !done && count > end_count) {
        end_snip();

        rr_end_replay_requested = 1;
    }

    return 0;
}
Exemple #2
0
int before_block_exec(CPUState *env, TranslationBlock *tb) {
    uint64_t count = rr_prog_point.guest_instr_count;
    if (!snipping && count+tb->num_guest_insns > start_count) {
        sassert((oldlog = fopen(rr_nondet_log->name, "r")));
        sassert(fread(&orig_last_prog_point, sizeof(RR_prog_point), 1, oldlog) == 1);
        printf("Original ending prog point: ");
        rr_spit_prog_point(orig_last_prog_point);

        actual_start_count = count;
        printf("Saving snapshot at instr count %lu...\n", count);
        do_savevm_rr(get_monitor(), snp_name);

        printf("Beginning cut-and-paste process at prog point:\n");
        rr_spit_prog_point(rr_prog_point);
        printf("Writing entries to %s...\n", nondet_name);
        newlog = fopen(nondet_name, "w");
        sassert(newlog);
        // We'll fix this up later.
        RR_prog_point prog_point = {0, 0, 0};
        fwrite(&prog_point, sizeof(RR_prog_point), 1, newlog);

        fseek(oldlog, ftell(rr_nondet_log->fp), SEEK_SET);

        RR_log_entry *item = rr_get_queue_head();
        while (item != NULL && item->header.prog_point.guest_instr_count < end_count) {
            write_entry(item);
            item = item->next;
        }
        while (prog_point.guest_instr_count < end_count && !feof(oldlog)) {
            prog_point = copy_entry();
        } 
        if (!feof(oldlog)) { // prog_point is the first one AFTER what we want
            printf("Reached end of old nondet log.\n");
        } else {
            printf("Past desired ending point for log.\n");
        }

        snipping = true;
        printf("Continuing with replay.\n");
    }

    if (snipping && !done && count > end_count) {
        end_snip();

        init_timer_alarm();
        rr_do_end_replay(0);
    }

    return 0;
}
Exemple #3
0
static void end_snip(void) {
    RR_prog_point prog_point = rr_prog_point();
    printf("Ending cut-and-paste on prog point:\n");
    rr_spit_prog_point(prog_point);
    prog_point.guest_instr_count -= actual_start_count;

    RR_header end;
    end.kind = RR_LAST;
    end.callsite_loc = RR_CALLSITE_LAST;
    end.prog_point = prog_point;
    end.prog_point.guest_instr_count -= actual_start_count;
    sassert(fwrite(&(end.prog_point), sizeof(end.prog_point), 1, newlog) == 1);
    sassert(fwrite(&(end.kind), sizeof(end.kind), 1, newlog) == 1);
    sassert(fwrite(&(end.callsite_loc), sizeof(end.callsite_loc), 1, newlog) == 1);

    rewind(newlog);
    fwrite(&prog_point, sizeof(RR_prog_point), 1, newlog);
    fclose(newlog);

    done = true;
}
Exemple #4
0
static void rr_spit_log_entry(RR_log_entry item) {
    rr_spit_prog_point(item.header.prog_point);
    switch (item.header.kind) {
        case RR_INPUT_1:
            printf("\tRR_INPUT_1 %d from %s\n", item.variant.input_1, get_callsite_string(item.header.callsite_loc));
            break;
        case RR_INPUT_2:
            printf("\tRR_INPUT_2 %d from %s\n", item.variant.input_2, get_callsite_string(item.header.callsite_loc));
            break;
        case RR_INPUT_4:
            printf("\tRR_INPUT_4 %d from %s\n", item.variant.input_4, get_callsite_string(item.header.callsite_loc));
            break;
        case RR_INPUT_8:
            printf("\tRR_INPUT_8 %ld from %s\n", item.variant.input_8, get_callsite_string(item.header.callsite_loc));
            break;
        case RR_INTERRUPT_REQUEST:
            printf("\tRR_INTERRUPT_REQUEST_%d from %s\n", item.variant.interrupt_request, get_callsite_string(item.header.callsite_loc));
            break;
        case RR_EXIT_REQUEST:
            printf("\tRR_EXIT_REQUEST_%d from %s\n", item.variant.exit_request, get_callsite_string(item.header.callsite_loc));
            break;
        case RR_SKIPPED_CALL:
            {
                RR_skipped_call_args *args = &item.variant.call_args;
                int callbytes;
                switch (item.variant.call_args.kind) {
                    case RR_CALL_CPU_MEM_RW:
                        callbytes = sizeof(args->variant.cpu_mem_rw_args) + args->variant.cpu_mem_rw_args.len;
                        break;
                    case RR_CALL_MEM_REGION_CHANGE:
                        callbytes = sizeof(args->variant.mem_region_change_args) + args->variant.mem_region_change_args.len;
                        break;
                    case RR_CALL_CPU_MEM_UNMAP:
                        callbytes = sizeof(args->variant.cpu_mem_unmap) + args->variant.cpu_mem_unmap.len;
                        break;
                    case RR_CALL_HD_TRANSFER:
                        callbytes = sizeof(args->variant.hd_transfer_args);
                        printf("This is a HD transfer. Source: 0x%lx, Dest: 0x%lx, Len: %d\n",
                            args->variant.hd_transfer_args.src_addr,
                            args->variant.hd_transfer_args.dest_addr,
                            args->variant.hd_transfer_args.num_bytes);

                        break;
                }
                printf("\tRR_SKIPPED_CALL_(%s) from %s %d bytes\n", 
                        get_skipped_call_kind_string(item.variant.call_args.kind),
                        get_callsite_string(item.header.callsite_loc),
                        callbytes);
                break;
            }
        case RR_LAST:
            printf("\tRR_LAST\n");
            break;
        case RR_DEBUG:
            printf("\tRR_DEBUG\n");
            break;
        default:
            printf("\tUNKNOWN RR log kind %d\n", item.header.kind);
            break;
    }
}