Exemplo n.º 1
0
/**
 * Build an inverted CFG for doing post-dominator analysis.  Running
 * the dominator analysis on this code will actually produce post-dominators
 **/
void dominatorBB::postDominatorPredAndSucc() {
   unsigned i;

   if (!bpatchBlock)
      return;

   //Predecessors
   BPatch_Vector<BPatch_basicBlock*> blocks;
   bpatchBlock->getTargets(blocks);
   for (i=0; i<blocks.size(); i++)
   {
      dominatorBB *p = dom_cfg->bpatchToDomBB(blocks[i]);
      assert(p);
      pred.push_back(p);
   }

   if (bpatchBlock->isExitBlock() || !blocks.size()) {
      dom_cfg->entryBlock->succ.push_back(this);
      pred.push_back(dom_cfg->entryBlock);
   }

   //Successors
   blocks.clear();
   bpatchBlock->getSources(blocks);
   for (i=0; i<blocks.size(); i++)
   {
      dominatorBB *s = dom_cfg->bpatchToDomBB(blocks[i]);
      assert(s);
      succ.push_back(s);
   }
}
Exemplo n.º 2
0
ostream& operator<<(ostream& os,BPatch_basicBlock& bb)
{
  unsigned i;
  os << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
  os << "Basic Block : " << bb.blockNo() <<" : [ ";
  os << ostream::hex << bb.getStartAddress() << " , ";
  os << ostream::hex << bb.getLastInsnAddress() << " | ";
  os << ostream::dec << bb.getEndAddress() - bb.getStartAddress() << " ]\n";

  if(bb.isEntryBlock())
    os <<"Type : ENTRY TO CFG\n";
  else if(bb.isExitBlock())
    os <<"Type : EXIT FROM CFG\n";

  cout << "Pred :\n";
  BPatch_Vector<BPatch_basicBlock *> elements;
  bb.getSources(elements);
  for (i=0; i<elements.size(); i++)
    os << "\t<- " << elements[i]->blockNo() << "\n";

  cout << "Succ:\n";
  elements.clear();
  bb.getTargets(elements);
  for (i=0; i<elements.size(); i++)
    os << "\t-> " << elements[i]->blockNo() << "\n";

  os << "Immediate Dominates: ";
  if(bb.immediateDominates){
     for (std::set<BPatch_basicBlock *>::iterator iter = bb.immediateDominates->begin();
          iter != bb.immediateDominates->end(); ++iter) {
        os << (*iter)->blockNo() << " ";
     }
  }
  os << "\n";

  os << "Immediate Dominator: ";
  if(!bb.immediateDominator)
    os << "None\n";
  else
    os << bb.immediateDominator->blockNo() << "\n";

  os << "\n";
  os << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
  return os;
}
Exemplo n.º 3
0
// static bool mutatorTest3and4(int testno, const char *testname)
test_results_t test_thread_2_Mutator::executeTest() {
  test3_threadCreateCounter = 0;
  callback_tids.clear();

  BPatchAsyncThreadEventCallback createcb = threadCreateCB;
  if (!bpatch->registerThreadEventCallback(BPatch_threadCreateEvent, createcb))
  {
    FAIL_MES(TESTNAME, TESTDESC);
    logerror("%s[%d]:  failed to register thread callback\n",
	     __FILE__, __LINE__);
    appThread->getProcess()->terminateExecution();
    return FAILED;
  }

#if 0
  //  unset mutateeIde to trigger thread (10) spawn.
  int zero = 0;
  // FIXME Check the return code for setVar
  setVar("mutateeIdle", (void *) &zero, TESTNO, TESTDESC);
  dprintf("%s[%d]:  continue execution for test %d\n", __FILE__, __LINE__, TESTNO);
  appThread->continueExecution();
#endif

  if( !appProc->continueExecution() ) {
      logerror("%s[%d]: failed to continue process\n", FILE__, __LINE__);
      appProc->terminateExecution();
      return FAILED;
  }

  //  wait until we have received the desired number of events

  int err = 0;
  BPatch_Vector<BPatch_thread *> threads;
  BPatch_process *appProc = appThread->getProcess();
  assert(appProc);
  appProc->getThreads(threads);
  int active_threads = 11; // FIXME Magic number
  threads.clear();
  while (((test3_threadCreateCounter < TEST3_THREADS)
         || (active_threads > 1)) && !appProc->isTerminated() ) {
    dprintf("%s[%d]: waiting for completion for test; ((%d < %d) || (%d > 1)) && !(%d)\n",
	    __FILE__, __LINE__, test3_threadCreateCounter, TEST3_THREADS,
	    active_threads, 1, appProc->isTerminated());
    if( !bpatch->waitForStatusChange() ) {
        logerror("%s[%d]: failed to wait for events\n", __FILE__, __LINE__);
        err = 1;
        break;
    }

    appProc->getThreads(threads);
    active_threads = threads.size();
    threads.clear();
  }

  if( appProc->isTerminated() ) {
      logerror("%s[%d]:  BAD NEWS:  somehow the process died\n", __FILE__, __LINE__);
      return FAILED;
  }

  dprintf("%s[%d]: ending test %d, num active threads = %d\n",
            __FILE__, __LINE__, TESTNO, active_threads);
  dprintf("%s[%d]:  stop execution for test %d\n", __FILE__, __LINE__, TESTNO);
  appProc->stopExecution();

  //   read all tids from the mutatee and verify that we got them all
  unsigned long mutatee_tids[TEST3_THREADS];
  const char *threads_varname = "test3_threads";
  if (getVar(threads_varname, (void *) mutatee_tids,
	     (sizeof(unsigned long) * TEST3_THREADS),
	     TESTNO, TESTDESC)) {
    appProc->terminateExecution();
    return FAILED;
  }

  if (debugPrint()) {
    dprintf("%s[%d]:  read following tids for test%d from mutatee\n", __FILE__, __LINE__, TESTNO);

    for (unsigned int i = 0; i < TEST3_THREADS; ++i) {
       dprintf("\t%lu\n", mutatee_tids[i]);
    }
  }

  for (unsigned int i = 0; i < TEST3_THREADS; ++i) {
     bool found = false;
     for (unsigned int j = 0; j < callback_tids.size(); ++j) {
       if (callback_tids[j] == mutatee_tids[i]) {
         found = true;
         break;
       }
     }

    if (!found) {
      FAIL_MES(TESTNAME, TESTDESC);
      logerror("%s[%d]:  could not find record for tid %lu: have these:\n",
             __FILE__, __LINE__, mutatee_tids[i]);
       for (unsigned int j = 0; j < callback_tids.size(); ++j) {
          logerror("%lu\n", callback_tids[j]);
       }
      err = 1;
      break;
    }
  }

  dprintf("%s[%d]: removing thread callback\n", __FILE__, __LINE__);
  if (!bpatch->removeThreadEventCallback(BPatch_threadCreateEvent, createcb)) {
    FAIL_MES(TESTNAME, TESTDESC);
    logerror("%s[%d]:  failed to remove thread callback\n",
           __FILE__, __LINE__);
    err = 1;
  }

  if (!err)  {
    logerror("No error reported, terminating process and returning success\n");
    PASS_MES(TESTNAME, TESTDESC);
    appProc->terminateExecution();
    logerror("\t Process terminated\n");
    return PASSED;
  }
  appProc->terminateExecution();
  return FAILED;
}
Exemplo n.º 4
0
//
// Start Test Case #3 - (overload operator)
//      
// static int mutatorTest(BPatch_thread *appThread, BPatch_image *appImage)
test_results_t test5_3_Mutator::executeTest() {

  BPatch_Vector<BPatch_function *> bpfv;
  const char *fn = "overload_op_test::func_cpp";
  if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #3 (overloaded operation)\n");
    logerror("    Unable to find function %s\n", fn);
    return FAILED;
  }
  BPatch_function *f1 = bpfv[0];  
  BPatch_Vector<BPatch_point *> *point3_1 = f1->findPoint(BPatch_subroutine);

  assert(point3_1);
  if (point3_1->size() == 0) {
    logerror("**Failed test5_3 (overload operation)\n");
    logerror("    Can't find overloaded operator call points\n");
    return FAILED;
  }

  unsigned int index = 0;
  char fn3[256];
  BPatch_function *func;
  while (index < point3_1->size()) {
     if ((func = (*point3_1)[index]->getCalledFunction()) != NULL &&
         !strcmp("overload_op_test::operator++", func->getName(fn3, 256)))
     {
        break;
     }
     index ++;
  }
  if(!func) {
    logerror("**Failed** test #3 (overload operation)\n");
    logerror("    Can't find the overload operator\n");
    return FAILED;
  }

  if (0 != strcmp("overload_op_test::operator++", func->getName(fn3, 256))) {
    logerror("**Failed** test #3 (overload operation)\n");
    logerror("    Can't find the overloaded operator\n");
    return FAILED;
  }
  // FIXME It caught fprintf...

  BPatch_Vector<BPatch_point *> *point3_2 = func->findPoint(BPatch_exit);
  assert(point3_2);
  
  bpfv.clear();
  const char *fn2 = "overload_op_test::call_cpp";
  if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #3 (overloaded operation)\n");
    logerror("    Unable to find function %s\n", fn2);
    return FAILED;
  }
  BPatch_function *call3_1 = bpfv[0];  
  
  BPatch_variableExpr *this2 = appImage->findVariable("test5_3_test3");
  if (this2 == NULL) {
    logerror( "**Failed** test #3 (overloaded operation)\n");
    logerror( "Unable to find variable \"test5_3_test3\"\n");
    return FAILED;
  }

  BPatch_Vector<BPatch_snippet *> opArgs;
  BPatch_arithExpr expr2_0(BPatch_addr, *this2);
  opArgs.push_back(&expr2_0);
  opArgs.push_back(new BPatch_retExpr());
  BPatch_funcCallExpr call3_1Expr(*call3_1, opArgs);
  
  checkCost(call3_1Expr);
  appAddrSpace->insertSnippet(call3_1Expr, *point3_2);
  //  int tag = 1;
  //  while (tag != 0) {}
  
  return PASSED;
}
Exemplo n.º 5
0
test_results_t test1_19_Mutator::executeTest() 
{
    // Avoid a race condition in fast & loose mode

    while (!appProc->isStopped())
	{
		BPatch::bpatch->waitForStatusChange();
    }

    appProc->continueExecution();

    if (waitUntilStopped(BPatch::bpatch, appProc, 19, "oneTimeCode") < 0)
	{
      return FAILED;
    }

    BPatch_Vector<BPatch_function *> bpfv;
    const char *fn = "test1_19_call1";

    if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
	|| NULL == bpfv[0])
	{
      logerror("    Unable to find function %s\n", fn);
      return FAILED;
    }

    BPatch_function *call19_1_func = bpfv[0];

    BPatch_Vector<BPatch_snippet *> nullArgs;
    BPatch_funcCallExpr call19_1Expr(*call19_1_func, nullArgs);
    checkCost(call19_1Expr);

    appProc->oneTimeCode(call19_1Expr);

    // Let the mutatee run to check the result
    appProc->continueExecution();

    // Wait for the next test

    if (waitUntilStopped(BPatch::bpatch, appProc, 19, "oneTimeCode") < 0)
	{
      return FAILED;
    }

    bpfv.clear();
    const char *fn2 = "test1_19_call2";

    if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
	|| NULL == bpfv[0])
	{
      logerror("    Unable to find function %s\n", fn2);
      return FAILED;
    }

    BPatch_function *call19_2_func = bpfv[0];

    BPatch_funcCallExpr call19_2Expr(*call19_2_func, nullArgs);
    checkCost(call19_2Expr);

    int callbackFlag = 0;

    // Register a callback that will set the flag callbackFlag
    BPatchOneTimeCodeCallback oldCallback = 
       BPatch::bpatch->registerOneTimeCodeCallback(test19_oneTimeCodeCallback);

    appProc->oneTimeCodeAsync(call19_2Expr, (void *)&callbackFlag);

    while (!appProc->isTerminated() && !appProc->isStopped() )
    {
		BPatch::bpatch->waitForStatusChange();
    }
    
    // Continue mutatee after one-time code runs
    appProc->continueExecution();

    // Wait for the callback to be called
    while (!appProc->isTerminated() && !callbackFlag) {
        if( !BPatch::bpatch->waitForStatusChange() ) {
            logerror("   FAILED: could not wait for callback to be called\n");
            return FAILED;
        }
    }

    if( !callbackFlag ) {
        logerror("     FAILED: process %d terminated while waiting for async oneTimeCode\n",
                appProc->getPid());
        return FAILED;
    }

    // After the oneTimeCode is completed, there could be a crash due to bugs in
    // the RPC code, wait for termination
    while( !appProc->isTerminated() ) {
        if( !BPatch::bpatch->waitForStatusChange() ) {
            logerror("   FAILED: could not wait for process to terminate\n");
            return FAILED;
        }
    }

    // Restore old callback (if there was one)
	BPatch::bpatch->registerOneTimeCodeCallback(oldCallback);

    return PASSED;
} // test1_19_Mutator::executeTest()
Exemplo n.º 6
0
// static bool mutatorTest3and4(int testno, const char *testname)
test_results_t test_thread_3_Mutator::executeTest() {
  test3_threadCreateCounter = 0;
  callback_tids.clear();

  unsigned int timeout = 0; // in ms
  int err = 0;

  BPatchAsyncThreadEventCallback createcb = threadCreateCB;
  if (!bpatch->registerThreadEventCallback(BPatch_threadCreateEvent, createcb))
  {
    FAIL_MES(TESTNAME, TESTDESC);
    logerror("%s[%d]:  failed to register thread callback\n",
           __FILE__, __LINE__);
    appThread->getProcess()->terminateExecution();
    return FAILED;
  }

#if 0
  //  unset mutateeIde to trigger thread (10) spawn.
  int zero = 0;
  // FIXME Check the return value of setVar()
  setVar("mutateeIdle", (void *) &zero, TESTNO, TESTDESC);
  dprintf("%s[%d]:  continue execution for test %d\n", __FILE__, __LINE__, TESTNO);
  appThread->continueExecution();
#endif

  //  wait until we have received the desired number of events
  //  (or timeout happens)

  BPatch_Vector<BPatch_thread *> threads;
  BPatch_process *appProc = appThread->getProcess();
  assert(appProc);
  appProc->getThreads(threads);
  int active_threads = 11; // FIXME Magic number
  threads.clear();
  while (((test3_threadCreateCounter < TEST3_THREADS)
         || (active_threads > 1))
         && (timeout < TIMEOUT)) {
    dprintf("%s[%d]: waiting for completion for test %d, num active threads = %d\n",
            __FILE__, __LINE__, TESTNO, active_threads);
    sleep_ms(SLEEP_INTERVAL/*ms*/);
    timeout += SLEEP_INTERVAL;
    if (appProc->isTerminated()) {
       dprintf("%s[%d]:  BAD NEWS:  somehow the process died\n", __FILE__, __LINE__);
       err = 1;
       break;
    }
    bpatch->pollForStatusChange();
    if (appProc->isStopped()) {
        appProc->continueExecution();
    }
    appProc->getThreads(threads);
    active_threads = threads.size();
    threads.clear();
  }

  if (timeout >= TIMEOUT) {
    FAIL_MES(TESTNAME, TESTDESC);
    logerror("%s[%d]:  test timed out. got %d/10 events\n", __FILE__, __LINE__, test3_threadCreateCounter);
    logerror("test3_createCounter is %d, expected %d; active threads %d, expected %d\n",
            test3_threadCreateCounter, TEST3_THREADS, active_threads, 1);
    err = 1;
  }

  dprintf("%s[%d]: ending test %d, num active threads = %d\n",
            __FILE__, __LINE__, TESTNO, active_threads);
  dprintf("%s[%d]:  stop execution for test %d\n", __FILE__, __LINE__, TESTNO);
  appProc->stopExecution();

  //   read all tids from the mutatee and verify that we got them all
  unsigned long mutatee_tids[TEST3_THREADS];
  const char *threads_varname = "test4_threads";
  getVar(threads_varname, (void *) mutatee_tids,
         (sizeof(unsigned long) * TEST3_THREADS),
         TESTNO, TESTDESC);

  if (debugPrint()) {
    dprintf("%s[%d]:  read following tids for test%d from mutatee\n", __FILE__, __LINE__, TESTNO);

    for (unsigned int i = 0; i < TEST3_THREADS; ++i) {
       dprintf("\t%lu\n", mutatee_tids[i]);
    }
  }

  for (unsigned int i = 0; i < TEST3_THREADS; ++i) {
     bool found = false;
     for (unsigned int j = 0; j < callback_tids.size(); ++j) {
       if (callback_tids[j] == mutatee_tids[i]) {
         found = true;
         break;
       }
     }

    if (!found) {
      FAIL_MES(TESTNAME, TESTDESC);
      logerror("%s[%d]:  could not find record for tid %lu: have these:\n",
             __FILE__, __LINE__, mutatee_tids[i]);
       for (unsigned int j = 0; j < callback_tids.size(); ++j) {
          logerror("%lu\n", callback_tids[j]);
       }
      err = true;
      break;
    }
  }

  dprintf("%s[%d]: removing thread callback\n", __FILE__, __LINE__);
  if (!bpatch->removeThreadEventCallback(BPatch_threadCreateEvent, createcb)) {
    FAIL_MES(TESTNAME, TESTDESC);
    logerror("%s[%d]:  failed to remove thread callback\n",
           __FILE__, __LINE__);
    err = true;
  }

  if (!err)  {
    PASS_MES(TESTNAME, TESTDESC);
    appProc->terminateExecution();
    return PASSED;
  }
  appProc->terminateExecution();
  return FAILED;
}
Exemplo n.º 7
0
void execFunc(BPatch_thread *thread)
{
  BPatch_Vector<BPatch_function *> bpfv;

    if (inTest == 1 || inTest == 2) {
	printf("**Failed Test #%d\n", inTest);
	printf("    execCallback invoked, but exec was not called!\n");
    } else if (inTest == 3) {
	dprintf("in exec callback for %d\n", thread->getPid());

	// insert code into parent
	BPatch_Vector<BPatch_snippet *> nullArgs;
        BPatch_image *appImage = thread->getImage();
        assert(appImage);

	char *fn = "func3_2";
	if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
	    || NULL == bpfv[0]){
	  fprintf(stderr, "    Unable to find function %s\n",fn);
	  exit(1);
	}

        BPatch_function *func3_2_parent = bpfv[0];
        BPatch_funcCallExpr callExpr(*func3_2_parent, nullArgs);

	bpfv.clear();
	char *fn2 = "func3_1";
	if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
	    || NULL == bpfv[0]){
	  fprintf(stderr, "    Unable to find function %s\n",fn2);
	  exit(1);
	}

	BPatch_function *func3_1_parent = bpfv[0];
	BPatch_Vector<BPatch_point *> *point = func3_1_parent->findPoint(BPatch_exit);

        assert(point);
        thread->insertSnippet(callExpr, *point);
	dprintf("%s[%d]:  MUTATEE: exec callback for %d, done with insert snippet\n", __FILE__, __LINE__, thread->getPid());
    } else if (inTest == 4) {
	dprintf("in exec callback for %d\n", thread->getPid());

        // insert code into child
	BPatch_Vector<BPatch_snippet *> nullArgs;
        BPatch_image *appImage = thread->getImage();
        assert(appImage);

	char *fn3 = "func4_4";
	if (NULL == appImage->findFunction(fn3, bpfv) || !bpfv.size()
	    || NULL == bpfv[0]){
	  fprintf(stderr, "    Unable to find function %s\n",fn3);
	  exit(1);
	}

	BPatch_function *func4_4_child = bpfv[0];
	BPatch_funcCallExpr callExpr1(*func4_4_child, nullArgs);
	
	bpfv.clear();
	char *fn4 = "func4_2";
	if (NULL == appImage->findFunction(fn4, bpfv) || !bpfv.size()
	    || NULL == bpfv[0]){
	  fprintf(stderr, "    Unable to find function %s\n",fn4);
	  exit(1);
	}

	BPatch_function *func4_2_child = bpfv[0];
	BPatch_Vector<BPatch_point *> *point1 = func4_2_child->findPoint(BPatch_exit);

	assert(point1);
        thread->insertSnippet(callExpr1, *point1);
    } else {
	printf("in exec callback for %d\n", thread->getPid());
    }
}
Exemplo n.º 8
0
void forkFunc(BPatch_thread *parent, BPatch_thread *child)
{
  dprintf("forkFunc called with parent %p, child %p\n", parent, child);
    BPatch_image *appImage;
    BPatch_Vector<BPatch_function *> bpfv;
    BPatch_Vector<BPatch_snippet *> nullArgs;

    if (child) mythreads[threadCount++] = child;

    if (!child) {
       dprintf("in prefork for %d\n", parent->getPid());
    } else {
       dprintf("in fork of %d to %d\n", parent->getPid(), child->getPid());
    }

    if (inTest == 1) {
       // nothing to do for this case
    } else if (inTest == 2) {
       if (!child) return;	// skip prefork case

       // Make a race condition always show up -- we don't run
       // until the processes have had a chance.
#if !defined(os_windows)
       sleep(1);
#endif
       // That'll make erroneous continues break...

       // insert code into parent
       appImage = parent->getImage();
       assert(appImage);

       char *fn = "func2_3";
       if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
	   || NULL == bpfv[0]){
	 fprintf(stderr, "    Unable to find function %s\n",fn);
	 exit(1);
       }

       BPatch_function *func2_3_parent = bpfv[0];
       BPatch_funcCallExpr callExpr2(*func2_3_parent, nullArgs);
 
       bpfv.clear();
       char *fn2 = "func2_2";
       if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
	   || NULL == bpfv[0]){
	 fprintf(stderr, "    Unable to find function %s\n",fn2);
	 exit(1);
       }

       BPatch_function *func2_2_parent = bpfv[0];
       BPatch_Vector<BPatch_point *> *point2 = func2_2_parent->findPoint(BPatch_exit);
       assert(point2);
       
       parent->insertSnippet(callExpr2, *point2);

       dprintf("MUTATEE:  after insert in fork of %d to %d\n", parent->getPid(), child->getPid());
       // insert different code into child
       appImage = child->getImage();
       assert(appImage);

       bpfv.clear();
       char *fn3 = "func2_4";
       if (NULL == appImage->findFunction(fn3, bpfv) || !bpfv.size()
	   || NULL == bpfv[0]){
	 fprintf(stderr, "    Unable to find function %s\n",fn3);
	 exit(1);
       }

       BPatch_function *func2_4_child = bpfv[0];
       BPatch_funcCallExpr callExpr1(*func2_4_child, nullArgs);

       bpfv.clear();
       char *fn4 = "func2_2";
       if (NULL == appImage->findFunction(fn4, bpfv) || !bpfv.size()
	   || NULL == bpfv[0]){
	 fprintf(stderr, "    Unable to find function %s\n",fn4);
	 exit(1);
       }

       BPatch_function *func2_2_child = bpfv[0];
       BPatch_Vector<BPatch_point *> *point1 = func2_2_child->findPoint(BPatch_exit);
       assert(point1);

       child->insertSnippet(callExpr1, *point1);

       dprintf("MUTATEE:  after insert2 in fork of %d to %d\n", parent->getPid(), child->getPid());
       test2Child = child;
       test2Parent = parent;
    } else if (inTest == 4) {
       if (!child) return;	// skip prefork case

       // insert code into parent
       appImage = parent->getImage();
       assert(appImage);

       char *fn5 = "func4_3";
       if (NULL == appImage->findFunction(fn5, bpfv) || !bpfv.size()
	   || NULL == bpfv[0]){
	 fprintf(stderr, "    Unable to find function %s\n",fn5);
	 exit(1);
       }

       BPatch_function *func4_3_parent = bpfv[0];
       BPatch_funcCallExpr callExpr2(*func4_3_parent, nullArgs);

       bpfv.clear();
       char *fn6 = "func4_2";
       if (NULL == appImage->findFunction(fn6, bpfv) || !bpfv.size()
	   || NULL == bpfv[0]){
	 fprintf(stderr, "    Unable to find function %s\n",fn6);
	 exit(1);
       }

       BPatch_function *func4_2_parent = bpfv[0];
       BPatch_Vector<BPatch_point *> *point2 = func4_2_parent->findPoint(BPatch_exit);
       assert(point2);
       parent->insertSnippet(callExpr2, *point2);

       // code goes into child after in-exec in this test.

       test4Child = child;
    }
}
Exemplo n.º 9
0
bool initTraceInMutatee(dynHandle *dh)
{
   // Chicken: Can't use goto for error handling because it would branch past
   // variable initialization.

   // Egg: Can't define variables at top of function (with dummy constructors)
   // because BPatch_funcCallExpr() needs a valid BPatch_function object.

   // Temporary solution: Deviate from similar functions and rely on external
   // error handling.

   // Permanent solution: BPatch_snippet and derivitives should have default
   // constructors.

   int value;
   BPatch_function *openFunc;
   BPatch_Vector< BPatch_function * > funcs;

   sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_TEST);
   if (!dh->image->findFunction("^(__)?open(64)?$", funcs)) {
      sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_FAIL,
              "Failure in BPatch_image::findFunction()");
      return false;

   } else if (funcs.size() == 0) {
      sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_FAIL,
              "Could not find any functions named 'open' in mutatee");
      return false;
   }
   sendMsg(config.outfd, ID_TRACE_FIND_OPEN, VERB2, ID_PASS);
   openFunc = funcs[0];

   //
   // Initialize global variables
   //
   trace_msglen = sizeof(void *) * 2;
   trace_fd = allocateIntegerInMutatee(dh, -1);
   funcs.clear();
   sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2);
   if (!dh->image->findFunction("^(__)?write$", funcs)) {
      sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2, ID_FAIL,
              "Failure in BPatch_image::findFunction()");
      return false;

   } else if (funcs.size() == 0) {
      sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2, ID_FAIL,
              "Could not find any functions named 'write' in mutatee");
      return false;
   }
   sendMsg(config.outfd, ID_TRACE_FIND_WRITE, VERB2, ID_PASS);
   trace_write = funcs[0];

   // "open(config.pipe_filename, O_WRONLY | O_DSYNC)"
   BPatch_constExpr path(config.pipe_filename);
   BPatch_constExpr flags(O_WRONLY | O_DSYNC);

   BPatch_Vector< BPatch_snippet * > param;
   param.push_back( &path );
   param.push_back( &flags );
   BPatch_funcCallExpr openCall(*openFunc, param); // Problem child. See above.

   // "fd = open(config.pipe_filename, O_WRONLY)"
   BPatch_arithExpr assign(BPatch_assign, *trace_fd, openCall);

   // Run the snippet.
   sendMsg(config.outfd, ID_TRACE_OPEN_WRITER, VERB2);
   dh->proc->oneTimeCode(assign);
   trace_fd->readValue(&value);
   if (value < 0) {
      sendMsg(config.outfd, ID_TRACE_OPEN_WRITER, VERB2, ID_FAIL,
              "Error detected in mutatee's call to open()");
      return false;
   }
   sendMsg(config.outfd, ID_TRACE_OPEN_WRITER, VERB2, ID_PASS);

   return true;
}
Exemplo n.º 10
0
//
// Start Test Case #9 - (derivation)
//
// static int mutatorTest(BPatch_thread *, BPatch_image *appImage)
test_results_t test5_9_Mutator::executeTest() {
   bool found = false;
   
  BPatch_Vector<BPatch_function *> bpfv;
  const char *fn = "derivation_test::func_cpp";
  if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #9 (derivation)\n");
    logerror("    Unable to find function %s\n", fn);
    return FAILED;
  }
  BPatch_function *f1 = bpfv[0];  
  BPatch_Vector<BPatch_point *> *point9_1 = f1->findPoint(BPatch_exit);
  if (!point9_1 || (point9_1->size() < 1)) {
    logerror("Unable to find point derivation_test::func_cpp - exit.\n");
    return FAILED;
  }
   
  bpfv.clear();
  const char *fn2 = "main";
  if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #9 (derivation)\n");
    logerror("    Unable to find function %s\n", fn2);
    return FAILED;
  }
  BPatch_function *f2 = bpfv[0];  
  BPatch_Vector<BPatch_point *> *point9_2 = f2->findPoint(BPatch_allLocations);
  if (!point9_2 || (point9_2->size() < 1)) {
    logerror("Unable to find point in main.\n");
    return FAILED;
  }

   BPatch_variableExpr *expr9_0=appImage->findVariable(*(*point9_2)[0], "test5_9_test9");
   if (!expr9_0) {
      logerror("**Failed** test #9 (derivation)\n");
      logerror("    Unable to locate one of variables\n");
      return FAILED;
   }

   BPatch_Vector<BPatch_variableExpr *> *fields = expr9_0->getComponents();
   if (!fields || fields->size() == 0 ) {
         logerror("**Failed** test #9 (derivation)\n");
         logerror("  struct lacked correct number of elements\n");
         return FAILED;
   }

   int index = 0;
   while ( index < fields->size() ) {
       if ( !strcmp("call_cpp", (*fields)[index]->getName()) ||
           !strcmp("cpp_test_util::call_cpp", (*fields)[index]->getName())) {
          found = true;
          break;
       }
       index ++;
   }
   
   if ( !found ) {
     logerror("**Failed** test #9 (derivation)\n");
     logerror("    Can't find inherited class member functions\n");
     logerror("    Expected call_cpp or cpp_test_util::call_cpp\n");
     index = 0;
     while ( index < fields->size() ) {
       logerror("    Field %d: %s\n", index, (*fields)[index]->getName());
       ++index;
     }
     return FAILED;
   }

   // TODO pass a success message to the mutatee
   const char *passfn = "test5_9_passed";
   BPatch_Vector<BPatch_function *> passfv;
   if ((NULL == appImage->findFunction(passfn, passfv))
       || (passfv.size() < 1) || (NULL == passfv[0])) {
     logerror("**Failed** test #9 (derivation)\n");
     logerror("    Can't find function %s\n", passfn);
     return FAILED;
   }
   BPatch_function *pass_func = passfv[0];
   BPatch_Vector<BPatch_snippet *> pass_args;
   BPatch_funcCallExpr pass_expr(*pass_func, pass_args);
   appAddrSpace->insertSnippet(pass_expr, *point9_1);
   
  return PASSED;
}
Exemplo n.º 11
0
test_results_t test1_33_Mutator::executeTest() 
{
	int pvalue;
	unsigned int i;

	if (isMutateeFortran(appImage)) 
	{
		return SKIPPED;
	}

	BPatch_Vector<BPatch_function *> bpfv;
	const char *fn = "test1_33_func2";
	if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
			|| NULL == bpfv[0])
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("    Unable to find function %s\n", fn);
		return FAILED;
	}

	BPatch_function *func2 = bpfv[0];

	BPatch_flowGraph *cfg = func2->getCFG();
	if (cfg == NULL) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Unable to get control flow graph of %s\n", fn);
		return FAILED;
	}

	/*
	 * Test for consistency of entry basic blocks.
	 */

	BPatch_Vector<BPatch_basicBlock*> entry_blocks;
	cfg->getEntryBasicBlock(entry_blocks);

	if (entry_blocks.size() != 1) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected %d entry basic blocks in %s, should have been one.\n", entry_blocks.size(), fn);
		return FAILED;
	}

	for (i = 0; i < entry_blocks.size(); i++) 
	{
		BPatch_Vector<BPatch_basicBlock*> sources;
		entry_blocks[i]->getSources(sources);

		if (sources.size() > 0) 
		{
			logerror("**Failed** test #33 (control flow graphs)\n");
			logerror("  An entry basic block has incoming edges in the control flow graph\n");
			return FAILED;
		}

		BPatch_Vector<BPatch_basicBlock*> targets;
		entry_blocks[i]->getTargets(targets);

		if (targets.size() < 1) 
		{
			logerror("**Failed** test #33 (control flow graphs\n");
			logerror("  An entry basic block has no outgoing edges in the control flow graph\n");
			return FAILED;
		}
	}

	/*
	 * Test for consistency of exit basic blocks.
	 */

	BPatch_Vector<BPatch_basicBlock*> exit_blocks;
	cfg->getExitBasicBlock(exit_blocks);

	if (exit_blocks.size() != 1) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected %d exit basic blocks in %s, should have been one.\n", exit_blocks.size(), fn);
		return FAILED;
	}

	for (i = 0; i < exit_blocks.size(); i++) 
	{
		BPatch_Vector<BPatch_basicBlock*> sources;
		exit_blocks[i]->getSources(sources);

		if (sources.size() < 1) 
		{
			logerror("**Failed** test #33 (control flow graphs)\n");
			logerror("  An exit basic block has no incoming edges in the control flow graph\n");
			return FAILED;
		}

		BPatch_Vector<BPatch_basicBlock*> targets;
		exit_blocks[i]->getTargets(targets);

		if (targets.size() > 0) 
		{
			logerror("**Failed** test #33 (control flow graphs)\n");
			logerror("  An exit basic block has outgoing edges in the control flow graph\n");
			return FAILED;
		}
	}

	/*
	 * Check structure of control flow graph.
	 */

        std::set<BPatch_basicBlock*> blocks;
	cfg->getAllBasicBlocks(blocks);

	if (blocks.size() < 4) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected %d basic blocks in %s, should be at least four.\n", blocks.size(), fn);
		return FAILED;
	}

	bool foundOutDegreeTwo = false;
	bool foundInDegreeTwo = false;
	int blocksNoIn = 0, blocksNoOut = 0;

        for (std::set<BPatch_basicBlock *>::iterator iter = blocks.begin();
             iter != blocks.end(); ++iter) {
           BPatch_Vector<BPatch_basicBlock*> in;
           BPatch_Vector<BPatch_basicBlock*> out;
           
           (*iter)->getSources(in);
           (*iter)->getTargets(out);
           
           if (in.size() == 0)
              blocksNoIn++;
           
           if (out.size() == 0)
              blocksNoOut++;
           
           if (in.size() > 2 || out.size() > 2) 
           {
              logerror("**Failed** test #33 (control flow graphs)\n");
              logerror("  Detected a basic block in %s with %d incoming edges and %d\n", fn, in.size(), out.size());
              logerror("  outgoing edges - neither should be greater than two.\n");
              return FAILED;
           } 
           else if (in.size() > 1 && out.size() > 1) 
           {
              logerror("**Failed** test #33 (control flow graphs)\n");
              logerror("  Detected a basic block in %s with %d incoming edges and %d\n", fn, in.size(), out.size());
              logerror("  outgoing edges - only one should be greater than one.\n");
              return FAILED;
           } 
           else if (in.size() == 0 && out.size() == 0) 
           {
              logerror("**Failed** test #33 (control flow graphs)\n");
              logerror("  Detected a basic block in %s with no incoming or outgoing edges.\n", fn);
              return FAILED;
           } 
           else if (in.size() == 2) 
           {
              assert(out.size() <= 1);
              
              if (foundInDegreeTwo) 
              {
                 logerror("**Failed** test #33 (control flow graphs)\n");
                 logerror("  Detected two basic blocks in %s with in degree two, there should only\n", fn);
                 logerror("  be one.\n");
                 return FAILED;
              }
              foundInDegreeTwo = true;
              
              if (in[0]->getBlockNumber() == in[1]->getBlockNumber()) 
              {
                 logerror("**Failed** test #33 (control flow graphs)\n");
                 logerror("  Two edges go to the same block (number %d).\n", in[0]->getBlockNumber());
                 return FAILED;
              }
           } 
           else if (out.size() == 2) 
           {
              assert(in.size() <= 1);
              
              if (foundOutDegreeTwo) 
              {
                 logerror("**Failed** test #33 (control flow graphs)\n");
                 logerror("  Detected two basic blocks in %s with out degree two, there should only\n", fn);
                 logerror("  be one.\n");
                 return FAILED;
              }
              foundOutDegreeTwo = true;
              
              if (out[0]->getBlockNumber() == out[1]->getBlockNumber()) 
              {
                 logerror("**Failed** test #33 (control flow graphs)\n");
                 logerror("  Two edges go to the same block (number %d).\n", out[0]->getBlockNumber());
                 return FAILED;
              }
           } 
           else if (in.size() > 1 || out.size() > 1) 
           {
              /* Shouldn't be able to get here. */
              logerror("**Failed** test #33 (control flow graphs)\n");
              logerror("  Detected a basic block in %s with %d incoming edges and %d\n", fn, in.size(), out.size());
              logerror("  outgoing edges.\n");
              return FAILED;
           }
	}
        
	if (blocksNoIn > 1) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected more than one block in %s with no incoming edges.\n", fn);
		return FAILED;
	}

	if (blocksNoOut > 1) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected more than block in %s with no outgoing edges.\n", fn);
		return FAILED;
	}

	if (!foundOutDegreeTwo) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Did not detect the \"if\" statement in %s.\n", fn);
		return FAILED;
	}

	/*
	 * Check for loops (there aren't any in the function we're looking at).
	 */

	std::set<int> empty;

	if (hasBackEdge(entry_blocks[0], empty)) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected a loop in %s, there should not be one.\n", fn);
		return FAILED;
	}

	/*
	 * Now check a function with a switch statement.
	 */
	bpfv.clear();
	const char *fn2 = "test1_33_func3";

	// Bernat, 8JUN05 -- include uninstrumentable here...

	if (NULL == appImage->findFunction(fn2, bpfv, false, false, true) || !bpfv.size()
			|| NULL == bpfv[0])
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("    Unable to find function %s\n", fn2);
		return FAILED;
	}

	BPatch_function *func3 = bpfv[0];
	BPatch_flowGraph *cfg3 = func3->getCFG();

	if (cfg3 == NULL) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Unable to get control flow graph of %s\n", fn2);
		return FAILED;
	}

        std::set<BPatch_basicBlock*> blocks3;
	cfg3->getAllBasicBlocks(blocks3);

	if (blocks3.size() < 10) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected %d basic blocks in %s, should be at least ten.\n", blocks3.size(), fn2);
		return FAILED;
	}

	bool foundSwitchIn = false;
	bool foundSwitchOut = false;
	bool foundRangeCheck = false;

        for (std::set<BPatch_basicBlock *>::iterator iter = blocks3.begin();
             iter != blocks3.end(); ++iter) {
           BPatch_basicBlock *block = *iter;

           BPatch_Vector<BPatch_basicBlock*> in;
           BPatch_Vector<BPatch_basicBlock*> out;
           
           block->getSources(in);
           block->getTargets(out);

           if (!foundSwitchOut && out.size() >= 10 && in.size() <= 1) 
           {
              foundSwitchOut = true;
           } 
           else if (!foundSwitchIn && in.size() >= 10 && out.size() <= 1) 
           {
              foundSwitchIn = true;
           } 
           else if (!foundRangeCheck && out.size() == 2 && in.size() <= 1) 
           {
              foundRangeCheck = true;
           } 
           else if (in.size() > 1 && out.size() > 1) 
           {
              logerror("**Failed** test #33 (control flow graphs)\n");
              logerror("  Found basic block in %s with unexpected number of edges.\n", fn2);
              logerror("  %d incoming edges, %d outgoing edges.\n",
                       in.size(), out.size());
              return FAILED;
           }
	}

	if (!foundSwitchIn || !foundSwitchOut) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		if (!foundSwitchIn)
			logerror("  Did not find \"switch\" statement in %s.\n", fn2);
		if (!foundSwitchOut)
			logerror("  Did not find block after \"switch\" statement.\n");
		return FAILED;
	}

	/* Check dominator info. */
	BPatch_Vector<BPatch_basicBlock*> entry3;
	cfg3->getEntryBasicBlock(entry3);

	if (entry3.size() != 1) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected %d entry basic blocks in %s, should have been one.\n", entry_blocks.size(), fn2);
		return FAILED;
	}

        for (std::set<BPatch_basicBlock *>::iterator iter2 = blocks3.begin();
             iter2 != blocks3.end(); ++iter2) {
           if (!entry3[0]->dominates(*iter2))  {
              logerror("**Failed** test #33 (control flow graphs)\n");
              logerror("  Entry block does not dominate all blocks in %s\n", fn2);
              return FAILED;
           }
	}

	BPatch_Vector<BPatch_basicBlock*> exit3;
	cfg3->getExitBasicBlock(exit3);

	if (exit3.size() != 1) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("  Detected %d exit basic blocks in  %s, should have been one.\n", exit3.size(), fn2);
		for (unsigned i = 0; i < exit3.size(); ++i) {
		  logerror("\t%d: 0x%lx\n", i, exit3[i]->getStartAddress());
		}
		return FAILED;
	}

	for (i = 0; i < (unsigned int) exit3.size(); i++) 
	{
		if (!exit3[i]->postdominates(entry3[0])) 
		{
			logerror("**Failed** test #33 (control flow graphs)\n");
			logerror("  Exit block %d does not postdominate all entry blocks in %s\n", i, fn2);
			return FAILED;
		}
	}
#if !defined(os_windows_test) && defined(ENABLE_PARSE_API_GRAPHS)
	logerror("Testing parseAPI dominators\n");
	
	ParseAPI::Function* parse_func = ParseAPI::convert(func3);
	assert(parse_func);
	Block* parse_entry = parse_func->entry();
	bool parse_idoms_ok = true;
	for(Function::blocklist::const_iterator bl = parse_func->blocks().begin();
	    bl != parse_func->blocks().end();
	    ++bl)
	{
	  if(*bl == parse_entry) continue;
	  if(!dominates(*parse_func, parse_entry, *bl))
	  {
	    parse_idoms_ok = false;
	  }
	}
	if(!parse_idoms_ok)
	{
	  logerror("**Failed** test #33 (CFG)\n");
	  logerror("  ParseAPI dominator algorithm does not have entry block dominating all blocks in function\n");
	  return FAILED;
	}
#endif	
		      

	BPatch_variableExpr *expr33_1 = 
		appImage->findVariable("test1_33_globalVariable1");
	if (expr33_1 == NULL) 
	{
		logerror("**Failed** test #33 (control flow graphs)\n");
		logerror("    Unable to locate test1_33_globalVariable1\n");
		return FAILED;
	} 

	pvalue = 1;
	expr33_1->writeValue(&pvalue);

	return PASSED;
}
Exemplo n.º 12
0
//
// Start Test Case #8 - (declaration)
//   
test_results_t test5_8_Mutator::executeTest() {
  // Find the exit point to the procedure "func_cpp"
  BPatch_Vector<BPatch_function *> bpfv;
  const char *fn = "decl_test::func_cpp";
  if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror( "**Failed** test #8 (declaration)\n");
    logerror( "    Unable to find function %s\n", fn);
    return FAILED;
  }
  BPatch_function *f1 = bpfv[0];  
  BPatch_Vector<BPatch_point *> *point8_1 = f1->findPoint(BPatch_exit);
  if (!point8_1 || (point8_1->size() < 1)) {
    logerror( "Unable to find point decl_test::func_cpp - exit.\n");
    return FAILED;
  }

  bpfv.clear();
  const char *fn2 = "main";
  if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror( "**Failed** test #8 (declaration)\n");
    logerror( "    Unable to find function %s\n", fn2);
    return FAILED;
  }
  BPatch_function *f2 = bpfv[0];  
  BPatch_Vector<BPatch_point *> *point8_2 = f2->findPoint(BPatch_allLocations);
  if (!point8_2 || (point8_2->size() < 1)) {
    logerror( "Unable to find point in main.\n");
    return FAILED;
  }

  bpfv.clear();
  const char *fn3 = "decl_test::call_cpp";
  if (NULL == appImage->findFunction(fn3, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror( "**Failed** test #8 (declaration)\n");
    logerror( "    Unable to find function %s\n", fn3);
    return FAILED;
  }
  BPatch_function *call8_func = bpfv[0];  

  BPatch_variableExpr *this8 = appImage->findVariable("test5_8_test8");
  if (this8 == NULL) {
    logerror( "**Failed** test #8 (declaration)\n");
    logerror( "Unable to find variable \"test5_8_test8\"\n");
    return FAILED;
  }

  BPatch_Vector<BPatch_snippet *> call8_args;
  BPatch_arithExpr expr8_0(BPatch_addr, *this8);
  call8_args.push_back(&expr8_0);
  BPatch_constExpr expr8_1(8);
  call8_args.push_back(&expr8_1);
  BPatch_funcCallExpr call8Expr(*call8_func, call8_args);

  // find the variables of different scopes
  // What *exactly* are we testing here?  Just finding variables of various
  // types with different point parameters to findVariable()?
  BPatch_variableExpr *expr8_2=appImage->findVariable("CPP_DEFLT_ARG");
  BPatch_variableExpr *expr8_3=appImage->findVariable(*(*point8_2)[0], "test5_8_test8");
  BPatch_variableExpr *expr8_4=appImage->findVariable(*(*point8_1)[0], "CPP_DEFLT_ARG");
  if (!expr8_2 || !expr8_3 || !expr8_4) {
    logerror( "**Failed** test #8 (delcaration)\n");
    logerror( "    Unable to locate one of variables\n");
    return FAILED;
  }

    BPatch_Vector<BPatch_variableExpr *> *fields = expr8_3->getComponents();
    if (!fields || fields->size() == 0 ) {
          logerror( "**Failed** test #8 (declaration)\n");
          logerror( "  struct lacked correct number of elements\n");
          return FAILED;
     }

    unsigned int index = 0;
    while ( index < fields->size() ) {
	char fieldName[100];
	strcpy(fieldName, (*fields)[index]->getName());
       if ( !strcmp("CPP_TEST_UTIL_VAR", (*fields)[index]->getName()) ) {
           dprintf("Inserted snippet2\n");
           checkCost(call8Expr);
	   BPatchSnippetHandle *handle;
           handle = appAddrSpace->insertSnippet(call8Expr, *point8_1);
           return PASSED;
       }
       
       index ++;
    }
    logerror( "**Failed** test #8 (declaration)\n");
    logerror( "    Can't find inherited class member variables\n");
    return FAILED;
}
Exemplo n.º 13
0
//  
// Start Test Case #1 - (C++ argument pass)
//       
// static int mutatorTest(BPatch_thread *appThread, BPatch_image *appImage)
test_results_t test5_1_Mutator::executeTest() {

  BPatch_Vector<BPatch_function *> bpfv;
  const char *fn = "arg_test::call_cpp";
  if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size()
      || NULL == bpfv[0]){
    logerror("**Failed** test #1\n");
    logerror("    Unable to find function %s\n", fn);
    return FAILED;
  }
  BPatch_function *f1 = bpfv[0];  
  BPatch_Vector<BPatch_point *> *point1_1 = f1->findPoint(BPatch_subroutine);
       
   assert(point1_1);
   assert((*point1_1)[0]);

   // check the paramter passing modes
   BPatch_variableExpr *arg0 = appImage->findVariable(*(*point1_1)[0],
       "reference");
   BPatch_variableExpr *arg1 = appImage->findVariable(*(*point1_1)[0],
       "arg1");
   BPatch_variableExpr *arg2 = appImage->findVariable(*(*point1_1)[0],
       "arg2");
   BPatch_variableExpr *arg3 = appImage->findVariable(*(*point1_1)[0],
       "arg3");
   BPatch_variableExpr *arg4 = appImage->findVariable(*(*point1_1)[0],
       "m");

   if (!arg0 || !arg1 || !arg2 || !arg3 || !arg4) {
      logerror("**Failed** test #1 (argument passing)\n");
      if ( !arg0 )
         logerror("  can't find local variable 'reference'\n");
      if ( !arg1 )
         logerror("  can't find local variable 'arg1'\n");
      if ( !arg2 )
         logerror("  can't find local variable 'arg2'\n");
      if ( !arg3 )
         logerror("  can't find local variable 'arg3'\n");
      if ( !arg4 )
         logerror("  can't find local variable 'm'\n");
      return FAILED;
   }

   BPatch_type *type1_0 = const_cast<BPatch_type *> (arg0->getType());
   BPatch_type *type1_1 = const_cast<BPatch_type *> (arg1->getType());
   BPatch_type *type1_2 = const_cast<BPatch_type *> (arg2->getType());
   BPatch_type *type1_3 = const_cast<BPatch_type *> (arg4->getType());
   assert(type1_0 && type1_1 && type1_2 && type1_3);

   if (!type1_1->isCompatible(type1_3)) {
       logerror("**Failed** test #1 (C++ argument pass)\n");
       logerror("    type1_1 reported as incompatibile with type1_3\n");
       return FAILED;
   }

   if (!type1_2->isCompatible(type1_0)) {
        logerror("**Failed** test #1 (C++ argument pass)\n");
        logerror("    type1_2 reported as incompatibile with type1_0\n");
        return FAILED;
   }

   BPatch_arithExpr expr1_1(BPatch_assign, *arg3, BPatch_constExpr(1));
   checkCost(expr1_1);
   appAddrSpace->insertSnippet(expr1_1, *point1_1);

   // pass a paramter to a class member function
   bpfv.clear();
   const char *fn2 = "arg_test::func_cpp";
   if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size()
       || NULL == bpfv[0]){
     logerror("**Failed** test #1 (C++ argument pass)\n");
     logerror("    Unable to find function %s\n", fn2);
     return FAILED;
   }
   BPatch_function *f2 = bpfv[0];  
   BPatch_Vector<BPatch_point *> *point1_2 = f2->findPoint(BPatch_subroutine);

   if (!point1_2 || (point1_2->size() < 1)) {
     logerror("**Failed** test #1 (C++ argument pass)\n");
      logerror("Unable to find point arg_test::func_cpp - exit.\n");
      return FAILED;
   }

   bpfv.clear();
   const char *fn3 = "arg_test::arg_pass";
   if (NULL == appImage->findFunction(fn3, bpfv) || !bpfv.size()
       || NULL == bpfv[0]) {
     logerror("**Failed** test #1 (C++ argument pass)\n");
     logerror("    Unable to find function %s\n", fn3);
     return FAILED;
   }
   BPatch_function *call1_func = bpfv[0];  

   BPatch_variableExpr *this1 = appImage->findVariable("test1");
   if (this1 == NULL) {
      logerror("**Failed** test #1 (C++ argument pass)\n");
      logerror("Unable to find variable \"test1\"\n");
      return FAILED;
   }

   BPatch_Vector<BPatch_snippet *> call1_args;
   BPatch_arithExpr expr1_2(BPatch_addr, *this1);
   call1_args.push_back(&expr1_2);
   BPatch_constExpr expr1_3(1);
   call1_args.push_back(&expr1_3);
   BPatch_funcCallExpr call1Expr(*call1_func, call1_args);

   checkCost(call1Expr);
   appAddrSpace->insertSnippet(call1Expr, *point1_2);
   return PASSED;
}