This function attempts to locate the numeric assignment to a given variable "what" starting from the end of the block "mb". It follows definitions backwards, even across blocks, until it either reaches the block "mbClusterHead", or, if the boolean "bAllowMultiSuccs" is false, it will stop the first time it reaches a block with more than one successor. If it finds an assignment whose source is a st
| 1459 | // If it finds an assignment whose source is a stack variable, then it will not be able to continue in the backwards direction, |
| 1460 | // because intervening memory writes will make the definition information useless. |
| 1461 | int FindBlockTargetOrLastCopy(mblock_t *mb, mblock_t *mbClusterHead, mop_t *what, bool bAllowMultiSuccs, bool bRecursive) |
| 1462 | { |
| 1463 | int iClusterHead = mbClusterHead->serial; |
| 1464 | MovChain local; |
| 1465 | mop_t *opNum = NULL; |
| 1466 | // Search backwards looking for a numeric assignment to "what". We may or may not find a numeric assignment, |
| 1467 | // but we might find intervening assignments where "what" is copied from other variables. |
| 1468 | bool bFound = FindNumericDefBackwards(mb, what, opNum, local, bRecursive, bAllowMultiSuccs, iClusterHead); |
| 1469 | if (local.empty()) |
| 1470 | return -1; |
| 1471 | |
| 1472 | // Copy the assignment chain into the erasures vector, so we can later remove them if our analysis succeeds. |
| 1473 | m_DeferredErasuresLocal.insert(m_DeferredErasuresLocal.end(), local.begin(), local.end()); |
| 1474 | |
| 1475 | if (bFound) { |
| 1476 | // Look up the integer number of the block corresponding to that value. |
| 1477 | int64 theImm = opNum->nnn->value; |
| 1478 | if (cfi.bOpAndAssign) // m_and assignment with immediate value |
| 1479 | theImm &= cfi.OpAndImm; |
| 1480 | int iDestNo = cfi.jcm->FindBlockByKey((Key_t)theImm); |
| 1481 | if (iDestNo > 0) { |
| 1482 | if (cfi.bOpAndAssign) { |
| 1483 | MSG_UF3(("[I] Target resolved: %d (cluster head %d) -> %d (%x & %x = %x)\n", mb->serial, iClusterHead, iDestNo, opNum->nnn->value, cfi.OpAndImm, theImm)); |
| 1484 | } else { |
| 1485 | MSG_UF3(("[I] Target resolved: %d (cluster head %d) -> %d (%d (0x%X))\n", mb->serial, iClusterHead, iDestNo, (int)theImm, (int)theImm)); |
| 1486 | } |
| 1487 | return iDestNo; |
| 1488 | } |
| 1489 | MSG_UF1(("[E] %a: Block %d assign unknown key %d (0x%X)\n", mb->start, mb->serial, (int)theImm, (int)theImm)); |
| 1490 | } |
| 1491 | return -1; |
| 1492 | } |
| 1493 | |
| 1494 | // This function is used for unflattening constructs that have two successors, such as if statements. Given a block that assigns to the assignment variable |
| 1495 | // that has two predecessors, analyze each of the predecessors looking for numeric assignments by calling the previous function. |
no test coverage detected