Exemple #1
0
/*==============================================================================
 * FUNCTION:		RtlTest::testIsCompare
 * OVERVIEW:		Test the isCompare function
 *============================================================================*/
void RtlTest::testIsCompare ()
{
  BinaryFileFactory bff;
  BinaryFile *pBF = bff.Load(SWITCH_SPARC);
  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 second instruction: "sub		%i0, 2, %o1"
  int iReg;
  Exp* eOperand = NULL;
  DecodeResult inst = pFE->decodeInstruction(0x10910);
  CPPUNIT_ASSERT(inst.rtl != NULL);
  CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false);

  // Decode fifth instruction: "cmp		%o1, 5"
  inst = pFE->decodeInstruction(0x1091c);
  CPPUNIT_ASSERT(inst.rtl != NULL);
  CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true);
  CPPUNIT_ASSERT_EQUAL(9, iReg);
  std::string expected("5");
  std::ostringstream ost1;
  eOperand->print(ost1);
  std::string actual(ost1.str());
  CPPUNIT_ASSERT_EQUAL(expected, actual);

  pBF->UnLoad();
  delete pBF;
  delete pFE;
  pBF = bff.Load(SWITCH_PENT);
  CPPUNIT_ASSERT(pBF != 0);
  CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM);
  pFE = new PentiumFrontEnd(pBF, prog, &bff);
  prog->setFrontEnd(pFE);

  // Decode fifth instruction: "cmp	$0x5,%eax"
  inst = pFE->decodeInstruction(0x80488fb);
  CPPUNIT_ASSERT(inst.rtl != NULL);
  CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true);
  CPPUNIT_ASSERT_EQUAL(24, iReg);
  std::ostringstream ost2;
  eOperand->print(ost2);
  actual = ost2.str();
  CPPUNIT_ASSERT_EQUAL(expected, actual);

  // Decode instruction: "add		$0x4,%esp"
  inst = pFE->decodeInstruction(0x804890c);
  CPPUNIT_ASSERT(inst.rtl != NULL);
  CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false);
  pBF->UnLoad();
  delete pFE;
}
Exemple #2
0
/*==============================================================================
 * FUNCTION:        LoaderTest::testPentiumLoad
 * OVERVIEW:        Test loading the pentium (Solaris) hello world program
 *============================================================================*/
void LoaderTest::testPentiumLoad ()
{
    std::ostringstream ost;

    // Load Pentium hello world
    BinaryFileFactory bff;
    BinaryFile* pBF = bff.Load(HELLO_PENTIUM);
    CPPUNIT_ASSERT(pBF != NULL);
    int n;
    SectionInfo* si;
    n = pBF->GetNumSections();
    ost << "Number of sections = " << std::dec << n << "\r\n\t";
    si = pBF->GetSectionInfo(1);
    ost << si->pSectionName << "\t";
    si = pBF->GetSectionInfo(n-1);
    ost << si->pSectionName;
    pBF->UnLoad();
    // Note: the string below needs to have embedded tabs. Edit with caution!
    // (And slightly different string to the sparc test, e.g. rel vs rela)
    std::string expected("Number of sections = 34\r\n\t"
                         ".interp	.strtab");


    CPPUNIT_ASSERT_EQUAL(expected, ost.str());
    bff.UnLoad();
}
Exemple #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;
}
Exemple #4
0
/*==============================================================================
 * FUNCTION:		ProcTest::testName
 * OVERVIEW:		Test setting and reading name, constructor, native address
 *============================================================================*/
void ProcTest::testName ()
{
  Prog* prog = new Prog();
  BinaryFile *pBF = new BinaryFileStub();
  CPPUNIT_ASSERT(pBF != 0);
  std::string nm("default name");
  BinaryFileFactory bff;
  pBF = bff.Load(HELLO_PENTIUM);
  FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
  CPPUNIT_ASSERT(pFE != 0);
  prog->setFrontEnd(pFE);
  CPPUNIT_ASSERT(prog);
  pFE->readLibraryCatalog();				// Since we are not decoding
  m_proc = new UserProc(prog, nm, 20000); // Will print in decimal if error
  std::string actual(m_proc->getName());
  CPPUNIT_ASSERT_EQUAL(std::string("default name"), actual);

  std::string name("printf");
  LibProc lp(prog, name, 30000);
  actual =  lp.getName();
  CPPUNIT_ASSERT_EQUAL(name, actual);

  ADDRESS a = lp.getNativeAddress();
  ADDRESS expected = 30000;
  CPPUNIT_ASSERT_EQUAL(expected, a);
  a = m_proc->getNativeAddress();
  expected = 20000;
  CPPUNIT_ASSERT_EQUAL(expected, a);

  delete prog;
  delete m_proc;
  // delete pFE;		// No! Deleting the prog deletes the pFE already (which deletes the BinaryFileFactory)
}
Exemple #5
0
/*==============================================================================
 * FUNCTION:        LoaderTest::testPalmLoad
 * OVERVIEW:        Test loading the Palm 68328 Starter.prc program
 *============================================================================*/
void LoaderTest::testPalmLoad ()
{
    std::ostringstream ost;

    // Load Palm Starter.prc
    BinaryFileFactory bff;
    BinaryFile* pBF = bff.Load(STARTER_PALM);
    CPPUNIT_ASSERT(pBF != NULL);
    int n;
    SectionInfo* si;
    n = pBF->GetNumSections();
    ost << "Number of sections = " << std::dec << n << "\r\n";
    for (int i=0; i < n; i++)
        {
            si = pBF->GetSectionInfo(i);
            ost << si->pSectionName << "\t";
        }
    pBF->UnLoad();
    // Note: the string below needs to have embedded tabs. Edit with caution!
    std::string expected("Number of sections = 8\r\n"
                         "code1	MBAR1000	tFRM1000	Talt1001	"
                         "data0	code0	tAIN1000	tver1000	");
    CPPUNIT_ASSERT_EQUAL(expected, ost.str());
    bff.UnLoad();
}
/*==============================================================================
 * FUNCTION:		TypeTest::testNotEqual
 * OVERVIEW:		Test type inequality
 *============================================================================*/
void TypeTest::testCompound() {
	BinaryFileFactory bff;
	BinaryFile *pBF = bff.Load(HELLO_WINDOWS);
	FrontEnd *pFE = new PentiumFrontEnd(pBF, new Prog, &bff);
	Boomerang::get()->setLogger(new FileLogger());		// May try to output some messages to LOG
	pFE->readLibraryCatalog();				// Read definitions

	Signature* paintSig = pFE->getLibSignature("BeginPaint");
	// Second argument should be an LPPAINTSTRUCT
	Type* ty = paintSig->getParamType(1);
	const char* p = ty->getCtype();
	std::string expected("LPPAINTSTRUCT");
	std::string actual(p);
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	// Get the type pointed to
	ty = ty->asPointer()->getPointsTo();
	p = ty->getCtype();
	expected = "PAINTSTRUCT";
	actual = p;
	CPPUNIT_ASSERT_EQUAL(expected, actual);


	// Offset 8 should have a RECT
	Type* subTy = ty->asCompound()->getTypeAtOffset(8*8);
	p = subTy->getCtype();
	expected = "RECT";
	actual = p;
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	// Name at offset C should be bottom
	p = subTy->asCompound()->getNameAtOffset(0x0C*8);
	expected = "bottom";
	actual = p;
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	// Now figure out the name at offset 8+C
	p = ty->asCompound()->getNameAtOffset((8 + 0x0C)*8);
	expected = "rcPaint";
	actual = p;
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	// Also at offset 8
	p = ty->asCompound()->getNameAtOffset((8 + 0)*8);
	actual = p;
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	// Also at offset 8+4
	p = ty->asCompound()->getNameAtOffset((8 + 4)*8);
	actual = p;
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	// And at offset 8+8
	p = ty->asCompound()->getNameAtOffset((8 + 8)*8);
	actual = p;
	CPPUNIT_ASSERT_EQUAL(expected, actual);

	delete pFE;
}
Exemple #7
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;
}
FrontEnd* FrontEnd::Load(const char *fname, Prog* prog) {
	BinaryFileFactory* pbff = new BinaryFileFactory;
	if (pbff == NULL) return NULL;
	std::cout<<"in frontend::load pBF =bff->load\n";
	BinaryFile *pBF = pbff->Load(fname);
  	std::cout<< fname << "\n";
  	if(ASS_FILE)prog->m_path=fname;//donbinhvn: remember path for later processing
	if (pBF == NULL) return NULL;
	return instantiate(pBF, prog, pbff);
}
Exemple #9
0
void FrontPentTest::testFindMain()
{
	// Test the algorithm for finding main, when there is a call to __libc_start_main
	// Also tests the loader hack
	BinaryFileFactory bff;
	BinaryFile *pBF = bff.Load(FEDORA2_TRUE);
	CPPUNIT_ASSERT(pBF != NULL);
	Prog *prog = new Prog;
	FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
	prog->setFrontEnd(pFE);
	CPPUNIT_ASSERT(pFE != NULL);
	bool found;
	ADDRESS addr = pFE->getMainEntryPoint(found);
	ADDRESS expected = 0x8048b10;
	CPPUNIT_ASSERT_EQUAL(expected, addr);
	pBF->Close();
	bff.UnLoad();

	pBF = bff.Load(FEDORA3_TRUE);
	CPPUNIT_ASSERT(pBF != NULL);
	pFE = new PentiumFrontEnd(pBF, prog, &bff);
	prog->setFrontEnd(pFE);
	CPPUNIT_ASSERT(pFE != NULL);
	addr = pFE->getMainEntryPoint(found);
	expected = 0x8048c4a;
	CPPUNIT_ASSERT_EQUAL(expected, addr);
	pBF->Close();
	bff.UnLoad();

	pBF = bff.Load(SUSE_TRUE);
	CPPUNIT_ASSERT(pBF != NULL);
	pFE = new PentiumFrontEnd(pBF, prog, &bff);
	prog->setFrontEnd(pFE);
	CPPUNIT_ASSERT(pFE != NULL);
	addr = pFE->getMainEntryPoint(found);
	expected = 0x8048b60;
	CPPUNIT_ASSERT_EQUAL(expected, addr);
	pBF->Close();

	delete pFE;
}
Exemple #10
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;
}
Exemple #11
0
/*==============================================================================
 * FUNCTION:		FrontPentTest::test1
 * OVERVIEW:		Test decoding some pentium instructions
 *============================================================================*/
void FrontPentTest::test1 ()
{
    std::ostringstream ost;

    BinaryFileFactory bff;
    BinaryFile *pBF = bff.Load(HELLO_PENT);
    if (pBF == NULL)
        pBF = new BinaryFileStub();
    CPPUNIT_ASSERT(pBF != 0);
    CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM);
    Prog* prog = new Prog;
    FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
    prog->setFrontEnd(pFE);

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

    // Decode first instruction
    DecodeResult inst = pFE->decodeInstruction(addr);
    inst.rtl->print(ost);

    std::string expected(
        "08048328    0 *32* m[r28 - 4] := r29\n"
        "            0 *32* r28 := r28 - 4\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(ost.str()));

    std::ostringstream o2;
    addr += inst.numBytes;
    inst = pFE->decodeInstruction(addr);
    inst.rtl->print(o2);
    expected = std::string("08048329    0 *32* r29 := r28\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));

    std::ostringstream o3;
    addr = 0x804833b;
    inst = pFE->decodeInstruction(addr);
    inst.rtl->print(o3);
    expected = std::string(
                   "0804833b    0 *32* m[r28 - 4] := 0x80483fc\n"
                   "            0 *32* r28 := r28 - 4\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));

    delete pFE;
    // delete pBF;
}
Exemple #12
0
/*==============================================================================
 * FUNCTION:		ProgTest::testName
 * OVERVIEW:		Test setting and reading name
 *============================================================================*/
void ProgTest::testName ()
{
  BinaryFileFactory bff;
  BinaryFile *pBF = bff.Load(HELLO_PENTIUM);	// Don't actually use it
  Prog* prog = new Prog();
  FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
  // We need a Prog object with a pBF (for getEarlyParamExp())
  prog->setFrontEnd(pFE);
  std::string actual(prog->getName());
  std::string expected(HELLO_PENTIUM);
  CPPUNIT_ASSERT_EQUAL(expected, actual);
  std::string name("Happy prog");
  prog->setName(name.c_str());
  actual =  prog->getName();
  CPPUNIT_ASSERT_EQUAL(name, actual);
  delete pFE;
}
Exemple #13
0
void FrontSparcTest::test2() {
	DecodeResult inst;
	std::string expected;

	BinaryFileFactory bff;
	BinaryFile *pBF = bff.Load(HELLO_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);

	std::ostringstream o1;
	inst = pFE->decodeInstruction(0x10690);
	inst.rtl->print(o1);
	// This call is to out of range of the program's text limits (to the Program Linkage Table (PLT), calling printf)
	// This is quite normal.
	expected = std::string("00010690    0 CALL printf(\n"
		"              )\n"
		"              Reaching definitions: \n"
		"              Live variables: \n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));

	std::ostringstream o2;
	inst = pFE->decodeInstruction(0x10694);
	inst.rtl->print(o2);
	expected = std::string("00010694\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));

	std::ostringstream o3;
	inst = pFE->decodeInstruction(0x10698);
	inst.rtl->print(o3);
	expected = std::string("00010698    0 *32* r8 := 0\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));

	std::ostringstream o4;
	inst = pFE->decodeInstruction(0x1069c);
	inst.rtl->print(o4);
	expected = std::string("0001069c    0 *32* r24 := r8\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o4.str()));

	delete pFE;
	// delete pBF;
}
Exemple #14
0
void FrontPentTest::testBranch()
{
    DecodeResult inst;
    std::string expected;

    BinaryFileFactory bff;
    BinaryFile *pBF = bff.Load(BRANCH_PENT);
    if (pBF == NULL)
        pBF = new BinaryFileStub();
    CPPUNIT_ASSERT(pBF != 0);
    CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM);
    Prog* prog = new Prog;
    FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
    prog->setFrontEnd(pFE);

    // jne
    std::ostringstream o1;
    inst = pFE->decodeInstruction(0x8048979);
    inst.rtl->print(o1);
    expected = std::string("08048979    0 BRANCH 0x8048988, condition "
                           "not equals\n"
                           "High level: %flags\n");
    CPPUNIT_ASSERT_EQUAL(expected, o1.str());

    // jg
    std::ostringstream o2;
    inst = pFE->decodeInstruction(0x80489c1);
    inst.rtl->print(o2);
    expected = std::string(
                   "080489c1    0 BRANCH 0x80489d5, condition signed greater\n"
                   "High level: %flags\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));

    // jbe
    std::ostringstream o3;
    inst = pFE->decodeInstruction(0x8048a1b);
    inst.rtl->print(o3);
    expected = std::string(
                   "08048a1b    0 BRANCH 0x8048a2a, condition unsigned less or equals\n"
                   "High level: %flags\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));

    delete pFE;
    // delete pBF;
}
Exemple #15
0
void FrontSparcTest::testBranch() {
	DecodeResult inst;
	std::string expected;

	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);

	// bne
	std::ostringstream o1;
	inst = pFE->decodeInstruction(0x10ab0);
	inst.rtl->print(o1);
	expected = std::string(
	  "00010ab0    0 BRANCH 0x10ac8, condition not equals\n"
	  "High level: %flags\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));

	// bg
	std::ostringstream o2;
	inst = pFE->decodeInstruction(0x10af8);
	inst.rtl->print(o2);
	expected = std::string("00010af8    0 BRANCH 0x10b10, condition "
	  "signed greater\n"
	  "High level: %flags\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));

	// bleu
	std::ostringstream o3;
	inst = pFE->decodeInstruction(0x10b44);
	inst.rtl->print(o3);
	expected = std::string(
		"00010b44    0 BRANCH 0x10b54, condition unsigned less or equals\n"
		"High level: %flags\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));

	delete pFE;
	// delete pBF;
}
Exemple #16
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;
}
Exemple #17
0
void FrontPentTest::test2()
{
    DecodeResult inst;
    std::string expected;

    BinaryFileFactory bff;
    BinaryFile *pBF = bff.Load(HELLO_PENT);
    if (pBF == NULL)
        pBF = new BinaryFileStub();
    CPPUNIT_ASSERT(pBF != 0);
    CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM);
    Prog* prog = new Prog;
    FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
    prog->setFrontEnd(pFE);

    std::ostringstream o1;
    inst = pFE->decodeInstruction(0x8048345);
    inst.rtl->print(o1);
    expected = std::string(
                   "08048345    0 *32* tmp1 := r28\n"
                   "            0 *32* r28 := r28 + 16\n"
                   "            0 *v* %flags := ADDFLAGS32( tmp1, 16, r28 )\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));

    std::ostringstream o2;
    inst = pFE->decodeInstruction(0x8048348);
    inst.rtl->print(o2);
    expected = std::string(
                   "08048348    0 *32* r24 := 0\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));

    std::ostringstream o3;
    inst = pFE->decodeInstruction(0x8048329);
    inst.rtl->print(o3);
    expected = std::string("08048329    0 *32* r29 := r28\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));

    delete pFE;
    // delete pBF;
}
Exemple #18
0
void FrontPentTest::test3()
{
    DecodeResult inst;
    std::string expected;

    BinaryFileFactory bff;
    BinaryFile *pBF = bff.Load(HELLO_PENT);
    if (pBF == NULL)
        pBF = new BinaryFileStub();
    CPPUNIT_ASSERT(pBF != 0);
    CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM);
    Prog* prog = new Prog;
    FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff);
    prog->setFrontEnd(pFE);

    std::ostringstream o1;
    inst = pFE->decodeInstruction(0x804834d);
    inst.rtl->print(o1);
    expected = std::string(
                   "0804834d    0 *32* r28 := r29\n"
                   "            0 *32* r29 := m[r28]\n"
                   "            0 *32* r28 := r28 + 4\n");
    CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));

    std::ostringstream o2;
    inst = pFE->decodeInstruction(0x804834e);
    inst.rtl->print(o2);
    expected = std::string(
                   "0804834e    0 *32* %pc := m[r28]\n"
                   "            0 *32* r28 := r28 + 4\n"
                   "            0 RET\n"
                   "              Modifieds: \n"
                   "              Reaching definitions: \n");

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

    delete pFE;
    // delete pBF;
}
Exemple #19
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;
}
Exemple #20
0
/*==============================================================================
 * FUNCTION:        LoaderTest::testHppaLoad
 * OVERVIEW:        Test loading the sparc hello world program
 *============================================================================*/
void LoaderTest::testHppaLoad ()
{
    std::ostringstream ost;

    // Load HPPA hello world
    BinaryFileFactory bff;
    BinaryFile* pBF = bff.Load(HELLO_HPPA);
    CPPUNIT_ASSERT(pBF != NULL);
    int n;
    SectionInfo* si;
    n = pBF->GetNumSections();
    ost << "Number of sections = " << std::dec << n << "\r\n";
    for (int i=0; i < n; i++)
        {
            si = pBF->GetSectionInfo(i);
            ost << si->pSectionName << "\t";
        }
    pBF->UnLoad();
    // Note: the string below needs to have embedded tabs. Edit with caution!
    std::string expected("Number of sections = 4\r\n"
                         "$HEADER$	$TEXT$	$DATA$	$BSS$	");
    CPPUNIT_ASSERT_EQUAL(expected, ost.str());
    bff.UnLoad();
}
Exemple #21
0
/*==============================================================================
 * FUNCTION:        LoaderTest::testSparcLoad
 * OVERVIEW:        Test loading the sparc hello world program
 *============================================================================*/
void LoaderTest::testSparcLoad ()
{
    std::ostringstream ost;

    // Load SPARC hello world
    BinaryFileFactory bff;
    BinaryFile* pBF = bff.Load(HELLO_SPARC);
    CPPUNIT_ASSERT(pBF != NULL);
    int n;
    SectionInfo* si;
    n = pBF->GetNumSections();
    ost << "Number of sections = " << std::dec << n << "\r\n\t";
    // Just use the first (real one) and last sections
    si = pBF->GetSectionInfo(1);
    ost << si->pSectionName << "\t";
    si = pBF->GetSectionInfo(n-1);
    ost << si->pSectionName;
    pBF->UnLoad();
    // Note: the string below needs to have embedded tabs. Edit with caution!
    std::string expected("Number of sections = 29\r\n\t"
                         ".interp	.stab.indexstr");
    CPPUNIT_ASSERT_EQUAL(expected, ost.str());
    bff.UnLoad();
}
Exemple #22
0
/*==============================================================================
 * FUNCTION:        LoaderTest::testWinLoad
 * OVERVIEW:        Test loading Windows programs
 *============================================================================*/
void LoaderTest::testWinLoad ()
{
    std::ostringstream ost;

#if 0 /* FIXME: these tests should use non-proprietary programs */
    // Load Windows program calc.exe
    BinaryFileFactory bff;
    BinaryFile* pBF = bff.Load(CALC_WINDOWS);
    CPPUNIT_ASSERT(pBF != NULL);
    int n;
    SectionInfo* si;
    n = pBF->GetNumSections();
    ost << "Number of sections = " << std::dec << n << "\r\n";
    for (int i=0; i < n; i++)
        {
            si = pBF->GetSectionInfo(i);
            ost << si->pSectionName << "\t";
        }

    // Note: the string below needs to have embedded tabs. Edit with caution!
    std::string expected("Number of sections = 5\r\n"
                         ".text	.rdata	.data	.rsrc	.reloc	");
    std::string actual(ost.str());
    CPPUNIT_ASSERT_EQUAL(expected, actual);

    ADDRESS addr = pBF->GetMainEntryPoint();
    CPPUNIT_ASSERT(addr != NO_ADDRESS);

    // Test symbol table (imports)
    const char* s = pBF->SymbolByAddress(0x1292060U);
    if (s == 0)
        actual = "<not found>";
    else
        actual = std::string(s);
    expected = std::string("SetEvent");
    CPPUNIT_ASSERT_EQUAL(expected, actual);

    ADDRESS a = pBF->GetAddressByName("SetEvent");
    ADDRESS expectedAddr = 0x1292060;
    CPPUNIT_ASSERT_EQUAL(expectedAddr, a);
    pBF->UnLoad();
    bff.UnLoad();

    // Test loading the "new style" exes, as found in winXP etc
    pBF = bff.Load(CALC_WINXP);
    CPPUNIT_ASSERT(pBF != NULL);
    addr = pBF->GetMainEntryPoint();
    std::ostringstream ost1;
    ost1 << std::hex << addr;
    actual = ost1.str();
    expected = "1001f51";
    CPPUNIT_ASSERT_EQUAL(expected, actual);
    pBF->UnLoad();
    bff.UnLoad();

    // Test loading the calc.exe found in Windows 2000 (more NT based)
    pBF = bff.Load(CALC_WIN2000);
    CPPUNIT_ASSERT(pBF != NULL);
    expected = "1001680";
    addr = pBF->GetMainEntryPoint();
    std::ostringstream ost2;
    ost2 << std::hex << addr;
    actual = ost2.str();
    CPPUNIT_ASSERT_EQUAL(expected, actual);
    pBF->UnLoad();
    bff.UnLoad();

    // Test loading the lpq.exe program - console mode PE file
    pBF = bff.Load(LPQ_WINDOWS);
    CPPUNIT_ASSERT(pBF != NULL);
    addr = pBF->GetMainEntryPoint();
    std::ostringstream ost3;
    ost3 << std::hex << addr;
    actual = ost3.str();
    expected = "18c1000";
    CPPUNIT_ASSERT_EQUAL(expected, actual);
    pBF->UnLoad();
    bff.UnLoad();
#endif

    // Borland
    BinaryFileFactory bff;
    BinaryFile* pBF = bff.Load(SWITCH_BORLAND);
    CPPUNIT_ASSERT(pBF != NULL);
    ADDRESS addr = pBF->GetMainEntryPoint();
    std::ostringstream ost4;
    ost4 << std::hex << addr;
    std::string actual(ost4.str());
    std::string expected("401150");
    CPPUNIT_ASSERT_EQUAL(expected, actual);
    pBF->UnLoad();
    bff.UnLoad();
}
Exemple #23
0
/*==============================================================================
 * FUNCTION:		FrontSparcTest::test1
 * OVERVIEW:		Test decoding some sparc instructions
 *============================================================================*/
void FrontSparcTest::test1 () {
	std::ostringstream ost;

	BinaryFileFactory bff;
	BinaryFile *pBF = bff.Load(HELLO_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);

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

	// Decode first instruction
	DecodeResult inst = pFE->decodeInstruction(addr);
	CPPUNIT_ASSERT(inst.rtl != NULL);
	inst.rtl->print(ost);
	
	std::string expected(
		"00010684    0 *32* tmp := r14 - 112\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");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(ost.str()));

	std::ostringstream o2;
	addr += inst.numBytes;
	inst = pFE->decodeInstruction(addr);
	inst.rtl->print(o2);
	expected = std::string("00010688    0 *32* r8 := 0x10400\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));

	std::ostringstream o3;
	addr += inst.numBytes;
	inst = pFE->decodeInstruction(addr);
	inst.rtl->print(o3);
	expected = std::string("0001068c    0 *32* r8 := r8 | 848\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));

	delete pFE;
	//delete pBF;
}
Exemple #24
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;
}
Exemple #25
0
void FrontSparcTest::test3() {
	DecodeResult inst;
	std::string expected;

	BinaryFileFactory bff;
	BinaryFile *pBF = bff.Load(HELLO_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);

	std::ostringstream o1;
	inst = pFE->decodeInstruction(0x106a0);
	inst.rtl->print(o1);
	expected = std::string("000106a0\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));

	std::ostringstream o2;
	inst = pFE->decodeInstruction(0x106a4);
	inst.rtl->print(o2);
	expected = std::string("000106a4    0 RET\n"
		"              Modifieds: \n"
		"              Reaching definitions: \n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));

	std::ostringstream o3;
	inst = pFE->decodeInstruction(0x106a8);
	inst.rtl->print(o3);
	expected = std::string(
		"000106a8    0 *32* tmp := 0\n"
		"            0 *32* r8 := r24\n"
		"            0 *32* r9 := r25\n"
		"            0 *32* r10 := r26\n"
		"            0 *32* r11 := r27\n"
		"            0 *32* r12 := r28\n"
		"            0 *32* r13 := r29\n"
		"            0 *32* r14 := r30\n"
		"            0 *32* r15 := r31\n"
		"            0 *32* r0 := tmp\n"
		"            0 *32* r16 := m[r14]\n"
		"            0 *32* r17 := m[r14 + 4]\n"
		"            0 *32* r18 := m[r14 + 8]\n"
		"            0 *32* r19 := m[r14 + 12]\n"
		"            0 *32* r20 := m[r14 + 16]\n"
		"            0 *32* r21 := m[r14 + 20]\n"
		"            0 *32* r22 := m[r14 + 24]\n"
		"            0 *32* r23 := m[r14 + 28]\n"
		"            0 *32* r24 := m[r14 + 32]\n"
		"            0 *32* r25 := m[r14 + 36]\n"
		"            0 *32* r26 := m[r14 + 40]\n"
		"            0 *32* r27 := m[r14 + 44]\n"
		"            0 *32* r28 := m[r14 + 48]\n"
		"            0 *32* r29 := m[r14 + 52]\n"
		"            0 *32* r30 := m[r14 + 56]\n"
		"            0 *32* r31 := m[r14 + 60]\n"
		"            0 *32* r0 := tmp\n");
	CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));

	delete pFE;
	// delete pBF;
}
Exemple #26
0
int main(int argc, char* argv[])
{
    // Usage

    if (argc != 2) {
        printf ("Usage: %s <filename>\n", argv[0]);
        printf ("%s dumps the contents of the given executable file\n", argv[0]); 
        return 1;
    }

    // Load the file

    BinaryFile *pbf = NULL;
    BinaryFileFactory bff; 
    pbf = bff.Load(argv[1]);

    if (pbf == NULL) {
	return 2;
    }

    // Display program and section information
    // If the DisplayDetails() function has not been implemented 
    // in the derived class (ElfBinaryFile in this case), then 
    // uncomment the commented code below to display section information.

    pbf->DisplayDetails (argv[0]); 

    // This is an alternative way of displaying binary-file information
    // by using individual sections.  The above approach is more general. 
    /*
    printf ("%d sections:\n", pbf->GetNumSections());
    for (int i=0; i < pbf->GetNumSections(); i++) 
    {
        SectionInfo* pSect = pbf->GetSectionInfo(i);
        printf("  Section %s at %X\n", pSect->pSectionName, pSect->uNativeAddr);
    }
    printf("\n");
    */

    // Display the code section in raw hexadecimal notation
    // Note: this is traditionally the ".text" section in Elf binaries.
    // In the case of Prc files (Palm), the code section is named "code0". 

    for (int i=0; i < pbf->GetNumSections(); i++) {
        SectionInfo* pSect = pbf->GetSectionInfo(i);
        if (pSect->bCode) {
            printf("  Code section:\n");
            ADDRESS a = pSect->uNativeAddr;
            unsigned char* p = (unsigned char*) pSect->uHostAddr;
            for (unsigned off = 0; off < pSect->uSectionSize; ) {
                printf("%04X: ", a);
                for (int j=0; (j < 16) && (off < pSect->uSectionSize); j++) {
                    printf("%02X ", *p++);
                    a++;
                    off++;
                }
                printf("\n");
            }
            printf("\n");
        }
    }

    // Display the data section(s) in raw hexadecimal notation

    for (int i=0; i < pbf->GetNumSections(); i++) {
        SectionInfo* pSect = pbf->GetSectionInfo(i);
        if (pSect->bData) {
            printf("  Data section: %s\n", pSect->pSectionName);
            ADDRESS a = pSect->uNativeAddr;
            unsigned char* p = (unsigned char*) pSect->uHostAddr;
            for (unsigned off = 0; off < pSect->uSectionSize; ) {
                printf("%04X: ", a);
                for (int j=0; (j < 16) && (off < pSect->uSectionSize); j++) {
                    printf("%02X ", *p++);
                    a++;
                    off++;
                }
                printf("\n");
            }
            printf("\n");
        }
    }

    pbf->UnLoad();
    return 0;
}