This function finds the "first" block immediately before the control flow flattening dispatcher begins. The logic is simple; start at the beginning of the function, keep moving forward until the next block has more than one predecessor. As it happens, this is where the assignment to the switch dispatch variable takes place, and that's mostly why we want it.
| 644 | // of the function, keep moving forward until the next block has more than one predecessor. As it happens, this is where the assignment to the switch |
| 645 | // dispatch variable takes place, and that's mostly why we want it. |
| 646 | mblock_t* GetFirstBlock(mbl_array_t* mba) |
| 647 | { |
| 648 | // Initialise iFirst and iDispatch to erroneous values |
| 649 | iFirst = -1, iDispatch = -1; |
| 650 | int npred_max = MIN_NUM_COMPARISONS - 1; |
| 651 | |
| 652 | // search for the block with maximum preds |
| 653 | for (mblock_t* mb = mba->get_mblock(0); mb->nextb != NULL; mb = mb->nextb) { |
| 654 | //dispatch is a block where jcc chain begins |
| 655 | if (npred_max < mb->npred() && mb->tail != NULL && is_mcode_jcond(mb->tail->opcode) && mb->tail->r.t == mop_n) { |
| 656 | if (isRegOvar(mb->tail->l.t) || (mb->tail->l.is_insn(m_and))) { |
| 657 | npred_max = mb->npred(); |
| 658 | iDispatch = mb->serial; |
| 659 | } |
| 660 | } |
| 661 | } |
| 662 | // extract the minimum block id (probably it's the "first" block) |
| 663 | if (iDispatch != -1) { |
| 664 | iFirst = mba->get_mblock(iDispatch)->pred(0); // it's rough but works mostly |
| 665 | mblock_t* mbFirst = mba->get_mblock(iFirst); |
| 666 | if (iFirst >= iDispatch || (mbFirst->tail != NULL && is_mcode_jcond(mbFirst->tail->opcode))) {// or check the minimum number gently |
| 667 | int iMinNum = iDispatch; |
| 668 | for (int i = 0; i < mba->get_mblock(iDispatch)->npred(); i++) { |
| 669 | int iCurr = mba->get_mblock(iDispatch)->pred(i); |
| 670 | mblock_t* mbCurr = mba->get_mblock(iCurr); |
| 671 | if (iCurr < iMinNum && !(mbCurr->tail != NULL && is_mcode_jcond(mbCurr->tail->opcode))) |
| 672 | iMinNum = iCurr; |
| 673 | } |
| 674 | if(iMinNum != iDispatch) |
| 675 | iFirst = iMinNum; |
| 676 | } |
| 677 | } |
| 678 | |
| 679 | if (iFirst != -1) |
| 680 | return mba->get_mblock(iFirst); |
| 681 | MSG_UF1(("[E] First block could not be found\n")); |
| 682 | return NULL; |
| 683 | } |
| 684 | |
| 685 | // This function computes all of the preliminary information needed for unflattening. |
| 686 | bool GetAssignedAndComparisonVariables(mbl_array_t *mba) |
no test coverage detected