Changeset 03139d5b in rtems for cpukit/libdl/rtl-obj.c


Ignore:
Timestamp:
Nov 20, 2018, 3:56:11 AM (21 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
5, master
Children:
9dfb9a98
Parents:
8e7c72a7
git-author:
Chris Johns <chrisj@…> (11/20/18 03:56:11)
git-committer:
Chris Johns <chrisj@…> (11/22/18 01:43:31)
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libdl/rtl-obj.c

    r8e7c72a7 r03139d5b  
    8484     */
    8585    rtems_chain_initialize_empty (&obj->sections);
     86    rtems_chain_initialize_empty (&obj->dependents);
    8687    /*
    8788     * No valid format.
     
    115116  rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,
    116117                              &obj->data_base, &obj->bss_base);
     118  rtems_rtl_obj_erase_sections (obj);
     119  rtems_rtl_obj_erase_dependents (obj);
    117120  rtems_rtl_symbol_obj_erase (obj);
    118121  rtems_rtl_obj_free_names (obj);
     
    549552                           &match);
    550553  return match.sect;
     554}
     555
     556bool
     557rtems_rtl_obj_alloc_dependents (rtems_rtl_obj* obj, size_t dependents)
     558{
     559  rtems_rtl_obj_depends* depends;
     560  size_t                 size;
     561
     562  size = sizeof (rtems_rtl_obj_depends) + sizeof (rtems_rtl_obj*) * dependents;
     563
     564  depends = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
     565                                 size,
     566                                 true);
     567  if (depends == NULL)
     568  {
     569    rtems_rtl_set_error (ENOMEM, "no memory for the dependency");
     570  }
     571  else
     572  {
     573    depends->dependents = dependents;
     574    rtems_chain_append (&obj->dependents, &depends->node);
     575  }
     576
     577  return depends != NULL;
     578}
     579
     580void
     581rtems_rtl_obj_erase_dependents (rtems_rtl_obj* obj)
     582{
     583  rtems_chain_node* node = rtems_chain_first (&obj->dependents);
     584  while (!rtems_chain_is_tail (&obj->dependents, node))
     585  {
     586    rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
     587    rtems_chain_node*      next_node = rtems_chain_next (node);
     588    rtems_chain_extract (node);
     589    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, depends);
     590    node = next_node;
     591  }
     592}
     593
     594bool
     595rtems_rtl_obj_add_dependent (rtems_rtl_obj* obj, rtems_rtl_obj* dependent)
     596{
     597  rtems_rtl_obj**   free_slot;
     598  rtems_chain_node* node;
     599  if (obj == dependent || dependent == rtems_rtl_baseimage ())
     600    return false;
     601  free_slot = NULL;
     602  node = rtems_chain_first (&obj->dependents);
     603  while (!rtems_chain_is_tail (&obj->dependents, node))
     604  {
     605    rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
     606    size_t                 d;
     607    for (d = 0; d < depends->dependents; ++d)
     608    {
     609      if (free_slot == NULL && depends->depends[d] == NULL)
     610        free_slot = &(depends->depends[d]);
     611      if (depends->depends[d] == dependent)
     612        return false;
     613    }
     614    node = rtems_chain_next (node);
     615  }
     616  if (free_slot == NULL)
     617  {
     618    if (rtems_rtl_obj_alloc_dependents (obj,
     619                                        RTEMS_RTL_DEPENDENCY_BLOCK_SIZE))
     620    {
     621      rtems_rtl_obj_depends* depends;
     622      node = rtems_chain_last (&obj->dependents);
     623      depends = (rtems_rtl_obj_depends*) node;
     624      free_slot = &(depends->depends[0]);
     625      if (*free_slot != NULL)
     626      {
     627        rtems_rtl_set_error (EINVAL, "new dependency node not empty");
     628        free_slot = NULL;
     629      }
     630    }
     631  }
     632  if (free_slot != NULL)
     633    *free_slot = dependent;
     634  return free_slot != NULL;
     635}
     636
     637bool
     638rtems_rtl_obj_iterate_dependents (rtems_rtl_obj*                 obj,
     639                                  rtems_rtl_obj_depends_iterator iterator,
     640                                  void*                          data)
     641{
     642  rtems_chain_node* node = rtems_chain_first (&obj->dependents);
     643  while (!rtems_chain_is_tail (&obj->dependents, node))
     644  {
     645    rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
     646    size_t                 d;
     647    for (d = 0; d < depends->dependents; ++d)
     648    {
     649      if (depends->depends[d])
     650      {
     651        if (iterator (obj, depends->depends[d], data))
     652          return true;
     653      }
     654    }
     655    node = rtems_chain_next (node);
     656  }
     657  return false;
    551658}
    552659
     
    12211328{
    12221329  if (obj->format >= 0 && obj->format < RTEMS_RTL_LOADERS)
    1223       return loaders[obj->format].unload (obj);
     1330  {
     1331    rtems_chain_node* node;
     1332
     1333    if (!loaders[obj->format].unload (obj))
     1334      return false;
     1335
     1336    node = rtems_chain_first (&obj->dependents);
     1337    while (!rtems_chain_is_tail (&obj->dependents, node))
     1338    {
     1339      rtems_rtl_obj_depends* depends = (rtems_rtl_obj_depends*) node;
     1340      size_t                 d;
     1341      for (d = 0; d < depends->dependents; ++d)
     1342      {
     1343        if (depends->depends[d] != NULL)
     1344          rtems_rtl_obj_dec_reference (depends->depends[d]);
     1345      }
     1346      node = rtems_chain_next (node);
     1347    }
     1348  }
     1349
    12241350  return false;
     1351}
     1352
     1353void
     1354rtems_rtl_obj_inc_reference (rtems_rtl_obj* obj)
     1355{
     1356  ++obj->refs;
     1357}
     1358
     1359void
     1360rtems_rtl_obj_dec_reference (rtems_rtl_obj* obj)
     1361{
     1362  if (obj->refs)
     1363    --obj->refs;
    12251364}
    12261365
Note: See TracChangeset for help on using the changeset viewer.