Changeset 194eb403 in rtems
- Timestamp:
- 01/21/19 21:48:19 (5 years ago)
- Branches:
- 5, master
- Children:
- 6c9f017
- Parents:
- d8c70ba6
- git-author:
- Chris Johns <chrisj@…> (01/21/19 21:48:19)
- git-committer:
- Chris Johns <chrisj@…> (02/08/19 23:06:34)
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/include/rtems/rtl/rtl-obj.h
rd8c70ba6 r194eb403 93 93 #define RTEMS_RTL_OBJ_SECT_BSS (1 << 3) /**< Section holds program bss. */ 94 94 #define RTEMS_RTL_OBJ_SECT_EH (1 << 4) /**< Section holds exception data. */ 95 #define RTEMS_RTL_OBJ_SECT_REL (1 << 5) /**< Section holds relocation recs. */ 96 #define RTEMS_RTL_OBJ_SECT_RELA (1 << 6) /**< Section holds reloc addend recs. */ 97 #define RTEMS_RTL_OBJ_SECT_SYM (1 << 7) /**< Section holds symbols. */ 98 #define RTEMS_RTL_OBJ_SECT_STR (1 << 8) /**< Section holds strings. */ 99 #define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 9) /**< Section allocates runtime memory. */ 100 #define RTEMS_RTL_OBJ_SECT_LOAD (1 << 10) /**< Section is loaded from object file. */ 101 #define RTEMS_RTL_OBJ_SECT_WRITE (1 << 11) /**< Section is writable, ie data. */ 102 #define RTEMS_RTL_OBJ_SECT_EXEC (1 << 12) /**< Section is executable. */ 103 #define RTEMS_RTL_OBJ_SECT_ZERO (1 << 13) /**< Section is preset to zero. */ 104 #define RTEMS_RTL_OBJ_SECT_LINK (1 << 14) /**< Section is link-ordered. */ 105 #define RTEMS_RTL_OBJ_SECT_CTOR (1 << 15) /**< Section contains constructors. */ 106 #define RTEMS_RTL_OBJ_SECT_DTOR (1 << 16) /**< Section contains destructors. */ 107 #define RTEMS_RTL_OBJ_SECT_LOCD (1 << 17) /**< Section has been located. */ 95 #define RTEMS_RTL_OBJ_SECT_TLS (1 << 5) /**< Section holds TLS data. */ 96 #define RTEMS_RTL_OBJ_SECT_REL (1 << 6) /**< Section holds relocation recs. */ 97 #define RTEMS_RTL_OBJ_SECT_RELA (1 << 7) /**< Section holds reloc addend recs. */ 98 #define RTEMS_RTL_OBJ_SECT_SYM (1 << 8) /**< Section holds symbols. */ 99 #define RTEMS_RTL_OBJ_SECT_STR (1 << 9) /**< Section holds strings. */ 100 #define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 10 /**< Section allocates runtime memory. */ 101 #define RTEMS_RTL_OBJ_SECT_LOAD (1 << 11) /**< Section is loaded from object file. */ 102 #define RTEMS_RTL_OBJ_SECT_WRITE (1 << 12) /**< Section is writable, ie data. */ 103 #define RTEMS_RTL_OBJ_SECT_EXEC (1 << 13) /**< Section is executable. */ 104 #define RTEMS_RTL_OBJ_SECT_ZERO (1 << 14) /**< Section is preset to zero. */ 105 #define RTEMS_RTL_OBJ_SECT_LINK (1 << 15) /**< Section is link-ordered. */ 106 #define RTEMS_RTL_OBJ_SECT_CTOR (1 << 16) /**< Section contains constructors. */ 107 #define RTEMS_RTL_OBJ_SECT_DTOR (1 << 17) /**< Section contains destructors. */ 108 #define RTEMS_RTL_OBJ_SECT_LOCD (1 << 18) /**< Section has been located. */ 108 109 109 110 /** … … 114 115 RTEMS_RTL_OBJ_SECT_DATA | \ 115 116 RTEMS_RTL_OBJ_SECT_BSS | \ 117 RTEMS_RTL_OBJ_SECT_TLS | \ 116 118 RTEMS_RTL_OBJ_SECT_EH) 117 119 … … 205 207 void* const_base; /**< The base address of the const section 206 208 * in memory. */ 209 size_t const_size; /**< The size of the const section. */ 207 210 void* eh_base; /**< The base address of the eh section in 208 211 * memory. */ … … 210 213 void* data_base; /**< The base address of the data section 211 214 * in memory. */ 215 size_t data_size; /**< The size of the data section. */ 212 216 void* bss_base; /**< The base address of the bss section in 213 217 * memory. */ -
cpukit/include/rtems/rtl/rtl-trace.h
rd8c70ba6 r194eb403 50 50 #define RTEMS_RTL_TRACE_CACHE (1UL << 11) 51 51 #define RTEMS_RTL_TRACE_ARCHIVES (1UL << 12) 52 #define RTEMS_RTL_TRACE_DEPENDENCY (1UL << 13) 53 #define RTEMS_RTL_TRACE_ALL (0xffffffffUL & ~(RTEMS_RTL_TRACE_CACHE)) 52 #define RTEMS_RTL_TRACE_ARCHIVE_SYMS (1UL << 13) 53 #define RTEMS_RTL_TRACE_DEPENDENCY (1UL << 14) 54 #define RTEMS_RTL_TRACE_ALL (0xffffffffUL & ~(RTEMS_RTL_TRACE_CACHE | \ 55 RTEMS_RTL_TRACE_GLOBAL_SYM | \ 56 RTEMS_RTL_TRACE_ARCHIVE_SYMS)) 54 57 55 58 /** -
cpukit/include/rtems/rtl/rtl-unresolved.h
rd8c70ba6 r194eb403 54 54 55 55 #include <rtems.h> 56 #include <rtems/chain.h> 56 57 #include "rtl-obj-fwd.h" 57 58 … … 80 81 */ 81 82 #define RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE (1 << 0) /**< Search the archive. */ 83 #define RTEMS_RTL_UNRESOLV_SYM_HAS_ERROR (1 << 1) /**< The symbol load 84 * has an error. */ 82 85 83 86 /** … … 94 97 uint16_t flags; /**< Flags to manage the symbol. */ 95 98 uint16_t length; /**< The length of this name. */ 96 const char name[ 10];/**< The symbol name. */99 const char name[]; /**< The symbol name. */ 97 100 } rtems_rtl_unresolv_symbol; 98 101 … … 118 121 union 119 122 { 120 rtems_rtl_unresolv_symbol name; /**< The sym nbol, or */123 rtems_rtl_unresolv_symbol name; /**< The symbol, or */ 121 124 rtems_rtl_unresolv_reloc reloc; /**< the relocation record. */ 122 125 } rec; … … 128 131 typedef struct rtems_rtl_unresolv_block 129 132 { 130 rtems_chain_node link; /**< Blocks are chained. */131 uint32_t recs; /**< The number of records in the block. */132 rtems_rtl_unresolv_rec rec ;/**< The records. More follow. */133 rtems_chain_node link; /**< Blocks are chained. */ 134 uint32_t recs; /**< The number of records in the block. */ 135 rtems_rtl_unresolv_rec rec[]; /**< The records. More follow. */ 133 136 } rtems_rtl_unresolv_block; 134 137 -
cpukit/include/rtems/rtl/rtl.h
rd8c70ba6 r194eb403 139 139 140 140 /** 141 * Get the RTL last error string with out locking. This call assumes the RTL is 142 * locked. 143 * 144 * @return const char* The RTL's laste error. 145 * @retval NULL The RTL data is not initialised. 146 */ 147 const char* rtems_rtl_last_error_unprotected (void); 148 149 /** 141 150 * Get the RTL objects table with out locking. This call assumes the RTL 142 151 * is locked. -
cpukit/libdl/rtl-archive.c
rd8c70ba6 r194eb403 294 294 else 295 295 { 296 ssize_t entry = symbols->entries / 2;297 ssize_t offset = entry;298 ssize_t last_entry = -1;299 while (entry >= 0 &&300 entry < symbols->entries &&301 entry != last_entry &&302 offset > 0)303 {304 int cmp = strcmp (search->symbol, symbols->symbols[entry].label);305 if (cmp == 0)306 {307 entry = symbols->symbols[entry].entry;296 rtems_rtl_archive_symbol* match; 297 const rtems_rtl_archive_symbol key = { 298 .entry = -1, 299 .label = search->symbol 300 }; 301 match = bsearch (&key, 302 symbols->symbols, 303 symbols->entries, 304 sizeof (symbols->symbols[0]), 305 rtems_rtl_archive_symbol_compare); 306 if (match != NULL) 307 { 308 308 search->archive = archive; 309 309 search->offset = 310 rtems_rtl_archive_read_32 (symbols->base + ( entry * 4));310 rtems_rtl_archive_read_32 (symbols->base + (match->entry * 4)); 311 311 return false; 312 }313 last_entry = entry;314 if (offset == 1)315 offset = 0;316 else317 offset = ((offset - 1) / 2) + 1;318 if (cmp < 0)319 entry -= offset;320 else321 entry += offset;322 312 } 323 313 } … … 453 443 archives->config_length = 0; 454 444 archives->config = 455 rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, sb.st_size , false);445 rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT, sb.st_size + 1, true); 456 446 if (archives->config == NULL) 457 447 { … … 520 510 */ 521 511 s = (char*) archives->config; 522 for (r = 0; r < archives->config_length; ++r) 523 { 524 if (s[r] != '\0') 512 r = 0; 513 while (r < archives->config_length) 514 { 515 if (s[r] == '\0') 516 { 517 ++r; 518 } 519 else 525 520 { 526 521 size_t ls = strlen (&s[r]); … … 528 523 while (b < ls && isspace (s[r + b])) 529 524 { 525 s[r + b] = '\0'; 530 526 ++b; 531 527 } 532 if (b > 0)533 memmove (&s[r], &s[r + b], ls - b);534 528 b = ls - 1; 535 while (b > 0 && isspace (s[ r +b]))529 while (b > 0 && isspace (s[b])) 536 530 { 537 s[ r +b] = '\0';531 s[b] = '\0'; 538 532 --b; 539 533 } 540 } 541 } 542 543 /* 544 * Compact the lines so there is only a single nul separator. 545 */ 546 s = (char*) archives->config; 547 for (r = 0; r < archives->config_length; ++r) 548 { 549 if (s[r] == '\0') 550 { 551 size_t e = r + 1; 552 while (e < archives->config_length) 553 { 554 if (s[e] != '\0') 555 { 556 if (archives->config_length - e - 1 > 0) 557 memmove (&s[r + 1], &s[e], archives->config_length - e - 1); 558 break; 559 } 560 } 534 r += ls; 561 535 } 562 536 } … … 566 540 int line = 1; 567 541 printf ("rtl: archive: config:\n"); 568 s = (char*) archives->config; 569 for (r = 0; r < archives->config_length; ++r, ++line) 570 { 571 size_t len = strlen (s); 572 printf (" %3d: %s\n", line, s); 573 s += len + 2; 574 r += len; 542 r = 0; 543 while (r < archives->config_length) 544 { 545 const char* cs = &archives->config[r]; 546 size_t len = strlen (cs); 547 if (len > 0) 548 { 549 printf (" %3d: %s\n", line, cs); 550 ++line; 551 } 552 r += len + 1; 575 553 } 576 554 } … … 741 719 (archive->symbols.entries + 1) * 4, 742 720 archive->symbols.symbols); 721 722 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ARCHIVE_SYMS) && 723 archive->symbols.entries > 0) 724 { 725 size_t e; 726 printf ("rtl: archive: symbols: %s\n", archive->name ); 727 for (e = 0; e < archive->symbols.entries; ++e) 728 { 729 printf(" %6zu: %6zu %s\n", e + 1, 730 archive->symbols.symbols[e].entry, 731 archive->symbols.symbols[e].label); 732 } 733 } 743 734 } 744 735 … … 852 843 853 844 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ARCHIVES)) 854 printf ("rtl: archive: refresh: checking: %s\n", entry.d_name); 845 printf ("rtl: archive: refresh: checking: %s (pattern: %s)\n", 846 entry.d_name, basename); 855 847 856 848 if (fnmatch (basename, entry.d_name, 0) == 0) 857 849 { 858 struct stat sb; 859 if (stat (entry.d_name, &sb) == 0) 860 { 861 rtems_rtl_archive* archive; 862 archive = rtems_rtl_archive_get (archives, dirname, entry.d_name); 863 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ARCHIVES)) 864 printf ("rtl: archive: refresh: %s: %sfound\n", 865 entry.d_name, archive == NULL ? ": not " : ""); 866 } 850 rtems_rtl_archive* archive; 851 archive = rtems_rtl_archive_get (archives, dirname, entry.d_name); 852 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ARCHIVES)) 853 printf ("rtl: archive: refresh: %s: %sfound\n", 854 entry.d_name, archive == NULL ? ": not " : ""); 867 855 } 868 856 } … … 1029 1017 { 1030 1018 if (rtems_rtl_trace (RTEMS_RTL_TRACE_ARCHIVES)) 1031 printf ("rtl: archive: loading: error: %s:%s@0x%08jx\n", 1032 obj->aname, obj->oname, obj->ooffset); 1019 printf ("rtl: archive: loading: error: %s:%s@0x%08jx: %s\n", 1020 obj->aname, obj->oname, obj->ooffset, 1021 rtems_rtl_last_error_unprotected ()); 1033 1022 rtems_chain_extract (&obj->link); 1034 1023 rtems_rtl_obj_free (obj); -
cpukit/libdl/rtl-elf.c
rd8c70ba6 r194eb403 22 22 #include <errno.h> 23 23 #include <fcntl.h> 24 #include <inttypes.h> 24 25 #include <stdlib.h> 25 26 #include <string.h> … … 65 66 } 66 67 68 static const char* 69 rtems_rtl_elf_separated_section (const char* name) 70 { 71 struct { 72 const char* label; 73 size_t len; 74 } prefix[] = { 75 #define SEPARATED_PREFIX(_p) { _p, sizeof (_p) - 1 } 76 SEPARATED_PREFIX (".text."), 77 SEPARATED_PREFIX (".rel.text."), 78 SEPARATED_PREFIX (".data."), 79 SEPARATED_PREFIX (".rel.data."), 80 SEPARATED_PREFIX (".rodata."), 81 SEPARATED_PREFIX (".rel.rodata.") 82 }; 83 const size_t prefixes = sizeof (prefix) / sizeof (prefix[0]); 84 size_t p; 85 for (p = 0; p < prefixes; ++p) 86 { 87 if (strncmp (name, prefix[p].label, prefix[p].len) == 0) 88 return name + prefix[p].len; 89 } 90 return NULL; 91 } 92 67 93 static bool 68 94 rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj, … … 101 127 102 128 *value = sym->st_value + (Elf_Addr) sect->base; 129 103 130 return true; 104 131 } … … 142 169 143 170 /* 144 * Check the reloc record to see if a trampoline is needed. 145 */ 146 if (is_rela) 147 { 148 const Elf_Rela* rela = (const Elf_Rela*) relbuf; 149 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) 150 printf ("rtl: rela tramp: sym:%s(%d)=%08jx type:%d off:%08jx addend:%d\n", 151 symname, (int) ELF_R_SYM (rela->r_info), 152 (uintmax_t) symvalue, (int) ELF_R_TYPE (rela->r_info), 153 (uintmax_t) rela->r_offset, (int) rela->r_addend); 154 if (!rtems_rtl_elf_relocate_rela_tramp (obj, rela, targetsect, 155 symname, sym->st_info, symvalue)) 156 return false; 171 * The symbol has to have been resolved to parse the reloc record. Unresolved 172 * symbols are handled in the relocator but we need to count them here so a 173 * trampoline is accounted for. We have to assume the unresolved may be out of 174 * of range. 175 */ 176 if (!resolved) 177 { 178 ++rd->unresolved; 157 179 } 158 180 else 159 181 { 160 const Elf_Rel* rel = (const Elf_Rel*) relbuf;161 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))162 printf ("rtl: rel tramp: sym:%s(%d)=%08jx type:%d off:%08jx\n",163 symname, (int) ELF_R_SYM (rel->r_info),164 (uintmax_t) symvalue, (int) ELF_R_TYPE (rel->r_info),165 (uintmax_t) rel->r_offset);166 if (!rtems_rtl_elf_relocate_rel_tramp (obj, rel, targetsect,167 symname, sym->st_info, symvalue))168 return false;169 }170 171 /*172 * If the symbol has been resolved and there is a symbol name it is a global173 * symbol and from another object file so add it as a dependency.174 */175 if (!resolved)176 {177 ++rd->unresolved;178 }179 else if (symname != NULL)180 {181 182 /* 182 * Find the symbol's object file. It cannot be NULL so ignore that result 183 * if returned, it means something is corrupted. We are in an iterator. 183 * Check the reloc record to see if a trampoline is needed. 184 184 */ 185 rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol); 186 if (sobj != NULL) 185 if (is_rela) 186 { 187 const Elf_Rela* rela = (const Elf_Rela*) relbuf; 188 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) 189 printf ("rtl: rela tramp: sym:%s(%d)=%08jx type:%d off:%08jx addend:%d\n", 190 symname, (int) ELF_R_SYM (rela->r_info), 191 (uintmax_t) symvalue, (int) ELF_R_TYPE (rela->r_info), 192 (uintmax_t) rela->r_offset, (int) rela->r_addend); 193 if (!rtems_rtl_elf_relocate_rela_tramp (obj, rela, targetsect, 194 symname, sym->st_info, symvalue)) 195 return false; 196 } 197 else 198 { 199 const Elf_Rel* rel = (const Elf_Rel*) relbuf; 200 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) 201 printf ("rtl: rel tramp: sym:%s(%d)=%08jx type:%d off:%08jx\n", 202 symname, (int) ELF_R_SYM (rel->r_info), 203 (uintmax_t) symvalue, (int) ELF_R_TYPE (rel->r_info), 204 (uintmax_t) rel->r_offset); 205 if (!rtems_rtl_elf_relocate_rel_tramp (obj, rel, targetsect, 206 symname, sym->st_info, symvalue)) 207 return false; 208 } 209 210 if (symname != NULL) 187 211 { 188 212 /* 189 * A dependency is not the base kernel image or itself. Tag the object as190 * having been visited so we count it only once.213 * Find the symbol's object file. It cannot be NULL so ignore that result 214 * if returned, it means something is corrupted. We are in an iterator. 191 215 */ 192 if (sobj != rtems_rtl_baseimage () && obj != sobj &&193 (sobj->flags & RTEMS_RTL_OBJ_RELOC_TAG) == 0)216 rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol); 217 if (sobj != NULL) 194 218 { 195 sobj->flags |= RTEMS_RTL_OBJ_RELOC_TAG; 196 ++rd->dependents; 219 /* 220 * A dependency is not the base kernel image or itself. Tag the object as 221 * having been visited so we count it only once. 222 */ 223 if (sobj != rtems_rtl_baseimage () && obj != sobj && 224 (sobj->flags & RTEMS_RTL_OBJ_RELOC_TAG) == 0) 225 { 226 sobj->flags |= RTEMS_RTL_OBJ_RELOC_TAG; 227 ++rd->dependents; 228 } 197 229 } 198 230 } 199 231 } 232 200 233 return true; 201 234 } … … 314 347 return true; 315 348 349 /* 350 * The section muct has been loaded. It could be a separate section in an 351 * archive and not loaded. 352 */ 353 if ((targetsect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == 0) 354 return true; 355 356 316 357 rtems_rtl_obj_caches (&symbols, &strings, &relocs); 317 358 … … 380 421 */ 381 422 if (ELF_ST_TYPE (sym.st_info) == STT_NOTYPE || 423 ELF_ST_TYPE (sym.st_info) == STT_TLS || 382 424 sym.st_shndx == SHN_COMMON) 383 425 { … … 687 729 (int) symbol.st_size); 688 730 731 /* 732 * If a duplicate forget it. 733 */ 734 if (rtems_rtl_symbol_global_find (name)) 735 continue; 736 689 737 if ((symbol.st_shndx != 0) && 690 738 ((ELF_ST_TYPE (symbol.st_info) == STT_OBJECT) || … … 706 754 /* 707 755 * If there is a globally exported symbol already present and this 708 * symbol is not weak raise an error. If the symbol is weak and 709 * present globally ignore this symbol and use the global one and if 710 * it is not present take this symbol global or weak. We accept the 711 * first weak symbol we find and make it globally exported. 756 * symbol is not weak raise check if the object file being loaded is 757 * from an archive. If the base image is built with text sections a 758 * symbol with it's section will be linked into the base image and not 759 * another symbol. If not an archive rause an error. 760 * 761 * If the symbol is weak and present globally ignore this symbol and 762 * use the global one and if it is not present take this symbol global 763 * or weak. We accept the first weak symbol we find and make it 764 * globally exported. 712 765 */ 713 766 if (rtems_rtl_symbol_global_find (name) && 714 767 (ELF_ST_BIND (symbol.st_info) != STB_WEAK)) 715 768 { 716 rtems_rtl_set_error (ENOMEM, "duplicate global symbol: %s", name); 717 return false; 769 if (!rtems_rtl_obj_aname_valid (obj)) 770 { 771 rtems_rtl_set_error (ENOMEM, "duplicate global symbol: %s", name); 772 return false; 773 } 718 774 } 719 775 else … … 785 841 for (sym = 0; sym < (sect->size / sizeof (Elf_Sym)); ++sym) 786 842 { 787 Elf_Sym symbol; 788 off_t off; 789 const char* name; 790 size_t len; 843 Elf_Sym symbol; 844 off_t off; 845 size_t len; 791 846 792 847 off = obj->ooffset + sect->offset + (sym * sizeof (symbol)); … … 812 867 } 813 868 814 off = obj->ooffset + strtab->offset + symbol.st_name;815 len = RTEMS_RTL_ELF_STRING_MAX;816 817 if (!rtems_rtl_obj_cache_read (strings, fd, off, (void**) &name, &len))818 return false;819 820 869 if ((symbol.st_shndx != 0) && 821 870 ((ELF_ST_TYPE (symbol.st_info) == STT_OBJECT) || … … 826 875 (ELF_ST_BIND (symbol.st_info) == STB_WEAK) || 827 876 (ELF_ST_BIND (symbol.st_info) == STB_LOCAL))) 877 { 878 rtems_rtl_obj_sect* symsect; 879 rtems_rtl_obj_sym* osym; 880 char* string; 881 Elf_Word value; 882 883 symsect = rtems_rtl_obj_find_section_by_index (obj, symbol.st_shndx); 884 if (symsect) 828 885 { 829 rtems_rtl_obj_sect* symsect; 830 rtems_rtl_obj_sym* osym; 831 char* string; 832 Elf_Word value; 833 834 symsect = rtems_rtl_obj_find_section_by_index (obj, symbol.st_shndx); 835 if (symsect) 886 const char* name; 887 888 off = obj->ooffset + strtab->offset + symbol.st_name; 889 len = RTEMS_RTL_ELF_STRING_MAX; 890 891 if (!rtems_rtl_obj_cache_read (strings, fd, off, (void**) &name, &len)) 892 return false; 893 894 /* 895 * If a duplicate forget it. 896 */ 897 if (rtems_rtl_symbol_global_find (name)) 898 continue; 899 900 if ((ELF_ST_BIND (symbol.st_info) == STB_GLOBAL) || 901 (ELF_ST_BIND (symbol.st_info) == STB_WEAK)) 836 902 { 837 if ((ELF_ST_BIND (symbol.st_info) == STB_GLOBAL) || 838 (ELF_ST_BIND (symbol.st_info) == STB_WEAK)) 839 { 840 osym = gsym; 841 string = gstring; 842 gstring += strlen (name) + 1; 843 ++gsym; 844 } 845 else 846 { 847 osym = lsym; 848 string = lstring; 849 lstring += strlen (name) + 1; 850 ++lsym; 851 } 852 853 /* 854 * Allocate any common symbols in the common section. 855 */ 856 if (symbol.st_shndx == SHN_COMMON) 857 { 858 size_t value_off = rtems_rtl_obj_align (common_offset, 859 symbol.st_value); 860 common_offset = value_off + symbol.st_size; 861 value = value_off; 862 } 863 else 864 { 865 value = symbol.st_value; 866 } 867 868 rtems_chain_set_off_chain (&osym->node); 869 memcpy (string, name, strlen (name) + 1); 870 osym->name = string; 871 osym->value = value + (uint8_t*) symsect->base; 872 osym->data = symbol.st_info; 873 874 if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL)) 875 printf ("rtl: sym:add:%-2d name:%-2d:%-20s bind:%-2d " \ 876 "type:%-2d val:%8p sect:%d size:%d\n", 877 sym, (int) symbol.st_name, osym->name, 878 (int) ELF_ST_BIND (symbol.st_info), 879 (int) ELF_ST_TYPE (symbol.st_info), 880 osym->value, symbol.st_shndx, 881 (int) symbol.st_size); 903 osym = gsym; 904 string = gstring; 905 gstring += strlen (name) + 1; 906 ++gsym; 882 907 } 908 else 909 { 910 osym = lsym; 911 string = lstring; 912 lstring += strlen (name) + 1; 913 ++lsym; 914 } 915 916 /* 917 * Allocate any common symbols in the common section. 918 */ 919 if (symbol.st_shndx == SHN_COMMON) 920 { 921 size_t value_off = rtems_rtl_obj_align (common_offset, 922 symbol.st_value); 923 common_offset = value_off + symbol.st_size; 924 value = value_off; 925 } 926 else 927 { 928 value = symbol.st_value; 929 } 930 931 rtems_chain_set_off_chain (&osym->node); 932 memcpy (string, name, strlen (name) + 1); 933 osym->name = string; 934 osym->value = value + (uint8_t*) symsect->base; 935 osym->data = symbol.st_info; 936 937 if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL)) 938 printf ("rtl: sym:add:%-2d name:%-2d:%-20s bind:%-2d " \ 939 "type:%-2d val:%8p sect:%d size:%d\n", 940 sym, (int) symbol.st_name, osym->name, 941 (int) ELF_ST_BIND (symbol.st_info), 942 (int) ELF_ST_TYPE (symbol.st_info), 943 osym->value, symbol.st_shndx, 944 (int) symbol.st_size); 883 945 } 946 } 884 947 } 885 948 … … 956 1019 for (section = 0; section < ehdr->e_shnum; ++section) 957 1020 { 1021 char* name; 1022 size_t len; 958 1023 uint32_t flags; 959 1024 … … 969 1034 return false; 970 1035 1036 len = RTEMS_RTL_ELF_STRING_MAX; 1037 if (!rtems_rtl_obj_cache_read (strings, fd, 1038 sectstroff + shdr.sh_name, 1039 (void**) &name, &len)) 1040 return false; 1041 971 1042 if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL)) 972 printf ("rtl: section: %2d: type=%d flags=%08x link=%d info=%d\n",973 section, (int) shdr.sh_type, (unsigned int) shdr.sh_flags,1043 printf ("rtl: section: %2d: name=%s type=%d flags=%08x link=%d info=%d\n", 1044 section, name, (int) shdr.sh_type, (unsigned int) shdr.sh_flags, 974 1045 (int) shdr.sh_link, (int) shdr.sh_info); 975 1046 … … 1011 1082 1012 1083 case SHT_RELA: 1013 flags = RTEMS_RTL_OBJ_SECT_RELA ;1084 flags = RTEMS_RTL_OBJ_SECT_RELA | RTEMS_RTL_OBJ_SECT_LOAD; 1014 1085 break; 1015 1086 … … 1019 1090 * holds the section index the relocations apply to. 1020 1091 */ 1021 flags = RTEMS_RTL_OBJ_SECT_REL ;1092 flags = RTEMS_RTL_OBJ_SECT_REL | RTEMS_RTL_OBJ_SECT_LOAD; 1022 1093 break; 1023 1094 … … 1064 1135 if (flags != 0) 1065 1136 { 1066 char* name; 1067 size_t len; 1137 /* 1138 * If the object file is part of a library check the section's name. If it 1139 * starts with '.text.*' see if the last part is a global symbol. If a 1140 * global symbol exists we have to assume the symbol in the archive is a 1141 * duplicate can can be ignored. 1142 */ 1143 if (rtems_rtl_obj_aname_valid (obj)) 1144 { 1145 const char* symname = rtems_rtl_elf_separated_section (name); 1146 if (symname != NULL && rtems_rtl_symbol_global_find (symname)) 1147 flags &= ~RTEMS_RTL_OBJ_SECT_LOAD; 1148 } 1068 1149 1069 1150 /* … … 1075 1156 1076 1157 /* 1077 * Some architexctures supporta named PROGBIT section for INIT/FINI.1158 * Some architexctures have a named PROGBIT section for INIT/FINI. 1078 1159 */ 1079 len = RTEMS_RTL_ELF_STRING_MAX;1080 if (!rtems_rtl_obj_cache_read (strings, fd,1081 sectstroff + shdr.sh_name,1082 (void**) &name, &len))1083 return false;1084 1085 1160 if (strcmp (".ctors", name) == 0) 1086 1161 flags |= RTEMS_RTL_OBJ_SECT_CTOR; … … 1154 1229 rtems_chain_control* sections = NULL; 1155 1230 rtems_chain_node* node = NULL; 1156 size_t mask = 0;1157 1231 int sec_num = 0; 1158 1232 section_detail* sd; 1159 1233 int i = 0; 1234 size_t m; 1235 1236 /* 1237 * The section masks to add to the linkmap. 1238 */ 1239 const uint32_t sect_mask[] = { 1240 RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_LOAD, 1241 RTEMS_RTL_OBJ_SECT_CONST | RTEMS_RTL_OBJ_SECT_LOAD, 1242 RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_LOAD, 1243 RTEMS_RTL_OBJ_SECT_BSS 1244 }; 1245 const size_t sect_masks = sizeof (sect_mask) / sizeof (sect_mask[0]); 1160 1246 1161 1247 /* 1162 1248 * Caculate the size of sections' name. 1163 1249 */ 1164 1165 for (mask = RTEMS_RTL_OBJ_SECT_TEXT; 1166 mask <= RTEMS_RTL_OBJ_SECT_BSS; 1167 mask <<= 1) 1250 for (m = 0; m < sect_masks; ++m) 1168 1251 { 1169 1252 sections = &obj->sections; … … 1172 1255 { 1173 1256 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node; 1174 if ((sect->size != 0) && ((sect->flags & mask) != 0)) 1257 const uint32_t mask = sect_mask[m]; 1258 if ((sect->size != 0) && ((sect->flags & mask) == mask)) 1175 1259 { 1176 1260 ++sec_num; … … 1206 1290 node = rtems_chain_first (sections); 1207 1291 1208 for (mask = RTEMS_RTL_OBJ_SECT_TEXT; 1209 mask <= RTEMS_RTL_OBJ_SECT_BSS; 1210 mask <<= 1) 1292 for (m = 0; m < sect_masks; ++m) 1211 1293 { 1212 1294 sections = &obj->sections; … … 1215 1297 { 1216 1298 rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node; 1217 1218 if ((sect->size != 0) && ((sect->flags & mask) != 0)) 1299 const uint32_t mask = sect_mask[m]; 1300 1301 if ((sect->size != 0) && ((sect->flags & mask) == mask)) 1219 1302 { 1220 1303 sd[i].name = sect->name; 1221 1304 sd[i].size = sect->size; 1222 if ( mask == RTEMS_RTL_OBJ_SECT_TEXT)1305 if ((mask & RTEMS_RTL_OBJ_SECT_TEXT) != 0) 1223 1306 { 1224 1307 sd[i].rap_id = rap_text; 1225 1308 sd[i].offset = sect->base - obj->text_base; 1226 1309 } 1227 if ( mask == RTEMS_RTL_OBJ_SECT_CONST)1310 if ((mask & RTEMS_RTL_OBJ_SECT_CONST) != 0) 1228 1311 { 1229 1312 sd[i].rap_id = rap_const; 1230 1313 sd[i].offset = sect->base - obj->const_base; 1231 1314 } 1232 if ( mask == RTEMS_RTL_OBJ_SECT_DATA)1315 if ((mask & RTEMS_RTL_OBJ_SECT_DATA) != 0) 1233 1316 { 1234 1317 sd[i].rap_id = rap_data; 1235 1318 sd[i].offset = sect->base - obj->data_base; 1236 1319 } 1237 if ( mask == RTEMS_RTL_OBJ_SECT_BSS)1320 if ((mask & RTEMS_RTL_OBJ_SECT_BSS) != 0) 1238 1321 { 1239 1322 sd[i].rap_id = rap_bss; -
cpukit/libdl/rtl-mdreloc-arm.c
rd8c70ba6 r194eb403 21 21 #include <rtems/rtl/rtl-trace.h> 22 22 #include "rtl-unwind.h" 23 24 /* 25 * Set to 1 to allow untested relocations. If you tested one and it 26 * works or you fixed the relocation please remove the guard. 27 */ 28 #define ALLOW_UNTESTED_RELOCS 1 23 29 24 30 /* … … 342 348 if (ELF_R_TYPE(rel->r_info) == R_TYPE(THM_JUMP24)) { 343 349 tmp = (tmp + 2) & ~3; /* aligned to 4 bytes only for JUMP24 */ 350 #if !ALLOW_UNTESTED_RELOCS 344 351 printf("THM_JUMP24 to arm not supported\n"); 345 352 return false; 353 #endif 346 354 } 347 355 else { … … 441 449 break; 442 450 451 case R_TYPE(TLS_LE32): 452 #if ALLOW_UNTESTED_RELOCS 453 if (!parsing) { 454 addend = *where; 455 *where = symvalue + addend; 456 if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) 457 printf ("rtl: TLS_LE32 %p @ %p in %s\n", 458 (void *)*where, where, rtems_rtl_obj_oname (obj)); 459 } 460 break; 461 #endif 462 case R_TYPE(TLS_GD32): 463 case R_TYPE(TLS_LDM32): 464 case R_TYPE(TLS_LDO32): 465 case R_TYPE(TLS_IE32): 466 case R_TYPE(TLS_LDO12): 467 case R_TYPE(TLS_LE12): 468 case R_TYPE(TLS_IE12GP): 469 printf("TSL relocations not supported\n"); 470 443 471 default: 444 printf ("rtl: reloc unknown: sym = %" PRIu32 ", type = %" PRIu32 ", offset = %p, " 445 "contents = %p\n", 472 printf ("rtl: reloc unknown: sym = %" PRIu32 ", type = %" PRIu32 ", offset = %p", 446 473 ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info), 447 (void *)rel->r_offset, (void *)*where); 474 (void *)rel->r_offset); 475 if (!parsing) 476 printf("contents = %p", (void *)*where); 477 printf("\n"); 448 478 rtems_rtl_set_error (EINVAL, 449 479 "%s: Unsupported relocation type %" PRIu32 " " -
cpukit/libdl/rtl-mdreloc-i386.c
rd8c70ba6 r194eb403 8 8 9 9 #include <errno.h> 10 #include <inttypes.h> 10 11 #include <stdio.h> 11 12 #include <sys/types.h> … … 68 69 { 69 70 (void) obj; 70 (void) rel a;71 (void) rel; 71 72 (void) sect; 72 73 (void) symname; … … 148 149 149 150 default: 150 printf ("rtl: reloc unknown: sym = % lu, type = %lu, offset = %p, "151 printf ("rtl: reloc unknown: sym = %i, type = %" PRIu32 ", offset = %p, " 151 152 "contents = %p\n", 152 ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),153 (int) ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info), 153 154 (void *)rel->r_offset, (void *)*where); 154 155 rtems_rtl_set_error (EINVAL, 155 "%s: Unsupported relocation type % ld"156 "%s: Unsupported relocation type %" PRIu32 " " 156 157 "in non-PLT relocations", 157 158 sect->name, (uint32_t) ELF_R_TYPE(rel->r_info)); -
cpukit/libdl/rtl-obj.c
rd8c70ba6 r194eb403 159 159 } 160 160 161 static bool 162 rtems_rtl_obj_unresolved_object (rtems_chain_node* node, void* data) 163 { 164 rtems_rtl_obj* obj = (rtems_rtl_obj*) node; 165 rtems_rtl_obj_unresolved_data* ud; 166 ud = (rtems_rtl_obj_unresolved_data*) data; 167 ud->has_unresolved = (obj->flags & RTEMS_RTL_OBJ_UNRESOLVED) != 0; 168 return !ud->has_unresolved; 169 } 170 161 171 bool 162 172 rtems_rtl_obj_unresolved (rtems_rtl_obj* obj) … … 170 180 if (!ud.has_unresolved) 171 181 { 172 rtems_rtl_obj_update_flags (RTEMS_RTL_OBJ_DEP_VISITED, 0); 173 obj->flags |= RTEMS_RTL_OBJ_DEP_VISITED; 174 rtems_rtl_obj_iterate_dependents (obj, 175 rtems_rtl_obj_unresolved_dependent, 176 &ud); 177 rtems_rtl_obj_update_flags (RTEMS_RTL_OBJ_DEP_VISITED, 0); 182 if ((obj->flags & RTEMS_RTL_OBJ_BASE) != 0) 183 { 184 rtems_rtl_data* rtl = rtems_rtl_data_unprotected (); 185 rtems_rtl_chain_iterate (&rtl->objects, 186 rtems_rtl_obj_unresolved_object, 187 &ud); 188 } 189 else 190 { 191 rtems_rtl_obj_update_flags (RTEMS_RTL_OBJ_DEP_VISITED, 0); 192 obj->flags |= RTEMS_RTL_OBJ_DEP_VISITED; 193 rtems_rtl_obj_iterate_dependents (obj, 194 rtems_rtl_obj_unresolved_dependent, 195 &ud); 196 rtems_rtl_obj_update_flags (RTEMS_RTL_OBJ_DEP_VISITED, 0); 197 } 178 198 } 179 199 return ud.has_unresolved; … … 728 748 rtems_rtl_obj_text_size (const rtems_rtl_obj* obj) 729 749 { 730 return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_TEXT); 750 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_TEXT; 751 return rtems_rtl_obj_section_size (obj, flags); 731 752 } 732 753 … … 734 755 rtems_rtl_obj_text_alignment (const rtems_rtl_obj* obj) 735 756 { 736 return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_TEXT); 757 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_TEXT; 758 return rtems_rtl_obj_section_alignment (obj, flags); 737 759 } 738 760 … … 740 762 rtems_rtl_obj_const_size (const rtems_rtl_obj* obj) 741 763 { 742 return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_CONST); 764 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_CONST; 765 return rtems_rtl_obj_section_size (obj, flags); 766 } 767 768 uint32_t 769 rtems_rtl_obj_const_alignment (const rtems_rtl_obj* obj) 770 { 771 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_CONST; 772 return rtems_rtl_obj_section_alignment (obj, flags); 743 773 } 744 774 … … 746 776 rtems_rtl_obj_eh_alignment (const rtems_rtl_obj* obj) 747 777 { 748 return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_EH); 778 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_EH; 779 return rtems_rtl_obj_section_alignment (obj, flags); 749 780 } 750 781 … … 752 783 rtems_rtl_obj_eh_size (const rtems_rtl_obj* obj) 753 784 { 754 return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_EH); 755 } 756 757 uint32_t 758 rtems_rtl_obj_const_alignment (const rtems_rtl_obj* obj) 759 { 760 return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_CONST); 785 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_EH; 786 return rtems_rtl_obj_section_size (obj, flags); 761 787 } 762 788 … … 764 790 rtems_rtl_obj_data_size (const rtems_rtl_obj* obj) 765 791 { 766 return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_DATA); 792 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_DATA; 793 return rtems_rtl_obj_section_size (obj, flags); 767 794 } 768 795 … … 770 797 rtems_rtl_obj_data_alignment (const rtems_rtl_obj* obj) 771 798 { 772 return rtems_rtl_obj_section_alignment (obj, RTEMS_RTL_OBJ_SECT_DATA); 799 const uint32_t flags = RTEMS_RTL_OBJ_SECT_LOAD | RTEMS_RTL_OBJ_SECT_DATA; 800 return rtems_rtl_obj_section_alignment (obj, flags); 773 801 } 774 802 … … 791 819 void* data) 792 820 { 793 uint32_t mask = RTEMS_RTL_OBJ_SECT_REL | RTEMS_RTL_OBJ_SECT_RELA; 794 return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data); 821 const uint32_t flags = (RTEMS_RTL_OBJ_SECT_LOAD | 822 RTEMS_RTL_OBJ_SECT_REL | 823 RTEMS_RTL_OBJ_SECT_RELA); 824 return rtems_rtl_obj_section_handler (flags, obj, fd, handler, data); 795 825 } 796 826 … … 1013 1043 else 1014 1044 { 1045 /* 1046 * This section is not to be loaded, clear the base. 1047 */ 1015 1048 sect->base = 0; 1016 rtems_rtl_set_error (errno, "section has no load/clear op");1017 return false;1018 1049 } 1019 1050 1020 base_offset += sect->size; 1051 if (sect->base) 1052 base_offset += sect->size; 1021 1053 1022 1054 ++order; … … 1054 1086 * Set the sizes held in the object data. We need this for a fast reference. 1055 1087 */ 1056 obj->text_size = text_size; 1057 obj->eh_size = eh_size; 1058 obj->bss_size = bss_size; 1088 obj->text_size = text_size; 1089 obj->const_size = const_size; 1090 obj->data_size = data_size; 1091 obj->eh_size = eh_size; 1092 obj->bss_size = bss_size; 1059 1093 1060 1094 /* -
cpukit/libdl/rtl-shell.c
rd8c70ba6 r194eb403 130 130 131 131 /** 132 * Return the different between 2 void*.133 */134 static size_t135 rtems_rtl_delta_voids (void* higher, void* lower)136 {137 char* ch = higher;138 char* cl = lower;139 return ch - cl;140 }141 142 /**143 132 * Parse an argument. 144 133 */ … … 236 225 printf ("%-*cexec size : %zi\n", print->indent, ' ', obj->exec_size); 237 226 printf ("%-*ctext base : %p (%zi)\n", print->indent, ' ', 238 obj->text_base, rtems_rtl_delta_voids (obj->const_base, obj->text_base));227 obj->text_base, obj->text_size); 239 228 printf ("%-*cconst base : %p (%zi)\n", print->indent, ' ', 240 obj->const_base, rtems_rtl_delta_voids (obj->data_base, obj->const_base));229 obj->const_base, obj->const_size); 241 230 printf ("%-*cdata base : %p (%zi)\n", print->indent, ' ', 242 obj->data_base, rtems_rtl_delta_voids (obj->bss_base, obj->data_base));231 obj->data_base, obj->data_size); 243 232 printf ("%-*cbss base : %p (%zi)\n", print->indent, ' ', 244 233 obj->bss_base, obj->bss_size); -
cpukit/libdl/rtl-unresolved.c
rd8c70ba6 r194eb403 37 37 size_t size = 38 38 (sizeof(rtems_rtl_unresolv_block) + 39 (sizeof(rtems_rtl_unresolv_rec) * (unresolved->block_recs - 1)));39 (sizeof(rtems_rtl_unresolv_rec) * unresolved->block_recs)); 40 40 rtems_rtl_unresolv_block* block = 41 41 rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_EXTERNAL, size, true); … … 43 43 { 44 44 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED)) 45 printf ("rtl: unresolv: block-alloc %p \n", block);45 printf ("rtl: unresolv: block-alloc %p (%p)\n", block, block + size); 46 46 rtems_chain_append (&unresolved->blocks, &block->link); 47 47 } … … 54 54 rtems_rtl_unresolved_symbol_rec_count (size_t length) 55 55 { 56 return ((length + sizeof(rtems_rtl_unresolv_symbol) - 1) / 57 sizeof(rtems_rtl_unresolv_symbol)); 58 } 59 56 const size_t rec_size = sizeof(rtems_rtl_unresolv_rec); 57 const size_t rec_name_header = offsetof(rtems_rtl_unresolv_rec, rec.name.name); 58 /* 59 * Add on the nul and rmeove 1 to be inside a record. 60 */ 61 return ((length + rec_name_header - 1) / rec_size) + 1; 62 } 60 63 61 64 static size_t 62 65 rtems_rtl_unresolved_symbol_recs (const char* name) 63 66 { 64 return rtems_rtl_unresolved_symbol_rec_count (strlen (name) );67 return rtems_rtl_unresolved_symbol_rec_count (strlen (name) + 1); 65 68 } 66 69 … … 69 72 rtems_rtl_unresolv_rec* rec) 70 73 { 71 return (rec - &block->rec) / sizeof (rtems_rtl_unresolv_rec);74 return rec - &block->rec[0]; 72 75 } 73 76 … … 75 78 rtems_rtl_unresolved_rec_first (rtems_rtl_unresolv_block* block) 76 79 { 77 return &block->rec ;80 return &block->rec[0]; 78 81 } 79 82 … … 84 87 { 85 88 case rtems_rtl_unresolved_empty: 89 default: 86 90 /* 87 91 * Empty returns NULL. The end of the records in the block. … … 100 104 ++rec; 101 105 break; 102 103 default:104 break;105 106 } 106 107 … … 112 113 rtems_rtl_unresolv_rec* rec) 113 114 { 114 int index = (rec - &block->rec) / sizeof (rec); 115 return !rec || (index >= block->recs) || (rec->type == rtems_rtl_unresolved_empty); 115 int index = rtems_rtl_unresolved_rec_index (block, rec); 116 return (rec == NULL || 117 (index < 0) || 118 (index >= block->recs) || 119 (rec->type == rtems_rtl_unresolved_empty)); 116 120 } 117 121 … … 119 123 rtems_rtl_unresolved_rec_first_free (rtems_rtl_unresolv_block* block) 120 124 { 121 return &block->rec + block->recs; 125 return &block->rec[0] + block->recs; 126 } 127 128 /** 129 * Name management iterator data. 130 */ 131 typedef struct 132 { 133 const char* name; /**< The name being searched for. */ 134 size_t length; /**< The length of the name. */ 135 rtems_rtl_unresolv_rec* rec; /**< The record being searched for. */ 136 int index; /**< The name's index. */ 137 int offset; /**< The offset to move the index. */ 138 } rtl_unresolved_name_data; 139 140 static bool 141 rtems_rtl_unresolved_find_name_iterator (rtems_rtl_unresolv_rec* rec, 142 void* data) 143 { 144 rtl_unresolved_name_data* nd = (rtl_unresolved_name_data*) data; 145 if (rec->type == rtems_rtl_unresolved_symbol) 146 { 147 if ((rec->rec.name.length == nd->length) 148 && (strcmp (rec->rec.name.name, nd->name) == 0)) 149 { 150 ++rec->rec.name.refs; 151 return true; 152 } 153 ++nd->index; 154 } 155 return false; 122 156 } 123 157 124 158 static int 125 rtems_rtl_unresolved_find_name (rtems_rtl_unresolved* unresolved, 126 const char* name, 127 bool update_refcount) 128 { 129 size_t length = strlen (name) + 1; 130 int index = 1; 131 132 rtems_chain_node* node = rtems_chain_first (&unresolved->blocks); 133 while (!rtems_chain_is_tail (&unresolved->blocks, node)) 134 { 135 rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node; 136 rtems_rtl_unresolv_rec* rec = rtems_rtl_unresolved_rec_first (block); 137 138 while (!rtems_rtl_unresolved_rec_is_last (block, rec)) 139 { 140 if (rec->type == rtems_rtl_unresolved_symbol) 141 { 142 if ((rec->rec.name.length == length) 143 && (strcmp (rec->rec.name.name, name) == 0)) 144 { 145 if (update_refcount) 146 ++rec->rec.name.refs; 147 return index; 148 } 149 ++index; 150 } 151 rec = rtems_rtl_unresolved_rec_next (rec); 152 } 153 154 node = rtems_chain_next (node); 155 } 156 157 return 0 - index; 159 rtems_rtl_unresolved_find_name (const char* name) 160 { 161 rtl_unresolved_name_data nd = { 162 .name = name, 163 .length = strlen (name) + 1, 164 .rec = NULL, 165 .index = 1, 166 .offset = 0 167 }; 168 if (rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_find_name_iterator, 169 &nd)) 170 return nd.index; 171 return -1; 172 } 173 174 static bool 175 rtems_rtl_unresolved_find_index_iterator (rtems_rtl_unresolv_rec* rec, 176 void* data) 177 { 178 rtl_unresolved_name_data* nd = (rtl_unresolved_name_data*) data; 179 if (rec == nd->rec) 180 return true; 181 if (rec->type == rtems_rtl_unresolved_symbol) 182 ++nd->index; 183 return false; 184 } 185 186 static int 187 rtems_rtl_unresolved_find_index (rtems_rtl_unresolv_rec* rec) 188 { 189 rtl_unresolved_name_data nd = { 190 .name = NULL, 191 .length = 0, 192 .rec = rec, 193 .index = 1, 194 .offset = 0 195 }; 196 if (rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_find_index_iterator, 197 &nd)) 198 return nd.index; 199 return -1; 200 } 201 202 static bool 203 rtems_rtl_unresolved_reindex_iterator (rtems_rtl_unresolv_rec* rec, 204 void* data) 205 { 206 rtl_unresolved_name_data* nd = (rtl_unresolved_name_data*) data; 207 /* 208 * Reindexing only effects the reloc records. 209 */ 210 if (rec->type == rtems_rtl_unresolved_reloc) 211 { 212 if (rec->rec.reloc.name >= nd->index) 213 rec->rec.reloc.name += nd->offset; 214 } 215 return false; 216 } 217 218 static void 219 rtems_rtl_unresolved_reindex_names (uint16_t index, int offset) 220 { 221 rtl_unresolved_name_data nd = { 222 .name = NULL, 223 .length = 0, 224 .rec = NULL, 225 .index = index, 226 .offset = offset 227 }; 228 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_reindex_iterator, 229 &nd); 158 230 } 159 231 … … 185 257 rd->name_rec->rec.name.name); 186 258 187 rtems_rtl_obj_relocate_unresolved (&rec->rec.reloc, rd->sym); 188 189 /* 190 * If all unresolved externals are resolved add the obj module 191 * to the pending queue. This will flush the object module's 192 * data from the cache and call it's constructors. 193 */ 194 if (rec->rec.reloc.obj->unresolved == 0) 259 if (rtems_rtl_obj_relocate_unresolved (&rec->rec.reloc, rd->sym)) 195 260 { 196 pending = rtems_rtl_pending_unprotected (); 197 rtems_chain_extract (&rec->rec.reloc.obj->link); 198 rtems_chain_append (pending, &rec->rec.reloc.obj->link); 261 /* 262 * If all unresolved externals are resolved add the obj module 263 * to the pending queue. This will flush the object module's 264 * data from the cache and call it's constructors. 265 */ 266 if (rec->rec.reloc.obj->unresolved == 0) 267 { 268 pending = rtems_rtl_pending_unprotected (); 269 rtems_chain_extract (&rec->rec.reloc.obj->link); 270 rtems_chain_append (pending, &rec->rec.reloc.obj->link); 271 } 272 273 /* 274 * Set the object pointer to NULL to indicate the record is 275 * not used anymore. Update the reference count of the name so 276 * it can garbage collected if not referenced. The sweep after 277 * relocating will remove the reloc records with obj set to 278 * NULL and names with a reference count of 0. 279 */ 280 rec->rec.reloc.obj = NULL; 281 if (rd->name_rec != NULL && rd->name_rec->rec.name.refs > 0) 282 --rd->name_rec->rec.name.refs; 199 283 } 200 201 /*202 * Check Set the object pointer to NULL to indicate the record is not used203 * anymore. Update the reference count of the name. The sweep after204 * relocating will remove the reloc records with obj set to NULL and205 * names with a reference count of 0.206 */207 rec->rec.reloc.obj = NULL;208 if (rd->name_rec != NULL && rd->name_rec->rec.name.refs > 0)209 --rd->name_rec->rec.name.refs;210 284 } 211 285 } … … 251 325 typedef struct rtems_rtl_unresolved_archive_reloc_data 252 326 { 253 uint16_t name; /**< Name index. */254 bool loaded; /**< Object file loaded. */255 rtems_rtl_archives* archives; /**< The archives to search. */327 uint16_t name; /**< Name index. */ 328 rtems_rtl_archive_search result; /**< The result of the load. */ 329 rtems_rtl_archives* archives; /**< The archives to search. */ 256 330 } rtems_rtl_unresolved_archive_reloc_data; 257 331 … … 269 343 if ((rec->rec.name.flags & RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE) != 0) 270 344 { 271 rtems_rtl_archive_search load;345 rtems_rtl_archive_search result; 272 346 273 347 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED)) … … 275 349 ard->name, rec->rec.name.name); 276 350 277 load= rtems_rtl_archive_obj_load (ard->archives,278 rec->rec.name.name, true);279 if ( load == rtems_rtl_archive_search_loaded)351 result = rtems_rtl_archive_obj_load (ard->archives, 352 rec->rec.name.name, true); 353 if (result != rtems_rtl_archive_search_not_found) 280 354 { 281 ard->loaded = true; 355 rec->rec.name.flags &= ~RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE; 356 ard->result = result; 282 357 return true; 283 358 } … … 293 368 { 294 369 if (rec->type == rtems_rtl_unresolved_symbol) 295 rec->rec.name.flags = RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE; 296 return false; 370 rec->rec.name.flags |= RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE; 371 return false; 372 } 373 374 static rtems_rtl_unresolv_block* 375 rtems_rtl_unresolved_alloc_recs (rtems_rtl_unresolved* unresolved, 376 size_t count) 377 { 378 rtems_chain_node* node = rtems_chain_first (&unresolved->blocks); 379 while (!rtems_chain_is_tail (&unresolved->blocks, node)) 380 { 381 rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node; 382 383 if (block->recs + count <= unresolved->block_recs) 384 return block; 385 node = rtems_chain_next (node); 386 } 387 return NULL; 297 388 } 298 389 … … 310 401 block->recs -= count; 311 402 bytes = count * sizeof (rtems_rtl_unresolv_rec); 312 memset (&block->rec + block->recs, 0, bytes);403 memset (&block->rec[block->recs], 0, bytes); 313 404 } 314 405 … … 329 420 rtems_rtl_unresolv_block* block = (rtems_rtl_unresolv_block*) node; 330 421 rtems_rtl_unresolv_rec* rec = rtems_rtl_unresolved_rec_first (block); 331 332 422 while (!rtems_rtl_unresolved_rec_is_last (block, rec)) 333 423 { 334 424 bool next_rec = true; 425 335 426 if (rec->type == rtems_rtl_unresolved_symbol) 336 427 { … … 338 429 if (rec->rec.name.refs == 0) 339 430 { 340 /* 341 * Iterate over the remaining reloc records and update the index. 342 */ 343 rtems_chain_node* reindex_node; 344 rtems_rtl_unresolv_rec* reindex_first; 345 size_t name_recs; 431 size_t name_recs; 346 432 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED)) 347 433 printf ("rtl: unresolv: remove name: %s\n", rec->rec.name.name); 348 reindex_node = node; 349 reindex_first = rtems_rtl_unresolved_rec_next (rec); 350 while (!rtems_chain_is_tail (&unresolved->blocks, reindex_node)) 351 { 352 rtems_rtl_unresolv_rec* reindex_rec; 353 rtems_rtl_unresolv_block* reindex_block; 354 reindex_block = (rtems_rtl_unresolv_block*) reindex_node; 355 if (reindex_first != NULL) 356 { 357 reindex_rec = reindex_first; 358 reindex_first = NULL; 359 } 360 else 361 { 362 reindex_rec = rtems_rtl_unresolved_rec_first (reindex_block); 363 } 364 while (!rtems_rtl_unresolved_rec_is_last (reindex_block, 365 reindex_rec)) 366 { 367 if (reindex_rec->type == rtems_rtl_unresolved_reloc) 368 { 369 if (reindex_rec->rec.reloc.name >= index) 370 --reindex_rec->rec.reloc.name; 371 } 372 reindex_rec = rtems_rtl_unresolved_rec_next (reindex_rec); 373 } 374 reindex_node = rtems_chain_next (reindex_node); 375 } 434 rtems_rtl_unresolved_reindex_names (index, -1); 376 435 /* 377 436 * Compact the block removing the name record. … … 471 530 { 472 531 rtems_rtl_unresolved* unresolved; 473 rtems_chain_node* node;474 532 rtems_rtl_unresolv_block* block; 475 533 rtems_rtl_unresolv_rec* rec; 476 534 int name_index; 477 size_t name_recs;478 535 479 536 if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED)) … … 486 543 487 544 /* 488 * Find the first block with a spare record.545 * Is the name present? 489 546 */ 490 node = rtems_chain_first (&unresolved->blocks); 491 block = NULL; 492 while (!rtems_chain_is_tail (&unresolved->blocks, node)) 493 { 494 block = (rtems_rtl_unresolv_block*) node; 495 if (block->recs < unresolved->block_recs) 496 break; 497 block = NULL; 498 node = rtems_chain_next (node); 499 } 547 name_index = rtems_rtl_unresolved_find_name (name); 500 548 501 549 /* 502 * No blocks with any spare records, allocate a new block. 503 */ 504 if (!block) 505 { 506 block = rtems_rtl_unresolved_block_alloc (unresolved); 507 if (!block) 508 return false; 509 } 510 511 name_index = rtems_rtl_unresolved_find_name (unresolved, name, true); 512 name_recs = rtems_rtl_unresolved_symbol_recs (name); 513 514 /* 515 * An index less than 0 means the name is present and "0 - index" is the next 516 * index to use. 550 * An index less than 0 means the name was not found. 517 551 */ 518 552 if (name_index < 0) 519 553 { 520 rtems_rtl_unresolv_block* name_block = block; 554 size_t name_recs; 555 556 name_recs = rtems_rtl_unresolved_symbol_recs (name); 521 557 522 558 /* 523 559 * Is there enough room to fit the name ? It not add a new block. 524 560 */ 525 if (name_recs > (unresolved->block_recs - block->recs)) 526 { 527 name_block = rtems_rtl_unresolved_block_alloc (unresolved); 528 if (!name_block) 529 return false; 530 } 531 532 rec = rtems_rtl_unresolved_rec_first_free (name_block); 533 rec->type = rtems_rtl_unresolved_symbol; 534 rec->rec.name.refs = 1; 535 rec->rec.name.flags = RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE; 536 rec->rec.name.length = strlen (name) + 1; 537 memcpy ((void*) &rec->rec.name.name[0], name, rec->rec.name.length + 1); 538 block->recs += name_recs; 539 name_index = 0 - name_index; 540 541 /* 542 * If the name block is the reloc block and it is full allocate a new 543 * block for the relocation record. 544 */ 545 if ((block == name_block) && (block->recs >= unresolved->block_recs)) 561 block = rtems_rtl_unresolved_alloc_recs (unresolved, name_recs); 562 if (block == NULL) 546 563 { 547 564 block = rtems_rtl_unresolved_block_alloc (unresolved); … … 549 566 return false; 550 567 } 568 569 /* 570 * Find the record in the block. 571 */ 572 rec = rtems_rtl_unresolved_rec_first_free (block); 573 574 /* 575 * Enter the new record before reindexing so the iterator can see 576 * it and the iterator is called. 577 */ 578 rec->type = rtems_rtl_unresolved_symbol; 579 rec->rec.name.refs = 1; 580 rec->rec.name.flags = RTEMS_RTL_UNRESOLV_SYM_SEARCH_ARCHIVE; 581 rec->rec.name.length = strlen (name) + 1; 582 memcpy ((void*) &rec->rec.name.name[0], name, rec->rec.name.length); 583 block->recs += name_recs; 584 585 /* 586 * Find the name index for the name and then reindex the names which 587 * are moved up because of the insertion. 588 */ 589 name_index = rtems_rtl_unresolved_find_index (rec); 590 if (name_index < 0) 591 { 592 rtems_rtl_set_error (ENOMEM, "internal unresolved block error"); 593 return false; 594 } 595 596 rtems_rtl_unresolved_reindex_names (name_index, 1); 597 } 598 599 /* 600 * Find the first block with a spare record. 601 */ 602 block = rtems_rtl_unresolved_alloc_recs (unresolved, 1); 603 if (block == NULL) 604 { 605 block = rtems_rtl_unresolved_block_alloc (unresolved); 606 if (!block) 607 return false; 551 608 } 552 609 … … 593 650 rtems_rtl_unresolved_archive_reloc_data ard = { 594 651 .name = 0, 595 . loaded = false,652 .result = rtems_rtl_archive_search_not_found, 596 653 .archives = rtems_rtl_archives_unprotected () 597 654 }; … … 601 658 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_archive_iterator, &ard); 602 659 603 resolving = ard. loaded;660 resolving = ard.result == rtems_rtl_archive_search_loaded; 604 661 } 605 662 … … 628 685 size_t rec; 629 686 size_t names; 687 bool show_relocs; 630 688 } rtems_rtl_unresolved_dump_data; 631 689 … … 643 701 case rtems_rtl_unresolved_symbol: 644 702 ++dd->names; 645 printf (" %3zu: 1: name: %3d refs: %2d: %2d: %s\n",703 printf (" %3zu: 1: name: %3d refs:%4d: flags:%04x %s (%d)\n", 646 704 dd->rec, dd->names, 647 rec->rec.name.refs, rec->rec.name.length, rec->rec.name.name); 705 rec->rec.name.refs, 706 rec->rec.name.flags, 707 rec->rec.name.name, 708 rec->rec.name.length); 648 709 break; 649 710 case rtems_rtl_unresolved_reloc: 650 printf (" %3zu: 2: reloc: obj:%s name:%2d: sect:%d\n", 651 dd->rec, 652 rec->rec.reloc.obj->oname, 653 rec->rec.reloc.name, 654 rec->rec.reloc.sect); 711 if (dd->show_relocs) 712 printf (" %3zu: 2: reloc: obj:%s name:%2d: sect:%d\n", 713 dd->rec, 714 rec->rec.reloc.obj == NULL ? "resolved" : rec->rec.reloc.obj->oname, 715 rec->rec.reloc.name, 716 rec->rec.reloc.sect); 655 717 break; 656 718 default: … … 663 725 664 726 void 665 rtems_rtl_unresolved_set_archive_search (void)666 {667 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_archive_search_iterator,668 NULL);669 }670 671 void672 727 rtems_rtl_unresolved_dump (void) 673 728 { … … 676 731 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_dump_iterator, &dd); 677 732 } 733 734 void 735 rtems_rtl_unresolved_set_archive_search (void) 736 { 737 rtems_rtl_unresolved_iterate (rtems_rtl_unresolved_archive_search_iterator, 738 NULL); 739 } -
cpukit/libdl/rtl.c
rd8c70ba6 r194eb403 145 145 * Open the archives. 146 146 */ 147 rtems_rtl_archives_open (&rtl->archives, "/etc/ rtl-libs.conf");147 rtems_rtl_archives_open (&rtl->archives, "/etc/libdl.conf"); 148 148 149 149 /* … … 264 264 } 265 265 return &rtl->globals; 266 } 267 268 const char* 269 rtems_rtl_last_error_unprotected (void) 270 { 271 if (!rtl) 272 return NULL; 273 return rtl->last_error; 266 274 } 267 275 -
testsuites/libtests/Makefile.am
rd8c70ba6 r194eb403 577 577 dl08-o6-123456789-123456789.o: dl08/dl-o6-123456789-123456789.c Makefile 578 578 $(AM_V_CC)$(COMPILE) -c -o $@ $< 579 # echo "#" > etc/rtl-libs.conf 580 # echo " # blah blah" >> etc/rtl-libs.conf 581 etc/rtl-libs.conf: 579 etc/libdl.conf: 582 580 mkdir etc; \ 583 echo "/libdl08*.a" >> etc/rtl-libs.conf 581 echo "#" > etc/libdl.conf 582 echo " # blah blah" >> etc/libdl.conf 583 echo "/libdl08*.a" >> etc/libdl.conf 584 echo "" >> etc/libdl.conf 585 echo "x" >> etc/libdl.conf 586 echo "" >> etc/libdl.conf 584 587 noinst_LIBRARIES = libdl08_1.a libdl08_2.a 585 588 libdl08_1_a_SOURCES = dl08-o2.c dl08-o4.c 586 589 libdl08_2_a_SOURCES = dl08-o3.c dl08-o5.c \ 587 590 dl08-o6-123456789-123456789.c 588 dl08.tar: etc/ rtl-libs.conf dl08-o1.o libdl08_1.a libdl08_2.a591 dl08.tar: etc/libdl.conf dl08-o1.o libdl08_1.a libdl08_2.a 589 592 @rm -f $@ 590 593 $(AM_V_GEN)$(PAX) -w -f $@ $+ … … 602 605 CLEANFILES += dl08.pre dl08-sym.o libdl08_1.a libdl08_2.a dl08-o1.o dl08-o2.o \ 603 606 dl08-o3.o dl08-o4.o dl08-o5.o dl08-o6-123456789-123456789.o \ 604 dl08.tar dl08-tar.h etc/ rtl-libs.conf607 dl08.tar dl08-tar.h etc/libdl.conf 605 608 endif 606 609 endif -
testsuites/libtests/dl08/dl-load.c
rd8c70ba6 r194eb403 16 16 RTEMS_RTL_TRACE_SYMBOL | \ 17 17 RTEMS_RTL_TRACE_RELOC | \ 18 RTEMS_RTL_TRACE_LOAD_SECT | \ 18 19 RTEMS_RTL_TRACE_ALLOCATOR | \ 19 20 RTEMS_RTL_TRACE_UNRESOLVED | \ 20 21 RTEMS_RTL_TRACE_ARCHIVES | \ 21 22 RTEMS_RTL_TRACE_DEPENDENCY) 22 #define DL_DEBUG_TRACE DEBUG_TRACE /* RTEMS_RTL_TRACE_ALL */ 23 /* RTEMS_RTL_TRACE_ALL */ 24 #define DL_DEBUG_TRACE DEBUG_TRACE 23 25 #define DL_RTL_CMDS 1 24 26 #else -
testsuites/libtests/dl09/dl-load.c
rd8c70ba6 r194eb403 100 100 } 101 101 102 static void* dl_load_obj (const char* name, bool has_unresolved)102 static void* dl_load_obj (const char* name, bool has_unresolved) 103 103 { 104 104 void* handle; … … 185 185 dl_load_dump (); 186 186 187 /* 188 * Check for any resolved externals. 189 */ 190 printf ("Check is any unresolved externals exist:\n"); 191 dl_check_resolved (RTLD_SELF, false); 192 187 193 printf ("Running rtems_main_o1:\n"); 188 194 if (dl_call (o[0].handle, "rtems_main_o1")) 189 195 return 1; 190 196 191 for (i = 0; i < NUMOF (od); ++i)197 for (i = 0; i < NUMOF (od); ++i) 192 198 dl_object_close (&o[i]); 193 199 -
testsuites/libtests/dl09/dl-o5.c
rd8c70ba6 r194eb403 8 8 9 9 #include "dl-load.h" 10 #include "dl-o4.h" 10 11 #include "dl-o5.h" 11 12
Note: See TracChangeset
for help on using the changeset viewer.