diff options
author | Chris Johns <chrisj@rtems.org> | 2019-05-14 10:34:32 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2019-05-22 09:28:06 +1000 |
commit | 327e45dac2edae51caabc7777e2381ad653502ff (patch) | |
tree | 4b3ead70909f23a4c0c7dba6b6bba3a56dd88e3e /cpukit/libdl/rtl-sym.c | |
parent | score: Add _SMP_Unicast_action() (diff) | |
download | rtems-327e45dac2edae51caabc7777e2381ad653502ff.tar.bz2 |
libdl: Sort object file symbols and use a binary search to find
- Replace the linear object file symbol search with a binary search.
- Sort the object file symbols after loading.
Closes #3748
Diffstat (limited to '')
-rw-r--r-- | cpukit/libdl/rtl-sym.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/cpukit/libdl/rtl-sym.c b/cpukit/libdl/rtl-sym.c index c27f2ee676..9dd891525b 100644 --- a/cpukit/libdl/rtl-sym.c +++ b/cpukit/libdl/rtl-sym.c @@ -200,26 +200,59 @@ rtems_rtl_symbol_global_find (const char* name) return NULL; } +static int +rtems_rtl_symbol_obj_compare (const void* a, const void* b) +{ + const rtems_rtl_obj_sym* sa; + const rtems_rtl_obj_sym* sb; + sa = (const rtems_rtl_obj_sym*) a; + sb = (const rtems_rtl_obj_sym*) b; + return strcmp (sa->name, sb->name); +} + +void +rtems_rtl_symbol_obj_sort (rtems_rtl_obj* obj) +{ + qsort (obj->local_table, + obj->local_syms, + sizeof (rtems_rtl_obj_sym), + rtems_rtl_symbol_obj_compare); + qsort (obj->global_table, + obj->global_syms, + sizeof (rtems_rtl_obj_sym), + rtems_rtl_symbol_obj_compare); +} + rtems_rtl_obj_sym* rtems_rtl_symbol_obj_find (rtems_rtl_obj* obj, const char* name) { - rtems_rtl_obj_sym* sym; - size_t s; /* * Check the object file's symbols first. If not found search the * global symbol table. */ if (obj->local_syms) { - for (s = 0, sym = obj->local_table; s < obj->local_syms; ++s, ++sym) - if (strcmp (name, sym->name) == 0) - return sym; + rtems_rtl_obj_sym* match; + rtems_rtl_obj_sym key = { 0 }; + key.name = name; + match = bsearch (&key, obj->local_table, + obj->local_syms, + sizeof (rtems_rtl_obj_sym), + rtems_rtl_symbol_obj_compare); + if (match != NULL) + return match; } if (obj->global_syms) { - for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym) - if (strcmp (name, sym->name) == 0) - return sym; + rtems_rtl_obj_sym* match; + rtems_rtl_obj_sym key = { 0 }; + key.name = name; + match = bsearch (&key, obj->global_table, + obj->global_syms, + sizeof (rtems_rtl_obj_sym), + rtems_rtl_symbol_obj_compare); + if (match != NULL) + return match; } return rtems_rtl_symbol_global_find (name); } |