Beispiel #1
0
int load_and_run_sc_main(std::string & InputFile)
{
	std::vector<std::string> InputArgv;
	std::string ErrorMsg;

	// Lot of copy-paste from lli.cpp
	LLVMContext &Context = getGlobalContext();

	// If we have a native target, initialize it to ensure it is linked in and
	// usable by the JIT.
	InitializeNativeTarget();

	// So that JIT-ed code can call pinavm_callback.
	//sys::DynamicLibrary::AddSymbol("pinavm_callback", (void *)pinavm_callback);

	// Load the bitcode...
	//Module *Mod = NULL;
	if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile,&ErrorMsg)){
		Mod = ParseBitcodeFile(Buffer, Context, &ErrorMsg);
		//Mod = getLazyBitcodeModule(Buffer, Context, &ErrorMsg);
		if (!Mod) delete Buffer;
	}

	if (!Mod) {
		errs() << "error loading program '" << InputFile << "': "
		       << ErrorMsg << "\n";
		exit(1);
	} else {
		TRACE_2("bitcode file loaded\n");
	}

	EngineBuilder builder(Mod);
	builder.setErrorStr(&ErrorMsg);
	builder.setEngineKind(EngineKind::JIT);

	builder.setOptLevel(CodeGenOpt::None);
	EE = builder.create();
	if (!EE) {
		if (!ErrorMsg.empty())
			errs() << "error creating EE: " << ErrorMsg << "\n";
		else
			errs() << "unknown error creating EE!\n";
		exit(1);
	}

	//EE->RegisterJITEventListener(createOProfileJITEventListener());

	// TODO: manage multiple arguments correctly.

	// Add the module's name to the start of the vector of arguments to main().
	InputArgv.push_back("main.exe");
	InputArgv.push_back(Args);

	// Call the main function from M as if its signature were:
	//   int main (int argc, char **argv, const char **envp)
	// using the contents of Args to determine argc & argv, and the contents of
	// EnvVars to determine envp.
	//
	std::string EntryFunc = "sc_main";
	Function *EntryFn = Mod->getFunction(EntryFunc);
	if (!EntryFn) {
		errs() << '\'' << EntryFunc << "\' function not found in module.\n";
		return -1;
	}

	// TODO: is this usefull?
	// If the program doesn't explicitly call exit, we will need the Exit
	// function later on to make an explicit call, so get the function now.
	Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context),
						  Type::getInt32Ty(Context),
						  NULL);

	// Reset errno to zero on entry to main.
	errno = 0;


	// Run static constructors.
	EE->runStaticConstructorsDestructors(false);


	TRACE_2("Running elaboration\n");
	// Run main.
	int Result = EE->runFunctionAsMain(EntryFn, InputArgv, NULL);

	// Run static destructors.
	EE->runStaticConstructorsDestructors(true);	

	// If the program didn't call exit explicitly, we should call it now.
	// This ensures that any atexit handlers get called correctly.
	if (Function *ExitF = dyn_cast<Function>(Exit)) {
		std::vector<GenericValue> Args;
		GenericValue ResultGV;
		ResultGV.IntVal = APInt(32, Result);
		Args.push_back(ResultGV);
		EE->runFunction(ExitF, Args);
		errs() << "ERROR: exit(" << Result << ") returned!\n";
		abort();
	} else {
		errs() << "ERROR: exit defined with wrong prototype!\n";
		abort();
	}
}