Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions
elf32-m68hc1x.h File Reference
#include "elf-bfd.h"
#include "bfdlink.h"
#include "elf/m68hc11.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  elf32_m68hc11_stub_hash_entry
struct  m68hc11_page_info
struct  m68hc11_elf_link_hash_table

Defines

#define BFD_M68HC11_BANK_START_NAME   "__bank_start"
#define BFD_M68HC11_BANK_SIZE_NAME   "__bank_size"
#define BFD_M68HC11_BANK_VIRTUAL_NAME   "__bank_virtual"
#define m68hc11_elf_hash_table(p)   ((struct m68hc11_elf_link_hash_table *) ((p)->hash))

Functions

bfd_boolean _bfd_m68hc11_elf_merge_private_bfd_data (bfd *, bfd *)
bfd_boolean _bfd_m68hc11_elf_set_private_flags (bfd *, flagword)
bfd_boolean _bfd_m68hc11_elf_print_private_bfd_data (bfd *, void *)
struct
m68hc11_elf_link_hash_table
m68hc11_elf_hash_table_create (bfd *)
void m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *)
void m68hc11_elf_get_bank_parameters (struct bfd_link_info *)
int m68hc11_addr_is_banked (struct m68hc11_page_info *, bfd_vma)
bfd_vma m68hc11_phys_addr (struct m68hc11_page_info *, bfd_vma)
bfd_vma m68hc11_phys_page (struct m68hc11_page_info *, bfd_vma)
bfd_reloc_status_type m68hc11_elf_ignore_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data, asection *input_section, bfd *output_bfd, char **error_message)
bfd_reloc_status_type m68hc11_elf_special_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data, asection *input_section, bfd *output_bfd, char **error_message)
bfd_boolean elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs)
bfd_boolean elf32_m68hc11_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)
bfd_boolean elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *sym, const char **namep, flagword *flagsp, asection **secp, bfd_vma *valp)
void elf32_m68hc11_post_process_headers (bfd *, struct bfd_link_info *)
int elf32_m68hc11_setup_section_lists (bfd *, struct bfd_link_info *)
bfd_boolean elf32_m68hc11_size_stubs (bfd *, bfd *, struct bfd_link_info *, asection *(*)(const char *, asection *))
bfd_boolean elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *)

Class Documentation

struct elf32_m68hc11_stub_hash_entry

Definition at line 44 of file elf32-m68hc1x.h.

Collaboration diagram for elf32_m68hc11_stub_hash_entry:
Class Members
bfd_vma stub_offset
asection * stub_sec
asection * target_section
bfd_vma target_value
struct m68hc11_page_info

Definition at line 88 of file elf32-m68hc1x.h.

Class Members
bfd_vma bank_mask
int bank_param_initialized
bfd_vma bank_physical
bfd_vma bank_physical_end
int bank_shift
bfd_vma bank_size
bfd_vma bank_virtual
bfd_vma trampoline_addr

Define Documentation

#define BFD_M68HC11_BANK_SIZE_NAME   "__bank_size"

Definition at line 31 of file elf32-m68hc1x.h.

#define BFD_M68HC11_BANK_START_NAME   "__bank_start"

Definition at line 30 of file elf32-m68hc1x.h.

#define BFD_M68HC11_BANK_VIRTUAL_NAME   "__bank_virtual"

Definition at line 32 of file elf32-m68hc1x.h.

#define m68hc11_elf_hash_table (   p)    ((struct m68hc11_elf_link_hash_table *) ((p)->hash))

Definition at line 131 of file elf32-m68hc1x.h.


Function Documentation

Definition at line 1179 of file elf32-m68hc1x.c.

{
  flagword old_flags;
  flagword new_flags;
  bfd_boolean ok = TRUE;

  /* 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;
  elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
  old_flags = elf_elfheader (obfd)->e_flags;

  if (! elf_flags_init (obfd))
    {
      elf_flags_init (obfd) = TRUE;
      elf_elfheader (obfd)->e_flags = new_flags;
      elf_elfheader (obfd)->e_ident[EI_CLASS]
       = elf_elfheader (ibfd)->e_ident[EI_CLASS];

      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
         && bfd_get_arch_info (obfd)->the_default)
       {
         if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
                               bfd_get_mach (ibfd)))
           return FALSE;
       }

      return TRUE;
    }

  /* Check ABI compatibility.  */
  if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
    {
      (*_bfd_error_handler)
       (_("%B: linking files compiled for 16-bit integers (-mshort) "
           "and others for 32-bit integers"), ibfd);
      ok = FALSE;
    }
  if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
    {
      (*_bfd_error_handler)
       (_("%B: linking files compiled for 32-bit double (-fshort-double) "
           "and others for 64-bit double"), ibfd);
      ok = FALSE;
    }

  /* Processor compatibility.  */
  if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
    {
      (*_bfd_error_handler)
       (_("%B: linking files compiled for HCS12 with "
           "others compiled for HC12"), ibfd);
      ok = FALSE;
    }
  new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
               | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));

  elf_elfheader (obfd)->e_flags = new_flags;

  new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
  old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);

  /* Warn about any other mismatches */
  if (new_flags != old_flags)
    {
      (*_bfd_error_handler)
       (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
        ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
      ok = FALSE;
    }

  if (! ok)
    {
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 1266 of file elf32-m68hc1x.c.

{
  FILE *file = (FILE *) ptr;

  BFD_ASSERT (abfd != NULL && ptr != NULL);

  /* Print normal ELF private data.  */
  _bfd_elf_print_private_bfd_data (abfd, ptr);

  /* xgettext:c-format */
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);

  if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
    fprintf (file, _("[abi=32-bit int, "));
  else
    fprintf (file, _("[abi=16-bit int, "));

  if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
    fprintf (file, _("64-bit double, "));
  else
    fprintf (file, _("32-bit double, "));

  if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
    fprintf (file, _("cpu=HC11]"));
  else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
    fprintf (file, _("cpu=HCS12]"));
  else
    fprintf (file, _("cpu=HC12]"));    

  if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
    fprintf (file, _(" [memory=bank-model]"));
  else
    fprintf (file, _(" [memory=flat]"));

  fputc ('\n', file);

  return TRUE;
}

Here is the call graph for this function:

Definition at line 1165 of file elf32-m68hc1x.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;
}
bfd_boolean elf32_m68hc11_add_symbol_hook ( bfd abfd,
struct bfd_link_info info,
Elf_Internal_Sym *  sym,
const char **  namep,
flagword flagsp,
asection **  secp,
bfd_vma valp 
)

Definition at line 616 of file elf32-m68hc1x.c.

{
  asection *stub_sec;
  struct bfd_hash_table *table;
  struct m68hc11_elf_link_hash_table *htab;
  struct m68hc11_scan_param param;

  m68hc11_elf_get_bank_parameters (info);
  htab = m68hc11_elf_hash_table (info);

  for (stub_sec = htab->stub_bfd->sections;
       stub_sec != NULL;
       stub_sec = stub_sec->next)
    {
      bfd_size_type size;

      /* Allocate memory to hold the linker stubs.  */
      size = stub_sec->size;
      stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
      if (stub_sec->contents == NULL && size != 0)
       return FALSE;
      stub_sec->size = 0;
    }

  /* Build the stubs as directed by the stub hash table.  */
  table = htab->stub_hash_table;
  bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
  
  /* Scan the output sections to see if we use the memory banks.
     If so, export the symbols that define how the memory banks
     are mapped.  This is used by gdb and the simulator to obtain
     the information.  It can be used by programs to burn the eprom
     at the good addresses.  */
  param.use_memory_banks = FALSE;
  param.pinfo = &htab->pinfo;
  bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
  if (param.use_memory_banks)
    {
      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
                              htab->pinfo.bank_physical,
                              bfd_abs_section_ptr);
      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
                              htab->pinfo.bank_virtual,
                              bfd_abs_section_ptr);
      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
                              htab->pinfo.bank_size,
                              bfd_abs_section_ptr);
    }

  return TRUE;
}

Here is the call graph for this function:

Definition at line 818 of file elf32-m68hc1x.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_M68HC11_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_M68HC11_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:

Definition at line 1317 of file elf32-m68hc1x.c.

{
  struct m68hc11_scan_param param;

  if (link_info == 0)
    return;

  m68hc11_elf_get_bank_parameters (link_info);

  param.use_memory_banks = FALSE;
  param.pinfo = &m68hc11_elf_hash_table (link_info)->pinfo;
  bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
  if (param.use_memory_banks)
    {
      Elf_Internal_Ehdr * i_ehdrp;

      i_ehdrp = elf_elfheader (abfd);
      i_ehdrp->e_flags |= E_M68HC12_BANKS;
    }
}

Here is the call graph for this function:

bfd_boolean elf32_m68hc11_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 
)

Definition at line 221 of file elf32-m68hc1x.c.

{
  bfd *input_bfd;
  unsigned int bfd_count;
  int top_id, top_index;
  asection *section;
  asection **input_list, **list;
  bfd_size_type amt;
  asection *text_section;
  struct m68hc11_elf_link_hash_table *htab;

  htab = m68hc11_elf_hash_table (info);

  if (htab->root.root.creator->flavour != bfd_target_elf_flavour)
    return 0;

  /* Count the number of input BFDs and find the top input section id.
     Also search for an existing ".tramp" section so that we know
     where generated trampolines must go.  Default to ".text" if we
     can't find it.  */
  htab->tramp_section = 0;
  text_section = 0;
  for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
       input_bfd != NULL;
       input_bfd = input_bfd->link_next)
    {
      bfd_count += 1;
      for (section = input_bfd->sections;
          section != NULL;
          section = section->next)
       {
          const char* name = bfd_get_section_name (input_bfd, section);

          if (!strcmp (name, ".tramp"))
            htab->tramp_section = section;

          if (!strcmp (name, ".text"))
            text_section = section;

         if (top_id < section->id)
           top_id = section->id;
       }
    }
  htab->bfd_count = bfd_count;
  if (htab->tramp_section == 0)
    htab->tramp_section = text_section;

  /* We can't use output_bfd->section_count here to find the top output
     section index as some sections may have been removed, and
     strip_excluded_output_sections doesn't renumber the indices.  */
  for (section = output_bfd->sections, top_index = 0;
       section != NULL;
       section = section->next)
    {
      if (top_index < section->index)
       top_index = section->index;
    }

  htab->top_index = top_index;
  amt = sizeof (asection *) * (top_index + 1);
  input_list = (asection **) bfd_malloc (amt);
  htab->input_list = input_list;
  if (input_list == NULL)
    return -1;

  /* For sections we aren't interested in, mark their entries with a
     value we can check later.  */
  list = input_list + top_index;
  do
    *list = bfd_abs_section_ptr;
  while (list-- != input_list);

  for (section = output_bfd->sections;
       section != NULL;
       section = section->next)
    {
      if ((section->flags & SEC_CODE) != 0)
       input_list[section->index] = NULL;
    }

  return 1;
}

Here is the call graph for this function:

bfd_boolean elf32_m68hc11_size_stubs ( bfd ,
bfd ,
struct bfd_link_info ,
asection *)(const char *, asection * 
)

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

{
  if (addr >= pinfo->bank_virtual)
    return 1;

  if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
    return 1;

  return 0;
}

Here is the caller graph for this function:

Definition at line 104 of file elf32-m68hc1x.c.

Here is the call graph for this function:

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

{
  unsigned i;
  struct m68hc11_page_info *pinfo;
  struct bfd_link_hash_entry *h;

  pinfo = &m68hc11_elf_hash_table (info)->pinfo;
  if (pinfo->bank_param_initialized)
    return;

  pinfo->bank_virtual = M68HC12_BANK_VIRT;
  pinfo->bank_mask = M68HC12_BANK_MASK;
  pinfo->bank_physical = M68HC12_BANK_BASE;
  pinfo->bank_shift = M68HC12_BANK_SHIFT;
  pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;

  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
                            FALSE, FALSE, TRUE);
  if (h != (struct bfd_link_hash_entry*) NULL
      && h->type == bfd_link_hash_defined)
    pinfo->bank_physical = (h->u.def.value
                            + h->u.def.section->output_section->vma
                            + h->u.def.section->output_offset);

  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
                            FALSE, FALSE, TRUE);
  if (h != (struct bfd_link_hash_entry*) NULL
      && h->type == bfd_link_hash_defined)
    pinfo->bank_virtual = (h->u.def.value
                           + h->u.def.section->output_section->vma
                           + h->u.def.section->output_offset);

  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
                            FALSE, FALSE, TRUE);
  if (h != (struct bfd_link_hash_entry*) NULL
      && h->type == bfd_link_hash_defined)
    pinfo->bank_size = (h->u.def.value
                        + h->u.def.section->output_section->vma
                        + h->u.def.section->output_offset);

  pinfo->bank_shift = 0;
  for (i = pinfo->bank_size; i != 0; i >>= 1)
    pinfo->bank_shift++;
  pinfo->bank_shift--;
  pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
  pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
  pinfo->bank_param_initialized = 1;

  h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
                            FALSE, TRUE);
  if (h != (struct bfd_link_hash_entry*) NULL
      && h->type == bfd_link_hash_defined)
    pinfo->trampoline_addr = (h->u.def.value
                              + h->u.def.section->output_section->vma
                              + h->u.def.section->output_offset);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 63 of file elf32-m68hc1x.c.

{
  struct m68hc11_elf_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);

  ret = (struct m68hc11_elf_link_hash_table *) bfd_malloc (amt);
  if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
    return NULL;

  memset (ret, 0, amt);
  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
                                  _bfd_elf_link_hash_newfunc,
                                  sizeof (struct elf_link_hash_entry)))
    {
      free (ret);
      return NULL;
    }

  /* Init the stub hash table too.  */
  amt = sizeof (struct bfd_hash_table);
  ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
  if (ret->stub_hash_table == NULL)
    {
      free (ret);
      return NULL;
    }
  if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
                         sizeof (struct elf32_m68hc11_stub_hash_entry)))
    return NULL;

  ret->stub_bfd = NULL;
  ret->stub_section = 0;
  ret->add_stub_section = NULL;
  ret->sym_sec.abfd = NULL;

  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_reloc_status_type m68hc11_elf_ignore_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
void *  data,
asection input_section,
bfd output_bfd,
char **  error_message 
)
bfd_reloc_status_type m68hc11_elf_special_reloc ( bfd abfd,
arelent reloc_entry,
asymbol symbol,
void *  data,
asection input_section,
bfd output_bfd,
char **  error_message 
)

Definition at line 743 of file elf32-m68hc1x.c.

{
  if (addr < pinfo->bank_virtual)
    return addr;

  /* Map the address to the memory bank.  */
  addr -= pinfo->bank_virtual;
  addr &= pinfo->bank_mask;
  addr += pinfo->bank_physical;
  return addr;
}

Here is the caller graph for this function:

Definition at line 757 of file elf32-m68hc1x.c.

{
  if (addr < pinfo->bank_virtual)
    return 0;

  /* Map the address to the memory bank.  */
  addr -= pinfo->bank_virtual;
  addr >>= pinfo->bank_shift;
  addr &= 0x0ff;
  return addr;
}

Here is the caller graph for this function: