lib: strictly type function return status enumerations
[babeltrace.git] / src / lib / plugin / plugin-so.c
CommitLineData
55bb57e0 1/*
e2f7325d 2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
55bb57e0 3 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
55bb57e0
PP
4 *
5 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
350ad6c1 26#define BT_LOG_TAG "LIB/PLUGIN-SO"
c2d9d9cf 27#include "lib/logging.h"
3fe0bf43 28
578e048b
MJ
29#include "common/assert.h"
30#include "lib/assert-pre.h"
31#include "compat/compiler.h"
3fadfbc0 32#include <babeltrace2/plugin/plugin-dev.h>
578e048b 33#include "lib/graph/component-class.h"
3fadfbc0
MJ
34#include <babeltrace2/graph/component-class.h>
35#include <babeltrace2/graph/component-class-source.h>
36#include <babeltrace2/graph/component-class-filter.h>
37#include <babeltrace2/graph/component-class-sink.h>
38#include <babeltrace2/types.h>
578e048b 39#include "common/list.h"
55bb57e0 40#include <string.h>
0fbb9a9f 41#include <stdlib.h>
55bb57e0
PP
42#include <glib.h>
43#include <gmodule.h>
44
578e048b
MJ
45#include "plugin.h"
46#include "plugin-so.h"
d24d5663
PP
47#include "lib/func-status.h"
48#include "common/common.h"
578e048b 49
44a3451a 50#define NATIVE_PLUGIN_SUFFIX "." G_MODULE_SUFFIX
55bb57e0
PP
51#define NATIVE_PLUGIN_SUFFIX_LEN sizeof(NATIVE_PLUGIN_SUFFIX)
52#define LIBTOOL_PLUGIN_SUFFIX ".la"
53#define LIBTOOL_PLUGIN_SUFFIX_LEN sizeof(LIBTOOL_PLUGIN_SUFFIX)
54
91d81473 55#define PLUGIN_SUFFIX_LEN bt_max_t(size_t, sizeof(NATIVE_PLUGIN_SUFFIX), \
55bb57e0
PP
56 sizeof(LIBTOOL_PLUGIN_SUFFIX))
57
52238017 58BT_PLUGIN_MODULE();
55bb57e0
PP
59
60/*
bfa9a4be
MD
61 * This list, global to the library, keeps all component classes that
62 * have a reference to their shared library handles. It allows iteration
63 * on all component classes still present when the destructor executes
64 * to release the shared library handle references they might still have.
55bb57e0 65 *
bfa9a4be 66 * The list items are the component classes created with
55bb57e0
PP
67 * bt_plugin_add_component_class(). They keep the shared library handle
68 * object created by their plugin alive so that the plugin's code is
69 * not discarded when it could still be in use by living components
70 * created from those component classes:
71 *
bfa9a4be 72 * [component] --ref-> [component class]-> [shlib handle]
55bb57e0 73 *
bfa9a4be 74 * It allows this use-case:
55bb57e0 75 *
c8db3219 76 * my_plugins = bt_plugin_find_all_from_file("/path/to/my-plugin.so");
55bb57e0
PP
77 * // instantiate components from a plugin's component classes
78 * // put plugins and free my_plugins here
79 * // user code of instantiated components still exists
80 *
bfa9a4be
MD
81 * An entry is removed from this list when a component class is
82 * destroyed thanks to a custom destroy listener. When the entry is
83 * removed, the entry is removed from the list, and we release the
84 * reference on the shlib handle. Assuming the original plugin object
85 * which contained some component classes is put first, when the last
86 * component class is removed from this list, the shared library handle
87 * object's reference count falls to zero and the shared library is
88 * finally closed.
55bb57e0 89 */
bfa9a4be 90
55bb57e0 91static
bfa9a4be 92BT_LIST_HEAD(component_class_list);
55bb57e0
PP
93
94__attribute__((destructor)) static
bfa9a4be
MD
95void fini_comp_class_list(void)
96{
97 struct bt_component_class *comp_class, *tmp;
98
99 bt_list_for_each_entry_safe(comp_class, tmp, &component_class_list, node) {
100 bt_list_del(&comp_class->node);
65300d60 101 BT_OBJECT_PUT_REF_AND_RESET(comp_class->so_handle);
55bb57e0 102 }
d94d92ac 103
bfa9a4be 104 BT_LOGD_STR("Released references from all component classes to shared library handles.");
55bb57e0
PP
105}
106
107static
108void bt_plugin_so_shared_lib_handle_destroy(struct bt_object *obj)
109{
110 struct bt_plugin_so_shared_lib_handle *shared_lib_handle;
111
f6ccaed9 112 BT_ASSERT(obj);
55bb57e0
PP
113 shared_lib_handle = container_of(obj,
114 struct bt_plugin_so_shared_lib_handle, base);
3fe0bf43
PP
115 const char *path = shared_lib_handle->path ?
116 shared_lib_handle->path->str : NULL;
117
3f7d4d90 118 BT_LOGI("Destroying shared library handle: addr=%p, path=\"%s\"",
3fe0bf43 119 shared_lib_handle, path);
55bb57e0
PP
120
121 if (shared_lib_handle->init_called && shared_lib_handle->exit) {
3fe0bf43 122 BT_LOGD_STR("Calling user's plugin exit function.");
9724cce9
PP
123 shared_lib_handle->exit();
124 BT_LOGD_STR("User function returned.");
55bb57e0
PP
125 }
126
127 if (shared_lib_handle->module) {
3f3b1761 128#ifndef BT_DEBUG_MODE
f1447220
PP
129 /*
130 * Valgrind shows incomplete stack traces when
131 * dynamically loaded libraries are closed before it
16b7b5e7 132 * finishes. Use the LIBBABELTRACE2_NO_DLCLOSE in a debug
f1447220
PP
133 * build to avoid this.
134 */
16b7b5e7 135 const char *var = getenv("LIBBABELTRACE2_NO_DLCLOSE");
f1447220
PP
136
137 if (!var || strcmp(var, "1") != 0) {
138#endif
3f7d4d90 139 BT_LOGI("Closing GModule: path=\"%s\"", path);
3fe0bf43 140
f1447220 141 if (!g_module_close(shared_lib_handle->module)) {
3fe0bf43
PP
142 BT_LOGE("Cannot close GModule: %s: path=\"%s\"",
143 g_module_error(), path);
f1447220 144 }
db5504f9
PP
145
146 shared_lib_handle->module = NULL;
3f3b1761 147#ifndef BT_DEBUG_MODE
3fe0bf43 148 } else {
16b7b5e7 149 BT_LOGI("Not closing GModule because `LIBBABELTRACE2_NO_DLCLOSE=1`: "
3fe0bf43 150 "path=\"%s\"", path);
55bb57e0 151 }
f1447220 152#endif
55bb57e0
PP
153 }
154
155 if (shared_lib_handle->path) {
156 g_string_free(shared_lib_handle->path, TRUE);
db5504f9 157 shared_lib_handle->path = NULL;
55bb57e0
PP
158 }
159
160 g_free(shared_lib_handle);
161}
162
163static
d24d5663 164int bt_plugin_so_shared_lib_handle_create(
9736d991
PP
165 const char *path,
166 struct bt_plugin_so_shared_lib_handle **shared_lib_handle)
55bb57e0 167{
d24d5663 168 int status = BT_FUNC_STATUS_OK;
55bb57e0 169
9736d991 170 BT_ASSERT(shared_lib_handle);
3f7d4d90 171 BT_LOGI("Creating shared library handle: path=\"%s\"", path);
9736d991
PP
172 *shared_lib_handle = g_new0(struct bt_plugin_so_shared_lib_handle, 1);
173 if (!*shared_lib_handle) {
3fe0bf43 174 BT_LOGE_STR("Failed to allocate one shared library handle.");
d24d5663 175 status = BT_FUNC_STATUS_MEMORY_ERROR;
9736d991 176 goto end;
55bb57e0
PP
177 }
178
9736d991 179 bt_object_init_shared(&(*shared_lib_handle)->base,
3fea54f6 180 bt_plugin_so_shared_lib_handle_destroy);
55bb57e0
PP
181
182 if (!path) {
183 goto end;
184 }
185
9736d991
PP
186 (*shared_lib_handle)->path = g_string_new(path);
187 if (!(*shared_lib_handle)->path) {
3fe0bf43 188 BT_LOGE_STR("Failed to allocate a GString.");
d24d5663 189 status = BT_FUNC_STATUS_MEMORY_ERROR;
9736d991 190 goto end;
55bb57e0
PP
191 }
192
9736d991
PP
193 (*shared_lib_handle)->module = g_module_open(path, G_MODULE_BIND_LOCAL);
194 if (!(*shared_lib_handle)->module) {
50ad9320 195 /*
3f7d4d90 196 * INFO-level logging because we're only _trying_ to
50ad9320
PP
197 * open this file as a Babeltrace plugin: if it's not,
198 * it's not an error. And because this can be tried
3f7d4d90
PP
199 * during bt_plugin_find_all_from_dir(), it's not even a
200 * warning.
50ad9320 201 */
3f7d4d90 202 BT_LOGI("Cannot open GModule: %s: path=\"%s\"",
3fe0bf43 203 g_module_error(), path);
9736d991 204 BT_OBJECT_PUT_REF_AND_RESET(*shared_lib_handle);
d24d5663 205 status = BT_FUNC_STATUS_NOT_FOUND;
9736d991 206 goto end;
55bb57e0
PP
207 }
208
209 goto end;
210
55bb57e0 211end:
d24d5663 212 BT_ASSERT(*shared_lib_handle || status != BT_FUNC_STATUS_OK);
9736d991 213 if (*shared_lib_handle) {
3f7d4d90 214 BT_LOGI("Created shared library handle: path=\"%s\", addr=%p",
9736d991 215 path, *shared_lib_handle);
3fe0bf43
PP
216 }
217
9736d991 218 return status;
55bb57e0
PP
219}
220
6fbd4105 221static
55bb57e0
PP
222void bt_plugin_so_destroy_spec_data(struct bt_plugin *plugin)
223{
224 struct bt_plugin_so_spec_data *spec = plugin->spec_data;
225
226 if (!plugin->spec_data) {
227 return;
228 }
229
f6ccaed9
PP
230 BT_ASSERT(plugin->type == BT_PLUGIN_TYPE_SO);
231 BT_ASSERT(spec);
65300d60 232 BT_OBJECT_PUT_REF_AND_RESET(spec->shared_lib_handle);
55bb57e0
PP
233 g_free(plugin->spec_data);
234 plugin->spec_data = NULL;
235}
236
237/*
238 * This function does the following:
239 *
240 * 1. Iterate on the plugin descriptor attributes section and set the
241 * plugin's attributes depending on the attribute types. This
242 * includes the name of the plugin, its description, and its
243 * initialization function, for example.
244 *
245 * 2. Iterate on the component class descriptors section and create one
246 * "full descriptor" (temporary structure) for each one that is found
247 * and attached to our plugin descriptor.
248 *
249 * 3. Iterate on the component class descriptor attributes section and
250 * set the corresponding full descriptor's attributes depending on
251 * the attribute types. This includes the description of the
252 * component class, as well as its initialization and destroy
253 * methods.
254 *
255 * 4. Call the user's plugin initialization function, if any is
256 * defined.
257 *
258 * 5. For each full component class descriptor, create a component class
259 * object, set its optional attributes, and add it to the plugin
260 * object.
261 *
262 * 6. Freeze the plugin object.
263 */
264static
d24d5663 265int bt_plugin_so_init(struct bt_plugin *plugin,
9736d991 266 bool fail_on_load_error,
55bb57e0
PP
267 const struct __bt_plugin_descriptor *descriptor,
268 struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
269 struct __bt_plugin_descriptor_attribute const * const *attrs_end,
270 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
271 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
272 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
273 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end)
274{
275 /*
276 * This structure's members point to the plugin's memory
277 * (do NOT free).
278 */
279 struct comp_class_full_descriptor {
280 const struct __bt_plugin_component_class_descriptor *descriptor;
281 const char *description;
279b3f15 282 const char *help;
d94d92ac
PP
283
284 union {
285 struct {
0d72b8c3
PP
286 bt_component_class_source_init_method init;
287 bt_component_class_source_finalize_method finalize;
288 bt_component_class_source_query_method query;
0d72b8c3 289 bt_component_class_source_output_port_connected_method output_port_connected;
d6e69534
PP
290 bt_component_class_source_message_iterator_init_method msg_iter_init;
291 bt_component_class_source_message_iterator_finalize_method msg_iter_finalize;
7474e7d3
PP
292 bt_component_class_source_message_iterator_seek_ns_from_origin_method msg_iter_seek_ns_from_origin;
293 bt_component_class_source_message_iterator_seek_beginning_method msg_iter_seek_beginning;
294 bt_component_class_source_message_iterator_can_seek_ns_from_origin_method msg_iter_can_seek_ns_from_origin;
295 bt_component_class_source_message_iterator_can_seek_beginning_method msg_iter_can_seek_beginning;
d94d92ac
PP
296 } source;
297
298 struct {
0d72b8c3
PP
299 bt_component_class_filter_init_method init;
300 bt_component_class_filter_finalize_method finalize;
301 bt_component_class_filter_query_method query;
0d72b8c3
PP
302 bt_component_class_filter_input_port_connected_method input_port_connected;
303 bt_component_class_filter_output_port_connected_method output_port_connected;
d6e69534
PP
304 bt_component_class_filter_message_iterator_init_method msg_iter_init;
305 bt_component_class_filter_message_iterator_finalize_method msg_iter_finalize;
7474e7d3
PP
306 bt_component_class_filter_message_iterator_seek_ns_from_origin_method msg_iter_seek_ns_from_origin;
307 bt_component_class_filter_message_iterator_seek_beginning_method msg_iter_seek_beginning;
308 bt_component_class_filter_message_iterator_can_seek_ns_from_origin_method msg_iter_can_seek_ns_from_origin;
309 bt_component_class_filter_message_iterator_can_seek_beginning_method msg_iter_can_seek_beginning;
d94d92ac
PP
310 } filter;
311
312 struct {
0d72b8c3
PP
313 bt_component_class_sink_init_method init;
314 bt_component_class_sink_finalize_method finalize;
315 bt_component_class_sink_query_method query;
0d72b8c3 316 bt_component_class_sink_input_port_connected_method input_port_connected;
5badd463 317 bt_component_class_sink_graph_is_configured_method graph_is_configured;
d94d92ac
PP
318 } sink;
319 } methods;
55bb57e0
PP
320 };
321
d24d5663 322 int status = BT_FUNC_STATUS_OK;
55bb57e0
PP
323 struct __bt_plugin_descriptor_attribute const * const *cur_attr_ptr;
324 struct __bt_plugin_component_class_descriptor const * const *cur_cc_descr_ptr;
325 struct __bt_plugin_component_class_descriptor_attribute const * const *cur_cc_descr_attr_ptr;
326 struct bt_plugin_so_spec_data *spec = plugin->spec_data;
327 GArray *comp_class_full_descriptors;
328 size_t i;
329 int ret;
330
3f7d4d90 331 BT_LOGI("Initializing plugin object from descriptors found in sections: "
3fe0bf43
PP
332 "plugin-addr=%p, plugin-path=\"%s\", "
333 "attrs-begin-addr=%p, attrs-end-addr=%p, "
334 "cc-descr-begin-addr=%p, cc-descr-end-addr=%p, "
335 "cc-descr-attrs-begin-addr=%p, cc-descr-attrs-end-addr=%p",
336 plugin,
337 spec->shared_lib_handle->path ?
338 spec->shared_lib_handle->path->str : NULL,
339 attrs_begin, attrs_end,
340 cc_descriptors_begin, cc_descriptors_end,
341 cc_descr_attrs_begin, cc_descr_attrs_end);
55bb57e0
PP
342 comp_class_full_descriptors = g_array_new(FALSE, TRUE,
343 sizeof(struct comp_class_full_descriptor));
344 if (!comp_class_full_descriptors) {
3fe0bf43 345 BT_LOGE_STR("Failed to allocate a GArray.");
d24d5663 346 status = BT_FUNC_STATUS_MEMORY_ERROR;
55bb57e0
PP
347 goto end;
348 }
349
350 /* Set mandatory attributes */
351 spec->descriptor = descriptor;
352 bt_plugin_set_name(plugin, descriptor->name);
353
354 /*
355 * Find and set optional attributes attached to this plugin
356 * descriptor.
357 */
358 for (cur_attr_ptr = attrs_begin; cur_attr_ptr != attrs_end; cur_attr_ptr++) {
359 const struct __bt_plugin_descriptor_attribute *cur_attr =
360 *cur_attr_ptr;
361
52238017
MJ
362 if (cur_attr == NULL) {
363 continue;
364 }
365
55bb57e0
PP
366 if (cur_attr->plugin_descriptor != descriptor) {
367 continue;
368 }
369
370 switch (cur_attr->type) {
371 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_INIT:
372 spec->init = cur_attr->value.init;
373 break;
374 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_EXIT:
375 spec->shared_lib_handle->exit = cur_attr->value.exit;
376 break;
377 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_AUTHOR:
378 bt_plugin_set_author(plugin, cur_attr->value.author);
379 break;
380 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_LICENSE:
381 bt_plugin_set_license(plugin, cur_attr->value.license);
382 break;
383 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
384 bt_plugin_set_description(plugin, cur_attr->value.description);
385 break;
386 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_VERSION:
387 bt_plugin_set_version(plugin,
388 (unsigned int) cur_attr->value.version.major,
389 (unsigned int) cur_attr->value.version.minor,
390 (unsigned int) cur_attr->value.version.patch,
391 cur_attr->value.version.extra);
392 break;
393 default:
9736d991
PP
394 BT_LOG_WRITE(fail_on_load_error ?
395 BT_LOG_WARN : BT_LOG_INFO, BT_LOG_TAG,
396 "%s plugin descriptor attribute: "
3fe0bf43
PP
397 "plugin-path=\"%s\", plugin-name=\"%s\", "
398 "attr-type-name=\"%s\", attr-type-id=%d",
9736d991
PP
399 fail_on_load_error ? "Unknown" :
400 "Ignoring unknown",
3fe0bf43
PP
401 spec->shared_lib_handle->path ?
402 spec->shared_lib_handle->path->str :
403 NULL,
404 descriptor->name, cur_attr->type_name,
405 cur_attr->type);
9736d991
PP
406
407 if (fail_on_load_error) {
d24d5663 408 status = BT_FUNC_STATUS_LOADING_ERROR;
9736d991
PP
409 goto end;
410 }
411
55bb57e0
PP
412 break;
413 }
414 }
415
416 /*
417 * Find component class descriptors attached to this plugin
418 * descriptor and initialize corresponding full component class
419 * descriptors in the array.
420 */
421 for (cur_cc_descr_ptr = cc_descriptors_begin; cur_cc_descr_ptr != cc_descriptors_end; cur_cc_descr_ptr++) {
422 const struct __bt_plugin_component_class_descriptor *cur_cc_descr =
423 *cur_cc_descr_ptr;
424 struct comp_class_full_descriptor full_descriptor = {0};
425
52238017
MJ
426 if (cur_cc_descr == NULL) {
427 continue;
428 }
429
55bb57e0
PP
430 if (cur_cc_descr->plugin_descriptor != descriptor) {
431 continue;
432 }
433
434 full_descriptor.descriptor = cur_cc_descr;
435 g_array_append_val(comp_class_full_descriptors,
436 full_descriptor);
437 }
438
439 /*
440 * Find component class descriptor attributes attached to this
441 * plugin descriptor and update corresponding full component
442 * class descriptors in the array.
443 */
444 for (cur_cc_descr_attr_ptr = cc_descr_attrs_begin; cur_cc_descr_attr_ptr != cc_descr_attrs_end; cur_cc_descr_attr_ptr++) {
445 const struct __bt_plugin_component_class_descriptor_attribute *cur_cc_descr_attr =
446 *cur_cc_descr_attr_ptr;
d94d92ac 447 enum bt_component_class_type cc_type;
55bb57e0 448
52238017
MJ
449 if (cur_cc_descr_attr == NULL) {
450 continue;
451 }
452
55bb57e0
PP
453 if (cur_cc_descr_attr->comp_class_descriptor->plugin_descriptor !=
454 descriptor) {
455 continue;
456 }
457
d94d92ac
PP
458 cc_type = cur_cc_descr_attr->comp_class_descriptor->type;
459
55bb57e0
PP
460 /* Find the corresponding component class descriptor entry */
461 for (i = 0; i < comp_class_full_descriptors->len; i++) {
462 struct comp_class_full_descriptor *cc_full_descr =
463 &g_array_index(comp_class_full_descriptors,
464 struct comp_class_full_descriptor, i);
465
d94d92ac 466 if (cur_cc_descr_attr->comp_class_descriptor !=
55bb57e0 467 cc_full_descr->descriptor) {
d94d92ac
PP
468 continue;
469 }
470
471 switch (cur_cc_descr_attr->type) {
472 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
473 cc_full_descr->description =
474 cur_cc_descr_attr->value.description;
475 break;
476 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_HELP:
477 cc_full_descr->help =
478 cur_cc_descr_attr->value.help;
479 break;
480 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_INIT_METHOD:
481 switch (cc_type) {
482 case BT_COMPONENT_CLASS_TYPE_SOURCE:
483 cc_full_descr->methods.source.init =
484 cur_cc_descr_attr->value.source_init_method;
55bb57e0 485 break;
d94d92ac
PP
486 case BT_COMPONENT_CLASS_TYPE_FILTER:
487 cc_full_descr->methods.filter.init =
488 cur_cc_descr_attr->value.filter_init_method;
279b3f15 489 break;
d94d92ac
PP
490 case BT_COMPONENT_CLASS_TYPE_SINK:
491 cc_full_descr->methods.sink.init =
492 cur_cc_descr_attr->value.sink_init_method;
55bb57e0 493 break;
d94d92ac
PP
494 default:
495 abort();
496 }
497 break;
498 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_FINALIZE_METHOD:
499 switch (cc_type) {
500 case BT_COMPONENT_CLASS_TYPE_SOURCE:
501 cc_full_descr->methods.source.finalize =
502 cur_cc_descr_attr->value.source_finalize_method;
55bb57e0 503 break;
d94d92ac
PP
504 case BT_COMPONENT_CLASS_TYPE_FILTER:
505 cc_full_descr->methods.filter.finalize =
506 cur_cc_descr_attr->value.filter_finalize_method;
8463eac2 507 break;
d94d92ac
PP
508 case BT_COMPONENT_CLASS_TYPE_SINK:
509 cc_full_descr->methods.sink.finalize =
510 cur_cc_descr_attr->value.sink_finalize_method;
72b913fb 511 break;
d94d92ac
PP
512 default:
513 abort();
514 }
515 break;
516 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_QUERY_METHOD:
517 switch (cc_type) {
518 case BT_COMPONENT_CLASS_TYPE_SOURCE:
519 cc_full_descr->methods.source.query =
520 cur_cc_descr_attr->value.source_query_method;
0d8b4d8e 521 break;
d94d92ac
PP
522 case BT_COMPONENT_CLASS_TYPE_FILTER:
523 cc_full_descr->methods.filter.query =
524 cur_cc_descr_attr->value.filter_query_method;
55bb57e0 525 break;
d94d92ac
PP
526 case BT_COMPONENT_CLASS_TYPE_SINK:
527 cc_full_descr->methods.sink.query =
528 cur_cc_descr_attr->value.sink_query_method;
55bb57e0 529 break;
d94d92ac
PP
530 default:
531 abort();
532 }
533 break;
d94d92ac
PP
534 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_INPUT_PORT_CONNECTED_METHOD:
535 switch (cc_type) {
536 case BT_COMPONENT_CLASS_TYPE_FILTER:
537 cc_full_descr->methods.filter.input_port_connected =
538 cur_cc_descr_attr->value.filter_input_port_connected_method;
539 break;
540 case BT_COMPONENT_CLASS_TYPE_SINK:
541 cc_full_descr->methods.sink.input_port_connected =
542 cur_cc_descr_attr->value.sink_input_port_connected_method;
55bb57e0 543 break;
55bb57e0 544 default:
d94d92ac
PP
545 abort();
546 }
547 break;
548 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_OUTPUT_PORT_CONNECTED_METHOD:
549 switch (cc_type) {
550 case BT_COMPONENT_CLASS_TYPE_SOURCE:
551 cc_full_descr->methods.source.output_port_connected =
552 cur_cc_descr_attr->value.source_output_port_connected_method;
553 break;
554 case BT_COMPONENT_CLASS_TYPE_FILTER:
555 cc_full_descr->methods.filter.output_port_connected =
556 cur_cc_descr_attr->value.filter_output_port_connected_method;
55bb57e0 557 break;
d94d92ac
PP
558 default:
559 abort();
55bb57e0 560 }
d94d92ac 561 break;
5badd463
PP
562 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_GRAPH_IS_CONFIGURED_METHOD:
563 switch (cc_type) {
564 case BT_COMPONENT_CLASS_TYPE_SINK:
565 cc_full_descr->methods.sink.graph_is_configured =
566 cur_cc_descr_attr->value.sink_graph_is_configured_method;
567 break;
568 default:
569 abort();
570 }
571 break;
d6e69534 572 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_INIT_METHOD:
d94d92ac
PP
573 switch (cc_type) {
574 case BT_COMPONENT_CLASS_TYPE_SOURCE:
d6e69534
PP
575 cc_full_descr->methods.source.msg_iter_init =
576 cur_cc_descr_attr->value.source_msg_iter_init_method;
d94d92ac
PP
577 break;
578 case BT_COMPONENT_CLASS_TYPE_FILTER:
d6e69534
PP
579 cc_full_descr->methods.filter.msg_iter_init =
580 cur_cc_descr_attr->value.filter_msg_iter_init_method;
d94d92ac
PP
581 break;
582 default:
583 abort();
584 }
585 break;
d6e69534 586 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_FINALIZE_METHOD:
d94d92ac
PP
587 switch (cc_type) {
588 case BT_COMPONENT_CLASS_TYPE_SOURCE:
d6e69534
PP
589 cc_full_descr->methods.source.msg_iter_finalize =
590 cur_cc_descr_attr->value.source_msg_iter_finalize_method;
d94d92ac
PP
591 break;
592 case BT_COMPONENT_CLASS_TYPE_FILTER:
d6e69534
PP
593 cc_full_descr->methods.filter.msg_iter_finalize =
594 cur_cc_descr_attr->value.filter_msg_iter_finalize_method;
d94d92ac
PP
595 break;
596 default:
597 abort();
598 }
599 break;
7474e7d3
PP
600 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_NS_FROM_ORIGIN_METHOD:
601 switch (cc_type) {
602 case BT_COMPONENT_CLASS_TYPE_SOURCE:
603 cc_full_descr->methods.source.msg_iter_seek_ns_from_origin =
604 cur_cc_descr_attr->value.source_msg_iter_seek_ns_from_origin_method;
605 break;
606 case BT_COMPONENT_CLASS_TYPE_FILTER:
607 cc_full_descr->methods.filter.msg_iter_seek_ns_from_origin =
608 cur_cc_descr_attr->value.filter_msg_iter_seek_ns_from_origin_method;
609 break;
610 default:
611 abort();
612 }
613 break;
614 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_BEGINNING_METHOD:
615 switch (cc_type) {
616 case BT_COMPONENT_CLASS_TYPE_SOURCE:
617 cc_full_descr->methods.source.msg_iter_seek_beginning =
618 cur_cc_descr_attr->value.source_msg_iter_seek_beginning_method;
619 break;
620 case BT_COMPONENT_CLASS_TYPE_FILTER:
621 cc_full_descr->methods.filter.msg_iter_seek_beginning =
622 cur_cc_descr_attr->value.filter_msg_iter_seek_beginning_method;
623 break;
624 default:
625 abort();
626 }
627 break;
628 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_NS_FROM_ORIGIN_METHOD:
629 switch (cc_type) {
630 case BT_COMPONENT_CLASS_TYPE_SOURCE:
631 cc_full_descr->methods.source.msg_iter_can_seek_ns_from_origin =
632 cur_cc_descr_attr->value.source_msg_iter_can_seek_ns_from_origin_method;
633 break;
634 case BT_COMPONENT_CLASS_TYPE_FILTER:
635 cc_full_descr->methods.filter.msg_iter_can_seek_ns_from_origin =
636 cur_cc_descr_attr->value.filter_msg_iter_can_seek_ns_from_origin_method;
637 break;
638 default:
639 abort();
640 }
641 break;
642 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_BEGINNING_METHOD:
643 switch (cc_type) {
644 case BT_COMPONENT_CLASS_TYPE_SOURCE:
645 cc_full_descr->methods.source.msg_iter_can_seek_beginning =
646 cur_cc_descr_attr->value.source_msg_iter_can_seek_beginning_method;
647 break;
648 case BT_COMPONENT_CLASS_TYPE_FILTER:
649 cc_full_descr->methods.filter.msg_iter_can_seek_beginning =
650 cur_cc_descr_attr->value.filter_msg_iter_can_seek_beginning_method;
651 break;
652 default:
653 abort();
654 }
655 break;
d94d92ac 656 default:
9736d991
PP
657 BT_LOG_WRITE(fail_on_load_error ?
658 BT_LOG_WARN : BT_LOG_INFO, BT_LOG_TAG,
659 "%s component class descriptor attribute: "
d94d92ac
PP
660 "plugin-path=\"%s\", "
661 "plugin-name=\"%s\", "
662 "comp-class-name=\"%s\", "
663 "comp-class-type=%s, "
664 "attr-type-name=\"%s\", "
665 "attr-type-id=%d",
9736d991
PP
666 fail_on_load_error ? "Unknown" :
667 "Ignoring unknown",
d94d92ac
PP
668 spec->shared_lib_handle->path ?
669 spec->shared_lib_handle->path->str :
670 NULL,
671 descriptor->name,
672 cur_cc_descr_attr->comp_class_descriptor->name,
673 bt_component_class_type_string(
674 cur_cc_descr_attr->comp_class_descriptor->type),
675 cur_cc_descr_attr->type_name,
676 cur_cc_descr_attr->type);
9736d991
PP
677
678 if (fail_on_load_error) {
d24d5663 679 status = BT_FUNC_STATUS_LOADING_ERROR;
9736d991
PP
680 goto end;
681 }
682
d94d92ac 683 break;
55bb57e0
PP
684 }
685 }
686 }
687
688 /* Initialize plugin */
689 if (spec->init) {
d24d5663 690 enum bt_plugin_init_func_status init_status;
a21d1cb8 691
3fe0bf43 692 BT_LOGD_STR("Calling user's plugin initialization function.");
a21d1cb8 693 init_status = spec->init((void *) plugin);
9736d991 694 BT_LOGD("User function returned: status=%s",
d24d5663 695 bt_common_func_status_string(init_status));
3fe0bf43 696
9724cce9 697 if (init_status < 0) {
9736d991
PP
698 BT_LOG_WRITE(fail_on_load_error ?
699 BT_LOG_WARN : BT_LOG_INFO, BT_LOG_TAG,
700 "User's plugin initialization function failed: "
701 "status=%s",
d24d5663 702 bt_common_func_status_string(init_status));
9736d991
PP
703
704 if (fail_on_load_error) {
d24d5663 705 status = init_status;
9736d991
PP
706 goto end;
707 }
55bb57e0
PP
708 }
709 }
710
c55a9f58 711 spec->shared_lib_handle->init_called = BT_TRUE;
55bb57e0
PP
712
713 /* Add described component classes to plugin */
714 for (i = 0; i < comp_class_full_descriptors->len; i++) {
715 struct comp_class_full_descriptor *cc_full_descr =
716 &g_array_index(comp_class_full_descriptors,
717 struct comp_class_full_descriptor, i);
0d72b8c3
PP
718 struct bt_component_class *comp_class = NULL;
719 struct bt_component_class_source *src_comp_class = NULL;
720 struct bt_component_class_filter *flt_comp_class = NULL;
721 struct bt_component_class_sink *sink_comp_class = NULL;
55bb57e0 722
3f7d4d90 723 BT_LOGI("Creating and setting properties of plugin's component class: "
3fe0bf43
PP
724 "plugin-path=\"%s\", plugin-name=\"%s\", "
725 "comp-class-name=\"%s\", comp-class-type=%s",
726 spec->shared_lib_handle->path ?
727 spec->shared_lib_handle->path->str :
728 NULL,
729 descriptor->name,
730 cc_full_descr->descriptor->name,
731 bt_component_class_type_string(
732 cc_full_descr->descriptor->type));
733
55bb57e0
PP
734 switch (cc_full_descr->descriptor->type) {
735 case BT_COMPONENT_CLASS_TYPE_SOURCE:
0d72b8c3 736 src_comp_class = bt_component_class_source_create(
55bb57e0 737 cc_full_descr->descriptor->name,
d6e69534 738 cc_full_descr->descriptor->methods.source.msg_iter_next);
0d72b8c3 739 comp_class = bt_component_class_source_as_component_class(
d94d92ac 740 src_comp_class);
55bb57e0
PP
741 break;
742 case BT_COMPONENT_CLASS_TYPE_FILTER:
0d72b8c3 743 flt_comp_class = bt_component_class_filter_create(
55bb57e0 744 cc_full_descr->descriptor->name,
d6e69534 745 cc_full_descr->descriptor->methods.source.msg_iter_next);
0d72b8c3 746 comp_class = bt_component_class_filter_as_component_class(
d94d92ac 747 flt_comp_class);
55bb57e0
PP
748 break;
749 case BT_COMPONENT_CLASS_TYPE_SINK:
0d72b8c3 750 sink_comp_class = bt_component_class_sink_create(
55bb57e0
PP
751 cc_full_descr->descriptor->name,
752 cc_full_descr->descriptor->methods.sink.consume);
0d72b8c3 753 comp_class = bt_component_class_sink_as_component_class(
d94d92ac 754 sink_comp_class);
55bb57e0
PP
755 break;
756 default:
9736d991
PP
757 BT_LOG_WRITE(fail_on_load_error ?
758 BT_LOG_WARN : BT_LOG_INFO, BT_LOG_TAG,
759 "%s component class type: "
3fe0bf43
PP
760 "plugin-path=\"%s\", plugin-name=\"%s\", "
761 "comp-class-name=\"%s\", comp-class-type=%d",
9736d991
PP
762 fail_on_load_error ? "Unknown" :
763 "Ignoring unknown",
3fe0bf43
PP
764 spec->shared_lib_handle->path->str ?
765 spec->shared_lib_handle->path->str :
766 NULL,
767 descriptor->name,
55bb57e0 768 cc_full_descr->descriptor->name,
3fe0bf43 769 cc_full_descr->descriptor->type);
9736d991
PP
770
771 if (fail_on_load_error) {
d24d5663 772 status = BT_FUNC_STATUS_LOADING_ERROR;
9736d991
PP
773 goto end;
774 }
775
55bb57e0
PP
776 continue;
777 }
778
779 if (!comp_class) {
3fe0bf43 780 BT_LOGE_STR("Cannot create component class.");
d24d5663 781 status = BT_FUNC_STATUS_MEMORY_ERROR;
55bb57e0
PP
782 goto end;
783 }
784
785 if (cc_full_descr->description) {
0d72b8c3 786 ret = bt_component_class_set_description(
d94d92ac 787 comp_class, cc_full_descr->description);
55bb57e0 788 if (ret) {
3fe0bf43 789 BT_LOGE_STR("Cannot set component class's description.");
d24d5663 790 status = BT_FUNC_STATUS_MEMORY_ERROR;
65300d60 791 BT_OBJECT_PUT_REF_AND_RESET(comp_class);
55bb57e0
PP
792 goto end;
793 }
794 }
795
279b3f15 796 if (cc_full_descr->help) {
0d72b8c3 797 ret = bt_component_class_set_help(comp_class,
279b3f15
PP
798 cc_full_descr->help);
799 if (ret) {
3fe0bf43 800 BT_LOGE_STR("Cannot set component class's help string.");
d24d5663 801 status = BT_FUNC_STATUS_MEMORY_ERROR;
65300d60 802 BT_OBJECT_PUT_REF_AND_RESET(comp_class);
279b3f15
PP
803 goto end;
804 }
805 }
806
d94d92ac
PP
807 switch (cc_full_descr->descriptor->type) {
808 case BT_COMPONENT_CLASS_TYPE_SOURCE:
809 if (cc_full_descr->methods.source.init) {
0d72b8c3 810 ret = bt_component_class_source_set_init_method(
d94d92ac
PP
811 src_comp_class,
812 cc_full_descr->methods.source.init);
813 if (ret) {
814 BT_LOGE_STR("Cannot set source component class's initialization method.");
d24d5663 815 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
816 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
817 goto end;
818 }
55bb57e0 819 }
55bb57e0 820
d94d92ac 821 if (cc_full_descr->methods.source.finalize) {
0d72b8c3 822 ret = bt_component_class_source_set_finalize_method(
d94d92ac
PP
823 src_comp_class,
824 cc_full_descr->methods.source.finalize);
825 if (ret) {
826 BT_LOGE_STR("Cannot set source component class's finalization method.");
d24d5663 827 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
828 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
829 goto end;
830 }
55bb57e0 831 }
55bb57e0 832
d94d92ac 833 if (cc_full_descr->methods.source.query) {
0d72b8c3 834 ret = bt_component_class_source_set_query_method(
d94d92ac
PP
835 src_comp_class,
836 cc_full_descr->methods.source.query);
837 if (ret) {
838 BT_LOGE_STR("Cannot set source component class's query method.");
d24d5663 839 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
840 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
841 goto end;
842 }
8463eac2 843 }
8463eac2 844
d94d92ac 845 if (cc_full_descr->methods.source.output_port_connected) {
0d72b8c3 846 ret = bt_component_class_source_set_output_port_connected_method(
d94d92ac
PP
847 src_comp_class,
848 cc_full_descr->methods.source.output_port_connected);
849 if (ret) {
850 BT_LOGE_STR("Cannot set source component class's \"output port connected\" method.");
d24d5663 851 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
852 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
853 goto end;
854 }
0d8b4d8e 855 }
0d8b4d8e 856
d6e69534
PP
857 if (cc_full_descr->methods.source.msg_iter_init) {
858 ret = bt_component_class_source_set_message_iterator_init_method(
d94d92ac 859 src_comp_class,
d6e69534 860 cc_full_descr->methods.source.msg_iter_init);
55bb57e0 861 if (ret) {
d6e69534 862 BT_LOGE_STR("Cannot set source component class's message iterator initialization method.");
d24d5663 863 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac 864 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
55bb57e0
PP
865 goto end;
866 }
867 }
868
d6e69534
PP
869 if (cc_full_descr->methods.source.msg_iter_finalize) {
870 ret = bt_component_class_source_set_message_iterator_finalize_method(
d94d92ac 871 src_comp_class,
d6e69534 872 cc_full_descr->methods.source.msg_iter_finalize);
55bb57e0 873 if (ret) {
d6e69534 874 BT_LOGE_STR("Cannot set source component class's message iterator finalization method.");
d24d5663 875 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac 876 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
55bb57e0
PP
877 goto end;
878 }
879 }
d94d92ac 880
7474e7d3
PP
881 if (cc_full_descr->methods.source.msg_iter_seek_ns_from_origin) {
882 ret = bt_component_class_source_set_message_iterator_seek_ns_from_origin_method(
883 src_comp_class,
884 cc_full_descr->methods.source.msg_iter_seek_ns_from_origin);
885 if (ret) {
886 BT_LOGE_STR("Cannot set source component class's message iterator \"seek nanoseconds from origin\" method.");
d24d5663 887 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
888 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
889 goto end;
890 }
891 }
892
893 if (cc_full_descr->methods.source.msg_iter_seek_beginning) {
894 ret = bt_component_class_source_set_message_iterator_seek_beginning_method(
895 src_comp_class,
896 cc_full_descr->methods.source.msg_iter_seek_beginning);
897 if (ret) {
898 BT_LOGE_STR("Cannot set source component class's message iterator \"seek beginning\" method.");
d24d5663 899 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
900 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
901 goto end;
902 }
903 }
904
905 if (cc_full_descr->methods.source.msg_iter_can_seek_ns_from_origin) {
906 ret = bt_component_class_source_set_message_iterator_can_seek_ns_from_origin_method(
907 src_comp_class,
908 cc_full_descr->methods.source.msg_iter_can_seek_ns_from_origin);
909 if (ret) {
910 BT_LOGE_STR("Cannot set source component class's message iterator \"can seek nanoseconds from origin\" method.");
d24d5663 911 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
912 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
913 goto end;
914 }
915 }
916
917 if (cc_full_descr->methods.source.msg_iter_can_seek_beginning) {
918 ret = bt_component_class_source_set_message_iterator_can_seek_beginning_method(
919 src_comp_class,
920 cc_full_descr->methods.source.msg_iter_can_seek_beginning);
921 if (ret) {
922 BT_LOGE_STR("Cannot set source component class's message iterator \"can seek beginning\" method.");
d24d5663 923 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
924 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
925 goto end;
926 }
927 }
928
55bb57e0
PP
929 break;
930 case BT_COMPONENT_CLASS_TYPE_FILTER:
d94d92ac 931 if (cc_full_descr->methods.filter.init) {
0d72b8c3 932 ret = bt_component_class_filter_set_init_method(
d94d92ac
PP
933 flt_comp_class,
934 cc_full_descr->methods.filter.init);
935 if (ret) {
936 BT_LOGE_STR("Cannot set filter component class's initialization method.");
d24d5663 937 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
938 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
939 goto end;
940 }
941 }
942
943 if (cc_full_descr->methods.filter.finalize) {
0d72b8c3 944 ret = bt_component_class_filter_set_finalize_method(
d94d92ac
PP
945 flt_comp_class,
946 cc_full_descr->methods.filter.finalize);
947 if (ret) {
948 BT_LOGE_STR("Cannot set filter component class's finalization method.");
d24d5663 949 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
950 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
951 goto end;
952 }
953 }
954
955 if (cc_full_descr->methods.filter.query) {
0d72b8c3 956 ret = bt_component_class_filter_set_query_method(
d94d92ac
PP
957 flt_comp_class,
958 cc_full_descr->methods.filter.query);
959 if (ret) {
960 BT_LOGE_STR("Cannot set filter component class's query method.");
d24d5663 961 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
962 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
963 goto end;
964 }
965 }
966
d94d92ac 967 if (cc_full_descr->methods.filter.input_port_connected) {
0d72b8c3 968 ret = bt_component_class_filter_set_input_port_connected_method(
d94d92ac
PP
969 flt_comp_class,
970 cc_full_descr->methods.filter.input_port_connected);
971 if (ret) {
972 BT_LOGE_STR("Cannot set filter component class's \"input port connected\" method.");
d24d5663 973 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
974 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
975 goto end;
976 }
977 }
978
979 if (cc_full_descr->methods.filter.output_port_connected) {
0d72b8c3 980 ret = bt_component_class_filter_set_output_port_connected_method(
d94d92ac
PP
981 flt_comp_class,
982 cc_full_descr->methods.filter.output_port_connected);
983 if (ret) {
984 BT_LOGE_STR("Cannot set filter component class's \"output port connected\" method.");
d24d5663 985 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
986 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
987 goto end;
988 }
989 }
990
d6e69534
PP
991 if (cc_full_descr->methods.filter.msg_iter_init) {
992 ret = bt_component_class_filter_set_message_iterator_init_method(
d94d92ac 993 flt_comp_class,
d6e69534 994 cc_full_descr->methods.filter.msg_iter_init);
55bb57e0 995 if (ret) {
d6e69534 996 BT_LOGE_STR("Cannot set filter component class's message iterator initialization method.");
d24d5663 997 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac 998 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
55bb57e0
PP
999 goto end;
1000 }
1001 }
1002
d6e69534
PP
1003 if (cc_full_descr->methods.filter.msg_iter_finalize) {
1004 ret = bt_component_class_filter_set_message_iterator_finalize_method(
d94d92ac 1005 flt_comp_class,
d6e69534 1006 cc_full_descr->methods.filter.msg_iter_finalize);
55bb57e0 1007 if (ret) {
d6e69534 1008 BT_LOGE_STR("Cannot set filter component class's message iterator finalization method.");
d24d5663 1009 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac 1010 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
55bb57e0
PP
1011 goto end;
1012 }
1013 }
d94d92ac 1014
7474e7d3
PP
1015 if (cc_full_descr->methods.filter.msg_iter_seek_ns_from_origin) {
1016 ret = bt_component_class_filter_set_message_iterator_seek_ns_from_origin_method(
1017 flt_comp_class,
1018 cc_full_descr->methods.filter.msg_iter_seek_ns_from_origin);
1019 if (ret) {
1020 BT_LOGE_STR("Cannot set filter component class's message iterator \"seek nanoseconds from origin\" method.");
d24d5663 1021 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
1022 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1023 goto end;
1024 }
1025 }
1026
1027 if (cc_full_descr->methods.filter.msg_iter_seek_beginning) {
1028 ret = bt_component_class_filter_set_message_iterator_seek_beginning_method(
1029 flt_comp_class,
1030 cc_full_descr->methods.filter.msg_iter_seek_beginning);
1031 if (ret) {
1032 BT_LOGE_STR("Cannot set filter component class's message iterator \"seek beginning\" method.");
d24d5663 1033 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
1034 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1035 goto end;
1036 }
1037 }
1038
1039 if (cc_full_descr->methods.filter.msg_iter_can_seek_ns_from_origin) {
1040 ret = bt_component_class_filter_set_message_iterator_can_seek_ns_from_origin_method(
1041 flt_comp_class,
1042 cc_full_descr->methods.filter.msg_iter_can_seek_ns_from_origin);
1043 if (ret) {
1044 BT_LOGE_STR("Cannot set filter component class's message iterator \"can seek nanoseconds from origin\" method.");
d24d5663 1045 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
1046 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1047 goto end;
1048 }
1049 }
1050
1051 if (cc_full_descr->methods.filter.msg_iter_can_seek_beginning) {
1052 ret = bt_component_class_filter_set_message_iterator_can_seek_beginning_method(
1053 flt_comp_class,
1054 cc_full_descr->methods.filter.msg_iter_can_seek_beginning);
1055 if (ret) {
1056 BT_LOGE_STR("Cannot set filter component class's message iterator \"can seek beginning\" method.");
d24d5663 1057 status = BT_FUNC_STATUS_MEMORY_ERROR;
7474e7d3
PP
1058 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1059 goto end;
1060 }
1061 }
1062
55bb57e0
PP
1063 break;
1064 case BT_COMPONENT_CLASS_TYPE_SINK:
d94d92ac 1065 if (cc_full_descr->methods.sink.init) {
0d72b8c3 1066 ret = bt_component_class_sink_set_init_method(
d94d92ac
PP
1067 sink_comp_class,
1068 cc_full_descr->methods.sink.init);
1069 if (ret) {
1070 BT_LOGE_STR("Cannot set sink component class's initialization method.");
d24d5663 1071 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
1072 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1073 goto end;
1074 }
1075 }
1076
1077 if (cc_full_descr->methods.sink.finalize) {
0d72b8c3 1078 ret = bt_component_class_sink_set_finalize_method(
d94d92ac
PP
1079 sink_comp_class,
1080 cc_full_descr->methods.sink.finalize);
1081 if (ret) {
1082 BT_LOGE_STR("Cannot set sink component class's finalization method.");
d24d5663 1083 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
1084 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1085 goto end;
1086 }
1087 }
1088
1089 if (cc_full_descr->methods.sink.query) {
0d72b8c3 1090 ret = bt_component_class_sink_set_query_method(
d94d92ac
PP
1091 sink_comp_class,
1092 cc_full_descr->methods.sink.query);
1093 if (ret) {
1094 BT_LOGE_STR("Cannot set sink component class's query method.");
d24d5663 1095 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
1096 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1097 goto end;
1098 }
1099 }
1100
d94d92ac 1101 if (cc_full_descr->methods.sink.input_port_connected) {
0d72b8c3 1102 ret = bt_component_class_sink_set_input_port_connected_method(
d94d92ac
PP
1103 sink_comp_class,
1104 cc_full_descr->methods.sink.input_port_connected);
1105 if (ret) {
1106 BT_LOGE_STR("Cannot set sink component class's \"input port connected\" method.");
d24d5663 1107 status = BT_FUNC_STATUS_MEMORY_ERROR;
d94d92ac
PP
1108 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1109 goto end;
1110 }
1111 }
1112
5badd463
PP
1113 if (cc_full_descr->methods.sink.graph_is_configured) {
1114 ret = bt_component_class_sink_set_graph_is_configured_method(
1115 sink_comp_class,
1116 cc_full_descr->methods.sink.graph_is_configured);
1117 if (ret) {
1118 BT_LOGE_STR("Cannot set sink component class's \"graph is configured\" method.");
d24d5663 1119 status = BT_FUNC_STATUS_MEMORY_ERROR;
5badd463
PP
1120 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1121 goto end;
1122 }
1123 }
1124
55bb57e0
PP
1125 break;
1126 default:
0fbb9a9f 1127 abort();
55bb57e0
PP
1128 }
1129
1130 /*
1131 * Add component class to the plugin object.
1132 *
1133 * This will call back
1134 * bt_plugin_so_on_add_component_class() so that we can
d94d92ac
PP
1135 * add a mapping in the component class list when we
1136 * know the component class is successfully added.
55bb57e0
PP
1137 */
1138 status = bt_plugin_add_component_class(plugin,
d94d92ac 1139 (void *) comp_class);
65300d60 1140 BT_OBJECT_PUT_REF_AND_RESET(comp_class);
55bb57e0 1141 if (status < 0) {
3fe0bf43 1142 BT_LOGE("Cannot add component class to plugin.");
55bb57e0
PP
1143 goto end;
1144 }
1145 }
1146
55bb57e0
PP
1147end:
1148 g_array_free(comp_class_full_descriptors, TRUE);
1149 return status;
1150}
1151
1152static
1153struct bt_plugin *bt_plugin_so_create_empty(
1154 struct bt_plugin_so_shared_lib_handle *shared_lib_handle)
1155{
1156 struct bt_plugin *plugin;
1157 struct bt_plugin_so_spec_data *spec;
1158
1159 plugin = bt_plugin_create_empty(BT_PLUGIN_TYPE_SO);
1160 if (!plugin) {
1161 goto error;
1162 }
1163
6fbd4105 1164 plugin->destroy_spec_data = bt_plugin_so_destroy_spec_data;
55bb57e0
PP
1165 plugin->spec_data = g_new0(struct bt_plugin_so_spec_data, 1);
1166 if (!plugin->spec_data) {
3fe0bf43 1167 BT_LOGE_STR("Failed to allocate one SO plugin specific data structure.");
55bb57e0
PP
1168 goto error;
1169 }
1170
1171 spec = plugin->spec_data;
398454ed
PP
1172 spec->shared_lib_handle = shared_lib_handle;
1173 bt_object_get_no_null_check(spec->shared_lib_handle);
55bb57e0
PP
1174 goto end;
1175
1176error:
65300d60 1177 BT_OBJECT_PUT_REF_AND_RESET(plugin);
55bb57e0
PP
1178
1179end:
1180 return plugin;
1181}
1182
52238017
MJ
1183static
1184size_t count_non_null_items_in_section(const void *begin, const void *end)
1185{
1186 size_t count = 0;
1187 const int * const *begin_int = (const int * const *) begin;
1188 const int * const *end_int = (const int * const *) end;
1189 const int * const *iter;
1190
1191 for (iter = begin_int; iter != end_int; iter++) {
1192 if (*iter) {
1193 count++;
1194 }
1195 }
1196
1197 return count;
1198}
1199
55bb57e0 1200static
d24d5663 1201int bt_plugin_so_create_all_from_sections(
55bb57e0 1202 struct bt_plugin_so_shared_lib_handle *shared_lib_handle,
9736d991 1203 bool fail_on_load_error,
55bb57e0
PP
1204 struct __bt_plugin_descriptor const * const *descriptors_begin,
1205 struct __bt_plugin_descriptor const * const *descriptors_end,
1206 struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
1207 struct __bt_plugin_descriptor_attribute const * const *attrs_end,
1208 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
1209 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
1210 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
9736d991
PP
1211 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end,
1212 struct bt_plugin_set **plugin_set_out)
55bb57e0 1213{
d24d5663 1214 int status = BT_FUNC_STATUS_OK;
55bb57e0
PP
1215 size_t descriptor_count;
1216 size_t attrs_count;
1217 size_t cc_descriptors_count;
1218 size_t cc_descr_attrs_count;
1219 size_t i;
55bb57e0 1220
9736d991
PP
1221 BT_ASSERT(plugin_set_out);
1222 *plugin_set_out = NULL;
52238017
MJ
1223 descriptor_count = count_non_null_items_in_section(descriptors_begin, descriptors_end);
1224 attrs_count = count_non_null_items_in_section(attrs_begin, attrs_end);
1225 cc_descriptors_count = count_non_null_items_in_section(cc_descriptors_begin, cc_descriptors_end);
1226 cc_descr_attrs_count = count_non_null_items_in_section(cc_descr_attrs_begin, cc_descr_attrs_end);
3f7d4d90 1227 BT_LOGI("Creating all SO plugins from sections: "
3fe0bf43
PP
1228 "plugin-path=\"%s\", "
1229 "descr-begin-addr=%p, descr-end-addr=%p, "
1230 "attrs-begin-addr=%p, attrs-end-addr=%p, "
1231 "cc-descr-begin-addr=%p, cc-descr-end-addr=%p, "
1232 "cc-descr-attrs-begin-addr=%p, cc-descr-attrs-end-addr=%p, "
1233 "descr-count=%zu, attrs-count=%zu, "
1234 "cc-descr-count=%zu, cc-descr-attrs-count=%zu",
1235 shared_lib_handle->path ? shared_lib_handle->path->str : NULL,
1236 descriptors_begin, descriptors_end,
1237 attrs_begin, attrs_end,
1238 cc_descriptors_begin, cc_descriptors_end,
1239 cc_descr_attrs_begin, cc_descr_attrs_end,
1240 descriptor_count, attrs_count,
1241 cc_descriptors_count, cc_descr_attrs_count);
9736d991
PP
1242 *plugin_set_out = bt_plugin_set_create();
1243 if (!*plugin_set_out) {
3fe0bf43 1244 BT_LOGE_STR("Cannot create empty plugin set.");
d24d5663 1245 status = BT_FUNC_STATUS_MEMORY_ERROR;
55bb57e0
PP
1246 goto error;
1247 }
1248
52238017 1249 for (i = 0; i < descriptors_end - descriptors_begin; i++) {
55bb57e0
PP
1250 const struct __bt_plugin_descriptor *descriptor =
1251 descriptors_begin[i];
1252 struct bt_plugin *plugin;
1253
52238017
MJ
1254 if (descriptor == NULL) {
1255 continue;
1256 }
1257
3f7d4d90 1258 BT_LOGI("Creating plugin object for plugin: "
3fe0bf43
PP
1259 "name=\"%s\", abi-major=%d, abi-minor=%d",
1260 descriptor->name, descriptor->major, descriptor->minor);
55bb57e0
PP
1261
1262 if (descriptor->major > __BT_PLUGIN_VERSION_MAJOR) {
9736d991
PP
1263 BT_LOG_WRITE(fail_on_load_error ? BT_LOG_WARN :
1264 BT_LOG_INFO, BT_LOG_TAG,
1265 "Unknown ABI major version: abi-major=%d",
1266 descriptor->major);
1267
1268 if (fail_on_load_error) {
d24d5663 1269 status = BT_FUNC_STATUS_LOADING_ERROR;
9736d991
PP
1270 goto error;
1271 } else {
1272 continue;
1273 }
55bb57e0
PP
1274 }
1275
1276 plugin = bt_plugin_so_create_empty(shared_lib_handle);
1277 if (!plugin) {
3fe0bf43 1278 BT_LOGE_STR("Cannot create empty shared library handle.");
d24d5663 1279 status = BT_FUNC_STATUS_MEMORY_ERROR;
55bb57e0
PP
1280 goto error;
1281 }
1282
1283 if (shared_lib_handle && shared_lib_handle->path) {
9736d991
PP
1284 bt_plugin_set_path(plugin,
1285 shared_lib_handle->path->str);
55bb57e0
PP
1286 }
1287
9736d991
PP
1288 status = bt_plugin_so_init(plugin, fail_on_load_error,
1289 descriptor, attrs_begin, attrs_end,
1290 cc_descriptors_begin, cc_descriptors_end,
55bb57e0 1291 cc_descr_attrs_begin, cc_descr_attrs_end);
d24d5663 1292 if (status == BT_FUNC_STATUS_OK) {
9736d991
PP
1293 /* Add to plugin set */
1294 bt_plugin_set_add_plugin(*plugin_set_out, plugin);
1295 BT_OBJECT_PUT_REF_AND_RESET(plugin);
1296 } else if (status < 0) {
50ad9320 1297 /*
9736d991
PP
1298 * bt_plugin_so_init() handles
1299 * `fail_on_load_error`, so this is a "real"
1300 * error.
50ad9320 1301 */
9736d991 1302 BT_LOGW_STR("Cannot initialize SO plugin object from sections.");
65300d60 1303 BT_OBJECT_PUT_REF_AND_RESET(plugin);
55bb57e0
PP
1304 goto error;
1305 }
1306
9736d991
PP
1307 BT_ASSERT(!plugin);
1308 }
1309
1310 BT_ASSERT(*plugin_set_out);
1311
1312 if ((*plugin_set_out)->plugins->len == 0) {
1313 BT_OBJECT_PUT_REF_AND_RESET(*plugin_set_out);
d24d5663 1314 status = BT_FUNC_STATUS_NOT_FOUND;
55bb57e0
PP
1315 }
1316
1317 goto end;
1318
1319error:
9736d991
PP
1320 BT_ASSERT(status < 0);
1321 BT_OBJECT_PUT_REF_AND_RESET(*plugin_set_out);
55bb57e0
PP
1322
1323end:
9736d991 1324 return status;
55bb57e0
PP
1325}
1326
1327BT_HIDDEN
d24d5663 1328int bt_plugin_so_create_all_from_static(bool fail_on_load_error,
9736d991 1329 struct bt_plugin_set **plugin_set_out)
55bb57e0 1330{
d24d5663 1331 int status;
9736d991 1332 struct bt_plugin_so_shared_lib_handle *shared_lib_handle = NULL;
55bb57e0 1333
9736d991
PP
1334 BT_ASSERT(plugin_set_out);
1335 *plugin_set_out = NULL;
1336 status = bt_plugin_so_shared_lib_handle_create(NULL,
1337 &shared_lib_handle);
d24d5663 1338 if (status != BT_FUNC_STATUS_OK) {
9736d991 1339 BT_ASSERT(!shared_lib_handle);
55bb57e0
PP
1340 goto end;
1341 }
1342
9736d991 1343 BT_ASSERT(shared_lib_handle);
3fe0bf43 1344 BT_LOGD_STR("Creating all SO plugins from built-in plugins.");
9736d991
PP
1345 status = bt_plugin_so_create_all_from_sections(shared_lib_handle,
1346 fail_on_load_error,
52238017
MJ
1347 __bt_get_begin_section_plugin_descriptors(),
1348 __bt_get_end_section_plugin_descriptors(),
1349 __bt_get_begin_section_plugin_descriptor_attributes(),
1350 __bt_get_end_section_plugin_descriptor_attributes(),
1351 __bt_get_begin_section_component_class_descriptors(),
1352 __bt_get_end_section_component_class_descriptors(),
1353 __bt_get_begin_section_component_class_descriptor_attributes(),
9736d991
PP
1354 __bt_get_end_section_component_class_descriptor_attributes(),
1355 plugin_set_out);
d24d5663 1356 BT_ASSERT((status == BT_FUNC_STATUS_OK && *plugin_set_out &&
9736d991 1357 (*plugin_set_out)->plugins->len > 0) || !*plugin_set_out);
55bb57e0
PP
1358
1359end:
65300d60 1360 BT_OBJECT_PUT_REF_AND_RESET(shared_lib_handle);
9736d991 1361 return status;
55bb57e0
PP
1362}
1363
1364BT_HIDDEN
d24d5663 1365int bt_plugin_so_create_all_from_file(const char *path,
9736d991 1366 bool fail_on_load_error, struct bt_plugin_set **plugin_set_out)
55bb57e0
PP
1367{
1368 size_t path_len;
d24d5663 1369 int status;
55bb57e0
PP
1370 struct __bt_plugin_descriptor const * const *descriptors_begin = NULL;
1371 struct __bt_plugin_descriptor const * const *descriptors_end = NULL;
1372 struct __bt_plugin_descriptor_attribute const * const *attrs_begin = NULL;
1373 struct __bt_plugin_descriptor_attribute const * const *attrs_end = NULL;
1374 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin = NULL;
1375 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end = NULL;
1376 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin = NULL;
1377 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end = NULL;
52238017
MJ
1378 struct __bt_plugin_descriptor const * const *(*get_begin_section_plugin_descriptors)(void);
1379 struct __bt_plugin_descriptor const * const *(*get_end_section_plugin_descriptors)(void);
1380 struct __bt_plugin_descriptor_attribute const * const *(*get_begin_section_plugin_descriptor_attributes)(void);
1381 struct __bt_plugin_descriptor_attribute const * const *(*get_end_section_plugin_descriptor_attributes)(void);
1382 struct __bt_plugin_component_class_descriptor const * const *(*get_begin_section_component_class_descriptors)(void);
1383 struct __bt_plugin_component_class_descriptor const * const *(*get_end_section_component_class_descriptors)(void);
1384 struct __bt_plugin_component_class_descriptor_attribute const * const *(*get_begin_section_component_class_descriptor_attributes)(void);
1385 struct __bt_plugin_component_class_descriptor_attribute const * const *(*get_end_section_component_class_descriptor_attributes)(void);
c55a9f58 1386 bt_bool is_libtool_wrapper = BT_FALSE, is_shared_object = BT_FALSE;
55bb57e0
PP
1387 struct bt_plugin_so_shared_lib_handle *shared_lib_handle = NULL;
1388
3f7d4d90 1389 BT_ASSERT(path);
9736d991
PP
1390 BT_ASSERT(plugin_set_out);
1391 *plugin_set_out = NULL;
55bb57e0 1392 path_len = strlen(path);
3f7d4d90
PP
1393 BT_ASSERT_PRE(path_len > PLUGIN_SUFFIX_LEN,
1394 "Path length is too short: path-length=%zu, min-length=%zu",
1395 path_len, PLUGIN_SUFFIX_LEN);
1396 BT_LOGI("Trying to create all SO plugins from file: path=\"%s\"", path);
55bb57e0 1397 path_len++;
3f7d4d90 1398
55bb57e0 1399 /*
3f7d4d90
PP
1400 * Check if the file ends with a known plugin file type suffix
1401 * (i.e. .so or .la on Linux).
55bb57e0
PP
1402 */
1403 is_libtool_wrapper = !strncmp(LIBTOOL_PLUGIN_SUFFIX,
1404 path + path_len - LIBTOOL_PLUGIN_SUFFIX_LEN,
1405 LIBTOOL_PLUGIN_SUFFIX_LEN);
1406 is_shared_object = !strncmp(NATIVE_PLUGIN_SUFFIX,
1407 path + path_len - NATIVE_PLUGIN_SUFFIX_LEN,
1408 NATIVE_PLUGIN_SUFFIX_LEN);
1409 if (!is_shared_object && !is_libtool_wrapper) {
3fe0bf43 1410 /* Name indicates this is not a plugin file; not an error */
9736d991 1411 BT_LOGI("File is not an SO plugin file: path=\"%s\"", path);
d24d5663 1412 status = BT_FUNC_STATUS_NOT_FOUND;
55bb57e0
PP
1413 goto end;
1414 }
1415
9736d991
PP
1416 status = bt_plugin_so_shared_lib_handle_create(path,
1417 &shared_lib_handle);
d24d5663 1418 if (status != BT_FUNC_STATUS_OK) {
3f7d4d90 1419 /* bt_plugin_so_shared_lib_handle_create() logs more details */
9736d991
PP
1420 BT_ASSERT(!shared_lib_handle);
1421 BT_LOGE_STR("Cannot create shared library handle.");
55bb57e0
PP
1422 goto end;
1423 }
1424
52238017
MJ
1425 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_plugin_descriptors",
1426 (gpointer *) &get_begin_section_plugin_descriptors)) {
1427 descriptors_begin = get_begin_section_plugin_descriptors();
1428 } else {
9736d991
PP
1429 /*
1430 * Use this first symbol to know whether or not this
1431 * shared object _looks like_ a Babeltrace plugin. Since
1432 * g_module_symbol() failed, assume that this is not a
1433 * Babeltrace plugin, so it's not an error.
1434 */
3f7d4d90 1435 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1436 "symbol=\"%s\"", path,
52238017 1437 "__bt_get_begin_section_plugin_descriptors");
d24d5663 1438 status = BT_FUNC_STATUS_NOT_FOUND;
55bb57e0
PP
1439 goto end;
1440 }
1441
9736d991
PP
1442 /*
1443 * If g_module_symbol() fails for any of the other symbols, fail
1444 * if `fail_on_load_error` is true.
1445 */
52238017
MJ
1446 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_plugin_descriptors",
1447 (gpointer *) &get_end_section_plugin_descriptors)) {
1448 descriptors_end = get_end_section_plugin_descriptors();
1449 } else {
9736d991
PP
1450 BT_LOG_WRITE(fail_on_load_error ? BT_LOG_WARN : BT_LOG_INFO,
1451 BT_LOG_TAG,
1452 "Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1453 "symbol=\"%s\"", path,
52238017 1454 "__bt_get_end_section_plugin_descriptors");
d24d5663
PP
1455 status = fail_on_load_error ? BT_FUNC_STATUS_LOADING_ERROR :
1456 BT_FUNC_STATUS_NOT_FOUND;
55bb57e0
PP
1457 goto end;
1458 }
1459
52238017
MJ
1460 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_plugin_descriptor_attributes",
1461 (gpointer *) &get_begin_section_plugin_descriptor_attributes)) {
1462 attrs_begin = get_begin_section_plugin_descriptor_attributes();
1463 } else {
3f7d4d90 1464 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1465 "symbol=\"%s\"", path,
52238017 1466 "__bt_get_begin_section_plugin_descriptor_attributes");
55bb57e0
PP
1467 }
1468
52238017
MJ
1469 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_plugin_descriptor_attributes",
1470 (gpointer *) &get_end_section_plugin_descriptor_attributes)) {
1471 attrs_end = get_end_section_plugin_descriptor_attributes();
1472 } else {
3f7d4d90 1473 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1474 "symbol=\"%s\"", path,
52238017 1475 "__bt_get_end_section_plugin_descriptor_attributes");
55bb57e0
PP
1476 }
1477
1478 if ((!!attrs_begin - !!attrs_end) != 0) {
9736d991
PP
1479 BT_LOG_WRITE(fail_on_load_error ? BT_LOG_WARN : BT_LOG_INFO,
1480 BT_LOG_TAG,
1481 "Found section start or end symbol, but not both: "
3fe0bf43
PP
1482 "path=\"%s\", symbol-start=\"%s\", "
1483 "symbol-end=\"%s\", symbol-start-addr=%p, "
1484 "symbol-end-addr=%p",
52238017
MJ
1485 path, "__bt_get_begin_section_plugin_descriptor_attributes",
1486 "__bt_get_end_section_plugin_descriptor_attributes",
3fe0bf43 1487 attrs_begin, attrs_end);
d24d5663
PP
1488 status = fail_on_load_error ? BT_FUNC_STATUS_LOADING_ERROR :
1489 BT_FUNC_STATUS_NOT_FOUND;
55bb57e0
PP
1490 goto end;
1491 }
1492
52238017
MJ
1493 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_component_class_descriptors",
1494 (gpointer *) &get_begin_section_component_class_descriptors)) {
1495 cc_descriptors_begin = get_begin_section_component_class_descriptors();
1496 } else {
3f7d4d90 1497 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1498 "symbol=\"%s\"", path,
52238017 1499 "__bt_get_begin_section_component_class_descriptors");
55bb57e0
PP
1500 }
1501
52238017
MJ
1502 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_component_class_descriptors",
1503 (gpointer *) &get_end_section_component_class_descriptors)) {
1504 cc_descriptors_end = get_end_section_component_class_descriptors();
1505 } else {
3f7d4d90 1506 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1507 "symbol=\"%s\"", path,
52238017 1508 "__bt_get_end_section_component_class_descriptors");
55bb57e0
PP
1509 }
1510
1511 if ((!!cc_descriptors_begin - !!cc_descriptors_end) != 0) {
9736d991
PP
1512 BT_LOG_WRITE(fail_on_load_error ? BT_LOG_WARN : BT_LOG_INFO,
1513 BT_LOG_TAG,
1514 "Found section start or end symbol, but not both: "
3fe0bf43
PP
1515 "path=\"%s\", symbol-start=\"%s\", "
1516 "symbol-end=\"%s\", symbol-start-addr=%p, "
1517 "symbol-end-addr=%p",
52238017
MJ
1518 path, "__bt_get_begin_section_component_class_descriptors",
1519 "__bt_get_end_section_component_class_descriptors",
3fe0bf43 1520 cc_descriptors_begin, cc_descriptors_end);
d24d5663
PP
1521 status = fail_on_load_error ? BT_FUNC_STATUS_LOADING_ERROR :
1522 BT_FUNC_STATUS_NOT_FOUND;
55bb57e0
PP
1523 goto end;
1524 }
1525
52238017
MJ
1526 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_component_class_descriptor_attributes",
1527 (gpointer *) &get_begin_section_component_class_descriptor_attributes)) {
1528 cc_descr_attrs_begin = get_begin_section_component_class_descriptor_attributes();
1529 } else {
3f7d4d90 1530 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1531 "symbol=\"%s\"", path,
52238017 1532 "__bt_get_begin_section_component_class_descriptor_attributes");
55bb57e0
PP
1533 }
1534
52238017
MJ
1535 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_component_class_descriptor_attributes",
1536 (gpointer *) &get_end_section_component_class_descriptor_attributes)) {
1537 cc_descr_attrs_end = get_end_section_component_class_descriptor_attributes();
1538 } else {
3f7d4d90 1539 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1540 "symbol=\"%s\"", path,
52238017 1541 "__bt_get_end_section_component_class_descriptor_attributes");
55bb57e0
PP
1542 }
1543
1544 if ((!!cc_descr_attrs_begin - !!cc_descr_attrs_end) != 0) {
9736d991
PP
1545 BT_LOG_WRITE(fail_on_load_error ? BT_LOG_WARN : BT_LOG_INFO,
1546 BT_LOG_TAG,
1547 "Found section start or end symbol, but not both: "
3fe0bf43
PP
1548 "path=\"%s\", symbol-start=\"%s\", "
1549 "symbol-end=\"%s\", symbol-start-addr=%p, "
1550 "symbol-end-addr=%p",
52238017
MJ
1551 path, "__bt_get_begin_section_component_class_descriptor_attributes",
1552 "__bt_get_end_section_component_class_descriptor_attributes",
3fe0bf43 1553 cc_descr_attrs_begin, cc_descr_attrs_end);
d24d5663
PP
1554 status = fail_on_load_error ? BT_FUNC_STATUS_LOADING_ERROR :
1555 BT_FUNC_STATUS_NOT_FOUND;
55bb57e0
PP
1556 goto end;
1557 }
1558
1559 /* Initialize plugin */
3fe0bf43 1560 BT_LOGD_STR("Initializing plugin object.");
9736d991
PP
1561 status = bt_plugin_so_create_all_from_sections(shared_lib_handle,
1562 fail_on_load_error,
55bb57e0
PP
1563 descriptors_begin, descriptors_end, attrs_begin, attrs_end,
1564 cc_descriptors_begin, cc_descriptors_end,
9736d991 1565 cc_descr_attrs_begin, cc_descr_attrs_end, plugin_set_out);
55bb57e0
PP
1566
1567end:
65300d60 1568 BT_OBJECT_PUT_REF_AND_RESET(shared_lib_handle);
9736d991 1569 return status;
55bb57e0
PP
1570}
1571
1572static
1573void plugin_comp_class_destroy_listener(struct bt_component_class *comp_class,
1574 void *data)
1575{
bfa9a4be 1576 bt_list_del(&comp_class->node);
65300d60 1577 BT_OBJECT_PUT_REF_AND_RESET(comp_class->so_handle);
3f7d4d90 1578 BT_LOGD("Component class destroyed: removed entry from list: "
3fe0bf43 1579 "comp-cls-addr=%p", comp_class);
55bb57e0
PP
1580}
1581
3230ee6b 1582void bt_plugin_so_on_add_component_class(struct bt_plugin *plugin,
55bb57e0
PP
1583 struct bt_component_class *comp_class)
1584{
55bb57e0
PP
1585 struct bt_plugin_so_spec_data *spec = plugin->spec_data;
1586
f6ccaed9
PP
1587 BT_ASSERT(plugin->spec_data);
1588 BT_ASSERT(plugin->type == BT_PLUGIN_TYPE_SO);
55bb57e0 1589
bfa9a4be 1590 bt_list_add(&comp_class->node, &component_class_list);
398454ed
PP
1591 comp_class->so_handle = spec->shared_lib_handle;
1592 bt_object_get_no_null_check(comp_class->so_handle);
55bb57e0
PP
1593
1594 /* Add our custom destroy listener */
3230ee6b 1595 bt_component_class_add_destroy_listener(comp_class,
55bb57e0 1596 plugin_comp_class_destroy_listener, NULL);
55bb57e0 1597}
This page took 0.12094 seconds and 4 git commands to generate.