forked from Imagelibrary/rtems
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
This commit is contained in:
@@ -96,6 +96,15 @@ bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
|
|||||||
*/
|
*/
|
||||||
rtems_rtl_obj_sym* rtems_rtl_symbol_global_find (const char* name);
|
rtems_rtl_obj_sym* rtems_rtl_symbol_global_find (const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort an object file's local and global symbol table. This needs to
|
||||||
|
* be done before calling @ref rtems_rtl_symbol_obj_find as it
|
||||||
|
* performs a binary search on the tables.
|
||||||
|
*
|
||||||
|
* @param obj The object file to sort.
|
||||||
|
*/
|
||||||
|
void rtems_rtl_symbol_obj_sort (rtems_rtl_obj* obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a symbol given the symbol label in the local object file.
|
* Find a symbol given the symbol label in the local object file.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -914,7 +914,11 @@ rtems_rtl_obj_load_symbols (rtems_rtl_obj* obj,
|
|||||||
void* data)
|
void* data)
|
||||||
{
|
{
|
||||||
uint32_t mask = RTEMS_RTL_OBJ_SECT_SYM;
|
uint32_t mask = RTEMS_RTL_OBJ_SECT_SYM;
|
||||||
return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
|
bool ok;
|
||||||
|
ok = rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
|
||||||
|
if (ok)
|
||||||
|
rtems_rtl_symbol_obj_sort (obj);
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
@@ -200,26 +200,59 @@ rtems_rtl_symbol_global_find (const char* name)
|
|||||||
return NULL;
|
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_obj_sym*
|
||||||
rtems_rtl_symbol_obj_find (rtems_rtl_obj* obj, const char* name)
|
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
|
* Check the object file's symbols first. If not found search the
|
||||||
* global symbol table.
|
* global symbol table.
|
||||||
*/
|
*/
|
||||||
if (obj->local_syms)
|
if (obj->local_syms)
|
||||||
{
|
{
|
||||||
for (s = 0, sym = obj->local_table; s < obj->local_syms; ++s, ++sym)
|
rtems_rtl_obj_sym* match;
|
||||||
if (strcmp (name, sym->name) == 0)
|
rtems_rtl_obj_sym key = { 0 };
|
||||||
return sym;
|
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)
|
if (obj->global_syms)
|
||||||
{
|
{
|
||||||
for (s = 0, sym = obj->global_table; s < obj->global_syms; ++s, ++sym)
|
rtems_rtl_obj_sym* match;
|
||||||
if (strcmp (name, sym->name) == 0)
|
rtems_rtl_obj_sym key = { 0 };
|
||||||
return sym;
|
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);
|
return rtems_rtl_symbol_global_find (name);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user