Changeset 8e7c72a7 in rtems for cpukit


Ignore:
Timestamp:
Nov 20, 2018, 3:00:48 AM (9 months ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
03139d5b
Parents:
803eac9
git-author:
Chris Johns <chrisj@…> (11/20/18 03:00:48)
git-committer:
Chris Johns <chrisj@…> (11/22/18 01:43:27)
Message:

libdl: Reindex unresolved names after removing used records.

Updates #3194

Location:
cpukit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/include/rtems/rtl/rtl-unresolved.h

    r803eac9 r8e7c72a7  
    129129typedef struct rtems_rtl_unresolved
    130130{
    131   uint32_t marker;
     131  uint32_t            marker;     /**< Block marker. */
    132132  size_t              block_recs; /**< The records per blocks allocated. */
    133133  rtems_chain_control blocks;     /**< List of blocks. */
     
    206206                                  const rtems_rtl_word* rel);
    207207
     208/**
     209 * Dump the RTL unresolved data.
     210 */
     211void rtems_rtl_unresolved_dump (void);
     212
    208213#ifdef __cplusplus
    209214}
  • cpukit/libdl/rtl-unresolved.c

    r803eac9 r8e7c72a7  
    4141    rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_EXTERNAL, size, true);
    4242  if (block)
     43  {
     44    if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
     45      printf ("rtl: unresolv: block-alloc %p\n", block);
    4346    rtems_chain_append (&unresolved->blocks, &block->link);
     47  }
    4448  else
    4549    rtems_rtl_set_error (ENOMEM, "no memory for unresolved block");
     
    7175rtems_rtl_unresolved_rec_next (rtems_rtl_unresolv_rec* rec)
    7276{
    73 
    7477  switch (rec->type)
    7578  {
     
    119122                                bool                  update_refcount)
    120123{
    121   size_t length = strlen (name);
     124  size_t length = strlen (name) + 1;
    122125  int    index = 1;
    123126
     
    133136      {
    134137        if ((rec->rec.name.length == length)
    135             && (strcmp (rec->rec.name.name, name)))
     138            && (strcmp (rec->rec.name.name, name) == 0))
    136139        {
    137140          if (update_refcount)
     
    155158typedef struct rtems_rtl_unresolved_reloc_data
    156159{
    157   uint16_t                  name;     /**< Name index. */
     160  uint16_t                name;     /**< Name index. */
    158161  rtems_rtl_unresolv_rec* name_rec; /**< Name record. */
    159162  rtems_rtl_obj_sym*      sym;      /**< The symbol record. */
     
    234237  if (bytes)
    235238    memmove (rec, rec + count, bytes);
    236   --block->recs;
     239  block->recs -= count;
    237240  bytes = count * sizeof (rtems_rtl_unresolv_rec);
    238241  memset (&block->rec + block->recs, 0, bytes);
     
    246249  {
    247250    /*
    248      * Iterate backwards over the blocks removing any used records. A block is
    249      * compacted moving up the block.
     251     * Iterate over the blocks removing any empty strings. If a string is removed
     252     * update the indexes of all strings above this level.
    250253     */
    251     rtems_chain_node* node = rtems_chain_last (&unresolved->blocks);
    252     while (!rtems_chain_is_head (&unresolved->blocks, node))
    253     {
    254       rtems_chain_node*         prev = rtems_chain_previous (node);
     254    rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
     255    uint16_t          index = 0;
     256    while (!rtems_chain_is_tail (&unresolved->blocks, node))
     257    {
    255258      rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node;
    256259      rtems_rtl_unresolv_rec*   rec = rtems_rtl_unresolved_rec_first (block);
     
    258261      while (!rtems_rtl_unresolved_rec_is_last (block, rec))
    259262      {
    260         bool next = true;
    261 
     263        bool next_rec = true;
    262264        if (rec->type == rtems_rtl_unresolved_name)
    263265        {
     266          ++index;
    264267          if (rec->rec.name.refs == 0)
    265268          {
    266             size_t name_recs = rtems_rtl_unresolved_name_recs (rec->rec.name.name);
     269            /*
     270             * Iterate over the remainnig reloc records and update the index.
     271             */
     272            rtems_chain_node*       reindex_node;
     273            rtems_rtl_unresolv_rec* reindex_first;
     274            size_t                  name_recs;
     275            if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
     276              printf ("rtl: unresolv: remove name: %s\n", rec->rec.name.name);
     277            reindex_node = node;
     278            reindex_first = rtems_rtl_unresolved_rec_next (rec);
     279            while (!rtems_chain_is_tail (&unresolved->blocks, reindex_node))
     280            {
     281              rtems_rtl_unresolv_rec*   reindex_rec;
     282              rtems_rtl_unresolv_block* reindex_block;
     283              reindex_block = (rtems_rtl_unresolv_block*) reindex_node;
     284              if (reindex_first != NULL)
     285              {
     286                reindex_rec = reindex_first;
     287                reindex_first = NULL;
     288              }
     289              else
     290              {
     291                reindex_rec = rtems_rtl_unresolved_rec_first (reindex_block);
     292              }
     293              while (!rtems_rtl_unresolved_rec_is_last (reindex_block,
     294                                                        reindex_rec))
     295              {
     296                if (reindex_rec->type == rtems_rtl_unresolved_reloc)
     297                {
     298                  if (reindex_rec->rec.reloc.name >= index)
     299                    --reindex_rec->rec.reloc.name;
     300                }
     301                reindex_rec = rtems_rtl_unresolved_rec_next (reindex_rec);
     302              }
     303              reindex_node = rtems_chain_next (reindex_node);
     304            }
     305            /*
     306             * Compact the block removing the name record.
     307             */
     308            name_recs = rtems_rtl_unresolved_name_recs (rec->rec.name.name);
    267309            rtems_rtl_unresolved_clean_block (block, rec, name_recs,
    268310                                              unresolved->block_recs);
    269             next = false;
     311            --index;
     312            next_rec = false;
    270313          }
    271314        }
    272315        else if (rec->type == rtems_rtl_unresolved_reloc)
    273316        {
    274           if (!rec->rec.reloc.obj)
     317          if (rec->rec.reloc.obj == NULL)
    275318          {
    276319            rtems_rtl_unresolved_clean_block (block, rec, 1,
    277320                                              unresolved->block_recs);
    278             next = false;
     321            next_rec = false;
    279322          }
    280323        }
    281324
    282         if (next)
     325        if (next_rec)
    283326          rec = rtems_rtl_unresolved_rec_next (rec);
    284327      }
     
    286329      if (block->recs == 0)
    287330      {
     331        rtems_chain_node* next_node = rtems_chain_next (node);
     332        if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
     333          printf ("rtl: unresolv: block-del %p\n", block);
    288334        rtems_chain_extract (node);
    289         free (block);
     335        rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_EXTERNAL, block);
     336        node = next_node;
    290337      }
    291 
    292       node = prev;
     338      else
     339      {
     340        node = rtems_chain_next (node);
     341      }
    293342    }
    294343  }
     
    456505  rtems_rtl_unresolved_interate (rtems_rtl_unresolved_resolve_iterator, &rd);
    457506  rtems_rtl_unresolved_compact ();
     507  if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
     508    rtems_rtl_unresolved_dump ();
    458509}
    459510
     
    470521  return false;
    471522}
     523
     524/**
     525 * Struct to pass relocation data in the iterator.
     526 */
     527typedef struct rtems_rtl_unresolved_dump_data
     528{
     529  size_t rec;
     530  size_t names;
     531} rtems_rtl_unresolved_dump_data;
     532
     533static bool
     534rtems_rtl_unresolved_dump_iterator (rtems_rtl_unresolv_rec* rec,
     535                                    void*                   data)
     536{
     537  rtems_rtl_unresolved_dump_data* dd;
     538  dd = (rtems_rtl_unresolved_dump_data*) data;
     539  switch (rec->type)
     540  {
     541  case rtems_rtl_unresolved_empty:
     542    printf (" %03zu: 0: empty\n", dd->rec);
     543    break;
     544  case rtems_rtl_unresolved_name:
     545    ++dd->names;
     546    printf (" %3zu: 1:  name: %3d refs: %2d: %2d: %s\n",
     547            dd->rec, dd->names,
     548            rec->rec.name.refs, rec->rec.name.length, rec->rec.name.name);
     549    break;
     550  case rtems_rtl_unresolved_reloc:
     551    printf (" %3zu: 2: reloc: obj:%s name:%2d: sect:%d\n",
     552            dd->rec,
     553            rec->rec.reloc.obj->oname,
     554            rec->rec.reloc.name,
     555            rec->rec.reloc.sect);
     556    break;
     557  default:
     558    printf (" %03zu: %d: unknown\n", dd->rec, rec->type);
     559    break;
     560  }
     561  ++dd->rec;
     562  return false;
     563}
     564
     565void
     566rtems_rtl_unresolved_dump (void)
     567{
     568  rtems_rtl_unresolved_dump_data dd = { 0 };
     569  printf ("RTL Unresolved data:\n");
     570  rtems_rtl_unresolved_interate (rtems_rtl_unresolved_dump_iterator, &dd);
     571}
Note: See TracChangeset for help on using the changeset viewer.