// =============================================================================
// replaceCallsInProcess
// 
// Replace indirect calls to write() or read() by direct calls 
// in the given process.
// =============================================================================
void TLMBasicPassImpl::replaceCallsInProcess(sc_core::sc_module *initiatorMod,
                                         sc_core::sc_process_b *proc) {
    
    // Get associate function
    std::string fctName = proc->func_process;
	std::string modType = typeid(*initiatorMod).name();
	std::string mainFctName = "_ZN" + modType + 
    utostr(fctName.size()) + fctName + "Ev";
	Function *oldProcf = this->llvmMod->getFunction(mainFctName);
    if (oldProcf==NULL)
        return;
    
    // We do not modifie the original function
    // Instead, we create a clone.
    Function *procf = createProcess(oldProcf, initiatorMod);
    void *funPtr = this->engine->getPointerToFunction(procf); 
    sc_core::SC_ENTRY_FUNC_OPT scfun = 
    reinterpret_cast<sc_core::SC_ENTRY_FUNC_OPT>(funPtr);
    proc->m_semantics_p = scfun;
    std::string procfName = procf->getName();
    MSG("      Replace in the process's function : "+procfName+"\n");
    
    std::ostringstream oss;
    sc_core::sc_module *targetMod;
    std::vector<CallInfo*> *work = new std::vector<CallInfo*>;
    
    inst_iterator ii;
    for (ii = inst_begin(procf); ii!=inst_end(procf); ii++) {
        Instruction &i = *ii;
        CallSite cs(&i);
        if (cs.getInstruction()) {
            // Candidate for a replacement
            Function *oldfun = cs.getCalledFunction();
            if (oldfun!=NULL && !oldfun->isDeclaration()) {
                std::string name = oldfun->getName();
                // === Write ===
                if (!strcmp(name.c_str(), wFunName.c_str())) {
                    
                    CallInfo *info = new CallInfo();
                    info->oldcall = dyn_cast<CallInst>(cs.getInstruction());
                    MSG("       Checking adress : ");
                    // Retrieve the adress argument by executing 
                    // the appropriated piece of code
                    SCJit *scjit = new SCJit(this->llvmMod, this->elab);
                    Process *irProc = this->elab->getProcess(proc);
                    scjit->setCurrentProcess(irProc);                    
                    bool jitErr = false;
                    info->addrArg = cs.getArgument(1);
                    int value = 
                    scjit->jitInt(procf, info->oldcall, info->addrArg, &jitErr);
                    if(jitErr) {
                        std::cout << "       cannot get the address value!" 
                          << std::endl;
                    } else {
                    oss.str("");  oss << std::hex << value;
                    MSG("0x"+oss.str()+"\n");
                    basic::addr_t a = static_cast<basic::addr_t>(value);            
                    
                    // Checking address alignment
                    if(value % sizeof(basic::data_t)) {
                        std::cerr << "  unaligned write : " <<
                        std::hex << value << std::endl;
                        abort();
                    }

                    // Retreive the target module using the address
                    targetMod =  getTargetModule(initiatorMod, a);
                                    
                    // Save informations to build a new call later
                    FunctionType *writeFunType = 
                        this->basicWriteFun->getFunctionType();  
                    info->targetType = writeFunType->getParamType(0);
                    LLVMContext &context = getGlobalContext();
                    IntegerType *intType;
                    if (this->is64Bit) {
                        intType = Type::getInt64Ty(context);
                    } else {
                        intType = Type::getInt32Ty(context);
                    }
                    info->targetModVal = ConstantInt::getSigned(intType,
                                        reinterpret_cast<intptr_t>(targetMod));
                    info->dataArg = cs.getArgument(2);
                    work->push_back(info);
                    }
   
                } else
                    
                // === Read ===
                if (!strcmp(name.c_str(), rFunName.c_str())) {
                    
                    // Not yet supported
                                        
                }
            }  
        }
    
    }
        
    // Before
    //procf->dump();
    
    // Replace calls
    std::vector<CallInfo*>::iterator it;
    for (it = work->begin(); it!=work->end(); ++it) {
        CallInfo *i = *it;
        
        LLVMContext &context = getGlobalContext();
        FunctionType *writeFunType = 
        this->writeFun->getFunctionType();
        IntegerType *i64 = Type::getInt64Ty(context);
        // Get a pointer to the target module
        basic::target_module_base *tmb = 
        dynamic_cast<basic::target_module_base*>(targetMod);
        Value *ptr = 
        ConstantInt::getSigned(i64, reinterpret_cast<intptr_t>(tmb));
        IntToPtrInst *modPtr = new IntToPtrInst(ptr, 
                                                writeFunType->getParamType(0),
                                                "myitp", i->oldcall);
        // Get a the address value
        LoadInst *addr = new LoadInst(i->addrArg, "", i->oldcall);
        
        // Create the new call
        Value *args[] = {modPtr, addr, i->dataArg};
        i->newcall = CallInst::Create(this->writeFun, ArrayRef<Value*>(args, 3));
        
        // Replace the old call
        BasicBlock::iterator it(i->oldcall);
        ReplaceInstWithInst(i->oldcall->getParent()->getInstList(), it, i->newcall);
        i->oldcall->replaceAllUsesWith(i->newcall);
        
        // Inline the new call
        DataLayout *td = new DataLayout(this->llvmMod);
        InlineFunctionInfo ifi(NULL, td);
        bool success = InlineFunction(i->newcall, ifi);
        if(!success) {
            MSG("       The call cannot be inlined (it's not an error :D)");
        }
        
        MSG("       Call optimized (^_-)\n");
        callOptCounter++;
    }
    
    //std::cout << "==================================\n";
    // Run preloaded passes on the function to propagate constants
    funPassManager->run(*procf);
    // After
    //procf->dump();        
    // Check if the function is corrupt
    verifyFunction(*procf);
    this->engine->recompileAndRelinkFunction(procf);
}
Exemple #2
0
void main()
{
	fstream ifile,ofile;
	settings u,t;
	char ch,user1[20],pass1[20];
	int a=1,b,c,d,e;
again:
	int i = mainmenu();
	switch(i)
	{
case 1:
	{
newuser:
		/* adding a user */
		clrscr();
	ofile.open("settings.dat",ios::binary|ios::out|ios::app);
	u.getuser();
	if(u.usercheck()==1){cout<<"\n Sorry  User already exists!returning to main menu...";ofile.close();getch();goto newuser;}
	ofile.write((char*)&u,sizeof(u));
	ofile.close();
	cout<<"\n User added.press m to return to main menu ";
	cin>>ch;
	if(ch == 'm')
	goto again;
	break;
	}
case 2:
{
	/* searching for user */
	clrscr();
	gotoxy(30,15);cout<<" Enter username:"******"settings.dat",ios::binary | ios::in);
	while(!ifile.eof())
	{
	ifile.read((char*)&u,sizeof(u));
	if(strcmp(u.username,user1) == 0)
	{a=0;break;}}
	if(a==0) {gotoxy(30,17); cout<<user1;}
	else {gotoxy(30,17);cout<<"\n not found";}
	ifile.close();
	cout<<"\n Press m to return to main menu";
	cin>>ch;
	if(ch=='m')
	goto again;
}
deluser:
case 3:
{	/* deleting user */
	clrscr();
	gotoxy(20,13);cout<<"\n Entet details of the user to delete: ";
	t.getuser();
	if(t.usercheck()==0){cout<<"\n user not found"; getch();goto again;}
	ifstream ifi("settings.dat",ios::binary);
	ofstream ofi("newsettings.dat",ios::binary);
	while(!ifi.eof())
	{
	ifi.read((char*)&u,sizeof(u));
	if(strcmp(t.username,u.username)!=0)
		ofi.write((char*)&u,sizeof(u));
	}
	ifi.close();
	ofi.close();
	remove("settings.dat");
	rename("newsettings.dat","settings.dat");
	cout<<"\n user deleted.. press m to return to main menu";
	cin>>ch;
	if(ch=='m')
	goto again;
	break;

}

case 4:
{       clrscr();
	gotoxy(30,10);cout<<" the existing users :";
	ifstream file("settings.dat",ios::binary);
	if(file)
	{
	gotoxy(30,12);cout<<"username       password";
	while(file.read((char*)&u,sizeof(u)))
       {
	gotoxy(30,16+i);cout<<u.username<<"\t\t"<<u.password;
	i+=2;
	}
	file.close();
	}
	cout<<"\n Press m to return to main menu";
	cin>>ch;
	if(ch=='m')
	goto again;
}
case 5:
{ofile.open("newsettings.dat",ios::binary|ios::in);
ofile.close();
remove("settings.dat");
rename("newsettings.dat","settings.dat");
goto again;
}
}
}
int test_load(bool with_register)
{
	std::cout << "=============== TEST LOAD ===============" << std::endl;
	ChunkArrayContainer cont2;

	if (with_register)
	{
		ChunkArrayFactory::register_CA<DoubleVecList>();
		ChunkArrayFactory::register_CA<StringListVec>();
		ChunkArrayFactory::register_CA<StringArray>();
	}

	std::ifstream ifi("pipo.map", std::ios::binary);
	cont2.load(ifi);
	ifi.close();

	ChunkArray<float>* att1 = cont2.get_attribute<float>("float");
	ChunkArray<std::string>* att4 = cont2.get_attribute<std::string>("std::string");
	ChunkArray<DoubleVecList>* att2 = cont2.get_attribute<DoubleVecList>("ListVecDouble");
	ChunkArray<StringListVec>* att3 = cont2.get_attribute<StringListVec>("VecListString");
	ChunkArray<StringArray>* att_string_array = cont2.get_attribute<StringArray>("StringArray");

	for(unsigned int i = cont2.begin(); i != cont2.end(); cont2.next(i))
	{
		if (att1)
			std::cout << "FLOAT=" << (*att1)[i] << "/";

		if (att4)
			std::cout << "STR=" << (*att4)[i] << "/";

		if (att2)
		{
			std::cout << " ATT2 = ";
			for (const auto& v : (*att2)[i])
			{
				for (auto x : v)
					std::cout << x << " ";
				std::cout << "/ ";
			}
		}

		if (att3)
		{
			std::cout << " ATT3 = ";
			for (const auto& v : (*att3)[i])
			{
				for (auto x : v)
					std::cout << x << " ";
				std::cout << "/ ";
			}
		}

		if (att_string_array)
		{
			std::cout << "att_string_array : ";
			for(const auto& s: (*att_string_array)[i])
				std::cout << s << " ";
			std::cout << "/ ";
		}

		std::cout << std::endl;
	}
	std::cout << "----------------------------------------" << std::endl;

	return 0;
}