* bucomm.c (list_supported_targets): Use bfd_target_list.
[deliverable/binutils-gdb.git] / bfd / elf32-m68hc12.c
index a2bb760ce502ec53be3eefd17acb7926b66492ef..9ab8780574c86c9c479072cb8a488f7e754eecac 100644 (file)
@@ -27,20 +27,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "opcode/m68hc11.h"
 
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
-PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
+  PARAMS ((bfd *, bfd_reloc_code_real_type));
 static void m68hc11_info_to_howto_rel
-PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
 
 static bfd_reloc_status_type m68hc11_elf_ignore_reloc
-PARAMS ((bfd *abfd, arelent *reloc_entry,
-         asymbol *symbol, PTR data, asection *input_section,
-         bfd *output_bfd, char **error_message));
+  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 boolean elf32_m68hc11_gc_sweep_hook
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+          const Elf_Internal_Rela *));
+
+boolean _bfd_m68hc12_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+boolean _bfd_m68hc12_elf_set_private_flags PARAMS ((bfd *, flagword));
+boolean _bfd_m68hc12_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
+
+
+
 /* Use REL instead of RELA to save space */
 #define USE_REL
 
@@ -576,6 +588,177 @@ m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
   cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
 }
 
+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;
+{
+  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);
+
+  return NULL;
+}
+
+static 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;
+}
+
+\f
+/* Set and control ELF flags in ELF header.  */
+
+boolean
+_bfd_m68hc12_elf_set_private_flags (abfd, flags)
+     bfd *abfd;
+     flagword flags;
+{
+  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;
+}
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
+boolean
+_bfd_m68hc12_elf_merge_private_bfd_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  flagword old_flags;
+  flagword new_flags;
+  boolean ok = true;
+
+  /* Check if we have the same endianess */
+  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+    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)
+       (_("%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;
+    }
+  new_flags &= ~EF_M68HC11_ABI;
+  old_flags &= ~EF_M68HC11_ABI;
+
+  /* Warn about any other mismatches */
+  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;
+}
+
+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]"));
+
+  fputc ('\n', file);
+
+  return true;
+}
+
 /* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
    The Motorola spec says to use a different Elf machine code.  */
 #define ELF_ARCH               bfd_arch_m68hc12
@@ -587,7 +770,17 @@ m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
 
 #define elf_info_to_howto      0
 #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_object_p   0
 #define elf_backend_final_write_processing     0
+/* Disabled as this backend uses the generic linker.  */
+#define elf_backend_can_gc_sections            0
+
+#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
+#define bfd_elf32_bfd_print_private_bfd_data \
+                                       _bfd_m68hc12_elf_print_private_bfd_data
 
 #include "elf32-target.h"
This page took 0.025514 seconds and 4 git commands to generate.