int before_block_exec(CPUState *env, TranslationBlock *tb){

  if (tubtf_on) {
    char *llvm_fn_name = (char *) tcg_llvm_get_func_name(tb);
    uint32_t pc, unk;
    sscanf(llvm_fn_name, "tcg-llvm-tb-%d-%x", &unk, &pc);
    env->panda_guest_pc = pc;
    tubtf_write_el_64(panda_current_asid(env), pc, TUBTFE_LLVM_FN, unk, 0, 0, 0);
  }
  else {
    fprintf(funclog, "%s\n", tcg_llvm_get_func_name(tb));
    DynValBuffer *dynval_buffer = PIFP->PIV->getDynvalBuffer();
    if (dynval_buffer->cur_size > 0){
        // Buffer wasn't flushed before, have to flush it now
      fwrite(dynval_buffer->start, dynval_buffer->cur_size, 1, memlog);
    }
    clear_dynval_buffer(dynval_buffer);
  }
    return 0;
}
Exemple #2
0
void write_dynval_buffer(DynValBuffer *dynval_buf, DynValEntry *entry){
    if (tubtf_on) {
        // XXX Fixme: note that when using tubt format, we still create that DynValBuffer.  Waste of memory
        uint64_t cr3, pc, typ;
        uint64_t arg1, arg2, arg3, arg4;
        arg1 = arg2 = arg3 = arg4 = 0;
        assert (tubtf->colw == TUBTF_COLW_64);
        uint32_t element_size = tubtf_element_size();
        // assert that there must be enough room in dynval buffer
        uint32_t bytes_used = dynval_buf->ptr - dynval_buf->start;
        uint32_t bytes_left = dynval_buf->max_size - bytes_used;
        assert (bytes_left > element_size);
        cr3 = panda_current_asid(env);  // virtual address space -- cr3 for x86
        pc = panda_current_pc(env);
        typ = 0;
        switch (entry->entrytype) {
            case ADDRENTRY:
                {
                    LogOp op = entry->entry.memaccess.op;
                    assert (op == LOAD ||op == STORE);
                    Addr *a = &(entry->entry.memaccess.addr);
                    typ = TUBTFE_LLVM_DV_LOAD;
                    if (op == STORE) {
                        typ = TUBTFE_LLVM_DV_STORE;
                    }
                    // a->type fits easily in a byte -- 1 .. 5
                    arg1 = (a->typ) | ((a->flag & 0xff) << 8) | (a->off << 16);
                    uint64_t val;

                    switch (a->typ) {
                        case HADDR:
                            val = a->val.ha;
                            break;
                        case MADDR:
                            val = a->val.ma;
                            break;
                        case IADDR:
                            val = a->val.ia;
                            break;
                        case LADDR:
                            val = a->val.la;
                            break;
                        case GREG:
                            val = a->val.gr;
                            break;
                        case GSPEC:
                            val = a->val.gs;
                            break;
                        case UNK:
                            val = a->val.ua;
                            break;
                        case CONST:
                            val = a->val.con;
                            break;
                        case RET:
                            val = a->val.ret;
                            break;
                        default:
                            assert (1==0);
                    }
                    arg2 = val;
                    break;
                }
            case PADDRENTRY:
                {
                    LogOp op = entry->entry.portaccess.op;
                    assert (op == PLOAD ||op == PSTORE);
                    Addr *a = &(entry->entry.portaccess.addr);
                    typ = TUBTFE_LLVM_DV_LOAD;
                    if (op == PSTORE) {
                        typ = TUBTFE_LLVM_DV_STORE;
                    }
                    // a->type fits easily in a byte -- 1 .. 5
                    arg1 = (a->typ) | ((a->flag & 0xff) << 8) | (a->off << 16);
                    uint64_t val;

                    switch (a->typ) {
                        case PADDR:
                            val = a->val.pa;
                            break;
                        default:
                            assert (1==0);
                    }
                    arg2 = val;
                    break;
                }
            case BRANCHENTRY:
                {
                    typ = TUBTFE_LLVM_DV_BRANCH;
                    arg1 = entry->entry.branch.br;
                    break;
                }
            case SELECTENTRY:
                {
                    typ = TUBTFE_LLVM_DV_SELECT;
                    arg1 = entry->entry.select.sel;
                    break;
                }
            case SWITCHENTRY:
                {
                    typ = TUBTFE_LLVM_DV_SWITCH;
                    arg1 = entry->entry.switchstmt.cond;
                    break;
                }
            case EXCEPTIONENTRY:
                {
                    typ = TUBTFE_LLVM_EXCEPTION;
                }
        }
        tubtf_write_el_64(cr3, pc, typ, arg1, arg2, arg3, arg4);
    }
    else {
        uint32_t bytes_used = dynval_buf->ptr - dynval_buf->start;
        assert(dynval_buf->max_size - bytes_used >= sizeof(DynValEntry));
        memcpy(dynval_buf->ptr, entry, sizeof(DynValEntry));
        dynval_buf->ptr += sizeof(DynValEntry);
        dynval_buf->cur_size = dynval_buf->ptr - dynval_buf->start;
    }
}