Fri Oct 24 11:15:58 1997 Jakub Jelinek <jj@sunsite.mff.cuni.cz>
authorRichard Henderson <rth@redhat.com>
Fri, 24 Oct 1997 18:14:52 +0000 (18:14 +0000)
committerRichard Henderson <rth@redhat.com>
Fri, 24 Oct 1997 18:14:52 +0000 (18:14 +0000)
        * elf64-sparc.c (sparc64_elf_merge_private_bfd_data):
        New function. Avoid mixing US1 and HAL R1 code.
        Set resulting memory ordering to the strongest one used.
        (sparc64_elf_object_p): Set bfd_mach correctly.

bfd/ChangeLog
bfd/elf64-sparc.c

index e124f92e72c63e3a4c2d689d17c98d8775b3d63c..0ef8a0983bb71ced019e07bf7cf161194fb96678 100644 (file)
@@ -1,3 +1,10 @@
+Fri Oct 24 11:15:58 1997  Jakub Jelinek  <jj@sunsite.mff.cuni.cz>
+
+       * elf64-sparc.c (sparc64_elf_merge_private_bfd_data):
+       New function. Avoid mixing US1 and HAL R1 code.
+       Set resulting memory ordering to the strongest one used.
+       (sparc64_elf_object_p): Set bfd_mach correctly.
+
 Thu Oct 23 14:09:33 1997  Richard Henderson  <rth@cygnus.com>
 
        * elf64-sparc.c (sparc64_elf_howto_table): Add UA64 & UA16.
index a579ba42227e6cf3f0b70d84ffd72a0bf14eb9da..b479ce063c704c35f8a0f818b6091c108d009966 100644 (file)
@@ -47,6 +47,9 @@ static boolean sparc64_elf_size_dynamic_sections
 static boolean sparc64_elf_adjust_dynindx
   PARAMS((struct elf_link_hash_entry *, PTR));
 
+static boolean sparc64_elf_merge_private_bfd_data
+  PARAMS ((bfd *, bfd *));
+
 static boolean sparc64_elf_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
@@ -2287,6 +2290,80 @@ sparc64_elf_finish_dynamic_sections (output_bfd, info)
 
   return true;
 }
+\f
+/* Functions for dealing with the e_flags field. */
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
+static boolean
+sparc64_elf_merge_private_bfd_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  boolean error;
+  flagword new_flags, old_flags;
+  int new_mm, old_mm;
+
+  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))   /* First call, no flags set */
+    {
+      elf_flags_init (obfd) = true;
+      elf_elfheader (obfd)->e_flags = new_flags;
+    }
+                      
+  else if (new_flags == old_flags)      /* Compatible flags are ok */
+    ;
+                            
+  else                                  /* Incompatible flags */
+    {
+      error = false;
+  
+      old_flags |= (new_flags & (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1));
+      new_flags |= (old_flags & (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1));
+      if ((old_flags & (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1)) ==
+           (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1))
+        {
+          error = true;
+          (*_bfd_error_handler)
+            ("%s: linking UltraSPARC specific with HAL specific code",
+             bfd_get_filename (ibfd));
+        }
+        
+      /* Choose the most restrictive memory ordering */
+      old_mm = (old_flags & EF_SPARCV9_MM);
+      new_mm = (new_flags & EF_SPARCV9_MM);
+      old_flags &= ~EF_SPARCV9_MM;
+      new_flags &= ~EF_SPARCV9_MM;
+      if (new_mm < old_mm) old_mm = new_mm;
+      old_flags |= old_mm;
+      new_flags |= old_mm;
+
+      /* Warn about any other mismatches */
+      if (new_flags != old_flags)
+        {
+          error = true;
+          (*_bfd_error_handler)
+            ("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)",
+             bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
+        }
+
+      elf_elfheader (obfd)->e_flags = old_flags;
+
+      if (error)
+        {
+          bfd_set_error (bfd_error_bad_value);
+          return false;
+        }
+    }
+  return true;
+}
 
 \f
 /* Set the right machine number for a SPARC64 ELF file.  */
@@ -2295,7 +2372,11 @@ static boolean
 sparc64_elf_object_p (abfd)
      bfd *abfd;
 {
-  return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
+  unsigned long mach = bfd_mach_sparc_v9;
+  
+  if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1)
+    mach = bfd_mach_sparc_v9a;
+  return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, mach);
 }
 
 #define TARGET_BIG_SYM bfd_elf64_sparc_vec
@@ -2324,6 +2405,9 @@ sparc64_elf_object_p (abfd)
 #define elf_backend_finish_dynamic_sections \
   sparc64_elf_finish_dynamic_sections
 
+#define bfd_elf64_bfd_merge_private_bfd_data \
+  sparc64_elf_merge_private_bfd_data
+
 #define elf_backend_object_p \
   sparc64_elf_object_p