00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <assert.h>
00033 #if defined(_MSC_VER) && _MSC_VER <= 1200
00034 #pragma warning(disable:4786)
00035 #endif
00036
00037 #include "gc.h"
00038 #include "types.h"
00039 #include "statement.h"
00040 #include "exp.h"
00041 #include "cfg.h"
00042 #include "register.h"
00043 #include "rtl.h"
00044 #include "hllcode.h"
00045 #include "proc.h"
00046 #include "prog.h"
00047 #include "util.h"
00048 #include "boomerang.h"
00049 #include "type.h"
00050 #include "log.h"
00051 #include "visitor.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 BasicBlock::BasicBlock()
00065 :
00066 m_DFTfirst(0), m_DFTlast(0),
00067 m_structType(NONE), m_loopCondType(NONE),
00068 m_loopHead(NULL), m_caseHead(NULL),
00069 m_condFollow(NULL), m_loopFollow(NULL),
00070 m_latchNode(NULL),
00071 m_nodeType(INVALID),
00072 m_pRtls(NULL),
00073 m_iLabelNum(0),
00074 m_labelneeded(false),
00075 m_bIncomplete(true),
00076 m_bJumpReqd(false),
00077 m_iNumInEdges(0),
00078 m_iNumOutEdges(0),
00079 m_iTraversed(false),
00080
00081 ord(-1), revOrd(-1), inEdgesVisited(0), numForwardInEdges(-1), traversed(UNTRAVERSED), hllLabel(false), indentLevel(0),
00082 immPDom(NULL), loopHead(NULL), caseHead(NULL), condFollow(NULL), loopFollow(NULL), latchNode(NULL), sType(Seq),
00083 usType(Structured),
00084
00085 overlappedRegProcessingDone(false)
00086 {
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 BasicBlock::~BasicBlock() {
00096 if (m_pRtls)
00097 {
00098
00099 for (std::list<RTL*>::iterator it = m_pRtls->begin(); it != m_pRtls->end(); it++)
00100 {
00101 if (*it)
00102 {
00103 delete *it;
00104 }
00105 }
00106
00107
00108 delete m_pRtls;
00109 m_pRtls = NULL;
00110 }
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120 BasicBlock::BasicBlock(const BasicBlock& bb)
00121 : m_DFTfirst(0), m_DFTlast(0),
00122 m_structType(bb.m_structType), m_loopCondType(bb.m_loopCondType),
00123 m_loopHead(bb.m_loopHead), m_caseHead(bb.m_caseHead),
00124 m_condFollow(bb.m_condFollow), m_loopFollow(bb.m_loopFollow),
00125 m_latchNode(bb.m_latchNode),
00126 m_nodeType(bb.m_nodeType),
00127 m_pRtls(NULL),
00128 m_iLabelNum(bb.m_iLabelNum),
00129 m_labelneeded(false),
00130 m_bIncomplete(bb.m_bIncomplete),
00131 m_bJumpReqd(bb.m_bJumpReqd),
00132 m_InEdges(bb.m_InEdges),
00133 m_OutEdges(bb.m_OutEdges),
00134 m_iNumInEdges(bb.m_iNumInEdges),
00135 m_iNumOutEdges(bb.m_iNumOutEdges),
00136 m_iTraversed(false),
00137
00138 ord(bb.ord), revOrd(bb.revOrd), inEdgesVisited(bb.inEdgesVisited), numForwardInEdges(bb.numForwardInEdges),
00139 traversed(bb.traversed), hllLabel(bb.hllLabel), indentLevel(bb.indentLevel), immPDom(bb.immPDom), loopHead(bb.loopHead),
00140 caseHead(bb.caseHead), condFollow(bb.condFollow), loopFollow(bb.loopFollow), latchNode(bb.latchNode), sType(bb.sType),
00141 usType(bb.usType)
00142 {
00143 setRTLs(bb.m_pRtls);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 BasicBlock::BasicBlock(std::list<RTL*>* pRtls, BBTYPE bbType, int iNumOutEdges)
00155 : m_DFTfirst(0), m_DFTlast(0),
00156 m_structType(NONE), m_loopCondType(NONE),
00157 m_loopHead(NULL), m_caseHead(NULL),
00158 m_condFollow(NULL), m_loopFollow(NULL),
00159 m_latchNode(NULL),
00160 m_nodeType(bbType),
00161 m_pRtls(NULL),
00162 m_iLabelNum(0),
00163 m_labelneeded(false),
00164 m_bIncomplete(false),
00165 m_bJumpReqd(false),
00166 m_iNumInEdges(0),
00167 m_iNumOutEdges(iNumOutEdges),
00168 m_iTraversed(false),
00169
00170 ord(-1), revOrd(-1), inEdgesVisited(0), numForwardInEdges(-1), traversed(UNTRAVERSED), hllLabel(false), indentLevel(0),
00171 immPDom(NULL), loopHead(NULL), caseHead(NULL), condFollow(NULL), loopFollow(NULL), latchNode(NULL), sType(Seq),
00172 usType(Structured)
00173 {
00174 m_OutEdges.reserve(iNumOutEdges);
00175
00176
00177 setRTLs(pRtls);
00178
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188 int BasicBlock::getLabel() {
00189 return m_iLabelNum;
00190 }
00191
00192 bool BasicBlock::isCaseOption() {
00193 if (caseHead)
00194 for (unsigned int i = 0; i < caseHead->getOutEdges().size() - 1; i++)
00195 if (caseHead->getOutEdge(i) == this)
00196 return true;
00197 return false;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 bool BasicBlock::isTraversed() {
00207 return m_iTraversed;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216 void BasicBlock::setTraversed(bool bTraversed) {
00217 m_iTraversed = bTraversed;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227 void BasicBlock::setRTLs(std::list<RTL*>* rtls) {
00228
00229 m_pRtls = rtls;
00230
00231
00232 }
00233
00234
00235
00236
00237
00238
00239
00240 BBTYPE BasicBlock::getType() {
00241 return m_nodeType;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 void BasicBlock::updateType(BBTYPE bbType, int iNumOutEdges) {
00253 m_nodeType = bbType;
00254 m_iNumOutEdges = iNumOutEdges;
00255
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265 void BasicBlock::setJumpReqd() {
00266 m_bJumpReqd = true;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 bool BasicBlock::isJumpReqd() {
00276 return m_bJumpReqd;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 char debug_buffer[DEBUG_BUFSIZE];
00286
00287 char* BasicBlock::prints() {
00288 std::ostringstream ost;
00289 print(ost);
00290
00291
00292 strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00293 debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00294 return debug_buffer;
00295 }
00296
00297 void BasicBlock::dump() {
00298 print(std::cerr);
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308 void BasicBlock::print(std::ostream& os, bool html) {
00309 if (html)
00310 os << "<br>";
00311 if (m_iLabelNum) os << "L" << std::dec << m_iLabelNum << ": ";
00312 switch(m_nodeType) {
00313 case ONEWAY: os << "Oneway BB"; break;
00314 case TWOWAY: os << "Twoway BB"; break;
00315 case NWAY: os << "Nway BB"; break;
00316 case CALL: os << "Call BB"; break;
00317 case RET: os << "Ret BB"; break;
00318 case FALL: os << "Fall BB"; break;
00319 case COMPJUMP: os << "Computed jump BB"; break;
00320 case COMPCALL: os << "Computed call BB"; break;
00321 case INVALID: os << "Invalid BB"; break;
00322 }
00323 os << ":\n";
00324 os << "in edges: ";
00325 for (unsigned int i = 0; i < m_InEdges.size(); i++)
00326 os << std::hex << m_InEdges[i]->getHiAddr() << " ";
00327 os << std::dec << "\n";
00328 os << "out edges: ";
00329 for (unsigned int i = 0; i < m_OutEdges.size(); i++)
00330 os << std::hex << m_OutEdges[i]->getLowAddr() << " ";
00331 os << std::dec << "\n";
00332 if (m_pRtls) {
00333 if (html)
00334 os << "<table>\n";
00335 std::list<RTL*>::iterator rit;
00336 for (rit = m_pRtls->begin(); rit != m_pRtls->end(); rit++) {
00337 (*rit)->print(os, html);
00338 }
00339 if (html)
00340 os << "</table>\n";
00341 }
00342 if (m_bJumpReqd) {
00343 if (html)
00344 os << "<br>";
00345 os << "Synthetic out edge(s) to ";
00346 for (int i=0; i < m_iNumOutEdges; i++) {
00347 PBB outEdge = m_OutEdges[i];
00348 if (outEdge && outEdge->m_iLabelNum)
00349 os << "L" << std::dec << outEdge->m_iLabelNum << " ";
00350 }
00351 os << std::endl;
00352 }
00353 }
00354
00355 void BasicBlock::printToLog() {
00356 std::ostringstream ost;
00357 print(ost);
00358 LOG << ost.str().c_str();
00359 }
00360
00361 bool BasicBlock::isBackEdge(int inEdge) {
00362 PBB in = m_InEdges[inEdge];
00363 return this == in || (m_DFTfirst < in->m_DFTfirst && m_DFTlast > in->m_DFTlast);
00364 }
00365
00366
00367
00368 void printBB(PBB bb) {
00369 bb->print(std::cerr);
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 ADDRESS BasicBlock::getLowAddr() {
00383 if (m_pRtls == NULL || m_pRtls->size() == 0) return 0;
00384 ADDRESS a = m_pRtls->front()->getAddress();
00385 if ((a == 0) && (m_pRtls->size() > 1)) {
00386 std::list<RTL*>::iterator it = m_pRtls->begin();
00387 ADDRESS add2 = (*++it)->getAddress();
00388
00389
00390 if (add2 < 0x10)
00391
00392 return 0;
00393 return add2;
00394 }
00395 return a;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 ADDRESS BasicBlock::getHiAddr() {
00406 assert(m_pRtls != NULL);
00407 return m_pRtls->back()->getAddress();
00408 }
00409
00410
00411
00412
00413
00414
00415
00416 std::list<RTL*>* BasicBlock::getRTLs() {
00417 return m_pRtls;
00418 }
00419
00420 RTL* BasicBlock::getRTLWithStatement(Statement *stmt)
00421 {
00422 if (m_pRtls == NULL)
00423 return NULL;
00424 for (std::list<RTL*>::iterator it = m_pRtls->begin(); it != m_pRtls->end(); it++) {
00425 RTL *rtl = *it;
00426 for (std::list<Statement*>::iterator it1 = rtl->getList().begin(); it1 != rtl->getList().end(); it1++)
00427 if (*it1 == stmt)
00428 return rtl;
00429 }
00430 return NULL;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439 std::vector<PBB>& BasicBlock::getInEdges() {
00440 return m_InEdges;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449 std::vector<PBB>& BasicBlock::getOutEdges() {
00450 return m_OutEdges;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 void BasicBlock::setInEdge(int i, PBB pNewInEdge) {
00462 m_InEdges[i] = pNewInEdge;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 void BasicBlock::setOutEdge(int i, PBB pNewOutEdge) {
00475 if (m_OutEdges.size() == 0) {
00476 assert(i == 0);
00477 m_OutEdges.push_back(pNewOutEdge);
00478 } else {
00479 assert(i < (int)m_OutEdges.size());
00480 m_OutEdges[i] = pNewOutEdge;
00481 }
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491 PBB BasicBlock::getOutEdge(unsigned int i) {
00492 if (i < m_OutEdges.size()) return m_OutEdges[i];
00493 else return 0;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 PBB BasicBlock::getCorrectOutEdge(ADDRESS a) {
00506 std::vector<PBB>::iterator it;
00507 for (it = m_OutEdges.begin(); it != m_OutEdges.end(); it++) {
00508 if ((*it)->getLowAddr() == a) return *it;
00509 }
00510 return 0;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 void BasicBlock::addInEdge(PBB pNewInEdge) {
00522 m_InEdges.push_back(pNewInEdge);
00523 m_iNumInEdges++;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 void BasicBlock::deleteInEdge(std::vector<PBB>::iterator& it) {
00537 it = m_InEdges.erase(it);
00538 m_iNumInEdges--;
00539 }
00540
00541 void BasicBlock::deleteInEdge(PBB edge) {
00542 for (std::vector<PBB>::iterator it = m_InEdges.begin();
00543 it != m_InEdges.end(); it++) {
00544 if (*it == edge) {
00545 deleteInEdge(it);
00546 break;
00547 }
00548 }
00549 }
00550
00551 void BasicBlock::deleteEdge(PBB edge) {
00552 edge->deleteInEdge(this);
00553 for (std::vector<PBB>::iterator it = m_OutEdges.begin();
00554 it != m_OutEdges.end(); it++) {
00555 if (*it == edge) {
00556 m_OutEdges.erase(it);
00557 m_iNumOutEdges--;
00558 break;
00559 }
00560 }
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 unsigned BasicBlock::DFTOrder(int& first, int& last) {
00572 first++;
00573 m_DFTfirst = first;
00574
00575 unsigned numTraversed = 1;
00576 m_iTraversed = true;
00577
00578 for (std::vector<PBB>::iterator it = m_OutEdges.begin(); it != m_OutEdges.end(); it++) {
00579 PBB child = *it;
00580 if (child->m_iTraversed == false)
00581 numTraversed = numTraversed + child->DFTOrder(first,last);
00582 }
00583
00584 last++;
00585 m_DFTlast = last;
00586
00587 return numTraversed;
00588 }
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 unsigned BasicBlock::RevDFTOrder(int& first, int& last) {
00599 first++;
00600 m_DFTrevfirst = first;
00601
00602 unsigned numTraversed = 1;
00603 m_iTraversed = true;
00604
00605 for (std::vector<PBB>::iterator it = m_InEdges.begin(); it != m_InEdges.end();
00606 it++) {
00607
00608 PBB parent = *it;
00609 if (parent->m_iTraversed == false)
00610 numTraversed = numTraversed + parent->RevDFTOrder(first,last);
00611 }
00612
00613 last++;
00614 m_DFTrevlast = last;
00615
00616 return numTraversed;
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626 bool BasicBlock::lessAddress(PBB bb1, PBB bb2) {
00627 return bb1->getLowAddr() < bb2->getLowAddr();
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 bool BasicBlock::lessFirstDFT(PBB bb1, PBB bb2) {
00639 return bb1->m_DFTfirst < bb2->m_DFTfirst;
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 bool BasicBlock::lessLastDFT(PBB bb1, PBB bb2) {
00652 return bb1->m_DFTlast < bb2->m_DFTlast;
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662 ADDRESS BasicBlock::getCallDest() {
00663 if (m_nodeType != CALL)
00664 return (ADDRESS)-1;
00665 if (m_pRtls->size() == 0)
00666 return (ADDRESS)-1;
00667 RTL* lastRtl = m_pRtls->back();
00668 RTL::reverse_iterator rit;
00669 std::list<Statement*>& sl = lastRtl->getList();
00670 for (rit = sl.rbegin(); rit != sl.rend(); rit++) {
00671 if ((*rit)->getKind() == STMT_CALL)
00672 return ((CallStatement*)(*rit))->getFixedDest();
00673 }
00674 return (ADDRESS)-1;
00675 }
00676
00677 Proc *BasicBlock::getCallDestProc() {
00678 if (m_nodeType != CALL)
00679 return 0;
00680 if (m_pRtls->size() == 0)
00681 return 0;
00682 RTL* lastRtl = m_pRtls->back();
00683 RTL::reverse_iterator it;
00684 std::list<Statement*>& sl = lastRtl->getList();
00685 for (it = sl.rbegin(); it != sl.rend(); it++) {
00686 if ((*it)->getKind() == STMT_CALL)
00687 return ((CallStatement*)(*it))->getDestProc();
00688 }
00689 return 0;
00690 }
00691
00692
00693
00694
00695 Statement* BasicBlock::getFirstStmt(rtlit& rit, StatementList::iterator& sit) {
00696 if (m_pRtls == NULL) return NULL;
00697 rit = m_pRtls->begin();
00698 while (rit != m_pRtls->end()) {
00699 RTL* rtl = *rit;
00700 sit = rtl->getList().begin();
00701 if (sit != rtl->getList().end())
00702 return *sit;
00703 rit++;
00704 }
00705 return NULL;
00706 }
00707
00708 Statement* BasicBlock::getNextStmt(rtlit& rit, StatementList::iterator& sit) {
00709 if (++sit != (*rit)->getList().end())
00710 return *sit;
00711
00712 do {
00713 if (++rit == m_pRtls->end())
00714 return NULL;
00715 } while ((*rit)->getNumStmt() == 0);
00716 sit = (*rit)->getList().begin();
00717 return *sit;
00718 }
00719
00720 Statement* BasicBlock::getPrevStmt(rtlrit& rit, StatementList::reverse_iterator& sit) {
00721 if (++sit != (*rit)->getList().rend())
00722 return *sit;
00723
00724 do {
00725 if (++rit == m_pRtls->rend())
00726 return NULL;
00727 } while ((*rit)->getNumStmt() == 0);
00728 sit = (*rit)->getList().rbegin();
00729 return *sit;
00730 }
00731
00732 Statement* BasicBlock::getLastStmt(rtlrit& rit, StatementList::reverse_iterator& sit) {
00733 if (m_pRtls == NULL) return NULL;
00734 rit = m_pRtls->rbegin();
00735 while (rit != m_pRtls->rend()) {
00736 RTL* rtl = *rit;
00737 sit = rtl->getList().rbegin();
00738 if (sit != rtl->getList().rend())
00739 return *sit;
00740 rit++;
00741 }
00742 return NULL;
00743 }
00744
00745 Statement* BasicBlock::getFirstStmt() {
00746 rtlit rit;
00747 StatementList::iterator sit;
00748 if (m_pRtls == NULL) return NULL;
00749 rit = m_pRtls->begin();
00750 while (rit != m_pRtls->end()) {
00751 RTL* rtl = *rit;
00752 sit = rtl->getList().begin();
00753 if (sit != rtl->getList().end())
00754 return *sit;
00755 rit++;
00756 }
00757 return NULL;
00758 }
00759 Statement* BasicBlock::getLastStmt() {
00760 rtlrit rit;
00761 StatementList::reverse_iterator sit;
00762 if (m_pRtls == NULL) return NULL;
00763 rit = m_pRtls->rbegin();
00764 while (rit != m_pRtls->rend()) {
00765 RTL* rtl = *rit;
00766 sit = rtl->getList().rbegin();
00767 if (sit != rtl->getList().rend())
00768 return *sit;
00769 rit++;
00770 }
00771 return NULL;
00772 }
00773
00774 void BasicBlock::getStatements(StatementList &stmts)
00775 {
00776 std::list<RTL*> *rtls = getRTLs();
00777 if (rtls) {
00778 for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
00779 RTL *rtl = *rit;
00780 for (RTL::iterator it = rtl->getList().begin(); it != rtl->getList().end(); it++) {
00781 if ((*it)->getBB() == NULL)
00782 (*it)->setBB(this);
00783 stmts.append(*it);
00784 }
00785 }
00786 }
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 Exp *BasicBlock::getCond() throw(LastStatementNotABranchError) {
00801
00802 assert(m_pRtls);
00803 RTL *last = m_pRtls->back();
00804
00805 BranchStatement* bs = (BranchStatement*)last->getHlStmt();
00806 if (bs && bs->getKind() == STMT_BRANCH)
00807 return bs->getCondExpr();
00808 if (VERBOSE)
00809 LOG << "throwing LastStatementNotABranchError\n";
00810 throw LastStatementNotABranchError(last->getHlStmt());
00811 }
00812
00813
00814 Exp *BasicBlock::getDest() throw(LastStatementNotAGotoError) {
00815
00816 assert(m_pRtls);
00817 RTL *lastRtl = m_pRtls->back();
00818
00819 Statement* lastStmt = lastRtl->getHlStmt();
00820 CaseStatement* cs = dynamic_cast<CaseStatement*>(lastStmt);
00821 if (cs) {
00822
00823 SWITCH_INFO* si = cs->getSwitchInfo();
00824 if (si)
00825 return si->pSwitchVar;
00826 } else {
00827 GotoStatement* gs = dynamic_cast<GotoStatement*>(lastStmt);
00828 if (gs)
00829 return gs->getDest();
00830 }
00831 if (VERBOSE)
00832 LOG << "throwing LastStatementNotAGotoError\n";
00833 throw LastStatementNotAGotoError(lastStmt);
00834 }
00835
00836 void BasicBlock::setCond(Exp *e) throw(LastStatementNotABranchError) {
00837
00838 assert(m_pRtls);
00839 RTL *last = m_pRtls->back();
00840
00841 std::list<Statement*>& sl = last->getList();
00842 RTL::reverse_iterator it;
00843 assert(sl.size());
00844 for (it = sl.rbegin(); it != sl.rend(); it++) {
00845 if ((*it)->getKind() == STMT_BRANCH) {
00846 ((BranchStatement*)(*it))->setCondExpr(e);
00847 return;
00848 }
00849 }
00850 throw LastStatementNotABranchError(NULL);
00851 }
00852
00853
00854 bool BasicBlock::isJmpZ(PBB dest) {
00855
00856 assert(m_pRtls);
00857 RTL *last = m_pRtls->back();
00858
00859 std::list<Statement*>& sl = last->getList();
00860 std::list<Statement*>::reverse_iterator it;
00861 assert(sl.size());
00862 for (it = sl.rbegin(); it != sl.rend(); it++) {
00863 if ((*it)->getKind() == STMT_BRANCH) {
00864 BRANCH_TYPE jt = ((BranchStatement*)(*it))->getCond();
00865 if ((jt != BRANCH_JE) && (jt != BRANCH_JNE)) return false;
00866 PBB trueEdge = m_OutEdges[0];
00867 if (jt == BRANCH_JE)
00868 return dest == trueEdge;
00869 else {
00870 PBB falseEdge = m_OutEdges[1];
00871 return dest == falseEdge;
00872 }
00873 }
00874 }
00875 assert(0);
00876 return false;
00877 }
00878
00879
00880 BasicBlock *BasicBlock::getLoopBody() {
00881 assert(m_structType == PRETESTLOOP || m_structType == POSTTESTLOOP || m_structType == ENDLESSLOOP);
00882 assert(m_iNumOutEdges == 2);
00883 if (m_OutEdges[0] != m_loopFollow)
00884 return m_OutEdges[0];
00885 return m_OutEdges[1];
00886 }
00887
00888 bool BasicBlock::isAncestorOf(BasicBlock *other) {
00889 return ((loopStamps[0] < other->loopStamps[0] &&
00890 loopStamps[1] > other->loopStamps[1]) ||
00891 (revLoopStamps[0] < other->revLoopStamps[0] &&
00892 revLoopStamps[1] > other->revLoopStamps[1]));
00893
00894
00895
00896 }
00897
00898 void BasicBlock::simplify() {
00899 if (m_pRtls)
00900 for (std::list<RTL*>::iterator it = m_pRtls->begin(); it != m_pRtls->end(); it++)
00901 (*it)->simplify();
00902 if (m_nodeType == TWOWAY) {
00903 if (m_pRtls == NULL || m_pRtls->size() == 0) {
00904 m_nodeType = FALL;
00905 } else {
00906 RTL *last = m_pRtls->back();
00907 if (last->getNumStmt() == 0) {
00908 m_nodeType = FALL;
00909 } else if (last->elementAt(last->getNumStmt()-1)->isGoto()) {
00910 m_nodeType = ONEWAY;
00911 } else if (!last->elementAt(last->getNumStmt()-1)->isBranch()) {
00912 m_nodeType = FALL;
00913 }
00914 }
00915 if (m_nodeType == FALL) {
00916
00917 if (VERBOSE) {
00918 LOG << "turning TWOWAY into FALL: "
00919 << m_OutEdges[0]->getLowAddr() << " "
00920 << m_OutEdges[1]->getLowAddr() << "\n";
00921 }
00922 PBB redundant = m_OutEdges[0];
00923 m_OutEdges[0] = m_OutEdges[1];
00924 m_OutEdges.resize(1);
00925 m_iNumOutEdges = 1;
00926 if (VERBOSE)
00927 LOG << "redundant edge to " << redundant->getLowAddr() << " inedges: ";
00928 std::vector<PBB> rinedges = redundant->m_InEdges;
00929 redundant->m_InEdges.clear();
00930 for (unsigned i = 0; i < rinedges.size(); i++) {
00931 if (VERBOSE)
00932 LOG << rinedges[i]->getLowAddr() << " ";
00933 if (rinedges[i] != this)
00934 redundant->m_InEdges.push_back(rinedges[i]);
00935 else {
00936 if (VERBOSE)
00937 LOG << "(ignored) ";
00938 }
00939 }
00940 if (VERBOSE)
00941 LOG << "\n";
00942 redundant->m_iNumInEdges = redundant->m_InEdges.size();
00943 if (VERBOSE)
00944 LOG << " after: " << m_OutEdges[0]->getLowAddr() << "\n";
00945 }
00946 if (m_nodeType == ONEWAY) {
00947
00948 if (VERBOSE) {
00949 LOG << "turning TWOWAY into ONEWAY: "
00950 << m_OutEdges[0]->getLowAddr() << " "
00951 << m_OutEdges[1]->getLowAddr() << "\n";
00952 }
00953 PBB redundant = m_OutEdges[1];
00954 m_OutEdges.resize(1);
00955 m_iNumOutEdges = 1;
00956 if (VERBOSE)
00957 LOG << "redundant edge to " << redundant->getLowAddr() << " inedges: ";
00958 std::vector<PBB> rinedges = redundant->m_InEdges;
00959 redundant->m_InEdges.clear();
00960 for (unsigned i = 0; i < rinedges.size(); i++) {
00961 if (VERBOSE)
00962 LOG << rinedges[i]->getLowAddr() << " ";
00963 if (rinedges[i] != this)
00964 redundant->m_InEdges.push_back(rinedges[i]);
00965 else {
00966 if (VERBOSE)
00967 LOG << "(ignored) ";
00968 }
00969 }
00970 if (VERBOSE)
00971 LOG << "\n";
00972 redundant->m_iNumInEdges = redundant->m_InEdges.size();
00973 if (VERBOSE)
00974 LOG << " after: " << m_OutEdges[0]->getLowAddr() << "\n";
00975 }
00976 }
00977 }
00978
00979 bool BasicBlock::hasBackEdgeTo(BasicBlock* dest) {
00980
00981 return dest == this || dest->isAncestorOf(this);
00982 }
00983
00984
00985
00986 bool BasicBlock::allParentsGenerated()
00987 {
00988 for (unsigned int i = 0; i < m_InEdges.size(); i++)
00989 if (!m_InEdges[i]->hasBackEdgeTo(this) &&
00990 m_InEdges[i]->traversed != DFS_CODEGEN)
00991 return false;
00992 return true;
00993 }
00994
00995
00996
00997
00998
00999 void BasicBlock::emitGotoAndLabel(HLLCode *hll, int indLevel, PBB dest)
01000 {
01001 if (loopHead && (loopHead == dest || loopHead->loopFollow == dest)) {
01002 if (loopHead == dest)
01003 hll->AddContinue(indLevel);
01004 else
01005 hll->AddBreak(indLevel);
01006 } else {
01007 hll->AddGoto(indLevel, dest->ord);
01008
01009 dest->hllLabel = true;
01010 }
01011 }
01012
01013
01014 void BasicBlock::WriteBB(HLLCode *hll, int indLevel)
01015 {
01016 if (DEBUG_GEN)
01017 LOG << "Generating code for BB at " << getLowAddr() << "\n";
01018
01019
01020
01021 hll->AddLabel(indLevel, ord);
01022
01023 if (m_pRtls) {
01024 for (std::list<RTL*>::iterator it = m_pRtls->begin(); it != m_pRtls->end(); it++) {
01025 if (DEBUG_GEN)
01026 LOG << (*it)->getAddress() << "\t";
01027 (*it)->generateCode(hll, this, indLevel);
01028 }
01029 if (DEBUG_GEN)
01030 LOG << "\n";
01031 }
01032
01033
01034 indentLevel = indLevel;
01035 }
01036
01037 void BasicBlock::generateCode(HLLCode *hll, int indLevel, PBB latch,
01038 std::list<PBB> &followSet, std::list<PBB> &gotoSet, UserProc* proc) {
01039
01040
01041 PBB enclFollow = followSet.size() == 0 ? NULL : followSet.back();
01042
01043 if (isIn(gotoSet, this) && !isLatchNode() &&
01044 ((latch && latch->loopHead && this == latch->loopHead->loopFollow) ||
01045 !allParentsGenerated())) {
01046 emitGotoAndLabel(hll, indLevel, this);
01047 return;
01048 } else if (isIn(followSet, this)) {
01049 if (this != enclFollow) {
01050 emitGotoAndLabel(hll, indLevel, this);
01051 return;
01052 } else return;
01053 }
01054
01055
01056 if (traversed == DFS_CODEGEN) {
01057
01058
01059
01060
01061 return;
01062 } else
01063 traversed = DFS_CODEGEN;
01064
01065
01066
01067 if (isLatchNode())
01068 if (latch && latch->loopHead &&
01069 indLevel == latch->loopHead->indentLevel + (latch->loopHead->lType == PreTested ? 1 : 0)) {
01070 WriteBB(hll, indLevel);
01071 return;
01072 } else {
01073
01074 traversed = UNTRAVERSED;
01075
01076 emitGotoAndLabel(hll, indLevel, this);
01077 return;
01078 }
01079
01080 PBB child = NULL;
01081 switch(sType) {
01082 case Loop:
01083 case LoopCond:
01084
01085 if (loopFollow)
01086 followSet.push_back(loopFollow);
01087
01088 if (lType == PreTested) {
01089 assert(latchNode->m_OutEdges.size() == 1);
01090
01091
01092 WriteBB(hll, indLevel);
01093
01094
01095 Exp *cond = getCond();
01096 if (m_OutEdges[BTHEN] == loopFollow) {
01097 cond = new Unary(opNot, cond);
01098 cond = cond->simplify();
01099 }
01100 hll->AddPretestedLoopHeader(indLevel, cond);
01101
01102
01103 PBB loopBody = (m_OutEdges[BELSE] == loopFollow) ? m_OutEdges[BTHEN] : m_OutEdges[BELSE];
01104 loopBody->generateCode(hll, indLevel + 1, latchNode, followSet, gotoSet, proc);
01105
01106
01107 if (latchNode->traversed != DFS_CODEGEN) {
01108 latchNode->traversed = DFS_CODEGEN;
01109 latchNode->WriteBB(hll, indLevel+1);
01110 }
01111
01112
01113
01114 hllLabel = false;
01115 WriteBB(hll, indLevel+1);
01116
01117
01118 hll->AddPretestedLoopEnd(indLevel);
01119 } else {
01120
01121 if (lType == Endless)
01122 hll->AddEndlessLoopHeader(indLevel);
01123 else
01124 hll->AddPosttestedLoopHeader(indLevel);
01125
01126
01127
01128 if (sType == LoopCond) {
01129
01130 sType = Cond;
01131 traversed = UNTRAVERSED;
01132 generateCode(hll, indLevel + 1, latchNode, followSet, gotoSet, proc);
01133 } else {
01134 WriteBB(hll, indLevel+1);
01135
01136
01137 m_OutEdges[0]->generateCode(hll, indLevel + 1, latchNode, followSet, gotoSet, proc);
01138 }
01139
01140 if (lType == PostTested) {
01141
01142 if (latchNode->traversed != DFS_CODEGEN) {
01143 latchNode->traversed = DFS_CODEGEN;
01144 latchNode->WriteBB(hll, indLevel+1);
01145 }
01146
01147
01148
01149
01150 hll->AddPosttestedLoopEnd(indLevel, latchNode->getCond());
01151 } else {
01152 assert(lType == Endless);
01153
01154
01155 if (latchNode->traversed != DFS_CODEGEN) {
01156 latchNode->traversed = DFS_CODEGEN;
01157 latchNode->WriteBB(hll, indLevel+1);
01158 }
01159
01160
01161 hll->AddEndlessLoopEnd(indLevel);
01162 }
01163 }
01164
01165
01166 if (loopFollow) {
01167
01168 followSet.resize(followSet.size()-1);
01169
01170 if (loopFollow->traversed != DFS_CODEGEN)
01171 loopFollow->generateCode(hll, indLevel, latch, followSet, gotoSet, proc);
01172 else
01173 emitGotoAndLabel(hll, indLevel, loopFollow);
01174 }
01175 break;
01176
01177 case Cond:
01178 {
01179
01180 if (latchNode)
01181 sType = LoopCond;
01182
01183
01184
01185 PBB tmpCondFollow = NULL;
01186
01187
01188
01189 int gotoTotal = 0;
01190
01191
01192 if (cType == Case)
01193 followSet.push_back(condFollow);
01194 else if (cType != Case && condFollow) {
01195
01196
01197
01198
01199 if (usType == Structured)
01200 followSet.push_back(condFollow);
01201
01202
01203
01204
01205 else {
01206 if (usType == JumpInOutLoop) {
01207
01208 PBB myLoopHead = (sType == LoopCond ? this : loopHead);
01209 gotoSet.push_back(condFollow);
01210 gotoTotal++;
01211
01212
01213 if (latch) {
01214 gotoSet.push_back(latch);
01215 gotoTotal++;
01216 }
01217
01218 if (condFollow->loopHead && condFollow->loopHead != myLoopHead) {
01219 gotoSet.push_back(condFollow->loopHead);
01220 gotoTotal++;
01221 }
01222 }
01223
01224 if (cType == IfThen)
01225 tmpCondFollow = m_OutEdges[BELSE];
01226 else
01227 tmpCondFollow = m_OutEdges[BTHEN];
01228
01229
01230 if (usType == JumpIntoCase)
01231 followSet.push_back(tmpCondFollow);
01232 }
01233 }
01234
01235
01236 WriteBB(hll, indLevel);
01237
01238
01239 SWITCH_INFO* psi = NULL;
01240 if (cType == Case) {
01241
01242 RTL* last = m_pRtls->back();
01243 CaseStatement* cs = (CaseStatement*)last->getHlStmt();
01244 psi = cs->getSwitchInfo();
01245
01246 hll->AddCaseCondHeader(indLevel, psi->pSwitchVar);
01247 } else {
01248 Exp *cond = getCond();
01249 if (cond == NULL)
01250 cond = new Const(0xfeedface);
01251 if (cType == IfElse) {
01252 cond = new Unary(opNot, cond->clone());
01253 cond = cond->simplify();
01254 }
01255 if (cType == IfThenElse)
01256 hll->AddIfElseCondHeader(indLevel, cond);
01257 else
01258 hll->AddIfCondHeader(indLevel, cond);
01259 }
01260
01261
01262 if (cType != Case) {
01263 PBB succ = (cType == IfElse ? m_OutEdges[BELSE] : m_OutEdges[BTHEN]);
01264
01265
01266
01267 if (succ->traversed == DFS_CODEGEN || (loopHead && succ == loopHead->loopFollow))
01268 emitGotoAndLabel(hll, indLevel + 1, succ);
01269 else
01270 succ->generateCode(hll, indLevel + 1, latch, followSet, gotoSet, proc);
01271
01272
01273 if (cType == IfThenElse) {
01274
01275 hll->AddIfElseCondOption(indLevel);
01276
01277 succ = m_OutEdges[BELSE];
01278
01279
01280
01281 if (succ->traversed == DFS_CODEGEN)
01282 emitGotoAndLabel(hll, indLevel + 1, succ);
01283 else
01284 succ->generateCode(hll, indLevel + 1, latch, followSet, gotoSet, proc);
01285
01286
01287 hll->AddIfElseCondEnd(indLevel);
01288 } else {
01289
01290 hll->AddIfCondEnd(indLevel);
01291 }
01292 } else {
01293
01294
01295
01296 for (unsigned int i = 0; i < m_OutEdges.size(); i++) {
01297
01298
01299 Const caseVal(0);
01300 if (psi->chForm == 'F')
01301 caseVal.setInt(((int*)psi->uTable)[i]);
01302
01303 else
01304 caseVal.setInt((int)(psi->iLower+i));
01305 hll->AddCaseCondOption(indLevel, &caseVal);
01306
01307
01308 PBB succ = m_OutEdges[i];
01309
01310 if (succ->traversed == DFS_CODEGEN)
01311 emitGotoAndLabel(hll, indLevel + 1, succ);
01312 else {
01313 succ->generateCode(hll, indLevel + 1, latch, followSet, gotoSet, proc);
01314 }
01315 }
01316
01317 hll->AddCaseCondEnd(indLevel);
01318 }
01319
01320
01321
01322 if (condFollow) {
01323
01324
01325 if (usType == Structured || usType == JumpIntoCase) {
01326 assert(gotoTotal == 0);
01327 followSet.resize(followSet.size()-1);
01328 } else
01329 for (int i = 0; i < gotoTotal; i++)
01330 gotoSet.resize(gotoSet.size()-1);
01331
01332
01333
01334 if (!tmpCondFollow)
01335 tmpCondFollow = condFollow;
01336
01337 if (tmpCondFollow->traversed == DFS_CODEGEN)
01338 emitGotoAndLabel(hll, indLevel, tmpCondFollow);
01339 else
01340 tmpCondFollow->generateCode(hll, indLevel, latch, followSet, gotoSet, proc);
01341 }
01342 break;
01343 }
01344 case Seq:
01345
01346 WriteBB(hll, indLevel);
01347
01348
01349 if (getType() == RET) {
01350
01351
01352 return;
01353 }
01354
01355
01356 if (m_OutEdges.size() == 0) {
01357 std::cerr << "WARNING: no out edge for this BB in " << proc->getName() << ":\n";
01358 this->print(std::cerr);
01359 std::cerr << std::endl;
01360 if (m_nodeType == COMPJUMP) {
01361 std::ostringstream ost;
01362 assert(m_pRtls->size());
01363 RTL* lastRTL = m_pRtls->back();
01364 assert(lastRTL->getNumStmt());
01365 GotoStatement* gs = (GotoStatement*)lastRTL->elementAt(lastRTL->getNumStmt()-1);
01366 ost << "goto " << gs->getDest();
01367 hll->AddLineComment((char*)ost.str().c_str());
01368 }
01369 return;
01370 }
01371
01372 child = m_OutEdges[0];
01373 if (m_OutEdges.size() != 1) {
01374 PBB other = m_OutEdges[1];
01375 LOG << "found seq with more than one outedge!\n";
01376 if (getDest()->isIntConst() &&
01377 ((Const*)getDest())->getInt() == (int)child->getLowAddr()) {
01378 other = child;
01379 child = m_OutEdges[1];
01380 LOG << "taken branch is first out edge\n";
01381 }
01382
01383 try {
01384 hll->AddIfCondHeader(indLevel, getCond());
01385 if (other->traversed == DFS_CODEGEN)
01386 emitGotoAndLabel(hll, indLevel+1, other);
01387 else
01388 other->generateCode(hll, indLevel+1, latch, followSet, gotoSet, proc);
01389 hll->AddIfCondEnd(indLevel);
01390 } catch (LastStatementNotABranchError &) {
01391 LOG << "last statement is not a cond, don't know what to do with this.\n";
01392 }
01393 }
01394
01395
01396
01397
01398 if (child->traversed == DFS_CODEGEN ||
01399 ((child->loopHead != loopHead) && (!child->allParentsGenerated() ||
01400 isIn(followSet, child))) ||
01401 (latch && latch->loopHead && latch->loopHead->loopFollow == child) ||
01402 !(caseHead == child->caseHead ||
01403 (caseHead && child == caseHead->condFollow)))
01404 emitGotoAndLabel(hll, indLevel, child);
01405 else {
01406 if (caseHead && child == caseHead->condFollow) {
01407
01408 hll->AddCaseCondOptionEnd(indLevel);
01409 } else if (caseHead == NULL || caseHead != child->caseHead || !child->isCaseOption())
01410 child->generateCode(hll, indLevel, latch, followSet, gotoSet, proc);
01411 }
01412 break;
01413 default:
01414 std::cerr << "unhandled sType " << (int)sType << "\n";
01415 }
01416 }
01417
01418
01419
01420 Proc* BasicBlock::getDestProc() {
01421
01422 CallStatement* call = (CallStatement*)(m_pRtls->back()->getHlStmt());
01423 assert(call->getKind() == STMT_CALL);
01424 Proc* proc = call->getDestProc();
01425 if (proc == NULL) {
01426 std::cerr << "Indirect calls not handled yet\n";
01427 assert(0);
01428 }
01429 return proc;
01430 }
01431
01432 void BasicBlock::setLoopStamps(int &time, std::vector<PBB> &order) {
01433
01434
01435 traversed = DFS_LNUM;
01436 loopStamps[0] = time;
01437
01438
01439 for (unsigned int i = 0; i < m_OutEdges.size(); i++) {
01440
01441
01442
01443
01444
01445 if (m_OutEdges[i]->traversed != DFS_LNUM)
01446 m_OutEdges[i]->setLoopStamps(++time, order);
01447 }
01448
01449
01450 loopStamps[1] = ++time;
01451
01452
01453 ord = order.size();
01454 order.push_back(this);
01455 }
01456
01457 void BasicBlock::setRevLoopStamps(int &time)
01458 {
01459
01460 traversed = DFS_RNUM;
01461 revLoopStamps[0] = time;
01462
01463
01464 for (int i = m_OutEdges.size() - 1; i >= 0; i--) {
01465
01466 if (m_OutEdges[i]->traversed != DFS_RNUM)
01467 m_OutEdges[i]->setRevLoopStamps(++time);
01468 }
01469
01470
01471 revLoopStamps[1] = ++time;
01472 }
01473
01474 void BasicBlock::setRevOrder(std::vector<PBB> &order)
01475 {
01476
01477 traversed = DFS_PDOM;
01478
01479
01480 for (unsigned int i = 0; i < m_InEdges.size(); i++)
01481 if (m_InEdges[i]->traversed != DFS_PDOM)
01482 m_InEdges[i]->setRevOrder(order);
01483
01484
01485
01486 revOrd = order.size();
01487 order.push_back(this);
01488 }
01489
01490 void BasicBlock::setCaseHead(PBB head, PBB follow)
01491 {
01492 assert(!caseHead);
01493
01494 traversed = DFS_CASE;
01495
01496
01497 if (this != head)
01498 caseHead = head;
01499
01500
01501
01502 if (getType() == NWAY && this != head) {
01503 if (condFollow && condFollow->traversed != DFS_CASE && condFollow != follow)
01504 condFollow->setCaseHead(head, follow);
01505 } else
01506
01507
01508
01509
01510 for (unsigned int i = 0; i < m_OutEdges.size(); i++)
01511 if (!hasBackEdgeTo(m_OutEdges[i]) &&
01512 m_OutEdges[i]->traversed != DFS_CASE &&
01513 m_OutEdges[i] != follow)
01514 m_OutEdges[i]->setCaseHead(head, follow);
01515 }
01516
01517 void BasicBlock::setStructType(structType s) {
01518
01519
01520 if (s == Cond) {
01521 if (getType() == NWAY)
01522 cType = Case;
01523 else if (m_OutEdges[BELSE] == condFollow)
01524 cType = IfThen;
01525 else if (m_OutEdges[BTHEN] == condFollow)
01526 cType = IfElse;
01527 else
01528 cType = IfThenElse;
01529 }
01530
01531 sType = s;
01532 }
01533
01534 void BasicBlock::setUnstructType(unstructType us) {
01535 assert((sType == Cond || sType == LoopCond) && cType != Case);
01536 usType = us;
01537 }
01538
01539 unstructType BasicBlock::getUnstructType() {
01540 assert((sType == Cond || sType == LoopCond) && cType != Case);
01541 return usType;
01542 }
01543
01544 void BasicBlock::setLoopType(loopType l) {
01545 assert (sType == Loop || sType == LoopCond);
01546 lType = l;
01547
01548
01549
01550 if (lType == PreTested || (lType == PostTested && this == latchNode))
01551 sType = Loop;
01552 }
01553
01554 loopType BasicBlock::getLoopType() {
01555 assert (sType == Loop || sType == LoopCond);
01556 return lType;
01557 }
01558
01559 void BasicBlock::setCondType(condType c) {
01560 assert (sType == Cond || sType == LoopCond);
01561 cType = c;
01562 }
01563
01564 condType BasicBlock::getCondType() {
01565 assert (sType == Cond || sType == LoopCond);
01566 return cType;
01567 }
01568
01569 bool BasicBlock::inLoop(PBB header, PBB latch) {
01570 assert(header->latchNode == latch);
01571 assert(header == latch ||
01572 ((header->loopStamps[0] > latch->loopStamps[0] && latch->loopStamps[1] > header->loopStamps[1]) ||
01573 (header->loopStamps[0] < latch->loopStamps[0] && latch->loopStamps[1] < header->loopStamps[1])));
01574
01575
01576
01577 return this == latch ||
01578 (header->loopStamps[0] < loopStamps[0] && loopStamps[1] < header->loopStamps[1] &&
01579 loopStamps[0] < latch->loopStamps[0] && latch->loopStamps[1] < loopStamps[1]) ||
01580 (header->revLoopStamps[0] < revLoopStamps[0] && revLoopStamps[1] < header->revLoopStamps[1] &&
01581 revLoopStamps[0] < latch->revLoopStamps[0] && latch->revLoopStamps[1] < revLoopStamps[1]);
01582 }
01583
01584
01585
01586 char* BasicBlock::getStmtNumber() {
01587 static char ret[12];
01588 rtlit rit; StatementList::iterator sit;
01589 Statement* first = getFirstStmt(rit, sit);
01590 if (first)
01591 sprintf(ret, "%d", first->getNumber());
01592 else
01593 sprintf(ret, "bb%x", (unsigned)this);
01594 return ret;
01595 }
01596
01597
01598
01599 void BasicBlock::prependStmt(Statement* s, UserProc* proc) {
01600
01601 s->setBB(this);
01602 s->setProc(proc);
01603 if (m_pRtls->size()) {
01604 RTL* rtl = m_pRtls->front();
01605 if (rtl->getAddress() == 0) {
01606
01607 rtl->appendStmt(s);
01608 return;
01609 }
01610 }
01611
01612 std::list<Statement*> listStmt;
01613 listStmt.push_back(s);
01614 RTL* rtl = new RTL(0, &listStmt);
01615 m_pRtls->push_front(rtl);
01616 }
01617
01618
01619
01620
01621
01622
01623 void checkForOverlap(LocationSet& liveLocs, LocationSet& ls, ConnectionGraph& ig, UserProc* proc) {
01624
01625 LocationSet::iterator uu;
01626 for (uu = ls.begin(); uu != ls.end(); uu++) {
01627 Exp* u = (Exp*)*uu;
01628 if (!u->isSubscript()) continue;
01629 RefExp* r = (RefExp*)u;
01630
01631 Exp *dr;
01632 if (liveLocs.findDifferentRef(r, dr)) {
01633
01634 ig.connect(r, dr);
01635 if (VERBOSE || DEBUG_LIVENESS)
01636 LOG << "interference of " << dr << " with " << r << "\n";
01637 }
01638
01639
01640 liveLocs.insert(u);
01641 }
01642 }
01643
01644 bool BasicBlock::calcLiveness(ConnectionGraph& ig, UserProc* myProc) {
01645
01646 LocationSet liveLocs, phiLocs;
01647 getLiveOut(liveLocs, phiLocs);
01648
01649
01650 checkForOverlap(liveLocs, phiLocs, ig, myProc);
01651
01652 std::list<RTL*>::reverse_iterator rit;
01653 if (m_pRtls)
01654 for (rit = m_pRtls->rbegin(); rit != m_pRtls->rend(); rit++) {
01655 std::list<Statement*>& stmts = (*rit)->getList();
01656 std::list<Statement*>::reverse_iterator sit;
01657
01658 for (sit = stmts.rbegin(); sit != stmts.rend(); sit++) {
01659 Statement* s = *sit;
01660 LocationSet defs;
01661 s->getDefinitions(defs);
01662
01663 defs.addSubscript(s );
01664 #if 0 // I used to think it necessary to consider definitions as a special case. However, I now believe that
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675 if (!s->isPhi())
01676 checkForOverlap(liveLocs, defs, ig, myProc, false);
01677 #endif
01678
01679 liveLocs.makeDiff(defs);
01680
01681
01682
01683
01684 if (s->isPhi()) continue;
01685
01686 LocationSet uses;
01687 s->addUsedLocs(uses);
01688 checkForOverlap(liveLocs, uses, ig, myProc);
01689 if (DEBUG_LIVENESS)
01690 LOG << " ## liveness: at top of " << s << ", liveLocs is " << liveLocs.prints() << "\n";
01691 }
01692 }
01693
01694 if (!(liveLocs == liveIn)) {
01695 liveIn = liveLocs;
01696 return true;
01697 } else
01698
01699 return false;
01700 }
01701
01702
01703
01704
01705
01706 void BasicBlock::getLiveOut(LocationSet &liveout, LocationSet& phiLocs) {
01707 liveout.clear();
01708 for (unsigned i = 0; i < m_OutEdges.size(); i++) {
01709 PBB currBB = m_OutEdges[i];
01710
01711 liveout.makeUnion(currBB->liveIn);
01712 int j = currBB->whichPred(this);
01713
01714 if (currBB->m_pRtls == NULL || currBB->m_pRtls->size() == 0)
01715 continue;
01716 RTL* phiRtl = currBB->m_pRtls->front();
01717 std::list<Statement*>& stmts = phiRtl->getList();
01718 std::list<Statement*>::iterator it;
01719 for (it = stmts.begin(); it != stmts.end(); it++) {
01720
01721
01722 if (!(*it)->isPhi()) continue;
01723 PhiAssign* pa = (PhiAssign*)*it;
01724
01725 Statement* def = pa->getStmtAt(j);
01726 RefExp* r = new RefExp(pa->getLeft()->clone(), def);
01727 liveout.insert(r);
01728 phiLocs.insert(r);
01729 if (DEBUG_LIVENESS)
01730 LOG << " ## Liveness: adding " << r << " due to ref to phi " << *it << " in BB at " << getLowAddr() <<
01731 "\n";
01732 }
01733 }
01734 }
01735
01736
01737
01738 int BasicBlock::whichPred(PBB pred) {
01739 int n = m_InEdges.size();
01740 for (int i=0; i < n; i++) {
01741 if (m_InEdges[i] == pred)
01742 return i;
01743 }
01744 assert(0);
01745 return -1;
01746 }
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 static Exp* forma = new RefExp(
01759 new Binary(opArrayIndex,
01760 new RefExp(
01761 new Terminal(opWild),
01762 (Statement*)-1),
01763 new Terminal(opWild)),
01764 (Statement*)-1);
01765
01766
01767 static Exp* formA = Location::memOf(
01768 new Binary(opPlus,
01769 new Binary(opMult,
01770 new Terminal(opWild),
01771 new Const(4)),
01772 new Terminal(opWildIntConst)));
01773
01774
01775
01776
01777 static Exp* formo = new RefExp(
01778 new Binary(opArrayIndex,
01779 new RefExp(
01780 new Terminal(opWild),
01781 (Statement*)-1),
01782 new Terminal(opWild)),
01783 (Statement*)-1);
01784
01785
01786 static Exp* formO = new Binary(opPlus,
01787 Location::memOf(
01788 new Binary(opPlus,
01789 new Binary(opMult,
01790 new Terminal(opWild),
01791 new Const(4)),
01792 new Terminal(opWildIntConst))),
01793 new Terminal(opWildIntConst));
01794
01795
01796
01797 static Exp* formR = new Binary(opPlus,
01798 new Terminal(opPC),
01799 Location::memOf(new Binary(opPlus,
01800 new Terminal(opPC),
01801 new Binary(opPlus,
01802 new Binary(opMult,
01803 new Terminal(opWild),
01804 new Const(4)),
01805 new Const(opWildIntConst)))));
01806
01807
01808
01809 static Exp* formr = new Binary(opPlus,
01810 new Terminal(opPC),
01811 Location::memOf(new Binary(opPlus,
01812 new Terminal(opPC),
01813 new Binary(opMinus,
01814 new Binary(opMult,
01815 new Terminal(opWild),
01816 new Const(4)),
01817 new Terminal(opWildIntConst)))));
01818
01819 static Exp* hlForms[] = {forma, formA, formo, formO, formR, formr};
01820 static char chForms[] = { 'a', 'A', 'o', 'O', 'R', 'r'};
01821
01822 void init_basicblock() {
01823 #ifndef NO_GARBAGE_COLLECTOR
01824 Exp** gc_pointers = (Exp**) GC_MALLOC_UNCOLLECTABLE(6 * sizeof(Exp*));
01825 gc_pointers[0] = forma;
01826 gc_pointers[1] = formA;
01827 gc_pointers[2] = formo;
01828 gc_pointers[3] = formO;
01829 gc_pointers[4] = formR;
01830 gc_pointers[5] = formr;
01831 #endif
01832 }
01833
01834
01835
01836 static Binary* vfc_funcptr = new Binary(opArrayIndex,
01837 new Location(opGlobal,
01838 new Terminal(opWildStrConst), NULL),
01839 new Const(0));
01840
01841
01842
01843 static Location* vfc_both = Location::memOf(
01844 new Binary(opPlus,
01845 Location::memOf(
01846 new Binary(opPlus,
01847 new Terminal(opWild),
01848 new Terminal(opWildIntConst))),
01849 new Terminal(opWildIntConst)));
01850
01851
01852 static Location* vfc_vto = Location::memOf(
01853 new Binary(opPlus,
01854 Location::memOf(
01855 new Terminal(opWild)),
01856 new Terminal(opWildIntConst)));
01857
01858
01859 Location* vfc_vfo = Location::memOf(
01860 Location::memOf(
01861 new Binary(opPlus,
01862 new Terminal(opWild),
01863 new Terminal(opWildIntConst))));
01864
01865
01866 Location* vfc_none = Location::memOf(
01867 Location::memOf(
01868 new Terminal(opWild)));
01869
01870 static Exp* hlVfc[] = {vfc_funcptr, vfc_both, vfc_vto, vfc_vfo, vfc_none};
01871
01872 void findSwParams(char form, Exp* e, Exp*& expr, ADDRESS& T) {
01873 switch (form) {
01874 case 'a': {
01875
01876 e = ((RefExp*)e)->getSubExp1();
01877 Exp* base = ((Binary*)e)->getSubExp1();
01878 if (base->isSubscript())
01879 base = ((RefExp*)base)->getSubExp1();
01880 Exp* con = ((Location*)base)->getSubExp1();
01881 char* gloName = ((Const*)con)->getStr();
01882 UserProc* p = ((Location*)base)->getProc();
01883 Prog* prog = p->getProg();
01884 T = (ADDRESS)prog->getGlobalAddr(gloName);
01885 expr = ((Binary*)e)->getSubExp2();
01886 break;
01887 }
01888 case 'A': {
01889
01890 if (e->isSubscript()) e = e->getSubExp1();
01891
01892 Binary* b = (Binary*)((Location*)e)->getSubExp1();
01893 Const* TT = (Const*)b->getSubExp2();
01894 T = (ADDRESS)TT->getInt();
01895 b = (Binary*)b->getSubExp1();
01896 expr = b->getSubExp1();
01897 break;
01898 }
01899 case 'O': {
01900
01901 T = ((Const*)((Binary*)e)->getSubExp2())->getInt();
01902
01903 Exp* l = ((Binary*)e)->getSubExp1();
01904 if (l->isSubscript()) l = l->getSubExp1();
01905
01906 Binary* b = (Binary*)((Location*)l)->getSubExp1();
01907
01908 b = (Binary*)b->getSubExp1();
01909
01910 expr = b->getSubExp1();
01911 break;
01912 }
01913 case 'R': {
01914
01915 T = 0;
01916
01917 Exp* l = ((Binary*)e)->getSubExp2();
01918 if (l->isSubscript()) l = l->getSubExp1();
01919
01920 Binary* b = (Binary*)((Location*)l)->getSubExp1();
01921
01922 b = (Binary*)b->getSubExp2();
01923
01924 b = (Binary*)b->getSubExp1();
01925
01926 expr = b->getSubExp1();
01927 break;
01928 }
01929 case 'r': {
01930
01931 T = 0;
01932
01933 Binary* b = (Binary*)((Binary*)e)->getSubExp1();
01934
01935 Exp* l = b->getSubExp2();
01936 if (l->isSubscript()) l = l->getSubExp1();
01937
01938 b = (Binary*)((Location*)l)->getSubExp1();
01939
01940 b = (Binary*)b->getSubExp2();
01941
01942 b = (Binary*)b->getSubExp1();
01943
01944 expr = b->getSubExp1();
01945 break;
01946 }
01947 default:
01948 expr = NULL;
01949 T = NO_ADDRESS;
01950 }
01951 }
01952
01953
01954
01955
01956
01957
01958
01959
01960 int BasicBlock::findNumCases() {
01961 std::vector<PBB>::iterator it;
01962 for (it = m_InEdges.begin(); it != m_InEdges.end(); it++) {
01963 if ((*it)->m_nodeType != TWOWAY)
01964 continue;
01965 assert((*it)->m_pRtls->size());
01966 RTL* lastRtl = (*it)->m_pRtls->back();
01967 assert(lastRtl->getNumStmt() >= 1);
01968 BranchStatement* lastStmt = (BranchStatement*)lastRtl->elementAt(lastRtl->getNumStmt()-1);
01969 Exp* pCond = lastStmt->getCondExpr();
01970 if (pCond->getArity() != 2) continue;
01971 Exp* rhs = ((Binary*)pCond)->getSubExp2();
01972 if (!rhs->isIntConst()) continue;
01973 int k = ((Const*)rhs)->getInt();
01974 OPER op = pCond->getOper();
01975 if (op == opGtr || op == opGtrUns)
01976 return k+1;
01977 if (op == opGtrEq || op == opGtrEqUns)
01978 return k;
01979 if (op == opLess || op == opLessUns)
01980 return k;
01981 if (op == opLessEq || op == opLessEqUns)
01982 return k+1;
01983 }
01984 LOG << "Could not find number of cases for n-way at address " << getLowAddr() << "\n";
01985 return 3;
01986 }
01987
01988
01989 void findConstantValues(Statement* s, std::list<int>& dests) {
01990 if (s == NULL) return;
01991 if (s->isPhi()) {
01992
01993 PhiAssign::Definitions::iterator it;
01994 for (it = ((PhiAssign*)s)->begin(); it != ((PhiAssign*)s)->end(); it++)
01995 findConstantValues(it->def, dests);
01996 }
01997 else if (s->isAssign()) {
01998 Exp* rhs = ((Assign*)s)->getRight();
01999 if (rhs->isIntConst())
02000 dests.push_back(((Const*)rhs)->getInt());
02001 }
02002 }
02003
02004
02005 bool BasicBlock::decodeIndirectJmp(UserProc* proc) {
02006 #define CHECK_REAL_PHI_LOOPS 0
02007 #if CHECK_REAL_PHI_LOOPS
02008 rtlit rit; StatementList::iterator sit;
02009 Statement* s = getFirstStmt(rit, sit);
02010 for (s=getFirstStmt(rit, sit); s; s = getNextStmt(rit, sit)) {
02011 if (!s->isPhi()) continue;
02012 Statement* originalPhi = s;
02013 StatementSet workSet, seenSet;
02014 workSet.insert(s);
02015 seenSet.insert(s);
02016 do {
02017 PhiAssign* pi = (PhiAssign*)*workSet.begin();
02018 workSet.remove(pi);
02019 PhiAssign::Definitions::iterator it;
02020 for (it = pi->begin(); it != pi->end(); it++) {
02021 if (it->def == NULL) continue;
02022 if (!it->def->isPhi()) continue;
02023 if (seenSet.exists(it->def)) {
02024 std::cerr << "Real phi loop involving statements " << originalPhi->getNumber() << " and " <<
02025 pi->getNumber() << "\n";
02026 break;
02027 } else {
02028 workSet.insert(it->def);
02029 seenSet.insert(it->def);
02030 }
02031 }
02032 } while (workSet.size());
02033 }
02034 #endif
02035
02036 if (m_nodeType == COMPJUMP) {
02037 assert(m_pRtls->size());
02038 RTL* lastRtl = m_pRtls->back();
02039 if (DEBUG_SWITCH)
02040 LOG << "decodeIndirectJmp: " << lastRtl->prints();
02041 assert(lastRtl->getNumStmt() >= 1);
02042 CaseStatement* lastStmt = (CaseStatement*)lastRtl->elementAt(lastRtl->getNumStmt()-1);
02043
02044
02045
02046
02047 bool convert;
02048 lastStmt->propagateTo(convert, NULL, NULL, true );
02049 Exp* e = lastStmt->getDest();
02050 int n = sizeof(hlForms) / sizeof(Exp*);
02051 char form = 0;
02052 for (int i=0; i < n; i++) {
02053 if (*e *= *hlForms[i]) {
02054 form = chForms[i];
02055 if (DEBUG_SWITCH)
02056 LOG << "indirect jump matches form " << form << "\n";
02057 break;
02058 }
02059 }
02060 if (form) {
02061 SWITCH_INFO* swi = new SWITCH_INFO;
02062 swi->chForm = form;
02063 ADDRESS T;
02064 Exp* expr;
02065 findSwParams(form, e, expr, T);
02066 if (expr) {
02067 swi->uTable = T;
02068 swi->iNumTable = findNumCases();
02069 #if 1 // TMN: Added actual control of the array members, to possibly truncate what findNumCases()
02070
02071 if (form == 'A') {
02072 Prog* prog = proc->getProg();
02073 for (int iPtr = 0; iPtr < swi->iNumTable; ++iPtr) {
02074 ADDRESS uSwitch = prog->readNative4(swi->uTable + iPtr*4);
02075 if (uSwitch >= prog->getLimitTextHigh() ||
02076 uSwitch < prog->getLimitTextLow())
02077 {
02078 if (DEBUG_SWITCH)
02079 LOG << "Truncating type A indirect jump array to " << iPtr << " entries "
02080 "due to finding an array entry pointing outside valid code\n";
02081
02082 swi->iNumTable = iPtr;
02083 break;
02084 }
02085 }
02086 }
02087 assert(swi->iNumTable > 0);
02088 #endif
02089 swi->iUpper = swi->iNumTable-1;
02090 if (expr->getOper() == opMinus && ((Binary*)expr)->getSubExp2()->isIntConst()) {
02091 swi->iLower = ((Const*)((Binary*)expr)->getSubExp2())->getInt();
02092 swi->iUpper += swi->iLower;
02093 expr = ((Binary*)expr)->getSubExp1();
02094 } else
02095 swi->iLower = 0;
02096 swi->pSwitchVar = expr;
02097 lastStmt->setDest((Exp*)NULL);
02098 lastStmt->setSwitchInfo(swi);
02099 return swi->iNumTable != 0;
02100 }
02101 } else {
02102
02103
02104 if (e->isSubscript()) {
02105 Exp* sub = ((RefExp*)e)->getSubExp1();
02106 if (sub->isLocation()) {
02107
02108
02109 std::list<int> dests;
02110 findConstantValues(((RefExp*)e)->getDef(), dests);
02111
02112 int n = dests.size();
02113 if (n) {
02114 int* destArray = new int[n];
02115 std::list<int>::iterator ii = dests.begin();
02116 for (int i=0; i < n; i++)
02117 destArray[i] = *ii++;
02118 SWITCH_INFO* swi = new SWITCH_INFO;
02119 swi->chForm = 'F';
02120 swi->pSwitchVar = e;
02121 swi->uTable = (ADDRESS)destArray;
02122 swi->iNumTable = n;
02123 swi->iLower = 1;
02124 swi->iUpper = n;
02125 lastStmt->setDest((Exp*)NULL);
02126 lastStmt->setSwitchInfo(swi);
02127 return true;
02128 }
02129 }
02130 }
02131 }
02132 return false;
02133 } else if (m_nodeType == COMPCALL) {
02134 assert(m_pRtls->size());
02135 RTL* lastRtl = m_pRtls->back();
02136 if (DEBUG_SWITCH)
02137 LOG << "decodeIndirectJmp: COMPCALL:\n" << lastRtl->prints() << "\n";
02138 assert(lastRtl->getNumStmt() >= 1);
02139 CallStatement* lastStmt = (CallStatement*)lastRtl->elementAt(lastRtl->getNumStmt()-1);
02140 Exp* e = lastStmt->getDest();
02141
02142
02143
02144 e = e->propagateAll();
02145
02146 ConstGlobalConverter cgc(proc->getProg());
02147 e = e->accept(&cgc);
02148
02149
02150
02151
02152 e = e->simplify();
02153 if (DEBUG_SWITCH)
02154 LOG << "decodeIndirect: propagated and const global converted call expression is " << e << "\n";
02155
02156 int n = sizeof(hlVfc) / sizeof(Exp*);
02157 bool recognised = false;
02158 int i;
02159 for (i=0; i < n; i++) {
02160 if (*e *= *hlVfc[i]) {
02161 recognised = true;
02162 if (DEBUG_SWITCH)
02163 LOG << "indirect call matches form " << i << "\n";
02164 break;
02165 }
02166 }
02167 if (!recognised) return false;
02168 lastStmt->setDest(e);
02169 int K1, K2;
02170 Exp *vtExp, *t1;
02171 Prog* prog = proc->getProg();
02172 switch (i) {
02173 case 0: {
02174
02175
02176
02177 K2 = 0;
02178 if (e->isSubscript()) e = e->getSubExp1();
02179 e = ((Binary*)e)->getSubExp1();
02180 if (e->isArrayIndex() &&
02181 (t1 = ((Binary*)e)->getSubExp2(), t1->isIntConst()) &&
02182 ((Const*)t1)->getInt() == 0)
02183 e = ((Binary*)e)->getSubExp1();
02184 if (e->isSubscript()) e = e->getSubExp1();
02185 Const* con = (Const*)((Location*)e)->getSubExp1();
02186 Global* glo = prog->getGlobal(con->getStr());
02187 assert(glo);
02188
02189 Type* ty = glo->getType();
02190 if (!ty->isPointer() && !((PointerType*)ty)->getPointsTo()->isFunc())
02191 glo->setType(new PointerType(new FuncType()));
02192 ADDRESS addr = glo->getAddress();
02193
02194
02195
02196 K1 = 0;
02197 vtExp = new Const(addr);
02198 break;
02199 }
02200 case 1: {
02201
02202 if (e->isSubscript())
02203 e = ((RefExp*)e)->getSubExp1();
02204 e = ((Location*)e)->getSubExp1();
02205 Exp* rhs = ((Binary*)e)->getSubExp2();
02206 K2 = ((Const*)rhs)->getInt();
02207 Exp* lhs = ((Binary*)e)->getSubExp1();
02208 if (lhs->isSubscript())
02209 lhs = ((RefExp*)lhs)->getSubExp1();
02210 vtExp = lhs;
02211 lhs = ((Unary*)lhs)->getSubExp1();
02212
02213 Exp* CK1 = ((Binary*)lhs)->getSubExp2();
02214 K1 = ((Const*)CK1)->getInt();
02215 break;
02216 }
02217 case 2: {
02218
02219 if (e->isSubscript())
02220 e = ((RefExp*)e)->getSubExp1();
02221 e = ((Location*)e)->getSubExp1();
02222 Exp* rhs = ((Binary*)e)->getSubExp2();
02223 K2 = ((Const*)rhs)->getInt();
02224 Exp* lhs = ((Binary*)e)->getSubExp1();
02225 if (lhs->isSubscript())
02226 lhs = ((RefExp*)lhs)->getSubExp1();
02227 vtExp = lhs;
02228 K1 = 0;
02229 break;
02230 }
02231 case 3: {
02232
02233 if (e->isSubscript())
02234 e = ((RefExp*)e)->getSubExp1();
02235 e = ((Location*)e)->getSubExp1();
02236 K2 = 0;
02237 if (e->isSubscript())
02238 e = ((RefExp*)e)->getSubExp1();
02239 vtExp = e;
02240 Exp* lhs = ((Unary*)e)->getSubExp1();
02241
02242 Exp* CK1 = ((Binary*)lhs)->getSubExp2();
02243 K1 = ((Const*)CK1)->getInt();
02244 break;
02245 }
02246 case 4: {
02247
02248 if (e->isSubscript())
02249 e = ((RefExp*)e)->getSubExp1();
02250 e = ((Location*)e)->getSubExp1();
02251 K2 = 0;
02252 if (e->isSubscript())
02253 e = ((RefExp*)e)->getSubExp1();
02254 vtExp = e;
02255 K1 = 0;
02256
02257 break;
02258 }
02259 default:
02260 K1 = K2 = -1;
02261 vtExp = (Exp*)-1;
02262 }
02263 if (DEBUG_SWITCH)
02264 LOG << "form " << i << ": from statement " << lastStmt->getNumber() << " get e = " << lastStmt->getDest() <<
02265 ", K1 = " << K1 << ", K2 = " << K2 << ", vtExp = " << vtExp << "\n";
02266
02267
02268
02269 vtExp = lastStmt->findDefFor(vtExp);
02270 if (vtExp && DEBUG_SWITCH)
02271 LOG << "VT expression boils down to this: " << vtExp << "\n";
02272
02273
02274 bool decodeThru = Boomerang::get()->decodeThruIndCall;
02275 if (decodeThru && vtExp && vtExp->isIntConst()) {
02276 int addr = ((Const*)vtExp)->getInt();
02277 ADDRESS pfunc = prog->readNative4(addr);
02278 if (prog->findProc(pfunc) == NULL) {
02279
02280 if (Boomerang::get()->noDecodeChildren)
02281 return false;
02282 prog->decodeEntryPoint(pfunc);
02283
02284
02285 return true;
02286 }
02287 }
02288 }
02289 return false;
02290 }
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302 void BasicBlock::processSwitch(UserProc* proc) {
02303
02304 RTL* last = m_pRtls->back();
02305 CaseStatement* lastStmt = (CaseStatement*)last->getHlStmt();
02306 SWITCH_INFO* si = lastStmt->getSwitchInfo();
02307
02308 if (Boomerang::get()->debugSwitch) {
02309 LOG << "processing switch statement type " << si->chForm << " with table at 0x" << si->uTable << ", ";
02310 if (si->iNumTable)
02311 LOG << si->iNumTable << " entries, ";
02312 LOG << "lo= " << si->iLower << ", hi= " << si->iUpper << "\n";
02313 }
02314 ADDRESS uSwitch;
02315 int iNumOut, iNum;
02316 iNumOut = si->iUpper-si->iLower+1;
02317 iNum = iNumOut;
02318
02319 updateType(NWAY, iNumOut);
02320
02321 Prog* prog = proc->getProg();
02322 Cfg* cfg = proc->getCFG();
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334 std::list<ADDRESS> dests;
02335 for (int i=0; i < iNum; i++) {
02336
02337 if (si->chForm == 'H') {
02338 int iValue = prog->readNative4(si->uTable + i*2);
02339 if (iValue == -1) continue;
02340 uSwitch =prog->readNative4(si->uTable + i*8 + 4);
02341 }
02342 else if (si->chForm == 'F')
02343 uSwitch = ((int*)si->uTable)[i];
02344 else
02345 uSwitch = prog->readNative4(si->uTable + i*4);
02346 if ((si->chForm == 'O') || (si->chForm == 'R') || (si->chForm == 'r'))
02347
02348
02349 uSwitch += si->uTable - si->iOffset;
02350 if (uSwitch < prog->getLimitTextHigh()) {
02351
02352 cfg->addOutEdge(this, uSwitch, true);
02353
02354
02355
02356 dests.push_back(uSwitch);
02357 } else {
02358 LOG << "switch table entry branches to past end of text section " << uSwitch << "\n";
02359 #if 1 // TMN: If we reached an array entry pointing outside the program text, we can be quite confident the array
02360
02361 LOG << "Assuming the end of the pointer-array has been reached at index " << i << "\n";
02362
02363
02364
02365 assert(m_iNumOutEdges >= (iNum - i));
02366
02367 m_iNumOutEdges -= (iNum - i);
02368 break;
02369 #else
02370 iNumOut--;
02371 m_iNumOutEdges--;
02372 #endif
02373 }
02374 }
02375
02376 std::list<ADDRESS>::iterator dd;
02377 int count = 0;
02378 for (dd = dests.begin(); dd != dests.end(); ++dd) {
02379 char tmp[1024];
02380 count++;
02381 sprintf(tmp, "before decoding fragment %i of %i (%x)", count, dests.size(), *dd);
02382 Boomerang::get()->alert_decompile_debug_point(proc, tmp);
02383 prog->decodeFragment(proc, *dd);
02384 }
02385 }
02386
02387
02388 bool BasicBlock::undoComputedBB(Statement* stmt) {
02389 RTL* last = m_pRtls->back();
02390 std::list<Statement*>& list = last->getList();
02391 std::list<Statement*>::reverse_iterator rr;
02392 for (rr = list.rbegin(); rr != list.rend(); rr++) {
02393 if (*rr == stmt) {
02394 m_nodeType = CALL;
02395 LOG << "undoComputedBB for statement " << stmt << "\n";
02396 return true;
02397 }
02398 }
02399 return false;
02400 }
02401