Exemple #1
0
SEXP
R_showModule(SEXP r_module, SEXP asString)
{
    llvm::Module *Mod = GET_REF(r_module, Module);
    verifyModule(*Mod, llvm::PrintMessageAction);
    llvm::PassManager PM;
    std::string str;
    llvm::raw_string_ostream to(str);
    PM.add(llvm::createPrintModulePass(LOGICAL(asString)[0] ? &to : &llvm::outs()));
    PM.run(*Mod);
    if(LOGICAL(asString)[0])
      return(ScalarString(mkChar(str.data())));
    else
      return(R_NilValue);
}
Exemple #2
0
static void codegenModule(Module* m)
{
    // debug info
    gIR->DBuilder.EmitCompileUnit(m);

    // process module members
    for (unsigned k=0; k < m->members->dim; k++) {
        Dsymbol* dsym = static_cast<Dsymbol*>(m->members->data[k]);
        assert(dsym);
        Declaration_codegen(dsym);
    }

    if (global.errors) return;

    // finalize debug info
    gIR->DBuilder.EmitModuleEnd();

    // Skip emission of all the additional module metadata if requested by the user.
    if (!m->noModuleInfo)
    {
        // generate ModuleInfo
        m->genmoduleinfo();

        build_llvm_used_array(gIR);

    #if LDC_LLVM_VER >= 303
        // Add the linker options metadata flag.
        gIR->module->addModuleFlag(llvm::Module::AppendUnique, "Linker Options",
            llvm::MDNode::get(gIR->context(), gIR->LinkerMetadataArgs));
    #endif

    #if LDC_LLVM_VER >= 304
        // Emit ldc version as llvm.ident metadata.
        llvm::NamedMDNode *IdentMetadata = gIR->module->getOrInsertNamedMetadata("llvm.ident");
        std::string Version("ldc version ");
        Version.append(global.ldc_version);
        llvm::Value *IdentNode[] = {
            llvm::MDString::get(gIR->context(), Version)
        };
        IdentMetadata->addOperand(llvm::MDNode::get(gIR->context(), IdentNode));
    #endif
    }

    // verify the llvm
    verifyModule(*gIR->module);
}
Exemple #3
0
		bool generateOutput(const string& fileContents, const string& outputBitCodeName) {
			// Parse the source file
			//cout << "Parsing..." << endl;
			base_expr_node rootAst;
			if (!parse(fileContents, rootAst)) {
				cerr << "Failed to parse source file!" << endl;
				return false;
			}

			// Generate the code
			//cout << "Generating code..." << endl;
			LLVMContext &context = getGlobalContext();
			unique_ptr<Module> module(new Module("", context));
			IRBuilder<> builder(getGlobalContext());

			ast_codegen codeGenerator(module.get(), builder);

			// Generate code for each expression at the root level
			const base_expr* expr = boost::get<base_expr>(&rootAst);
			for (auto& itr : expr->children) {
				boost::apply_visitor(codeGenerator, itr);
			}

			// Perform an LLVM verify as a sanity check
			string errorInfo;
			raw_string_ostream errorOut(errorInfo);

			if (verifyModule(*module, &errorOut)) {
				cerr << "Failed to generate LLVM IR: " << errorInfo << endl;

				module->print(errorOut, nullptr);
				cerr << "Module:" << endl << errorInfo << endl;
				return false;
			}

			// Dump the LLVM IR to a file
			llvm::raw_fd_ostream outStream(outputBitCodeName.c_str(), errorInfo, llvm::sys::fs::F_None);
			llvm::WriteBitcodeToFile(module.get(), outStream);

			return true;
		}
Exemple #4
0
// =============================================================================
// runOnModule
// 
//  
// 
// =============================================================================
bool TwetoPassImpl::runOnModule(Module & M)
{

	MSG("\n============== Tweto Pass =============\n");
	this->llvmMod = &M;

	LinkExternalBitcode(this->llvmMod, ExternalBitCodePath);

	// Retrieve the method that does all the vtable calculations
	// in order to call the actual 'write' method (see replaceCallsInProcess)
	this->writeFun =
	    this->llvmMod->getFunction("tweto_call_write_method");
	if (!this->writeFun) {
		std::cerr << "tweto_call_write_method is missing,";
		std::cerr << "pass aborded!" << std::endl;
		return false;
	}
	// Retrieve the base write method in order to get the types
	// of the 'this' pointer, the address and the data
	// (should be always mangled like this, so if the Basic-protocol's includes
	//  are correctly imported, no error will be throw)
	this->basicWriteFun = this->llvmMod->getFunction(wFunName);
	if (!this->basicWriteFun) {
		std::cerr << "basic's write method is missing,";
		std::cerr << "pass aborded!" << std::endl;
		return false;
	}

	writeFun->dump();

	// Initialize function passes
	DataLayout *target = new DataLayout(this->llvmMod);
	DataLayoutPass *dlpass = new DataLayoutPass(*target);
	funPassManager = new FunctionPassManager(this->llvmMod);
	funPassManager->add(dlpass);
	funPassManager->add(createIndVarSimplifyPass());
	funPassManager->add(createLoopUnrollPass());
	funPassManager->add(createInstructionCombiningPass());
	funPassManager->add(createReassociatePass());
	funPassManager->add(createGVNPass());
	funPassManager->add(createCFGSimplificationPass());
	funPassManager->add(createConstantPropagationPass());

	// Modules
	std::vector < sc_core::sc_module * >modules =
	    sc_core::sc_get_curr_simcontext()->get_module_registry()->
	    m_module_vec;
	std::vector < sc_core::sc_module * >::iterator modIt;
	for (modIt = modules.begin(); modIt < modules.end(); ++modIt) {
		sc_core::sc_module * initiatorMod = *modIt;
		std::string moduleName =
		    (std::string) initiatorMod->name();
		// Optimize this module
		optimize(initiatorMod);
	}

	// Check if the module is corrupt
	verifyModule(*this->llvmMod);
	std::ostringstream oss;
	oss << callOptCounter;
	MSG("\n Pass report - " + oss.str() + "/" + "?");
	MSG(" - opt/total\n");
	MSG("===========================================\n\n");

	// TODO : handle false case
	return true;
}
bool init_plugin(void *self) {
    printf("Initializing plugin llvm_trace\n");

    // Look for llvm_trace:base=dir
    for (int i = 0; i < panda_argc; i++) {
        if(0 == strncmp(panda_argv[i], "llvm_trace", 10)) {
            basedir = strrchr(panda_argv[i], '=');
            if (basedir) basedir++; // advance past '='
        }
    }
    if (basedir == NULL) {
        basedir = default_basedir;
    }

    if (tubtf_on) {
      char tubtf_path[256];
      strcpy(tubtf_path, basedir);
      strcat(tubtf_path, "/tubtf.log");
      tubtf_open(tubtf_path, TUBTF_COLW_64);     
      panda_enable_precise_pc();
    }
    else {
      // XXX: unsafe string manipulations
      char memlog_path[256];
      char funclog_path[256];
      strcpy(memlog_path, basedir);
      strcat(memlog_path, "/llvm-memlog.log");
      open_memlog(memlog_path);
      strcpy(funclog_path, basedir);
      strcat(funclog_path, "/llvm-functions.log");
      funclog = fopen(funclog_path, "w");
    }

    panda_cb pcb;
    panda_enable_memcb();
    pcb.before_block_exec = before_block_exec;
    panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
    pcb.after_block_exec = after_block_exec;
    panda_register_callback(self, PANDA_CB_AFTER_BLOCK_EXEC, pcb);
    pcb.phys_mem_read = phys_mem_read_callback;
    panda_register_callback(self, PANDA_CB_PHYS_MEM_READ, pcb);
    pcb.phys_mem_write = phys_mem_write_callback;
    panda_register_callback(self, PANDA_CB_PHYS_MEM_WRITE, pcb);
    pcb.cb_cpu_restore_state = cb_cpu_restore_state;
    panda_register_callback(self, PANDA_CB_CPU_RESTORE_STATE, pcb);

#ifndef CONFIG_SOFTMMU
    pcb.user_after_syscall = user_after_syscall;
    panda_register_callback(self, PANDA_CB_USER_AFTER_SYSCALL, pcb);
#endif

    if (!execute_llvm){
        panda_enable_llvm();
    }
    llvm::llvm_init();
    panda_enable_llvm_helpers();

    /*
     * Run instrumentation pass over all helper functions that are now in the
     * module, and verify module.
     */
    llvm::Module *mod = tcg_llvm_ctx->getModule();
    for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){
        if (i->isDeclaration()){
            continue;
        }
        PIFP->runOnFunction(*i);
    }
    std::string err;
    if(verifyModule(*mod, llvm::AbortProcessAction, &err)){
        printf("%s\n", err.c_str());
        exit(1);
    }

    return true;
}
Exemple #6
0
void enable_taint(){
    panda_cb pcb;
    pcb.before_block_exec = before_block_exec;
    panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
    pcb.after_block_exec = after_block_exec;
    panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_EXEC, pcb);
    pcb.phys_mem_read = phys_mem_read_callback;
    panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_READ, pcb);
    pcb.phys_mem_write = phys_mem_write_callback;
    panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_WRITE, pcb);
    pcb.cb_cpu_restore_state = cb_cpu_restore_state;
    panda_register_callback(plugin_ptr, PANDA_CB_CPU_RESTORE_STATE, pcb);
    
    if (!execute_llvm){
        panda_enable_llvm();
    }
    llvm::llvm_init();
    panda_enable_llvm_helpers();

    /*
     * Run instrumentation pass over all helper functions that are now in the
     * module, and verify module.
     */
    llvm::Module *mod = tcg_llvm_ctx->getModule();
    for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){
        if (i->isDeclaration()){
            continue;
        }
        PIFP->runOnFunction(*i);
    }
    std::string err;
    if(verifyModule(*mod, llvm::AbortProcessAction, &err)){
        printf("%s\n", err.c_str());
        exit(1);
    }

    /*
     * Taint processor initialization
     */

    //uint32_t ram_size = 536870912; // 500MB each
#ifdef TARGET_X86_64
    // this is only for the fast bitmap which we currently aren't using for
    // 64-bit, it only supports 32-bit
    //XXX FIXME
    uint64_t ram_size = 0;
#else
    uint32_t ram_size = 0xffffffff; //guest address space -- QEMU user mode
#endif
    uint64_t hd_size =  536870912;
    uint64_t io_size = 536870912;
    uint16_t num_vals = 2000; // LLVM virtual registers //XXX assert this
    shadow = tp_init(hd_size, ram_size, io_size, num_vals);
    if (shadow == NULL){
        printf("Error initializing shadow memory...\n");
        exit(1);
    }

    taintfpm = new llvm::FunctionPassManager(tcg_llvm_ctx->getModule());

    // Add the taint analysis pass to our taint pass manager
    llvm::FunctionPass *taintfp =
        llvm::createPandaTaintFunctionPass(15*1048576/* global taint op buffer
        size, 10MB */, NULL /* existing taint cache */);
    PTFP = static_cast<llvm::PandaTaintFunctionPass*>(taintfp);
    taintfpm->add(taintfp);
    taintfpm->doInitialization();

    // Populate taint cache with helper function taint ops
    for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){
        if (i->isDeclaration()){
            continue;
        }
        PTFP->runOnFunction(*i);
    }
}
Exemple #7
0
llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir)
{
    bool logenabled = Logger::enabled();
    if (llvmForceLogging && !logenabled)
    {
        Logger::enable();
    }

    Logger::println("Generating module: %s", (md ? md->toChars() : toChars()));
    LOG_SCOPE;

    if (global.params.verbose_cg)
        printf("codegen: %s (%s)\n", toPrettyChars(), srcfile->toChars());

    assert(!global.errors);

    // name the module
#if 1
    // Temporary workaround for http://llvm.org/bugs/show_bug.cgi?id=11479 –
    // just use the source file name, as it is unlikely to collide with a
    // symbol name used somewhere in the module.
    llvm::StringRef mname(srcfile->toChars());
#else
    llvm::StringRef mname(toChars());
    if (md != 0)
        mname = md->toChars();
#endif

    // create a new ir state
    // TODO look at making the instance static and moving most functionality into IrModule where it belongs
    IRState ir(new llvm::Module(mname, context));
    gIR = &ir;
    ir.dmodule = this;

    // reset all IR data stored in Dsymbols
    IrDsymbol::resetAll();

    sir->setState(&ir);

    // set target triple
    ir.module->setTargetTriple(global.params.targetTriple.str());

    // set final data layout
    ir.module->setDataLayout(gDataLayout->getStringRepresentation());
    if (Logger::enabled())
        Logger::cout() << "Final data layout: " << ir.module->getDataLayout() << '\n';

    // allocate the target abi
    gABI = TargetABI::getTarget();

    // debug info
    DtoDwarfCompileUnit(this);

    // handle invalid 'objectø module
    if (!ClassDeclaration::object) {
        error("is missing 'class Object'");
        fatal();
    }
    if (!ClassDeclaration::classinfo) {
        error("is missing 'class ClassInfo'");
        fatal();
    }

    LLVM_D_InitRuntime();

    // process module members
    for (unsigned k=0; k < members->dim; k++) {
        Dsymbol* dsym = static_cast<Dsymbol*>(members->data[k]);
        assert(dsym);
        dsym->codegen(sir);
    }

    // emit function bodies
    sir->emitFunctionBodies();

    // for singleobj-compilation, fully emit all seen template instances
    if (global.params.singleObj)
    {
        while (!ir.seenTemplateInstances.empty())
        {
            IRState::TemplateInstanceSet::iterator it, end = ir.seenTemplateInstances.end();
            for (it = ir.seenTemplateInstances.begin(); it != end; ++it)
                (*it)->codegen(sir);
            ir.seenTemplateInstances.clear();

            // emit any newly added function bodies
            sir->emitFunctionBodies();
        }
    }

    // finilize debug info
    DtoDwarfModuleEnd();

    // generate ModuleInfo
    genmoduleinfo();

    // verify the llvm
    verifyModule(*ir.module);

    gIR = NULL;

    if (llvmForceLogging && !logenabled)
    {
        Logger::disable();
    }

    sir->setState(NULL);

    return ir.module;
}
Exemple #8
0
void __taint2_enable_taint(void) {
    if(taintEnabled) {return;}
    printf ("taint2: __taint_enable_taint\n");
    taintEnabled = true;
    panda_cb pcb;

    pcb.after_block_translate = after_block_translate;
    panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_TRANSLATE, pcb);
    pcb.before_block_exec_invalidate_opt = before_block_exec_invalidate_opt;
    panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC_INVALIDATE_OPT, pcb);
    pcb.before_block_exec = before_block_exec;
    panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
    pcb.after_block_exec = after_block_exec;
    panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_EXEC, pcb);
    pcb.phys_mem_read = phys_mem_read_callback;
    panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_READ, pcb);
    pcb.phys_mem_write = phys_mem_write_callback;
    panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_WRITE, pcb);
/*
    pcb.cb_cpu_restore_state = cb_cpu_restore_state;
    panda_register_callback(plugin_ptr, PANDA_CB_CPU_RESTORE_STATE, pcb);
    // for hd and network taint
    pcb.replay_hd_transfer = cb_replay_hd_transfer_taint;
    panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_HD_TRANSFER, pcb);
    pcb.replay_net_transfer = cb_replay_net_transfer_taint;
    panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_NET_TRANSFER, pcb);
    pcb.replay_before_cpu_physical_mem_rw_ram = cb_replay_cpu_physical_mem_rw_ram;
    panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_BEFORE_CPU_PHYSICAL_MEM_RW_RAM, pcb);
*/
    panda_enable_precise_pc(); //before_block_exec requires precise_pc for panda_current_asid

    if (!execute_llvm){
        panda_enable_llvm();
    }
    panda_enable_llvm_helpers();

    /*
     * Taint processor initialization
     */

    shadow = tp_init(TAINT_BYTE_LABEL, TAINT_GRANULARITY_BYTE);
    if (shadow == NULL){
        printf("Error initializing shadow memory...\n");
        exit(1);
    }

    // Initialize memlog.
    memset(&taint_memlog, 0, sizeof(taint_memlog));

    llvm::Module *mod = tcg_llvm_ctx->getModule();
    FPM = tcg_llvm_ctx->getFunctionPassManager();

    // Add the taint analysis pass to our taint pass manager
    PTFP = new llvm::PandaTaintFunctionPass(shadow, &taint_memlog);
    FPM->add(PTFP);

    if (optimize_llvm) {
        printf("taint2: Adding default optimizations (-O1).\n");
        llvm::PassManagerBuilder Builder;
        Builder.OptLevel = 1;
        Builder.SizeLevel = 0;
        Builder.populateFunctionPassManager(*FPM);
    }

    FPM->doInitialization();

    // Populate module with helper function taint ops
    for (auto i = mod->begin(); i != mod->end(); i++){
        if (!i->isDeclaration()) PTFP->runOnFunction(*i);
    }

    printf("taint2: Done processing helper functions for taint.\n");

    std::string err;
    if(verifyModule(*mod, llvm::AbortProcessAction, &err)){
        printf("%s\n", err.c_str());
        exit(1);
    }

    //tcg_llvm_write_module(tcg_llvm_ctx, "/tmp/llvm-mod.bc");

    printf("taint2: Done verifying module. Running...\n");
}
void CouchRunner::runIR( CouchWorkingMemory *wm ){
  /*
  Module *theM;
  theM = ParseBitcodeFile( MemoryBuffer::getFile("out.bc"), 
			   getGlobalContext(),
			   &error );
  */

  // Loads intermediate representation source
  std::string error;
  SMDiagnostic Err;
  std::auto_ptr<Module> theM(ParseAssemblyFile( fSourceFile, Err, getGlobalContext() ));
  std::cout << "KBVM v1.0 (experimental)\nIntermediate Representation Interpreter\n";  
  std::cout << "Parsing " << fSourceFile << "\n";
  // Verifies module
  try{
    std::string VerifErr;
    if (verifyModule( *theM.get(), ReturnStatusAction, &VerifErr)) {
      errs() << fSourceFile
	     << ": assembly parsed, but does not verify as correct!\n";
      errs() << VerifErr;
      return;
    }
  }
  catch(...){
    std::cerr << "Verification of module failed!\n";
    return;
  }
  // Prepares to execute
  S_wm = wm;

  IRBuilder<>  theBuilder( getGlobalContext() );
  // Create the JIT.
  S_TheExecutionEngine = ExecutionEngine::create(theM.get());

  //ExistingModuleProvider OurModuleProvider( M );
  FunctionPassManager OurFPM( theM.get() );
      
  // Set up the optimizer pipeline.  
  // Start with registering info about how the
  // target lays out data structures.
  OurFPM.add(new TargetData(*S_TheExecutionEngine->getTargetData()));
  // Promote allocas to registers.
  OurFPM.add(createPromoteMemoryToRegisterPass());
  // Do simple "peephole" optimizations and bit-twiddling optzns.
  OurFPM.add(createInstructionCombiningPass());
  // Reassociate expressions.
  OurFPM.add(createReassociatePass());
  // Eliminate Common SubExpressions.
  OurFPM.add(createGVNPass());
  // Simplify the control flow graph (deleting unreachable blocks, etc).
  OurFPM.add(createCFGSimplificationPass());

  // Set the global so the code gen can use this.
  S_TheFPM = &OurFPM;

  // Inital setup of the agenda
  unsigned int i;
  CouchRunner::S_Agenda->reset();

  // Initial setup of the working memory
  S_TheFPM->run( *theM->getFunction("ag_forward") );

  std::string sign, val;
  Function *FFwrd = S_TheExecutionEngine->FindFunctionNamed( "ag_forward" );
  void *FFwrdPtr = S_TheExecutionEngine->getPointerToFunction(FFwrd);
  void (*FFwrdP)(const char*) = (void (*)( const char*))FFwrdPtr;
  DOMElement *elt;

  DOMNodeList *domSuggests = 
    fDom->getElementsByTagName( XMLString::transcode("suggest") );
  for( i = 0; i < domSuggests->getLength(); i++ ){
    CouchRunner::S_Agenda->push( std::string(XMLString::transcode( ((DOMText *)(domSuggests->item(i)->getFirstChild()))->getData() )), S_wm );
  }

  DOMNodeList *domVolunteers = 
    fDom->getElementsByTagName( XMLString::transcode("volunteer") );
  for( i = 0; i < domVolunteers->getLength(); i++ ){
    elt = (DOMElement *)(domVolunteers->item(i));
    sign = std::string( XMLString::transcode( ((DOMText *)(elt->getElementsByTagName(XMLString::transcode("var"))->item(0)->getFirstChild()))->getData() ) );
    val = std::string( XMLString::transcode( ((DOMText *)(elt->getElementsByTagName(XMLString::transcode("const"))->item(0)->getFirstChild()))->getData() ) );
    // TODO: update with type information
    if( std::string("true") == val ){
      S_wm->set( sign.c_str(), (int)1 );
    }
    else if( std::string("false") == val ){
      S_wm->set( sign.c_str(), (int)0 );
    }
    else if( isalpha( *(val.c_str()) ) ){
      S_wm->set( sign.c_str(), val.c_str() );
    }
    else{
      double d = strtod( val.c_str(), NULL );
      S_wm->set( sign.c_str(), d );
    }
    // Update agenda as if forwarded from execution
    FFwrdP( sign.c_str() );
  }


  std::cout << "Session Started\n" << *S_wm << *CouchRunner::S_Agenda;

  {
    // Creates the `entry' function that sets up the Agenda, which
    // also serves as continuation for the postponed calls
    std::vector<Value *> args;
    Function *Main;


    while( !CouchRunner::S_Agenda->empty() ){

      // Erase previous entry function if present
      if( NULL != (Main = theM->getFunction("entry")) ){
	Main->eraseFromParent();
      }
      // Creates code block
      Main = cast<Function>(
			    theM->getOrInsertFunction( "entry", 
						       Type::getInt32Ty(getGlobalContext()), 
						       (Type *)0)
			    );
      BasicBlock *EB = BasicBlock::Create(getGlobalContext(), 
					  "EntryBlock", Main);
      theBuilder.SetInsertPoint(EB);
      // Loops through the current agenda
      Value *res = NULL, *call;
      std::string hypo;

      // Copies agenda to current Agenda
	
      while( !CouchRunner::S_Agenda->empty() ){
	hypo = CouchRunner::S_Agenda->pop();
	if( WorkingMemory::WM_UNKNOWN == S_wm->knownp( hypo.c_str() ) ){
	  call = theBuilder.CreateCall(theM->getFunction( hypo ),
				       args.begin(),
				       args.end(), "suggest");
	  res = 
	    theBuilder.CreateIntCast( call, 
				      Type::getInt32Ty(getGlobalContext()), 
				      false, "cast_tmp" );
	}
      }
      theBuilder.CreateRet( res == NULL ? 
			    ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 2) : 
			    res );
      // Check it
      S_TheFPM->run( *Main );
      // Run it
      Function *F = S_TheExecutionEngine->FindFunctionNamed( "entry" );
      void *FPtr = S_TheExecutionEngine->getPointerToFunction(F);
      typedef int (*PFN)();
      PFN FP = reinterpret_cast<PFN>( FPtr );
      //      int (*FP)() = (int (*)())FPtr;
      printf( "Result = %d\n", FP() );
      std::cout << *S_wm << std::endl;
      std::cout << *CouchRunner::S_Agenda << std::endl;
    }  
    S_wm = NULL;
  }
}
Exemple #10
0
void __taint_enable_taint(void) {
    if(taintEnabled) {return;}
  printf ("__taint_enable_taint\n");
  taintJustEnabled = true;
  taintEnabled = true;
    panda_cb pcb;

    pcb.before_block_exec = before_block_exec;
    panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
    pcb.after_block_exec = after_block_exec;
    panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_EXEC, pcb);
    pcb.phys_mem_read = phys_mem_read_callback;
    panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_READ, pcb);
    pcb.phys_mem_write = phys_mem_write_callback;
    panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_WRITE, pcb);
    pcb.cb_cpu_restore_state = cb_cpu_restore_state;
    panda_register_callback(plugin_ptr, PANDA_CB_CPU_RESTORE_STATE, pcb);

    // for hd and network taint
#ifdef CONFIG_SOFTMMU
    pcb.replay_hd_transfer = cb_replay_hd_transfer_taint;
    panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_HD_TRANSFER, pcb);
    pcb.replay_net_transfer = cb_replay_net_transfer_taint;
    panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_NET_TRANSFER, pcb);
    pcb.replay_before_cpu_physical_mem_rw_ram = cb_replay_cpu_physical_mem_rw_ram;
    panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_BEFORE_CPU_PHYSICAL_MEM_RW_RAM, pcb);
#endif

    panda_enable_precise_pc(); //before_block_exec requires precise_pc for panda_current_asid

    if (!execute_llvm){
        panda_enable_llvm();
    }
    llvm::llvm_init();
    panda_enable_llvm_helpers();

    /*
     * Run instrumentation pass over all helper functions that are now in the
     * module, and verify module.
     */
    llvm::Module *mod = tcg_llvm_ctx->getModule();
    for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){
        if (i->isDeclaration()){
            continue;
        }
#if defined(TARGET_ARM)
        //TODO: Fix handling of ARM's cpu_reset() helper
        // Currently, we skip instrumenting it, because we generate invalid LLVM bitcode if we try
        std::string modname =  i->getName().str();
        if (modname == "cpu_reset_llvm"){
            printf("Skipping instrumentation of cpu_reset\n");
            continue;
        }
#endif
        PIFP->runOnFunction(*i);
    }
    std::string err;
    if(verifyModule(*mod, llvm::AbortProcessAction, &err)){
        printf("%s\n", err.c_str());
        exit(1);
    }

    /*
     * Taint processor initialization
     */

    //uint32_t ram_size = 536870912; // 500MB each
#ifdef TARGET_X86_64
    // this is only for the fast bitmap which we currently aren't using for
    // 64-bit, it only supports 32-bit
    //XXX FIXME
    uint64_t ram_size = 0;
#else
    uint32_t ram_size = 0xffffffff; //guest address space -- QEMU user mode
#endif
    uint64_t hd_size =  536870912;
    uint64_t io_size = 536870912;
    uint16_t num_vals = 2000; // LLVM virtual registers //XXX assert this
    shadow = tp_init(hd_size, ram_size, io_size, num_vals);
    if (shadow == NULL){
        printf("Error initializing shadow memory...\n");
        exit(1);
    }

    taintfpm = new llvm::FunctionPassManager(tcg_llvm_ctx->getModule());

    // Add the taint analysis pass to our taint pass manager
    llvm::FunctionPass *taintfp =
        llvm::createPandaTaintFunctionPass(15*1048576/* global taint op buffer
        size, 10MB */, NULL /* existing taint cache */);
    PTFP = static_cast<llvm::PandaTaintFunctionPass*>(taintfp);
    taintfpm->add(taintfp);
    taintfpm->doInitialization();

    // Populate taint cache with helper function taint ops
    for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){
        if (i->isDeclaration()){
            continue;
        }
        PTFP->runOnFunction(*i);
    }
}
Exemple #11
0
llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context)
{
    bool logenabled = Logger::enabled();
    if (llvmForceLogging && !logenabled)
    {
        Logger::enable();
    }

    IF_LOG Logger::println("Generating module: %s", (md ? md->toChars() : toChars()));
    LOG_SCOPE;

    if (global.params.verbose_cg)
        printf("codegen: %s (%s)\n", toPrettyChars(), srcfile->toChars());

    if (global.errors)
    {
        Logger::println("Aborting because of errors");
        fatal();
    }

    // name the module
#if 1
    // Temporary workaround for http://llvm.org/bugs/show_bug.cgi?id=11479 –
    // just use the source file name, as it is unlikely to collide with a
    // symbol name used somewhere in the module.
    llvm::StringRef mname(srcfile->toChars());
#else
    llvm::StringRef mname(toChars());
    if (md != 0)
        mname = md->toChars();
#endif

    // create a new ir state
    // TODO look at making the instance static and moving most functionality into IrModule where it belongs
    IRState ir(new llvm::Module(mname, context));
    gIR = &ir;
    ir.dmodule = this;

    // reset all IR data stored in Dsymbols
    IrDsymbol::resetAll();

    // set target triple
    ir.module->setTargetTriple(global.params.targetTriple.str());

    // set final data layout
    ir.module->setDataLayout(gDataLayout->getStringRepresentation());
    IF_LOG Logger::cout() << "Final data layout: " << ir.module->getDataLayout() << '\n';

    // allocate the target abi
    gABI = TargetABI::getTarget();

    // debug info
    gIR->DBuilder.EmitCompileUnit(this);

    // handle invalid 'objectø module
    if (!ClassDeclaration::object) {
        error("is missing 'class Object'");
        fatal();
    }

    LLVM_D_InitRuntime();

    // process module members
    for (unsigned k=0; k < members->dim; k++) {
        Dsymbol* dsym = static_cast<Dsymbol*>(members->data[k]);
        assert(dsym);
        Declaration_codegen(dsym);
    }

    // finalize debug info
    gIR->DBuilder.EmitModuleEnd();

    // generate ModuleInfo
    genmoduleinfo();

    build_llvm_used_array(&ir);

#if LDC_LLVM_VER >= 303
    // Add the linker options metadata flag.
    ir.module->addModuleFlag(llvm::Module::AppendUnique, "Linker Options",
                             llvm::MDNode::get(ir.context(), ir.LinkerMetadataArgs));
#endif

#if LDC_LLVM_VER >= 304
    // Emit ldc version as llvm.ident metadata.
    llvm::NamedMDNode *IdentMetadata = ir.module->getOrInsertNamedMetadata("llvm.ident");
    std::string Version("ldc version ");
    Version.append(global.ldc_version);
    llvm::Value *IdentNode[] = {
        llvm::MDString::get(ir.context(), Version)
    };
    IdentMetadata->addOperand(llvm::MDNode::get(ir.context(), IdentNode));
#endif

    // verify the llvm
    verifyModule(*ir.module);

    gIR = NULL;

    if (llvmForceLogging && !logenabled)
    {
        Logger::disable();
    }

    return ir.module;
}