Changeset b36c5209 in rtems for cpukit/libdl/rtl-unresolved.c


Ignore:
Timestamp:
May 3, 2019, 12:15:20 AM (6 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
8bd4f61c
Parents:
be50969
Message:

libdl: Do not access the ELF file while the allocator is locked.

  • Load symbols before allocation.
  • Parse reloc records and place any reloc recs in a cache to use while the allocator is locked.
  • Relocate symbols after section allocation.
  • Split section loading into allocation/locating and loading.
  • Update all arch back-ends with a new reloc interface to control tramp handling.
  • Add -a and -t to the object list shell command.

Closes #3741

File:
1 edited

Legend:

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

    rbe50969 rb36c5209  
    2828#include <rtems/rtl/rtl-unresolved.h>
    2929#include <rtems/rtl/rtl-trace.h>
     30#include "rtl-trampoline.h"
    3031
    3132static rtems_rtl_unresolv_block*
     
    7071static int
    7172rtems_rtl_unresolved_rec_index (rtems_rtl_unresolv_block* block,
    72                                 rtems_rtl_unresolv_rec* rec)
     73                                rtems_rtl_unresolv_rec*   rec)
    7374{
    7475  return rec - &block->rec[0];
     
    102103
    103104    case rtems_rtl_unresolved_reloc:
     105    case rtems_rtl_trampoline_reloc:
    104106      ++rec;
    105107      break;
     
    402404  bytes = count * sizeof (rtems_rtl_unresolv_rec);
    403405  memset (&block->rec[block->recs], 0, bytes);
     406}
     407
     408static rtems_chain_node*
     409rtems_rtl_unresolved_delete_block_if_empty (rtems_chain_control*      blocks,
     410                                            rtems_rtl_unresolv_block* block)
     411{
     412  rtems_chain_node* node = &block->link;
     413  rtems_chain_node* next_node = rtems_chain_next (node);
     414  /*
     415   * Always leave a single block allocated. Eases possible heap fragmentation.
     416   */
     417  if (block->recs == 0 && !rtems_chain_has_only_one_node (blocks))
     418  {
     419    if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
     420      printf ("rtl: unresolv: block-del %p\n", block);
     421    rtems_chain_extract (node);
     422    rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_EXTERNAL, block);
     423  }
     424  return next_node;
    404425}
    405426
     
    457478      }
    458479
    459       if (block->recs == 0)
    460       {
    461         rtems_chain_node* next_node = rtems_chain_next (node);
    462         if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
    463           printf ("rtl: unresolv: block-del %p\n", block);
    464         rtems_chain_extract (node);
    465         rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_EXTERNAL, block);
    466         node = next_node;
    467       }
    468       else
    469       {
    470         node = rtems_chain_next (node);
    471       }
     480      node = rtems_rtl_unresolved_delete_block_if_empty (&unresolved->blocks,
     481                                                         block);
    472482    }
    473483  }
     
    481491  unresolved->block_recs = block_recs;
    482492  rtems_chain_initialize_empty (&unresolved->blocks);
    483   return true;
     493  return rtems_rtl_unresolved_block_alloc (unresolved);
    484494}
    485495
     
    633643  /*
    634644   * The resolving process is two separate stages, The first stage is to
    635    * iterate over the unresolved symbols search the global symbol table. If a
    636    * symbol is found iterate over the unresolved relocation records for the
     645   * iterate over the unresolved symbols searching the global symbol table. If
     646   * a symbol is found iterate over the unresolved relocation records for the
    637647   * symbol fixing up the relocations. The second stage is to search the
    638    * archives for symbols we have not been search before and if a symbol if
    639    * found in an archve loaded the object file. Loading an object file stops
    640    * the search of the archives for symbols and stage one is performed
    641    * again. The process repeats until no more symbols are resolved.
     648   * archives for symbols we have not searched before and if a symbol is found
     649   * in an archve load the object file. Loading an object file stops the
     650   * search of the archives for symbols and stage one is performed again. The
     651   * process repeats until no more symbols are resolved or there is an error.
    642652   */
    643653  while (resolving)
     
    666676
    667677bool
    668 rtems_rtl_unresolved_remove (rtems_rtl_obj*        obj,
    669                              const char*           name,
    670                              const uint16_t        sect,
    671                              const rtems_rtl_word* rel)
    672 {
    673   rtems_rtl_unresolved* unresolved;
     678rtems_rtl_trampoline_add (rtems_rtl_obj*        obj,
     679                          const uint16_t        flags,
     680                          const uint16_t        sect,
     681                          const rtems_rtl_word  symvalue,
     682                          const rtems_rtl_word* rel)
     683{
     684  rtems_rtl_unresolved*     unresolved;
     685  rtems_rtl_unresolv_block* block;
     686  rtems_rtl_unresolv_rec*   rec;
     687
     688  if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
     689    printf ("rtl: tramp: add: %s sect:%d flags:%04x\n",
     690            rtems_rtl_obj_oname (obj), sect, flags);
     691
    674692  unresolved = rtems_rtl_unresolved_unprotected ();
    675   if (unresolved == NULL)
     693  if (!unresolved)
    676694    return false;
     695
     696  block = rtems_rtl_unresolved_alloc_recs (unresolved, 1);
     697  if (block == NULL)
     698  {
     699    block = rtems_rtl_unresolved_block_alloc (unresolved);
     700    if (!block)
     701      return false;
     702  }
     703
     704  rec = rtems_rtl_unresolved_rec_first_free (block);
     705  rec->type = rtems_rtl_trampoline_reloc;
     706  rec->rec.tramp.obj = obj;
     707  rec->rec.tramp.flags = flags;
     708  rec->rec.tramp.sect = sect;
     709  rec->rec.tramp.symvalue = symvalue;
     710  rec->rec.tramp.rel[0] = rel[0];
     711  rec->rec.tramp.rel[1] = rel[1];
     712  rec->rec.tramp.rel[2] = rel[2];
     713
     714  ++block->recs;
     715
    677716  return true;
     717}
     718
     719void
     720rtems_rtl_trampoline_remove (rtems_rtl_obj* obj)
     721{
     722  rtems_rtl_unresolved* unresolved = rtems_rtl_unresolved_unprotected ();
     723  if (unresolved)
     724  {
     725    /*
     726     * Iterate over the blocks clearing any trampoline records.
     727     */
     728    rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
     729    while (!rtems_chain_is_tail (&unresolved->blocks, node))
     730    {
     731      rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node;
     732      rtems_rtl_unresolv_rec*   rec = rtems_rtl_unresolved_rec_first (block);
     733
     734      /*
     735       * Search the table for a trampoline record and if found clean the
     736       * record moving the remaining records down the block.
     737       */
     738      while (!rtems_rtl_unresolved_rec_is_last (block, rec))
     739      {
     740        bool next_rec = true;
     741
     742        if (rec->type == rtems_rtl_trampoline_reloc && rec->rec.tramp.obj == obj)
     743        {
     744            rtems_rtl_unresolved_clean_block (block, rec, 1,
     745                                              unresolved->block_recs);
     746            next_rec = false;
     747        }
     748
     749        if (next_rec)
     750          rec = rtems_rtl_unresolved_rec_next (rec);
     751      }
     752
     753      node = rtems_rtl_unresolved_delete_block_if_empty (&unresolved->blocks,
     754                                                         block);
     755    }
     756  }
    678757}
    679758
     
    709788    break;
    710789  case rtems_rtl_unresolved_reloc:
     790  case rtems_rtl_trampoline_reloc:
    711791    if (dd->show_relocs)
    712       printf (" %3zu: 2: reloc: obj:%s name:%2d: sect:%d\n",
     792      printf (" %3zu: 2:reloc%c: obj:%s name:%2d: sect:%d\n",
     793              rec->type == rtems_rtl_unresolved_reloc ? 'R' : 'T',
    713794              dd->rec,
    714795              rec->rec.reloc.obj == NULL ? "resolved" : rec->rec.reloc.obj->oname,
Note: See TracChangeset for help on using the changeset viewer.