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_dodata(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_drefs(op, dr_O); break; // displ case o_displ: if (isOff(uFlag, op.n)) { ua_add_off_drefs(op, dr_O); ua_dodata(op.addr, op.dtyp); } break; // reg - do nothing case o_reg: case o_void: break; default: IDA_ERROR("Invalid op.type in handle_operand()"); } }
static void TouchArg( op_t &x, int isload ) { switch( x.type ) { case o_imm: case o_displ: if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dr_O); break; case o_mem: case o_ind_mem: { ulong dea = intmem + x.addr; ua_dodata( dea, x.dtyp ); if( !isload ) doVar( dea ); ua_add_dref( x.offb, dea, isload ? dr_R : dr_W ); } break; case o_near: ulong ea = toEA( cmd.cs, x.addr ); int iscall = InstrIsSet( cmd.itype, CF_CALL ); ua_add_cref( x.offb, ea, iscall ? fl_CN : fl_JN ); if( flow && iscall ) { if ( !func_does_return(ea) ) flow = false; } } }
//---------------------------------------------------------------------- static void TouchArg(op_t &x,int isload) { switch ( x.type ) { case o_regpair: case o_reg: case o_phrase: break; case o_imm: if ( !isload ) goto badTouch; /* no break */ case o_displ: doImmdValue(x.n); if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dr_O); break; case o_near: ua_add_cref(x.offb,toEA(cmd.cs,x.addr),fl_JN); break; default: badTouch: warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } }
/* #<pydoc> def ua_add_off_drefs(op, type): """ Add xrefs for offset operand of the current instruction Please check ua.hpp / ua_add_off_drefs() @param op: operand (of type op_t) @return: None """ pass #</pydoc> */ ea_t py_ua_add_off_drefs(PyObject *py_op, dref_t type) { PYW_GIL_CHECK_LOCKED_SCOPE(); op_t *op = op_t_get_clink(py_op); return op == NULL ? BADADDR : ua_add_off_drefs(*op, type); }
//---------------------------------------------------------------------- static void handle_operand(op_t &x, bool read_access) { ea_t ea; dref_t dreftype; switch ( x.type ) { case o_void: case o_reg: break; case o_imm: QASSERT(557, read_access); dreftype = dr_O; MAKE_IMMD: doImmdValue(); if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dreftype); break; case o_displ: dreftype = read_access ? dr_R : dr_W; switch ( x.phrase ) { case rD: // "dp" case rDX: // "dp, X" case rDY: // "dp, Y" case riDX: // "(dp, X)" case rDi: // "(dp,n)" case rDiL: // "long(dp,n)" case rDiY: // "(dp,n), Y" case rDiLY: // "long(dp,n), Y" { sel_t dp = get_segreg(cmd.ea, rD); if ( dp != BADSEL ) { ea_t orig_ea = dp + x.addr; ea = xlat(orig_ea); goto MAKE_DREF; } else { goto MAKE_IMMD; } } case rAbsi: // "(abs)" case rAbsX: // "abs, X" case rAbsY: // "abs, Y" case rAbsiL: // "long(abs)" ea = toEA(dataSeg_op(x.n), x.addr); goto MAKE_DREF; case rAbsXi: // "(abs,X)" ea = toEA(codeSeg(cmd.ea, x.n), x.addr); // jmp, jsr goto MAKE_DREF; case rAbsLX: // "long abs, X" ea = x.addr; goto MAKE_DREF; default: goto MAKE_IMMD; } case o_mem: case o_mem_far: ea = calc_addr(x); MAKE_DREF: ua_dodata2(x.offb, ea, x.dtyp); if ( !read_access ) doVar(ea); ua_add_dref(x.offb, ea, read_access ? dr_R : dr_W); break; case o_near: case o_far: { ea_t orig_ea; ea = calc_addr(x, &orig_ea); if ( cmd.itype == M65816_per ) { ua_add_dref(x.offb, ea, dr_O); } else { bool iscall = InstrIsSet(cmd.itype, CF_CALL); cref_t creftype = x.type == o_near ? iscall ? fl_CN : fl_JN : iscall ? fl_CF : fl_JF; ua_add_cref(x.offb, ea, creftype); if ( flow && iscall ) flow = func_does_return(ea); } } break; default: INTERR(558); } }
//---------------------------------------------------------------------- static void TouchArg(op_t &x,int isAlt,int isload) { switch (x.type) { case o_phrase: //Добавляем в список ошибок(выводим сообщение) //ошибку и адресс где это случилось //QueueMark(Q_jumps, cmd.ea); case o_void: case o_reg: break; case o_imm: { //Установить для данного байта признак immedia doImmd(cmd.ea); //Получить флаг для указанного линейного адресса if(!isAlt) { uint32 offb; ushort addr = ushort(x.addr); if(x.type == o_displ ) { addr += (ushort)cmd.ip; addr += cmd.size; //Получить линейный адресс offb = (uint32)toEA(codeSeg(addr,x.n), 0); DataSet(x, offb+addr, isload); } else if ( isOff(uFlag, x.n) ) { reref: ua_add_off_drefs(x, dr_O); if ( x.type == o_displ ) //Преобразовать данные по указанному линейному адрессу в указанный тип ua_dodata2(x.offb, calc_target(cmd.ea+x.offb, cmd.ea, x.n, x.addr), x.dtyp); } else if(x.type == o_displ && !x.reg && !isDefArg(uFlag, x.n) && set_offset(cmd.ea, x.n, toEA(cmd.cs,0))) goto reref; } } break; case o_bit: case o_mem: // Конвертирование в данные(указан адресс) по указанному типу, //добавить крос референсы для текущей инструкции DataSet(x, toEA(codeSeg(x.addr,x.n), x.addr), isload); break; case o_near: { //Получить линейный адресс ea_t ea = toEA(cmd.cs, x.addr); //Проверить является ли значение по указанному линейному адрессу - инструкцией int iscall = InstrIsSet(cmd.itype, CF_CALL); //добавить крос референсы для текущей инструкции ua_add_cref(x.offb, ea, iscall ? fl_CN : fl_JN); if ( iscall ) flow = func_does_return(ea); } break; default: warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } }