Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions | Variables
elf32-d10v.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/d10v.h"
#include "elf32-target.h"

Go to the source code of this file.

Classes

struct  d10v_reloc_map

Defines

#define USE_REL   1
#define ELF_ARCH   bfd_arch_d10v
#define ELF_MACHINE_CODE   EM_D10V
#define ELF_MACHINE_ALT1   EM_CYGNUS_D10V
#define ELF_MAXPAGESIZE   0x1000
#define TARGET_BIG_SYM   bfd_elf32_d10v_vec
#define TARGET_BIG_NAME   "elf32-d10v"
#define elf_info_to_howto   0
#define elf_info_to_howto_rel   d10v_info_to_howto_rel
#define elf_backend_object_p   0
#define elf_backend_final_write_processing   0
#define elf_backend_gc_mark_hook   elf32_d10v_gc_mark_hook
#define elf_backend_check_relocs   elf32_d10v_check_relocs
#define elf_backend_relocate_section   elf32_d10v_relocate_section
#define elf_backend_can_gc_sections   1

Functions

static reloc_howto_type * bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
static reloc_howto_type * bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
static void d10v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, Elf_Internal_Rela *dst)
static asectionelf32_d10v_gc_mark_hook (asection *sec, struct bfd_link_info *info, Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
static bfd_boolean elf32_d10v_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)
static bfd_vma extract_rel_addend (bfd *abfd, bfd_byte *where, reloc_howto_type *howto)
static void insert_rel_addend (bfd *abfd, bfd_byte *where, reloc_howto_type *howto, bfd_vma addend)
static bfd_boolean elf32_d10v_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms, asection **local_sections)

Variables

static reloc_howto_type elf_d10v_howto_table []
static struct d10v_reloc_map []

Class Documentation

struct d10v_reloc_map

Definition at line 172 of file elf32-d10v.c.

Class Members
bfd_reloc_code_real_type bfd_reloc_val
unsigned char elf_reloc_val

Define Documentation

#define ELF_ARCH   bfd_arch_d10v

Definition at line 544 of file elf32-d10v.c.

Definition at line 559 of file elf32-d10v.c.

Definition at line 557 of file elf32-d10v.c.

Definition at line 555 of file elf32-d10v.c.

Definition at line 556 of file elf32-d10v.c.

#define elf_backend_object_p   0

Definition at line 554 of file elf32-d10v.c.

Definition at line 558 of file elf32-d10v.c.

#define elf_info_to_howto   0

Definition at line 552 of file elf32-d10v.c.

Definition at line 553 of file elf32-d10v.c.

Definition at line 546 of file elf32-d10v.c.

#define ELF_MACHINE_CODE   EM_D10V

Definition at line 545 of file elf32-d10v.c.

#define ELF_MAXPAGESIZE   0x1000

Definition at line 547 of file elf32-d10v.c.

#define TARGET_BIG_NAME   "elf32-d10v"

Definition at line 550 of file elf32-d10v.c.

Definition at line 549 of file elf32-d10v.c.

#define USE_REL   1

Definition at line 30 of file elf32-d10v.c.


Function Documentation

static reloc_howto_type* bfd_elf32_bfd_reloc_name_lookup ( bfd *abfd  ATTRIBUTE_UNUSED,
const char *  r_name 
) [static]

Definition at line 207 of file elf32-d10v.c.

{
  unsigned int i;

  for (i = 0;
       i < sizeof (elf_d10v_howto_table) / sizeof (elf_d10v_howto_table[0]);
       i++)
    if (elf_d10v_howto_table[i].name != NULL
       && strcasecmp (elf_d10v_howto_table[i].name, r_name) == 0)
      return &elf_d10v_howto_table[i];

  return NULL;
}

Here is the call graph for this function:

static reloc_howto_type* bfd_elf32_bfd_reloc_type_lookup ( bfd *abfd  ATTRIBUTE_UNUSED,
bfd_reloc_code_real_type  code 
) [static]

Definition at line 192 of file elf32-d10v.c.

{
  unsigned int i;

  for (i = 0;
       i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map);
       i++)
    if (d10v_reloc_map[i].bfd_reloc_val == code)
      return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val];

  return NULL;
}
static void d10v_info_to_howto_rel ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent cache_ptr,
Elf_Internal_Rela dst 
) [static]

Definition at line 225 of file elf32-d10v.c.

{
  unsigned int r_type;

  r_type = ELF32_R_TYPE (dst->r_info);
  BFD_ASSERT (r_type < (unsigned int) R_D10V_max);
  cache_ptr->howto = &elf_d10v_howto_table[r_type];
}
static bfd_boolean elf32_d10v_check_relocs ( bfd abfd,
struct bfd_link_info info,
asection sec,
const Elf_Internal_Rela relocs 
) [static]

Definition at line 259 of file elf32-d10v.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;

  if (info->relocatable)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
  if (!elf_bad_symtab (abfd))
    sym_hashes_end -= symtab_hdr->sh_info;

  rel_end = relocs + sec->reloc_count;
  for (rel = relocs; rel < rel_end; rel++)
    {
      struct elf_link_hash_entry *h;
      unsigned long r_symndx;

      r_symndx = ELF32_R_SYM (rel->r_info);
      if (r_symndx < symtab_hdr->sh_info)
        h = NULL;
      else
       {
         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
         while (h->root.type == bfd_link_hash_indirect
               || h->root.type == bfd_link_hash_warning)
           h = (struct elf_link_hash_entry *) h->root.u.i.link;
       }

      switch (ELF32_R_TYPE (rel->r_info))
        {
        /* This relocation describes the C++ object vtable hierarchy.
           Reconstruct it for later use during GC.  */
        case R_D10V_GNU_VTINHERIT:
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;

        /* This relocation describes which C++ vtable entries are actually
           used.  Record for later use during GC.  */
        case R_D10V_GNU_VTENTRY:
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
        }
    }

  return TRUE;
}

Here is the call graph for this function:

static asection* elf32_d10v_gc_mark_hook ( asection sec,
struct bfd_link_info info,
Elf_Internal_Rela rel,
struct elf_link_hash_entry h,
Elf_Internal_Sym *  sym 
) [static]

Definition at line 237 of file elf32-d10v.c.

{
  if (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_D10V_GNU_VTINHERIT:
      case R_D10V_GNU_VTENTRY:
       return NULL;
      }

  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}

Here is the call graph for this function:

static bfd_boolean elf32_d10v_relocate_section ( bfd output_bfd,
struct bfd_link_info info,
bfd input_bfd,
asection input_section,
bfd_byte contents,
Elf_Internal_Rela relocs,
Elf_Internal_Sym *  local_syms,
asection **  local_sections 
) [static]

Definition at line 386 of file elf32-d10v.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  Elf_Internal_Rela *rel, *relend;
  const char *name;

  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);

  rel = relocs;
  relend = relocs + input_section->reloc_count;
  for (; rel < relend; rel++)
    {
      int r_type;
      reloc_howto_type *howto;
      unsigned long r_symndx;
      Elf_Internal_Sym *sym;
      asection *sec;
      struct elf_link_hash_entry *h;
      bfd_vma relocation;
      bfd_reloc_status_type r;

      r_symndx = ELF32_R_SYM (rel->r_info);
      r_type = ELF32_R_TYPE (rel->r_info);

      if (r_type == R_D10V_GNU_VTENTRY
          || r_type == R_D10V_GNU_VTINHERIT)
        continue;

      howto = elf_d10v_howto_table + r_type;
      h = NULL;
      sym = NULL;
      sec = NULL;
      if (r_symndx < symtab_hdr->sh_info)
       {
         sym = local_syms + r_symndx;
         sec = local_sections[r_symndx];
         relocation = (sec->output_section->vma
                     + sec->output_offset
                     + sym->st_value);
         if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
             && ((sec->flags & SEC_MERGE) != 0
                || (info->relocatable
                    && sec->output_offset != 0)))
           {
             bfd_vma addend;
             bfd_byte *where = contents + rel->r_offset;

             addend = extract_rel_addend (input_bfd, where, howto);

             if (info->relocatable)
              addend += sec->output_offset;
             else
              {
                asection *msec = sec;
                addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
                                             addend);
                addend -= relocation;
                addend += msec->output_section->vma + msec->output_offset;
              }
             insert_rel_addend (input_bfd, where, howto, addend);
           }
       }
      else
       {
         bfd_boolean unresolved_reloc, warned;

         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                               r_symndx, symtab_hdr, sym_hashes,
                               h, sec, relocation,
                               unresolved_reloc, warned);
       }

      if (sec != NULL && elf_discarded_section (sec))
       {
         /* For relocs against symbols from removed linkonce sections,
            or sections discarded by a linker script, we just want the
            section contents zeroed.  Avoid any special processing.  */
         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
         rel->r_info = 0;
         rel->r_addend = 0;
         continue;
       }

      if (info->relocatable)
       continue;

      if (h != NULL)
       name = h->root.root.string;
      else
       {
         name = (bfd_elf_string_from_elf_section
                (input_bfd, symtab_hdr->sh_link, sym->st_name));
         if (name == NULL || *name == '\0')
           name = bfd_section_name (input_bfd, sec);
       }

      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                    contents, rel->r_offset,
                                    relocation, (bfd_vma) 0);

      if (r != bfd_reloc_ok)
       {
         const char * msg = (const char *) 0;

         switch (r)
           {
           case bfd_reloc_overflow:
             if (!((*info->callbacks->reloc_overflow)
                  (info, (h ? &h->root : NULL), name, howto->name,
                   (bfd_vma) 0, input_bfd, input_section,
                   rel->r_offset)))
              return FALSE;
             break;

           case bfd_reloc_undefined:
             if (!((*info->callbacks->undefined_symbol)
                  (info, name, input_bfd, input_section,
                   rel->r_offset, TRUE)))
              return FALSE;
             break;

           case bfd_reloc_outofrange:
             msg = _("internal error: out of range error");
             goto common_error;

           case bfd_reloc_notsupported:
             msg = _("internal error: unsupported relocation error");
             goto common_error;

           case bfd_reloc_dangerous:
             msg = _("internal error: dangerous error");
             goto common_error;

           default:
             msg = _("internal error: unknown error");
             /* fall through */

           common_error:
             if (!((*info->callbacks->warning)
                  (info, msg, name, input_bfd, input_section,
                   rel->r_offset)))
              return FALSE;
             break;
           }
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_vma extract_rel_addend ( bfd abfd,
bfd_byte where,
reloc_howto_type *  howto 
) [static]

Definition at line 317 of file elf32-d10v.c.

{
  bfd_vma insn, val;

  switch (howto->size)
    {
    case 0:
      insn = bfd_get_8 (abfd, where);
      break;
    case 1:
      insn = bfd_get_16 (abfd, where);
      break;
    case 2:
      insn = bfd_get_32 (abfd, where);
      break;
    default:
      abort ();
    }

  val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift;
  /* We should really be testing for signed addends here, but we don't
     have that info directly in the howto.  */
  if (howto->pc_relative)
    {
      bfd_vma sign;
      sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1));
      sign = sign >> howto->bitpos << howto->rightshift;
      val = (val ^ sign) - sign;
    }
  return val;
}

Here is the caller graph for this function:

static void insert_rel_addend ( bfd abfd,
bfd_byte where,
reloc_howto_type *  howto,
bfd_vma  addend 
) [static]

Definition at line 352 of file elf32-d10v.c.

{
  bfd_vma insn;

  addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
  insn = ~howto->dst_mask;
  switch (howto->size)
    {
    case 0:
      insn &= bfd_get_8 (abfd, where);
      insn |= addend;
      bfd_put_8 (abfd, insn, where);
      break;
    case 1:
      insn &= bfd_get_16 (abfd, where);
      insn |= addend;
      bfd_put_16 (abfd, insn, where);
      break;
    case 2:
      insn &= bfd_get_32 (abfd, where);
      insn |= addend;
      bfd_put_32 (abfd, insn, where);
      break;
    default:
      abort ();
    }
}

Here is the caller graph for this function:


Variable Documentation

struct d10v_reloc_map[] [static]
Initial value:
{
  { BFD_RELOC_NONE, R_D10V_NONE, },
  { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
  { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
  { BFD_RELOC_16, R_D10V_16 },
  { BFD_RELOC_D10V_18, R_D10V_18 },
  { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
  { BFD_RELOC_32, R_D10V_32 },
  { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT },
  { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY },
}

Definition at line 178 of file elf32-d10v.c.

reloc_howto_type elf_d10v_howto_table[] [static]

Definition at line 32 of file elf32-d10v.c.