/** * Test the dominator frontier code. */ void CfgTest::testDominators() { #define FRONTIER_FOUR 0x08048347 #define FRONTIER_FIVE 0x08048351 #define FRONTIER_TWELVE 0x080483b2 #define FRONTIER_THIRTEEN 0x080483b9 auto prog = Prog::open(FRONTIER_PENTIUM); CPPUNIT_ASSERT(prog); auto fe = prog->getFrontEnd(); Type::clearNamedTypes(); fe->decode(); bool gotMain; ADDRESS addr = fe->getMainEntryPoint(gotMain); CPPUNIT_ASSERT(addr != NO_ADDRESS); UserProc *pProc = (UserProc *)prog->getProc(0); Cfg *cfg = pProc->getCFG(); DataFlow *df = pProc->getDataFlow(); df->dominators(cfg); // Find BB "5" (as per Appel, Figure 19.5). BasicBlock *bb = nullptr; for (const auto &b : *cfg) { if (b->getLowAddr() == FRONTIER_FIVE) { bb = b; break; } } CPPUNIT_ASSERT(bb); std::ostringstream expected, actual; #if 0 expected << std::hex << FRONTIER_FIVE << " " << FRONTIER_THIRTEEN << " " << FRONTIER_TWELVE << " " << FRONTIER_FOUR << " " << std::dec; #endif expected << std::hex << FRONTIER_THIRTEEN << " " << FRONTIER_FOUR << " " << FRONTIER_TWELVE << " " << FRONTIER_FIVE << " " << std::dec; int n5 = df->pbbToNode(bb); std::set<int> &DFset = df->getDF(n5); for (const auto &ii : DFset) actual << std::hex << (unsigned)df->nodeToBB(ii)->getLowAddr() << std::dec << " "; CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str()); delete prog; }
/** * Test a case where semi dominators are different to dominators. */ void CfgTest::testSemiDominators() { #define SEMI_L 0x80483b0 #define SEMI_M 0x80483e2 #define SEMI_B 0x8048345 #define SEMI_D 0x8048354 #define SEMI_M 0x80483e2 auto prog = Prog::open(SEMI_PENTIUM); CPPUNIT_ASSERT(prog); auto fe = prog->getFrontEnd(); Type::clearNamedTypes(); fe->decode(); bool gotMain; ADDRESS addr = fe->getMainEntryPoint(gotMain); CPPUNIT_ASSERT(addr != NO_ADDRESS); UserProc *pProc = (UserProc *)prog->getProc(0); Cfg *cfg = pProc->getCFG(); DataFlow *df = pProc->getDataFlow(); df->dominators(cfg); // Find BB "L (6)" (as per Appel, Figure 19.8). BasicBlock *bb = nullptr; for (const auto &b : *cfg) { if (b->getLowAddr() == SEMI_L) { bb = b; break; } } CPPUNIT_ASSERT(bb); int nL = df->pbbToNode(bb); // The dominator for L should be B, where the semi dominator is D // (book says F) unsigned actual_dom = (unsigned)df->nodeToBB(df->getIdom(nL))->getLowAddr(); unsigned actual_semi = (unsigned)df->nodeToBB(df->getSemi(nL))->getLowAddr(); CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_B, actual_dom); CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_D, actual_semi); // Check the final dominator frontier as well; should be M and B std::ostringstream expected, actual; #if 0 expected << std::hex << SEMI_M << " " << SEMI_B << " " << std::dec; #endif expected << std::hex << SEMI_B << " " << SEMI_M << " " << std::dec; std::set<int> &DFset = df->getDF(nL); for (const auto &ii : DFset) actual << std::hex << (unsigned)df->nodeToBB(ii)->getLowAddr() << std::dec << " "; CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str()); delete prog; }
void CfgTest::testSemiDominators () { BinaryFileFactory bff; BinaryFile* pBF = bff.Load(SEMI_PENTIUM); CPPUNIT_ASSERT(pBF != 0); Prog* prog = new Prog; FrontEnd* pFE = new PentiumFrontEnd(pBF, prog, &bff); Type::clearNamedTypes(); prog->setFrontEnd(pFE); pFE->decode(prog); bool gotMain; ADDRESS addr = pFE->getMainEntryPoint(gotMain); CPPUNIT_ASSERT (addr != NO_ADDRESS); UserProc* pProc = (UserProc*) prog->getProc(0); Cfg* cfg = pProc->getCFG(); DataFlow* df = pProc->getDataFlow(); df->dominators(cfg); // Find BB "L (6)" (as per Appel, Figure 19.8). BB_IT it; PBB bb = cfg->getFirstBB(it); while (bb && bb->getLowAddr() != SEMI_L) { bb = cfg->getNextBB(it); } CPPUNIT_ASSERT(bb); int nL = df->pbbToNode(bb); // The dominator for L should be B, where the semi dominator is D // (book says F) unsigned actual_dom = (unsigned)df->nodeToBB(df->getIdom(nL))->getLowAddr(); unsigned actual_semi = (unsigned)df->nodeToBB(df->getSemi(nL))->getLowAddr(); CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_B, actual_dom); CPPUNIT_ASSERT_EQUAL((unsigned)SEMI_D, actual_semi); // Check the final dominator frontier as well; should be M and B std::ostringstream expected, actual; //expected << std::hex << SEMI_M << " " << SEMI_B << " "; expected << std::hex << SEMI_B << " " << SEMI_M << " "; std::set<int>::iterator ii; std::set<int>& DFset = df->getDF(nL); for (ii=DFset.begin(); ii != DFset.end(); ii++) actual << std::hex << (unsigned)df->nodeToBB(*ii)->getLowAddr() << " "; CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str()); delete pFE; }
void CfgTest::testDominators () { BinaryFileFactory bff; BinaryFile *pBF = bff.Load(FRONTIER_PENTIUM); CPPUNIT_ASSERT(pBF != 0); Prog* prog = new Prog; FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff); Type::clearNamedTypes(); prog->setFrontEnd(pFE); pFE->decode(prog); bool gotMain; ADDRESS addr = pFE->getMainEntryPoint(gotMain); CPPUNIT_ASSERT (addr != NO_ADDRESS); UserProc* pProc = (UserProc*) prog->getProc(0); Cfg* cfg = pProc->getCFG(); DataFlow* df = pProc->getDataFlow(); df->dominators(cfg); // Find BB "5" (as per Appel, Figure 19.5). BB_IT it; PBB bb = cfg->getFirstBB(it); while (bb && bb->getLowAddr() != FRONTIER_FIVE) { bb = cfg->getNextBB(it); } CPPUNIT_ASSERT(bb); std::ostringstream expected, actual; //expected << std::hex << FRONTIER_FIVE << " " << FRONTIER_THIRTEEN << " " << FRONTIER_TWELVE << " " << // FRONTIER_FOUR << " "; expected << std::hex << FRONTIER_THIRTEEN << " " << FRONTIER_FOUR << " " << FRONTIER_TWELVE << " " << FRONTIER_FIVE << " "; int n5 = df->pbbToNode(bb); std::set<int>::iterator ii; std::set<int>& DFset = df->getDF(n5); for (ii=DFset.begin(); ii != DFset.end(); ii++) actual << std::hex << (unsigned)df->nodeToBB(*ii)->getLowAddr() << " "; CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str()); pBF->UnLoad(); delete pFE; }