2000-12-07 Kazu Hirata <kazu@hxi.com>
[binutils-gdb.git] / bfd / elf32-arm.h
index 1baee0fc24d41c43157f5d9f4916d691eb5ecbb7..52dc7563c401cfb4668150aadc3687409910c755 100644 (file)
@@ -17,7 +17,6 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-
 typedef unsigned long int insn32;
 typedef unsigned short int insn16;
 
@@ -159,7 +158,6 @@ struct elf32_arm_link_hash_table
   int no_pipeline_knowledge;
 };
 
-
 /* Create an entry in an ARM ELF linker hash table.  */
 
 static struct bfd_hash_entry *
@@ -682,7 +680,7 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
                }
            }
 
-         /* If the relocation is not against a symbol it cannot concern us. */
+         /* If the relocation is not against a symbol it cannot concern us.  */
          h = NULL;
 
          /* We don't care about local symbols.  */
@@ -1479,7 +1477,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                                       (bfd_vma) 0);
 
     case R_ARM_GOTPC:
-      /* Use global offset table as symbol value. */
+      /* Use global offset table as symbol value.  */
       BFD_ASSERT (sgot != NULL);
 
       if (sgot == NULL)
@@ -1907,10 +1905,15 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
          switch (r)
            {
            case bfd_reloc_overflow:
-             if (!((*info->callbacks->reloc_overflow)
-                   (info, name, howto->name, (bfd_vma) 0,
-                    input_bfd, input_section, rel->r_offset)))
-               return false;
+             /* If the overflowing reloc was to an undefined symbol,
+                we have already printed one error message and there
+                is no point complaining again.  */
+             if ((! h ||
+                  h->root.type != bfd_link_hash_undefined)
+                 && (!((*info->callbacks->reloc_overflow)
+                       (info, name, howto->name, (bfd_vma) 0,
+                        input_bfd, input_section, rel->r_offset))))
+                 return false;
              break;
 
            case bfd_reloc_undefined:
@@ -2000,10 +2003,6 @@ elf32_arm_copy_private_bfd_data (ibfd, obfd)
       && EF_ARM_EABI_VERSION (out_flags) == EF_ARM_EABI_UNKNOWN
       && in_flags != out_flags)
     {
-      /* Cannot mix PIC and non-PIC code.  */
-      if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
-       return false;
-
       /* Cannot mix APCS26 and APCS32 code.  */
       if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
        return false;
@@ -2023,6 +2022,10 @@ Warning: Clearing the interwork flag in %s because non-interworking code in %s h
 
          in_flags &= ~EF_INTERWORK;
        }
+
+      /* Likewise for PIC, though don't warn for this case.  */
+      if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
+       in_flags &= ~EF_PIC;
     }
 
   elf_elfheader (obfd)->e_flags = in_flags;
@@ -2041,6 +2044,9 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
 {
   flagword out_flags;
   flagword in_flags;
+  boolean flags_compatible = true;
+  boolean null_input_bfd = true;
+  asection *sec;
 
   /* Check if we have the same endianess.  */
   if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
@@ -2081,10 +2087,26 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
       return true;
     }
 
-  /* Check flag compatibility.  */
+  /* Identical flags must be compatible.  */
   if (in_flags == out_flags)
     return true;
 
+  /* Check to see if the input BFD actually contains any sections.
+     If not, its flags may not have been initialised either, but it cannot
+     actually cause any incompatibility.  */
+  for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+    {
+      /* Ignore synthetic glue sections.  */
+      if (strcmp (sec->name, ".glue_7")
+         && strcmp (sec->name, ".glue_7t"))
+       {
+         null_input_bfd = false;
+         break;
+       }
+    }
+  if (null_input_bfd)
+    return true;
+
   /* Complain about various flag mismatches.  */
   if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_VERSION (out_flags))
     {
@@ -2094,47 +2116,58 @@ Error: %s compiled for EABI version %d, whereas %s is compiled for version %d"),
                         (in_flags & EF_ARM_EABIMASK) >> 24,
                         bfd_get_filename (obfd),
                         (out_flags & EF_ARM_EABIMASK) >> 24);
+      return false;
     }
-  else if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_UNKNOWN)
-    /* Not sure what needs to be checked for EABI versions >= 1.  */
-    return true;
 
-  if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
-    _bfd_error_handler (_("\
+  /* Not sure what needs to be checked for EABI versions >= 1.  */
+  if (EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
+    {
+      if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
+       {
+         _bfd_error_handler (_("\
 Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
                        bfd_get_filename (ibfd),
                        in_flags & EF_APCS_26 ? 26 : 32,
                        bfd_get_filename (obfd),
                        out_flags & EF_APCS_26 ? 26 : 32);
+         flags_compatible = false;
+       }
 
-  if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
-    _bfd_error_handler (_("\
+      if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
+       {
+         _bfd_error_handler (_("\
 Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
                        bfd_get_filename (ibfd),
                     in_flags & EF_APCS_FLOAT ? _("float") : _("integer"),
                        bfd_get_filename (obfd),
                      out_flags & EF_APCS_26 ? _("float") : _("integer"));
+         flags_compatible = false;
+       }
 
-  if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
-    _bfd_error_handler (_("\
-Error: %s is compiled as position %s code, whereas %s is not"),
-                       bfd_get_filename (ibfd),
-                   in_flags & EF_PIC ? _("independent") : _("dependent"),
-                       bfd_get_filename (obfd));
+#ifdef EF_SOFT_FLOAT
+      if ((in_flags & EF_SOFT_FLOAT) != (out_flags & EF_SOFT_FLOAT))
+       {
+         _bfd_error_handler (_ ("\
+Error: %s uses %s floating point, whereas %s uses %s floating point"),
+                             bfd_get_filename (ibfd),
+                             in_flags & EF_SOFT_FLOAT ? _("soft") : _("hard"),
+                             bfd_get_filename (obfd),
+                             out_flags & EF_SOFT_FLOAT ? _("soft") : _("hard"));
+         flags_compatible = false;
+       }
+#endif
 
-  /* Interworking mismatch is only a warning.  */
-  if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
-    {
-      _bfd_error_handler (_("\
+      /* Interworking mismatch is only a warning.  */
+      if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
+       _bfd_error_handler (_("\
 Warning: %s %s interworking, whereas %s %s"),
                          bfd_get_filename (ibfd),
          in_flags & EF_INTERWORK ? _("supports") : _("does not support"),
                          bfd_get_filename (obfd),
                    out_flags & EF_INTERWORK ? _("does not") : _("does"));
-      return true;
     }
 
-  return false;
+  return flags_compatible;
 }
 
 /* Display the flags field.  */
@@ -2586,7 +2619,6 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
   return true;
 }
 
-
 /* Find the nearest line to a particular section and offset, for error
    reporting.   This code is a duplicate of the code in elf.c, except
    that it also accepts STT_ARM_TFUNC as a symbol that names a function.  */
@@ -3331,12 +3363,10 @@ elf32_arm_post_process_headers (abfd, link_info)
   i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
 }
 
-
 #define ELF_ARCH                       bfd_arch_arm
 #define ELF_MACHINE_CODE               EM_ARM
 #define ELF_MAXPAGESIZE                        0x8000
 
-
 #define bfd_elf32_bfd_copy_private_bfd_data    elf32_arm_copy_private_bfd_data
 #define bfd_elf32_bfd_merge_private_bfd_data   elf32_arm_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags                elf32_arm_set_private_flags