A wrapper around my_find_def_backwards. It is extended in the following ways: If my_find_def_backwards identifies a definition of the variable "op" which is an assignment from another variable, this function then continues looking for numeric assignments to that var (and recursively so, if that var is assigned from another var). It keeps a list of all the assignment instructions it finds along the
| 1358 | // * It won't traverse into blocks with more than one successor if bAllowMultiSuccs is false. |
| 1359 | // * In any case, it will never traverse past the block numbered iBlockStop, if that parameter is non-negative. |
| 1360 | bool FindNumericDefBackwards(mblock_t* blk, mop_t* op, mop_t*& opNum, MovChain& chain, bool bRecursive, bool bAllowMultiSuccs, int iBlockStop) |
| 1361 | { |
| 1362 | mbl_array_t* mba = blk->mba; |
| 1363 | mlist_t ml; |
| 1364 | |
| 1365 | if (!InsertOp(blk, ml, op)) { |
| 1366 | MSG_UF3(("[i] FindNumericDefBackwards(%d, %s) fail, bad op\n", blk->serial, op->dstr())); |
| 1367 | return false; |
| 1368 | } |
| 1369 | |
| 1370 | // Start from the end of the block. This variable gets updated when a copy is encountered, so that subsequent searches start from the right place. |
| 1371 | minsn_t* mStart = NULL; |
| 1372 | bool bFirst = true; |
| 1373 | do { |
| 1374 | minsn_t* mDef; |
| 1375 | if(bFirst && cfi.bPtrAssign) // use hacked version only at the first assignment in a chain |
| 1376 | mDef = my_find_def_backwards_hacked(blk, ml, mStart); |
| 1377 | else |
| 1378 | mDef = my_find_def_backwards(blk, ml, mStart); |
| 1379 | if (mDef != NULL) { |
| 1380 | // Ensure that it's kind of a mov instruction we want |
| 1381 | if (mDef->opcode != m_mov && mDef->opcode != m_xdu && mDef->opcode != m_xds && |
| 1382 | !(bFirst && cfi.bPtrAssign && mDef->opcode == m_stx)) { |
| 1383 | MSG_UF1(("[E] %a: FindNumericDef found '%s' in blk %d\n", mDef->ea, mDef->dstr(), blk->serial)); |
| 1384 | return false; |
| 1385 | } |
| 1386 | bFirst = false; |
| 1387 | // Now that we found a mov, add it to the chain. |
| 1388 | MovInfo& mi = chain.push_back(); |
| 1389 | mi.opCopy = &mDef->l; |
| 1390 | mi.iBlock = blk->serial; |
| 1391 | mi.insMov = mDef; |
| 1392 | if (mDef->l.t == mop_n) {// Was it a numeric assignment? |
| 1393 | opNum = &mDef->l; |
| 1394 | MSG_UF3(("[I] %a: FindNumericDef found '%s' in blk %d\n", mDef->ea, mDef->dstr(), blk->serial)); |
| 1395 | return true; |
| 1396 | } |
| 1397 | |
| 1398 | // Otherwise, if it was not a numeric assignment, then try to track whatever was assigned to it. |
| 1399 | ml.clear(); |
| 1400 | if (cfi.bPtrAssign && mDef->l.t == mop_a) { //is it addr of? |
| 1401 | // InsertOp() doesnt work in that case becouse &var use all memory |
| 1402 | // try dirty hack |
| 1403 | if(!mop2list(mDef->l.a, &ml, mba)) { |
| 1404 | MSG_UF3(("[i] FindNumericDefBackwards(%d, %s) fail on mop2list\n", blk->serial, op->dstr())); |
| 1405 | return false; |
| 1406 | } |
| 1407 | } else { |
| 1408 | // This can only succeed if the thing that was assigned was a register or stack variable. |
| 1409 | if (!InsertOp(blk, ml, &mDef->l)) { |
| 1410 | MSG_UF3(("[i] FindNumericDefBackwards(%d, %s) fail, bad left op %s\n", blk->serial, op->dstr(), mDef->l.dstr())); |
| 1411 | return false; |
| 1412 | } |
| 1413 | } |
| 1414 | |
| 1415 | // Try to start tracking the other thing... |
| 1416 | MSG_UF3(("[I] %a: Blk %d FindNumericDef now tracking '%s' (bRecursive %d, bAllowMultiSuccs %d, iBlockStop %d)\n", |
| 1417 | mDef->ea, blk->serial, mDef->l.dstr(), bRecursive, bAllowMultiSuccs, iBlockStop)); |
no test coverage detected