Back to index

cell-binutils  2.17cvs20070401
Defines | Functions | Variables
elf32-mcore.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/mcore.h"
#include <assert.h>
#include "elf32-target.h"

Go to the source code of this file.

Defines

#define NUM_ELEM(a)   (sizeof (a) / sizeof (a)[0])
#define MCORE_INST_BSR   0xF800
#define TARGET_BIG_SYM   bfd_elf32_mcore_big_vec
#define TARGET_BIG_NAME   "elf32-mcore-big"
#define TARGET_LITTLE_SYM   bfd_elf32_mcore_little_vec
#define TARGET_LITTLE_NAME   "elf32-mcore-little"
#define ELF_ARCH   bfd_arch_mcore
#define ELF_MACHINE_CODE   EM_MCORE
#define ELF_MAXPAGESIZE   0x1000 /* 4k, if we ever have 'em */
#define elf_info_to_howto   mcore_elf_info_to_howto
#define elf_info_to_howto_rel   NULL
#define bfd_elf32_bfd_merge_private_bfd_data   mcore_elf_merge_private_bfd_data
#define bfd_elf32_bfd_set_private_flags   mcore_elf_set_private_flags
#define bfd_elf32_bfd_reloc_type_lookup   mcore_elf_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup   mcore_elf_reloc_name_lookup
#define elf_backend_relocate_section   mcore_elf_relocate_section
#define elf_backend_gc_mark_hook   mcore_elf_gc_mark_hook
#define elf_backend_gc_sweep_hook   mcore_elf_gc_sweep_hook
#define elf_backend_check_relocs   mcore_elf_check_relocs
#define elf_backend_special_sections   mcore_elf_special_sections
#define elf_backend_can_gc_sections   1
#define elf_backend_rela_normal   1

Functions

static bfd_boolean mcore_elf_set_private_flags (bfd *abfd, flagword flags)
static bfd_boolean mcore_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
static bfd_reloc_status_type mcore_elf_unsupported_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol ATTRIBUTE_UNUSED, PTR data ATTRIBUTE_UNUSED, asection *input_section ATTRIBUTE_UNUSED, bfd *output_bfd ATTRIBUTE_UNUSED, char **error_message ATTRIBUTE_UNUSED)
static void mcore_elf_howto_init (void)
static reloc_howto_type * mcore_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
static reloc_howto_type * mcore_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
static void mcore_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, Elf_Internal_Rela *dst)
static bfd_boolean mcore_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 asectionmcore_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 mcore_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
static bfd_boolean mcore_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)

Variables

static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max]
static reloc_howto_type mcore_elf_howto_raw []
static struct bfd_elf_special_section []

Define Documentation

Definition at line 667 of file elf32-mcore.c.

Definition at line 670 of file elf32-mcore.c.

Definition at line 669 of file elf32-mcore.c.

Definition at line 668 of file elf32-mcore.c.

#define ELF_ARCH   bfd_arch_mcore

Definition at line 661 of file elf32-mcore.c.

Definition at line 677 of file elf32-mcore.c.

Definition at line 674 of file elf32-mcore.c.

Definition at line 672 of file elf32-mcore.c.

Definition at line 673 of file elf32-mcore.c.

#define elf_backend_rela_normal   1

Definition at line 678 of file elf32-mcore.c.

Definition at line 671 of file elf32-mcore.c.

#define elf_backend_special_sections   mcore_elf_special_sections

Definition at line 675 of file elf32-mcore.c.

Definition at line 664 of file elf32-mcore.c.

Definition at line 665 of file elf32-mcore.c.

#define ELF_MACHINE_CODE   EM_MCORE

Definition at line 662 of file elf32-mcore.c.

#define ELF_MAXPAGESIZE   0x1000 /* 4k, if we ever have 'em */

Definition at line 663 of file elf32-mcore.c.

#define MCORE_INST_BSR   0xF800
#define NUM_ELEM (   a)    (sizeof (a) / sizeof (a)[0])

Definition at line 270 of file elf32-mcore.c.

#define TARGET_BIG_NAME   "elf32-mcore-big"

Definition at line 657 of file elf32-mcore.c.

Definition at line 656 of file elf32-mcore.c.

#define TARGET_LITTLE_NAME   "elf32-mcore-little"

Definition at line 659 of file elf32-mcore.c.

Definition at line 658 of file elf32-mcore.c.


Function Documentation

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

Definition at line 589 of file elf32-mcore.c.

{
  Elf_Internal_Shdr * symtab_hdr;
  struct elf_link_hash_entry ** sym_hashes;
  struct elf_link_hash_entry ** 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_MCORE_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_MCORE_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* mcore_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 556 of file elf32-mcore.c.

{
  if (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_MCORE_GNU_VTINHERIT:
      case R_MCORE_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 mcore_elf_gc_sweep_hook ( bfd *abfd  ATTRIBUTE_UNUSED,
struct bfd_link_info *info  ATTRIBUTE_UNUSED,
asection *sec  ATTRIBUTE_UNUSED,
const Elf_Internal_Rela *relocs  ATTRIBUTE_UNUSED 
) [static]

Definition at line 576 of file elf32-mcore.c.

{
  return TRUE;
}
static void mcore_elf_howto_init ( void  ) [static]

Definition at line 275 of file elf32-mcore.c.

{
  unsigned int i;

  for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
    {
      unsigned int type;

      type = mcore_elf_howto_raw[i].type;

      BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));

      mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
    }
}

Here is the caller graph for this function:

static void mcore_elf_info_to_howto ( bfd *abfd  ATTRIBUTE_UNUSED,
arelent cache_ptr,
Elf_Internal_Rela dst 
) [static]

Definition at line 339 of file elf32-mcore.c.

{
  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
    /* Initialize howto table if needed.  */
    mcore_elf_howto_init ();

  BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);

  cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
}

Here is the call graph for this function:

static bfd_boolean mcore_elf_merge_private_bfd_data ( bfd ibfd,
bfd obfd 
) [static]

Definition at line 52 of file elf32-mcore.c.

{
  flagword old_flags;
  flagword new_flags;

  /* Check if we have the same endianess.  */
  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
    return FALSE;

  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  new_flags = elf_elfheader (ibfd)->e_flags;
  old_flags = elf_elfheader (obfd)->e_flags;

  if (! elf_flags_init (obfd))
    {
       /* First call, no flags set.  */
      elf_flags_init (obfd) = TRUE;
      elf_elfheader (obfd)->e_flags = new_flags;
    }
  else if (new_flags == old_flags)
    /* Compatible flags are OK.  */
    ;
  else
    {
      /* FIXME */
    }

  return TRUE;
}

Here is the call graph for this function:

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

Definition at line 321 of file elf32-mcore.c.

{
  unsigned int i;

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

  return NULL;
}

Here is the call graph for this function:

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

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

{
  enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;

  switch (code)
    {
    case BFD_RELOC_NONE:                mcore_reloc = R_MCORE_NONE; break;
    case BFD_RELOC_32:                         mcore_reloc = R_MCORE_ADDR32; break;
    case BFD_RELOC_MCORE_PCREL_IMM8BY4:        mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
    case BFD_RELOC_MCORE_PCREL_IMM11BY2:     mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
    case BFD_RELOC_MCORE_PCREL_IMM4BY2:        mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
    case BFD_RELOC_32_PCREL:                   mcore_reloc = R_MCORE_PCREL32; break;
    case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
    case BFD_RELOC_VTABLE_INHERIT:           mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
    case BFD_RELOC_VTABLE_ENTRY:             mcore_reloc = R_MCORE_GNU_VTENTRY; break;
    case BFD_RELOC_RVA:                      mcore_reloc = R_MCORE_RELATIVE; break;
    default:
      return NULL;
    }

  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
    /* Initialize howto table if needed.  */
    mcore_elf_howto_init ();

  return mcore_elf_howto_table [(int) mcore_reloc];
};

Here is the call graph for this function:

static bfd_boolean mcore_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 382 of file elf32-mcore.c.

{
  Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
  struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
  Elf_Internal_Rela * rel = relocs;
  Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
  bfd_boolean ret = TRUE;

#ifdef DEBUG
  _bfd_error_handler
    ("mcore_elf_relocate_section called for %B section %A, %ld relocations%s",
     input_bfd,
     input_section,
     (long) input_section->reloc_count,
     (info->relocatable) ? " (relocatable)" : "");
#endif

  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])   /* Initialize howto table if needed */
    mcore_elf_howto_init ();

  for (; rel < relend; rel++)
    {
      enum elf_mcore_reloc_type    r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
      bfd_vma                      offset = rel->r_offset;
      bfd_vma                      addend = rel->r_addend;
      bfd_reloc_status_type        r = bfd_reloc_other;
      asection *                   sec = NULL;
      reloc_howto_type *           howto;
      bfd_vma                      relocation;
      Elf_Internal_Sym *           sym = NULL;
      unsigned long                r_symndx;
      struct elf_link_hash_entry * h = NULL;
      unsigned short               oldinst = 0;

      /* Unknown relocation handling.  */
      if ((unsigned) r_type >= (unsigned) R_MCORE_max
         || ! mcore_elf_howto_table [(int)r_type])
       {
         _bfd_error_handler (_("%B: Unknown relocation type %d\n"),
                           input_bfd, (int) r_type);

         bfd_set_error (bfd_error_bad_value);
         ret = FALSE;
         continue;
       }

      howto = mcore_elf_howto_table [(int) r_type];
      r_symndx = ELF32_R_SYM (rel->r_info);

      /* Complain about known relocation that are not yet supported.  */
      if (howto->special_function == mcore_elf_unsupported_reloc)
       {
         _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
                           input_bfd,
                           howto->name,
                           (int)r_type);

         bfd_set_error (bfd_error_bad_value);
         ret = FALSE;
         continue;
       }

      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);
         addend = rel->r_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;

      switch (r_type)
       {
       default:
         break;

       case R_MCORE_PCRELJSR_IMM11BY2:
         oldinst = bfd_get_16 (input_bfd, contents + offset);
#define       MCORE_INST_BSR       0xF800
         bfd_put_16 (input_bfd, (bfd_vma) MCORE_INST_BSR, contents + offset);
         break;
       }

#ifdef DEBUG
      fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
              howto->name, r_type, r_symndx, (long) offset, (long) addend);
#endif

      r = _bfd_final_link_relocate
       (howto, input_bfd, input_section, contents, offset, relocation, addend);

      if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
       {
         /* Wasn't ok, back it out and give up.  */
         bfd_put_16 (input_bfd, (bfd_vma) oldinst, contents + offset);
         r = bfd_reloc_ok;
       }

      if (r != bfd_reloc_ok)
       {
         ret = FALSE;

         switch (r)
           {
           default:
             break;

           case bfd_reloc_overflow:
             {
              const char * name;

              if (h != NULL)
                name = NULL;
              else
                {
                  name = bfd_elf_string_from_elf_section
                    (input_bfd, symtab_hdr->sh_link, sym->st_name);

                  if (name == NULL)
                    break;

                  if (* name == '\0')
                    name = bfd_section_name (input_bfd, sec);
                }

              (*info->callbacks->reloc_overflow)
                (info, (h ? &h->root : NULL), name, howto->name,
                 (bfd_vma) 0, input_bfd, input_section, offset);
             }
             break;
           }
       }
    }

#ifdef DEBUG
  fprintf (stderr, "\n");
#endif

  return ret;
}

Here is the call graph for this function:

static bfd_boolean mcore_elf_set_private_flags ( bfd abfd,
flagword  flags 
) [static]

Definition at line 38 of file elf32-mcore.c.

{
  BFD_ASSERT (! elf_flags_init (abfd)
             || elf_elfheader (abfd)->e_flags == flags);

  elf_elfheader (abfd)->e_flags = flags;
  elf_flags_init (abfd) = TRUE;
  return TRUE;
}
static bfd_reloc_status_type mcore_elf_unsupported_reloc ( bfd abfd,
arelent reloc_entry,
asymbol *symbol  ATTRIBUTE_UNUSED,
PTR data  ATTRIBUTE_UNUSED,
asection *input_section  ATTRIBUTE_UNUSED,
bfd *output_bfd  ATTRIBUTE_UNUSED,
char **error_message  ATTRIBUTE_UNUSED 
) [static]

Definition at line 88 of file elf32-mcore.c.

{
  BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);

  _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
                    abfd,
                    reloc_entry->howto->name,
                    reloc_entry->howto->type);

  return bfd_reloc_notsupported;
}

Here is the caller graph for this function:


Variable Documentation

Initial value:
{
  { STRING_COMMA_LEN (".ctors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".dtors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
  { NULL,                     0,  0, 0,            0 }
}

Definition at line 649 of file elf32-mcore.c.

reloc_howto_type mcore_elf_howto_raw[] [static]

Definition at line 108 of file elf32-mcore.c.

reloc_howto_type* mcore_elf_howto_table[(int) R_MCORE_max] [static]

Definition at line 106 of file elf32-mcore.c.