bfd/
[platform/upstream/binutils.git] / bfd / elf32-sh.c
index e1d7e1a..a5aa4ff 100644 (file)
@@ -50,8 +50,10 @@ static bfd_boolean sh_elf_relax_delete_bytes
   (bfd *, asection *, bfd_vma, int);
 static bfd_boolean sh_elf_align_loads
   (bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_boolean *);
+#ifndef SH64_ELF
 static bfd_boolean sh_elf_swap_insns
   (bfd *, asection *, void *, bfd_byte *, bfd_vma);
+#endif
 static bfd_boolean sh_elf_relocate_section
   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
    Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
@@ -107,10 +109,12 @@ static enum elf_reloc_type_class sh_elf_reloc_type_class
 #ifdef INCLUDE_SHMEDIA
 inline static void movi_shori_putval (bfd *, unsigned long, char *);
 #endif
+#if !defined SH_TARGET_ALREADY_DEFINED
 static bfd_boolean elf32_shlin_grok_prstatus
   (bfd *abfd, Elf_Internal_Note *note);
 static bfd_boolean elf32_shlin_grok_psinfo
   (bfd *abfd, Elf_Internal_Note *note);
+#endif
 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
@@ -2238,8 +2242,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
       laddr = irel->r_offset + 4 + irel->r_addend;
       if (laddr >= sec->size)
        {
-         (*_bfd_error_handler) (_("%s: 0x%lx: warning: bad R_SH_USES offset"),
-                                bfd_archive_filename (abfd),
+         (*_bfd_error_handler) (_("%B: 0x%lx: warning: bad R_SH_USES offset"),
+                                abfd,
                                 (unsigned long) irel->r_offset);
          continue;
        }
@@ -2250,8 +2254,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
       if ((insn & 0xf000) != 0xd000)
        {
          ((*_bfd_error_handler)
-          (_("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
-           bfd_archive_filename (abfd), (unsigned long) irel->r_offset, insn));
+          (_("%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
+           abfd, (unsigned long) irel->r_offset, insn));
          continue;
        }
 
@@ -2267,8 +2271,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
       if (paddr >= sec->size)
        {
          ((*_bfd_error_handler)
-          (_("%s: 0x%lx: warning: bad R_SH_USES load offset"),
-           bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
+          (_("%B: 0x%lx: warning: bad R_SH_USES load offset"),
+           abfd, (unsigned long) irel->r_offset));
          continue;
        }
 
@@ -2282,8 +2286,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
       if (irelfn >= irelend)
        {
          ((*_bfd_error_handler)
-          (_("%s: 0x%lx: warning: could not find expected reloc"),
-           bfd_archive_filename (abfd), (unsigned long) paddr));
+          (_("%B: 0x%lx: warning: could not find expected reloc"),
+           abfd, (unsigned long) paddr));
          continue;
        }
 
@@ -2310,8 +2314,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
              != (unsigned int) _bfd_elf_section_from_bfd_section (abfd, sec))
            {
              ((*_bfd_error_handler)
-              (_("%s: 0x%lx: warning: symbol in unexpected section"),
-               bfd_archive_filename (abfd), (unsigned long) paddr));
+              (_("%B: 0x%lx: warning: symbol in unexpected section"),
+               abfd, (unsigned long) paddr));
              continue;
            }
 
@@ -2435,8 +2439,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
       if (irelcount >= irelend)
        {
          ((*_bfd_error_handler)
-          (_("%s: 0x%lx: warning: could not find expected COUNT reloc"),
-           bfd_archive_filename (abfd), (unsigned long) paddr));
+          (_("%B: 0x%lx: warning: could not find expected COUNT reloc"),
+           abfd, (unsigned long) paddr));
          continue;
        }
 
@@ -2444,8 +2448,8 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
         just deleted one.  */
       if (irelcount->r_addend == 0)
        {
-         ((*_bfd_error_handler) (_("%s: 0x%lx: warning: bad count"),
-                                 bfd_archive_filename (abfd),
+         ((*_bfd_error_handler) (_("%B: 0x%lx: warning: bad count"),
+                                 abfd,
                                  (unsigned long) paddr));
          continue;
        }
@@ -2839,8 +2843,8 @@ sh_elf_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr,
          if (overflow)
            {
              ((*_bfd_error_handler)
-              (_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
-               bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
+              (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
+               abfd, (unsigned long) irel->r_offset));
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -3090,6 +3094,7 @@ sh_elf_align_loads (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
   return FALSE;
 }
 
+#ifndef SH64_ELF
 /* Swap two SH instructions.  This is like sh_swap_insns in coff-sh.c.  */
 
 static bfd_boolean
@@ -3208,8 +3213,8 @@ sh_elf_swap_insns (bfd *abfd, asection *sec, void *relocs,
          if (overflow)
            {
              ((*_bfd_error_handler)
-              (_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
-               bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
+              (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
+               abfd, (unsigned long) irel->r_offset));
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -3218,6 +3223,7 @@ sh_elf_swap_insns (bfd *abfd, asection *sec, void *relocs,
 
   return TRUE;
 }
+#endif /* defined SH64_ELF */
 \f
 #ifdef INCLUDE_SHMEDIA
 
@@ -4789,9 +4795,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              if (howto->rightshift || howto->src_mask != 0xffffffff)
                {
                  (*_bfd_error_handler)
-                   (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"),
-                    bfd_archive_filename (input_bfd),
-                    bfd_get_section_name (input_bfd, input_section),
+                   (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
+                    input_bfd, input_section,
                     (long) rel->r_offset, howto->name);
                  return FALSE;
                }
@@ -4894,9 +4899,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              else if (sec->output_section == NULL)
                {
                  (*_bfd_error_handler)
-                   (_("%s: unresolvable relocation against symbol `%s' from %s section"),
-                    bfd_archive_filename (input_bfd), h->root.root.string,
-                    bfd_get_section_name (input_bfd, input_section));
+                   (_("%B(%A): unresolvable relocation against symbol `%s'"),
+                    input_bfd, input_section, h->root.root.string);
                  return FALSE;
                }
              else
@@ -4965,8 +4969,8 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              if (disp & mask)
                {
                  ((*_bfd_error_handler)
-                  (_("%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
-                   bfd_archive_filename (input_section->owner),
+                  (_("%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
+                   input_section->owner,
                    (unsigned long) rel->r_offset));
                  bfd_set_error (bfd_error_bad_value);
                  return FALSE;
@@ -4998,10 +5002,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          if (relocation & 3)
            {
              ((*_bfd_error_handler)
-              (_("%s: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
-               bfd_archive_filename (input_section->owner),
+              (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
+               input_section->owner,
                (unsigned long) rel->r_offset, howto->name, 
-               (unsigned long)relocation));
+               (unsigned long) relocation));
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -5013,10 +5017,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          if (relocation & 1)
            {
              ((*_bfd_error_handler)
-              (_("%s: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
-               bfd_archive_filename (input_section->owner),
+              (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
+               input_section->owner,
                (unsigned long) rel->r_offset, howto->name, 
-               (unsigned long)relocation));
+               (unsigned long) relocation));
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -5027,10 +5031,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              || (signed int)relocation > 32)
            {
              ((*_bfd_error_handler)
-              (_("%s: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"),
-               bfd_archive_filename (input_section->owner),
+              (_("%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"),
+               input_section->owner,
                (unsigned long) rel->r_offset,
-               (unsigned long)relocation));
+               (unsigned long) relocation));
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -5041,10 +5045,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              || (signed int)relocation > 16)
            {
              ((*_bfd_error_handler)
-              (_("%s: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"),
-               bfd_archive_filename (input_section->owner),
+              (_("%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"),
+               input_section->owner,
                (unsigned long) rel->r_offset,
-               (unsigned long)relocation));
+               (unsigned long) relocation));
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -6571,8 +6575,8 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
              else
                {
                  (*_bfd_error_handler)
-                   (_("%s: `%s' accessed both as normal and thread local symbol"),
-                    bfd_archive_filename (abfd), h->root.root.string);
+                   (_("%B: `%s' accessed both as normal and thread local symbol"),
+                    abfd, h->root.root.string);
                  return FALSE;
                }
            }
@@ -6783,8 +6787,9 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
        case R_SH_TLS_LE_32:
          if (info->shared)
            {
-             (*_bfd_error_handler) (_("%s: TLS local exec code cannot be linked into shared objects"),
-                                    bfd_archive_filename (abfd));
+             (*_bfd_error_handler)
+               (_("%B: TLS local exec code cannot be linked into shared objects"),
+                abfd);
              return FALSE;
            }
 
@@ -6876,21 +6881,24 @@ sh_elf_copy_private_data (bfd * ibfd, bfd * obfd)
 
 /* This function returns the ELF architecture number that
    corresponds to the given arch_sh* flags.  */
+
 int
 sh_find_elf_flags (unsigned int arch_set)
 {
+  extern unsigned long sh_get_bfd_mach_from_arch_set (unsigned int);
   unsigned long bfd_mach = sh_get_bfd_mach_from_arch_set (arch_set);
 
   return sh_elf_get_flags_from_mach (bfd_mach);
 }
 
-
 /* This routine initialises the elf flags when required and
    calls sh_merge_bfd_arch() to check dsp/fpu compatibility.  */
 
 static bfd_boolean
 sh_elf_merge_private_data (bfd *ibfd, bfd *obfd)
 {
+  extern bfd_boolean sh_merge_bfd_arch (bfd *, bfd *);
+
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
@@ -6903,8 +6911,14 @@ sh_elf_merge_private_data (bfd *ibfd, bfd *obfd)
       sh_elf_set_mach_from_flags (obfd);
     }
 
-  if ( ! sh_merge_bfd_arch (ibfd, obfd) )
-    return FALSE;
+  if (! sh_merge_bfd_arch (ibfd, obfd))
+    {
+      _bfd_error_handler ("%B: uses instructions which are incompatible "
+                         "with instructions used in previous modules",
+                         ibfd);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
 
   elf_elfheader (obfd)->e_flags =
     sh_elf_get_flags_from_mach (bfd_get_mach (obfd));
@@ -7383,7 +7397,9 @@ sh_elf_reloc_type_class (const Elf_Internal_Rela *rela)
     }
 }
 
+#if !defined SH_TARGET_ALREADY_DEFINED
 /* Support for Linux core dump NOTE sections.  */
+
 static bfd_boolean
 elf32_shlin_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 {
@@ -7443,6 +7459,7 @@ elf32_shlin_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+#endif /* not SH_TARGET_ALREADY_DEFINED */
 
  
 /* Return address for Ith PLT stub in section PLT, for relocation REL
@@ -7455,10 +7472,13 @@ sh_elf_plt_sym_val (bfd_vma i, const asection *plt,
   return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
 }
 
+#if !defined SH_TARGET_ALREADY_DEFINED
 #define TARGET_BIG_SYM         bfd_elf32_sh_vec
 #define TARGET_BIG_NAME                "elf32-sh"
 #define TARGET_LITTLE_SYM      bfd_elf32_shl_vec
 #define TARGET_LITTLE_NAME     "elf32-shl"
+#endif
+
 #define ELF_ARCH               bfd_arch_sh
 #define ELF_MACHINE_CODE       EM_SH
 #ifdef __QNXTARGET__
@@ -7511,7 +7531,7 @@ sh_elf_plt_sym_val (bfd_vma i, const asection *plt,
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    12
 
-#ifndef INCLUDE_SHMEDIA
+#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED
 
 #include "elf32-target.h"
 
@@ -7553,4 +7573,4 @@ sh_elf_plt_sym_val (bfd_vma i, const asection *plt,
 
 #include "elf32-target.h"
 
-#endif /* INCLUDE_SHMEDIA */
+#endif /* neither INCLUDE_SHMEDIA nor SH_TARGET_ALREADY_DEFINED */