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