Esempio n. 1
0
File: fubar.c Progetto: texane/prof
static dr_emit_flags_t event_bb
(
 void* drcontext,
 void* tag,
 instrlist_t* bb,
 bool for_trace,
 bool translating
)
{
  /* refer to dr_ir_instr.h */

  instr_t* insn = instrlist_first(bb);

  for (; insn != NULL; insn = instr_get_next(insn))
  {
    ++insn_count;

    if (instr_reads_memory(insn))
    {
      ++read_count;
      read_size += instr_memory_reference_size(insn);
      dr_printf("read_size:%u\n", instr_memory_reference_size(insn));
    }

    if (instr_writes_memory(insn))
    {
      ++writ_count;
      writ_size += instr_memory_reference_size(insn);
    }
  }

  return DR_EMIT_DEFAULT;
}
Esempio n. 2
0
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
	int i;
    instr_t *instr, *first = instrlist_first(bb);
    
    for (instr = first; instr != NULL; instr = instr_get_next(instr)) {
		if (instr_reads_memory(instr)) {
			for (i = 0; i < instr_num_srcs(instr); i++) {
				if (opnd_is_memory_reference(instr_get_src(instr, i))) {
					instrument_mem(drcontext, bb, instr, i, false);
				}
			}
		}
		if (instr_writes_memory(instr)) {
			for (i = 0; i < instr_num_dsts(instr); i++) {
				if (opnd_is_memory_reference(instr_get_dst(instr, i))) {
					instrument_mem(drcontext, bb, instr, i, true);
				}
			}
		}
    }
//	dr_printf("count %d\n",count);
    return DR_EMIT_DEFAULT;
}
Esempio n. 3
0
/* event_bb_insert calls instrument_mem to instrument every
 * application memory reference.
 */
dr_emit_flags_t
memtrace_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb,
                instr_t *instr, bool for_trace, bool translating,
                void *user_data)
{
    int i;
	reg_id_t reg;
	file_t out_file;
	instr_t * first = NULL;
	instr_t * current;
 
	//DR_ASSERT(instr_ok_to_mangle(instr));

	if (instr_ok_to_mangle(instr)){
		/* FIXME - need to generalize the filtering library */



		for (current = instrlist_first(bb); current != NULL; current = instr_get_next(current)){
			if (instr_ok_to_mangle(current)){
				first = current;
				break;
			}
		}


		if ((first != NULL) && filter_from_list(head, first, client_arg->filter_mode)){


			if (instr_reads_memory(instr)) {
				for (i = 0; i < instr_num_srcs(instr); i++) {
					if (opnd_is_memory_reference(instr_get_src(instr, i))) {
						instrument_mem(drcontext, bb, instr, i, false);
					}
				}
			}
			if (instr_writes_memory(instr)) {
				for (i = 0; i < instr_num_dsts(instr); i++) {
					if (opnd_is_memory_reference(instr_get_dst(instr, i))) {
						instrument_mem(drcontext, bb, instr, i, true);
					}
				}
			}

		}
	}

    return DR_EMIT_DEFAULT;
}
Esempio n. 4
0
/* For each memory reference app instr, we insert inline code to fill the buffer
 * with an instruction entry and memory reference entries.
 */
static dr_emit_flags_t
event_app_instruction(void *drcontext, void *tag, instrlist_t *bb, instr_t *instr,
                      bool for_trace, bool translating, void *user_data)
{
    int i;

    if (!instr_is_app(instr))
        return DR_EMIT_DEFAULT;
    if (!instr_reads_memory(instr) && !instr_writes_memory(instr))
        return DR_EMIT_DEFAULT;

    /* insert code to add an entry for app instruction */
    instrument_instr(drcontext, bb, instr);

    /* insert code to add an entry for each memory reference opnd */
    for (i = 0; i < instr_num_srcs(instr); i++) {
        if (opnd_is_memory_reference(instr_get_src(instr, i)))
            instrument_mem(drcontext, bb, instr, instr_get_src(instr, i), false);
    }

    for (i = 0; i < instr_num_dsts(instr); i++) {
        if (opnd_is_memory_reference(instr_get_dst(instr, i)))
            instrument_mem(drcontext, bb, instr, instr_get_dst(instr, i), true);
    }

    /* insert code to call clean_call for processing the buffer */
    if (/* XXX i#1698: there are constraints for code between ldrex/strex pairs,
         * so we minimize the instrumentation in between by skipping the clean call.
         * As we're only inserting instrumentation on a memory reference, and the
         * app should be avoiding memory accesses in between the ldrex...strex,
         * the only problematic point should be before the strex.
         * However, there is still a chance that the instrumentation code may clear the
         * exclusive monitor state.
         * Using a fault to handle a full buffer should be more robust, and the
         * forthcoming buffer filling API (i#513) will provide that.
         */
        IF_AARCHXX_ELSE(!instr_is_exclusive_store(instr), true))
        dr_insert_clean_call(drcontext, bb, instr, (void *)clean_call, false, 0);

    return DR_EMIT_DEFAULT;
}
Esempio n. 5
0
/* event_bb_insert calls instrument_mem to instrument every
 * application memory reference.
 */
static dr_emit_flags_t
event_bb_insert(void *drcontext, void *tag, instrlist_t *bb,
                instr_t *instr, bool for_trace, bool translating,
                void *user_data)
{
    int i;
    if (instr_get_app_pc(instr) == NULL)
        return DR_EMIT_DEFAULT;
    if (instr_reads_memory(instr)) {
        for (i = 0; i < instr_num_srcs(instr); i++) {
            if (opnd_is_memory_reference(instr_get_src(instr, i))) {
                instrument_mem(drcontext, bb, instr, i, false);
            }
        }
    }
    if (instr_writes_memory(instr)) {
        for (i = 0; i < instr_num_dsts(instr); i++) {
            if (opnd_is_memory_reference(instr_get_dst(instr, i))) {
                instrument_mem(drcontext, bb, instr, i, true);
            }
        }
    }
    return DR_EMIT_DEFAULT;
}
Esempio n. 6
0
void
watchpoint_indirect_call_event(dcontext_t *drcontext, instrlist_t *ilist, instr_t *instr,
                     instr_t *next_instr, bool mangle_calls, uint flags)
{
    opnd_t instr_opnd;
    reg_id_t base_reg;
    unsigned long used_registers = 0;
    app_pc pc;
    struct memory_operand_modifier ops = {0};

    instr_t *begin_instrumenting = INSTR_CREATE_label(drcontext);
    instr_t *done_instrumenting = INSTR_CREATE_label(drcontext);
    instr_t *nop = INSTR_CREATE_nop(drcontext);
    instr_t *emulated;


    memset(&ops, 0, sizeof(struct memory_operand_modifier));

    if(instr_reads_memory(instr)) {
        instr_opnd = instr_get_src(instr, 0);
        if (opnd_is_rel_addr(instr_opnd) || opnd_is_abs_addr(instr_opnd)) {

        }else if (opnd_is_base_disp(instr_opnd)) {

            for_each_src_operand(instr, &ops, (opnd_callback_t *) memory_src_operand_finder);
           // base_reg = opnd_get_reg(instr_opnd);

            switch(ops.found_operand.value.base_disp.base_reg) {
                case DR_REG_RSP: case DR_REG_ESP: case DR_REG_SP:
                case DR_REG_RBP: case DR_REG_EBP: case DR_REG_BP:
                    return;
                default:
                  break;
            }

            collect_regs(&used_registers, instr, instr_num_srcs, instr_get_src );
            collect_regs(&used_registers, instr, instr_num_dsts, instr_get_dst );

            reg_id_t reg_watched_addr = get_next_free_reg(&used_registers);
            opnd_t opnd_watched_addr = opnd_create_reg(reg_watched_addr);

            reg_id_t reg_unwatched_addr = get_next_free_reg(&used_registers);
            opnd_t opnd_unwatched_addr = opnd_create_reg(reg_unwatched_addr);

            PRE(ilist, instr, begin_instrumenting);
            PRE(ilist, instr, INSTR_CREATE_push(drcontext, opnd_watched_addr));
            PRE(ilist, instr, INSTR_CREATE_push(drcontext, opnd_unwatched_addr));
            PRE(ilist, instr, INSTR_CREATE_pushf(drcontext));
            PRE(ilist, instr, INSTR_CREATE_lea(drcontext, opnd_watched_addr, opnd_create_base_disp(opnd_get_base(ops.found_operand),
                                                        opnd_get_index(ops.found_operand), opnd_get_scale(ops.found_operand),
                                                        opnd_get_disp(ops.found_operand), OPSZ_lea)));

            PRE(ilist, instr, INSTR_CREATE_mov_imm(drcontext, opnd_unwatched_addr,
                                            OPND_CREATE_INT64(WATCHPOINT_INDEX_MASK)));
            PRE(ilist, instr, INSTR_CREATE_or(drcontext, opnd_unwatched_addr, opnd_watched_addr));

            emulated = instr_clone(drcontext, instr);
            emulated->translation = 0;

            ops.replacement_operand = opnd_create_base_disp(
                    reg_unwatched_addr, DR_REG_NULL,1, 0 , ops.found_operand.size);

            for_each_operand(emulated, &ops, (opnd_callback_t *) memory_operand_replacer);

            PRE(ilist, instr, INSTR_CREATE_popf(drcontext));
            PRE(ilist, instr, emulated);
            PRE(ilist, instr, INSTR_CREATE_pop(drcontext, opnd_unwatched_addr));
            PRE(ilist, instr, INSTR_CREATE_pop(drcontext, opnd_watched_addr));

            PRE(ilist, instr, INSTR_CREATE_jmp_short(drcontext,
                    opnd_create_instr(done_instrumenting)));

            pc = instr->translation;
            instr->translation = 0; // hack!
            instr_being_modified(instr, false);
            instr_set_ok_to_mangle(instr, false);

            if(NULL != pc){
                nop->translation = pc + instr->length;
            }
            POST(ilist, instr, nop);
            POST(ilist, instr, done_instrumenting);

        }
    }
}
Esempio n. 7
0
/*
 * The main function called to instrument each machine instruction.
 */
static dr_emit_flags_t instrument_instr(
    void *drcontext, void *tag, instrlist_t *bb, instr_t *instr,
    bool for_trace, bool translating, void *user_data)
{
    char *loc = NULL;

    /*
     * If this instruction is the first in its basic block, call
     * log_pc to record that we're executing this block at all.
     */
    if (drmgr_is_first_instr(drcontext, instr)) {
        instr_format_location(instr, &loc);
        dr_insert_clean_call(
            drcontext, bb, instr, (void *)log_pc, false,
            1, OPND_CREATE_INTPTR(loc));
    }

    /*
     * If the instruction reads or writes memory, log its access.
     */
    if (instr_reads_memory(instr) || instr_writes_memory(instr)) {
        for (int i = 0, limit = instr_num_srcs(instr); i < limit; i++)
            try_mem_opnd(drcontext, bb, instr, &loc,
                         instr_get_src(instr, i), false);
        for (int i = 0, limit = instr_num_dsts(instr); i < limit; i++)
            try_mem_opnd(drcontext, bb, instr, &loc,
                         instr_get_dst(instr, i), false);
    }

    /*
     * Now do opcode-specific checks.
     */
    int opcode = instr_get_opcode(instr);

    switch (opcode) {
      case OP_div:
      case OP_idiv:
        /*
         * x86 hardware divisions. The operand order for DR's
         * representation of these seem to be: 0 = denominator, 1 =
         * numerator MSW, 2 = numerator LSW.
         */
        instr_format_location(instr, &loc);
        dr_insert_clean_call(
            drcontext, bb, instr, (void *)log_div, false,
            3, instr_get_src(instr, 2), instr_get_src(instr, 0),
            OPND_CREATE_INTPTR(loc));
        break;
      case OP_shl:
      case OP_shr:
      case OP_sar:
      case OP_shlx:
      case OP_shrx:
      case OP_sarx:
      case OP_rol:
      case OP_ror:
      case OP_rcl:
      case OP_rcr:
        /*
         * Shift instructions. If they're register-controlled, log the
         * shift count.
         */
        {
            opnd_t shiftcount = instr_get_src(instr, 0);
            if (!opnd_is_immed(shiftcount)) {
                reg_id_t r0;
                drreg_status_t st;
                st = drreg_reserve_register(drcontext, bb, instr, NULL, &r0);
                DR_ASSERT(st == DRREG_SUCCESS);
                opnd_t op_r0 = opnd_create_reg(r0);
                instrlist_preinsert(bb, instr, INSTR_CREATE_movzx(
                                        drcontext, op_r0, shiftcount));
                instr_format_location(instr, &loc);
                dr_insert_clean_call(
                    drcontext, bb, instr, (void *)log_var_shift, false,
                    2, op_r0, OPND_CREATE_INTPTR(loc));
                st = drreg_unreserve_register(drcontext, bb, instr, r0);
                DR_ASSERT(st == DRREG_SUCCESS);
            }
        }
        break;
    }

    return DR_EMIT_DEFAULT;
}