Esempio n. 1
0
/* If has_instr_jmp_targets is true, this routine trashes the note field
 * of each instr_t to store the offset in order to properly encode
 * the relative pc for an instr_t jump target
 */
byte *
instrlist_encode_to_copy(dcontext_t *dcontext, instrlist_t *ilist, byte *copy_pc,
                         byte *final_pc, byte *max_pc, bool has_instr_jmp_targets)
{
    instr_t *inst;
    int len = 0;
#ifdef ARM
    /* XXX i#1734: reset encode state to avoid any stale encode state
     * or dangling pointer.
     */
    if (instr_get_isa_mode(instrlist_first(ilist)) == DR_ISA_ARM_THUMB)
        encode_reset_it_block(dcontext);
#endif
    /* Do an extra pass over the instrlist so we can determine if an instr opnd
     * was erroneously used with has_instr_jmp_targets = false.
     */
    DOCHECK(2, {
        if (!has_instr_jmp_targets) {
            for (inst = instrlist_first(ilist); inst; inst = instr_get_next(inst)) {
                if (TEST(INSTR_OPERANDS_VALID, (inst)->flags)) {
                    int i;
                    for (i = 0; i < instr_num_srcs(inst); ++i) {
                        CLIENT_ASSERT(!opnd_is_instr(instr_get_src(inst, i)),
                                      "has_instr_jmp_targets was unset "
                                      "but an instr opnd was found");
                    }
                }
            }
        }
    });
Esempio n. 2
0
instrlist_t*
instrlist_clone(dcontext_t *dcontext, instrlist_t *old)
{
    instr_t *inst, *copy;
    instrlist_t *newlist = instrlist_create(dcontext);

    inst = instrlist_first(old);
    while (inst != NULL) {
        copy = instr_clone(dcontext, inst);
        /* to copy instr targets we temporarily clobber note field */
        instr_set_note(inst, (void *)copy);
        instrlist_append(newlist, copy);
        inst = instr_get_next(inst);
    }

    /* Fix up instr src if it is an instr and restore note field */
    /* Note: we do not allows instruction update code cache,
     * which is very dangerous.
     * So we do not support instr as dst opnd and won't fix up here if any.
     */
    for (inst = instrlist_first(old), copy = instrlist_first(newlist);
            inst != NULL && copy != NULL;
            inst = instr_get_next(inst), copy = instr_get_next(copy)) {
        int i;
        for (i = 0; i < inst->num_srcs; i++) {
            instr_t *tgt;
            opnd_t   op = instr_get_src(copy, i);
            if (!opnd_is_instr(op))
                continue;
            CLIENT_ASSERT(opnd_get_instr(op) != NULL,
                          "instrlist_clone: NULL instr operand");
            tgt = (instr_t *) instr_get_note(opnd_get_instr(op));
            CLIENT_ASSERT(tgt != NULL,
                          "instrlist_clone: operand instr not in instrlist");
            if (opnd_is_far_instr(op)) {
                instr_set_src(copy, i,
                              opnd_create_far_instr
                              (opnd_get_segment_selector(op), tgt));
            } else
                instr_set_src(copy, i,
                              opnd_create_instr(tgt));
        }
    }
    for (inst = instrlist_first(old), copy = instrlist_first(newlist);
            inst != NULL && copy != NULL;
            inst = instr_get_next(inst), copy = instr_get_next(copy)) {
        /* restore note field */
        instr_set_note(inst, instr_get_note(copy));
    }
#ifdef CLIENT_INTERFACE
    newlist->fall_through_bb = old->fall_through_bb;
#endif
    return newlist;
}
Esempio n. 3
0
/* To support multiple non-meta ctis in app2app phase, we mark them meta
 * before handing to DR to satisfy its bb constraints
 */
static void
drmgr_fix_app_ctis(void *drcontext, instrlist_t *bb)
{
    instr_t *inst;
    for (inst = instrlist_first(bb); inst != NULL; inst = instr_get_next(inst)) {
        /* Any CTI with an instr target must have an intra-bb target and thus
         * we assume it should not be mangled.  We mark it meta.
         */
        if (instr_ok_to_mangle(inst) && 
            instr_is_cti(inst) &&
            opnd_is_instr(instr_get_target(inst))) {
            instr_set_ok_to_mangle(inst, false);
            /* instrumentation passes should set the translation field
             * so other passes can see what app pc these app instrs
             * correspond to: but DR complains if there's a meta instr
             * w/ a translation but no restore_state event
             */
            instr_set_translation(inst, NULL);
        }
    }
}