Refactor the plugin registration and loading machinery
[babeltrace.git] / lib / plugin / plugin.c
index e1e0387b373451a6fc1beb417b4a6e0044fa9e30..5a72b42e49283f944299f3ad624bb4fe9fc068fb 100644 (file)
 #include <sys/stat.h>
 #include <dirent.h>
 
-#define PLUGIN_SYMBOL_NAME             "__bt_plugin_name"
-#define PLUGIN_SYMBOL_AUTHOR           "__bt_plugin_author"
-#define PLUGIN_SYMBOL_LICENSE          "__bt_plugin_license"
-#define PLUGIN_SYMBOL_INIT             "__bt_plugin_init"
-#define PLUGIN_SYMBOL_EXIT             "__bt_plugin_exit"
-#define PLUGIN_SYMBOL_DESCRIPTION      "__bt_plugin_description"
 #define NATIVE_PLUGIN_SUFFIX           ".so"
 #define NATIVE_PLUGIN_SUFFIX_LEN       sizeof(NATIVE_PLUGIN_SUFFIX)
 #define LIBTOOL_PLUGIN_SUFFIX          ".la"
 #define PLUGIN_SUFFIX_LEN      max_t(size_t, sizeof(NATIVE_PLUGIN_SUFFIX), \
                                        sizeof(LIBTOOL_PLUGIN_SUFFIX))
 
-#define SECTION_BEGIN(_name)           &__start_##_name
-#define SECTION_END(_name)             &__stop_##_name
+#define SECTION_BEGIN(_name)           (&(__start_##_name))
+#define SECTION_END(_name)             (&(__stop_##_name))
 #define SECTION_ELEMENT_COUNT(_name) (SECTION_END(_name) - SECTION_BEGIN(_name))
 
 #define DECLARE_SECTION(_type, _name)                          \
-       extern _type const __start_##_name __attribute((weak)); \
-       extern _type const __stop_##_name __attribute((weak))
-
-DECLARE_SECTION(bt_plugin_init_func, __bt_plugin_init_funcs);
-DECLARE_SECTION(bt_plugin_exit_func, __bt_plugin_exit_funcs);
-DECLARE_SECTION(const char *, __bt_plugin_names);
-DECLARE_SECTION(const char *, __bt_plugin_authors);
-DECLARE_SECTION(const char *, __bt_plugin_licenses);
-DECLARE_SECTION(const char *, __bt_plugin_descriptions);
-
-#define PRINT_SECTION(_printer, _name)                                         \
-       do {                                                                    \
-               _printer("Section " #_name " [%p - %p], (%zu elements)\n",      \
-                       SECTION_BEGIN(_name), SECTION_END(_name),               \
-                       SECTION_ELEMENT_COUNT(_name));                          \
-       } while (0)
-
-#define PRINT_PLUG_IN_SECTIONS(_printer)                               \
-       do {                                                            \
-               PRINT_SECTION(_printer, __bt_plugin_init_funcs);        \
-               PRINT_SECTION(_printer, __bt_plugin_exit_funcs);        \
-               PRINT_SECTION(_printer, __bt_plugin_names);             \
-               PRINT_SECTION(_printer, __bt_plugin_authors);           \
-               PRINT_SECTION(_printer, __bt_plugin_licenses);          \
-               PRINT_SECTION(_printer, __bt_plugin_descriptions);      \
-       } while (0)
+       extern _type __start_##_name __attribute((weak));       \
+       extern _type __stop_##_name __attribute((weak))
+
+DECLARE_SECTION(struct __bt_plugin_descriptor const *, __bt_plugin_descriptors);
+DECLARE_SECTION(struct __bt_plugin_descriptor_attribute const *, __bt_plugin_descriptor_attributes);
+DECLARE_SECTION(struct __bt_plugin_component_class_descriptor const *, __bt_plugin_component_class_descriptors);
+DECLARE_SECTION(struct __bt_plugin_component_class_descriptor_attribute const *, __bt_plugin_component_class_descriptor_attributes);
 
 /*
  * This hash table, global to the library, maps component class pointers
@@ -106,9 +81,9 @@ DECLARE_SECTION(const char *, __bt_plugin_descriptions);
  *
  * 1. To allow this application:
  *
- *        my_plugin = bt_plugin_create_from_file("/path/to/my-plugin.so");
- *        // instantiate components from the plugin's component classes
- *        BT_PUT(my_plugin);
+ *        my_plugins = bt_plugin_create_all_from_file("/path/to/my-plugin.so");
+ *        // instantiate components from a plugin's component classes
+ *        // put plugins and free my_plugins here
  *        // user code of instantiated components still exists
  *
  * 2. To decouple the plugin subsystem from the component subsystem:
@@ -156,8 +131,11 @@ void bt_plugin_shared_lib_handle_destroy(struct bt_object *obj)
                enum bt_plugin_status status = shared_lib_handle->exit();
 
                if (status < 0) {
-                       printf_verbose("Plugin `%s` exited with error %d\n",
-                               shared_lib_handle->name, status);
+                       const char *path = shared_lib_handle->path ?
+                               shared_lib_handle->path->str : "[built-in]";
+
+                       printf_verbose("Plugin in module `%s` exited with error %d\n",
+                               path, status);
                }
        }
 
@@ -180,7 +158,6 @@ struct bt_plugin_shared_lib_handle *bt_plugin_shared_lib_handle_create(
                const char *path)
 {
        struct bt_plugin_shared_lib_handle *shared_lib_handle = NULL;
-       gpointer symbol = NULL;
 
        shared_lib_handle = g_new0(struct bt_plugin_shared_lib_handle, 1);
        if (!shared_lib_handle) {
@@ -204,68 +181,6 @@ struct bt_plugin_shared_lib_handle *bt_plugin_shared_lib_handle_create(
                goto error;
        }
 
-       if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_NAME,
-                       (gpointer *) &shared_lib_handle->name)) {
-               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
-                       PLUGIN_SYMBOL_NAME,
-                       g_module_name(shared_lib_handle->module));
-               goto error;
-       }
-
-       if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_LICENSE,
-                       (gpointer *) &shared_lib_handle->license)) {
-               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
-                       PLUGIN_SYMBOL_LICENSE,
-                       g_module_name(shared_lib_handle->module));
-               goto error;
-       }
-
-       if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_AUTHOR,
-                       (gpointer *) &shared_lib_handle->author)) {
-               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
-                       PLUGIN_SYMBOL_AUTHOR,
-                       g_module_name(shared_lib_handle->module));
-               goto error;
-       }
-
-       if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_DESCRIPTION,
-                       (gpointer *) &shared_lib_handle->description)) {
-               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
-                       PLUGIN_SYMBOL_DESCRIPTION,
-                       g_module_name(shared_lib_handle->module));
-               goto error;
-       }
-
-       if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_INIT,
-                       &symbol)) {
-               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
-                       PLUGIN_SYMBOL_INIT,
-                       g_module_name(shared_lib_handle->module));
-               goto error;
-       } else {
-               shared_lib_handle->init = *((bt_plugin_init_func *) symbol);
-               if (!shared_lib_handle->init) {
-                       printf_verbose("NULL %s symbol target\n",
-                               PLUGIN_SYMBOL_INIT);
-                       goto error;
-               }
-       }
-
-       if (!g_module_symbol(shared_lib_handle->module, PLUGIN_SYMBOL_EXIT,
-                       &symbol)) {
-               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
-                       PLUGIN_SYMBOL_EXIT,
-                       g_module_name(shared_lib_handle->module));
-               goto error;
-       } else {
-               shared_lib_handle->exit = *((bt_plugin_exit_func *) symbol);
-               if (!shared_lib_handle->exit) {
-                       printf_verbose("NULL %s symbol target\n",
-                               PLUGIN_SYMBOL_EXIT);
-                       goto error;
-               }
-       }
-
        goto end;
 
 error:
@@ -293,47 +208,352 @@ void bt_plugin_destroy(struct bt_object *obj)
 }
 
 static
-enum bt_plugin_status init_plugin(struct bt_plugin *plugin)
+struct bt_plugin *bt_plugin_create_empty(
+               struct bt_plugin_shared_lib_handle *shared_lib_handle)
+{
+       struct bt_plugin *plugin = NULL;
+
+       plugin = g_new0(struct bt_plugin, 1);
+       if (!plugin) {
+               goto error;
+       }
+
+       bt_object_init(plugin, bt_plugin_destroy);
+       plugin->shared_lib_handle = bt_get(shared_lib_handle);
+
+       /* Create empty array of component classes */
+       plugin->comp_classes =
+               g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
+       if (!plugin->comp_classes) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       BT_PUT(plugin);
+
+end:
+       return plugin;
+}
+
+static
+enum bt_plugin_status bt_plugin_init(
+               struct bt_plugin *plugin,
+               const struct __bt_plugin_descriptor *descriptor,
+               struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
+               struct __bt_plugin_descriptor_attribute const * const *attrs_end,
+               struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
+               struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
+               struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
+               struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end)
 {
+       /*
+        * This structure's members point to the plugin's memory
+        * (do NOT free).
+        */
+       struct comp_class_full_descriptor {
+               const struct __bt_plugin_component_class_descriptor *descriptor;
+               const char *description;
+       };
+
        enum bt_plugin_status status = BT_PLUGIN_STATUS_OK;
+       struct __bt_plugin_descriptor_attribute const * const *cur_attr_ptr;
+       struct __bt_plugin_component_class_descriptor const * const *cur_cc_descr_ptr;
+       struct __bt_plugin_component_class_descriptor_attribute const * const *cur_cc_descr_attr_ptr;
+       GArray *comp_class_full_descriptors;
+       size_t i;
+
+       comp_class_full_descriptors = g_array_new(FALSE, TRUE,
+               sizeof(struct comp_class_full_descriptor));
+       if (!comp_class_full_descriptors) {
+               status = BT_PLUGIN_STATUS_ERROR;
+               goto end;
+       }
 
-       if (plugin->shared_lib_handle->init) {
-               status = plugin->shared_lib_handle->init(plugin);
+       /* Set mandatory attributes */
+       plugin->descriptor = descriptor;
+       plugin->name = descriptor->name;
 
+       /*
+        * Find and set optional attributes attached to this plugin
+        * descriptor.
+        */
+       for (cur_attr_ptr = attrs_begin; cur_attr_ptr != attrs_end; cur_attr_ptr++) {
+               const struct __bt_plugin_descriptor_attribute *cur_attr =
+                       *cur_attr_ptr;
+
+               if (cur_attr->plugin_descriptor != descriptor) {
+                       continue;
+               }
+
+               switch (cur_attr->type) {
+               case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_INIT:
+                       plugin->init = cur_attr->value.init;
+                       break;
+               case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_EXIT:
+                       plugin->shared_lib_handle->exit = cur_attr->value.exit;
+                       break;
+               case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_AUTHOR:
+                       plugin->author = cur_attr->value.author;
+                       break;
+               case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_LICENSE:
+                       plugin->license = cur_attr->value.license;
+                       break;
+               case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
+                       plugin->description = cur_attr->value.description;
+                       break;
+               default:
+                       printf_verbose("WARNING: Unknown attribute \"%s\" (type %d) for plugin %s\n",
+                               cur_attr->type_name, cur_attr->type,
+                               descriptor->name);
+                       break;
+               }
+       }
+
+       /*
+        * Find component class descriptors attached to this plugin
+        * descriptor and initialize corresponding full component class
+        * descriptors in the array.
+        */
+       for (cur_cc_descr_ptr = cc_descriptors_begin; cur_cc_descr_ptr != cc_descriptors_end; cur_cc_descr_ptr++) {
+               const struct __bt_plugin_component_class_descriptor *cur_cc_descr =
+                       *cur_cc_descr_ptr;
+               struct comp_class_full_descriptor full_descriptor;
+
+               if (cur_cc_descr->plugin_descriptor != descriptor) {
+                       continue;
+               }
+
+               full_descriptor.descriptor = cur_cc_descr;
+               full_descriptor.description = NULL;
+               g_array_append_val(comp_class_full_descriptors,
+                       full_descriptor);
+       }
+
+       /*
+        * Find component class descriptor attributes attached to this
+        * plugin descriptor and update corresponding full component
+        * class descriptors in the array.
+        */
+       for (cur_cc_descr_attr_ptr = cc_descr_attrs_begin; cur_cc_descr_attr_ptr != cc_descr_attrs_end; cur_cc_descr_attr_ptr++) {
+               const struct __bt_plugin_component_class_descriptor_attribute *cur_cc_descr_attr =
+                       *cur_cc_descr_attr_ptr;
+
+               if (cur_cc_descr_attr->comp_class_descriptor->plugin_descriptor !=
+                               descriptor) {
+                       continue;
+               }
+
+               /* Find the corresponding component class descriptor entry */
+               for (i = 0; i < comp_class_full_descriptors->len; i++) {
+                       struct comp_class_full_descriptor *cc_full_descr =
+                               &g_array_index(comp_class_full_descriptors,
+                                       struct comp_class_full_descriptor, i);
+
+                       if (cur_cc_descr_attr->comp_class_descriptor ==
+                                       cc_full_descr->descriptor) {
+                               switch (cur_cc_descr_attr->type) {
+                               case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
+                                       cc_full_descr->description =
+                                               cur_cc_descr_attr->value.description;
+                                       break;
+                               default:
+                                       printf_verbose("WARNING: Unknown attribute \"%s\" (type %d) for component class %s (type %d) in plugin %s\n",
+                                               cur_cc_descr_attr->type_name,
+                                               cur_cc_descr_attr->type,
+                                               cur_cc_descr_attr->comp_class_descriptor->name,
+                                               cur_cc_descr_attr->comp_class_descriptor->type,
+                                               descriptor->name);
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       /* Initialize plugin */
+       if (plugin->init) {
+               status = plugin->init(plugin);
                if (status < 0) {
                        printf_verbose("Plugin `%s` initialization error: %d\n",
-                               plugin->shared_lib_handle->name, status);
+                               plugin->name, status);
                        goto end;
                }
        }
 
        plugin->shared_lib_handle->init_called = true;
 
+       for (i = 0; i < comp_class_full_descriptors->len; i++) {
+               struct comp_class_full_descriptor *cc_full_descr =
+                       &g_array_index(comp_class_full_descriptors,
+                               struct comp_class_full_descriptor, i);
+               struct bt_component_class *comp_class;
+
+               comp_class = bt_component_class_create(
+                       cc_full_descr->descriptor->type,
+                       cc_full_descr->descriptor->name,
+                       cc_full_descr->description,
+                       cc_full_descr->descriptor->init_cb);
+               if (!comp_class) {
+                       status = BT_PLUGIN_STATUS_ERROR;
+                       goto end;
+               }
+
+               status = bt_plugin_add_component_class(plugin,
+                       comp_class);
+               BT_PUT(comp_class);
+               if (status < 0) {
+                       printf_verbose("Cannot add component class %s (type %d) to plugin `%s`: status = %d\n",
+                               cc_full_descr->descriptor->name,
+                               cc_full_descr->descriptor->type,
+                               plugin->name, status);
+                       goto end;
+               }
+       }
+
        /*
-        * The initialization function should have added the component
-        * classes at this point. We freeze the plugin so that it's not
-        * possible to add component classes to this plugin object after
-        * this stage (plugin object becomes immutable).
+        * All the plugin's component classes should be added at this
+        * point. We freeze the plugin so that it's not possible to add
+        * component classes to this plugin object after this stage
+        * (plugin object becomes immutable).
         */
        plugin->frozen = true;
 
 end:
+       g_array_free(comp_class_full_descriptors, TRUE);
        return status;
 }
 
-struct bt_plugin *bt_plugin_create_from_file(const char *path)
+static
+struct bt_plugin **bt_plugin_create_all_from_sections(
+               struct bt_plugin_shared_lib_handle *shared_lib_handle,
+               struct __bt_plugin_descriptor const * const *descriptors_begin,
+               struct __bt_plugin_descriptor const * const *descriptors_end,
+               struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
+               struct __bt_plugin_descriptor_attribute const * const *attrs_end,
+               struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
+               struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
+               struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
+               struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end)
+{
+       size_t descriptor_count;
+       size_t attrs_count;
+       size_t cc_descriptors_count;
+       size_t cc_descr_attrs_count;
+       size_t i;
+       struct bt_plugin **plugins = NULL;
+
+       descriptor_count = descriptors_end - descriptors_begin;
+       attrs_count = attrs_end - attrs_begin;
+       cc_descriptors_count = cc_descriptors_end - cc_descriptors_begin;
+       cc_descr_attrs_count = cc_descr_attrs_end - cc_descr_attrs_begin;
+       printf_verbose("Section: Plugin descriptors: [%p - %p], (%zu elements)\n",
+               descriptors_begin, descriptors_end, descriptor_count);
+       printf_verbose("Section: Plugin descriptor attributes: [%p - %p], (%zu elements)\n",
+               attrs_begin, attrs_end, attrs_count);
+       printf_verbose("Section: Plugin component class descriptors: [%p - %p], (%zu elements)\n",
+               cc_descriptors_begin, cc_descriptors_end, cc_descriptors_count);
+       printf_verbose("Section: Plugin component class descriptor attributes: [%p - %p], (%zu elements)\n",
+               cc_descr_attrs_begin, cc_descr_attrs_end, attrs_count);
+       plugins = calloc(descriptor_count + 1, sizeof(*plugins));
+       if (!plugins) {
+               goto error;
+       }
+
+       for (i = 0; i < descriptor_count; i++) {
+               enum bt_plugin_status status;
+               const struct __bt_plugin_descriptor *descriptor =
+                       descriptors_begin[i];
+               struct bt_plugin *plugin;
+
+               printf_verbose("Loading plugin %s (%d.%d)\n", descriptor->name,
+                       descriptor->major, descriptor->minor);
+
+               if (descriptor->major > __BT_PLUGIN_VERSION_MAJOR) {
+                       printf_error("Unknown plugin's major version: %d\n",
+                               descriptor->major);
+                       goto error;
+               }
+
+               plugin = bt_plugin_create_empty(shared_lib_handle);
+               if (!plugin) {
+                       printf_error("Cannot allocate plugin object for plugin %s\n",
+                               descriptor->name);
+                       goto error;
+               }
+
+               status = bt_plugin_init(plugin, descriptor, attrs_begin,
+                       attrs_end, cc_descriptors_begin, cc_descriptors_end,
+                       cc_descr_attrs_begin, cc_descr_attrs_end);
+               if (status < 0) {
+                       printf_error("Cannot initialize plugin object %s\n",
+                               descriptor->name);
+                       BT_PUT(plugin);
+                       goto error;
+               }
+
+               /* Transfer ownership to the array */
+               plugins[i] = plugin;
+       }
+
+       goto end;
+
+error:
+       g_free(plugins);
+       plugins = NULL;
+
+end:
+       return plugins;
+}
+
+struct bt_plugin **bt_plugin_create_all_from_static(void)
+{
+       struct bt_plugin **plugins = NULL;
+       struct bt_plugin_shared_lib_handle *shared_lib_handle =
+               bt_plugin_shared_lib_handle_create(NULL);
+
+       if (!shared_lib_handle) {
+               goto end;
+       }
+
+       plugins = bt_plugin_create_all_from_sections(shared_lib_handle,
+               SECTION_BEGIN(__bt_plugin_descriptors),
+               SECTION_END(__bt_plugin_descriptors),
+               SECTION_BEGIN(__bt_plugin_descriptor_attributes),
+               SECTION_END(__bt_plugin_descriptor_attributes),
+               SECTION_BEGIN(__bt_plugin_component_class_descriptors),
+               SECTION_END(__bt_plugin_component_class_descriptors),
+               SECTION_BEGIN(__bt_plugin_component_class_descriptor_attributes),
+               SECTION_END(__bt_plugin_component_class_descriptor_attributes));
+
+end:
+       BT_PUT(shared_lib_handle);
+
+       return plugins;
+}
+
+struct bt_plugin **bt_plugin_create_all_from_file(const char *path)
 {
        size_t path_len;
-       struct bt_plugin *plugin = NULL;
+       struct bt_plugin **plugins = NULL;
+       struct __bt_plugin_descriptor const * const *descriptors_begin = NULL;
+       struct __bt_plugin_descriptor const * const *descriptors_end = NULL;
+       struct __bt_plugin_descriptor_attribute const * const *attrs_begin = NULL;
+       struct __bt_plugin_descriptor_attribute const * const *attrs_end = NULL;
+       struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin = NULL;
+       struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end = NULL;
+       struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin = NULL;
+       struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end = NULL;
        bool is_libtool_wrapper = false, is_shared_object = false;
+       struct bt_plugin_shared_lib_handle *shared_lib_handle = NULL;
 
        if (!path) {
-               goto error;
+               goto end;
        }
 
        path_len = strlen(path);
        if (path_len <= PLUGIN_SUFFIX_LEN) {
-               goto error;
+               goto end;
        }
 
        path_len++;
@@ -349,43 +569,99 @@ struct bt_plugin *bt_plugin_create_from_file(const char *path)
                NATIVE_PLUGIN_SUFFIX_LEN);
        if (!is_shared_object && !is_libtool_wrapper) {
                /* Name indicates that this is not a plugin file. */
-               goto error;
+               goto end;
        }
 
-       plugin = g_new0(struct bt_plugin, 1);
-       if (!plugin) {
-               goto error;
+       shared_lib_handle = bt_plugin_shared_lib_handle_create(path);
+       if (!shared_lib_handle) {
+               goto end;
        }
 
-       bt_object_init(plugin, bt_plugin_destroy);
+       if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_descriptors",
+                       (gpointer *) &descriptors_begin)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__start___bt_plugin_descriptors",
+                       g_module_name(shared_lib_handle->module));
+               goto end;
+       }
 
-       /* Create shared lib handle */
-       plugin->shared_lib_handle = bt_plugin_shared_lib_handle_create(path);
-       if (!plugin->shared_lib_handle) {
-               printf_verbose("Failed to create a shared library handle (path `%s`)\n",
-                       path);
-               goto error;
+       if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_descriptors",
+                       (gpointer *) &descriptors_end)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__stop___bt_plugin_descriptors",
+                       g_module_name(shared_lib_handle->module));
+               goto end;
        }
 
-       /* Create empty array of component classes */
-       plugin->comp_classes =
-               g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
-       if (!plugin->comp_classes) {
-               goto error;
+       if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_descriptor_attributes",
+                       (gpointer *) &attrs_begin)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__start___bt_plugin_descriptor_attributes",
+                       g_module_name(shared_lib_handle->module));
        }
 
-       /* Initialize plugin */
-       if (init_plugin(plugin) < 0) {
-               goto error;
+       if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_descriptor_attributes",
+                       (gpointer *) &attrs_end)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__stop___bt_plugin_descriptor_attributes",
+                       g_module_name(shared_lib_handle->module));
        }
 
-       goto end;
+       if ((!!attrs_begin - !!attrs_end) != 0) {
+               printf_verbose("Found __start___bt_plugin_descriptor_attributes or __stop___bt_plugin_descriptor_attributes symbol, but not both in %s\n",
+                       g_module_name(shared_lib_handle->module));
+               goto end;
+       }
 
-error:
-       BT_PUT(plugin);
+       if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_component_class_descriptors",
+                       (gpointer *) &cc_descriptors_begin)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__start___bt_plugin_component_class_descriptors",
+                       g_module_name(shared_lib_handle->module));
+       }
+
+       if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_component_class_descriptors",
+                       (gpointer *) &cc_descriptors_end)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__stop___bt_plugin_component_class_descriptors",
+                       g_module_name(shared_lib_handle->module));
+       }
+
+       if ((!!cc_descriptors_begin - !!cc_descriptors_end) != 0) {
+               printf_verbose("Found __start___bt_plugin_component_class_descriptors or __stop___bt_plugin_component_class_descriptors symbol, but not both in %s\n",
+                       g_module_name(shared_lib_handle->module));
+               goto end;
+       }
+
+       if (!g_module_symbol(shared_lib_handle->module, "__start___bt_plugin_component_class_descriptor_attributes",
+                       (gpointer *) &cc_descr_attrs_begin)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__start___bt_plugin_component_class_descriptor_attributes",
+                       g_module_name(shared_lib_handle->module));
+       }
+
+       if (!g_module_symbol(shared_lib_handle->module, "__stop___bt_plugin_component_class_descriptor_attributes",
+                       (gpointer *) &cc_descr_attrs_end)) {
+               printf_verbose("Unable to resolve plugin symbol %s from %s\n",
+                       "__stop___bt_plugin_component_class_descriptor_attributes",
+                       g_module_name(shared_lib_handle->module));
+       }
+
+       if ((!!cc_descr_attrs_begin - !!cc_descr_attrs_end) != 0) {
+               printf_verbose("Found __start___bt_plugin_component_class_descriptor_attributes or __stop___bt_plugin_component_class_descriptor_attributes symbol, but not both in %s\n",
+                       g_module_name(shared_lib_handle->module));
+               goto end;
+       }
+
+       /* Initialize plugin */
+       plugins = bt_plugin_create_all_from_sections(shared_lib_handle,
+               descriptors_begin, descriptors_end, attrs_begin, attrs_end,
+               cc_descriptors_begin, cc_descriptors_end,
+               cc_descr_attrs_begin, cc_descr_attrs_end);
 
 end:
-       return plugin;
+       BT_PUT(shared_lib_handle);
+       return plugins;
 }
 
 /* Allocate dirent as recommended by READDIR(3), NOTES on readdir_r */
@@ -412,9 +688,16 @@ enum bt_plugin_status bt_plugin_create_append_all_from_dir(
        DIR *directory = NULL;
        struct dirent *entry = NULL, *result = NULL;
        char *file_path = NULL;
-       size_t path_len = strlen(path);
+       size_t path_len;
        enum bt_plugin_status ret = BT_PLUGIN_STATUS_OK;
 
+       if (!path) {
+               ret = BT_PLUGIN_STATUS_ERROR;
+               goto end;
+       }
+
+       path_len = strlen(path);
+
        if (path_len >= PATH_MAX) {
                ret = BT_PLUGIN_STATUS_ERROR;
                goto end;
@@ -479,11 +762,18 @@ enum bt_plugin_status bt_plugin_create_append_all_from_dir(
                                goto end;
                        }
                } else if (S_ISREG(st.st_mode)) {
-                       struct bt_plugin *plugin = bt_plugin_create_from_file(file_path);
+                       struct bt_plugin **plugins_from_file =
+                               bt_plugin_create_all_from_file(file_path);
 
-                       if (plugin) {
-                               /* Transfer ownership to array */
-                               g_ptr_array_add(plugins, plugin);
+                       if (plugins_from_file) {
+                               struct bt_plugin **plugin;
+
+                               for (plugin = plugins_from_file; *plugin; plugin++) {
+                                       /* Transfer ownership to array */
+                                       g_ptr_array_add(plugins, *plugin);
+                               }
+
+                               free(plugins_from_file);
                        }
                }
        }
@@ -505,19 +795,10 @@ end:
 struct bt_plugin **bt_plugin_create_all_from_dir(const char *path,
                bool recurse)
 {
-       GPtrArray *plugins_array = NULL;
+       GPtrArray *plugins_array = g_ptr_array_new();
        struct bt_plugin **plugins = NULL;
        enum bt_plugin_status status;
 
-       if (!path) {
-               goto error;
-       }
-
-       plugins_array = g_ptr_array_new();
-       if (!plugins_array) {
-               goto error;
-       }
-
        /* Append found plugins to array */
        status = bt_plugin_create_append_all_from_dir(plugins_array, path,
                recurse);
@@ -544,124 +825,19 @@ end:
        return plugins;
 }
 
-static
-struct bt_plugin *bt_plugin_create_from_static_at_index(size_t i)
-{
-       struct bt_plugin *plugin = NULL;
-
-       plugin = g_new0(struct bt_plugin, 1);
-       if (!plugin) {
-               goto error;
-       }
-
-       bt_object_init(plugin, bt_plugin_destroy);
-
-       /* Create shared lib handle */
-       plugin->shared_lib_handle = bt_plugin_shared_lib_handle_create(NULL);
-       if (!plugin->shared_lib_handle) {
-               goto error;
-       }
-
-       /* Fill shared lib handle */
-       plugin->shared_lib_handle->init =
-               (SECTION_BEGIN(__bt_plugin_init_funcs))[i];
-       if (!plugin->shared_lib_handle->init) {
-               goto error;
-       }
-
-       plugin->shared_lib_handle->exit =
-               (SECTION_BEGIN(__bt_plugin_exit_funcs))[i];
-       if (!plugin->shared_lib_handle->exit) {
-               goto error;
-       }
-
-       plugin->shared_lib_handle->name = (SECTION_BEGIN(__bt_plugin_names))[i];
-       plugin->shared_lib_handle->author =
-               (SECTION_BEGIN(__bt_plugin_authors))[i];
-       plugin->shared_lib_handle->license =
-               (SECTION_BEGIN(__bt_plugin_licenses))[i];
-       plugin->shared_lib_handle->description =
-               (SECTION_BEGIN(__bt_plugin_descriptions))[i];
-
-       /* Create empty array of component classes */
-       plugin->comp_classes =
-               g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
-       if (!plugin->comp_classes) {
-               goto error;
-       }
-
-       /* Initialize plugin */
-       if (init_plugin(plugin) < 0) {
-               goto error;
-       }
-
-       goto end;
-
-error:
-       BT_PUT(plugin);
-
-end:
-       return plugin;
-}
-
-struct bt_plugin **bt_plugin_create_all_from_static(void)
-{
-       size_t count, i;
-       struct bt_plugin **plugins = NULL;
-
-       PRINT_PLUG_IN_SECTIONS(printf_verbose);
-       count = SECTION_ELEMENT_COUNT(__bt_plugin_init_funcs);
-       if (SECTION_ELEMENT_COUNT(__bt_plugin_exit_funcs) != count ||
-                       SECTION_ELEMENT_COUNT(__bt_plugin_names) != count ||
-                       SECTION_ELEMENT_COUNT(__bt_plugin_authors) != count ||
-                       SECTION_ELEMENT_COUNT(__bt_plugin_licenses) != count ||
-                       SECTION_ELEMENT_COUNT(__bt_plugin_descriptions) != count) {
-               printf_error("Some statically-linked plug-ins do not define all the mandatory symbols\n");
-               goto error;
-       }
-
-       printf_verbose("Detected %zu statically-linked plug-ins\n", count);
-       plugins = g_new0(struct bt_plugin *, count + 1);
-       if (!plugins) {
-               goto error;
-       }
-
-       for (i = 0; i < count; i++) {
-               struct bt_plugin *plugin =
-                       bt_plugin_create_from_static_at_index(i);
-
-               if (!plugin) {
-                       printf_error("Cannot create statically-linked plug-in at index %zu\n",
-                               i);
-                       goto error;
-               }
-
-               /* Transfer ownership to the array */
-               plugins[i] = plugin;
-       }
-
-       goto end;
-
-error:
-       g_free(plugins);
-
-end:
-       return plugins;
-}
-
 const char *bt_plugin_get_name(struct bt_plugin *plugin)
 {
-       return plugin ? plugin->shared_lib_handle->name : NULL;
+       return plugin ? plugin->name : NULL;
 }
 
 const char *bt_plugin_get_author(struct bt_plugin *plugin)
 {
-       return plugin ? plugin->shared_lib_handle->author : NULL;
+       return plugin ? plugin->author : NULL;
 }
 
 const char *bt_plugin_get_license(struct bt_plugin *plugin)
 {
-       return plugin ? plugin->shared_lib_handle->license : NULL;
+       return plugin ? plugin->license : NULL;
 }
 
 const char *bt_plugin_get_path(struct bt_plugin *plugin)
@@ -672,7 +848,7 @@ const char *bt_plugin_get_path(struct bt_plugin *plugin)
 
 const char *bt_plugin_get_description(struct bt_plugin *plugin)
 {
-       return plugin ? plugin->shared_lib_handle->description : NULL;
+       return plugin ? plugin->description : NULL;
 }
 
 int bt_plugin_get_component_class_count(struct bt_plugin *plugin)
@@ -765,7 +941,7 @@ enum bt_plugin_status bt_plugin_add_component_class(
                bt_component_class_get_type(comp_class));
        if (comp_class_dup) {
                printf_verbose("Plugin `%s`: adding component class with existing name `%s` and type %d\n",
-                       plugin->shared_lib_handle->name,
+                       plugin->name,
                        bt_component_class_get_name(comp_class),
                        bt_component_class_get_type(comp_class));
                goto error;
This page took 0.034202 seconds and 4 git commands to generate.