summaryrefslogtreecommitdiffstats
path: root/cpukit/libdl/rtl.c
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2018-11-20 14:56:11 +1100
committerChris Johns <chrisj@rtems.org>2018-11-22 12:43:31 +1100
commit03139d5b1cf95d5b2f699e8f56e1f0ba2d7f89e4 (patch)
tree33fd489eac7497cdebe61560bc43e613b3eef0a9 /cpukit/libdl/rtl.c
parentlibdl: Reindex unresolved names after removing used records. (diff)
downloadrtems-03139d5b1cf95d5b2f699e8f56e1f0ba2d7f89e4.tar.bz2
libdl: Add object file dependencies to track references
Tracking references lets us manage when an object file can be unloaded. If an object file has references to it, it cannot be unloaded. Modules that depend on each other cannot be unloaded. Updates #3605
Diffstat (limited to 'cpukit/libdl/rtl.c')
-rw-r--r--cpukit/libdl/rtl.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/cpukit/libdl/rtl.c b/cpukit/libdl/rtl.c
index 628fc771bc..fdf4c1229f 100644
--- a/cpukit/libdl/rtl.c
+++ b/cpukit/libdl/rtl.c
@@ -216,6 +216,11 @@ rtems_rtl_data_init (void)
*/
rtl->base->oname = rtems_rtl_strdup ("rtems-kernel");
+ /*
+ * Lock the base image and flag it as the base image.
+ */
+ rtl->base->flags |= RTEMS_RTL_OBJ_LOCKED | RTEMS_RTL_OBJ_BASE;
+
rtems_chain_append (&rtl->objects, &rtl->base->link);
}
@@ -312,6 +317,21 @@ rtems_rtl_obj_decompress (rtems_rtl_obj_comp** decomp,
}
}
+void
+rtems_rtl_obj_update_flags (uint32_t clear, uint32_t set)
+{
+ rtems_chain_node* node = rtems_chain_first (&rtl->objects);
+ while (!rtems_chain_is_tail (&rtl->objects, node))
+ {
+ rtems_rtl_obj* obj = (rtems_rtl_obj*) node;
+ if (clear != 0)
+ obj->flags &= ~clear;
+ if (set != 0)
+ obj->flags |= set;
+ node = rtems_chain_next (node);
+ }
+}
+
rtems_rtl_data*
rtems_rtl_lock (void)
{
@@ -386,6 +406,21 @@ rtems_rtl_find_obj (const char* name)
}
rtems_rtl_obj*
+rtems_rtl_find_obj_with_symbol (const rtems_rtl_obj_sym* sym)
+{
+ rtems_chain_node* node = rtems_chain_first (&rtl->objects);
+ while (!rtems_chain_is_tail (&rtl->objects, node))
+ {
+ rtems_rtl_obj* obj = (rtems_rtl_obj*) node;
+ if (sym >= obj->global_table &&
+ sym < (obj->global_table + obj->global_syms))
+ return obj;
+ node = rtems_chain_next (node);
+ }
+ return NULL;
+}
+
+rtems_rtl_obj*
rtems_rtl_load_object (const char* name, int mode)
{
rtems_rtl_obj* obj;
@@ -489,6 +524,11 @@ rtems_rtl_unload_object (rtems_rtl_obj* obj)
if (obj->users == 0)
{
+ if (obj->refs != 0)
+ {
+ rtems_rtl_set_error (EBUSY, "object file referenced");
+ return false;
+ }
obj->flags |= RTEMS_RTL_OBJ_LOCKED;
rtems_rtl_unlock ();
rtems_rtl_obj_run_dtors (obj);
@@ -618,5 +658,11 @@ rtems_rtl_base_sym_global_add (const unsigned char* esyms,
rtems_rtl_obj*
rtems_rtl_baseimage (void)
{
- return NULL;
+ rtems_rtl_obj* base = NULL;
+ if (rtems_rtl_lock ())
+ {
+ base = rtl->base;
+ rtems_rtl_unlock ();
+ }
+ return base;
}