static void handle_operand(op_t &op) { switch (op.type) { // code address case o_near: { ea_t ea = toEA(cmd.cs, op.addr); cref_t mode = fl_JN; if (cmd.itype == m740_jsr) { if ( !func_does_return(ea) ) flow = false; mode = fl_CN; } ua_add_cref(op.offb, ea, mode); } break; // data address case o_mem: { enum dref_t mode = dr_U; if (is_addr_ind(op)) mode = dr_R; /* NOT dr_O */ else if (is_addr_read(op)) mode = dr_R; else if (is_addr_write(op)) mode = dr_W; ua_add_dref(op.offb, toEA(cmd.cs, op.addr), mode); ua_dodata2(op.offb, op.addr, op.dtyp); } break; // immediate case o_imm: handle_imm(op); // if the value was converted to an offset, then create a data xref: if (isOff(uFlag, op.n)) ua_add_off_drefs2(op, dr_O, 0); break; // displ case o_displ: if (isOff(uFlag, op.n)) { ua_add_off_drefs2(op, dr_O, OOF_ADDR); ua_dodata2(op.offb, op.addr, op.dtyp); } break; // reg - do nothing case o_reg: case o_void: break; default: IDA_ERROR("Invalid op.type in handle_operand()"); } }
// emulate an instruction int emu(void) { uint32 feature = cmd.get_canon_feature(); flow = ((feature & CF_STOP) == 0); if (cmd.Op1.type != o_void) handle_operand(cmd.Op1); if (cmd.Op2.type != o_void) handle_operand(cmd.Op2); if (cmd.Op3.type != o_void) handle_operand(cmd.Op3); /* we can't use this code if (feature & CF_USE1) handle_operand(cmd.Op1, 1); if (feature & CF_USE2) handle_operand(cmd.Op2, 1); if (feature & CF_USE3) handle_operand(cmd.Op3, 1); */ // we don't use CF_JUMP //if (feature & CF_JUMP) switch (cmd.itype) { case m740_jmp: case m740_jsr: if (cmd.Op1.type != o_void && is_addr_ind(cmd.Op1)) QueueMark(Q_jumps, cmd.ea); break; } /* if (feature & CF_CHG1) handle_operand(cmd.Op1, 0); if (feature & CF_CHG2) handle_operand(cmd.Op2, 0); if (feature & CF_CHG3) handle_operand(cmd.Op3, 0); */ if (flow) { // skip the next byte if the current insn is brk if (cmd.itype == m740_brk) { ua_add_cref(0, cmd.ea + cmd.size + 1, fl_JN); doByte(cmd.ea + cmd.size, 1); } else { ua_add_cref(0, cmd.ea + cmd.size, fl_F); } } return 1; }
// output an address static void outaddr(op_t &op, const bool replace_with_label = true) { bool ind = is_addr_ind(op); // is operand indirect ? bool sp = is_addr_sp(op); // is operand special page ? int size = 16; // operand is 16 bits long if ( ind) out_symbol('(' ); if ( sp) { out_symbol('\\' ); size = 8; /* just display the first 8 bits */ } if ( !out_name_expr(op, toEA(cmd.cs, op.addr), op.addr) || !replace_with_label) { if ( replace_with_label) out_tagon(COLOR_ERROR ); OutValue(op, OOF_ADDR | OOFS_NOSIGN | (size < 16 ? OOFW_8 : OOFW_16) ); if ( replace_with_label) out_tagoff(COLOR_ERROR ); } if ( ind) out_symbol(')' ); }