示例#1
0
文件: mono-dl.c 项目: SbGibson/mono
/**
 * mono_dl_open:
 * @name: name of file containing shared module
 * @flags: flags
 * @error_msg: pointer for error message on failure
 *
 * Load the given file @name as a shared library or dynamically loadable
 * module. @name can be NULL to indicate loading the currently executing
 * binary image.
 * @flags can have the MONO_DL_LOCAL bit set to avoid exporting symbols
 * from the module to the shared namespace. The MONO_DL_LAZY bit can be set
 * to lazily load the symbols instead of resolving everithing at load time.
 * @error_msg points to a string where an error message will be stored in
 * case of failure.   The error must be released with g_free.
 *
 * Returns: a MonoDl pointer on success, NULL on failure.
 */
MonoDl*
mono_dl_open (const char *name, int flags, char **error_msg)
{
	MonoDl *module;
	void *lib;
	MonoDlFallbackHandler *dl_fallback = NULL;
	int lflags = LL_SO_TRFLAGS (flags);

	if (error_msg)
		*error_msg = NULL;

	module = malloc (sizeof (MonoDl));
	if (!module) {
		if (error_msg)
			*error_msg = g_strdup ("Out of memory");
		return NULL;
	}
	module->main_module = name == NULL? TRUE: FALSE;

#ifdef PLATFORM_ANDROID
	/* Bionic doesn't support NULL filenames */
	if (!name)
		lib = NULL;
	else
		lib = LL_SO_OPEN (name, lflags);
#else
	lib = LL_SO_OPEN (name, lflags);
#endif
	if (!lib) {
		GSList *node;
		for (node = fallback_handlers; node != NULL; node = node->next){
			MonoDlFallbackHandler *handler = (MonoDlFallbackHandler *) node->data;
			if (error_msg)
				*error_msg = NULL;
			
			lib = handler->load_func (name, lflags, error_msg, handler->user_data);
			if (error_msg && *error_msg != NULL)
				g_free (*error_msg);
			
			if (lib != NULL){
				dl_fallback = handler;
				break;
			}
		}
	}
	if (!lib && !dl_fallback) {
		char *lname;
		char *llname;
		const char *suff;
		const char *ext;
		/* This platform does not support dlopen */
		if (name == NULL) {
			free (module);
			return NULL;
		}
		
		suff = ".la";
		ext = strrchr (name, '.');
		if (ext && strcmp (ext, ".la") == 0)
			suff = "";
		lname = g_strconcat (name, suff, NULL);
		llname = get_dl_name_from_libtool (lname);
		g_free (lname);
		if (llname) {
			lib = LL_SO_OPEN (llname, lflags);
			g_free (llname);
		}
		if (!lib) {
			if (error_msg) {
				*error_msg = LL_SO_ERROR ();
			}
			free (module);
			return NULL;
		}
	}
	module->handle = lib;
	module->dl_fallback = dl_fallback;
	return module;
}
示例#2
0
/**
 * mono_dl_open:
 * @name: name of file containing shared module
 * @flags: flags
 * @error_msg: pointer for error message on failure
 *
 * Load the given file @name as a shared library or dynamically loadable
 * module. @name can be NULL to indicate loading the currently executing
 * binary image.
 * @flags can have the MONO_DL_LOCAL bit set to avoid exporting symbols
 * from the module to the shared namespace. The MONO_DL_LAZY bit can be set
 * to lazily load the symbols instead of resolving everithing at load time.
 * @error_msg points to a string where an error message will be stored in
 * case of failure.   The error must be released with g_free.
 *
 * Returns: a MonoDl pointer on success, NULL on failure.
 */
MonoDl*
mono_dl_open (const char *name, int flags, char **error_msg)
{
	MonoDl *module;
	void *lib;
	MonoDlFallbackHandler *dl_fallback = NULL;
	int lflags = mono_dl_convert_flags (flags);

	if (error_msg)
		*error_msg = NULL;

	module = (MonoDl *) g_malloc (sizeof (MonoDl));
	if (!module) {
		if (error_msg)
			*error_msg = g_strdup ("Out of memory");
		return NULL;
	}
	module->main_module = name == NULL? TRUE: FALSE;

	lib = mono_dl_open_file (name, lflags);

	if (!lib) {
		GSList *node;
		for (node = fallback_handlers; node != NULL; node = node->next){
			MonoDlFallbackHandler *handler = (MonoDlFallbackHandler *) node->data;
			if (error_msg)
				*error_msg = NULL;
			
			lib = handler->load_func (name, lflags, error_msg, handler->user_data);
			if (error_msg && *error_msg != NULL)
				g_free (*error_msg);
			
			if (lib != NULL){
				dl_fallback = handler;
				break;
			}
		}
	}
	if (!lib && !dl_fallback) {
		char *lname;
		char *llname;
		const char *suff;
		const char *ext;
		/* This platform does not support dlopen */
		if (name == NULL) {
			g_free (module);
			return NULL;
		}
		
		suff = ".la";
		ext = strrchr (name, '.');
		if (ext && strcmp (ext, ".la") == 0)
			suff = "";
		lname = g_strconcat (name, suff, NULL);
		llname = get_dl_name_from_libtool (lname);
		g_free (lname);
		if (llname) {
			lib = mono_dl_open_file (llname, lflags);
			g_free (llname);
		}
		if (!lib) {
			if (error_msg) {
				*error_msg = mono_dl_current_error_string ();
			}
			g_free (module);
			return NULL;
		}
	}
	module->handle = lib;
	module->dl_fallback = dl_fallback;
	return module;
}