void plugin_load(char *name, char *args, plugintype_t type) { plugin_t *plugin, *temp; if (plugins != NULL) { temp = plugins; while (temp != NULL) { if (!strcmp(name, temp->name)) { BX_PANIC(("plugin '%s' already loaded", name)); return; } temp = temp->next; } } plugin = (plugin_t *)malloc (sizeof(plugin_t)); if (!plugin) { BX_PANIC(("malloc plugin_t failed")); } plugin->type = type; plugin->name = name; plugin->args = args; plugin->initialized = 0; char plugin_filename[BX_PATHNAME_LEN], buf[BX_PATHNAME_LEN]; sprintf(buf, PLUGIN_FILENAME_FORMAT, name); sprintf(plugin_filename, "%s%s", PLUGIN_PATH, buf); // Set context so that any devices that the plugin registers will // be able to see which plugin created them. The registration will // be called from either dlopen (global constructors) or plugin_init. BX_ASSERT(current_plugin_context == NULL); current_plugin_context = plugin; #if defined(_MSC_VER) plugin->handle = LoadLibrary(plugin_filename); BX_INFO(("DLL handle is %p", plugin->handle)); if (!plugin->handle) { current_plugin_context = NULL; BX_PANIC(("LoadLibrary failed for module '%s': error=%d", name, GetLastError())); free(plugin); return; } #else plugin->handle = lt_dlopen (plugin_filename); BX_INFO(("lt_dlhandle is %p", plugin->handle)); if (!plugin->handle) { current_plugin_context = NULL; BX_PANIC(("dlopen failed for module '%s': %s", name, lt_dlerror ())); free(plugin); return; } #endif if (type != PLUGTYPE_USER) { sprintf(buf, PLUGIN_INIT_FMT_STRING, name); } else { sprintf(buf, PLUGIN_INIT_FMT_STRING, "user"); } #if defined(_MSC_VER) plugin->plugin_init = (plugin_init_t) GetProcAddress(plugin->handle, buf); if (plugin->plugin_init == NULL) { pluginlog->panic("could not find plugin_init: error=%d", GetLastError()); plugin_abort (); } #else plugin->plugin_init = (plugin_init_t) lt_dlsym (plugin->handle, buf); if (plugin->plugin_init == NULL) { pluginlog->panic("could not find plugin_init: %s", lt_dlerror ()); plugin_abort (); } #endif if (type != PLUGTYPE_USER) { sprintf(buf, PLUGIN_FINI_FMT_STRING, name); } else { sprintf(buf, PLUGIN_FINI_FMT_STRING, "user"); } #if defined(_MSC_VER) plugin->plugin_fini = (plugin_fini_t) GetProcAddress(plugin->handle, buf); if (plugin->plugin_fini == NULL) { pluginlog->panic("could not find plugin_fini: error=%d", GetLastError()); plugin_abort (); } #else plugin->plugin_fini = (plugin_fini_t) lt_dlsym (plugin->handle, buf); if (plugin->plugin_fini == NULL) { pluginlog->panic("could not find plugin_fini: %s", lt_dlerror ()); plugin_abort(); } #endif pluginlog->info("loaded plugin %s",plugin_filename); /* Insert plugin at the _end_ of the plugin linked list. */ plugin->next = NULL; if (!plugins) { /* Empty list, this become the first entry. */ plugins = plugin; } else { /* Non-empty list. Add to end. */ temp = plugins; while (temp->next) temp = temp->next; temp->next = plugin; } plugin_init_one(plugin); // check that context didn't change. This should only happen if we // need a reentrant plugin_load. BX_ASSERT(current_plugin_context == plugin); current_plugin_context = NULL; }
void plugin_load(char *name, char *args, plugintype_t type) { plugin_t *plugin; plugin = (plugin_t *)malloc (sizeof(plugin_t)); if (!plugin) { BX_PANIC(("malloc plugin_t failed")); } plugin->type = type; plugin->name = name; plugin->args = args; plugin->initialized = 0; char plugin_filename[BX_PATHNAME_LEN], buf[BX_PATHNAME_LEN]; sprintf(buf, PLUGIN_FILENAME_FORMAT, name); sprintf(plugin_filename, "%s%s", PLUGIN_PATH, buf); // Set context so that any devices that the plugin registers will // be able to see which plugin created them. The registration will // be called from either dlopen (global constructors) or plugin_init. BX_ASSERT (current_plugin_context == NULL); current_plugin_context = plugin; plugin->handle = lt_dlopen (plugin_filename); BX_INFO (("lt_dlhandle is %p", plugin->handle)); if (!plugin->handle) { current_plugin_context = NULL; BX_PANIC (("dlopen failed for module '%s': %s", name, lt_dlerror ())); free (plugin); return; } sprintf(buf, PLUGIN_INIT_FMT_STRING, name); plugin->plugin_init = (int (*)(struct _plugin_t *, enum plugintype_t, int, char *[])) /* monster typecast */ lt_dlsym (plugin->handle, buf); if (plugin->plugin_init == NULL) { pluginlog->panic("could not find plugin_init: %s", lt_dlerror ()); plugin_abort (); } sprintf(buf, PLUGIN_FINI_FMT_STRING, name); plugin->plugin_fini = (void (*)(void)) lt_dlsym (plugin->handle, buf); if (plugin->plugin_init == NULL) { pluginlog->panic("could not find plugin_fini: %s", lt_dlerror ()); plugin_abort (); } pluginlog->info("loaded plugin %s",plugin_filename); /* Insert plugin at the _end_ of the plugin linked list. */ plugin->next = NULL; if (!plugins) { /* Empty list, this become the first entry. */ plugins = plugin; } else { /* Non-empty list. Add to end. */ plugin_t *temp = plugins; while (temp->next) temp = temp->next; temp->next = plugin; } plugin_init_one(plugin); // check that context didn't change. This should only happen if we // need a reentrant plugin_load. BX_ASSERT (current_plugin_context == plugin); current_plugin_context = NULL; return; }