Exemplo n.º 1
0
void check_opnd(opnd_t opnd, void *pc, int read, void *drcontext,
		dr_mcontext_t *mctx, void *prev_pc)
{
  if (opnd_is_memory_reference(opnd) && opnd_is_base_disp(opnd))
    add_hit(pc, opnd_size_in_bytes(opnd_get_size(opnd)),
	    opnd_get_disp(opnd) + (void *)reg_get_value(opnd_get_base(opnd),
						       mctx),
	    read, drcontext, prev_pc);
  else if (opnd_is_memory_reference(opnd) && opnd_get_addr(opnd))
    add_hit(pc, opnd_size_in_bytes(opnd_get_size(opnd)), opnd_get_addr(opnd),
	    read, drcontext, prev_pc);
  // for now no other kind of memory reference was noticed to access heap data
  else if (opnd_is_memory_reference(opnd))
    dr_printf("need to implem other memory ref\n");
}
Exemplo n.º 2
0
/* emits the instruction to buf (for tests that wish to do additional checks on
 * the output) */
static void
test_instr_encode_and_decode(void *dc, instr_t *instr, uint len_expect,
                             /* also checks one operand's size */
                             bool src, uint opnum, opnd_size_t sz, uint bytes)
{
    opnd_t op;
    opnd_size_t opsz;
    instr_t *decin;
    uint len;
    byte *pc = instr_encode(dc, instr, buf);
    len = (int) (pc - (byte *)buf);
#if VERBOSE
    disassemble_with_info(dc, buf, STDOUT, true, true);
#endif
    ASSERT(len == len_expect);
    decin = instr_create(dc);
    decode(dc, buf, decin);
    ASSERT(instr_same(instr, decin));

    /* PR 245805: variable sizes should be resolved on decode */
    if (src)
        op = instr_get_src(decin, opnum);
    else
        op = instr_get_dst(decin, opnum);
    opsz = opnd_get_size(op);
    ASSERT(opsz == sz && opnd_size_in_bytes(opsz) == bytes);

    instr_destroy(dc, instr);
    instr_destroy(dc, decin);
}
Exemplo n.º 3
0
static void
memory_operand_replacer(instr_t *in, opnd_t *opnd, bool is_source, struct memory_operand_modifier *mod) {
    if(BASE_DISP_kind == opnd->kind) {
        const int orig_size = opnd_get_size(*opnd);
        *opnd = mod->replacement_operand;
        opnd_set_size(opnd, orig_size);
        instr_set_raw_bits_valid(in, false);
    }

    (void) is_source;
}
Exemplo n.º 4
0
std::string
raw2trace_t::append_memref(INOUT trace_entry_t **buf_in, uint tidx, instr_t *instr,
                           opnd_t ref, bool write)
{
    trace_entry_t *buf = *buf_in;
    offline_entry_t in_entry;
    if (!thread_files[tidx]->read((char*)&in_entry, sizeof(in_entry)))
        return "Trace ends mid-block";
    if (in_entry.addr.type != OFFLINE_TYPE_MEMREF &&
        in_entry.addr.type != OFFLINE_TYPE_MEMREF_HIGH) {
        // This happens when there are predicated memrefs in the bb.
        // They could be earlier, so "instr" may not itself be predicated.
        // XXX i#2015: if there are multiple predicated memrefs, our instr vs
        // data stream may not be in the correct order here.
        VPRINT(4, "Missing memref (next type is 0x" ZHEX64_FORMAT_STRING ")\n",
               in_entry.combined_value);
        // Put back the entry.
        thread_files[tidx]->seekg(-(std::streamoff)sizeof(in_entry),
                                  thread_files[tidx]->cur);
        return "";
    }
    if (instr_is_prefetch(instr)) {
        buf->type = instru_t::instr_to_prefetch_type(instr);
        buf->size = 1;
    } else if (instru_t::instr_is_flush(instr)) {
        buf->type = TRACE_TYPE_DATA_FLUSH;
        buf->size = (ushort) opnd_size_in_bytes(opnd_get_size(ref));
    } else {
        if (write)
            buf->type = TRACE_TYPE_WRITE;
        else
            buf->type = TRACE_TYPE_READ;
        buf->size = (ushort) opnd_size_in_bytes(opnd_get_size(ref));
    }
    // We take the full value, to handle low or high.
    buf->addr = (addr_t) in_entry.combined_value;
    VPRINT(4, "Appended memref to " PFX "\n", (ptr_uint_t)buf->addr);
    *buf_in = ++buf;
    return "";
}
Exemplo n.º 5
0
void
modify_instr_for_relocations(void *drcontext, instr_t *inst,
                             ptr_uint_t *immed, ptr_uint_t *disp)
{
    int i;
    ptr_uint_t limmed = 0, ldisp = 0;
    for (i = instr_num_srcs(inst) - 1; i >= 0; i--) {
        opnd_t opnd = instr_get_src(inst, i);
        if (opnd_is_immed_int(opnd) && opnd_get_immed_int(opnd) > 0x10000) {
            if (limmed != 0) {
                ASSERT(false);
            } else {
                limmed = opnd_get_immed_int(opnd);
            }
            instr_set_src(inst, i, opnd_create_immed_int(0, opnd_get_size(opnd)));
        }
        if (opnd_is_base_disp(opnd) && opnd_get_disp(opnd) > 0x10000) {
            if (ldisp != 0 && ldisp != opnd_get_disp(opnd)) {
                ASSERT(false);
            } else {
                ldisp = opnd_get_disp(opnd);
            }
            instr_set_src(inst, i, opnd_create_base_disp(opnd_get_base(opnd), opnd_get_index(opnd), opnd_get_scale(opnd), 0, opnd_get_size(opnd)));
        }
    }
    for (i = instr_num_dsts(inst) - 1; i >= 0; i--) {
        opnd_t opnd = instr_get_dst(inst, i);
        ASSERT(!opnd_is_immed(opnd));
        if (opnd_is_base_disp(opnd) && opnd_get_disp(opnd) > 0x10000) {
            if (ldisp != 0 && ldisp != opnd_get_disp(opnd)) {
                ASSERT(false);
            } else {
                ldisp = opnd_get_disp(opnd);
            }
            instr_set_dst(inst, i, opnd_create_base_disp(opnd_get_base(opnd), opnd_get_index(opnd), opnd_get_scale(opnd), 0, opnd_get_size(opnd)));
        }
    }
    if (limmed != 0)
        *immed = limmed;
    if (ldisp != 0)
        *disp = ldisp; 
}
Exemplo n.º 6
0
/* prints out the operands / populates the operands in the instrace mode */
static void output_populator_printer(void * drcontext, opnd_t opnd, instr_t * instr, uint64 addr, uint mem_type, operand_t * output){


	int value;
	float float_value;
	uint width;
	int i;

	per_thread_t * data = drmgr_get_tls_field(drcontext,tls_index);


	if(opnd_is_reg(opnd)){
		
		value = opnd_get_reg(opnd);
		if (value != DR_REG_NULL){
			width = opnd_size_in_bytes(reg_get_size(value));
		}
		else{
			width = 0;
		}
		
#ifdef READABLE_TRACE
		dr_fprintf(data->outfile,",%u,%u,%u",REG_TYPE, width, value);
#else	
		output->type = REG_TYPE; 
		output->width = width;
		output->value = value;

#endif
	
	}
	else if(opnd_is_immed(opnd)){
		
		//DR_ASSERT(opnd_is_immed_float(opnd) == false);

		if(opnd_is_immed_float(opnd)){

			width = opnd_size_in_bytes(opnd_get_size(opnd));

			if (instr_get_opcode(instr) == OP_fld1){
				dr_fprintf(data->outfile, ",%u,%u,1", IMM_FLOAT_TYPE, width);
			}
			else if (instr_get_opcode(instr) == OP_fldz){
				dr_fprintf(data->outfile, ",%u,%u,0", IMM_FLOAT_TYPE, width);
			}
			else{
				dr_messagebox("immediate float unknown\n");
				dr_abort();
			}

			//float_value = opnd_get_immed_float(opnd);

#ifdef READABLE_TRACE
			//dr_fprintf(data->outfile,",%u,%u,%.4f",IMM_FLOAT_TYPE,width,float_value);
#else
			output->type = IMM_FLOAT_TYPE;
			output->width = width;
			output->float_value = float_value;
#endif

		}
		
		if(opnd_is_immed_int(opnd)){

			width = opnd_size_in_bytes(opnd_get_size(opnd));
			value = opnd_get_immed_int(opnd);
#ifdef READABLE_TRACE
			dr_fprintf(data->outfile,",%u,%u,%d",IMM_INT_TYPE,width,value);
#else
			output->type = IMM_INT_TYPE;
			output->width = width;
			output->value = value;
#endif
		}

	}
	else if(opnd_is_memory_reference(opnd)){

		width = drutil_opnd_mem_size_in_bytes(opnd,instr);
#ifdef READABLE_TRACE
		dr_fprintf(data->outfile, ",%u,%u,%llu",mem_type,width,addr);
#else
		output->type = mem_type;
		output->width = width;
		output->float_value = addr;
#endif

	}
	

}
Exemplo n.º 7
0
/* First tried something like this, but we hit too many issues in decode and encode */
bool
compare_pages(void *drcontext, byte *start1, byte *start2)
{
    byte *p1 = start1, *p2 = start2;
    int skipped_bytes = 0, identical_skipped_bytes = 0;

    while (p1 < start1 + PAGE_SIZE) {
        int instr_size = decode_sizeof(drcontext, p1, NULL _IF_X64(NULL));
        if (p1 + instr_size > start1 + PAGE_SIZE) {
            /* We're overlapping the end of the page, skip these. */
            int end_skip = start1 + PAGE_SIZE - p1;
            VVERBOSE_PRINT("Passing PAGE_END %d bytes", end_skip);
            skipped_bytes += end_skip;
            if (memcmp(p1, p2, end_skip) == 0)
                identical_skipped_bytes += end_skip;
            break;
        }
        if (decode_sizeof(drcontext, p2, NULL _IF_X64(NULL)) != instr_size) {
            VVERBOSE_PRINT("Instruction alignment mismatch\n");
            return false;
        }
        /* assumption - instructions <= 4 bytes in size won't have relocations */
        if (instr_size < 5) {
            if (memcmp(p1, p2, instr_size) != 0) {
                VVERBOSE_PRINT("Difference found in small instr\n");
                return false;
            }
            p1 += size;
            p2 += size;
        } else {
            /* guess if there could be a relocation */
            instr_t *instr1 = instr_create(drcontext);
            instr_t *instr2 = instr_create(drcontext);
            p1 = decode(drcontext, p1, instr1);
            p2 = decode(drcontext, p2, instr2);
            if (p1 - start1 != p2 - start2) {
                VVERBOSE_PRINT("Instruction alignment mismatch on full decode\n");
                /* Fixme - free instr, don't expect this to happen */
                return false;
            }
            if (instr_get_num_srcs(instr1) != instr_get_num_srcs(instr2) ||
                instr_get_num_dsts(instr1) != instr_get_num_dsts(instr2)) {
                VVERBOSE_PRINT("Full decode operand mismatch");
                return false;
            }
            for (i = instr_get_num_srcs(instr1); i > 0; i--) {
                opnd_t opnd = instr_get_src(instr1, i);
                if (opnd_is_immed_int(opnd) && opnd_get_immed_int(opnd) > 0x10000) {
                    instr_set_src(instr1, i, opnd_create_immed_int(opnd_get_immed_int(opnd), opnd_get_size(opnd)));
                }
            }
        }
    }
}