Esempio n. 1
0
void UVDFlirtutilFixture::verifyDump(const std::string &sigFileNameIn, const std::string &expectedDumpFileNameIn)
{
	std::string tempFile;

	std::string unitTestDir;
	//std::string outputPatFileName = getTempFileName();
	std::string output;
	std::string expectedOutput;
	std::string inputFileName;
	std::string expectedOutputFileName;
	
	unitTestDir = getUnitTestDir();
	inputFileName = unitTestDir + "/flirt/ELF/" + sigFileNameIn;
	expectedOutputFileName = unitTestDir + "/flirt/ELF/" + expectedDumpFileNameIn;

	m_args.clear();
	init();
	UVCPPUNIT_ASSERT(m_flirt->dumpSigFile(inputFileName));
	deinit();
	
	//FIXME: we aren't verifying right now...
	//we need a way to capture the output
	//probably by changing the dump API		
	printf_warn("FIXME: no dump verify support\n");
}
Esempio n. 2
0
uv_err_t UVDPluginEngine::activatePluginByName(const std::string &name)
{
	std::map<std::string, UVDPlugin *>::iterator iter = m_plugins.find(name);
	UVDPlugin *plugin = NULL;

	printf_plugin_debug("initializing plugin %s\n", name.c_str());
	if( iter == m_plugins.end() )
	{
		printf_error("no plugin loaded named %s\n", name.c_str());
		return UV_DEBUG(UV_ERR_GENERAL);
	}
	if( m_loadedPlugins.find(name) != m_loadedPlugins.end() )
	{
		printf_warn("skipping double load of plugin %s\n", name.c_str());
		return UV_DEBUG(UV_ERR_WARNING);
	}
	plugin = (*iter).second;
	uv_assert_ret(plugin);
	
	/*
	Initialize dependencies
	TODO: check for circular refs
	*/
	std::vector<UVDPlugin *> dependencies;
	uv_assert_err_ret(getAllPluginDependencies(name, dependencies));

	//std::string pluginName;
	for( std::vector<UVDPlugin *>::iterator iter = dependencies.begin();
			iter != dependencies.end(); ++iter )
	{
		//std::string dependentPluginName = *iter;
		UVDPlugin *dependentPlugin = *iter;
		
		uv_assert_err_ret(ensurePluginActiveByName(dependentPlugin->getName()));
	}
	
	uv_assert_err_ret(plugin->init(g_config));
	m_loadedPlugins[name] = plugin;
	
	//Notify callbacks
	for( std::set<OnPluginActivatedItem>::iterator iter = m_onPluginActivated.begin();
			iter != m_onPluginActivated.end(); ++iter )
	{
		OnPluginActivated callback = (*iter).first;
		void *user = (*iter).second;
	
		if( !callback )
		{
			printf_error("bad callback\n");
			continue;
		}
		//Ready to roll
		UV_DEBUG(callback(plugin, user));
	}
	
	return UV_ERR_OK;
}
Esempio n. 3
0
/*
TODO: branch to sub tables
*/
void UVDDisasmOpcodeLookupTable::usageStats(void)
{
	int i = 0;
	int used = 0;
	int unused = 0;
	
	for( i = 0; i < 256; ++i )
	{
		if( m_lookupTable[i] )
		{
			++used;
		}
		else
		{
			printf_warn("opcode 0x%.2X is non-encoding\n", i);
			++unused;
		}
	}
	printf_debug("Used opcodes: %d, unused opcodes: %d\n", used, unused);
}
Esempio n. 4
0
uv_err_t UVD::analyzeControlFlowTrace()
{
	printf_debug_level(UVD_DEBUG_PASSES, "control flow analysis trace / recursive descent\n");
	//For now only try to find where code is, so it doesn't matter how we arrived
	std::set<uint32_t> openSet;
	std::set<uint32_t> closedSet;
	
	//Probably need full ranges, do only start for now
	std::set<uint32_t> calls;
	std::set<uint32_t> jumps;
	//uv_addr_t numberAnalyzedBytes = 0;
	
	uv_assert_ret(m_runtime->m_architecture);
	uv_assert_ret(m_config);
	//uv_assert_err_ret(m_analyzer->getNumberAnalyzedBytes(&numberAnalyzedBytes));

	//Another way to do with would be to do "START" and then all other vectors
	for( std::vector<UVDCPUVector *>::iterator iter = m_runtime->m_architecture->m_vectors.begin();
			iter != m_runtime->m_architecture->m_vectors.end(); ++iter )
	{
		UVDCPUVector *vector = *iter;
		
		uv_assert_ret(vector);
		openSet.insert(vector->m_offset);
	}
	
	UVDInstructionIterator end;
	uv_assert_err_ret(instructionEnd(end));
	
	while( !openSet.empty() )
	{
		uint32_t nextStartAddress = *openSet.begin();
		UVDInstructionIterator iter;
		int isVectorValid = 0;

		openSet.erase(openSet.begin());
		//Did we already try to process it?
		if( closedSet.find(nextStartAddress) != closedSet.end() )
		{
			continue;
		}
		closedSet.insert(nextStartAddress);
	
		//Make sure it seems reasonable
		uv_assert_err_ret(suspectValidInstruction(nextStartAddress, &isVectorValid));
		{
		if( !isVectorValid )
			printf_warn("ignoring address: 0x%08X\n", nextStartAddress);
			continue;
		}

		//Keep going until we hit a branch point

		//uint32_t printPercentage = 1;
		//uint32_t printNext = printPercentage;

		uv_assert_err_ret(instructionBeginByAddress(nextStartAddress, iter));
		for( ;; )
		{
			UVDInstructionAnalysis instructionAnalysis;
			//std::string action;
			//uint32_t startPos = iter.getPosition();
			//uint32_t endPos = 0;
			
			/*
			if( numberAnalyzedBytes )
			{
				uint32_t curPercent = 100 * startPos / numberAnalyzedBytes;
				if( curPercent >= printNext )
				{
					printf_debug_level(UVD_DEBUG_SUMMARY, "uvd: raw control structure analysis: %d %%\n", curPercent);
					printNext += printPercentage;
				}
			}
			*/

			UVDInstruction *instruction = NULL;

			//printf_debug("\n\nAnalysis at: 0x%.8X\n", startPos);

			//XXX is this really correct?  what if we jumped towards the end
			//should be more of a continue
			if( iter == end )
			{
				printf_debug("disassemble: end");
				break;
			}
			uv_assert_err_ret(iter.get(&instruction));
			//endPos = iter.getPosition();
			
			//action = instruction.m_shared->m_action;

			//printf_debug("Next instruction (start: 0x%.8X, end: 0x%.8X): %s\n", startPos, endPos, instruction.m_shared->m_memoric.c_str());

			//printf_debug("Action: %s, type: %d\n", action.c_str(), instruction.m_shared->m_inst_class);
			uv_assert_err_ret(instruction->analyzeControlFlow(&instructionAnalysis));
			//Only care about resolved targets
			if( instructionAnalysis.m_isJump == UVD_TRI_TRUE || instructionAnalysis.m_isCall == UVD_TRI_TRUE )
			{
				openSet.insert(nextStartAddress);
			}
			//Unconditional jumps mean end of sweep
			//TODO: also consider adding something for noreturn type functions?
			//rare on embedded platforms?
			if( instructionAnalysis.m_isJump == UVD_TRI_TRUE && !instructionAnalysis.m_isConditional )
			{
				//Straight JMP style instruction
				break;
			}

			//If we aren't at end, there should be more data
			uv_assert_err_ret(iter.next());
		}
	}
	
	return UV_DEBUG(UV_ERR_GENERAL);
}
Esempio n. 5
0
uv_err_t UVD::analyzeControlFlowLinear()
{
	/*
	Linear flow anlaysis constructs functions in a greedy manner:
	A function is defined as all of the code between one function entry and the next function entry
	Each time a function is found we will add it and it will take up the remaining data, spliting as necessary
	*/
	
	UVDInstructionIterator iter;
	UVDInstructionIterator iterEnd;
	//uint32_t printPercentage = 1;
	//uint32_t printNext = printPercentage;
	//uv_addr_t numberAnalyzedBytes = 0;
	uv_addr_t startPosition = 0;
	
	printf_debug_level(UVD_DEBUG_PASSES, "control flow analysis linear\n");
	
	//Need at least one start location
	uv_assert_ret(!m_runtime->m_architecture->m_vectors.empty());
	//FIXME: take the lowest vector
	startPosition = m_runtime->m_architecture->m_vectors[0]->m_offset;
	if( m_runtime->m_architecture->m_vectors.size() != 1 )
	{
		printf_warn("%d vectors, only sweeping from 0x%08X, consider using recursive descent or specify start\n",
				m_runtime->m_architecture->m_vectors.size(), startPosition);
	}
	uv_assert_err_ret(instructionBegin(iter));
	uv_assert_err_ret(instructionEnd(iterEnd));
	uv_assert_err_ret(iterEnd.check());
	uv_assert_ret(m_config);
	//FIXME: iterator rework
	//uv_assert_err_ret(iter.m_address.m_space->getNumberAnalyzedBytes(&numberAnalyzedBytes));

	for( ;; )
	{
		UVDAddress startPos;
		uv_assert_err_ret(iter.getAddress(&startPos));
		UVDInstruction *instruction = NULL;
		
		//printf("analysis: ITERATING\n");
		uv_assert_err_ret(iter.check());
		
		if( iter == iterEnd )
		{
			printf_debug("disassemble: end");
			break;
		}

		uv_assert_err_ret(iter.get(&instruction));
		
		if( instruction ) {
			//printf("\n\nAnalysis at: 0x%.8X\n", startPos);		
			uv_assert_err_ret(instruction->analyzeControlFlow());
		}

		//If we aren't at end, there should be more data
		uv_assert_err_ret(iter.next());
	}

	return UV_ERR_OK;
}
Esempio n. 6
0
void NokiaComposer(int argc UNUSED, char *argv[])
{
	GSM_Error error;
	GSM_Ringtone 		ringtone;
	gboolean			started;
	int 			i,j;
	GSM_RingNote 		*Note;
	GSM_RingNoteDuration 	Duration;
	GSM_RingNoteDuration 	DefNoteDuration = 32; /* 32 = Duration_1_4 */
	unsigned int		DefNoteScale 	= Scale_880;

	ringtone.Format	= 0;
	error=GSM_ReadRingtoneFile(argv[2],&ringtone);
	Print_Error(error);

	if (ringtone.Format != RING_NOTETONE) {
		printf("%s\n", _("It can be RTTL ringtone only used with this option"));
		Terminate(2);
	}

	started = FALSE;
	j	= 0;
	for (i=0;i<ringtone.NoteTone.NrCommands;i++) {
		if (ringtone.NoteTone.Commands[i].Type == RING_Note) {
			Note = &ringtone.NoteTone.Commands[i].Note;
			if (!started) {
				if (Note->Note != Note_Pause) {
					printf(_("Ringtone \"%s\" (tempo = %i Beats Per Minute)"),DecodeUnicodeConsole(ringtone.Name),GSM_RTTLGetTempo(Note->Tempo));
					printf("\n\n");
					started = TRUE;
				}
			}
			if (started) j++;
		}
	}
    	if (j>50) {
		printf_warn(_("length=%i notes, but you will enter only first 50 tones."), j);
	}

	printf("\n\n%s ", _("This ringtone in Nokia Composer in phone should look:"));
	started = FALSE;
	for (i=0;i<ringtone.NoteTone.NrCommands;i++) {
		if (ringtone.NoteTone.Commands[i].Type == RING_Note) {
			Note = &ringtone.NoteTone.Commands[i].Note;
			if (!started) {
				if (Note->Note != Note_Pause) started = TRUE;
			}
			if (started) {
				switch (Note->Duration) {
					case Duration_Full: printf("1"); break;
					case Duration_1_2 : printf("2"); break;
					case Duration_1_4 : printf("4"); break;
					case Duration_1_8 : printf("8"); break;
					case Duration_1_16: printf("16");break;
					case Duration_1_32: printf("32");break;
				}
				if (Note->DurationSpec == DottedNote) printf(".");
				switch (Note->Note) {
					case Note_C  	: printf("c");	break;
					case Note_Cis	: printf("#c");	break;
					case Note_D  	 :printf("d");	break;
					case Note_Dis	: printf("#d");	break;
					case Note_E  	: printf("e");	break;
					case Note_F  	: printf("f");	break;
					case Note_Fis	: printf("#f");	break;
					case Note_G  	: printf("g");	break;
					case Note_Gis	: printf("#g");	break;
					case Note_A  	: printf("a");	break;
					case Note_Ais	: printf("#a");	break;
					case Note_H  	: printf("h");	break;
					case Note_Pause : printf("-");	break;
				}
				if (Note->Note != Note_Pause) printf("%i",Note->Scale - 4);
				printf(" ");
			}
		}
	}

	printf("\n\n%s ", _("To enter it please press:"));
	started = FALSE;
	for (i=0;i<ringtone.NoteTone.NrCommands;i++) {
		if (ringtone.NoteTone.Commands[i].Type == RING_Note) {
			Note = &ringtone.NoteTone.Commands[i].Note;
			if (!started) {
				if (Note->Note != Note_Pause) started = TRUE;
			}
			if (started) {
				switch (Note->Note) {
	      				case Note_C  : case Note_Cis:	printf("1");break;
	      				case Note_D  : case Note_Dis:	printf("2");break;
	      				case Note_E  :			printf("3");break;
	      				case Note_F  : case Note_Fis:	printf("4");break;
	      				case Note_G  : case Note_Gis:	printf("5");break;
	      				case Note_A  : case Note_Ais:	printf("6");break;
	      				case Note_H  :			printf("7");break;
	      				default      :			printf("0");break;
				}
				if (Note->DurationSpec == DottedNote) printf("%s", _("(longer)"));
	    			switch (Note->Note) {
      					case Note_Cis: case Note_Dis:
      					case Note_Fis: case Note_Gis:
      					case Note_Ais:
						printf("#");
						break;
      					default      :
						break;
    				}
				if (Note->Note != Note_Pause) {
					if ((unsigned int)Note->Scale != DefNoteScale) {
						while (DefNoteScale != (unsigned int)Note->Scale) {
							printf("*");
							DefNoteScale++;
							if (DefNoteScale==Scale_7040) DefNoteScale = Scale_880;
						}
					}
				}
				Duration = 0;
				switch (Note->Duration) {
					case Duration_Full : Duration = 128;	break;
					case Duration_1_2  : Duration = 64;	break;
					case Duration_1_4  : Duration = 32;	break;
					case Duration_1_8  : Duration = 16;	break;
					case Duration_1_16 : Duration = 8;	break;
					case Duration_1_32 : Duration = 4;	break;
					default		   : fprintf(stderr, "error\n");break;
				}
				if (Duration > DefNoteDuration) {
		        		while (DefNoteDuration != Duration) {
						printf("9");
			  			DefNoteDuration = DefNoteDuration * 2;
					}
			      	}
				if (Duration < DefNoteDuration) {
		        		while (DefNoteDuration != Duration) {
						printf("8");
			  			DefNoteDuration = DefNoteDuration / 2;
					}
			      	}
				printf(" ");
			}
		}
	}

	printf("\n");
	fflush(stdout);
}
Esempio n. 7
0
uv_err_t uvmain(int argc, char **argv)
{
	uv_err_t rc = UV_ERR_GENERAL;
	UVDConfig *config = NULL;
	UVDFLIRTConfig *flirtConfig = NULL;
	uv_err_t parseMainRc = UV_ERR_GENERAL;
	
	if( strcmp(GetVersion(), UVDGetVersion()) )
	{
		printf_warn("libuvudec version mismatch (exe: %s, libuvudec: %s)\n", GetVersion(), UVDGetVersion());
		fflush(stdout);
	}
	
	//Early library initialization.  Logging and arg parsing structures
	uv_assert_err_ret(UVDInit());
	config = g_config;
	uv_assert_ret(config);
	//Early local initialization
	uv_assert_err_ret(initProgConfig());
	
	//Grab our command line options
	parseMainRc = config->parseMain(argc, argv);
	uv_assert_err_ret(parseMainRc);
	if( parseMainRc == UV_ERR_DONE )
	{
		rc = UV_ERR_OK;
		goto error;
	}


	//Create a doConvertr engine active on that input
	printf_debug_level(UVD_DEBUG_SUMMARY, "doConvert: initializing FLIRT engine...\n");
	if( UV_FAILED(UVDFLIRT::getFLIRT(&g_flirt)) )
	{
		printf_error("Failed to initialize FLIRT engine\n");
		rc = UV_ERR_OK;
		goto error;
	}
	uv_assert_ret(g_flirt);

	flirtConfig = g_UVDFLIRTConfig;
	uv_assert_ret(flirtConfig);

	//Source .pat files
	if( flirtConfig->m_targetFiles.empty() )
	{
		printf_error("Target file(s) not specified\n");
		config->printHelp();
		uv_assert_err(UV_ERR_GENERAL);
	}
	
	if( UV_FAILED(doConvert()) )
	{
		printf_error("Top level doConvert failed\n");
		uv_assert(UV_ERR_GENERAL);
	}	

	rc = UV_ERR_OK;

error:
	uv_assert_err_ret(UVDDeinit());
		
	return UV_DEBUG(rc);
}
Esempio n. 8
0
//int init_count = 0;
uv_err_t UVD::init(UVDObject *object, UVDArchitecture *architecture)
{
	UVDBenchmark engineInitBenchmark;

	if( !m_config->m_argv )
	{
		printf_warn("initializing UVD without parsing main\n");
	}
	uv_assert_err(initEarly());

	printf_debug_level(UVD_DEBUG_PASSES, "UVD::init(): initializing runtime...\n");
	//We might want to make this more dynamic just in case
	m_runtime = new UVDRuntime();
	uv_assert(m_runtime);
	uv_assert_err(m_runtime->init(object, architecture));

	printf_debug_level(UVD_DEBUG_PASSES, "UVD::init(): initializing engine...\n");
	engineInitBenchmark.start();

	uv_assert(m_config);
		
	m_config->m_verbose = m_config->m_verbose_init;

	/*
	m_CPU = new UVDCPU();
	uv_assert(m_CPU);
	uv_assert_err(m_CPU->init());
	*/

	m_analyzer = new UVDAnalyzer();
	uv_assert(m_analyzer);
	uv_assert_err(m_analyzer->init(this));
	m_format = new UVDFormat();
	uv_assert(m_format);
	m_eventEngine = new UVDEventEngine();
	uv_assert(m_eventEngine);
	uv_assert_err(m_eventEngine->init());
	/*
	Read file
	This is raw dat, NOT null terminated string
	*/

	uv_assert_err(m_config->m_plugin.m_pluginEngine.onUVDInit());

	printFormatting();
	printf_debug("UVD: init OK!\n\n\n");

	m_config->m_verbose = m_config->m_verbose_processing;
	
	engineInitBenchmark.stop();
	printf_debug_level(UVD_DEBUG_PASSES, "engine init time: %s\n", engineInitBenchmark.toString().c_str());

	//printf("Address spaces: %d\n", m_runtime->m_addressSpaces.m_addressSpaces.size());
	

	return UV_ERR_OK;
	
error:
	//If we fail, we do not own its subobjects
	if( m_runtime )
	{
		m_runtime->m_object = NULL;
		m_runtime->m_architecture = NULL;
		delete m_runtime;
		m_runtime = NULL;
	}
	return UV_DEBUG(UV_ERR_GENERAL);
}
Esempio n. 9
0
uv_err_t UVD::initArchitecture(UVDObject *object, const UVDRuntimeHints &hints, UVDArchitecture **out)
{
	//FIXME: replace this with a config based selection
	//Must be able to feed into plugins
	//This should be a switch instead
	//m_architecture->m_architecture = architecture;
	UVDArchitecture *architecture = NULL;
	std::vector<UVDPlugin *> best;
	uvd_priority_t bestPriority = UVD_MATCH_NONE;
	
	printf_debug_level(UVD_DEBUG_PASSES, "UVD::initArchitecture()...\n");
	for( std::map<std::string, UVDPlugin *>::iterator iter = m_pluginEngine->m_loadedPlugins.begin();
		iter != m_pluginEngine->m_loadedPlugins.end(); ++iter )
	{
		UVDPlugin *plugin = (*iter).second;
		uv_err_t rcTemp = UV_ERR_GENERAL;
		uvd_priority_t loadPriority = 0;
		
		uv_assert_ret(plugin);
		rcTemp = plugin->canGetArchitecture(object, hints,  &loadPriority);
		if( UV_FAILED(rcTemp) )
		{
			printf_plugin_debug("plugin %s failed to canLoad architecture\n", (*iter).first.c_str());
			continue;
		}

		printf_plugin_debug("plugin %s returned from canLoad architecture with priority 0x%08X\n",
				(*iter).first.c_str(), loadPriority);
		if( loadPriority <= bestPriority )
		{
			if( loadPriority < bestPriority )
			{
				best.clear();
				bestPriority = loadPriority;
			}
			best.push_back(plugin);
		}
	}
	
	printf_plugin_debug("best priorty: 0x%08X, plugins: %d\n", bestPriority, best.size());
	if( bestPriority == UVD_MATCH_NONE )
	{
		printf_warn("could not find a suitable architecture loader\n");
		return UV_ERR_NOTFOUND;
	}
	uv_assert_ret(!best.empty());

	//Iterate over all plugins until one accepts our input
	for( std::vector<UVDPlugin *>::iterator iter = best.begin();
		iter != best.end(); ++iter )
	{
		UVDPlugin *plugin = *iter;
		uv_err_t rcTemp = UV_ERR_GENERAL;
		
		uv_assert_ret(plugin);		
		rcTemp = plugin->getArchitecture(object, hints, &architecture);
		if( UV_FAILED(rcTemp) )
		{
			printf_error("plugin %s failed to load architecture\n", plugin->getName().c_str());
			continue;
		}
		else if( !architecture )
		{
			printf_error("plugin %s claimed successed but didn't set architecture\n", plugin->getName().c_str());
			continue;
		}
		else
		{
			printf_debug_level(UVD_DEBUG_PASSES, "loaded architecture from plugin %s\n", plugin->getName().c_str());
			break;
		}
	}
	
	if( !architecture )
	{
		printf_error("could not find a suitable architecture loader\n");
		return UV_ERR_NOTFOUND;
	}
	
	uv_assert_err_ret(architecture->doInit());
	uv_assert_err_ret(architecture->fixupDefaults());

	uv_assert_ret(out);
	*out = architecture;

	return UV_ERR_OK;
}
Esempio n. 10
0
uv_err_t UVD::initObject(UVDData *data, const UVDRuntimeHints &hints, UVDObject **out)
{
	//FIXME: replace this with a config based selection
	//Must be able to feed into plugins
	//This should be a switch instead
	//m_architecture->m_architecture = architecture;
	UVDObject *object = NULL;
	std::vector<UVDPlugin *> best;
	uvd_priority_t bestPriority = UVD_MATCH_NONE;
	
	printf_debug_level(UVD_DEBUG_PASSES, "UVD::initObject()...\n");
	UVD_POKE(data);
	//Iterate over all plugins until one accepts our input
	uv_assert_ret(m_pluginEngine);
	for( std::map<std::string, UVDPlugin *>::iterator iter = m_pluginEngine->m_loadedPlugins.begin();
			iter != m_pluginEngine->m_loadedPlugins.end(); ++iter )
	{
		UVDPlugin *plugin = (*iter).second;
		uv_err_t rcTemp = UV_ERR_GENERAL;
		uvd_priority_t loadPriority = 0;
		
		uv_assert_ret(plugin);
		printf_plugin_debug("plugin %s trying canLoad object\n", (*iter).first.c_str());
		rcTemp = plugin->canLoadObject(data, hints,  &loadPriority);
		if( UV_FAILED(rcTemp) )
		{
			printf_plugin_debug("plugin %s failed to canLoad object\n", (*iter).first.c_str());
			continue;
		}

		if( loadPriority <= bestPriority )
		{
			printf_plugin_debug("plugin %s candidate at priority 0x%08X\n", (*iter).first.c_str(), loadPriority);
			if( loadPriority < bestPriority )
			{
				if( !best.empty() )
				{
					printf_plugin_debug("clearing %d plugins due to better priorty\n", best.size());
				}
				best.clear();
				bestPriority = loadPriority;
			}
			best.push_back(plugin);
		}
		else
		{
			printf_plugin_debug("plugin %s skipped due to worse priority (cur: %d, plugin: %d)\n",
					(*iter).first.c_str(), bestPriority, loadPriority);
		}
	}
	
	UVD_POKE(data);
	printf_plugin_debug("best priorty: 0x%08X, plugins: %d\n", bestPriority, best.size());
	if( bestPriority == UVD_MATCH_NONE )
	{
		printf_warn("could not find a suitable object loader\n");
		return UV_ERR_NOTFOUND;
	}
	uv_assert_ret(!best.empty());

	//Iterate over all plugins until one accepts our input
	uv_assert_ret(m_pluginEngine);
	for( std::vector<UVDPlugin *>::iterator iter = best.begin();
		iter != best.end(); ++iter )
	{
		UVDPlugin *plugin = *iter;
		uv_err_t rcTemp = UV_ERR_GENERAL;
		
		uv_assert_ret(plugin);
		rcTemp = plugin->loadObject(data, hints, &object);
		if( UV_FAILED(rcTemp) )
		{
			printf_error("plugin %s failed to load object\n", plugin->getName().c_str());
			continue;
		}
		else if( !object )
		{
			printf_error("plugin %s claimed successed but didn't set object\n", plugin->getName().c_str());
			continue;
		}
		else
		{
			printf_debug_level(UVD_DEBUG_PASSES, "loaded object from plugin %s (%p)\n", plugin->getName().c_str(), object);
			break;
		}
	}
	
	if( !object )
	{
		printf_error("could not find a suitable object module\n");
		return UV_ERR_GENERAL;
	}
	
	//Its probably better to let the object take care of this
	//For example, if init fails, we can try another candidate
	//uv_assert_err_ret(object->init(data));
	
	uv_assert_ret(out);
	*out = object;

	return UV_ERR_OK;
}
Esempio n. 11
0
uv_err_t UVDPluginEngine::loadByDir(const std::string &pluginDir, UVDConfig *config,
			bool recursive,
			bool failOnError, bool failOnPluginError)
{
	//boost throws exceptions
	//TODO: move to UVD friendly adapter interface
	try
	{
		for( boost::filesystem::directory_iterator iter(pluginDir);
			iter != boost::filesystem::directory_iterator(); ++iter )
		{
			//Not necessarily canonical
			std::string path;
			uv_err_t loadByPathRc = UV_ERR_GENERAL;
		
			path = pluginDir + "/" + iter->path().filename();
			if( is_directory(iter->status()) )
			{
				if( recursive )
				{
					uv_assert_err_ret(loadByDir(path, config,
							recursive,
							failOnError, failOnPluginError));
				}
				continue;				
			}
		
			//Try loading it, ignoring errors since it might just be a plugin config file or something
			//We should print a warning if
			loadByPathRc = loadByPath(path, false);
			if( UV_FAILED(loadByPathRc) )
			{
				if( loadByPathRc == UV_ERR_NOTSUPPORTED )
				{
					if( failOnError )
					{
						printf_error("failed to load possible plugin: %s\n", path.c_str());
						return UV_DEBUG(UV_ERR_GENERAL);
					}
					else
					{
						printf_plugin_debug("failed to load possible plugin: %s\n", path.c_str());
					}
				}
				else
				{
					if( failOnError || failOnPluginError )
					{
						printf_error("failed to load plugin: %s\n", path.c_str());
						return UV_DEBUG(UV_ERR_GENERAL);
					}
					else
					{
						printf_warn("failed to load plugin: %s\n", path.c_str());
					}
				}
			}
		}		

		return UV_ERR_OK;
	}
	catch(...)
	{
		if( !config->m_suppressErrors )
		{
			printf_error("failed to load plugin dir %s\n", pluginDir.c_str());
		}
		
		if( config->m_ignoreErrors )
		{
			return UV_DEBUG(UV_ERR_WARNING);
		}
		else
		{
			return UV_DEBUG(UV_ERR_GENERAL);			
		}		
	}
}