File indexing completed on 2025-05-11 08:24:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039
0040 #include <errno.h>
0041 #include <inttypes.h>
0042 #include <stdlib.h>
0043 #include <stdio.h>
0044 #include <string.h>
0045
0046 #include <rtems/rtl/rtl.h>
0047 #include "rtl-error.h"
0048 #include <rtems/rtl/rtl-unresolved.h>
0049 #include <rtems/rtl/rtl-trace.h>
0050 #include "rtl-trampoline.h"
0051
0052 static rtems_rtl_unresolv_block*
0053 rtems_rtl_unresolved_block_alloc (rtems_rtl_unresolved* unresolved)
0054 {
0055
0056
0057
0058 size_t size =
0059 (sizeof(rtems_rtl_unresolv_block) +
0060 (sizeof(rtems_rtl_unresolv_rec) * unresolved->block_recs));
0061 rtems_rtl_unresolv_block* block =
0062 rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_EXTERNAL, size, true);
0063 if (block)
0064 {
0065 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0066 printf ("rtl: unresolv: block-alloc %p (%p)\n", block, block + size);
0067 rtems_chain_append (&unresolved->blocks, &block->link);
0068 }
0069 else
0070 rtems_rtl_set_error (ENOMEM, "no memory for unresolved block");
0071 return block;
0072 }
0073
0074 static size_t
0075 rtems_rtl_unresolved_symbol_rec_count (size_t length)
0076 {
0077 const size_t rec_size = sizeof(rtems_rtl_unresolv_rec);
0078 const size_t rec_name_header = offsetof(rtems_rtl_unresolv_rec, rec.name.name);
0079
0080
0081
0082 return ((length + rec_name_header - 1) / rec_size) + 1;
0083 }
0084
0085 static size_t
0086 rtems_rtl_unresolved_symbol_recs (const char* name)
0087 {
0088 return rtems_rtl_unresolved_symbol_rec_count (strlen (name) + 1);
0089 }
0090
0091 static int
0092 rtems_rtl_unresolved_rec_index (rtems_rtl_unresolv_block* block,
0093 rtems_rtl_unresolv_rec* rec)
0094 {
0095 return rec - &block->rec[0];
0096 }
0097
0098 static rtems_rtl_unresolv_rec*
0099 rtems_rtl_unresolved_rec_first (rtems_rtl_unresolv_block* block)
0100 {
0101 return &block->rec[0];
0102 }
0103
0104 static rtems_rtl_unresolv_rec*
0105 rtems_rtl_unresolved_rec_next (rtems_rtl_unresolv_rec* rec)
0106 {
0107 switch (rec->type)
0108 {
0109 case rtems_rtl_unresolved_empty:
0110 default:
0111
0112
0113
0114 rec = NULL;
0115 break;
0116
0117 case rtems_rtl_unresolved_symbol:
0118
0119
0120
0121 rec += rtems_rtl_unresolved_symbol_rec_count (rec->rec.name.length);
0122 break;
0123
0124 case rtems_rtl_unresolved_reloc:
0125 case rtems_rtl_trampoline_reloc:
0126 ++rec;
0127 break;
0128 }
0129
0130 return rec;
0131 }
0132
0133 static bool
0134 rtems_rtl_unresolved_rec_is_last (rtems_rtl_unresolv_block* block,
0135 rtems_rtl_unresolv_rec* rec)
0136 {
0137 int index = rtems_rtl_unresolved_rec_index (block, rec);
0138 return (rec == NULL ||
0139 (index < 0) ||
0140 (index >= block->recs) ||
0141 (rec->type == rtems_rtl_unresolved_empty));
0142 }
0143
0144 static rtems_rtl_unresolv_rec*
0145 rtems_rtl_unresolved_rec_first_free (rtems_rtl_unresolv_block* block)
0146 {
0147 return &block->rec[0] + block->recs;
0148 }
0149
0150
0151
0152
0153 typedef struct
0154 {
0155 const char* name;
0156 size_t length;
0157 rtems_rtl_unresolv_rec* rec;
0158 int index;
0159 int offset;
0160 } rtl_unresolved_name_data;
0161
0162 static bool
0163 rtems_rtl_unresolved_find_name_iterator (rtems_rtl_unresolv_rec* rec,
0164 void* data)
0165 {
0166 rtl_unresolved_name_data* nd = (rtl_unresolved_name_data*) data;
0167 if (rec->type == rtems_rtl_unresolved_symbol)
0168 {
0169 if ((rec->rec.name.length == nd->length)
0170 && (strcmp (rec->rec.name.name, nd->name) == 0))
0171 {
0172 ++rec->rec.name.refs;
0173 return true;
0174 }
0175 ++nd->index;
0176 }
0177 return false;
0178 }
0179
0180 static int
0181 rtems_rtl_unresolved_find_name (const char* name)
0182 {
0183 rtl_unresolved_name_data nd = {
0184 .name = name,
0185 .length = strlen (name) + 1,
0186 .rec = NULL,
0187 .index = 1,
0188 .offset = 0
0189 };
0190 if (rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_find_name_iterator,
0191 &nd))
0192 return nd.index;
0193 return -1;
0194 }
0195
0196 static bool
0197 rtems_rtl_unresolved_find_index_iterator (rtems_rtl_unresolv_rec* rec,
0198 void* data)
0199 {
0200 rtl_unresolved_name_data* nd = (rtl_unresolved_name_data*) data;
0201 if (rec == nd->rec)
0202 return true;
0203 if (rec->type == rtems_rtl_unresolved_symbol)
0204 ++nd->index;
0205 return false;
0206 }
0207
0208 static int
0209 rtems_rtl_unresolved_find_index (rtems_rtl_unresolv_rec* rec)
0210 {
0211 rtl_unresolved_name_data nd = {
0212 .name = NULL,
0213 .length = 0,
0214 .rec = rec,
0215 .index = 1,
0216 .offset = 0
0217 };
0218 if (rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_find_index_iterator,
0219 &nd))
0220 return nd.index;
0221 return -1;
0222 }
0223
0224 static bool
0225 rtems_rtl_unresolved_reindex_iterator (rtems_rtl_unresolv_rec* rec,
0226 void* data)
0227 {
0228 rtl_unresolved_name_data* nd = (rtl_unresolved_name_data*) data;
0229
0230
0231
0232 if (rec->type == rtems_rtl_unresolved_reloc)
0233 {
0234 if (rec->rec.reloc.name >= nd->index)
0235 rec->rec.reloc.name += nd->offset;
0236 }
0237 return false;
0238 }
0239
0240 static void
0241 rtems_rtl_unresolved_reindex_names (uint16_t index, int offset)
0242 {
0243 rtl_unresolved_name_data nd = {
0244 .name = NULL,
0245 .length = 0,
0246 .rec = NULL,
0247 .index = index,
0248 .offset = offset
0249 };
0250 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_reindex_iterator,
0251 &nd);
0252 }
0253
0254
0255
0256
0257 typedef struct rtems_rtl_unresolved_reloc_data
0258 {
0259 uint16_t name;
0260 rtems_rtl_unresolv_rec* name_rec;
0261 rtems_rtl_obj_sym* sym;
0262 } rtems_rtl_unresolved_reloc_data;
0263
0264 static bool
0265 rtems_rtl_unresolved_resolve_reloc (rtems_rtl_unresolv_rec* rec,
0266 void* data)
0267 {
0268 if (rec->type == rtems_rtl_unresolved_reloc)
0269 {
0270 rtems_chain_control* pending;
0271 rtems_rtl_unresolved_reloc_data* rd;
0272
0273 rd = (rtems_rtl_unresolved_reloc_data*) data;
0274
0275 if (rec->rec.reloc.name == rd->name && rec->rec.reloc.obj != NULL)
0276 {
0277 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0278 printf ("rtl: unresolv: resolve reloc: %s\n",
0279 rd->name_rec->rec.name.name);
0280
0281 if (rtems_rtl_obj_relocate_unresolved (&rec->rec.reloc, rd->sym))
0282 {
0283
0284
0285
0286
0287
0288 if (rec->rec.reloc.obj->unresolved == 0)
0289 {
0290 pending = rtems_rtl_pending_unprotected ();
0291 rtems_chain_extract (&rec->rec.reloc.obj->link);
0292 rtems_chain_append (pending, &rec->rec.reloc.obj->link);
0293 }
0294
0295
0296
0297
0298
0299
0300
0301
0302 rec->rec.reloc.obj = NULL;
0303 if (rd->name_rec != NULL && rd->name_rec->rec.name.refs > 0)
0304 --rd->name_rec->rec.name.refs;
0305 }
0306 }
0307 }
0308 return false;
0309 }
0310
0311 static bool
0312 rtems_rtl_unresolved_resolve_iterator (rtems_rtl_unresolv_rec* rec,
0313 void* data)
0314 {
0315 if (rec->type == rtems_rtl_unresolved_symbol)
0316 {
0317 rtems_rtl_unresolved_reloc_data* rd;
0318 rd = (rtems_rtl_unresolved_reloc_data*) data;
0319
0320 ++rd->name;
0321
0322 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0323 printf ("rtl: unresolv: lookup: %d: %s\n", rd->name, rec->rec.name.name);
0324
0325 rd->sym = rtems_rtl_symbol_global_find (rec->rec.name.name);
0326
0327 if (rd->sym)
0328 {
0329 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0330 printf ("rtl: unresolv: found: %s\n", rec->rec.name.name);
0331
0332 rd->name_rec = rec;
0333
0334 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_resolve_reloc, rd);
0335
0336 rd->name_rec = NULL;
0337 rd->sym = NULL;
0338 }
0339 }
0340
0341 return false;
0342 }
0343
0344
0345
0346
0347 typedef struct rtems_rtl_unresolved_archive_reloc_data
0348 {
0349 uint16_t name;
0350 rtems_rtl_archive_search result;
0351 rtems_rtl_archives* archives;
0352 } rtems_rtl_unresolved_archive_reloc_data;
0353
0354 static bool
0355 rtems_rtl_unresolved_archive_iterator (rtems_rtl_unresolv_rec* rec,
0356 void* data)
0357 {
0358 if (rec->type == rtems_rtl_unresolved_symbol)
0359 {
0360 rtems_rtl_unresolved_archive_reloc_data* ard;
0361 ard = (rtems_rtl_unresolved_archive_reloc_data*) data;
0362
0363 ++ard->name;
0364
0365 if ((rec->rec.name.flags & RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE) != 0)
0366 {
0367 rtems_rtl_archive_search result;
0368
0369 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0370 printf ("rtl: unresolv: archive lookup: %d: %s\n",
0371 ard->name, rec->rec.name.name);
0372
0373 result = rtems_rtl_archive_obj_load (ard->archives,
0374 rec->rec.name.name, true);
0375 if (result != rtems_rtl_archive_search_not_found)
0376 {
0377 rec->rec.name.flags &= ~RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE;
0378 ard->result = result;
0379 return true;
0380 }
0381 }
0382 }
0383
0384 return false;
0385 }
0386
0387 static bool
0388 rtems_rtl_unresolved_archive_search_iterator (rtems_rtl_unresolv_rec* rec,
0389 void* data)
0390 {
0391 if (rec->type == rtems_rtl_unresolved_symbol)
0392 rec->rec.name.flags |= RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE;
0393 return false;
0394 }
0395
0396 static rtems_rtl_unresolv_block*
0397 rtems_rtl_unresolved_alloc_recs (rtems_rtl_unresolved* unresolved,
0398 size_t count)
0399 {
0400 rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
0401 while (!rtems_chain_is_tail (&unresolved->blocks, node))
0402 {
0403 rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node;
0404
0405 if (block->recs + count <= unresolved->block_recs)
0406 return block;
0407 node = rtems_chain_next (node);
0408 }
0409 return NULL;
0410 }
0411
0412 static void
0413 rtems_rtl_unresolved_clean_block (rtems_rtl_unresolv_block* block,
0414 rtems_rtl_unresolv_rec* rec,
0415 size_t count,
0416 size_t recs_per_block)
0417 {
0418 size_t index = rtems_rtl_unresolved_rec_index (block, rec);
0419 size_t bytes =
0420 (block->recs - index - count) * sizeof (rtems_rtl_unresolv_rec);
0421 if (bytes)
0422 memmove (rec, rec + count, bytes);
0423 block->recs -= count;
0424 bytes = count * sizeof (rtems_rtl_unresolv_rec);
0425 memset (&block->rec[block->recs], 0, bytes);
0426 }
0427
0428 static rtems_chain_node*
0429 rtems_rtl_unresolved_delete_block_if_empty (rtems_chain_control* blocks,
0430 rtems_rtl_unresolv_block* block)
0431 {
0432 rtems_chain_node* node = &block->link;
0433 rtems_chain_node* next_node = rtems_chain_next (node);
0434
0435
0436
0437 if (block->recs == 0 && !rtems_chain_has_only_one_node (blocks))
0438 {
0439 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0440 printf ("rtl: unresolv: block-del %p\n", block);
0441 rtems_chain_extract (node);
0442 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_EXTERNAL, block);
0443 }
0444 return next_node;
0445 }
0446
0447 static void
0448 rtems_rtl_unresolved_compact (void)
0449 {
0450 rtems_rtl_unresolved* unresolved = rtems_rtl_unresolved_unprotected ();
0451 if (unresolved)
0452 {
0453
0454
0455
0456
0457 rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
0458 uint16_t index = 0;
0459 while (!rtems_chain_is_tail (&unresolved->blocks, node))
0460 {
0461 rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node;
0462 rtems_rtl_unresolv_rec* rec = rtems_rtl_unresolved_rec_first (block);
0463 while (!rtems_rtl_unresolved_rec_is_last (block, rec))
0464 {
0465 bool next_rec = true;
0466
0467 if (rec->type == rtems_rtl_unresolved_symbol)
0468 {
0469 ++index;
0470 if (rec->rec.name.refs == 0)
0471 {
0472 size_t name_recs;
0473 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0474 printf ("rtl: unresolv: remove name: %s\n", rec->rec.name.name);
0475 rtems_rtl_unresolved_reindex_names (index, -1);
0476
0477
0478
0479 name_recs = rtems_rtl_unresolved_symbol_recs (rec->rec.name.name);
0480 rtems_rtl_unresolved_clean_block (block, rec, name_recs,
0481 unresolved->block_recs);
0482 --index;
0483 next_rec = false;
0484 }
0485 }
0486 else if (rec->type == rtems_rtl_unresolved_reloc)
0487 {
0488 if (rec->rec.reloc.obj == NULL)
0489 {
0490 rtems_rtl_unresolved_clean_block (block, rec, 1,
0491 unresolved->block_recs);
0492 next_rec = false;
0493 }
0494 }
0495
0496 if (next_rec)
0497 rec = rtems_rtl_unresolved_rec_next (rec);
0498 }
0499
0500 node = rtems_rtl_unresolved_delete_block_if_empty (&unresolved->blocks,
0501 block);
0502 }
0503 }
0504 }
0505
0506 bool
0507 rtems_rtl_unresolved_table_open (rtems_rtl_unresolved* unresolved,
0508 size_t block_recs)
0509 {
0510 unresolved->marker = 0xdeadf00d;
0511 unresolved->block_recs = block_recs;
0512 rtems_chain_initialize_empty (&unresolved->blocks);
0513 return rtems_rtl_unresolved_block_alloc (unresolved);
0514 }
0515
0516 void
0517 rtems_rtl_unresolved_table_close (rtems_rtl_unresolved* unresolved)
0518 {
0519 rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
0520 while (!rtems_chain_is_tail (&unresolved->blocks, node))
0521 {
0522 rtems_chain_node* next = rtems_chain_next (node);
0523 rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_EXTERNAL, node);
0524 node = next;
0525 }
0526 }
0527
0528 bool
0529 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_iterator iterator,
0530 void* data)
0531 {
0532 rtems_rtl_unresolved* unresolved = rtems_rtl_unresolved_unprotected ();
0533 if (unresolved)
0534 {
0535 rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
0536 while (!rtems_chain_is_tail (&unresolved->blocks, node))
0537 {
0538 rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node;
0539 rtems_rtl_unresolv_rec* rec = rtems_rtl_unresolved_rec_first (block);
0540
0541 while (!rtems_rtl_unresolved_rec_is_last (block, rec))
0542 {
0543 if (iterator (rec, data))
0544 return true;
0545 rec = rtems_rtl_unresolved_rec_next (rec);
0546 }
0547
0548 node = rtems_chain_next (node);
0549 }
0550 }
0551 return false;
0552 }
0553
0554 bool
0555 rtems_rtl_unresolved_add (rtems_rtl_obj* obj,
0556 const uint16_t flags,
0557 const char* name,
0558 const uint16_t sect,
0559 const rtems_rtl_word* rel)
0560 {
0561 rtems_rtl_unresolved* unresolved;
0562 rtems_rtl_unresolv_block* block;
0563 rtems_rtl_unresolv_rec* rec;
0564 int name_index;
0565
0566 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0567 printf ("rtl: unresolv: add: %s(s:%d) -> %s\n",
0568 rtems_rtl_obj_oname (obj), sect, name);
0569
0570 unresolved = rtems_rtl_unresolved_unprotected ();
0571 if (!unresolved)
0572 return false;
0573
0574
0575
0576
0577 name_index = rtems_rtl_unresolved_find_name (name);
0578
0579
0580
0581
0582 if (name_index < 0)
0583 {
0584 size_t name_recs;
0585
0586 name_recs = rtems_rtl_unresolved_symbol_recs (name);
0587
0588
0589
0590
0591 block = rtems_rtl_unresolved_alloc_recs (unresolved, name_recs);
0592 if (block == NULL)
0593 {
0594 block = rtems_rtl_unresolved_block_alloc (unresolved);
0595 if (!block)
0596 return false;
0597 }
0598
0599
0600
0601
0602 rec = rtems_rtl_unresolved_rec_first_free (block);
0603
0604
0605
0606
0607
0608 rec->type = rtems_rtl_unresolved_symbol;
0609 rec->rec.name.refs = 1;
0610 rec->rec.name.flags = RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE;
0611 rec->rec.name.length = strlen (name) + 1;
0612 memcpy ((void*) &rec->rec.name.name[0], name, rec->rec.name.length);
0613 block->recs += name_recs;
0614
0615
0616
0617
0618
0619 name_index = rtems_rtl_unresolved_find_index (rec);
0620 if (name_index < 0)
0621 {
0622 rtems_rtl_set_error (ENOMEM, "internal unresolved block error");
0623 return false;
0624 }
0625
0626 rtems_rtl_unresolved_reindex_names (name_index, 1);
0627 }
0628
0629
0630
0631
0632 block = rtems_rtl_unresolved_alloc_recs (unresolved, 1);
0633 if (block == NULL)
0634 {
0635 block = rtems_rtl_unresolved_block_alloc (unresolved);
0636 if (!block)
0637 return false;
0638 }
0639
0640 rec = rtems_rtl_unresolved_rec_first_free (block);
0641 rec->type = rtems_rtl_unresolved_reloc;
0642 rec->rec.reloc.obj = obj;
0643 rec->rec.reloc.flags = flags;
0644 rec->rec.reloc.name = name_index;
0645 rec->rec.reloc.sect = sect;
0646 rec->rec.reloc.rel[0] = rel[0];
0647 rec->rec.reloc.rel[1] = rel[1];
0648 rec->rec.reloc.rel[2] = rel[2];
0649
0650 ++block->recs;
0651
0652 return true;
0653 }
0654
0655 void
0656 rtems_rtl_unresolved_resolve (void)
0657 {
0658 bool resolving = true;
0659
0660 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0661 printf ("rtl: unresolv: global resolve\n");
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673 while (resolving)
0674 {
0675 rtems_rtl_unresolved_reloc_data rd = {
0676 .name = 0,
0677 .name_rec = NULL,
0678 .sym = NULL
0679 };
0680 rtems_rtl_unresolved_archive_reloc_data ard = {
0681 .name = 0,
0682 .result = rtems_rtl_archive_search_not_found,
0683 .archives = rtems_rtl_archives_unprotected ()
0684 };
0685
0686 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_resolve_iterator, &rd);
0687 rtems_rtl_unresolved_compact ();
0688 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_archive_iterator, &ard);
0689
0690 resolving = ard.result == rtems_rtl_archive_search_loaded;
0691 }
0692
0693 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0694 rtems_rtl_unresolved_dump ();
0695 }
0696
0697 bool
0698 rtems_rtl_trampoline_add (rtems_rtl_obj* obj,
0699 const uint16_t flags,
0700 const uint16_t sect,
0701 const rtems_rtl_word symvalue,
0702 const rtems_rtl_word* rel)
0703 {
0704 rtems_rtl_unresolved* unresolved;
0705 rtems_rtl_unresolv_block* block;
0706 rtems_rtl_unresolv_rec* rec;
0707
0708 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
0709 printf ("rtl: tramp: add: %s sect:%d flags:%04x\n",
0710 rtems_rtl_obj_oname (obj), sect, flags);
0711
0712 unresolved = rtems_rtl_unresolved_unprotected ();
0713 if (!unresolved)
0714 return false;
0715
0716 block = rtems_rtl_unresolved_alloc_recs (unresolved, 1);
0717 if (block == NULL)
0718 {
0719 block = rtems_rtl_unresolved_block_alloc (unresolved);
0720 if (!block)
0721 return false;
0722 }
0723
0724 rec = rtems_rtl_unresolved_rec_first_free (block);
0725 rec->type = rtems_rtl_trampoline_reloc;
0726 rec->rec.tramp.obj = obj;
0727 rec->rec.tramp.flags = flags;
0728 rec->rec.tramp.sect = sect;
0729 rec->rec.tramp.symvalue = symvalue;
0730 rec->rec.tramp.rel[0] = rel[0];
0731 rec->rec.tramp.rel[1] = rel[1];
0732 rec->rec.tramp.rel[2] = rel[2];
0733
0734 ++block->recs;
0735
0736 return true;
0737 }
0738
0739 void
0740 rtems_rtl_trampoline_remove (rtems_rtl_obj* obj)
0741 {
0742 rtems_rtl_unresolved* unresolved = rtems_rtl_unresolved_unprotected ();
0743 if (unresolved)
0744 {
0745
0746
0747
0748 rtems_chain_node* node = rtems_chain_first (&unresolved->blocks);
0749 while (!rtems_chain_is_tail (&unresolved->blocks, node))
0750 {
0751 rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node;
0752 rtems_rtl_unresolv_rec* rec = rtems_rtl_unresolved_rec_first (block);
0753
0754
0755
0756
0757
0758 while (!rtems_rtl_unresolved_rec_is_last (block, rec))
0759 {
0760 bool next_rec = true;
0761
0762 if (rec->type == rtems_rtl_trampoline_reloc && rec->rec.tramp.obj == obj)
0763 {
0764 rtems_rtl_unresolved_clean_block (block, rec, 1,
0765 unresolved->block_recs);
0766 next_rec = false;
0767 }
0768
0769 if (next_rec)
0770 rec = rtems_rtl_unresolved_rec_next (rec);
0771 }
0772
0773 node = rtems_rtl_unresolved_delete_block_if_empty (&unresolved->blocks,
0774 block);
0775 }
0776 }
0777 }
0778
0779
0780
0781
0782 typedef struct rtems_rtl_unresolved_dump_data
0783 {
0784 size_t rec;
0785 size_t names;
0786 bool show_relocs;
0787 } rtems_rtl_unresolved_dump_data;
0788
0789 static bool
0790 rtems_rtl_unresolved_dump_iterator (rtems_rtl_unresolv_rec* rec,
0791 void* data)
0792 {
0793 rtems_rtl_unresolved_dump_data* dd;
0794 dd = (rtems_rtl_unresolved_dump_data*) data;
0795 switch (rec->type)
0796 {
0797 case rtems_rtl_unresolved_empty:
0798 printf (" %03zu: 0: empty\n", dd->rec);
0799 break;
0800 case rtems_rtl_unresolved_symbol:
0801 ++dd->names;
0802 printf (" %3zu: 1: name: %3zu refs:%4d: flags:%04x %s (%d)\n",
0803 dd->rec, dd->names,
0804 rec->rec.name.refs,
0805 rec->rec.name.flags,
0806 rec->rec.name.name,
0807 rec->rec.name.length);
0808 break;
0809 case rtems_rtl_unresolved_reloc:
0810 case rtems_rtl_trampoline_reloc:
0811 if (dd->show_relocs)
0812 printf (" %3zu: 2:reloc%c: obj:%s name:%2d: sect:%d\n",
0813 dd->rec,
0814 rec->type == rtems_rtl_unresolved_reloc ? 'R' : 'T',
0815 rec->rec.reloc.obj == NULL ? "resolved" : rec->rec.reloc.obj->oname,
0816 rec->rec.reloc.name,
0817 rec->rec.reloc.sect);
0818 break;
0819 default:
0820 printf (" %03zu: %d: unknown\n", dd->rec, rec->type);
0821 break;
0822 }
0823 ++dd->rec;
0824 return false;
0825 }
0826
0827 void
0828 rtems_rtl_unresolved_dump (void)
0829 {
0830 rtems_rtl_unresolved_dump_data dd = { 0 };
0831 printf ("RTL Unresolved data:\n");
0832 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_dump_iterator, &dd);
0833 }
0834
0835 void
0836 rtems_rtl_unresolved_set_archive_search (void)
0837 {
0838 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_archive_search_iterator,
0839 NULL);
0840 }