2004-06-09 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / bfd / elf32-m68hc12.c
index 219fd6b0da331a371d0f452fa0c5f13f746defee..cfc265efd7332d2d2e36652cc8b5147810dcef0a 100644 (file)
@@ -1,5 +1,5 @@
 /* Motorola 68HC12-specific support for 32-bit ELF
-   Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
    Contributed by Stephane Carrez (stcarrez@nerim.fr)
    (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
 
@@ -21,49 +21,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
+#include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
+#include "elf32-m68hc1x.h"
 #include "elf/m68hc11.h"
 #include "opcode/m68hc11.h"
 
+/* Relocation functions.  */
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
-  PARAMS ((bfd *, bfd_reloc_code_real_type));
+  (bfd *, bfd_reloc_code_real_type);
 static void m68hc11_info_to_howto_rel
-  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
-
-static bfd_reloc_status_type m68hc11_elf_ignore_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static bfd_reloc_status_type m68hc12_elf_special_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static int m68hc12_addr_is_banked PARAMS ((bfd_vma));
-static bfd_vma m68hc12_phys_addr PARAMS ((bfd_vma));
-static bfd_vma m68hc12_phys_page PARAMS ((bfd_vma));
-
-/* GC mark and sweep.  */
-static asection *elf32_m68hc11_gc_mark_hook
-  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-          struct elf_link_hash_entry *, Elf_Internal_Sym *));
-static bfd_boolean elf32_m68hc11_gc_sweep_hook
-  PARAMS ((bfd *, struct bfd_link_info *, asection *,
-          const Elf_Internal_Rela *));
-
-static bfd_boolean m68hc12_elf_set_mach_from_flags PARAMS ((bfd *));
-
-bfd_boolean _bfd_m68hc12_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
-bfd_boolean _bfd_m68hc12_elf_set_private_flags PARAMS ((bfd *, flagword));
-bfd_boolean _bfd_m68hc12_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
+  (bfd *, arelent *, Elf_Internal_Rela *);
 
+/* Trampoline generation.  */
+static bfd_boolean m68hc12_elf_size_one_stub
+  (struct bfd_hash_entry *gen_entry, void *in_arg);
+static bfd_boolean m68hc12_elf_build_one_stub
+  (struct bfd_hash_entry *gen_entry, void *in_arg);
+static struct bfd_link_hash_table* m68hc12_elf_bfd_link_hash_table_create
+  (bfd*);
 
+static bfd_boolean m68hc12_elf_set_mach_from_flags PARAMS ((bfd *));
 
 /* Use REL instead of RELA to save space */
 #define USE_REL        1
 
-/* The Motorola 68HC11 microcontroler only addresses 64Kb.
-   We must handle 8 and 16-bit relocations.  The 32-bit relocation
-   is defined but not used except by gas when -gstabs is used (which
-   is wrong).
-
-   The 68HC12 microcontroler has a memory bank switching system
+/* The 68HC12 microcontroler has a memory bank switching system
    with a 16Kb window in the 64Kb address space.  The extended memory
    is mapped in the 16Kb window (at 0x8000).  The page register controls
    which 16Kb bank is mapped.  The call/rtc instructions take care of
@@ -199,7 +183,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0x00ff,                /* src_mask */
         0x00ff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* A 16 bit absolute relocation */
   HOWTO (R_M68HC11_16,         /* type */
@@ -209,7 +193,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
-        m68hc12_elf_special_reloc,     /* special_function */
+        bfd_elf_generic_reloc, /* special_function */
         "R_M68HC12_16",        /* name */
         FALSE,                 /* partial_inplace */
         0xffff,                /* src_mask */
@@ -260,7 +244,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0xffff,                /* src_mask */
         0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* GNU extension to record C++ vtable hierarchy */
   HOWTO (R_M68HC11_GNU_VTINHERIT,      /* type */
@@ -295,16 +279,16 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
   /* A 24 bit relocation */
   HOWTO (R_M68HC11_24,         /* type */
         0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
         24,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
-        m68hc12_elf_special_reloc,     /* special_function */
+        m68hc11_elf_special_reloc,     /* special_function */
         "R_M68HC12_24",        /* name */
         FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        0xffffff,              /* src_mask */
+        0xffffff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* A 16-bit low relocation */
@@ -315,7 +299,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
-        m68hc12_elf_special_reloc,/* special_function */
+        m68hc11_elf_special_reloc,/* special_function */
         "R_M68HC12_LO16",      /* name */
         FALSE,                 /* partial_inplace */
         0xffff,                /* src_mask */
@@ -330,7 +314,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,        /* complain_on_overflow */
-        m68hc12_elf_special_reloc,/* special_function */
+        m68hc11_elf_special_reloc,/* special_function */
         "R_M68HC12_PAGE",      /* name */
         FALSE,                 /* partial_inplace */
         0x00ff,                /* src_mask */
@@ -406,9 +390,8 @@ static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
 };
 
 static reloc_howto_type *
-bfd_elf32_bfd_reloc_type_lookup (abfd, code)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     bfd_reloc_code_real_type code;
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                 bfd_reloc_code_real_type code)
 {
   unsigned int i;
 
@@ -423,221 +406,109 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
   return NULL;
 }
 
-/* This function is used for relocs which are only used for relaxing,
-   which the linker should otherwise ignore.  */
-
-static bfd_reloc_status_type
-m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
-                          output_bfd, error_message)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *reloc_entry;
-     asymbol *symbol ATTRIBUTE_UNUSED;
-     PTR data ATTRIBUTE_UNUSED;
-     asection *input_section;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
-{
-  if (output_bfd != NULL)
-    reloc_entry->address += input_section->output_offset;
-  return bfd_reloc_ok;
-}
+/* Set the howto pointer for an M68HC11 ELF reloc.  */
 
-static int
-m68hc12_addr_is_banked (addr)
-     bfd_vma addr;
+static void
+m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+                           arelent *cache_ptr, Elf_Internal_Rela *dst)
 {
-   return (addr >= M68HC12_BANK_VIRT) ? 1 : 0;
-}
+  unsigned int r_type;
 
-/* Return the physical address seen by the processor, taking
-   into account banked memory.  */
-static bfd_vma
-m68hc12_phys_addr (addr)
-     bfd_vma addr;
-{
-  if (addr < M68HC12_BANK_VIRT)
-    return addr;
-
-  /* Map the address to the memory bank.  */
-  addr -= M68HC12_BANK_VIRT;
-  addr &= M68HC12_BANK_MASK;
-  addr += M68HC12_BANK_BASE;
-  return addr;
+  r_type = ELF32_R_TYPE (dst->r_info);
+  BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
+  cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
 }
 
-/* Return the page number corresponding to an address in banked memory.  */
-static bfd_vma
-m68hc12_phys_page (addr)
-     bfd_vma addr;
-{
-  if (addr < M68HC12_BANK_VIRT)
-    return 0;
-
-  /* Map the address to the memory bank.  */
-  addr -= M68HC12_BANK_VIRT;
-  addr >>= M68HC12_BANK_SHIFT;
-  addr &= M68HC12_BANK_PAGE_MASK;
-  return addr;
-}
+\f
+/* Far trampoline generation.  */
 
-static bfd_reloc_status_type
-m68hc12_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section,
-                           output_bfd, error_message)
-     bfd *abfd;
-     arelent *reloc_entry;
-     asymbol *symbol;
-     PTR data;
-     asection *input_section;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+/* Build a 68HC12 trampoline stub.  */
+static bfd_boolean
+m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 {
-  reloc_howto_type *howto;
-  bfd_vma relocation;
-  bfd_vma phys_addr;
-  bfd_vma phys_page;
-  bfd_vma insn_page;
-  bfd_vma insn_addr;
-
-  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;
-    }
+  struct elf32_m68hc11_stub_hash_entry *stub_entry;
+  struct bfd_link_info *info;
+  struct m68hc11_elf_link_hash_table *htab;
+  asection *stub_sec;
+  bfd *stub_bfd;
+  bfd_byte *loc;
+  bfd_vma sym_value, phys_page, phys_addr;
 
-  if (output_bfd != NULL)
-    return bfd_reloc_continue;
+  /* Massage our args to the form they really have.  */
+  stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
+  info = (struct bfd_link_info *) in_arg;
 
-  if (reloc_entry->address > input_section->_cooked_size)
-    return bfd_reloc_outofrange;
+  htab = m68hc11_elf_hash_table (info);
 
-  /* Compute relocation.  */
-  relocation = (symbol->value
-               + symbol->section->output_section->vma
-               + symbol->section->output_offset);
-  relocation += reloc_entry->addend;
-  relocation += bfd_get_16 (abfd, (bfd_byte*) data + reloc_entry->address);
+  stub_sec = stub_entry->stub_sec;
 
-  /* Do the memory bank mapping.  */
-  phys_addr = m68hc12_phys_addr (relocation);
-  phys_page = m68hc12_phys_page (relocation);
+  /* Make a note of the offset within the stubs for this entry.  */
+  stub_entry->stub_offset = stub_sec->_raw_size;
+  stub_sec->_raw_size += 7;
+  loc = stub_sec->contents + stub_entry->stub_offset;
 
-  howto = reloc_entry->howto;
-  if (howto->complain_on_overflow != complain_overflow_dont
-      && (phys_addr & (((bfd_vma) -1) << 16)))
-     return bfd_reloc_overflow;
+  stub_bfd = stub_sec->owner;
 
-  switch (howto->type)
-    {
-    case R_M68HC11_16:
-          /* Get virtual address of instruction having the relocation.  */
-       insn_addr = input_section->output_section->vma
-          + input_section->output_offset
-          + reloc_entry->address;
-
-      insn_page = m68hc12_phys_page (insn_addr);
-
-      if (m68hc12_addr_is_banked (relocation)
-          && m68hc12_addr_is_banked (insn_addr)
-          && phys_page != insn_page)
-         {
-            *error_message = _("address is not in the same bank");
-            return bfd_reloc_dangerous;
-         }
-      if (m68hc12_addr_is_banked (relocation)
-          && !m68hc12_addr_is_banked (insn_addr))
-         {
-            *error_message = _("reference to a banked address in "
-                               "the normal address space");
-            return bfd_reloc_dangerous;
-         }
-
-    case R_M68HC11_LO16:
-      bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
-      break;
+  /* Create the trampoline call stub:
 
-    case R_M68HC11_24:
-      bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
-      bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address + 2);
-      break;
+     ldy #%addr(symbol)
+     call %page(symbol), __trampoline
 
-    case R_M68HC11_PAGE:
-      bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address);
-      break;
+  */
+  sym_value = (stub_entry->target_value
+               + stub_entry->target_section->output_offset
+               + stub_entry->target_section->output_section->vma);
+  phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
+  phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
 
-    default:
-       abort ();
-       break;
-    }
+  /* ldy #%page(sym) */
+  bfd_put_8 (stub_bfd, 0xCD, loc);
+  bfd_put_16 (stub_bfd, phys_addr, loc + 1);
+  loc += 3;
 
-  return bfd_reloc_ok;
+  /* call %page(sym), __trampoline  */
+  bfd_put_8 (stub_bfd, 0x4a, loc);
+  bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
+  bfd_put_8 (stub_bfd, phys_page, loc + 3);
+
+  return TRUE;
 }
 
-/* Set the howto pointer for an M68HC11 ELF reloc.  */
+/* As above, but don't actually build the stub.  Just bump offset so
+   we know stub section sizes.  */
 
-static void
-m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *cache_ptr;
-     Elf_Internal_Rela *dst;
+static bfd_boolean
+m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
+                           void *in_arg ATTRIBUTE_UNUSED)
 {
-  unsigned int r_type;
+  struct elf32_m68hc11_stub_hash_entry *stub_entry;
 
-  r_type = ELF32_R_TYPE (dst->r_info);
-  BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
-  cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
+  /* Massage our args to the form they really have.  */
+  stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
+
+  stub_entry->stub_sec->_raw_size += 7;
+  return TRUE;
 }
 
-static asection *
-elf32_m68hc11_gc_mark_hook (sec, info, rel, h, sym)
-     asection *sec;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     Elf_Internal_Rela *rel;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+/* Create a 68HC12 ELF linker hash table.  */
+
+static struct bfd_link_hash_table *
+m68hc12_elf_bfd_link_hash_table_create (bfd *abfd)
 {
-  if (h != NULL)
-    {
-      switch (ELF32_R_TYPE (rel->r_info))
-       {
-       default:
-         switch (h->root.type)
-           {
-           case bfd_link_hash_defined:
-           case bfd_link_hash_defweak:
-             return h->root.u.def.section;
-
-           case bfd_link_hash_common:
-             return h->root.u.c.p->section;
-
-           default:
-             break;
-           }
-       }
-    }
-  else
-    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+  struct m68hc11_elf_link_hash_table *ret;
 
-  return NULL;
-}
+  ret = m68hc11_elf_hash_table_create (abfd);
+  if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
+    return NULL;
 
-static bfd_boolean
-elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     asection *sec ATTRIBUTE_UNUSED;
-     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
-{
-  /* We don't use got and plt entries for 68hc11/68hc12.  */
-  return TRUE;
-}
+  ret->size_one_stub = m68hc12_elf_size_one_stub;
+  ret->build_one_stub = m68hc12_elf_build_one_stub;
 
+  return &ret->root.root;
+}
 \f
 static bfd_boolean
-m68hc12_elf_set_mach_from_flags (abfd)
-     bfd *abfd;
+m68hc12_elf_set_mach_from_flags (bfd *abfd)
 {
   flagword flags = elf_elfheader (abfd)->e_flags;
 
@@ -659,149 +530,20 @@ m68hc12_elf_set_mach_from_flags (abfd)
   return TRUE;
 }
 
-/* Set and control ELF flags in ELF header.  */
-
-bfd_boolean
-_bfd_m68hc12_elf_set_private_flags (abfd, flags)
-     bfd *abfd;
-     flagword flags;
+/* Specific sections:
+   - The .page0 is a data section that is mapped in [0x0000..0x00FF].
+     Page0 accesses are faster on the M68HC12.
+   - The .vectors is the section that represents the interrupt
+     vectors.  */
+static struct bfd_elf_special_section const elf32_m68hc12_special_sections[]=
 {
-  BFD_ASSERT (!elf_flags_init (abfd)
-             || elf_elfheader (abfd)->e_flags == flags);
-
-  elf_elfheader (abfd)->e_flags = flags;
-  elf_flags_init (abfd) = TRUE;
-  return m68hc12_elf_set_mach_from_flags (abfd);
-}
-
-/* Merge backend specific data from an object file to the output
-   object file when linking.  */
-
-bfd_boolean
-_bfd_m68hc12_elf_merge_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
-{
-  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;
-  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)
-       (_("%s: linking files compiled for 16-bit integers (-mshort) "
-           "and others for 32-bit integers"),
-        bfd_archive_filename (ibfd));
-      ok = FALSE;
-    }
-  if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
-    {
-      (*_bfd_error_handler)
-       (_("%s: linking files compiled for 32-bit double (-fshort-double) "
-           "and others for 64-bit double"),
-        bfd_archive_filename (ibfd));
-      ok = FALSE;
-    }
-
-  /* Processor compatibility.  */
-  if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
-    {
-      (*_bfd_error_handler)
-       (_("%s: linking files compiled for HCS12 with "
-           "others compiled for HC12"),
-        bfd_archive_filename (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;
-
-  /* Warn about any other mismatches */
-  new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
-  old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
-  if (new_flags != old_flags)
-    {
-      (*_bfd_error_handler)
-       (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
-        bfd_archive_filename (ibfd), (unsigned long) new_flags,
-        (unsigned long) old_flags);
-      ok = FALSE;
-    }
-
-  if (! ok)
-    {
-      bfd_set_error (bfd_error_bad_value);
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-bfd_boolean
-_bfd_m68hc12_elf_print_private_bfd_data (abfd, ptr)
-     bfd *abfd;
-     PTR ptr;
-{
-  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 (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
-    fprintf (file, _(" cpu=HCS12]"));
-  else
-    fprintf (file, _(" cpu=HC12]"));
-  fputc ('\n', file);
-
-  return TRUE;
-}
-
+  { ".eeprom",   7, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { ".softregs", 9, 0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
+  { ".page0",    6, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { ".vectors",  8, 0, SHT_PROGBITS, SHF_ALLOC },
+  { NULL,        0, 0, 0,            0 }
+};
+\f
 #define ELF_ARCH               bfd_arch_m68hc12
 #define ELF_MACHINE_CODE       EM_68HC12
 #define ELF_MAXPAGESIZE                0x1000
@@ -813,15 +555,23 @@ _bfd_m68hc12_elf_print_private_bfd_data (abfd, ptr)
 #define elf_info_to_howto_rel  m68hc11_info_to_howto_rel
 #define elf_backend_gc_mark_hook     elf32_m68hc11_gc_mark_hook
 #define elf_backend_gc_sweep_hook    elf32_m68hc11_gc_sweep_hook
+#define elf_backend_check_relocs     elf32_m68hc11_check_relocs
+#define elf_backend_relocate_section elf32_m68hc11_relocate_section
 #define elf_backend_object_p           m68hc12_elf_set_mach_from_flags
 #define elf_backend_final_write_processing     0
-/* Disabled as this backend uses the generic linker.  */
-#define elf_backend_can_gc_sections            0
-
+#define elf_backend_can_gc_sections            1
+#define elf_backend_special_sections elf32_m68hc12_special_sections
+#define elf_backend_post_process_headers     elf32_m68hc11_post_process_headers
+#define elf_backend_add_symbol_hook  elf32_m68hc11_add_symbol_hook
+
+#define bfd_elf32_bfd_link_hash_table_create \
+                                m68hc12_elf_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_free \
+                               m68hc11_elf_bfd_link_hash_table_free
 #define bfd_elf32_bfd_merge_private_bfd_data \
-                                       _bfd_m68hc12_elf_merge_private_bfd_data
-#define bfd_elf32_bfd_set_private_flags        _bfd_m68hc12_elf_set_private_flags
+                                       _bfd_m68hc11_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags        _bfd_m68hc11_elf_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data \
-                                       _bfd_m68hc12_elf_print_private_bfd_data
+                                       _bfd_m68hc11_elf_print_private_bfd_data
 
 #include "elf32-target.h"
This page took 0.034383 seconds and 4 git commands to generate.