mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-30 00:10:16 +00:00
cpukit/libdl: Fix loading symbols from an object file at runtime
- Assume a relocation record with a symbol name with a length of 0 is resolved. ARM seems to create a symbol with no name for R_ARM_V4BX relocation records. - Move the addition of the rtems_rtl_base_sym_global_add symbol to the global symbol table to the weak rtems_rtl_base_global_syms_init call. If symbols are embedded the support for runtime loading symbols is over loaded. This change is required so the base object has a valid global symbol table attached to track dependencies. Fixes #5234
This commit is contained in:
@@ -374,7 +374,7 @@ static inline size_t rtems_rtl_obj_align (size_t offset,
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the symbol in this object's files globa symbol table?
|
||||
* Is the symbol in this object's files global symbol table?
|
||||
*
|
||||
* @param obj The object file's descriptor to search.
|
||||
* @param sym The symbol to check.
|
||||
|
||||
@@ -97,6 +97,15 @@ bool rtems_rtl_symbol_table_open (rtems_rtl_symbols* symbols,
|
||||
*/
|
||||
void rtems_rtl_symbol_table_close (rtems_rtl_symbols* symbols);
|
||||
|
||||
/**
|
||||
* Insert a symbol into a symbol table.
|
||||
*
|
||||
* @param symbols Symbol table
|
||||
* @param symbols Symbol to add
|
||||
*/
|
||||
void rtems_rtl_symbol_global_insert (rtems_rtl_symbols* symbols,
|
||||
rtems_rtl_obj_sym* symbol);
|
||||
|
||||
/**
|
||||
* Add a table of exported symbols to the symbol table.
|
||||
*
|
||||
|
||||
@@ -557,6 +557,8 @@ rtems_rtl_elf_relocate_worker (rtems_rtl_obj* obj,
|
||||
resolved = rtems_rtl_elf_find_symbol (obj,
|
||||
&sym, symname,
|
||||
&symbol, &symvalue);
|
||||
if (symname != NULL && strlen(symname) == 0)
|
||||
resolved = true;
|
||||
|
||||
if (!handler (obj,
|
||||
is_rela, relbuf, targetsect,
|
||||
|
||||
@@ -48,16 +48,6 @@
|
||||
#include <rtems/rtl/rtl-sym.h>
|
||||
#include <rtems/rtl/rtl-trace.h>
|
||||
|
||||
/**
|
||||
* The single symbol forced into the global symbol table that is used to load a
|
||||
* symbol table from an object file.
|
||||
*/
|
||||
static rtems_rtl_obj_sym global_sym_add =
|
||||
{
|
||||
.name = "rtems_rtl_base_sym_global_add",
|
||||
.value = (void*) rtems_rtl_base_sym_global_add
|
||||
};
|
||||
|
||||
static uint_fast32_t
|
||||
rtems_rtl_symbol_hash (const char *s)
|
||||
{
|
||||
@@ -68,15 +58,6 @@ rtems_rtl_symbol_hash (const char *s)
|
||||
return h & 0xffffffff;
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_rtl_symbol_global_insert (rtems_rtl_symbols* symbols,
|
||||
rtems_rtl_obj_sym* symbol)
|
||||
{
|
||||
uint_fast32_t hash = rtems_rtl_symbol_hash (symbol->name);
|
||||
rtems_chain_append (&symbols->buckets[hash % symbols->nbuckets],
|
||||
&symbol->node);
|
||||
}
|
||||
|
||||
static const rtems_rtl_tls_offset*
|
||||
rtems_rtl_symbol_find_tls_offset (size_t index,
|
||||
const rtems_rtl_tls_offset* tls_offsets,
|
||||
@@ -108,7 +89,6 @@ rtems_rtl_symbol_table_open (rtems_rtl_symbols* symbols,
|
||||
symbols->nbuckets = buckets;
|
||||
for (buckets = 0; buckets < symbols->nbuckets; ++buckets)
|
||||
rtems_chain_initialize_empty (&symbols->buckets[buckets]);
|
||||
rtems_rtl_symbol_global_insert (symbols, &global_sym_add);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -118,6 +98,15 @@ rtems_rtl_symbol_table_close (rtems_rtl_symbols* symbols)
|
||||
rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_SYMBOL, symbols->buckets);
|
||||
}
|
||||
|
||||
void
|
||||
rtems_rtl_symbol_global_insert (rtems_rtl_symbols* symbols,
|
||||
rtems_rtl_obj_sym* symbol)
|
||||
{
|
||||
uint_fast32_t hash = rtems_rtl_symbol_hash (symbol->name);
|
||||
rtems_chain_append (&symbols->buckets[hash % symbols->nbuckets],
|
||||
&symbol->node);
|
||||
}
|
||||
|
||||
bool
|
||||
rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
|
||||
const unsigned char* esyms,
|
||||
|
||||
@@ -562,10 +562,18 @@ rtems_rtl_unresolved_add (rtems_rtl_obj* obj,
|
||||
rtems_rtl_unresolv_block* block;
|
||||
rtems_rtl_unresolv_rec* rec;
|
||||
int name_index;
|
||||
const int name_len = (int) strlen(name);
|
||||
|
||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
|
||||
printf ("rtl: unresolv: add: %s(s:%d) -> %s\n",
|
||||
rtems_rtl_obj_oname (obj), sect, name);
|
||||
printf ("rtl: unresolv: add: %s(s:%d) -> '%s' (len: %i)\n",
|
||||
rtems_rtl_obj_oname (obj), sect, name, name_len);
|
||||
|
||||
/*
|
||||
* No name or an empty name is not able to resolved?
|
||||
*/
|
||||
if (name_len == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unresolved = rtems_rtl_unresolved_unprotected ();
|
||||
if (!unresolved)
|
||||
|
||||
@@ -78,17 +78,47 @@
|
||||
static rtems_rtl_data* rtl;
|
||||
static bool rtl_data_init;
|
||||
|
||||
/**
|
||||
* The single symbol forced into the global symbol table that is used to load a
|
||||
* symbol table from an object file.
|
||||
*/
|
||||
static rtems_rtl_obj_sym default_global_syms =
|
||||
{
|
||||
.name = "rtems_rtl_base_sym_global_add",
|
||||
.value = (void*) rtems_rtl_base_sym_global_add
|
||||
};
|
||||
|
||||
/**
|
||||
* Define a default base global symbol loader function that is weak
|
||||
* so a real table can be linked in when the user wants one.
|
||||
*
|
||||
* The default init handler add the one symbol used when loading
|
||||
* symbols with an object file. It is an unresolved external in that
|
||||
* object file.
|
||||
*/
|
||||
void rtems_rtl_base_global_syms_init (void) __attribute__ ((weak));
|
||||
void
|
||||
rtems_rtl_base_global_syms_init (void)
|
||||
{
|
||||
/*
|
||||
* Do nothing.
|
||||
*/
|
||||
rtems_rtl_symbols* symbols;
|
||||
|
||||
if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
|
||||
printf ("rtl: adding default global symbol\n");
|
||||
|
||||
if (!rtems_rtl_lock ())
|
||||
{
|
||||
rtems_rtl_set_error (EINVAL, "global add cannot lock rtl");
|
||||
return;
|
||||
}
|
||||
|
||||
symbols = rtems_rtl_global_symbols ();
|
||||
|
||||
rtl->base->global_table = &default_global_syms;
|
||||
rtl->base->global_syms = 1;
|
||||
|
||||
rtems_rtl_symbol_global_insert (symbols, &default_global_syms);
|
||||
|
||||
rtems_rtl_unlock ();
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
Reference in New Issue
Block a user