Back to index

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

Go to the source code of this file.

Classes

struct  fr30_reloc_map

Defines

#define ELF_ARCH   bfd_arch_fr30
#define ELF_MACHINE_CODE   EM_FR30
#define ELF_MACHINE_ALT1   EM_CYGNUS_FR30
#define ELF_MAXPAGESIZE   0x1000
#define TARGET_BIG_SYM   bfd_elf32_fr30_vec
#define TARGET_BIG_NAME   "elf32-fr30"
#define elf_info_to_howto_rel   NULL
#define elf_info_to_howto   fr30_info_to_howto_rela
#define elf_backend_relocate_section   fr30_elf_relocate_section
#define elf_backend_gc_mark_hook   fr30_elf_gc_mark_hook
#define elf_backend_check_relocs   fr30_elf_check_relocs
#define elf_backend_can_gc_sections   1
#define elf_backend_rela_normal   1
#define bfd_elf32_bfd_reloc_type_lookup   fr30_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup   fr30_reloc_name_lookup

Functions

static bfd_reloc_status_type
fr30_elf_i20_reloc 
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **))
static reloc_howto_type
*fr30_reloc_type_lookup 
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code))
static void fr30_info_to_howto_rela PARAMS ((bfd *, arelent *, Elf_Internal_Rela *))
static bfd_boolean
fr30_elf_relocate_section 
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **))
static bfd_reloc_status_type
fr30_final_link_relocate 
PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma))
static bfd_boolean
fr30_elf_check_relocs 
PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *))
static bfd_reloc_status_type fr30_elf_i20_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, PTR data, asection *input_section, bfd *output_bfd, error_message)
static bfd_reloc_status_type fr30_elf_i32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, PTR data, asection *input_section, bfd *output_bfd, error_message)
static reloc_howto_type * fr30_reloc_type_lookup (abfd, bfd_reloc_code_real_type code)
static reloc_howto_type * fr30_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
static void fr30_info_to_howto_rela (abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
static bfd_reloc_status_type fr30_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd, asection *input_section, bfd_byte *contents, Elf_Internal_Rela *rel, bfd_vma relocation)
static bfd_boolean fr30_elf_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 asectionfr30_elf_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 fr30_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)

Variables

static reloc_howto_type fr30_elf_howto_table []
static struct fr30_reloc_map []

Class Documentation

struct fr30_reloc_map

Definition at line 331 of file elf32-fr30.c.

Class Members
bfd_reloc_code_real_type bfd_reloc_val
unsigned int fr30_reloc_val

Define Documentation

Definition at line 745 of file elf32-fr30.c.

Definition at line 744 of file elf32-fr30.c.

#define ELF_ARCH   bfd_arch_fr30

Definition at line 727 of file elf32-fr30.c.

Definition at line 741 of file elf32-fr30.c.

Definition at line 739 of file elf32-fr30.c.

Definition at line 738 of file elf32-fr30.c.

#define elf_backend_rela_normal   1

Definition at line 742 of file elf32-fr30.c.

Definition at line 737 of file elf32-fr30.c.

Definition at line 736 of file elf32-fr30.c.

Definition at line 735 of file elf32-fr30.c.

Definition at line 729 of file elf32-fr30.c.

#define ELF_MACHINE_CODE   EM_FR30

Definition at line 728 of file elf32-fr30.c.

#define ELF_MAXPAGESIZE   0x1000

Definition at line 730 of file elf32-fr30.c.

#define TARGET_BIG_NAME   "elf32-fr30"

Definition at line 733 of file elf32-fr30.c.

Definition at line 732 of file elf32-fr30.c.


Function Documentation

static bfd_boolean fr30_elf_check_relocs ( bfd abfd,
struct bfd_link_info info,
asection sec,
const Elf_Internal_Rela relocs 
) [static]

Definition at line 669 of file elf32-fr30.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_FR30_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_FR30_GNU_VTENTRY:
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
        }
    }

  return TRUE;
}

Here is the call graph for this function:

static asection* fr30_elf_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 647 of file elf32-fr30.c.

{
  if (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_FR30_GNU_VTINHERIT:
      case R_FR30_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_reloc_status_type fr30_elf_i20_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
PTR  data,
asection input_section,
bfd output_bfd,
error_message   
) [static]

Definition at line 246 of file elf32-fr30.c.

{
  bfd_vma relocation;
  unsigned long x;

  /* This part is from bfd_elf_generic_reloc.  */
  if (output_bfd != (bfd *) NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && (! reloc_entry->howto->partial_inplace
         || reloc_entry->addend == 0))
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }

  if (output_bfd != NULL)
    /* FIXME: See bfd_perform_relocation.  Is this right?  */
    return bfd_reloc_ok;

  relocation =
    symbol->value
    + symbol->section->output_section->vma
    + symbol->section->output_offset
    + reloc_entry->addend;

  if (relocation > (((bfd_vma) 1 << 20) - 1))
    return bfd_reloc_overflow;

  x = bfd_get_32 (abfd, (char *) data + reloc_entry->address);
  x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
  bfd_put_32 (abfd, (bfd_vma) x, (char *) data + reloc_entry->address);

  return bfd_reloc_ok;
}
static bfd_reloc_status_type fr30_elf_i32_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
PTR  data,
asection input_section,
bfd output_bfd,
error_message   
) [static]

Definition at line 292 of file elf32-fr30.c.

{
  bfd_vma relocation;

  /* This part is from bfd_elf_generic_reloc.  */
  if (output_bfd != (bfd *) NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && (! reloc_entry->howto->partial_inplace
         || reloc_entry->addend == 0))
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }

  if (output_bfd != NULL)
    /* FIXME: See bfd_perform_relocation.  Is this right?  */
    return bfd_reloc_ok;

  relocation =
    symbol->value
    + symbol->section->output_section->vma
    + symbol->section->output_offset
    + reloc_entry->addend;

  bfd_put_32 (abfd, relocation, (char *) data + reloc_entry->address + 2);

  return bfd_reloc_ok;
}
static bfd_boolean fr30_elf_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 512 of file elf32-fr30.c.

{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;

  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);
  relend     = relocs + input_section->reloc_count;

  for (rel = relocs; rel < relend; rel ++)
    {
      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;
      const char *name;
      int r_type;

      r_type = ELF32_R_TYPE (rel->r_info);

      if (   r_type == R_FR30_GNU_VTINHERIT
         || r_type == R_FR30_GNU_VTENTRY)
       continue;

      r_symndx = ELF32_R_SYM (rel->r_info);

      howto  = fr30_elf_howto_table + ELF32_R_TYPE (rel->r_info);
      h      = NULL;
      sym    = NULL;
      sec    = NULL;

      if (r_symndx < symtab_hdr->sh_info)
       {
         sym = local_syms + r_symndx;
         sec = local_sections [r_symndx];
         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);

         name = bfd_elf_string_from_elf_section
           (input_bfd, symtab_hdr->sh_link, sym->st_name);
         name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
       }
      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);

         name = h->root.root.string;
       }

      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;

      r = fr30_final_link_relocate (howto, input_bfd, input_section,
                                 contents, rel, relocation);

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

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

           case bfd_reloc_undefined:
             r = info->callbacks->undefined_symbol
              (info, name, input_bfd, input_section, rel->r_offset,
               TRUE);
             break;

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

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

           case bfd_reloc_dangerous:
             msg = _("internal error: dangerous relocation");
             break;

           default:
             msg = _("internal error: unknown error");
             break;
           }

         if (msg)
           r = info->callbacks->warning
             (info, msg, name, input_bfd, input_section, rel->r_offset);

         if (! r)
           return FALSE;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

static bfd_reloc_status_type fr30_final_link_relocate ( reloc_howto_type *  howto,
bfd input_bfd,
asection input_section,
bfd_byte contents,
Elf_Internal_Rela rel,
bfd_vma  relocation 
) [static]

Definition at line 403 of file elf32-fr30.c.

{
  bfd_reloc_status_type r = bfd_reloc_ok;
  bfd_vma x;
  bfd_signed_vma srel;

  switch (howto->type)
    {
    case R_FR30_20:
      contents   += rel->r_offset;
      relocation += rel->r_addend;

      if (relocation > ((1 << 20) - 1))
       return bfd_reloc_overflow;

      x = bfd_get_32 (input_bfd, contents);
      x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
      bfd_put_32 (input_bfd, x, contents);
      break;

    case R_FR30_48:
      contents   += rel->r_offset + 2;
      relocation += rel->r_addend;
      bfd_put_32 (input_bfd, relocation, contents);
      break;

    case R_FR30_9_PCREL:
      contents   += rel->r_offset + 1;
      srel = (bfd_signed_vma) relocation;
      srel += rel->r_addend;
      srel -= rel->r_offset;
      srel -= 2;  /* Branch instructions add 2 to the PC...  */
      srel -= (input_section->output_section->vma +
                   input_section->output_offset);

      if (srel & 1)
       return bfd_reloc_outofrange;
      if (srel > ((1 << 8) - 1) || (srel < - (1 << 8)))
       return bfd_reloc_overflow;

      bfd_put_8 (input_bfd, srel >> 1, contents);
      break;

    case R_FR30_12_PCREL:
      contents   += rel->r_offset;
      srel = (bfd_signed_vma) relocation;
      srel += rel->r_addend;
      srel -= rel->r_offset;
      srel -= 2; /* Branch instructions add 2 to the PC...  */
      srel -= (input_section->output_section->vma +
                   input_section->output_offset);

      if (srel & 1)
       return bfd_reloc_outofrange;
      if (srel > ((1 << 11) - 1) || (srel < - (1 << 11)))
         return bfd_reloc_overflow;

      x = bfd_get_16 (input_bfd, contents);
      x = (x & 0xf800) | ((srel >> 1) & 0x7ff);
      bfd_put_16 (input_bfd, x, contents);
      break;

    default:
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                contents, rel->r_offset,
                                relocation, rel->r_addend);
    }

  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fr30_info_to_howto_rela ( abfd  ,
arelent cache_ptr,
Elf_Internal_Rela dst 
) [static]

Definition at line 387 of file elf32-fr30.c.

{
  unsigned int r_type;

  r_type = ELF32_R_TYPE (dst->r_info);
  BFD_ASSERT (r_type < (unsigned int) R_FR30_max);
  cache_ptr->howto = & fr30_elf_howto_table [r_type];
}
static reloc_howto_type* fr30_reloc_name_lookup ( bfd *abfd  ATTRIBUTE_UNUSED,
const char *  r_name 
) [static]

Definition at line 370 of file elf32-fr30.c.

{
  unsigned int i;

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

  return NULL;
}

Here is the call graph for this function:

static reloc_howto_type* fr30_reloc_type_lookup ( abfd  ,
bfd_reloc_code_real_type  code 
) [static]

Definition at line 355 of file elf32-fr30.c.

{
  unsigned int i;

  for (i = sizeof (fr30_reloc_map) / sizeof (fr30_reloc_map[0]);
       --i;)
    if (fr30_reloc_map [i].bfd_reloc_val == code)
      return & fr30_elf_howto_table [fr30_reloc_map[i].fr30_reloc_val];

  return NULL;
}
static bfd_reloc_status_type fr30_elf_i20_reloc PARAMS ( (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)  ) [static]
static reloc_howto_type* fr30_reloc_type_lookup PARAMS ( (bfd *abfd, bfd_reloc_code_real_type code ) [static]
static void fr30_info_to_howto_rela PARAMS ( (bfd *, arelent *, Elf_Internal_Rela *)  ) [static]
static bfd_boolean fr30_elf_relocate_section PARAMS ( (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)  ) [static]
static bfd_reloc_status_type fr30_final_link_relocate PARAMS ( (reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma ) [static]

Variable Documentation

reloc_howto_type fr30_elf_howto_table[] [static]

Definition at line 46 of file elf32-fr30.c.

struct fr30_reloc_map[] [static]
Initial value:
{
  { BFD_RELOC_NONE,           R_FR30_NONE },
  { BFD_RELOC_8,              R_FR30_8 },
  { BFD_RELOC_FR30_20,        R_FR30_20 },
  { BFD_RELOC_32,             R_FR30_32 },
  { BFD_RELOC_FR30_48,        R_FR30_48 },
  { BFD_RELOC_FR30_6_IN_4,    R_FR30_6_IN_4 },
  { BFD_RELOC_FR30_8_IN_8,    R_FR30_8_IN_8 },
  { BFD_RELOC_FR30_9_IN_8,    R_FR30_9_IN_8 },
  { BFD_RELOC_FR30_10_IN_8,   R_FR30_10_IN_8 },
  { BFD_RELOC_FR30_9_PCREL,   R_FR30_9_PCREL },
  { BFD_RELOC_FR30_12_PCREL,  R_FR30_12_PCREL },
  { BFD_RELOC_VTABLE_INHERIT, R_FR30_GNU_VTINHERIT },
  { BFD_RELOC_VTABLE_ENTRY,   R_FR30_GNU_VTENTRY },
}

Definition at line 337 of file elf32-fr30.c.