Пример #1
0
/* iterate basic block to find a dead register */
static reg_id_t
bb_find_dead_reg(instrlist_t *ilist)
{
    instr_t *instr;
    int i;
    bool reg_is_read[DR_NUM_GPR_REGS] = { false,};

    for (instr  = instrlist_first(ilist);
         instr != NULL;
         instr  = instr_get_next(instr)) {
        if (instr_is_syscall(instr) || instr_is_interrupt(instr))
            return DR_REG_NULL;
        for (i = 0; i < DR_NUM_GPR_REGS; i++) {
            if (!reg_is_read[i] &&
                instr_reads_from_reg(instr, (reg_id_t)(DR_REG_START_GPR + i))) {
                reg_is_read[i] = true;
            }
            if (!reg_is_read[i] &&
                instr_writes_to_exact_reg(instr,
                                          (reg_id_t)(DR_REG_START_GPR + i))) {
                return (reg_id_t)(DR_REG_START_GPR + i);
            }
#ifdef X64
            /* in x64, update on 32-bit register kills the whole register */
            if (!reg_is_read[i] &&
                instr_writes_to_exact_reg(instr,
                                          reg_64_to_32
                                          ((reg_id_t)(DR_REG_START_GPR + i)))) {
                return (reg_id_t)(DR_REG_START_GPR + i);
            }
#endif
        }
    }
    return DR_REG_NULL;
}
Пример #2
0
bool
instr_is_return(instr_t *instr)
{
    /* There is no "return" opcode so we consider a return to be either:
     * A) An indirect branch through lr;
     * B) An instr that reads lr and writes pc;
     *    (XXX: should we limit to a move and rule out an add or shift or whatever?)
     * C) A pop into pc.
     */
    int opc = instr_get_opcode(instr);
    if ((opc == OP_bx || opc ==  OP_bxj) &&
        opnd_get_reg(instr_get_src(instr, 0)) == DR_REG_LR)
        return true;
    if (!instr_writes_to_reg(instr, DR_REG_PC, DR_QUERY_INCLUDE_ALL))
        return false;
    return (instr_reads_from_reg(instr, DR_REG_LR, DR_QUERY_INCLUDE_ALL) ||
            instr_is_pop(instr));
}
Пример #3
0
static inline void
calc_set_num(instr_t *instr, t_glob_reg_state* glob_reg_state )
{
  int i;
  //general purpose registers. Instead of using the whole enum, we only need to check for the
  //largest registers, any overlapping accesses will also trigger.
#ifdef X64
  update_setnrs(instr, DR_REG_START_64, DR_REG_STOP_64, glob_reg_state);
#else
  update_setnrs(instr, DR_REG_START_32, DR_REG_STOP_32, glob_reg_state);
#endif
#ifdef CONSIDER_MORE_REGS
  update_setnrs(instr, DR_REG_START_MMX, DR_REG_STOP_MMX, glob_reg_state);
  update_setnrs(instr, DR_REG_START_XMM, DR_REG_STOP_XMM, glob_reg_state);
  update_setnrs(instr, DR_REG_START_YMM, DR_REG_STOP_YMM, glob_reg_state);
  update_setnrs(instr, DR_REG_START_FLOAT, DR_REG_STOP_FLOAT, glob_reg_state);
  update_setnrs(instr, DR_REG_START_SEGMENT, DR_REG_START_CR, glob_reg_state);
  update_setnrs(instr, DR_REG_START_DR, DR_REG_STOP_DR, glob_reg_state);
  update_setnrs(instr, DR_REG_START_CR, DR_REG_STOP_CR, glob_reg_state);
#endif
#ifdef CONSIDER_EFLAGS
  update_eflag_setnrs(instr, glob_reg_state);
#endif
  glob_reg_state->final_setnr = MAX4(glob_reg_state->raw_setnr, glob_reg_state->war_setnr,
                        glob_reg_state->waw_setnr, glob_reg_state->else_setnr);
  //assigning the set number
  for (i = 0; i <= DR_REG_LAST_VALID_ENUM; i++) {
    if ( (i != DR_REG_NULL) && (i != DR_REG_INVALID) ) {
        if(instr_reads_from_reg(instr, i)) {
            glob_reg_state->my_readfrom[i] = MAX(glob_reg_state->my_readfrom[i],
                                                 glob_reg_state->final_setnr);
        }
        if(instr_writes_to_reg(instr, i)) {
            glob_reg_state->my_writtento[i] = MAX(glob_reg_state->my_writtento[i],
                                                  glob_reg_state->final_setnr);
        }
    }
  }
  glob_reg_state->num_sets = MAX(glob_reg_state->num_sets, glob_reg_state->final_setnr);
}
Пример #4
0
inline void update_setnrs(instr_t *instr, int dr_reg_enum_start, int dr_reg_enum_stop,
                          t_glob_reg_state* glob_reg_state) {
    int i;
    for (i = dr_reg_enum_start; i <= dr_reg_enum_stop; i++) {
        if(i != DR_REG_NULL && i != DR_REG_INVALID) {

            if(instr_reads_from_reg(instr, i)){
                //determine set number for rule 1: RaW (WRITTEN TO + 1)
                glob_reg_state->raw_setnr = MAX(glob_reg_state->raw_setnr,
                                                glob_reg_state->my_writtento[i]+1);
            }

            if(instr_writes_to_reg(instr, i)){
                //determine set number for rule 2: WaR (READ FROM + 1)
                glob_reg_state->war_setnr = MAX(glob_reg_state->war_setnr,
                                                glob_reg_state->my_readfrom[i]+1);

                //determine set number for rule 3: WaW (WRITTEN TO + 1)
                glob_reg_state->waw_setnr = MAX(glob_reg_state->waw_setnr,
                                                glob_reg_state->my_writtento[i]+1);
            }
        }
    }
}