예제 #1
0
파일: plugin.cpp 프로젝트: iver6/BA
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;
}
예제 #2
0
파일: plugin.cpp 프로젝트: ralvaradoc/libsf
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;
}