コード例 #1
0
ファイル: rtl-obj.c プロジェクト: AlexShiLucky/rtems
bool
rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name)
{
  const char*       pname;
  rtems_rtl_data_t* rtl;

  /*
   * Parse the name. The object descriptor will have the archive name and/or
   * object name fields filled in. A find of the file will result in the file
   * name (fname) field pointing to the actual file if present on the file
   * system.
   */
  if (!rtems_rtl_obj_parse_name (obj, name))
    return false;

  /*
   * If the archive field (aname) is set we use that name else we use the
   * object field (oname). If selected name is absolute we just point the aname
   * field to the fname field to that name. If the field is relative we search
   * the paths set in the RTL for the file.
   */
  if (rtems_rtl_obj_aname_valid (obj))
    pname = rtems_rtl_obj_aname (obj);
  else
    pname = rtems_rtl_obj_oname (obj);

  rtl = rtems_rtl_lock ();

  if (!rtems_rtl_find_file (pname, rtl->paths, &obj->fname, &obj->fsize))
  {
    rtems_rtl_set_error (ENOENT, "file not found");
    rtems_rtl_unlock ();
    return false;
  }

  rtems_rtl_unlock ();

  return true;
}
コード例 #2
0
ファイル: rtl-mdreloc-mips.c プロジェクト: AlexShiLucky/rtems
/*
 * 1. _gp_disp symbol are not considered in this file.
 * 2. There is a local/external column;
 * local corresponds to (STB_LOCAL & STT_SECTION) and
 * all others are external. Because if the type of a
 * symbol is STT_SECTION, it must be STB_LOCAL. Thus
 * just consider symtype here.
 */
bool
rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
                            const Elf_Rel*              rel,
                            const rtems_rtl_obj_sect_t* sect,
                            const char*                 symname,
                            const Elf_Byte              syminfo,
                            const Elf_Word              symvalue)
{
  Elf_Addr *where;
  Elf_Word  tmp;
  Elf_Word addend = (Elf_Word)0;
  Elf_Word local = 0;
  uint32_t t;


  static Elf_Addr *where_hi16;
  static Elf_Addr ahl;

  where = (Elf_Addr *)(sect->base + rel->r_offset);
  addend = *where;

  if (syminfo == STT_SECTION)
    local = 1;

  switch (ELF_R_TYPE(rel->r_info)) {
    case R_TYPE(NONE):
      break;

    case R_TYPE(16):
      tmp = addend & 0xffff;
      if ((tmp & 0x8000) == 0x8000)
        tmp |= 0xffff0000; /* Sign extend */
      tmp = symvalue + (int)tmp;
      if ((tmp & 0xffff0000) != 0) {
        printf("R_MIPS_16 Overflow\n");
        return false;
      }

      *where = (tmp & 0xffff) | (*where & 0xffff0000);

      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: R_MIPS_16 %p @ %p in %s\n",
                (void *)*(where), where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(32):
      tmp = symvalue + addend;
      if (addend != tmp)
        *where = tmp;

      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: R_MIPS_32 %p @ %p in %s\n",
                (void *)*(where), where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(26):

        addend &= 0x03ffffff;
        addend <<= 2;

      if (local == 1) { /* STB_LOCAL and STT_SECTION */
        tmp = symvalue + (((Elf_Addr)where & 0xf0000000) | addend);
        tmp >>= 2;

      } else { /* external */
コード例 #3
0
ファイル: rtl-unresolved.c プロジェクト: goetzpf/rtems
bool
rtems_rtl_unresolved_add (rtems_rtl_obj_t*        obj,
                          const uint16_t          flags,
                          const char*             name,
                          const uint16_t          sect,
                          const rtems_rtl_word_t* rel)
{
    rtems_rtl_unresolved_t* unresolved;
    rtems_chain_node* node;
    rtems_rtl_unresolv_block_t* block;
    rtems_rtl_unresolv_rec_t* rec;
    int name_index;
    size_t name_recs;

    if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
        printf ("rtl: unresolv: add: %s(s:%d) -> %s\n",
                rtems_rtl_obj_oname (obj), sect, name);

    unresolved = rtems_rtl_unresolved ();
    if (!unresolved)
        return false;

    /*
     * Find the first block with a spare record.
     */
    node = rtems_chain_first (&unresolved->blocks);
    block = NULL;
    while (!rtems_chain_is_tail (&unresolved->blocks, node))
    {
        block = (rtems_rtl_unresolv_block_t*) node;
        if (block->recs < unresolved->block_recs)
            break;
        block = NULL;
        node = rtems_chain_next (node);
    }

    /*
     * No blocks with any spare records, allocate a new block.
     */
    if (!block)
    {
        block = rtems_rtl_unresolved_block_alloc (unresolved);
        if (!block)
            return false;
    }

    name_index = rtems_rtl_unresolved_find_name (unresolved, name, true);
    name_recs = rtems_rtl_unresolved_name_recs (name);

    /*
     * An index less than 0 means the name is present and "0 - index" is the next
     * index to use.
     */
    if (name_index < 0)
    {
        rtems_rtl_unresolv_block_t* name_block = block;

        /*
         * Is there enough room to fit the name ? It not add a new block.
         */
        if (name_recs > (unresolved->block_recs - block->recs))
        {
            name_block = rtems_rtl_unresolved_block_alloc (unresolved);
            if (!name_block)
                return false;
        }

        rec = rtems_rtl_unresolved_rec_first_free (name_block);
        rec->type = rtems_rtl_unresolved_name;
        rec->rec.name.refs = 1;
        rec->rec.name.length = strlen (name) + 1;
        memcpy ((void*) &rec->rec.name.name[0], name, rec->rec.name.length + 1);
        block->recs += name_recs;
        name_index = 0 - name_index;

        /*
         * If the name block is the reloc block and it is full allocate a new
         * block for the relocation record.
         */
        if ((block == name_block) && (block->recs >= unresolved->block_recs))
        {
            block = rtems_rtl_unresolved_block_alloc (unresolved);
            if (!block)
                return false;
        }
    }

    rec = rtems_rtl_unresolved_rec_first_free (block);
    rec->type = rtems_rtl_unresolved_reloc;
    rec->rec.reloc.obj = obj;
    rec->rec.reloc.flags = flags;
    rec->rec.reloc.name = name_index;
    rec->rec.reloc.sect = sect;
    rec->rec.reloc.rel[0] = rel[0];
    rec->rec.reloc.rel[1] = rel[1];
    rec->rec.reloc.rel[2] = rel[2];

    ++block->recs;

    return true;
}
コード例 #4
0
bool
rtems_rtl_elf_relocate_rela (const rtems_rtl_obj_t*      obj,
                             const Elf_Rela*             rela,
                             const rtems_rtl_obj_sect_t* sect,
                             const char*                 symname,
                             const Elf_Byte              syminfo,
                             const Elf_Word              symvalue)
{
  Elf_Addr* where;
  Elf_Word tmp;
  uint32_t mask = 0;
  uint32_t bits = 0;

  where = (Elf_Addr *)(sect->base + rela->r_offset);
  switch (ELF_R_TYPE(rela->r_info)) {
    case R_TYPE(NONE):
      break;

    case R_TYPE(32):
      /*
       * value:1; Field: word32; Expression: S + A
       */
      *where = symvalue + rela->r_addend;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: ADDR32 %p @ %p in %s\n",
                (void *)*(where), where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(14):
      /*
       * value:7; Field: low14*; Expression: (S + A) >> 2
       */
    case R_TYPE(24):
      /*
       * value:2; Field: low24*; Expression: (S + A) >> 2
       */
      if (ELF_R_TYPE(rela->r_info) == R_TYPE(14)) {
        bits = 14;
        mask = 0xfffc;
      } else {
        bits = 24;
        mask = 0x3fffffc;
      }
      tmp = (symvalue + rela->r_addend) >> 2;
      if (tmp > ((1<<bits) - 1 )) {
        printf("Overflow ADDR14/ADDR24\n");
        return false;
      }
      tmp = *where;
      tmp &= ~mask;
      tmp |= (symvalue + rela->r_addend) & mask;
      *where = tmp;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: ADDR14/ADDR24 %p @ %p in %s\n",
                (void *)*where, where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(16_HA):
      /*
       * value:6; Field:half16; Expression: #ha(S+A)
       */

      tmp = symvalue + rela->r_addend;
      *(uint16_t *)where = (((tmp >> 16) + ((tmp & 0x8000) ? 1: 0)) & 0xffff);
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: 16_HA %p @ %p in %s\n",
                (void *)*(where), where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(16_HI):
      /*
       * value:5; Field:half16; Expression: #hi(S+A)
       */
      *(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: 16_HI %p @ %p in %s\n",
                (void *)*where, where, rtems_rtl_obj_oname (obj));
      break;
    case R_TYPE(16_LO):
      /*
       * value:4; Field:half16; Expression: #lo(S+A)
       */
      *(uint16_t *)where = (symvalue + (rela->r_addend)) & 0xffff;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: 16_LO %p @ %p in %s\n",
                (void *)*where, where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(REL14):
      /*
       * value:11; Field:low14*; Expression:(S+A-P)>>2
       */
    case R_TYPE(REL24):
      /*
       * value:10; Field:low24*; Expression:(S+A-P)>>2
       */
      if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL24)) {
        mask = 0x3fffffc;
        bits = 24;
      }
      else if (ELF_R_TYPE(rela->r_info) == R_TYPE(REL14)) {
        mask = 0xfffc;
        bits = 14;
      }

      tmp =((int) (symvalue + rela->r_addend - (Elf_Addr)where)) >> 2;
      if (((Elf_Sword)tmp > ((1<<(bits-1)) - 1)) ||
          ((Elf_Sword)tmp < -(1<<(bits-1)))) {
        printf("Overflow REL14/REL24\n");
        return false;
      }

      tmp = *where;
      tmp &= ~mask;
      tmp |= (symvalue + rela->r_addend - (Elf_Addr)where) & mask;
      *where = tmp;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: REL24/REL14 %p @ %p in %s\n",
                (void *)*where, where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(REL32):
      /*
       * value:26; Field:word32*; Expression:S+A-P
       */
      *where = symvalue + rela->r_addend - (Elf_Addr)where;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: REL32 %p @ %p in %s\n",
                (void *)*where, where, rtems_rtl_obj_oname (obj));
      break;

    default:
      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
              "contents = %p\n",
              ELF_R_SYM(rela->r_info), (uint32_t) ELF_R_TYPE(rela->r_info),
              (void *)rela->r_offset, (void *)*where);
      rtems_rtl_set_error (EINVAL,
                           "%s: Unsupported relocation type %ld "
                           "in non-PLT relocations",
                           sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
      return false;
  }
  return true;
}
コード例 #5
0
bool
rtems_rtl_elf_relocate_rel (const rtems_rtl_obj_t*      obj,
                            const Elf_Rel*              rel,
                            const rtems_rtl_obj_sect_t* sect,
                            const char*                 symname,
                            const Elf_Byte              syminfo,
                            const Elf_Word              symvalue)
{
	Elf_Addr  target = 0;
  Elf_Addr* where;
  Elf_Addr  tmp;

  where = (Elf_Addr *)(sect->base + rel->r_offset);

  switch (ELF_R_TYPE(rel->r_info)) {
    case R_TYPE(NONE):
      break;

    case R_TYPE(PC32):
      target = (Elf_Addr) symvalue;
      *where += target - (Elf_Addr)where;

      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: reloc PC32 in %s --> %p (%p @ %p) in %s\n",
                sect->name, (void*) symvalue,
                (void *)*where, where, rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(GOT32):
    case R_TYPE(32):
    case R_TYPE(GLOB_DAT):
      target = (Elf_Addr) symvalue;

      tmp = target + *where;
      if (*where != tmp)
        *where = tmp;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: reloc 32/GLOB_DAT in %s --> %p @ %p in %s\n",
                sect->name, (void *)*where, where,
                rtems_rtl_obj_oname (obj));
      break;

    case R_TYPE(RELATIVE):
      *where += (Elf_Addr)sect->base;
      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
        printf ("rtl: reloc RELATIVE in %s --> %p @ %p\n",
                rtems_rtl_obj_oname (obj), (void *)*where, where);
      break;

    case R_TYPE(COPY):
      printf ("rtl: reloc COPY (please report)\n");
      break;

    default:
      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
              "contents = %p\n",
              ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
              (void *)rel->r_offset, (void *)*where);
      rtems_rtl_set_error (EINVAL,
                           "%s: Unsupported relocation type %ld "
                           "in non-PLT relocations",
                           sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
      return false;
  }

  return true;
}
コード例 #6
0
ファイル: rtl-shell.c プロジェクト: ycg663/rtems
/**
 * Object printer.
 */
static bool
rtems_rtl_obj_printer (rtems_rtl_obj_print_t* print, rtems_rtl_obj_t* obj)
{
    char flags_str[33];

    /*
     * Skip the base module unless asked to show it.
     */
    if (!print->base && (obj == print->rtl->base))
        return true;

    if (print->oname)
    {
        printf ("%-*cobject name   : %s\n",
                print->indent, ' ', rtems_rtl_obj_oname (obj));
    }
    if (print->names)
    {
        printf ("%-*cfile name     : %s\n",
                print->indent, ' ', rtems_rtl_obj_fname (obj));
        printf ("%-*carchive name  : %s\n",
                print->indent, ' ', rtems_rtl_obj_aname (obj));
        strcpy (flags_str, "--");
        if (obj->flags & RTEMS_RTL_OBJ_LOCKED)
            flags_str[0] = 'L';
        if (obj->flags & RTEMS_RTL_OBJ_UNRESOLVED)
            flags_str[1] = 'U';
        printf ("%-*cflags         : %s\n", print->indent, ' ', flags_str);
        printf ("%-*cfile offset   : %" PRIdoff_t "\n", print->indent, ' ', obj->ooffset);
        printf ("%-*cfile size     : %zi\n", print->indent, ' ', obj->fsize);
    }
    if (print->memory_map)
    {
        printf ("%-*cexec size     : %zi\n", print->indent, ' ', obj->exec_size);
        printf ("%-*ctext base     : %p (%zi)\n", print->indent, ' ',
                obj->text_base, rtems_rtl_delta_voids (obj->const_base, obj->text_base));
        printf ("%-*cconst base    : %p (%zi)\n", print->indent, ' ',
                obj->const_base, rtems_rtl_delta_voids (obj->data_base, obj->const_base));
        printf ("%-*cdata base     : %p (%zi)\n", print->indent, ' ',
                obj->data_base, rtems_rtl_delta_voids (obj->bss_base, obj->data_base));
        printf ("%-*cbss base      : %p (%zi)\n", print->indent, ' ',
                obj->bss_base, obj->bss_size);
    }
    printf ("%-*cunresolved    : %lu\n", print->indent, ' ', obj->unresolved);
    printf ("%-*csymbols       : %zi\n", print->indent, ' ', obj->global_syms);
    printf ("%-*csymbol memory : %zi\n", print->indent, ' ', obj->global_size);
    if (print->symbols)
    {
        int max_len = 0;
        int s;
        for (s = 0; s < obj->global_syms; ++s)
        {
            int len = strlen (obj->global_table[s].name);
            if (len > max_len)
                max_len = len;
        }
        for (s = 0; s < obj->global_syms; ++s)
            printf ("%-*c%-*s = %p\n", print->indent + 2, ' ',
                    max_len, obj->global_table[s].name, obj->global_table[s].value);
    }
    printf ("\n");
    return true;
}