static dr_emit_flags_t event_bb_insert(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst, bool for_trace, bool translating, void *user_data) { static int freq; reg_id_t reg1 = IF_X86_ELSE(DR_REG_XAX, DR_REG_R0); reg_id_t reg2 = IF_X86_ELSE(DR_REG_XCX, DR_REG_R1); CHECK(drmgr_is_first_instr(drcontext, instrlist_first_app(bb)), "first incorrect"); CHECK(!drmgr_is_first_instr(drcontext, instrlist_last(bb)) || instrlist_first_app(bb) == instrlist_last(bb), "first incorrect"); CHECK(drmgr_is_last_instr(drcontext, instrlist_last(bb)), "last incorrect"); CHECK(!drmgr_is_last_instr(drcontext, instrlist_first_app(bb)) || instrlist_first_app(bb) == instrlist_last(bb), "last incorrect"); /* hack to instrument every nth bb. assumes DR serializes bb events. */ freq++; if (freq % 100 == 0 && inst == (instr_t*)user_data/*first instr*/) { /* test read from cache */ dr_save_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1); drmgr_insert_read_tls_field(drcontext, tls_idx, bb, inst, reg1); dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_from_cache, false, 1, opnd_create_reg(reg1)); drmgr_insert_read_cls_field(drcontext, cls_idx, bb, inst, reg1); dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_from_cache, false, 1, opnd_create_reg(reg1)); dr_restore_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1); } if (freq % 300 == 0 && inst == (instr_t*)user_data/*first instr*/) { instr_t *first, *second; /* test write from cache */ dr_save_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1); dr_save_reg(drcontext, bb, inst, reg2, SPILL_SLOT_2); instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t)MAGIC_NUMBER_FROM_CACHE, opnd_create_reg(reg1), bb, inst, &first, &second); instr_set_meta(first); if (second != NULL) instr_set_meta(second); drmgr_insert_write_tls_field(drcontext, tls_idx, bb, inst, reg1, reg2); dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_write_from_cache, false, 0); drmgr_insert_write_cls_field(drcontext, cls_idx, bb, inst, reg1, reg2); dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_write_from_cache, false, 0); dr_restore_reg(drcontext, bb, inst, reg2, SPILL_SLOT_2); dr_restore_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1); } return DR_EMIT_DEFAULT; }
void cfi_cleanup_after_native_call(void *drcontext, instrlist_t *ilist, instr_t *where) { instr_t *in = (where == NULL) ? instrlist_last(ilist) : instr_get_prev(where); CFI_ASSERT(drcontext != NULL, "dr_cleanup_after_call: drcontext cannot be NULL"); /* PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RDI))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RSI))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBP)));*/ /* skip xsp by popping into dead rbx */ /* PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RDX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RCX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RAX))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R8))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R9))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R10))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R11))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R12))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R13))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R14))); PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R15))); PRE(ilist, where, INSTR_CREATE_lea (drcontext, opnd_create_reg(REG_XSP), OPND_CREATE_MEM_lea(REG_XSP, REG_NULL, 0, XMM_SLOTS_SIZE))); */ PRE(ilist, where, INSTR_CREATE_popf(drcontext)); /* now go through and mark inserted instrs as meta */ if (in == NULL) in = instrlist_first(ilist); else in = instr_get_next(in); while (in != where) { instr_set_ok_to_mangle(in, false); in = instr_get_next(in); } }
void cfi_insert_meta_native_call_vargs(void *dcontext, instrlist_t *bb, instr_t *cursor, bool clean_call, void *callee) { instr_t *in = (cursor == NULL) ? instrlist_last(bb) : instr_get_prev(cursor); // PRE(ilist, instr, INSTR_CREATE_mov_ld(dcontext, opnd_create_reg(REG_RDI), opnd_create_reg(REG_RSP))); PRE(bb, cursor, INSTR_CREATE_call(dcontext, opnd_create_pc(callee))); /* mark it all meta */ if (in == NULL) in = instrlist_first(bb); else in = instr_get_next(in); while (in != cursor) { instr_set_ok_to_mangle(in, false); in = instr_get_next(in); } }
unsigned int cfi_prepare_for_native_call(void *drcontext, instrlist_t *ilist, instr_t *where) { unsigned int eflags_offs, dstack_offs = 0; instr_t *in = (where == NULL) ? instrlist_last(ilist) : instr_get_prev(where); CFI_ASSERT(drcontext != NULL, "cfi_prepare_for_native_call: drcontext cannot be NULL"); //PRE(ilist, where, INSTR_CREATE_push_imm(dcontext, OPND_CREATE_INT32(0))); //dstack_offs += XSP_SZ; PRE(ilist, where, INSTR_CREATE_pushf(drcontext)); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0, OPSZ_STACK))); PRE(ilist, where, INSTR_CREATE_and(drcontext, opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0, OPSZ_STACK), OPND_CREATE_INT32(~(EFLAGS_NON_SYSTEM | EFLAGS_IF)))); PRE(ilist, where, INSTR_CREATE_popf(drcontext)); /* dstack_offs += XSP_SZ; eflags_offs = dstack_offs; PRE(ilist, where, INSTR_CREATE_lea(drcontext, opnd_create_reg(REG_XSP), OPND_CREATE_MEM_lea(REG_XSP, REG_NULL, 0, - XMM_SLOTS_SIZE))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R15))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R14))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R13))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R12))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R11))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R10))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R9))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_R8))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RAX))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RCX))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RDX))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RBX)));*/ /* we do NOT match pusha xsp value *//* PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RSP))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RBP))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RSI))); PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_reg(REG_RDI))); dstack_offs += 16*XSP_SZ + XMM_SLOTS_SIZE; PRE(ilist, where, INSTR_CREATE_push(drcontext, opnd_create_base_disp(REG_XSP, REG_NULL, 0, dstack_offs - eflags_offs, OPSZ_STACK))); PRE(ilist, where, INSTR_CREATE_and(drcontext, opnd_create_base_disp(REG_XSP, REG_NULL, 0, 0, OPSZ_STACK), OPND_CREATE_INT32(~(EFLAGS_NON_SYSTEM | EFLAGS_IF)))); PRE(ilist, where, INSTR_CREATE_popf(drcontext));*/ /* now go through and mark inserted instrs as meta */ if (in == NULL) in = instrlist_first(ilist); else in = instr_get_next(in); while (in != where) { instr_set_ok_to_mangle(in, false); in = instr_get_next(in); } return dstack_offs; }