Пример #1
0
static bool
rtems_rtl_unresolved_resolve_iterator (rtems_rtl_unresolv_rec_t* rec,
                                       void*                     data)
{
    if (rec->type == rtems_rtl_unresolved_name)
    {
        rtems_rtl_unresolved_reloc_data_t* rd;
        rd = (rtems_rtl_unresolved_reloc_data_t*) data;

        ++rd->name;

        if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
            printf ("rtl: unresolv: lookup: %d: %s\n", rd->name, rec->rec.name.name);

        rd->sym = rtems_rtl_symbol_global_find (rec->rec.name.name);

        if (rd->sym)
        {
            if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
                printf ("rtl: unresolv: found: %s\n", rec->rec.name.name);

            rd->name_rec = rec;

            rtems_rtl_unresolved_interate (rtems_rtl_unresolved_resolve_reloc, rd);

            rd->name_rec = NULL;
            rd->sym = NULL;
        }
    }

    return false;
}
Пример #2
0
rtems_rtl_obj_sym_t*
rtems_rtl_symbol_obj_find (rtems_rtl_obj_t* obj, const char* name)
{
  rtems_rtl_obj_sym_t* 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;
  }
  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;
  }
  return rtems_rtl_symbol_global_find (name);
}
Пример #3
0
bool
rtems_rtl_symbol_global_add (rtems_rtl_obj_t*     obj,
                             const unsigned char* esyms,
                             unsigned int         size)
{
  rtems_rtl_symbols_t* symbols;
  rtems_rtl_obj_sym_t* sym;
  size_t               count;
  size_t               s;
  uint32_t             marker;

  count = 0;
  s = 0;
  while ((s < size) && (esyms[s] != 0))
  {
    int l = strlen ((char*) &esyms[s]);
    if ((esyms[s + l] != '\0') || ((s + l) > size))
    {
      rtems_rtl_set_error (EINVAL, "invalid exported symbol table");
      return false;
    }
    ++count;
    s += l + sizeof (unsigned long) + 1;
  }

  /*
   * Check this is the correct end of the table.
   */
  marker = esyms[s + 1];
  marker <<= 8;
  marker |= esyms[s + 2];
  marker <<= 8;
  marker |= esyms[s + 3];
  marker <<= 8;
  marker |= esyms[s + 4];

  if (marker != 0xdeadbeefUL)
  {
    rtems_rtl_set_error (ENOMEM, "invalid export symbol table");
    return false;
  }

  if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
    printf ("rtl: global symbol add: %zi\n", count);

  obj->global_size = count * sizeof (rtems_rtl_obj_sym_t);
  obj->global_table = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_SYMBOL,
                                           obj->global_size, true);
  if (!obj->global_table)
  {
    obj->global_size = 0;
    rtems_rtl_set_error (ENOMEM, "no memory for global symbols");
    return false;
  }

  symbols = rtems_rtl_global_symbols ();

  s = 0;
  sym = obj->global_table;

  while ((s < size) && (esyms[s] != 0))
  {
    /*
     * Copy the void* using a union and memcpy to avoid any strict aliasing or
     * alignment issues. The variable length of the label and the packed nature
     * of the table means casting is not suitable.
     */
    union {
      uint8_t data[sizeof (void*)];
      void*   value;
    } copy_voidp;
    int b;

    sym->name = (const char*) &esyms[s];
    s += strlen (sym->name) + 1;
    for (b = 0; b < sizeof (void*); ++b, ++s)
      copy_voidp.data[b] = esyms[s];
    sym->value = copy_voidp.value;
    if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
      printf ("rtl: esyms: %s -> %8p\n", sym->name, sym->value);
    if (rtems_rtl_symbol_global_find (sym->name) == NULL)
      rtems_rtl_symbol_global_insert (symbols, sym);
    ++sym;
  }

  obj->global_syms = count;

  return true;
}