00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #define HELLO_PENTIUM "test/pentium/hello"
00015 #define GLOBAL1_PENTIUM "test/pentium/global1"
00016
00017 #include "StatementTest.h"
00018 #include "cfg.h"
00019 #include "rtl.h"
00020 #include "pentiumfrontend.h"
00021 #include "boomerang.h"
00022 #include "exp.h"
00023 #include "managed.h"
00024 #include "log.h"
00025 #include "signature.h"
00026
00027 #include <sstream>
00028 #include <map>
00029
00030 class NullLogger : public Log {
00031 public:
00032 virtual Log &operator<<(const char *str) {
00033
00034 return *this;
00035 }
00036 virtual ~NullLogger() {};
00037 };
00038
00039
00040
00041
00042
00043
00044 #define MYTEST(name) \
00045 suite->addTest(new CppUnit::TestCaller<StatementTest> ("Statements", \
00046 &StatementTest::name, *this))
00047
00048 void StatementTest::registerTests(CppUnit::TestSuite* suite) {
00049
00050 MYTEST(testLocationSet);
00051 MYTEST(testWildLocationSet);
00052 MYTEST(testEmpty);
00053 MYTEST(testFlow);
00054 MYTEST(testKill);
00055 MYTEST(testUse);
00056 MYTEST(testUseOverKill);
00057 MYTEST(testUseOverBB);
00058 MYTEST(testUseKill);
00059
00060
00061
00062 MYTEST(testClone);
00063 MYTEST(testIsAssign);
00064 MYTEST(testIsFlagAssgn);
00065 MYTEST(testAddUsedLocsAssign);
00066 MYTEST(testAddUsedLocsBranch);
00067 MYTEST(testAddUsedLocsCase);
00068 MYTEST(testAddUsedLocsCall);
00069 MYTEST(testAddUsedLocsReturn);
00070 MYTEST(testAddUsedLocsBool);
00071 MYTEST(testSubscriptVars);
00072 MYTEST(testBypass);
00073 MYTEST(testStripSizes);
00074 MYTEST(testFindConstants);
00075 }
00076
00077 int StatementTest::countTestCases () const
00078 { return 2; }
00079
00080
00081
00082
00083
00084
00085
00086
00087 static bool logset = false;
00088 void StatementTest::setUp () {
00089 if (!logset) {
00090 logset = true;
00091 Boomerang::get()->setLogger(new NullLogger());
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102 void StatementTest::tearDown () {
00103 }
00104
00105
00106
00107
00108
00109 void StatementTest::testEmpty () {
00110
00111 Boomerang* boo = Boomerang::get();
00112 boo->vFlag = true;
00113 boo->setOutputDirectory("./unit_test/");
00114 boo->setLogger(new FileLogger());
00115
00116
00117 Prog* prog = new Prog;
00118 BinaryFileFactory bff;
00119 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00120 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00121 prog->setFrontEnd(pFE);
00122
00123
00124 std::string name = "test";
00125 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00126
00127 Cfg *cfg = proc->getCFG();
00128 std::list<RTL*>* pRtls = new std::list<RTL*>();
00129 std::list<Statement*>* ls = new std::list<Statement*>;
00130 ls->push_back(new ReturnStatement);
00131 pRtls->push_back(new RTL(0x123));
00132 PBB bb = cfg->newBB(pRtls, RET, 0);
00133 cfg->setEntryBB(bb);
00134 proc->setDecoded();
00135
00136 int indent = 0;
00137 proc->decompile(new ProcList, indent);
00138
00139 std::ostringstream st;
00140 cfg->print(st);
00141 std::string s = st.str();
00142
00143 std::string expected =
00144 "Ret BB:\n"
00145 "00000123\n\n";
00146 CPPUNIT_ASSERT_EQUAL(expected, s);
00147
00148 delete prog;
00149 }
00150
00151
00152
00153
00154
00155 void StatementTest::testFlow () {
00156
00157 Prog* prog = new Prog;
00158 BinaryFileFactory bff;
00159 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00160 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00161
00162 prog->setFrontEnd(pFE);
00163
00164
00165 std::string name = "test";
00166 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00167
00168 Cfg *cfg = proc->getCFG();
00169 std::list<RTL*>* pRtls = new std::list<RTL*>();
00170 RTL *rtl = new RTL();
00171 Assign *a = new Assign(Location::regOf(24), new Const(5));
00172 a->setProc(proc);
00173 a->setNumber(1);
00174 rtl->appendStmt(a);
00175 pRtls->push_back(rtl);
00176 PBB first = cfg->newBB(pRtls, FALL, 1);
00177 pRtls = new std::list<RTL*>();
00178 rtl = new RTL(0x123);
00179 ReturnStatement* rs = new ReturnStatement;
00180 rs->setNumber(2);
00181 rs->addReturn(new Assign(Location::regOf(24), new Const(5)));
00182 rtl->appendStmt(rs);
00183 pRtls->push_back(rtl);
00184 PBB ret = cfg->newBB(pRtls, RET, 0);
00185 first->setOutEdge(0, ret);
00186 ret->addInEdge(first);
00187 cfg->setEntryBB(first);
00188 proc->setDecoded();
00189
00190 int indent = 0;
00191 proc->decompile(new ProcList, indent);
00192
00193 std::ostringstream st;
00194 cfg->print(st);
00195 std::string s = st.str();
00196
00197 std::string expected;
00198
00199
00200 expected =
00201 "Fall BB:\n"
00202 "00000000\n"
00203 "Ret BB:\n"
00204 "00000123 2 RET *v* r24 := 5\n"
00205 " Modifieds: \n"
00206 " Reaching definitions: r24=5\n\n";
00207
00208 CPPUNIT_ASSERT_EQUAL(expected, s);
00209
00210 delete prog;
00211 }
00212
00213
00214
00215
00216
00217 void StatementTest::testKill () {
00218
00219 Prog* prog = new Prog;
00220 BinaryFileFactory bff;
00221 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00222 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00223
00224 prog->setFrontEnd(pFE);
00225
00226 std::string name = "test";
00227 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00228
00229 Cfg *cfg = proc->getCFG();
00230 std::list<RTL*>* pRtls = new std::list<RTL*>();
00231 RTL *rtl = new RTL();
00232 Assign *e = new Assign(Location::regOf(24),
00233 new Const(5));
00234 e->setNumber(1);
00235 e->setProc(proc);
00236 rtl->appendStmt(e);
00237 e = new Assign(Location::regOf(24),
00238 new Const(6));
00239 e->setNumber(2);
00240 e->setProc(proc);
00241 rtl->appendStmt(e);
00242 pRtls->push_back(rtl);
00243 PBB first = cfg->newBB(pRtls, FALL, 1);
00244 pRtls = new std::list<RTL*>();
00245 rtl = new RTL(0x123);
00246 ReturnStatement* rs = new ReturnStatement;
00247 rs->setNumber(3);
00248 rs->addReturn(new Assign(Location::regOf(24), new Const(0)));
00249 rtl->appendStmt(rs);
00250 pRtls->push_back(rtl);
00251 PBB ret = cfg->newBB(pRtls, RET, 0);
00252 first->setOutEdge(0, ret);
00253 ret->addInEdge(first);
00254 cfg->setEntryBB(first);
00255 proc->setDecoded();
00256
00257 int indent = 0;
00258 proc->decompile(new ProcList, indent);
00259
00260 std::ostringstream st;
00261 cfg->print(st);
00262 std::string s = st.str();
00263
00264 std::string expected;
00265 expected =
00266 "Fall BB:\n"
00267 "00000000\n"
00268 "Ret BB:\n"
00269 "00000123 3 RET *v* r24 := 0\n"
00270 " Modifieds: \n"
00271 " Reaching definitions: r24=6\n\n";
00272
00273 CPPUNIT_ASSERT_EQUAL(expected, s);
00274
00275 delete prog;
00276 }
00277
00278
00279
00280
00281
00282 void StatementTest::testUse () {
00283
00284 Prog* prog = new Prog;
00285 BinaryFileFactory bff;
00286 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00287 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00288
00289 prog->setFrontEnd(pFE);
00290
00291 std::string name = "test";
00292 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00293
00294 Cfg *cfg = proc->getCFG();
00295 std::list<RTL*>* pRtls = new std::list<RTL*>();
00296 RTL *rtl = new RTL();
00297 Assign *a = new Assign(Location::regOf(24), new Const(5));
00298 a->setNumber(1);
00299 a->setProc(proc);
00300 rtl->appendStmt(a);
00301 a = new Assign(Location::regOf(28), Location::regOf(24));
00302 a->setNumber(2);
00303 a->setProc(proc);
00304 rtl->appendStmt(a);
00305 pRtls->push_back(rtl);
00306 PBB first = cfg->newBB(pRtls, FALL, 1);
00307 pRtls = new std::list<RTL*>();
00308 rtl = new RTL(0x123);
00309 ReturnStatement* rs = new ReturnStatement;
00310 rs->setNumber(3);
00311 rs->addReturn(new Assign(Location::regOf(28), new Const(1000)));
00312 rtl->appendStmt(rs);
00313 pRtls->push_back(rtl);
00314 PBB ret = cfg->newBB(pRtls, RET, 0);
00315 first->setOutEdge(0, ret);
00316 ret->addInEdge(first);
00317 cfg->setEntryBB(first);
00318 proc->setDecoded();
00319
00320 int indent = 0;
00321 proc->decompile(new ProcList, indent);
00322
00323 std::ostringstream st;
00324 cfg->print(st);
00325 std::string s = st.str();
00326
00327 std::string expected;
00328 expected =
00329 "Fall BB:\n"
00330 "00000000\n"
00331 "Ret BB:\n"
00332 "00000123 3 RET *v* r28 := 1000\n"
00333 " Modifieds: \n"
00334 " Reaching definitions: r24=5, r28=5\n\n";
00335
00336 CPPUNIT_ASSERT_EQUAL(expected, s);
00337
00338 delete prog;
00339 }
00340
00341
00342
00343
00344
00345 void StatementTest::testUseOverKill () {
00346
00347 Prog* prog = new Prog;
00348 BinaryFileFactory bff;
00349 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00350 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00351
00352 prog->setFrontEnd(pFE);
00353
00354 std::string name = "test";
00355 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00356
00357 Cfg *cfg = proc->getCFG();
00358 std::list<RTL*>* pRtls = new std::list<RTL*>();
00359 RTL *rtl = new RTL();
00360 Assign *e = new Assign(Location::regOf(24), new Const(5));
00361 e->setNumber(1);
00362 e->setProc(proc);
00363 rtl->appendStmt(e);
00364 e = new Assign(Location::regOf(24), new Const(6));
00365 e->setNumber(2);
00366 e->setProc(proc);
00367 rtl->appendStmt(e);
00368 e = new Assign(Location::regOf(28), Location::regOf(24));
00369 e->setNumber(3);
00370 e->setProc(proc);
00371 rtl->appendStmt(e);
00372 pRtls->push_back(rtl);
00373 PBB first = cfg->newBB(pRtls, FALL, 1);
00374 pRtls = new std::list<RTL*>();
00375 rtl = new RTL(0x123);
00376 ReturnStatement* rs = new ReturnStatement;
00377 rs->setNumber(4);
00378 rs->addReturn(new Assign(Location::regOf(24), new Const(0)));
00379 rtl->appendStmt(rs);
00380 pRtls->push_back(rtl);
00381 PBB ret = cfg->newBB(pRtls, RET, 0);
00382 first->setOutEdge(0, ret);
00383 ret->addInEdge(first);
00384 cfg->setEntryBB(first);
00385 proc->setDecoded();
00386
00387 int indent = 0;
00388 proc->decompile(new ProcList, indent);
00389
00390 std::ostringstream st;
00391 cfg->print(st);
00392 std::string s = st.str();
00393
00394 std::string expected;
00395 expected =
00396 "Fall BB:\n"
00397 "00000000\n"
00398 "Ret BB:\n"
00399 "00000123 4 RET *v* r24 := 0\n"
00400 " Modifieds: \n"
00401 " Reaching definitions: r24=6, r28=6\n\n";
00402
00403 CPPUNIT_ASSERT_EQUAL(expected, s);
00404
00405 delete prog;
00406 }
00407
00408
00409
00410
00411
00412 void StatementTest::testUseOverBB () {
00413
00414 Prog* prog = new Prog;
00415 BinaryFileFactory bff;
00416 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00417 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00418
00419 prog->setFrontEnd(pFE);
00420
00421 std::string name = "test";
00422 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00423
00424 Cfg *cfg = proc->getCFG();
00425 std::list<RTL*>* pRtls = new std::list<RTL*>();
00426 RTL *rtl = new RTL();
00427 Assign *a = new Assign(Location::regOf(24),
00428 new Const(5));
00429 a->setNumber(1);
00430 a->setProc(proc);
00431 rtl->appendStmt(a);
00432 a = new Assign(Location::regOf(24), new Const(6));
00433 a->setNumber(2);
00434 a->setProc(proc);
00435 rtl->appendStmt(a);
00436 pRtls->push_back(rtl);
00437 PBB first = cfg->newBB(pRtls, FALL, 1);
00438 pRtls = new std::list<RTL*>();
00439 rtl = new RTL();
00440 a = new Assign(Location::regOf(28), Location::regOf(24));
00441 a->setNumber(3);
00442 a->setProc(proc);
00443 rtl->appendStmt(a);
00444 pRtls->push_back(rtl);
00445 rtl = new RTL(0x123);
00446 ReturnStatement* rs = new ReturnStatement;
00447 rs->setNumber(4);
00448 rs->addReturn(new Assign(Location::regOf(24), new Const(0)));
00449 rtl->appendStmt(rs);
00450 pRtls->push_back(rtl);
00451 PBB ret = cfg->newBB(pRtls, RET, 0);
00452 first->setOutEdge(0, ret);
00453 ret->addInEdge(first);
00454 cfg->setEntryBB(first);
00455 proc->setDecoded();
00456
00457 int indent = 0;
00458 proc->decompile(new ProcList, indent);
00459
00460 std::ostringstream st;
00461 cfg->print(st);
00462 std::string s = st.str();
00463
00464 std::string expected;
00465 expected =
00466 "Fall BB:\n"
00467 "00000000\n"
00468 "Ret BB:\n"
00469 "00000000\n"
00470 "00000123 4 RET *v* r24 := 0\n"
00471 " Modifieds: \n"
00472 " Reaching definitions: r24=6, r28=6\n\n";
00473
00474 CPPUNIT_ASSERT_EQUAL(expected, s);
00475
00476 delete prog;
00477 }
00478
00479
00480
00481
00482
00483 void StatementTest::testUseKill () {
00484
00485 Prog* prog = new Prog;
00486 BinaryFileFactory bff;
00487 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00488 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00489
00490 prog->setFrontEnd(pFE);
00491
00492 std::string name = "test";
00493 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00494
00495 Cfg *cfg = proc->getCFG();
00496 std::list<RTL*>* pRtls = new std::list<RTL*>();
00497 RTL *rtl = new RTL();
00498 Assign *a = new Assign(Location::regOf(24), new Const(5));
00499 a->setNumber(1);
00500 a->setProc(proc);
00501 rtl->appendStmt(a);
00502 a = new Assign(Location::regOf(24),
00503 new Binary(opPlus,
00504 Location::regOf(24),
00505 new Const(1)));
00506 a->setNumber(2);
00507 a->setProc(proc);
00508 rtl->appendStmt(a);
00509 pRtls->push_back(rtl);
00510 PBB first = cfg->newBB(pRtls, FALL, 1);
00511 pRtls = new std::list<RTL*>();
00512 rtl = new RTL(0x123);
00513 ReturnStatement* rs = new ReturnStatement;
00514 rs->setNumber(3);
00515 rs->addReturn(new Assign(Location::regOf(24), new Const(0)));
00516 rtl->appendStmt(rs);
00517 pRtls->push_back(rtl);
00518 PBB ret = cfg->newBB(pRtls, RET, 0);
00519 first->setOutEdge(0, ret);
00520 ret->addInEdge(first);
00521 cfg->setEntryBB(first);
00522 proc->setDecoded();
00523
00524 int indent = 0;
00525 proc->decompile(new ProcList, indent);
00526
00527 std::ostringstream st;
00528 cfg->print(st);
00529 std::string s = st.str();
00530
00531 std::string expected;
00532 expected =
00533 "Fall BB:\n"
00534 "00000000\n"
00535 "Ret BB:\n"
00536 "00000123 3 RET *v* r24 := 0\n"
00537 " Modifieds: \n"
00538 " Reaching definitions: r24=6\n\n";
00539
00540 CPPUNIT_ASSERT_EQUAL(expected, s);
00541
00542 delete prog;
00543 }
00544
00545
00546
00547
00548
00549 void StatementTest::testEndlessLoop () {
00550
00551 Prog* prog = new Prog;
00552 BinaryFileFactory bff;
00553 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00554 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00555
00556 prog->setFrontEnd(pFE);
00557
00558 std::string name = "test";
00559 UserProc* proc = (UserProc*) prog->newProc("test", 0x123);
00560
00561 Cfg *cfg = proc->getCFG();
00562 std::list<RTL*>* pRtls = new std::list<RTL*>();
00563 RTL *rtl = new RTL();
00564
00565 Assign *e = new Assign(Location::regOf(24),
00566 new Const(5));
00567 e->setProc(proc);
00568 rtl->appendStmt(e);
00569 pRtls->push_back(rtl);
00570 PBB first = cfg->newBB(pRtls, FALL, 1);
00571 pRtls = new std::list<RTL*>();
00572 rtl = new RTL();
00573
00574 e = new Assign(Location::regOf(24),
00575 new Binary(opPlus,
00576 Location::regOf(24),
00577 new Const(1)));
00578 e->setProc(proc);
00579 rtl->appendStmt(e);
00580 pRtls->push_back(rtl);
00581 PBB body = cfg->newBB(pRtls, ONEWAY, 1);
00582 first->setOutEdge(0, body);
00583 body->addInEdge(first);
00584 body->setOutEdge(0, body);
00585 body->addInEdge(body);
00586 cfg->setEntryBB(first);
00587 proc->setDecoded();
00588
00589 int indent = 0;
00590 proc->decompile(new ProcList, indent);
00591
00592 std::ostringstream st;
00593 cfg->print(st);
00594 std::string s = st.str();
00595
00596 std::string expected;
00597 expected =
00598 "Fall BB: reach in: \n"
00599 "00000000 *v* r[24] := 5\n"
00600 "Oneway BB:\n"
00601 "00000000 *v* r[24] := r[24] + 1 uses: ** r[24] := 5, "
00602 "*v* r[24] := r[24] + 1, used by: ** r[24] := r[24] + 1, \n"
00603 "cfg reachExit: \n";
00604 CPPUNIT_ASSERT_EQUAL(expected, s);
00605
00606 delete prog;
00607 }
00608
00609
00610
00611
00612
00613 void StatementTest::testLocationSet () {
00614 Location rof(opRegOf, new Const(12), NULL);
00615 Const& theReg = *(Const*)rof.getSubExp1();
00616 LocationSet ls;
00617 LocationSet::iterator ii;
00618 ls.insert(rof.clone());
00619 theReg.setInt(8);
00620 ls.insert(rof.clone());
00621 theReg.setInt(31);
00622 ls.insert(rof.clone());
00623 theReg.setInt(24);
00624 ls.insert(rof.clone());
00625 theReg.setInt(12);
00626 ls.insert(rof.clone());
00627 int size = (int)ls.size();
00628 CPPUNIT_ASSERT_EQUAL(4, size);
00629 theReg.setInt(8);
00630 ii = ls.begin();
00631 CPPUNIT_ASSERT(rof == **ii);
00632 theReg.setInt(12);
00633 Exp* e;
00634 e = *(++ii); CPPUNIT_ASSERT(rof == *e);
00635 theReg.setInt(24);
00636 e = *(++ii); CPPUNIT_ASSERT(rof == *e);
00637 theReg.setInt(31);
00638 e = *(++ii); CPPUNIT_ASSERT(rof == *e);
00639 Location mof(opMemOf,
00640 new Binary(opPlus,
00641 Location::regOf(14),
00642 new Const(4)), NULL);
00643 ls.insert(mof.clone());
00644 ls.insert(mof.clone());
00645 size = (int)ls.size();
00646 CPPUNIT_ASSERT_EQUAL(5, size);
00647 ii = --ls.end();
00648 CPPUNIT_ASSERT(mof == **ii);
00649 LocationSet ls2 = ls;
00650 Exp* e2 = *ls2.begin();
00651 CPPUNIT_ASSERT(!(e2 == *ls.begin()));
00652 size = (int)ls2.size();
00653 CPPUNIT_ASSERT_EQUAL(5, size);
00654 theReg.setInt(8);
00655 CPPUNIT_ASSERT(rof == **ls2.begin());
00656 theReg.setInt(12);
00657 e = *(++ls2.begin());
00658 CPPUNIT_ASSERT(rof == *e);
00659 Assign s10(new Const(0), new Const(0)), s20(new Const(0), new Const(0));
00660 s10.setNumber(10);
00661 s20.setNumber(20);
00662 RefExp* r1 = new RefExp(
00663 Location::regOf(8),
00664 &s10);
00665 RefExp* r2 = new RefExp(
00666 Location::regOf(8),
00667 &s20);
00668 ls.insert(r1);
00669 size = (int)ls.size();
00670 CPPUNIT_ASSERT_EQUAL(6, size);
00671 Exp* dummy;
00672 CPPUNIT_ASSERT(!ls.findDifferentRef(r1, dummy));
00673 CPPUNIT_ASSERT( ls.findDifferentRef(r2, dummy));
00674
00675 Exp* r8 = Location::regOf(8);
00676 CPPUNIT_ASSERT(! ls.existsImplicit(r8));
00677
00678 RefExp r3(Location::regOf(8), NULL);
00679 ls.insert (&r3);
00680 std::cerr << ls.prints() << "\n";
00681 CPPUNIT_ASSERT(ls.existsImplicit(r8));
00682
00683 ls.remove(&r3);
00684
00685 ImplicitAssign zero(r8);
00686 RefExp r4(Location::regOf(8), &zero);
00687 ls.insert (&r4);
00688 std::cerr << ls.prints() << "\n";
00689 CPPUNIT_ASSERT(ls.existsImplicit(r8));
00690 }
00691
00692
00693
00694
00695
00696 void StatementTest::testWildLocationSet () {
00697 Location rof12(opRegOf, new Const(12), NULL);
00698 Location rof13(opRegOf, new Const(13), NULL);
00699 Assign a10, a20;
00700 a10.setNumber(10);
00701 a20.setNumber(20);
00702 RefExp r12_10(rof12.clone(), &a10);
00703 RefExp r12_20(rof12.clone(), &a20);
00704 RefExp r12_0 (rof12.clone(), NULL);
00705 RefExp r13_10(rof13.clone(), &a10);
00706 RefExp r13_20(rof13.clone(), &a20);
00707 RefExp r13_0 (rof13.clone(), NULL);
00708 RefExp r11_10(Location::regOf(11), &a10);
00709 RefExp r22_10(Location::regOf(22), &a10);
00710 LocationSet ls;
00711 ls.insert(&r12_10);
00712 ls.insert(&r12_20);
00713 ls.insert(&r12_0);
00714 ls.insert(&r13_10);
00715 ls.insert(&r13_20);
00716 ls.insert(&r13_0);
00717 RefExp wildr12(rof12.clone(), (Statement*)-1);
00718 CPPUNIT_ASSERT(ls.exists(&wildr12));
00719 RefExp wildr13(rof13.clone(), (Statement*)-1);
00720 CPPUNIT_ASSERT(ls.exists(&wildr13));
00721 RefExp wildr10(Location::regOf(10), (Statement*)-1);
00722 CPPUNIT_ASSERT(!ls.exists(&wildr10));
00723
00724 Exp* x;
00725 CPPUNIT_ASSERT( ls.findDifferentRef(&r13_10, x));
00726 CPPUNIT_ASSERT( ls.findDifferentRef(&r13_20, x));
00727 CPPUNIT_ASSERT( ls.findDifferentRef(&r13_0 , x));
00728 CPPUNIT_ASSERT( ls.findDifferentRef(&r12_10, x));
00729 CPPUNIT_ASSERT( ls.findDifferentRef(&r12_20, x));
00730 CPPUNIT_ASSERT( ls.findDifferentRef(&r12_0 , x));
00731
00732 CPPUNIT_ASSERT(!ls.findDifferentRef(&r11_10, x));
00733 CPPUNIT_ASSERT(!ls.findDifferentRef(&r22_10, x));
00734 ls.insert(&r11_10);
00735 ls.insert(&r22_10);
00736 CPPUNIT_ASSERT(!ls.findDifferentRef(&r11_10, x));
00737 CPPUNIT_ASSERT(!ls.findDifferentRef(&r22_10, x));
00738 }
00739
00740
00741
00742
00743
00744 void StatementTest::testRecursion () {
00745
00746 Prog* prog = new Prog;
00747 BinaryFileFactory bff;
00748 BinaryFile *pBF = bff.Load(HELLO_PENTIUM);
00749 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
00750
00751 prog->setFrontEnd(pFE);
00752
00753 std::string name = "test";
00754 UserProc *proc = new UserProc(prog, name, 0);
00755
00756 Cfg *cfg = proc->getCFG();
00757 std::list<RTL*>* pRtls = new std::list<RTL*>();
00758 RTL *rtl = new RTL();
00759
00760
00761 Assign *a = new Assign(Location::regOf(28),
00762 new Binary(opPlus,
00763 Location::regOf(28),
00764 new Const(-4)));
00765 rtl->appendStmt(a);
00766
00767 a = new Assign(
00768 Location::memOf(
00769 Location::regOf(28)),
00770 Location::regOf(29));
00771 rtl->appendStmt(a);
00772 pRtls->push_back(rtl);
00773 pRtls = new std::list<RTL*>();
00774
00775
00776 a = new Assign(Location::regOf(28),
00777 new Binary(opPlus,
00778 Location::regOf(28),
00779 new Const(-4)));
00780 rtl->appendStmt(a);
00781
00782
00783
00784 a = new Assign(Location::memOf(Location::regOf(28)),
00785 new Binary(opPlus,
00786 Location::memOf(
00787 new Binary(opPlus,
00788 Location::regOf(28),
00789 new Const(12))),
00790 new Const(1)));
00791 a->setProc(proc);
00792 rtl->appendStmt(a);
00793 pRtls->push_back(rtl);
00794 PBB first = cfg->newBB(pRtls, FALL, 1);
00795
00796
00797 pRtls = new std::list<RTL*>();
00798 rtl = new RTL(1);
00799
00800 a = new Assign(Location::regOf(28),
00801 new Binary(opPlus, Location::regOf(28), new Const(-4)));
00802 rtl->appendStmt(a);
00803
00804 a = new Assign(Location::memOf(Location::regOf(28)),
00805 new Terminal(opPC));
00806 rtl->appendStmt(a);
00807
00808 a = new Assign(new Terminal(opPC),
00809 new Binary(opPlus,
00810 new Binary(opPlus,
00811 new Terminal(opPC),
00812 new Const(5)),
00813 new Const(135893848)));
00814 a->setProc(proc);
00815 rtl->appendStmt(a);
00816 pRtls->push_back(rtl);
00817 CallStatement* c = new CallStatement;
00818 rtl->appendStmt(c);
00819 #if 0
00820
00821 std::vector<Exp*> args;
00822
00823 Exp* a = Location::memOf( new Binary(opPlus,
00824 Location::regOf(28), new Const(8)));
00825 args.push_back(a);
00826 crtl->setArguments(args);
00827 #endif
00828 c->setDestProc(proc);
00829 PBB callbb = cfg->newBB(pRtls, CALL, 1);
00830 first->setOutEdge(0, callbb);
00831 callbb->addInEdge(first);
00832 callbb->setOutEdge(0, callbb);
00833 callbb->addInEdge(callbb);
00834
00835 pRtls = new std::list<RTL*>();
00836 rtl = new RTL(0x123);
00837 rtl->appendStmt(new ReturnStatement);
00838
00839
00840
00841 a = new Assign(new Terminal(opPC),
00842 Location::memOf(
00843 Location::regOf(28)));
00844 rtl->appendStmt(a);
00845
00846 a = new Assign(Location::regOf(28),
00847 new Binary(opPlus,
00848 Location::regOf(28),
00849 new Const(4)));
00850 rtl->appendStmt(a);
00851 pRtls->push_back(rtl);
00852 PBB ret = cfg->newBB(pRtls, RET, 0);
00853 callbb->setOutEdge(0, ret);
00854 ret->addInEdge(callbb);
00855 cfg->setEntryBB(first);
00856
00857
00858 prog->decompile();
00859
00860 std::ostringstream st;
00861 cfg->print(st);
00862 std::string s = st.str();
00863
00864 std::string expected;
00865 expected =
00866 "Fall BB: reach in: \n"
00867 "00000000 ** r[24] := 5 uses: used by: ** r[24] := r[24] + 1, \n"
00868 "00000000 ** r[24] := 5 uses: used by: ** r[24] := r[24] + 1, \n"
00869 "Call BB: reach in: ** r[24] := 5, ** r[24] := r[24] + 1, \n"
00870 "00000001 ** r[24] := r[24] + 1 uses: ** r[24] := 5, "
00871 "** r[24] := r[24] + 1, used by: ** r[24] := r[24] + 1, \n"
00872 "cfg reachExit: \n";
00873 CPPUNIT_ASSERT_EQUAL(expected, s);
00874
00875 delete prog;
00876 }
00877
00878
00879
00880
00881
00882 void StatementTest::testClone () {
00883 Assign* a1 = new Assign(
00884 Location::regOf(8),
00885 new Binary(opPlus,
00886 Location::regOf(9),
00887 new Const(99)));
00888 Assign* a2 = new Assign(new IntegerType(16, 1),
00889 new Location(opParam, new Const("x"), NULL),
00890 new Location(opParam, new Const("y"), NULL));
00891 Assign* a3 = new Assign(new IntegerType(16, -1),
00892 new Location(opParam, new Const("z"), NULL),
00893 new Location(opParam, new Const("q"), NULL));
00894 Statement* c1 = a1->clone();
00895 Statement* c2 = a2->clone();
00896 Statement* c3 = a3->clone();
00897 std::ostringstream o1, o2;
00898 a1->print(o1);
00899 delete a1;
00900 c1->print(o2);
00901 a2->print(o1);
00902 c2->print(o2);
00903 a3->print(o1);
00904 c3->print(o2);
00905 std::string expected(" 0 *v* r8 := r9 + 99 0 *i16* x := y"
00906 " 0 *u16* z := q");
00907 std::string act1(o1.str());
00908 std::string act2(o2.str());
00909 CPPUNIT_ASSERT_EQUAL(expected, act1);
00910 CPPUNIT_ASSERT_EQUAL(expected, act2);
00911 }
00912
00913
00914
00915
00916
00917 void StatementTest::testIsAssign () {
00918 std::ostringstream ost;
00919
00920 Assign a(
00921 Location::regOf(2),
00922 new Const(99));
00923 a.print(ost);
00924 std::string expected(" 0 *v* r2 := 99");
00925 std::string actual (ost.str());
00926 CPPUNIT_ASSERT_EQUAL(expected, actual);
00927
00928 CPPUNIT_ASSERT(a.isAssign());
00929
00930 CallStatement* c = new CallStatement;
00931 CPPUNIT_ASSERT(!c->isAssign());
00932 }
00933
00934
00935
00936
00937
00938 void StatementTest::testIsFlagAssgn () {
00939 std::ostringstream ost;
00940
00941 Assign fc(
00942 new Terminal(opFlags),
00943 new Binary (opFlagCall,
00944 new Const("addFlags"),
00945 new Binary(opList,
00946 Location::regOf(2),
00947 new Const(99))));
00948 CallStatement* call = new CallStatement;
00949 BranchStatement* br = new BranchStatement;
00950 Assign* as = new Assign(
00951 Location::regOf(9),
00952 new Binary(opPlus,
00953 Location::regOf(10),
00954 new Const(4)));
00955 fc.print(ost);
00956 std::string expected(" 0 *v* %flags := addFlags( r2, 99 )");
00957 std::string actual(ost.str());
00958 CPPUNIT_ASSERT_EQUAL(expected, actual);
00959 CPPUNIT_ASSERT ( fc.isFlagAssgn());
00960 CPPUNIT_ASSERT (!call->isFlagAssgn());
00961 CPPUNIT_ASSERT (! br->isFlagAssgn());
00962 CPPUNIT_ASSERT (! as->isFlagAssgn());
00963 delete call; delete br;
00964 }
00965
00966
00967
00968
00969
00970 void StatementTest::testAddUsedLocsAssign() {
00971
00972 Assign* a = new Assign(
00973 Location::memOf(
00974 new Binary(opMinus,
00975 Location::regOf(28),
00976 new Const(4))),
00977 new Binary(opMult,
00978 Location::memOf(
00979 new Binary(opMinus,
00980 Location::regOf(28),
00981 new Const(8))),
00982 Location::regOf(26)));
00983 a->setNumber(1);
00984 LocationSet l;
00985 a->addUsedLocs(l);
00986 std::ostringstream ost1;
00987 l.print(ost1);
00988 std::string expected = "r26,\tr28,\tm[r28 - 8]";
00989 std::string actual = ost1.str();
00990 CPPUNIT_ASSERT_EQUAL(expected, actual);
00991
00992 l.clear();
00993 GotoStatement* g = new GotoStatement();
00994 g->setNumber(55);
00995 g->setDest(Location::memOf(Location::regOf(26)));
00996 g->addUsedLocs(l);
00997 std::ostringstream ost2;
00998 l.print(ost2);
00999 expected = "r26,\tm[r26]";
01000 actual = ost2.str();
01001 CPPUNIT_ASSERT_EQUAL(expected, actual);
01002 }
01003
01004 void StatementTest::testAddUsedLocsBranch() {
01005
01006 GotoStatement* g = new GotoStatement();
01007 g->setNumber(55);
01008 LocationSet l;
01009 BranchStatement* b = new BranchStatement;
01010 b->setNumber(99);
01011 b->setDest(
01012 new RefExp(
01013 Location::memOf(
01014 new RefExp(
01015 Location::regOf(26),
01016 b)),
01017 g));
01018 b->setCondExpr(new Terminal(opFlags));
01019 b->addUsedLocs(l);
01020 std::ostringstream ost3;
01021 l.print(ost3);
01022 std::string expected("r26{99},\tm[r26{99}]{55},\t%flags");
01023 std::string actual(ost3.str());
01024 CPPUNIT_ASSERT_EQUAL(expected, actual);
01025 }
01026
01027 void StatementTest::testAddUsedLocsCase() {
01028
01029 LocationSet l;
01030 CaseStatement* c = new CaseStatement;
01031 c->setDest(Location::memOf(Location::regOf(26)));
01032 SWITCH_INFO si;
01033 si.pSwitchVar = Location::memOf(
01034 new Binary(opMinus,
01035 Location::regOf(28),
01036 new Const(12)));
01037 c->setSwitchInfo(&si);
01038 c->addUsedLocs(l);
01039 std::ostringstream ost4;
01040 l.print(ost4);
01041 std::string expected("r26,\tr28,\tm[r28 - 12],\tm[r26]");
01042 std::string actual(ost4.str());
01043 CPPUNIT_ASSERT_EQUAL(expected, actual);
01044 }
01045
01046 void StatementTest::testAddUsedLocsCall() {
01047
01048 LocationSet l;
01049 GotoStatement* g = new GotoStatement();
01050 g->setNumber(55);
01051 CallStatement* ca = new CallStatement;
01052 ca->setDest(Location::memOf(Location::regOf(26)));
01053 StatementList argl;
01054 argl.append(new Assign(Location::regOf(8), Location::memOf(Location::regOf(27))));
01055 argl.append(new Assign(Location::regOf(9), new RefExp(Location::regOf(28), g)));
01056 ca->setArguments(argl);
01057 ca->addDefine(new ImplicitAssign(Location::regOf(31)));
01058 ca->addDefine(new ImplicitAssign(Location::regOf(24)));
01059 ca->addUsedLocs(l);
01060 std::ostringstream ost5;
01061 l.print(ost5);
01062 std::string expected("r26,\tr27,\tm[r26],\tm[r27],\tr28{55}");
01063 std::string actual(ost5.str());
01064 CPPUNIT_ASSERT_EQUAL(expected, actual);
01065
01066
01067 #if 0 // FIXME: to be completed
01068 l.clear();
01069 ca->addUsedLocs(l, true);
01070 std::ostringstream ost5f;
01071 l.print(ost5f);
01072 expected = "m[r26],\tm[r27],\tr26,\tr27,\tr28{55}";
01073 actual = ost5f.str();
01074 CPPUNIT_ASSERT_EQUAL(expected, actual);
01075 #endif
01076 }
01077
01078 void StatementTest::testAddUsedLocsReturn() {
01079
01080 LocationSet l;
01081 GotoStatement* g = new GotoStatement();
01082 g->setNumber(55);
01083 BranchStatement* b = new BranchStatement;
01084 b->setNumber(99);
01085 ReturnStatement* r = new ReturnStatement;
01086 r->addReturn(new Assign(Location::regOf(31), new Const(100)));
01087 r->addReturn(new Assign(Location::memOf(Location::regOf(24)), new Const(0)));
01088 r->addReturn(new Assign(
01089 Location::memOf(
01090 new Binary(opPlus,
01091 new RefExp(Location::regOf(25), g),
01092 new RefExp(Location::regOf(26), b))),
01093 new Const(5)));
01094 r->addUsedLocs(l);
01095 std::ostringstream ost6;
01096 l.print(ost6);
01097 std::string expected("r24,\tr25{55},\tr26{99}");
01098 std::string actual(ost6.str());
01099 CPPUNIT_ASSERT_EQUAL(expected, actual);
01100 }
01101
01102 void StatementTest::testAddUsedLocsBool() {
01103
01104 LocationSet l;
01105 BoolAssign* bs = new BoolAssign(8);
01106 bs->setCondExpr(new Binary(opEquals,
01107 Location::memOf(Location::regOf(24)),
01108 Location::regOf(25)));
01109 std::list<Statement*> stmts;
01110 Assign* a = new Assign(Location::memOf(Location::regOf(26)), new Terminal(opNil));
01111 stmts.push_back(a);
01112 bs->setLeftFromList(&stmts);
01113 bs->addUsedLocs(l);
01114 std::ostringstream ost7;
01115 l.print(ost7);
01116 std::string expected("r24,\tr25,\tr26,\tm[r24]");
01117 std::string actual(ost7.str());
01118 CPPUNIT_ASSERT_EQUAL(expected, actual);
01119
01120
01121 l.clear();
01122 Exp* base = Location::memOf(
01123 new Binary(opPlus,
01124 Location::local("local21", NULL),
01125 new Const(16)));
01126 Assign s372(base, new Const(0));
01127 s372.setNumber(372);
01128 PhiAssign* pa = new PhiAssign(base);
01129 pa->putAt(0, NULL, base);
01130 pa->putAt(1, &s372, base);
01131 pa->addUsedLocs(l);
01132
01133 expected = "m[local21 + 16]{-},\tm[local21 + 16]{372},\tlocal21";
01134 std::ostringstream ost8;
01135 l.print(ost8);
01136 actual = ost8.str();
01137 CPPUNIT_ASSERT_EQUAL(expected, actual);
01138
01139
01140 l.clear();
01141 ImplicitAssign* ia = new ImplicitAssign(Location::memOf(
01142 new Binary(opMinus,
01143 new RefExp(
01144 Location::regOf(28),
01145 NULL),
01146 new Const(4))));
01147 std::ostringstream ost9;
01148 ia->addUsedLocs(l);
01149 l.print(ost9);
01150 actual = ost9.str();
01151 expected = "r28{-}";
01152 CPPUNIT_ASSERT_EQUAL(expected, actual);
01153
01154 }
01155
01156
01157
01158
01159
01160 void StatementTest::testSubscriptVars () {
01161 Exp* srch = Location::regOf(28);
01162 Assign s9(new Const(0), new Const(0));
01163 s9.setNumber(9);
01164
01165
01166 Assign* a = new Assign(
01167 Location::memOf(
01168 new Binary(opMinus,
01169 Location::regOf(28),
01170 new Const(4))),
01171 new Binary(opMult,
01172 Location::memOf(
01173 new Binary(opMinus,
01174 Location::regOf(28),
01175 new Const(8))),
01176 Location::regOf(26)));
01177 a->setNumber(1);
01178 std::ostringstream ost1;
01179 a->subscriptVar(srch, &s9);
01180 ost1 << a;
01181 std::string expected = " 1 *v* m[r28{9} - 4] := m[r28{9} - 8] * r26";
01182 std::string actual(ost1.str());
01183 CPPUNIT_ASSERT_EQUAL(expected, actual);
01184
01185
01186 GotoStatement* g = new GotoStatement();
01187 g->setNumber(55);
01188 g->setDest(Location::regOf(28));
01189 std::ostringstream ost2;
01190 g->subscriptVar(srch, &s9);
01191 ost2 << g;
01192 expected = " 55 GOTO r28{9}";
01193 actual = ost2.str();
01194 CPPUNIT_ASSERT_EQUAL(expected, actual);
01195
01196
01197 BranchStatement* b = new BranchStatement;
01198 b->setNumber(99);
01199 Exp* srchb = Location::memOf(
01200 new RefExp(
01201 Location::regOf(26),
01202 b));
01203 b->setDest(new RefExp(srchb, g));
01204 b->setCondExpr(new Terminal(opFlags));
01205 std::ostringstream ost3;
01206 b->subscriptVar(srchb, &s9);
01207 b->subscriptVar(new Terminal(opFlags), g);
01208 ost3 << b;
01209 expected = " 99 BRANCH m[r26{99}]{55}, condition equals\n"
01210 "High level: %flags{55}";
01211 actual = ost3.str();
01212 CPPUNIT_ASSERT_EQUAL(expected, actual);
01213
01214
01215 CaseStatement* c = new CaseStatement;
01216 c->setDest(Location::memOf(Location::regOf(26)));
01217 SWITCH_INFO si;
01218 si.pSwitchVar = Location::memOf(
01219 new Binary(opMinus,
01220 Location::regOf(28),
01221 new Const(12)));
01222 c->setSwitchInfo(&si);
01223 std::ostringstream ost4;
01224 c->subscriptVar(srch, &s9);
01225 ost4 << c;
01226 expected = " 0 SWITCH(m[r28{9} - 12])\n";
01227 actual = ost4.str();
01228 CPPUNIT_ASSERT_EQUAL(expected, actual);
01229
01230
01231 c->setDest(Location::regOf(28));
01232 c->setSwitchInfo(NULL);
01233 std::ostringstream ost4a;
01234 c->subscriptVar(srch, &s9);
01235 ost4a << c;
01236 expected = " 0 CASE [r28{9}]";
01237 actual = ost4a.str();
01238 CPPUNIT_ASSERT_EQUAL(expected, actual);
01239
01240
01241 CallStatement* ca = new CallStatement;
01242 ca->setDest(Location::memOf(Location::regOf(26)));
01243 StatementList argl;
01244 argl.append(new Assign(Location::memOf(Location::regOf(27)), new Const(1)));
01245 argl.append(new Assign(Location::regOf(28), new Const(2)));
01246 ca->setArguments(argl);
01247 ca->addDefine(new ImplicitAssign(Location::regOf(28)));
01248 ca->addDefine(new ImplicitAssign(Location::memOf(Location::regOf(28))));
01249 std::string name("dest");
01250 ca->setDestProc(new UserProc(new Prog(), name, 0x2000));
01251 ca->setCalleeReturn(new ReturnStatement);
01252 std::ostringstream ost5;
01253 ca->subscriptVar(srch, &s9);
01254 ost5 << ca;
01255 expected =
01256 " 0 {*v* r28, *v* m[r28]} := CALL dest(\n"
01257 " *v* m[r27] := 1\n"
01258 " *v* r28 := 2\n"
01259 " )\n"
01260 " Reaching definitions: \n"
01261 " Live variables: ";
01262 actual = ost5.str();
01263 CPPUNIT_ASSERT_EQUAL(expected, actual);
01264
01265
01266 ca = new CallStatement;
01267 ca->setDest(Location::regOf(28));
01268 argl.clear();
01269 argl.append(new Assign(Location::memOf(Location::regOf(27)), new Const(1)));
01270 argl.append(new Assign(Location::regOf(29), new Const(2)));
01271 ca->setArguments(argl);
01272 ca->addDefine(new ImplicitAssign(Location::regOf(31)));
01273 ca->addDefine(new ImplicitAssign(Location::memOf(Location::regOf(31))));
01274 ca->setDestProc(new UserProc(new Prog(), name, 0x2000));
01275 ca->setCalleeReturn(new ReturnStatement);
01276 std::ostringstream ost5a;
01277 ca->subscriptVar(srch, &s9);
01278 ost5a << ca;
01279 expected =
01280 " 0 {*v* r31, *v* m[r31]} := CALL dest(\n"
01281 " *v* m[r27] := 1\n"
01282 " *v* r29 := 2\n"
01283 " )\n"
01284 " Reaching definitions: \n"
01285 " Live variables: ";
01286 actual = ost5a.str();
01287 CPPUNIT_ASSERT_EQUAL(expected, actual);
01288
01289
01290
01291
01292 ReturnStatement* r = new ReturnStatement;
01293 r->addReturn(new Assign(Location::regOf(28), new Const(1000)));
01294 r->addReturn(new Assign(Location::memOf(Location::regOf(28)), new Const(2000)));
01295 r->addReturn(new Assign(
01296 Location::memOf(
01297 new Binary(opPlus,
01298 new RefExp(Location::regOf(28), g),
01299 new RefExp(Location::regOf(26), b))),
01300 new Const(100)));
01301 std::ostringstream ost6;
01302 r->subscriptVar(srch, &s9);
01303 ost6 << r;
01304 expected =
01305 " 0 RET *v* r28 := 1000, *v* m[r28{9}] := 0x7d0, *v* m[r28{55} + r26{99}] := 100\n"
01306 " Modifieds: \n"
01307 " Reaching definitions: ";
01308 actual = ost6.str();
01309 CPPUNIT_ASSERT_EQUAL(expected, actual);
01310
01311
01312 BoolAssign* bs = new BoolAssign(8);
01313 bs->setCondExpr(new Binary(opEquals,
01314 Location::memOf(Location::regOf(28)),
01315 Location::regOf(28)));
01316 bs->setLeft(Location::memOf(Location::regOf(28)));
01317 std::ostringstream ost7;
01318 bs->subscriptVar(srch, &s9);
01319 ost7 << bs;
01320 expected=" 0 BOOL m[r28{9}] := CC(equals)\n"
01321 "High level: m[r28{9}] = r28{9}\n";
01322 actual = ost7.str();
01323 CPPUNIT_ASSERT_EQUAL(expected, actual);
01324 }
01325
01326
01327
01328
01329
01330 void StatementTest::testBypass () {
01331 Prog* prog = new Prog;
01332 BinaryFileFactory bff;
01333 BinaryFile *pBF = bff.Load(GLOBAL1_PENTIUM);
01334 FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
01335 Type::clearNamedTypes();
01336 prog->setFrontEnd(pFE);
01337 pFE->decode(prog, true);
01338 pFE->decode(prog, NO_ADDRESS);
01339 bool gotMain;
01340 ADDRESS addr = pFE->getMainEntryPoint(gotMain);
01341 CPPUNIT_ASSERT (addr != NO_ADDRESS);
01342 UserProc* proc = (UserProc*) prog->findProc("foo2");
01343 assert(proc);
01344 proc->promoteSignature();
01345 Cfg* cfg = proc->getCFG();
01346
01347 cfg->sortByAddress();
01348
01349 proc->initStatements();
01350
01351 proc->getDataFlow()->dominators(cfg);
01352
01353
01354 proc->numberStatements();
01355 proc->getDataFlow()->renameBlockVars(proc, 0, 0);
01356 proc->getDataFlow()->renameBlockVars(proc, 0, 1);
01357
01358 StatementList stmts;
01359 proc->getStatements(stmts);
01360 StatementList::iterator it = stmts.begin();
01361 while (!(*it)->isCall())
01362 it++;
01363 CallStatement* call = (CallStatement*)*it;
01364 call->setDestProc(proc);
01365
01366 advance(it, 2);
01367 Statement* s20 = *it;
01368
01369 s20->bypass();
01370
01371 std::string expected(" 20 *32* r28 := r28{-} - 16");
01372 std::string actual;
01373 std::ostringstream ost1;
01374 ost1 << s20;
01375 actual = ost1.str();
01376
01377 #if 0 // No longer needed, but could maybe expand the test one day
01378
01379 Exp* r29 = Location::regOf(29);
01380 proc->setProven(new Binary(opEquals, r29, r29->clone()));
01381 (*it)->bypass();
01382
01383 expected = " 22 *32* r24 := m[r29{3} + 8]{-}";
01384 std::ostringstream ost2;
01385 ost2 << *it;
01386 actual = ost2.str();
01387 CPPUNIT_ASSERT_EQUAL(expected, actual);
01388 #endif
01389 delete pFE;
01390 }
01391
01392
01393
01394
01395
01396 void StatementTest::testStripSizes () {
01397
01398
01399 Exp* lhs = Location::regOf(24);
01400 Exp* rhs = new Binary(opDiv,
01401 new Binary(opSize,
01402 new Const(8),
01403 new Binary(opSize,
01404 new Const(8),
01405 Location::memOf(
01406 new Binary(opPlus,
01407 new Ternary(opZfill,
01408 new Const(8),
01409 new Const(32),
01410 Location::local("local5", NULL)),
01411 Location::local("param6", NULL))))),
01412 new Const(16));
01413 Statement* s = new Assign(lhs, rhs);
01414 s->stripSizes();
01415 std::string expected(
01416 " 0 *v* r24 := m[zfill(8,32,local5) + param6] / 16");
01417 std::string actual;
01418 std::ostringstream ost;
01419 ost << s;
01420 actual = ost.str();
01421 CPPUNIT_ASSERT_EQUAL(expected, actual);
01422 }
01423
01424
01425
01426
01427
01428 void StatementTest::testFindConstants () {
01429 Statement* a = new Assign(
01430 Location::regOf(24),
01431 new Binary(opPlus,
01432 new Const(3),
01433 new Const(4)));
01434 std::list<Const*> lc;
01435 a->findConstants(lc);
01436 std::list<Const*>::iterator it;
01437 std::ostringstream ost1;
01438 for (it = lc.begin(); it != lc.end(); ) {
01439 ost1 << *it;
01440 if (++it != lc.end())
01441 ost1 << ", ";
01442 }
01443 std::string actual = ost1.str();
01444 std::string expected("3, 4");
01445 CPPUNIT_ASSERT_EQUAL(expected, actual);
01446 }