PrologEpilogGenerator::PrologEpilogGenerator(Cfg &cfg) :
    mm(cfg.getMM()),
    cfg(cfg), 
    outRegArgs(mm),
    prologInsts(mm),
    epilogInsts(mm),
    allocInsts(mm),
    saveSpInsts(mm),
    savePfsInsts(mm),
    saveUnatInsts(mm),
    saveGrsInsts(mm),
    saveFrsInsts(mm),
    saveBrsInsts(mm),
    savePrsInsts(mm),
    saveRpInsts(mm),
    restRpInsts(mm),
    restPrsInsts(mm),
    restBrsInsts(mm),
    restFrsInsts(mm),
    restGrsInsts(mm),
    restUnatInsts(mm),
    restPfsInsts(mm),
    restSpInsts(mm),
    epilogNodes(mm) {
    
    opndManager = cfg.getOpndManager();
    p0          = opndManager->getP0();
    sp          = opndManager->getR12();
    stackAddr   = opndManager->newRegOpnd(OPND_G_REG, DATA_I64, SPILL_REG1);
}
Пример #2
0
Graph* Connector::connect(Graph* g)
{
	const std::vector<CfgNode*>& nodes = g->getNodes();

	std::map<unsigned int, CfgNode*> id2node = getId2Node(nodes);

	for (unsigned int i = 0; i < nodes.size(); i++) {
		CfgNode* fromNode = nodes[i];
		Cfg* cfg = fromNode->getCfg();

		std::vector<unsigned int> nexts = cfg->getNext();

		for (unsigned int j = 0; j < nexts.size(); j++) {
			CfgNode* toNode = id2node[nexts[j]];

			if (toNode == NULL)
				THROWEXCEPTION("next statement is illegal; there is no node with id=%d", nexts[j]);

			if (connectNodes) // insert the connection in the graph
				g->addEdge(fromNode, toNode);

			msg(MSG_INFO,  "Connecting module %s[Id = %d] -> %s[Id = %d]",
					cfg->getName().c_str(), cfg->getID(),
					id2node[nexts[j]]->getCfg()->getName().c_str(),
					id2node[nexts[j]]->getCfg()->getID());

			if (connectModules) {// connect the modules
				DPRINTF("connecting instances");
				cfg->connectInstances(toNode->getCfg());
			}
		}
	}

	return g;
}
Пример #3
0
IpfVarCodeSelector::IpfVarCodeSelector(Cfg &cfg, OpndVector &opnds) :
    mm(cfg.getMM()),
    cfg(cfg),
    opnds(opnds) {

    opndManager = cfg.getOpndManager();
}
Пример #4
0
static Handle<Code> MakeCode(FunctionLiteral* literal,
                             Handle<Script> script,
                             Handle<Context> context,
                             bool is_eval) {
  ASSERT(literal != NULL);

  // Rewrite the AST by introducing .result assignments where needed.
  if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) {
    // Signal a stack overflow by returning a null handle.  The stack
    // overflow exception will be thrown by the caller.
    return Handle<Code>::null();
  }

  {
    // Compute top scope and allocate variables. For lazy compilation
    // the top scope only contains the single lazily compiled function,
    // so this doesn't re-allocate variables repeatedly.
    HistogramTimerScope timer(&Counters::variable_allocation);
    Scope* top = literal->scope();
    while (top->outer_scope() != NULL) top = top->outer_scope();
    top->AllocateVariables(context);
  }

#ifdef DEBUG
  if (Bootstrapper::IsActive() ?
      FLAG_print_builtin_scopes :
      FLAG_print_scopes) {
    literal->scope()->Print();
  }
#endif

  // Optimize the AST.
  if (!Rewriter::Optimize(literal)) {
    // Signal a stack overflow by returning a null handle.  The stack
    // overflow exception will be thrown by the caller.
    return Handle<Code>::null();
  }

  if (FLAG_multipass) {
    CfgGlobals scope(literal);
    Cfg* cfg = Cfg::Build();
#ifdef DEBUG
    if (FLAG_print_cfg && cfg != NULL) {
      SmartPointer<char> name = literal->name()->ToCString();
      PrintF("Function \"%s\":\n", *name);
      cfg->Print();
      PrintF("\n");
    }
#endif
    if (cfg != NULL) {
      return cfg->Compile(script);
    }
  }

  // Generate code and return it.
  Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval);
  return result;
}
Пример #5
0
/*
 * ssa_cfg_to_instr_list -- First restore conventional (non-SSA form).
 * Then convert the resulting CFG to InstrList form, delete the now-empty
 * CFG, and return the instruction list.
 */
InstrList*
ssa_cfg_to_instr_list(SsaCfg *ssa_cfg)
{
    Cfg *cfg = restore(ssa_cfg);
    InstrList *instr_list = cfg->to_instr_list();

    delete cfg;
    return instr_list;
}
Пример #6
0
QpTree::QpTree(Cfg &cfg) : 
    cfg(cfg),
    mm(cfg.getMM()),
    qpMap(mm),
    slot(0),
    p0(cfg.getOpndManager()->getP0()) {

    qpMap.insert( make_pair(p0, new(mm) QpNode(NULL, MAX_QP_MASK)) );  // make root qpNode
}
Пример #7
0
int main(int argc, char * argv[]){

   remove("tmp/test1.txt");
   remove("tmp/test2.txt");
   remove("./tmp/graph.dot");
   if (argc < 2) {
      cout << "erreur : pas de fichier assembleur en entrée" << endl;
   }	  
   Program prog(argv[1]);
   Function* functmp;

   list <Basic_block*> myBB;

   cout<<"Le programme a "<<prog.size()<<" lignes\n"<<endl;

   cout<<"Contenu du programme:"<<endl;
   //prog.display();
   prog.in_file("tmp/restit.txt");

   cout<<"\n Calcul des fonctions des block de base et restitution\n"<<endl;

   prog.comput_function();
   
   cout<<"nombre de fonction: "<<prog.nbr_func()<<endl;

   Cfg *graph;
   for (int i=0; i<prog.nbr_func(); i++){
      
      functmp= prog.get_function(i);

      if(functmp==NULL){
	 cout<<"null"<<endl;
	 break;
      }
//      functmp->restitution("tmp/test1.txt");
      functmp->comput_basic_block();
      functmp->comput_label();
      
      for(int j=0; j<functmp->nbr_BB(); j++){
	//functmp->get_BB(j)->display();
      }
      
      functmp->comput_succ_pred_BB();
		
      graph =new Cfg(functmp->get_BB(0),
			  functmp->nbr_BB());
	
		
      cout<<"------------Function "<< (i+1) <<"/"<<prog.nbr_func()<<" DISPLAY----------\n" <<endl;
      //functmp->test();
      graph->display(NULL);
   }
//   graph->restitution(NULL,"./tmp/graph.dot");
}
Пример #8
0
IpfCfgCodeSelector::IpfCfgCodeSelector(Cfg                  &cfg, 
                                       NodeVector           &nodes, 
                                       OpndVector           &opnds,
                                       CompilationInterface &compilationInterface) : 
    mm(cfg.getMM()),
    cfg(cfg),
    nodes(nodes), 
    opnds(opnds),
    compilationInterface(compilationInterface),
    opndManager(cfg.getOpndManager()) {
}
Пример #9
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;
}
Пример #10
0
LiveAnalyzer::LiveAnalyzer(Cfg &cfg) : 
    cfg(cfg),
    mm(cfg.getMM()),
    workSet(mm),
    liveManager(cfg),
    liveSet(liveManager.getLiveSet()),
    dceFlag(false) {
}
Пример #11
0
void ConfigManager::shutdown()
{
	lockGraph();
	std::vector<CfgNode*> topoNodes = graph->topoSort();

	// shutdown modules
	for (size_t i = 0; i < topoNodes.size(); i++) {
		Cfg* cfg = topoNodes[i]->getCfg();
		msg(MSG_INFO, "shutting down module %s (id=%u)", cfg->getName().c_str(), cfg->getID());
		cfg->shutdown(true, true);
	}

	// trigger sensorManager to get the final statistics of this Vermont run
	if (sensorManager) {
		sensorManager->retrieveStatistics(true);
	}

	// disconnect the modules
	for (size_t i = 0; i < topoNodes.size(); i++) {
		CfgNode* n = topoNodes[i];
		Cfg* cfg = n->getCfg();

		// disconnect the module from its sources ..
		vector<CfgNode*> sources = graph->getSources(n);
		msg(MSG_INFO, "disconnecting module %s (id=%u)", cfg->getName().c_str(), cfg->getID());
		for (size_t k = 0; k < sources.size(); k++) {
			sources[k]->getCfg()->disconnectInstances();
		}
	}
	unlockGraph();
}
Пример #12
0
void readCfg(Cfg& config, const string& cfg)
{
  xmlDocPtr config_doc = xmlParseFile(cfg.c_str());
  if(config_doc == NULL) {
    throw string("missing configuration file ")+cfg;
  }
  config.ReConfigure(config_doc->children);
  xmlFreeDoc(config_doc);
}
Пример #13
0
IpfMethodCodeSelector::IpfMethodCodeSelector(Cfg                  &cfg,
                                             CompilationInterface &compilationInterface) : 
    mm(cfg.getMM()),
    cfg(cfg), 
    compilationInterface(compilationInterface),
    methodDesc(NULL),
    opnds(mm),
    nodes(mm) {
}
Пример #14
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;
}
Пример #15
0
/*==============================================================================
 * FUNCTION:	createReturnBlock
 * OVERVIEW:	Create a Return or a Oneway BB if a return statement already exists
 * PARAMETERS:	pProc: pointer to enclosing UserProc
 *				BB_rtls: list of RTLs for the current BB (not including pRtl)
 *				pRtl: pointer to the current RTL with the semantics for the return statement (including a
 *					ReturnStatement as the last statement)
 * RETURNS:		Pointer to the newly created BB
 *============================================================================*/
PBB FrontEnd::createReturnBlock(UserProc* pProc, std::list<RTL*>* BB_rtls, RTL* pRtl) {
	Cfg* pCfg = pProc->getCFG();
	PBB pBB;
	// Add the RTL to the list; this has the semantics for the return instruction as well as the ReturnStatement
	// The last Statement may get replaced with a GotoStatement
	if (BB_rtls == NULL) BB_rtls = new std::list<RTL*>;		// In case no other semantics
	BB_rtls->push_back(pRtl);
	ADDRESS retAddr = pProc->getTheReturnAddr();
	std::cout << "retAddr = " << std::hex << retAddr << " rtl = " <<std::hex<< pRtl->getAddress() << "\n";
	// LOG << "retAddr = " << retAddr << " rtl = " << pRtl->getAddress() << "\n";
	if (retAddr == NO_ADDRESS) {
		// Create the basic block
		pBB = pCfg->newBB(BB_rtls, RET, 0);
		Statement* s = pRtl->getList().back();		// The last statement should be the ReturnStatement
		pProc->setTheReturnAddr((ReturnStatement*)s, pRtl->getAddress());
	} else {
		// We want to replace the *whole* RTL with a branch to THE first return's RTL. There can sometimes be extra
		// semantics associated with a return (e.g. Pentium return adds to the stack pointer before setting %pc and
		// branching). Other semantics (e.g. SPARC returning a value as part of the restore instruction) are assumed to
		// appear in a previous RTL. It is assumed that THE return statement will have the same semantics (NOTE: may
		// not always be valid). To avoid this assumption, we need branches to statements, not just to native addresses
		// (RTLs).
		PBB retBB = pProc->getCFG()->findRetNode();
		assert(retBB);
		if (retBB->getFirstStmt()->isReturn()) {
			// ret node has no semantics, clearly we need to keep ours
			pRtl->deleteLastStmt();
		} else
			pRtl->clear();
		pRtl->appendStmt(new GotoStatement(retAddr));
		try {
			pBB = pCfg->newBB(BB_rtls, ONEWAY, 1);
			// if BB already exists but is incomplete, exception is thrown
			pCfg->addOutEdge(pBB, retAddr, true);
			// Visit the return instruction. This will be needed in most cases to split the return BB (if it has other
			// instructions before the return instruction).
			targetQueue.visit(pCfg, retAddr, pBB);
		} catch(Cfg::BBAlreadyExistsError &) {
			if (VERBOSE)
				LOG << "not visiting " << retAddr << " due to exception\n";
		}
	}
	return pBB;
}
Пример #16
0
Configuration::Configuration( QWidget *parent, Cfg &cfg )
	: QDialog( parent, 0, TRUE, WStyle_ContextHelp )
{
	setCaption( tr( "Configure Checkbook" ) );

    // Setup layout to make everything pretty
	QVBoxLayout *layout = new QVBoxLayout( this );
	layout->setMargin( 2 );
	layout->setSpacing( 4 );

	// Setup tabs for all info
	_mainWidget = new QTabWidget( this );
	layout->addWidget( _mainWidget );

    // Settings tab
    _mainWidget->addTab( initSettings(cfg), tr( "&Settings" ) );

    // Account Types tab
    ColumnDef *d;
    _listEditTypes=new ListEdit(_mainWidget, "TYPES" );
    d=new ColumnDef( tr("Type"), (ColumnDef::ColumnType)(ColumnDef::typeString | ColumnDef::typeUnique), tr("New Account Type"));
    _listEditTypes->addColumnDef( d );
    _listEditTypes->addData( cfg.getAccountTypes() );
    _mainWidget->addTab( _listEditTypes, tr( "&Account Types" ) );

    // Categories tab
    _listEditCategories=new ListEdit(_mainWidget, "CATEGORIES" );
    _listEditCategories->addColumnDef( new ColumnDef( tr("Category"), (ColumnDef::ColumnType)(ColumnDef::typeString | ColumnDef::typeUnique), tr("New Category")) );
    d=new ColumnDef(  tr("Type"), ColumnDef::typeList, tr("Expense") );
    d->addColumnValue( tr("Expense") );
    d->addColumnValue( tr("Income") );
    _listEditCategories->addColumnDef( d );
    QStringList lst=cfg.getCategories();
    _listEditCategories->addData( lst );
    _mainWidget->addTab( _listEditCategories, tr( "&Categories" ) );

    // Payees tab
    _listEditPayees=new ListEdit(_mainWidget, "PAYEES");
    _listEditPayees->addColumnDef( new ColumnDef( tr("Payee"), (ColumnDef::ColumnType)(ColumnDef::typeString | ColumnDef::typeUnique), tr("New Payee")) );
    _listEditPayees->addData( cfg.getPayees() );
    _mainWidget->addTab( _listEditPayees, tr("&Payees") );
}
Пример #17
0
std::vector<Cfg> tmr::post(const Cfg& cfg, unsigned short tid, MemorySetup msetup) {
	// execute low-level action
	auto post = get_post_cfgs(cfg, tid, msetup);

	#define RETURN return post;

	// check for high-level simulation
	#if REPLACE_INTERFERENCE_WITH_SUMMARY
		assert(msetup == PRF);
		assert(tid == 0);

		// initial and summaries do not need a summary
		auto& stmt = *cfg.pc[tid];
		if (ignore_for_summary(stmt)) {
			RETURN;
		}

		// find those post cfgs that require a summary, i.e. that changed the shared heap
		auto require_summaries = find_effectful_configurations(cfg, post);
		if (require_summaries.size() == 0) {
			RETURN;
		}

		// frees shall have an empty summary
		if (stmt.clazz() == Statement::FREE) {
			// if a free comes that far, we are in trouble as it requires a non-empty summary
			throw std::runtime_error("Misbehaving Summary: free stmt requires non-empty summary.");
		}

		// prepare summary
		Cfg tmp = cfg.copy();
		tmp.pc[tid] = &stmt.function().summary();
		if (stmt.function().has_output()) tmp.inout[tid] = OValue();

		// execute summary
		auto sumpost = get_post_cfgs(tmp, tid, msetup);

		// check summary
		for (const Cfg& postcfg : require_summaries) {
			bool covered = false;
			for (const Cfg& summarycfg : sumpost) {
				if (subset_shared(postcfg, summarycfg)) {
					covered = true;
					break;
				}
			}
			if (!covered) throw std::runtime_error("Misbehaving Summary: failed to mimic low-level action.");
		}
	#endif

	RETURN;
}
Пример #18
0
// --- saveConfig -------------------------------------------------------------
void Configuration::saveConfig(Cfg &cfg)
{
    // Settings
    cfg.setCurrencySymbol( symbolEdit->text() );
    cfg.setUseSmallFont( smallFontCB->isChecked() );
    cfg.setShowLocks( lockCB->isChecked() );
    cfg.setShowBalances( balCB->isChecked() );
    cfg.setOpenLastBook( openLastBookCB->isChecked() );
    cfg.setShowLastTab( lastTabCB->isChecked() );
    cfg.setSavePayees( savePayees->isChecked() );

    // Typelist
    _listEditTypes->storeInList( cfg.getAccountTypes() );

    // Category list
    QStringList lst;
    _listEditCategories->storeInList( lst );
    cfg.setCategories( lst );

    // Payees
    _listEditPayees->storeInList( cfg.getPayees() );
}
Пример #19
0
PackageInfo PackageManager::GetPackageManifest(const Cfg& cfg, const string& packageId, const std::string& texmfPrefix)
{
  auto key = cfg.GetKey(packageId);
  if (key == nullptr)
  {
    MIKTEX_UNEXPECTED();
  }
  PackageInfo packageInfo;
  packageInfo.id = packageId;
  for (auto val : *key)
  {
    if (val->GetName() == "displayName")
    {
      packageInfo.displayName = val->AsString();
    }
    else if (val->GetName() == "creator")
    {
      packageInfo.creator = val->AsString();
    }
    else if (val->GetName() == "title")
    {
      packageInfo.title = val->AsString();
    }
    else if (val->GetName() == "version")
    {
      packageInfo.version = val->AsString();
    }
    else if (val->GetName() == "targetSystem")
    {
      packageInfo.targetSystem = val->AsString();
    }
    else if (val->GetName() == "description[]")
    {
      packageInfo.description = std::for_each(val->begin(), val->end(), Flattener('\n')).result;
    }
    else if (val->GetName() == "require[]")
    {
      packageInfo.requiredPackages = val->AsStringVector();
    }
    else if (val->GetName() == "runSize")
    {
      packageInfo.sizeRunFiles = Utils::ToSizeT(val->AsString());
    }
    else if (val->GetName() == "run[]")
    {
      for (const string& s : *val)
      {
        PathName path(s);
#if defined(MIKTEX_UNIX)
        path.ConvertToUnix();
#endif
        if (texmfPrefix.empty() || (PathName::Compare(texmfPrefix, path, texmfPrefix.length()) == 0))
        {
          packageInfo.runFiles.push_back(path.ToString());
        }
      }
    }
    else if (val->GetName() == "docSize")
    {
      packageInfo.sizeDocFiles = Utils::ToSizeT(val->AsString());
    }
    else if (val->GetName() == "doc[]")
    {
      for (const string& s : *val)
      {
        PathName path(s);
#if defined(MIKTEX_UNIX)
        path.ConvertToUnix();
#endif
        if (texmfPrefix.empty() || (PathName::Compare(texmfPrefix, path, texmfPrefix.length()) == 0))
        {
          packageInfo.docFiles.push_back(path.ToString());
        }
      }
    }
    else if (val->GetName() == "sourceSize")
    {
      packageInfo.sizeSourceFiles = Utils::ToSizeT(val->AsString());
    }
    else if (val->GetName() == "source[]")
    {
      for (const string& s : *val)
      {
        PathName path(s);
#if defined(MIKTEX_UNIX)
        path.ConvertToUnix();
#endif
        if (texmfPrefix.empty() || (PathName::Compare(texmfPrefix, path, texmfPrefix.length()) == 0))
        {
          packageInfo.sourceFiles.push_back(path.ToString());
        }
      }
    }
    else if (val->GetName() == "timePackaged")
    {
      packageInfo.timePackaged = Utils::ToTimeT(val->AsString());
    }
    else if (val->GetName() == "digest")
    {
      packageInfo.digest = MD5::Parse(val->AsString());
    }
    else if (val->GetName() == "ctanPath")
    {
      packageInfo.ctanPath = val->AsString();
    }
    else if (val->GetName() == "copyrightOwner")
    {
      packageInfo.copyrightOwner = val->AsString();
    }
    else if (val->GetName() == "copyrightYear")
    {
      packageInfo.copyrightYear = val->AsString();
    }
    else if (val->GetName() == "licenseType")
    {
      packageInfo.licenseType = val->AsString();
    }
  }
  return packageInfo;
}
Пример #20
0
LiveManager::LiveManager(Cfg &cfg) : 
    cfg(cfg),
    qpTree(cfg),
    liveSet(cfg.getMM()) {
}
Пример #21
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;
}
Пример #22
0
Graph* ConfigManager::reconnect(Graph* g, Graph *old)
{
    Graph *newGraph;
    Graph *oldGraph;
	newGraph = g;
    oldGraph = old;

	vector<CfgNode*> topoOld = oldGraph->topoSort();
	vector<CfgNode*> topoNew = newGraph->topoSort();

	/* disconnect all modules */
	for (size_t i = 0; i < topoOld.size(); i++) {
		topoOld[i]->getCfg()->getInstance()->preReconfiguration();
		topoOld[i]->getCfg()->disconnectInstances();
        msg(MSG_INFO, "Disconnecting instance: %s", topoOld[i]->getCfg()->getName().c_str());
	}

	/* call onReconfiguration1 on all modules */
	for (size_t i = 0; i < topoOld.size(); i++) {
		topoOld[i]->getCfg()->onReconfiguration1();
	}

	/* call preConfiguration2 on all modules */
	for (size_t i = 0; i < topoOld.size(); i++) {
		topoOld[i]->getCfg()->onReconfiguration2();
	}


	// compare the nodes in the old and new graph and search for
	// (nearly) identical modules which could be reused
	for (size_t i = 0; i < topoOld.size(); i++) {
		Cfg* oldCfg = topoOld[i]->getCfg();
		for (size_t j = 0; j < topoNew.size(); j++) {
			Cfg* newCfg = topoNew[j]->getCfg();
			if (oldCfg->getID() == newCfg->getID()) { // possible match
				msg(MSG_INFO, "found a match between %s(id=%d) -> %s(id=%d)",
						oldCfg->getName().c_str(), oldCfg->getID(),
						newCfg->getName().c_str(), newCfg->getID());

				// check if we could use the same module instance in the new config
				if (newCfg->deriveFrom(oldCfg)) {
					msg(MSG_INFO, "reusing %s(id=%d)",
							oldCfg->getName().c_str(), oldCfg->getID());
					newCfg->transferInstance(oldCfg);
				} else {
                    deleter_list_item delme;
                    delme.c = oldCfg;
                    delme.delete_after = time(NULL) + DELETER_DELAY; // current time + 20 seconds
                    deleter_list.push_back(delme);
                    msg(MSG_INFO, "can't reuse %s(id=%d)",
							oldCfg->getName().c_str(), oldCfg->getID());
				}
			}
		}
	}


	/* Now that we transfered all module instances which could be reused
	 * into the new graph, we have to build up the new connections
	 *
	 * The Connector will take care to call preConnect for us!!!
	 */
	Connector con(false, true);
	newGraph->accept(&con);

	return newGraph;
}
Пример #23
0
int main(int argc, char * argv[]){

	if (argc < 2) {
	  cout << "erreur : pas de fichier assembleur" << endl;
	}	  
	Program prog(argv[1]);
	Function* functmp;
	list <Function*> myfunc; 
	list <Basic_block*> myBB;

	cout<<"Le programme a "<<prog.size()<<" lignes\n"<<endl;

	prog.comput_function();
	cout<<"nombre de fonctions : "<<prog.nbr_func()<<endl;

	list<Function*>::iterator itfct;
	list<Basic_block*>::iterator itbb;
	Basic_block *bb;
	int i, j;
	list<int> frees;
	Dfg *d;
	Cfg *c;
	
	std::ostringstream *oss ;
	for(itfct=prog.function_list_begin(), i=0;
	    itfct!=prog.function_list_end(); itfct++, i++){
	   functmp=*itfct;
	    cout<<"------------Function DISPLAY----------\n" <<endl;
	    functmp->display();
	   functmp->comput_basic_block();
	   functmp->comput_label();
	   functmp->comput_succ_pred_BB();
	   
	   oss=new std::ostringstream;
	   
	   (*oss)<<"./tmp/func_"<<i<<".dot";
	   c=new Cfg(functmp->get_BB(0), functmp->nbr_BB());
	   c->restitution(NULL, oss->str());
	   
	   cout<<"========== Function "<<i<<"==========="<<endl;
	   cout<<"============================"<<endl;
	   
	   functmp ->compute_live_var();
	   j=0;
	   int total1 = 0, total2 = 0, total3 = 0, total4 = 0;
	   for(itbb=functmp->bb_list_begin(); 
	       itbb!=functmp->bb_list_end(); itbb++, j++){
	      bb=*itbb;
	      bb->link_instructions();
	      bb->comput_pred_succ_dep();

	      total1 += bb->nb_cycles();
	      d = new Dfg(bb);
	      d->scheduling(false);
	      d->apply_scheduling();
	      total2 += bb->nb_cycles();

	      bb->reg_rename();
	      // il faut annuler le calcul des dépendances et le refaire
	      bb->reset_pred_succ_dep();
	      bb->comput_pred_succ_dep();
	      total3 += bb->nb_cycles();

	      d= new Dfg(bb);
	      d->scheduling(false);
	      d->apply_scheduling();

	      total4 += bb->nb_cycles();
	      //return 0;
	   }
	   printf("Nombres de cycles : \n");
	   printf(" BASIC  | SCHEDULED | RENAMED | RE-SCHEDULED\n");
	   printf("   %d   |    %d     |    %d   |     %d      \n", total1, total2, total3, total4);
	}
	    
	
	

	
}
Пример #24
0
/**
 * parses configuration and adjusts/creates module graph accordingly
 * afterwards all modules are started
 */
void ConfigManager::parseConfig(std::string fileName)
{
	lockGraph();
	Graph* oldGraph = graph;

	graph = new Graph();

	old_document = document;
	document = XMLDocument::parse_file(fileName);
	XMLElement* root = document->getRootNode();

	// consistency checks
	if (!root) {
		unlockGraph();
		THROWEXCEPTION("%s is an empty XML-Document!", fileName.c_str());
	}

	if (!root->matches("ipfixConfig")) {
		unlockGraph();
		THROWEXCEPTION("Root element does not match \"ipfixConfig\"."
			       " This is not a valid configuration file!");
	}

	/* process each root element node and add a new node (with its config
	 * attached to the node) to the graph
	 */
	XMLNode::XMLSet<XMLElement*> rootElements = root->getElementChildren();
	for (XMLNode::XMLSet<XMLElement*>::const_iterator it = rootElements.begin();
	     it != rootElements.end();
	     it++) {
		bool found = false;
		for (unsigned int i = 0; i < ARRAY_SIZE(configModules); i++) {
			if ((*it)->getName() == configModules[i]->getName()) {
				Cfg* cfg = configModules[i]->create(*it);

				// handle special modules
				SensorManagerCfg* smcfg = dynamic_cast<SensorManagerCfg*>(cfg);
				if (smcfg) {
					// SensorManager will not be connected to any modules, so its instance
					// needs to be started manually
					smcfg->setGraphIS(this);
					sensorManager = smcfg->getInstance();
				}

				graph->addNode(cfg);
				found = true;
			}
		}

		if (!found) {
			msg(MSG_ERROR, "Unknown cfg entry %s found", (*it)->getName().c_str());
		}
	}

	if (!oldGraph) { // this is the first config we have read
		Connector connector;
		graph->accept(&connector);
	} else {
		// first, connect the nodes on the new graph (but NOT the modules)
		Connector connector(true, false);
		graph->accept(&connector);
		// now connect the modules reusing those from the old graph
		graph = reconnect(graph, oldGraph);
	}

	// start the instances if not already running
	std::vector<CfgNode*> topoNodes = graph->topoSort();

	for (size_t i = 0; i < topoNodes.size(); i++) {
		Cfg* cfg = topoNodes[topoNodes.size() -1 -i]->getCfg();
		msg(MSG_INFO, "Starting module %s", cfg->getName().c_str());
		cfg->start(false);
	}

	if (old_document)
		delete old_document;

	unlockGraph();

}
Пример #25
0
void SensorManager::collectDataWorker()
{
	time_t lasttime = time(0);
	
	char* xmlpre = "<vermont>\n\t<sensorData time=\"%s\" host=\"%s\">\n";
	char* xmlpost = "\t</sensorData>\n</vermont>\n";
	char* xmlglobals = "\t\t<%s>%s</%s>\n";	
	
	if (!graphIS) {
		THROWEXCEPTION("GraphInstanceSupplier variable graphIS MUST be set when module is started!");
	}
	
	string lockfile = outputFilename + ".lock";
	char hostname[100];
	if (gethostname(hostname, 100) != 0) 
		THROWEXCEPTION("failed to get hostname by gethostname()!");
		
	registerCurrentThread();
	
	msg(MSG_FATAL, "SensorManager: checking sensor values every %u seconds", checkInterval);
	while (!exitFlag) {		
		uint32_t sleepcount = checkInterval*2;
		uint32_t i = 0;
		while (i<sleepcount && !exitFlag) {
			// restart nanosleep with the remaining sleep time
			// if we got interrupted by a signal
			timespec req;
			req.tv_sec = 0;
			req.tv_nsec = 50000000;
			while (nanosleep(&req, &req) == -1 && errno == EINTR);
			i++;
		}
			
		
		if (exitFlag) break;
		
		// we must not wait for the graph lock, else there may be a race condition with
		// the ConfigManager
		while (!graphIS->tryLockGraph()) {
			if (exitFlag) break;
			timespec timeout = { 0, 200000 };
			nanosleep(&timeout, NULL);
		}
		if (exitFlag) break;
		
		int fdlock = open(lockfile.c_str(), O_CREAT|O_RDONLY);
		if (fdlock == -1)
			msg(MSG_DEBUG, "failed to open file %s, error code %d", lockfile.c_str(), errno);
		
		if (flock(fdlock, LOCK_EX)!=0)			
			msg(MSG_DEBUG, "failed to activate exclusive lock on file %s (flock())", lockfile.c_str());
		
		FILE* file = fopen(outputFilename.c_str(), "w");
		if (!file) {
			THROWEXCEPTION("failed to reopen file %s", outputFilename.c_str());
			perror("error:");
		}
		
		time_t curtime = time(0);
		char curtimestr[100];
		ctime_r(&curtime, curtimestr);
		curtimestr[strlen(curtimestr)-1] = 0;
		fprintf(file, xmlpre, curtimestr, hostname);
		char text[100];
		snprintf(text, 100, "%u", static_cast<uint32_t>(getpid()));
		fprintf(file, xmlglobals, "pid", text, "pid");		
		char lasttimestr[100];
		ctime_r(&lasttime, lasttimestr);
		lasttimestr[strlen(lasttimestr)-1] = 0;
		fprintf(file, xmlglobals, "lastTime", lasttimestr, "lastTime");
		
#if defined(__linux__)		
		char* xmlglobalsuint = "\t\t<%s>%u</%s>\n";
		ThreadCPUInterface::SystemInfo si = ThreadCPUInterface::getSystemInfo();
		
		fprintf(file, xmlglobalsuint, "processorAmount", si.noCPUs, "processorAmount");
		for (uint16_t i=0; i<si.sysJiffies.size(); i++) {
			double sysutil = (si.sysJiffies[i]-lastSystemInfo.sysJiffies[i])/(static_cast<double>(curtime)-lasttime)/hertzValue*100;
			double userutil = (si.userJiffies[i]-lastSystemInfo.userJiffies[i])/(static_cast<double>(curtime)-lasttime)/hertzValue*100;
			fprintf(file, "\t\t<processor id=\"%u\"><util type=\"system\">%.2f%%</util><util type=\"user\">%.2f%%</util></processor>\n",
					i, sysutil, userutil);			
		}
		fprintf(file, "\t\t<memory><free type=\"bytes\">%llu</free><total type=\"bytes\">%llu</total></memory>\n",
				si.freeMemory, si.totalMemory);
		lastSystemInfo = si;
#endif
	
		DPRINTF("*** sensor data at %s", ctime(&curtime));
		
		Graph* g = graphIS->getGraph();
		vector<CfgNode*> nodes = g->getNodes();
		vector<CfgNode*>::iterator iter = nodes.begin();
		while (iter != nodes.end()) {
			Cfg* cfg = (*iter)->getCfg();
			Sensor* s = cfg->getInstance();		
			vector<uint32_t> nextids = cfg->getNext();
			writeSensorXML(file, s, cfg->getName().c_str(), cfg->getID(), true, curtime, lasttime, &nextids);
			
			iter++;
		}
		
		// iterate through all non-module sensors
		mutex.lock();
		list<SensorEntry>::const_iterator siter = sensors.begin();
		while (siter != sensors.end()) {
			writeSensorXML(file, siter->sensor, siter->name.c_str(), siter->id, false, curtime, lasttime, NULL);
			siter++;
		}
		mutex.unlock();
		
		fprintf(file, xmlpost);
		fclose(file);
		close(fdlock);
		
		lasttime = time(0);
		
		graphIS->unlockGraph();
	}
	
	
	unregisterCurrentThread();
}
Пример #26
0
bool DataFlow::placePhiFunctions(UserProc* proc) {
	// First free some memory no longer needed
	dfnum.resize(0);
	semi.resize(0);
	ancestor.resize(0);
	samedom.resize(0);
	vertex.resize(0);
	parent.resize(0);
	best.resize(0);
	bucket.resize(0);
	defsites.clear();			// Clear defsites map,
	defallsites.clear();
	A_orig.clear();				// and A_orig,
	defStmts.clear();			// and the map from variable to defining Stmt 

	bool change = false;

	// Set the sizes of needed vectors
	unsigned numBB = indices.size();
	Cfg* cfg = proc->getCFG();
	assert(numBB == cfg->getNumBBs());
	A_orig.resize(numBB);

	// We need to create A_orig[n] for all n, the array of sets of locations defined at BB n
	// Recreate each call because propagation and other changes make old data invalid
	unsigned n;
	for (n=0; n < numBB; n++) {
		BasicBlock::rtlit rit; StatementList::iterator sit;
		PBB bb = BBs[n];
		for (Statement* s = bb->getFirstStmt(rit, sit); s; s = bb->getNextStmt(rit, sit)) {
			LocationSet ls;
			LocationSet::iterator it;
			s->getDefinitions(ls);
			if (s->isCall() && ((CallStatement*)s)->isChildless())		// If this is a childless call
				defallsites.insert(n);									// then this block defines every variable
			for (it = ls.begin(); it != ls.end(); it++) {
				if (canRename(*it, proc)) {
					A_orig[n].insert((*it)->clone());
					defStmts[*it] = s;
				}
			}
		}
	}

	// For each node n
	for (n=0; n < numBB; n++) {
		// For each variable a in A_orig[n]
		std::set<Exp*, lessExpStar>& s = A_orig[n];
		std::set<Exp*, lessExpStar>::iterator aa;
		for (aa = s.begin(); aa != s.end(); aa++) {
			Exp* a = *aa;
			defsites[a].insert(n);
		}
	}

	// For each variable a (in defsites, i.e. defined anywhere)
	std::map<Exp*, std::set<int>, lessExpStar>::iterator mm;
	for (mm = defsites.begin(); mm != defsites.end(); mm++) {
		Exp* a = (*mm).first;				// *mm is pair<Exp*, set<int>>

		// Special processing for define-alls
		// for each n in defallsites
		std::set<int>::iterator da;
		for (da = defallsites.begin(); da != defallsites.end(); ++da)
			defsites[a].insert(*da);

		// W <- defsites[a];
		std::set<int> W = defsites[a];		// set copy
		// While W not empty
		while (W.size()) {
			// Remove some node n from W
			int n = *W.begin();				// Copy first element
			W.erase(W.begin());				// Remove first element
			// for each y in DF[n]
			std::set<int>::iterator yy;
			std::set<int>& DFn = DF[n];
			for (yy = DFn.begin(); yy != DFn.end(); yy++) {
				int y = *yy;
				// if y not element of A_phi[a]
				std::set<int>& s = A_phi[a];
				if (s.find(y) == s.end()) {
					// Insert trivial phi function for a at top of block y: a := phi()
					change = true;
					Statement* as = new PhiAssign(a->clone());
					PBB Ybb = BBs[y];
					Ybb->prependStmt(as, proc);
					// A_phi[a] <- A_phi[a] U {y}
					s.insert(y);
					// if a !elementof A_orig[y]
					if (A_orig[y].find(a) == A_orig[y].end()) {
						// W <- W U {y}
						W.insert(y);
					}
				}
			}
		}
	}
	return change;
}		// end placePhiFunctions
Пример #27
0
/*==============================================================================
 * FUNCTION:      processProc
 * OVERVIEW:      Process a procedure, given a native (source machine) address.
 * PARAMETERS:    address - the address at which the procedure starts
 *                delta - the offset of the above address from the logical
 *                  address at which the procedure starts (i.e. the one
 *                  given by dis)
 *                uUpper - the highest address of the text segment
 *                pProc - the procedure object
 *                decoder - NJMCDecoder object
 * RETURNS:       <nothing>
 *============================================================================*/
void processProc(ADDRESS uAddr, ptrdiff_t delta, ADDRESS uUpper, UserProc* pProc,
                 NJMCDecoder& decoder)
{
    PBB pBB;                    // Pointer to the current basic block
    INSTTYPE type;              // Cfg type of instruction (e.g. IRET)

    // Declare a queue of targets not yet processed yet. This has to be
    // individual to the procedure!
    TARGETS targets;

    // Indicates whether or not the next instruction to be decoded is the
    // lexical successor of the current one. Will be true for all NCTs and for
    // CTIs with a fall through branch.
    bool sequentialDecode = true;

    Cfg* pCfg = pProc->getCFG();

    // Initialise the queue of control flow targets that have yet to be decoded.
    targets.push(uAddr);

    // Clear the pointer used by the caller prologue code to access the last
    // call rtl of this procedure
    //decoder.resetLastCall();

    while ((uAddr = nextAddress(targets, pCfg)) != 0)
        {

            // The list of RTLs for the current basic block
            list<HRTL*>* BB_rtls = new list<HRTL*>();

            // Keep decoding sequentially until a CTI without a fall through branch
            // is decoded
            ADDRESS start = uAddr;
            DecodeResult inst;
            while (sequentialDecode)
                {

                    // Decode and classify the current instruction
                    if (progOptions.trace)
                        cout << "*" << hex << uAddr << "\t" << flush;

                    // Decode the inst at uAddr.
                    inst = decoder.decodeInstruction(uAddr, delta, pProc);

                    // Need to construct a new list of RTLs if a basic block has just
                    // been finished but decoding is continuing from its lexical
                    // successor
                    if (BB_rtls == NULL)
                        BB_rtls = new list<HRTL*>();

                    HRTL* pRtl = inst.rtl;
                    if (inst.numBytes == 0)
                        {
                            // An invalid instruction. Most likely because a call did
                            // not return (e.g. call _exit()), etc. Best thing is to
                            // emit a INVALID BB, and continue with valid instructions
                            ostrstream ost;
                            ost << "invalid instruction at " << hex << uAddr;
                            warning(str(ost));
                            // Emit the RTL anyway, so we have the address and maybe
                            // some other clues
                            BB_rtls->push_back(new RTL(uAddr));
                            pBB = pCfg->newBB(BB_rtls, INVALID, 0);
                            sequentialDecode = false;
                            BB_rtls = NULL;
                            continue;
                        }

                    HLJump* rtl_jump = static_cast<HLJump*>(pRtl);

                    // Display RTL representation if asked
                    if (progOptions.rtl) pRtl->print();

                    ADDRESS uDest;

                    switch (pRtl->getKind())
                        {

                        case JUMP_HRTL:
                        {
                            uDest = rtl_jump->getFixedDest();

                            // Handle one way jumps and computed jumps separately
                            if (uDest != NO_ADDRESS)
                                {
                                    BB_rtls->push_back(pRtl);
                                    sequentialDecode = false;

                                    pBB = pCfg->newBB(BB_rtls,ONEWAY,1);

                                    // Exit the switch now and stop decoding sequentially if the
                                    // basic block already existed
                                    if (pBB == 0)
                                        {
                                            sequentialDecode = false;
                                            BB_rtls = NULL;
                                            break;
                                        }

                                    // Add the out edge if it is to a destination within the
                                    // procedure
                                    if (uDest < uUpper)
                                        {
                                            visit(pCfg, uDest, targets, pBB);
                                            pCfg->addOutEdge(pBB, uDest, true);
                                        }
                                    else
                                        {
                                            ostrstream ost;
                                            ost << "Error: Instruction at " << hex << uAddr;
                                            ost << " branches beyond end of section, to ";
                                            ost << uDest;
                                            error(str(ost));
                                        }
                                }
                            break;
                        }

                        case NWAYJUMP_HRTL:
                        {
                            BB_rtls->push_back(pRtl);
                            // We create the BB as a COMPJUMP type, then change
                            // to an NWAY if it turns out to be a switch stmt
                            pBB = pCfg->newBB(BB_rtls, COMPJUMP, 0);
                            if (isSwitch(pBB, rtl_jump->getDest(), pProc, pBF))
                                {
                                    processSwitch(pBB, delta, pCfg, targets, pBF);
                                }
                            else   // Computed jump
                                {
                                    // Not a switch statement
                                    ostrstream ost;
                                    string sKind("JUMP");
                                    if (type == I_COMPCALL) sKind = "CALL";
                                    ost << "COMPUTED " << sKind << " at "
                                        << hex << uAddr << endl;
                                    warning(str(ost));
                                    BB_rtls = NULL;    // New HRTLList for next BB
                                }
                            sequentialDecode = false;
                            break;
                        }



                        case JCOND_HRTL:
                        {
                            uDest = rtl_jump->getFixedDest();
                            BB_rtls->push_back(pRtl);
                            pBB = pCfg->newBB(BB_rtls, TWOWAY, 2);

                            // Stop decoding sequentially if the basic block already existed
                            // otherwise complete the basic block
                            if (pBB == 0)
                                sequentialDecode = false;
                            else
                                {

                                    // Add the out edge if it is to a destination within the
                                    // procedure
                                    if (uDest < uUpper)
                                        {
                                            visit(pCfg, uDest, targets, pBB);
                                            pCfg->addOutEdge(pBB, uDest, true);
                                        }
                                    else
                                        {
                                            ostrstream ost;
                                            ost << "Error: Instruction at " << hex << uAddr;
                                            ost << " branches beyond end of section, to ";
                                            ost << uDest;
                                            error(str(ost));
                                        }

                                    // Add the fall-through outedge
                                    pCfg->addOutEdge(pBB, uAddr + inst.numBytes);
                                }

                            // Create the list of RTLs for the next basic block and continue
                            // with the next instruction.
                            BB_rtls = NULL;
                            break;
                        }

                        case CALL_HRTL:
                        {
                            HLCall* call = static_cast<HLCall*>(pRtl);

                            // Treat computed and static calls seperately
                            if (call->isComputed())
                                {
                                    BB_rtls->push_back(pRtl);
                                    pBB = pCfg->newBB(BB_rtls, COMPCALL, 1);

                                    // Stop decoding sequentially if the basic block already
                                    // existed otherwise complete the basic block
                                    if (pBB == 0)
                                        sequentialDecode = false;
                                    else
                                        pCfg->addOutEdge(pBB, uAddr + inst.numBytes);

                                }
                            else        // Static call
                                {

                                    BB_rtls->push_back(pRtl);

                                    // Find the address of the callee.
                                    ADDRESS uNewAddr = call->getFixedDest();

                                    // Add this non computed call site to the set of call
                                    // sites which need to be analysed later.
                                    pCfg->addCall(call);

                                    // Record the called address as the start of a new
                                    // procedure if it didn't already exist.
                                    if ((uNewAddr != NO_ADDRESS) &&
                                            prog.findProc(uNewAddr) == NULL)
                                        {
                                            prog.visitProc(uNewAddr);
                                            if (progOptions.trace)
                                                cout << "p" << hex << uNewAddr << "\t" << flush;
                                        }

                                    // Check if this is the _exit function. May prevent us from
                                    // attempting to decode invalid instructions.
                                    char* name = prog.pBF->SymbolByAddress(uNewAddr);
                                    if (name && strcmp(name, "_exit") == 0)
                                        {
                                            // Create the new basic block
                                            pBB = pCfg->newBB(BB_rtls, CALL, 0);

                                            // Stop decoding sequentially
                                            sequentialDecode = false;
                                        }
                                    else
                                        {
                                            // Create the new basic block
                                            pBB = pCfg->newBB(BB_rtls, CALL, 1);

                                            if (call->isReturnAfterCall())
                                                {
                                                    // Constuct the RTLs for the new basic block
                                                    list<HRTL*>* rtls = new list<HRTL*>();
                                                    // The only RTL in the basic block is a high level
                                                    // return that doesn't have any RTs.
                                                    rtls->push_back(new HLReturn(0, NULL));

                                                    BasicBlock* returnBB = pCfg->newBB(rtls, RET, 0);
                                                    // Add out edge from call to return
                                                    pCfg->addOutEdge(pBB, returnBB);
                                                    // Put a label on the return BB (since it's an
                                                    // orphan); a jump will be reqd
                                                    pCfg->setLabel(returnBB);
                                                    pBB->setJumpReqd();
                                                    // Give the enclosing proc a dummy callee epilogue
                                                    pProc->setEpilogue(new CalleeEpilogue("__dummy",
                                                                                          list<string>()));
                                                    // Mike: do we need to set return locations?
                                                    // This ends the function
                                                    sequentialDecode = false;
                                                }
                                            else
                                                {
                                                    // Add the fall through edge if the block didn't
                                                    // already exist
                                                    if (pBB != NULL)
                                                        pCfg->addOutEdge(pBB, uAddr + inst.numBytes);
                                                }
                                        }
                                }

                            // Create the list of RTLs for the next basic block and continue
                            // with the next instruction.
                            BB_rtls = NULL;
                            break;
                        }

                        case RET_HRTL:
                            // Stop decoding sequentially
                            sequentialDecode = false;

                            // Add the RTL to the list
                            BB_rtls->push_back(pRtl);
                            // Create the basic block
                            pBB = pCfg->newBB(BB_rtls, RET, 0);

                            // Create the list of RTLs for the next basic block and continue
                            // with the next instruction.
                            BB_rtls = NULL;    // New HRTLList for next BB
                            break;

                        case SCOND_HRTL:
                            // This is just an ordinary instruction; no control transfer
                            // Fall through
                        case LOW_LEVEL_HRTL:
                            // We must emit empty RTLs for NOPs, because they could be the
                            // destinations of jumps (and splitBB won't work)
                            // Just emit the current instr to the current BB
                            BB_rtls->push_back(pRtl);
                            break;

                        } // switch (pRtl->getKind())

                    uAddr += inst.numBytes;
                    // Update the RTL's number of bytes for coverage analysis (only)
                    inst.rtl->updateNumBytes(inst.numBytes);

                    // If sequentially decoding, check if the next address happens to
                    // be the start of an existing BB. If so, finish off the current BB
                    // (if any RTLs) as a fallthrough, and  no need to decode again
                    // (unless it's an incomplete BB, then we do decode it).
                    // In fact, mustn't decode twice, because it will muck up the
                    // coverage, but also will cause subtle problems like add a call
                    // to the list of calls to be processed, then delete the call RTL
                    // (e.g. Pentium 134.perl benchmark)
                    if (sequentialDecode && pCfg->existsBB(uAddr))
                        {
                            // Create the fallthrough BB, if there are any RTLs at all
                            if (BB_rtls)
                                {
                                    PBB pBB = pCfg->newBB(BB_rtls, FALL, 1);
                                    // Add an out edge to this address
                                    if (pBB)
                                        {
                                            pCfg->addOutEdge(pBB, uAddr);
                                            BB_rtls = NULL;         // Need new list of RTLs
                                        }
                                }
                            // Pick a new address to decode from, if the BB is complete
                            if (!pCfg->isIncomplete(uAddr))
                                sequentialDecode = false;
                        }

                }   // while sequentialDecode

            // Add this range to the coverage
            pProc->addRange(start, uAddr);

            // Must set sequentialDecode back to true
            sequentialDecode = true;

        }   // while nextAddress()

    // This pass is to remove up to 3 nops between ranges.
    // These will be assumed to be padding for alignments of BBs
    // Possibly removes a lot of ranges that could otherwise be combined
    ADDRESS a1, a2;
    COV_CIT ii;
    Coverage temp;
    if (pProc->getFirstGap(a1, a2, ii))
        {
            do
                {
                    int gap = a2 - a1;
                    if (gap < 8)
                        {
                            bool allNops = true;
                            for (int i=0; i < gap; i+= 2)
                                {
                                    // Beware endianness! getWord will work properly
                                    if (getWord(a1+i+delta) != 0x4e71)
                                        {
                                            allNops = false;
                                            break;
                                        }
                                }
                            if (allNops)
                                // Remove this gap, by adding a range equal to the gap
                                // Note: it's not safe to add the range now, so we put
                                // the range into a temp Coverage object to be added later
                                temp.addRange(a1, a2);
                        }
                }
            while (pProc->getNextGap(a1, a2, ii));
        }
    // Now add the ranges in temp
    pProc->addRanges(temp);

}
Пример #28
0
Graph* Connector::connect(Graph* g)
{
	const std::vector<CfgNode*>& nodes = g->getNodes();

	std::map<unsigned int, CfgNode*> id2node = getId2Node(nodes);

	//add a ConnectionQueue to every Module which has more predecessors
	vector<Cfg*> check;
	for (unsigned int i = 0; i < nodes.size(); i++) {
		vector<unsigned int> nexts = nodes[i]->getCfg()->getNext();

		for (unsigned int j = 0; j < nexts.size(); j++){
			Cfg* successor = id2node[nexts[j]]->getCfg();
			bool found = false;

			for(unsigned int k = 0; k < check.size(); k++){
				if(check[k] == successor){
					found = true;
					msg(MSG_INFO, "Creating ConnectionQueue for module %s[Id = %d] because of multiple predecessors",
							successor->getName().c_str(), successor->getID());
					successor->getQueueInstance(true);
					break;
				}
			}
			if(!found)
				check.push_back(successor);
		}
	}

	//connect modules
	for (unsigned int i = 0; i < nodes.size(); i++) {
		CfgNode* fromNode = nodes[i];
		Cfg* cfg = fromNode->getCfg();

		std::vector<unsigned int> nexts = cfg->getNext();

		if (nexts.size()==0) {
			cfg->setupWithoutSuccessors();
		} else {
			for (unsigned int j = 0; j < nexts.size(); j++) {
				CfgNode* toNode = id2node[nexts[j]];

				if (toNode == NULL)
					THROWEXCEPTION("next statement is illegal; there is no node with id=%d", nexts[j]);

				if (connectNodes) // insert the connection in the graph
					g->addEdge(fromNode, toNode);

				msg(MSG_INFO,  "Connecting module %s[Id = %d/%08X] -> %s[Id = %d/%08X]",
						cfg->getName().c_str(), cfg->getID(), cfg->getInstance(),
						id2node[nexts[j]]->getCfg()->getName().c_str(),
						id2node[nexts[j]]->getCfg()->getID(), id2node[nexts[j]]->getCfg()->getInstance());

				if (connectModules) {// connect the modules
					DPRINTF("connecting instances");
					cfg->connectInstances(toNode->getCfg());
				}
			}
		}
	}

	return g;
}
Пример #29
0
void SensorManager::retrieveStatistics(bool ignoreshutdown)
{
	const char* xmlpre = "<vermont>\n\t<sensorData time=\"%s\" host=\"%s\">\n";
	const char* xmlpost = "\t</sensorData>\n</vermont>\n";
	const char* xmlglobals = "\t\t<%s>%s</%s>\n";

	string lockfile = outputFilename + ".lock";

	// we must not wait for the graph lock, else there may be a race condition with
	// the ConfigManager
	while (!graphIS->tryLockGraph()) {
		if (smExitFlag) break;
		timespec timeout = { 0, 200000 };
		nanosleep(&timeout, NULL);
	}

	if (!ignoreshutdown && smExitFlag) return;

	const char* openflags = (append ? "a" : "w");
	FILE* file = fopen(outputFilename.c_str(), openflags);
	if (!file) {
		THROWEXCEPTION("failed to reopen file %s", outputFilename.c_str());
		perror("error:");
	}

	time_t curtime = time(0);
	char curtimestr[100];
	ctime_r(&curtime, curtimestr);
	curtimestr[strlen(curtimestr)-1] = 0;
	fprintf(file, xmlpre, curtimestr, hostname);
	char text[100];
	snprintf(text, 100, "%u", static_cast<uint32_t>(getpid()));
	fprintf(file, xmlglobals, "pid", text, "pid");
	char lasttimestr[100];
	ctime_r(&lasttime, lasttimestr);
	lasttimestr[strlen(lasttimestr)-1] = 0;
	fprintf(file, xmlglobals, "lastTime", lasttimestr, "lastTime");

#if defined(__linux__)
	const char* xmlglobalsuint = "\t\t<%s>%u</%s>\n";
	ThreadCPUInterface::SystemInfo si = ThreadCPUInterface::getSystemInfo();

	fprintf(file, "\t\t<jiffyFrequency>%llu</jiffyFrequency>\n", hertzValue);
	fprintf(file, xmlglobalsuint, "processorAmount", si.noCPUs, "processorAmount");
	for (uint16_t i=0; i<si.sysJiffies.size(); i++) {
		double sysutil = (si.sysJiffies[i]-lastSystemInfo.sysJiffies[i])/(static_cast<double>(curtime)-lasttime)/hertzValue*100;
		double userutil = (si.userJiffies[i]-lastSystemInfo.userJiffies[i])/(static_cast<double>(curtime)-lasttime)/hertzValue*100;
		fprintf(file, "\t\t<processor id=\"%u\"><util type=\"system\">%.2f</util><util type=\"user\">%.2f</util></processor>\n",
				i, sysutil, userutil);
	}
	fprintf(file, "\t\t<memory><free type=\"bytes\">%llu</free><total type=\"bytes\">%llu</total></memory>\n",
			si.freeMemory, si.totalMemory);
	lastSystemInfo = si;
#endif

	//DPRINTF("*** sensor data at %s", ctime(&curtime));

	Graph* g = graphIS->getGraph();
	vector<CfgNode*> nodes = g->getNodes();
	vector<CfgNode*>::iterator iter = nodes.begin();
	while (iter != nodes.end()) {
		Cfg* cfg = (*iter)->getCfg();
		Sensor* s = cfg->getInstance();
		vector<uint32_t> nextids = cfg->getNext();
		writeSensorXML(file, s, cfg->getName().c_str(), cfg->getID(), true, curtime, lasttime, &nextids);

		iter++;
	}

	// iterate through all non-module sensors
	mutex.lock();
	list<SensorEntry>::const_iterator siter = sensors.begin();
	while (siter != sensors.end()) {
		writeSensorXML(file, siter->sensor, siter->name.c_str(), siter->id, false, curtime, lasttime, NULL);
		siter++;
	}
	mutex.unlock();

	fprintf(file, "%s", xmlpost);
	fclose(file);



	graphIS->unlockGraph();
}
Пример #30
0
/*==============================================================================
 * FUNCTION:	  FrontEnd::processProc
 * OVERVIEW:	  Process a procedure, given a native (source machine) address.
 * PARAMETERS:	  address - the address at which the procedure starts
 *				  pProc - the procedure object
 *				  frag - if true, this is just a fragment of a procedure
 *				  spec - if true, this is a speculative decode
 *				  os - the output stream for .rtl output
 * NOTE:		  This is a sort of generic front end. For many processors, this will be overridden
 *					in the FrontEnd derived class, sometimes calling this function to do most of the work
 * RETURNS:		  true for a good decode (no illegal instructions)
 *============================================================================*/
bool FrontEnd::processProc(ADDRESS uAddr, UserProc* pProc, std::ofstream &os, bool frag /* = false */,
		bool spec /* = false */) {
	PBB pBB;					// Pointer to the current basic block
	std::cout<<"Entering Processing Proc\n"; 
	// just in case you missed it
	first_line = true;
	if (AssProgram)
		std::cout <<"Name Of Program : " << AssProgram->name << std::endl;
	Boomerang::get()->alert_new(pProc);
	 
	// We have a set of CallStatement pointers. These may be disregarded if this is a speculative decode
	// that fails (i.e. an illegal instruction is found). If not, this set will be used to add to the set of calls
	// to be analysed in the cfg, and also to call newProc()
	std::list<CallStatement*> callList;

	// Indicates whether or not the next instruction to be decoded is the lexical successor of the current one.
	// Will be true for all NCTs and for CTIs with a fall through branch.
	bool sequentialDecode = true;

	Cfg* pCfg = pProc->getCFG();

	// If this is a speculative decode, the second time we decode the same address, we get no cfg. Else an error.
	if (spec && (pCfg == 0))
		return false;
	assert(pCfg);

	// Initialise the queue of control flow targets that have yet to be decoded.
	targetQueue.initial(uAddr);

	// Clear the pointer used by the caller prologue code to access the last call rtl of this procedure
	//decoder.resetLastCall();

	// ADDRESS initAddr = uAddr;
	int nTotalBytes = 0;
	ADDRESS startAddr = uAddr;
	ADDRESS lastAddr = uAddr;
	ADDRESS address = uAddr;
	std::cout << "Start at address = " << uAddr << std::endl; 
	//------IMPORTANT------------------------------------------------------------------------
	list<AssemblyLabel*>::iterator lbi;
	list<AssemblyLine*>* temp_lines = new list<AssemblyLine*>();
	
	if (AssProgram){
		for(lbi = AssProgram->labelList->begin(); lbi != AssProgram->labelList->end(); ++lbi ){
			if((*lbi)->address == uAddr){
				temp_lines = (*lbi)->lineList;
				std::cout << "***DECODE LABEL: " << (*lbi)->name << std::endl;
				std::cout << "***AT ADDRESS: " << (*lbi)->address << std::endl;
				std::cout << "***NUMBER OF INSTRUCTION: " << (*lbi)->lineList->size() << std::endl;
				break;
			}
		}
	}
	
	list<AssemblyLine*>::iterator li;
	if (temp_lines->size()>0)
		li = temp_lines->begin();
	
	//---------------------------------------------------------------------------------------
	while ((uAddr = targetQueue.nextAddress(pCfg)) != NO_ADDRESS) {
		// The list of RTLs for the current basic block
		std::list<RTL*>* BB_rtls = new std::list<RTL*>();

		// Keep decoding sequentially until a CTI without a fall through branch is decoded
		//ADDRESS start = uAddr;
		DecodeResult inst;
		while (sequentialDecode) {

			// Decode and classify the current source instruction
			if (Boomerang::get()->traceDecoder)
				LOG << "*" << uAddr << "\t";

			// Decode the inst at uAddr.
			
			if(ASS_FILE){
				if(li != temp_lines->end()){

					inst = decodeAssemblyInstruction(uAddr,"assemblySets.at(line)", (*li));
				}
			}
			else
				inst = decodeInstruction(uAddr);
			
			// If invalid and we are speculating, just exit
			if (spec && !inst.valid)
				return false;

			// Need to construct a new list of RTLs if a basic block has just been finished but decoding is
			// continuing from its lexical successor
			if (BB_rtls == NULL)
				BB_rtls = new std::list<RTL*>();

			RTL* pRtl = inst.rtl;
			if (inst.valid == false) {
				
				// Alert the watchers to the problem
				Boomerang::get()->alert_baddecode(uAddr);

				// An invalid instruction. Most likely because a call did not return (e.g. call _exit()), etc.
				// Best thing is to emit a INVALID BB, and continue with valid instructions
				if (VERBOSE) {
					LOG << "Warning: invalid instruction at " << uAddr << ": ";
					// Emit the next 4 bytes for debugging
					for (int ii=0; ii < 4; ii++)
						LOG << (unsigned)(pBF->readNative1(uAddr + ii) & 0xFF) << " ";
					LOG << "\n";
				}
				// Emit the RTL anyway, so we have the address and maybe some other clues
				BB_rtls->push_back(new RTL(uAddr));	 
				pBB = pCfg->newBB(BB_rtls, INVALID, 0);
				sequentialDecode = false; BB_rtls = NULL; continue;
			}
            //pProc->unionDefine = new list<UnionDefine*>();
            pProc->bitVar = AssProgram->bitVar;
            pProc->replacement = AssProgram->replacement;
			// alert the watchers that we have decoded an instruction
			Boomerang::get()->alert_decode(uAddr, inst.numBytes);
			nTotalBytes += inst.numBytes;			
			
			// Check if this is an already decoded jump instruction (from a previous pass with propagation etc)
			// If so, we throw away the just decoded RTL (but we still may have needed to calculate the number
			// of bytes.. ick.)
			std::map<ADDRESS, RTL*>::iterator ff = previouslyDecoded.find(uAddr);
			if (ff != previouslyDecoded.end())
				pRtl = ff->second;

			if (pRtl == NULL) {
				// This can happen if an instruction is "cancelled", e.g. call to __main in a hppa program
				// Just ignore the whole instruction
				if (inst.numBytes > 0)
					uAddr += inst.numBytes;
				continue;
			}
			
			// Display RTL representation if asked
                std::cout<<"RTL: "<<std::endl;
				std::ostringstream st;
				pRtl->print(st);
                std::cout << st.str().c_str()<<std::endl;

	
			ADDRESS uDest;

			// For each Statement in the RTL
			//std::list<Statement*>& sl = pRtl->getList();
			std::list<Statement*> sl = pRtl->getList();
			// Make a copy (!) of the list. This is needed temporarily to work around the following problem.
			// We are currently iterating an RTL, which could be a return instruction. The RTL is passed to
			// createReturnBlock; if this is not the first return statement, it will get cleared, and this will
			// cause problems with the current iteration. The effects seem to be worse for MSVC/Windows.
			// This problem will likely be easier to cope with when the RTLs are removed, and there are special
			// Statements to mark the start of instructions (and their native address).
			// FIXME: However, this workaround breaks logic below where a GOTO is changed to a CALL followed by a return
			// if it points to the start of a known procedure
			std::list<Statement*>::iterator ss;
#if 1
			for (ss = sl.begin(); ss != sl.end(); ss++) { // }
#else
			// The counter is introduced because ss != sl.end() does not work as it should
			// FIXME: why? Does this really fix the problem?
			int counter = sl.size();

			for (ss = sl.begin(); counter > 0; ss++, counter--) {
#endif
				Statement* s = *ss;
				s->setProc(pProc);		// let's do this really early!
				if (refHints.find(pRtl->getAddress()) != refHints.end()) {
					const char *nam = refHints[pRtl->getAddress()].c_str();
					ADDRESS gu = prog->getGlobalAddr((char*)nam);
					if (gu != NO_ADDRESS) {
						s->searchAndReplace(new Const((int)gu), new Unary(opAddrOf, Location::global(nam, pProc)));
					}
				}
				s->simplify();
				GotoStatement* stmt_jump = static_cast<GotoStatement*>(s);

				// Check for a call to an already existing procedure (including self recursive jumps), or to the PLT
				// (note that a LibProc entry for the PLT function may not yet exist)
				ADDRESS dest;
				Proc* proc;
				
				if (s->getKind() == STMT_GOTO) {
					dest = stmt_jump->getFixedDest();
					if (dest != NO_ADDRESS) {
						proc = prog->findProc(dest);
						if (proc == NULL) {
							if(!ASS_FILE){
								if (pBF->IsDynamicLinkedProc(dest))
									proc = prog->setNewProc(dest);
							}
						}
						if (proc != NULL && proc != (Proc*)-1) {
							s = new CallStatement();
							CallStatement *call = static_cast<CallStatement*>(s);
							call->setDest(dest);
							call->setDestProc(proc);
							call->setReturnAfterCall(true);
							// also need to change it in the actual RTL
							std::list<Statement*>::iterator ss1 = ss;
							ss1++;
							assert(ss1 == sl.end());
							pRtl->replaceLastStmt(s);
							*ss = s;
						}
					}
				}

				switch (s->getKind())
				{

				case STMT_GOTO: {
					uDest = stmt_jump->getFixedDest();
	
					// Handle one way jumps and computed jumps separately
					if (uDest != NO_ADDRESS) {

						BB_rtls->push_back(pRtl);
						sequentialDecode = false;

						pBB = pCfg->newBB(BB_rtls,ONEWAY,1);
						BB_rtls = NULL;		// Clear when make new BB

						// Exit the switch now if the basic block already existed
						if (pBB == 0) {
							break;
						}

						// Add the out edge if it is to a destination within the
						// procedure

						if (uDest < pBF->getLimitTextHigh()) {
							targetQueue.visit(pCfg, uDest, pBB);
							pCfg->addOutEdge(pBB, uDest, true);
						}
						else {
							std::cout<<"Entering Processing Proc5\n"; 
							if (!ASS_FILE)
								LOG << "Error: Instruction at " << uAddr << " branches beyond end of section, to "
									<< uDest << "\n";
							else{
								targetQueue.visit(pCfg, uDest, pBB);
								pCfg->addOutEdge(pBB, uDest, true);
							} 

						}
					}
					break;
				}

				case STMT_CASE: {
					Exp* pDest = stmt_jump->getDest();
					if (pDest == NULL) {				// Happens if already analysed (now redecoding)
						// SWITCH_INFO* psi = ((CaseStatement*)stmt_jump)->getSwitchInfo();
						BB_rtls->push_back(pRtl);
						pBB = pCfg->newBB(BB_rtls, NWAY, 0);	// processSwitch will update num outedges
						pBB->processSwitch(pProc);		// decode arms, set out edges, etc
						sequentialDecode = false;		// Don't decode after the jump
						BB_rtls = NULL;					// New RTLList for next BB
						break;							// Just leave it alone
					}
					// Check for indirect calls to library functions, especially in Win32 programs
					if (pDest && pDest->getOper() == opMemOf &&
							pDest->getSubExp1()->getOper() == opIntConst && 
							pBF->IsDynamicLinkedProcPointer(((Const*)pDest->getSubExp1())->getAddr())) {
						if (VERBOSE)
							LOG << "jump to a library function: " << stmt_jump << ", replacing with a call/ret.\n";
						// jump to a library function
						// replace with a call ret
						// TODO: 
						std::string func = pBF->GetDynamicProcName(
							((Const*)stmt_jump->getDest()->getSubExp1())->getAddr());
						//------------------------------------
						CallStatement *call = new CallStatement;
						call->setDest(stmt_jump->getDest()->clone());
						LibProc *lp = pProc->getProg()->getLibraryProc(func.c_str());
						if (lp == NULL)
							LOG << "getLibraryProc returned NULL, aborting\n";
						assert(lp);
						call->setDestProc(lp);
						std::list<Statement*>* stmt_list = new std::list<Statement*>;
						stmt_list->push_back(call);
						BB_rtls->push_back(new RTL(pRtl->getAddress(), stmt_list));
						pBB = pCfg->newBB(BB_rtls, CALL, 1);
						appendSyntheticReturn(pBB, pProc, pRtl);
						sequentialDecode = false;
						BB_rtls = NULL;
						if (pRtl->getAddress() == pProc->getNativeAddress()) {
							// it's a thunk
							// Proc *lp = prog->findProc(func.c_str());
							func = std::string("__imp_") + func;
							pProc->setName(func.c_str());
							//lp->setName(func.c_str());
							Boomerang::get()->alert_update_signature(pProc);
						}
						callList.push_back(call);
						ss = sl.end(); ss--;	// get out of the loop
						break;
					}
					BB_rtls->push_back(pRtl);
					// We create the BB as a COMPJUMP type, then change to an NWAY if it turns out to be a switch stmt
					pBB = pCfg->newBB(BB_rtls, COMPJUMP, 0);
					LOG << "COMPUTED JUMP at " << uAddr << ", pDest = " << pDest << "\n";
					if (Boomerang::get()->noDecompile) {
						// try some hacks
						if (pDest->isMemOf() && pDest->getSubExp1()->getOper() == opPlus &&
								pDest->getSubExp1()->getSubExp2()->isIntConst()) {
							// assume subExp2 is a jump table
							ADDRESS jmptbl = ((Const*)pDest->getSubExp1()->getSubExp2())->getInt();
							unsigned int i;
							for (i = 0; ; i++) {
								ADDRESS uDest = pBF->readNative4(jmptbl + i * 4);
								if (pBF->getLimitTextLow() <= uDest && uDest < pBF->getLimitTextHigh()) {
									LOG << "  guessed uDest " << uDest << "\n";
									targetQueue.visit(pCfg, uDest, pBB);
									pCfg->addOutEdge(pBB, uDest, true);
								} else
									break;
							}
							pBB->updateType(NWAY, i);
						}
					}
					sequentialDecode = false;
					BB_rtls = NULL;		// New RTLList for next BB
					break;
				}


				case STMT_BRANCH: {
					uDest = stmt_jump->getFixedDest();
					BB_rtls->push_back(pRtl);
					pBB = pCfg->newBB(BB_rtls, TWOWAY, 2);

					// Stop decoding sequentially if the basic block already existed otherwise complete the basic block
					if (pBB == 0)
						sequentialDecode = false;
					else {

						// Add the out edge if it is to a destination within the procedure
						if (!ASS_FILE){
							if (uDest < pBF->getLimitTextHigh()) {
								targetQueue.visit(pCfg, uDest, pBB);
								pCfg->addOutEdge(pBB, uDest, true);
							}
							else
								LOG << "Error: Instruction at " << uAddr << " branches beyond end of section, to "
									<< uDest << "\n";
						}
						else {
								targetQueue.visit(pCfg, uDest, pBB);
								pCfg->addOutEdge(pBB, uDest, true);
						}

						// Add the fall-through outedge
						pCfg->addOutEdge(pBB, uAddr + inst.numBytes); 
					}

					// Create the list of RTLs for the next basic block and continue with the next instruction.
					BB_rtls = NULL;
					break;
				}

				case STMT_CALL: {
					CallStatement* call = static_cast<CallStatement*>(s);
					
					// Check for a dynamic linked library function
					// TODO: solution dont use pBF
					if (!ASS_FILE){ 
						if (call->getDest()->getOper() == opMemOf &&
								call->getDest()->getSubExp1()->getOper() == opIntConst &&
								pBF->IsDynamicLinkedProcPointer(((Const*)call->getDest()->getSubExp1())->getAddr())) {
							// Dynamic linked proc pointers are treated as static.
							const char *nam = pBF->GetDynamicProcName( ((Const*)call->getDest()->getSubExp1())->getAddr());
							Proc *p = pProc->getProg()->getLibraryProc(nam);
							call->setDestProc(p);
							call->setIsComputed(false);
						}
					}
					else {
						if (call->getDest()->getOper() == opMemOf &&
								call->getDest()->getSubExp1()->getOper() == opIntConst &&
								funcsType.find(((Const*)call->getDest()->getSubExp1())->getAddr())->second) {
							// Dynamic linked proc pointers are treated as static.
							const char *nam = namesList.find(((Const*)call->getDest()->getSubExp1())->getAddr())->second;
							Proc *p = pProc->getProg()->getLibraryProc(nam);
							call->setDestProc(p);
							call->setIsComputed(false);
						}
					}

					// Is the called function a thunk calling a library function?
					// A "thunk" is a function which only consists of: "GOTO library_function"
					// Should i modify
					if (!ASS_FILE){
						if(	call &&	call->getFixedDest() != NO_ADDRESS ) {
							// Get the address of the called function.
							ADDRESS callAddr=call->getFixedDest();
							// It should not be in the PLT either, but getLimitTextHigh() takes this into account
							if (callAddr < pBF->getLimitTextHigh()) {
								// Decode it.
								DecodeResult decoded=decodeInstruction(callAddr);
								if (decoded.valid) { // is the instruction decoded succesfully?
									// Yes, it is. Create a Statement from it.
									RTL *rtl = decoded.rtl;
									Statement* first_statement = *rtl->getList().begin();
									if (first_statement) {
										first_statement->setProc(pProc);
										first_statement->simplify();
										GotoStatement* stmt_jump = static_cast<GotoStatement*>(first_statement);
										// In fact it's a computed (looked up) jump, so the jump seems to be a case
										// statement.
										//TODO : We dont handle this case
										if ( first_statement->getKind() == STMT_CASE &&
											stmt_jump->getDest()->getOper() == opMemOf &&
											stmt_jump->getDest()->getSubExp1()->getOper() == opIntConst &&
											pBF->IsDynamicLinkedProcPointer(((Const*)stmt_jump->getDest()->getSubExp1())->
												getAddr())) // Is it an "DynamicLinkedProcPointer"?
										{
											// Yes, it's a library function. Look up it's name.
											ADDRESS a = ((Const*)stmt_jump->getDest()->getSubExp1())->getAddr();
											// TODO : We dont handle this case
											const char *nam = pBF->GetDynamicProcName(a);
											// Assign the proc to the call
											Proc *p = pProc->getProg()->getLibraryProc(nam);
											if (call->getDestProc()) {
												// prevent unnecessary __imp procs
												prog->removeProc(call->getDestProc()->getName());
											}
											call->setDestProc(p);
											call->setIsComputed(false);
											call->setDest(Location::memOf(new Const(a)));
										}
									}
								}
							}
						}
					}
					// Treat computed and static calls separately
					if (call->isComputed()) {
						BB_rtls->push_back(pRtl);
						pBB = pCfg->newBB(BB_rtls, COMPCALL, 1);

						// Stop decoding sequentially if the basic block already
						// existed otherwise complete the basic block
						if (pBB == 0)
							sequentialDecode = false;
						else
							pCfg->addOutEdge(pBB, uAddr + inst.numBytes);
						// Add this call to the list of calls to analyse. We won't
						// be able to analyse it's callee(s), of course.
						callList.push_back(call);
					}
					else {		// Static call
						// Find the address of the callee.
						ADDRESS uNewAddr = call->getFixedDest();

						// Calls with 0 offset (i.e. call the next instruction) are simply pushing the PC to the
						// stack. Treat these as non-control flow instructions and continue.
						if (uNewAddr == uAddr + inst.numBytes)
							break;

						// Call the virtual helper function. If implemented, will check for machine specific funcion
						// calls
						if (helperFunc(uNewAddr, uAddr, BB_rtls)) {
							// We have already added to BB_rtls
							pRtl = NULL;		// Discard the call semantics
							break;
						}

						BB_rtls->push_back(pRtl);

						// Add this non computed call site to the set of call sites which need to be analysed later.
						//pCfg->addCall(call);
						callList.push_back(call);

						// Record the called address as the start of a new procedure if it didn't already exist.
						if (uNewAddr && uNewAddr != NO_ADDRESS && pProc->getProg()->findProc(uNewAddr) == NULL) {
							callList.push_back(call);
							//newProc(pProc->getProg(), uNewAddr);
							if (Boomerang::get()->traceDecoder)
								LOG << "p" << uNewAddr << "\t";
						}

 						// Check if this is the _exit or exit function. May prevent us from attempting to decode
						// invalid instructions, and getting invalid stack height errors
						
						const char* name;
						if (!ASS_FILE){
							name = pBF->SymbolByAddress(uNewAddr);
							if (name == NULL && call->getDest()->isMemOf() && 
												call->getDest()->getSubExp1()->isIntConst()) {
								ADDRESS a = ((Const*)call->getDest()->getSubExp1())->getInt();
								if (pBF->IsDynamicLinkedProcPointer(a))
									name = pBF->GetDynamicProcName(a);
							}
						}
						else {
							name = namesList.find(uNewAddr)->second;
						}	
						if (name && noReturnCallDest(name)) {
							// Make sure it has a return appended (so there is only one exit from the function)
							//call->setReturnAfterCall(true);		// I think only the Sparc frontend cares
							// Create the new basic block
							pBB = pCfg->newBB(BB_rtls, CALL, 1);
							appendSyntheticReturn(pBB, pProc, pRtl);

							// Stop decoding sequentially
							sequentialDecode = false;
						}
						else {
							// Create the new basic block
							pBB = pCfg->newBB(BB_rtls, CALL, 1);

							if (call->isReturnAfterCall()) {
								// Constuct the RTLs for the new basic block
								std::list<RTL*>* rtls = new std::list<RTL*>();
								// The only RTL in the basic block is one with a ReturnStatement
								std::list<Statement*>* sl = new std::list<Statement*>;
								sl->push_back(new ReturnStatement());
								rtls->push_back(new RTL(pRtl->getAddress()+1, sl));
		
								BasicBlock* returnBB = pCfg->newBB(rtls, RET, 0);
								// Add out edge from call to return
								pCfg->addOutEdge(pBB, returnBB);
								// Put a label on the return BB (since it's an orphan); a jump will be reqd
								pCfg->setLabel(returnBB);
								pBB->setJumpReqd();
								// Mike: do we need to set return locations?
								// This ends the function
								sequentialDecode = false;
							}
							else {
								// Add the fall through edge if the block didn't
								// already exist
								if (pBB != NULL)
									pCfg->addOutEdge(pBB, uAddr+inst.numBytes);
							}
						}
					}

					extraProcessCall(call, BB_rtls);

					// Create the list of RTLs for the next basic block and continue with the next instruction.
					BB_rtls = NULL;
					break;	
				}

				case STMT_RET: {
					// Stop decoding sequentially
					sequentialDecode = false;

					pBB = createReturnBlock(pProc, BB_rtls, pRtl);

					// Create the list of RTLs for the next basic block and
					// continue with the next instruction.
					BB_rtls = NULL;		// New RTLList for next BB
				}
				break;

				case STMT_BOOLASSIGN:
					// This is just an ordinary instruction; no control transfer
					// Fall through
				case STMT_JUNCTION:
					// FIXME: Do we need to do anything here?
				case STMT_ASSIGN:
				case STMT_PHIASSIGN:
				case STMT_IMPASSIGN:
				case STMT_IMPREF:
					// Do nothing
					break;
		
				} // switch (s->getKind())
			}
			if (BB_rtls && pRtl)
				// If non null, we haven't put this RTL into a the current BB as yet
				BB_rtls->push_back(pRtl);

			if (inst.reDecode)
				// Special case: redecode the last instruction, without advancing uAddr by numBytes
				continue;
			uAddr += inst.numBytes;
			
			if (uAddr > lastAddr)
				lastAddr = uAddr;

			// If sequentially decoding, check if the next address happens to be the start of an existing BB. If so,
			// finish off the current BB (if any RTLs) as a fallthrough, and no need to decode again (unless it's an
			// incomplete BB, then we do decode it).
			// In fact, mustn't decode twice, because it will muck up the coverage, but also will cause subtle problems
			// like add a call to the list of calls to be processed, then delete the call RTL (e.g. Pentium 134.perl
			// benchmark)
			if (sequentialDecode && pCfg->existsBB(uAddr)) {
				// Create the fallthrough BB, if there are any RTLs at all
				if (BB_rtls) {
					PBB pBB = pCfg->newBB(BB_rtls, FALL, 1);
					// Add an out edge to this address
					if (pBB) {
						pCfg->addOutEdge(pBB, uAddr);
						BB_rtls = NULL;			// Need new list of RTLs
					}
				}
				// Pick a new address to decode from, if the BB is complete
				if (!pCfg->isIncomplete(uAddr))
					sequentialDecode = false;
			}
			if(AssProgram)
			++ li ;
		}	// while sequentialDecode
		
		// Add this range to the coverage
//		  pProc->addRange(start, uAddr);

		// Must set sequentialDecode back to true
		sequentialDecode = true;
		

	}	// while nextAddress() != NO_ADDRESS

	//ProgWatcher *w = prog->getWatcher();
	//if (w)
	//	  w->alert_done(pProc, initAddr, lastAddr, nTotalBytes);

	// Add the callees to the set of CallStatements, and also to the Prog object
	std::list<CallStatement*>::iterator it;
	for (it = callList.begin(); it != callList.end(); it++) {
		ADDRESS dest = (*it)->getFixedDest();
		// Don't speculatively decode procs that are outside of the main text section, apart from dynamically
		// linked ones (in the .plt)
		// TODO: change pBF pointers
		if (!ASS_FILE){
			if (pBF->IsDynamicLinkedProc(dest) || !spec || (dest < pBF->getLimitTextHigh())) {
				pCfg->addCall(*it);
				// Don't visit the destination of a register call
				Proc *np = (*it)->getDestProc();
				if (np == NULL && dest != NO_ADDRESS) {
					//np = newProc(pProc->getProg(), dest);
					np = pProc->getProg()->setNewProc(dest);
				}
				if (np != NULL) {
					np->setFirstCaller(pProc);
					pProc->addCallee(np);
				}			
			}
		}
		else{
				pCfg->addCall(*it);
				// Don't visit the destination of a register call
				Proc *np = (*it)->getDestProc();
				if (np == NULL && dest != NO_ADDRESS) {
					//np = newProc(pProc->getProg(), dest);
					np = pProc->getProg()->setNewProc(dest);
				}
				if (np != NULL) {
					np->setFirstCaller(pProc);
					pProc->addCallee(np);
				}			
		}
	}

	Boomerang::get()->alert_decode(pProc, startAddr, lastAddr, nTotalBytes);
	std::cout<< "finished processing proc " << pProc->getName() << " at address " << pProc->getNativeAddress() << "\n";
	if (VERBOSE)
		LOG << "finished processing proc " << pProc->getName() << " at address " << pProc->getNativeAddress() << "\n";

	return true;
}

/*==============================================================================
 * FUNCTION:	FrontEnd::getInst
 * OVERVIEW:	Fetch the smallest (nop-sized) instruction, in an endianness independent manner
 * NOTE:		Frequently overridden
 * PARAMETERS:	addr - host address to getch from
 * RETURNS:		An integer with the instruction in it
 *============================================================================*/
int FrontEnd::getInst(int addr)
{
	return (int)(*(unsigned char*)addr);
}


/*==============================================================================
 * FUNCTION:	TargetQueue::visit
 * OVERVIEW:	Visit a destination as a label, i.e. check whether we need to queue it as a new BB to create later.
 *				Note: at present, it is important to visit an address BEFORE an out edge is added to that address.
 *				This is because adding an out edge enters the address into the Cfg's BB map, and it looks like the
 *				BB has already been visited, and it gets overlooked. It would be better to have a scheme whereby
 *				the order of calling these functions (i.e. visit() and AddOutEdge()) did not matter.
 * PARAMETERS:	pCfg - the enclosing CFG
 *				uNewAddr - the address to be checked
 *				pNewBB - set to the lower part of the BB if the address
 *				already exists as a non explicit label (BB has to be split)
 * RETURNS:		<nothing>
 *============================================================================*/
void TargetQueue::visit(Cfg* pCfg, ADDRESS uNewAddr, PBB& pNewBB) {
	// Find out if we've already parsed the destination
	bool bParsed = pCfg->label(uNewAddr, pNewBB);
	// Add this address to the back of the local queue,
	// if not already processed
	if (!bParsed) {
		targets.push(uNewAddr);
		if (Boomerang::get()->traceDecoder)
			LOG << ">" << uNewAddr << "\t";
	}
}