Beispiel #1
0
/**
 * Test the renaming of variables.
 */
void
CfgTest::testRenameVars()
{
	auto prog = Prog::open(FRONTIER_PENTIUM);
	CPPUNIT_ASSERT(prog);

	auto fe = prog->getFrontEnd();
	Type::clearNamedTypes();
	fe->decode();

	UserProc *pProc = (UserProc *)prog->getProc(0);
	Cfg *cfg = pProc->getCFG();
	DataFlow *df = pProc->getDataFlow();

	// Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
	prog->finishDecode();

	df->dominators(cfg);
	df->placePhiFunctions(pProc);
	pProc->numberStatements();         // After placing phi functions!
	df->renameBlockVars(pProc, 0, 1);  // Block 0, mem depth 1

	// MIKE: something missing here?

	delete prog;
}
Beispiel #2
0
/**
 * Test the placing of phi functions.
 */
void
CfgTest::testPlacePhi()
{
	auto prog = Prog::open(FRONTIER_PENTIUM);
	CPPUNIT_ASSERT(prog);

	auto fe = prog->getFrontEnd();
	Type::clearNamedTypes();
	fe->decode();

	UserProc *pProc = (UserProc *)prog->getProc(0);
	Cfg *cfg = pProc->getCFG();

	// Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
	prog->finishDecode();

	DataFlow *df = pProc->getDataFlow();
	df->dominators(cfg);
	df->placePhiFunctions(pProc);

	// m[r29 - 8] (x for this program)
	Exp *e = Location::memOf(
	    new Binary(opMinus,
	        Location::regOf(29),
	        new Const(4)));

	// A_phi[x] should be the set {7 8 10 15 20 21} (all the join points)
	std::ostringstream ost;
	std::set<int> &A_phi = df->getA_phi(e);
	for (const auto &ii : A_phi)
		ost << ii << " ";
	std::string expected("7 8 10 15 20 21 ");
	CPPUNIT_ASSERT_EQUAL(expected, ost.str());
	delete prog;
}
Beispiel #3
0
/*==============================================================================
 * FUNCTION:		CfgTest::testRenameVars
 * OVERVIEW:		Test the renaming of variables
 *============================================================================*/
void CfgTest::testRenameVars ()
{
  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);

  UserProc* pProc = (UserProc*) prog->getProc(0);
  Cfg* cfg = pProc->getCFG();
  DataFlow* df = pProc->getDataFlow();

  // Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
  prog->finishDecode();

  df->dominators(cfg);
  df->placePhiFunctions(pProc);
  pProc->numberStatements();				// After placing phi functions!
  df->renameBlockVars(pProc, 0, 1);		// Block 0, mem depth 1

  // MIKE: something missing here?

  delete pFE;
}
Beispiel #4
0
/**
 * 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;
}
Beispiel #5
0
/*==============================================================================
 * FUNCTION:		CfgTest::testPlacePhi2
 * OVERVIEW:		Test a case where a phi function is not needed
 *============================================================================*/
void CfgTest::testPlacePhi2 ()
{
  BinaryFileFactory bff;
  BinaryFile* pBF = bff.Load(IFTHEN_PENTIUM);
  CPPUNIT_ASSERT(pBF != 0);
  Prog* prog = new Prog;
  FrontEnd* pFE = new PentiumFrontEnd(pBF, prog, &bff);
  Type::clearNamedTypes();
  prog->setFrontEnd(pFE);
  pFE->decode(prog);

  UserProc* pProc = (UserProc*) prog->getProc(0);
  Cfg* cfg = pProc->getCFG();
  DataFlow* df = pProc->getDataFlow();

  // Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
  prog->finishDecode();

  df->dominators(cfg);
  df->placePhiFunctions(pProc);

  // In this program, x is allocated at [ebp-4], a at [ebp-8], and
  // b at [ebp-12]
  // We check that A_phi[ m[ebp-8] ] is 4, and that
  // A_phi A_phi[ m[ebp-8] ] is null
  // (block 4 comes out with n=4)

  std::string expected = "4 ";
  std::ostringstream actual;
  // m[r29 - 8]
  Exp* e = new Unary(opMemOf,
                     new Binary(opMinus,
                                Location::regOf(29),
                                new Const(8)));
  std::set<int>& s = df->getA_phi(e);
  std::set<int>::iterator pp;
  for (pp = s.begin(); pp != s.end(); pp++)
    actual << *pp << " ";
  CPPUNIT_ASSERT_EQUAL(expected, actual.str());
  delete e;

  expected = "";
  std::ostringstream actual2;
  // m[r29 - 12]
  e = new Unary(opMemOf,
                new Binary(opMinus,
                           Location::regOf(29),
                           new Const(12)));

  std::set<int>& s2 = df->getA_phi(e);
  for (pp = s2.begin(); pp != s2.end(); pp++)
    actual2 << *pp << " ";
  CPPUNIT_ASSERT_EQUAL(expected, actual2.str());
  delete e;
  delete pFE;
}
Beispiel #6
0
/**
 * 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;
}
Beispiel #7
0
/**
 * Test a case where a phi function is not needed.
 */
void
CfgTest::testPlacePhi2()
{
	auto prog = Prog::open(IFTHEN_PENTIUM);
	CPPUNIT_ASSERT(prog);

	auto fe = prog->getFrontEnd();
	Type::clearNamedTypes();
	fe->decode();

	UserProc *pProc = (UserProc *)prog->getProc(0);
	Cfg *cfg = pProc->getCFG();
	DataFlow *df = pProc->getDataFlow();

	// Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
	prog->finishDecode();

	df->dominators(cfg);
	df->placePhiFunctions(pProc);

	// In this program, x is allocated at [ebp-4], a at [ebp-8], and
	// b at [ebp-12]
	// We check that A_phi[ m[ebp-8] ] is 4, and that
	// A_phi A_phi[ m[ebp-8] ] is null
	// (block 4 comes out with n=4)

	std::string expected = "4 ";
	std::ostringstream actual;
	// m[r29 - 8]
	Exp *e = Location::memOf(
	    new Binary(opMinus,
	        Location::regOf(29),
	        new Const(8)));
	std::set<int> &s = df->getA_phi(e);
	for (const auto &pp : s)
		actual << pp << " ";
	CPPUNIT_ASSERT_EQUAL(expected, actual.str());
	delete e;

	expected = "";
	std::ostringstream actual2;
	// m[r29 - 12]
	e = Location::memOf(
	    new Binary(opMinus,
	        Location::regOf(29),
	        new Const(12)));

	std::set<int> &s2 = df->getA_phi(e);
	for (const auto &pp : s2)
		actual2 << pp << " ";
	CPPUNIT_ASSERT_EQUAL(expected, actual2.str());
	delete e;
	delete prog;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
/*==============================================================================
 * FUNCTION:		CfgTest::testPlacePhi
 * OVERVIEW:		Test the placing of phi functions
 *============================================================================*/
void CfgTest::testPlacePhi ()
{
  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);

  UserProc* pProc = (UserProc*) prog->getProc(0);
  Cfg* cfg = pProc->getCFG();

  // Simplify expressions (e.g. m[ebp + -8] -> m[ebp - 8]
  prog->finishDecode();

  DataFlow* df = pProc->getDataFlow();
  df->dominators(cfg);
  df->placePhiFunctions(pProc);

  // m[r29 - 8] (x for this program)
  Exp* e = new Unary(opMemOf,
                     new Binary(opMinus,
                                Location::regOf(29),
                                new Const(4)));

  // A_phi[x] should be the set {7 8 10 15 20 21} (all the join points)
  std::ostringstream ost;
  std::set<int>::iterator ii;
  std::set<int>& A_phi = df->getA_phi(e);
  for (ii = A_phi.begin(); ii != A_phi.end(); ++ii)
    ost << *ii << " ";
  std::string expected("7 8 10 15 20 21 ");
  CPPUNIT_ASSERT_EQUAL(expected, ost.str());
  delete pFE;
}
Beispiel #11
0
void FrontSparcTest::testDelaySlot() {
	
	BinaryFileFactory bff;
	BinaryFile *pBF = bff.Load(BRANCH_SPARC);
	if (pBF == NULL)
		pBF = new BinaryFileStub();	   // fallback on stub
	CPPUNIT_ASSERT(pBF != 0);
	CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
	Prog* prog = new Prog;
	FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
	prog->setFrontEnd(pFE);
	// decode calls readLibraryCatalog(), which needs to have definitions for non-sparc architectures cleared
	Type::clearNamedTypes();
	pFE->decode(prog);

	bool gotMain;
	ADDRESS addr = pFE->getMainEntryPoint(gotMain);
	CPPUNIT_ASSERT (addr != NO_ADDRESS);

	std::string name("testDelaySlot");
	UserProc* pProc = new UserProc(prog, name, addr);
	std::ofstream dummy;
	bool res = pFE->processProc(addr, pProc, dummy, false);

	CPPUNIT_ASSERT(res == 1);
	Cfg* cfg = pProc->getCFG();
	BB_IT it;
	PBB bb = cfg->getFirstBB(it);
	std::ostringstream o1;
	bb->print(o1);
	std::string expected("Call BB:\n"
		"in edges: \n"
		"out edges: 10a98 \n"
		"00010a80    0 *32* tmp := r14 - 120\n"
		"            0 *32* m[r14] := r16\n"
		"            0 *32* m[r14 + 4] := r17\n"
		"            0 *32* m[r14 + 8] := r18\n"
		"            0 *32* m[r14 + 12] := r19\n"
		"            0 *32* m[r14 + 16] := r20\n"
		"            0 *32* m[r14 + 20] := r21\n"
		"            0 *32* m[r14 + 24] := r22\n"
		"            0 *32* m[r14 + 28] := r23\n"
		"            0 *32* m[r14 + 32] := r24\n"
		"            0 *32* m[r14 + 36] := r25\n"
		"            0 *32* m[r14 + 40] := r26\n"
		"            0 *32* m[r14 + 44] := r27\n"
		"            0 *32* m[r14 + 48] := r28\n"
		"            0 *32* m[r14 + 52] := r29\n"
		"            0 *32* m[r14 + 56] := r30\n"
		"            0 *32* m[r14 + 60] := r31\n"
		"            0 *32* r24 := r8\n"
		"            0 *32* r25 := r9\n"
		"            0 *32* r26 := r10\n"
		"            0 *32* r27 := r11\n"
		"            0 *32* r28 := r12\n"
		"            0 *32* r29 := r13\n"
		"            0 *32* r30 := r14\n"
		"            0 *32* r31 := r15\n"
		"            0 *32* r14 := tmp\n"
		"00010a84    0 *32* r16 := 0x11400\n"
		"00010a88    0 *32* r16 := r16 | 808\n"
		"00010a8c    0 *32* r8 := r16\n"
		"00010a90    0 *32* tmp := r30\n"
		"            0 *32* r9 := r30 - 20\n"
		"00010a90    0 CALL scanf(\n"
		"              )\n"
		"              Reaching definitions: \n"
		"              Live variables: \n");

	std::string actual(o1.str());
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	bb = cfg->getNextBB(it);
	CPPUNIT_ASSERT(bb);
	std::ostringstream o2;
	bb->print(o2);
	expected = std::string("Call BB:\n"
		"in edges: 10a90 \n"
		"out edges: 10aa4 \n"
		"00010a98    0 *32* r8 := r16\n"
		"00010a9c    0 *32* tmp := r30\n"
		"            0 *32* r9 := r30 - 24\n"
		"00010a9c    0 CALL scanf(\n"
		"              )\n"
		"              Reaching definitions: \n"
		"              Live variables: \n");

	actual = std::string(o2.str());
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	bb = cfg->getNextBB(it);
	CPPUNIT_ASSERT(bb);
	std::ostringstream o3;
	bb->print(o3);
	expected = std::string("Twoway BB:\n"
	"in edges: 10a9c \n"
	"out edges: 10ac8 10ab8 \n"
	"00010aa4    0 *32* r8 := m[r30 - 20]\n"
	"00010aa8    0 *32* r16 := 5\n"
	"00010aac    0 *32* tmp := r16\n"
	"            0 *32* r0 := r16 - r8\n"
	"            0 *v* %flags := SUBFLAGS( tmp, r8, r0 )\n"
	"00010ab0    0 *32* r8 := 0x11400\n"
	"00010ab0    0 BRANCH 0x10ac8, condition not equals\n"
	"High level: %flags\n");
	actual = std::string(o3.str());
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	bb = cfg->getNextBB(it);
	CPPUNIT_ASSERT(bb);
	std::ostringstream o4;
	bb->print(o4);
	expected = std::string("L1: Twoway BB:\n"
		"in edges: 10ab0 10ac4 \n"
		"out edges: 10ad8 10ad0 \n"
		"00010ac8    0 *32* r8 := 0x11400\n"
		"00010ac8    0 BRANCH 0x10ad8, condition equals\n"
		"High level: %flags\n");
	actual = std::string(o4.str());
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	bb = cfg->getNextBB(it);
	CPPUNIT_ASSERT(bb);
	std::ostringstream o5;
	bb->print(o5);
	expected = std::string("Call BB:\n"
		"in edges: 10ab0 \n"
		"out edges: 10ac0 \n"
		"00010ab8    0 *32* r8 := r8 | 816\n"
		"00010ab8    0 CALL printf(\n"
		"              )\n"
		"              Reaching definitions: \n"
		"              Live variables: \n");

	actual = std::string(o5.str());
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	delete prog;
}