This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Some m68k compatibility fixes


m68k_cpus has an incorrect entry for cpu_cf5208: it should be
mcfemac rather than mcfmac.  This patch fixes it.

I stumbled across the problem as a linker failure when trying to combine
5207 and 528x code (which ought to be compatible).  The linker's error
message wasn't very helpful though: it just said "failed to merge target
specific data of file ...", but with no details as to why.  The patch
tries to fix that too.

There are two functions responsible for detecting incompatible objects.
The first is bfd_m68k_compatible, which operates on bfd_machs.
The second is elf32_m68k_merge_private_bfd_data, which operates
on ELF flags.

The linker will use bfd_m68k_compatible first.  It will warn if the
function fails -- with a relatively helpful error message -- otherwise
it will call elf32_m68k_merge_private_bfd_data.  If e_m_m_p_b_d then
detects an incompatibility, it should use bfd_error_handler to report it.
The problem is that e_m_m_p_b_d is not using bfd_error_handle at present;
it just returns FALSE.

As things stand, bfd_m68k_compatible detects coldfire vs. non-coldfire
incompatibilties, but it doesn't detect ISA or MAC incompatibilities.
elf32_m68k_merge_private_bfd_data detects all three.  So either we
need to use bfd_error_handle for the existing elf32_m68k_merge_private_
bfd_data checks, or we need to move them to bfd_m68k_compatible.

I prefer the latter, because it means that all incompatibilities
are reported in the same way.  It's also a lot simpler and leads
to less code duplication.

Note that elf32_m68k_merge_private_bfd_data already inlined the logic of
bfd_m68k_compatible (with slight, but unintentional, differences in the
handling of the "unknown" architecture), so the patch makes it call
bfd_get_compatible instead.

Tested on m68k-elf.  OK to install?

Richard


bfd/
	* cpu-m68k.c (bfd_m68k_compatible): Treat ISA A+ and ISA B code as
	incompatible.  Likewise MAC and EMAC code.
	* elf32-m68k.c (elf32_m68k_merge_private_bfd_data): Use
	bfd_get_compatible to set the new bfd architecture.  Rely on it
	to detect incompatibilities.

gas/
	* config/tc-m68k.c (m68k_cpus): Change cpu_cf5208 entries to use
	mcfemac instead of mcfmac.

ld/testsuite/
	* ld-m68k/merge-error-1a.s, ld-m68k/merge-error-1b.s,
	* ld-m68k/merge-error-1a.d, ld-m68k/merge-error-1b.d,
	* ld-m68k/merge-error-1c.d, ld-m68k/merge-error-1d.d,
	* ld-m68k/merge-error-1e.d, ld-m68k/merge-ok-1a.d,
	* ld-m68k/merge-ok-1b.d: New tests.
	* ld-m68k/m68k.exp: Run them.

Index: bfd/cpu-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/cpu-m68k.c,v
retrieving revision 1.12
diff -u -p -r1.12 cpu-m68k.c
--- bfd/cpu-m68k.c	6 Mar 2006 13:42:03 -0000	1.12
+++ bfd/cpu-m68k.c	14 Mar 2006 19:10:35 -0000
@@ -208,9 +208,16 @@ bfd_m68k_compatible (const bfd_arch_info
       /* Merge cf machine.  */
       unsigned features = (bfd_m68k_mach_to_features (a->mach)
 			   | bfd_m68k_mach_to_features (b->mach));
-      unsigned machine = bfd_m68k_features_to_mach (features);
 
-      return bfd_lookup_arch (a->arch, machine);
+      /* ISA A+ and ISA B are incompatible.  */
+      if ((~features & (mcfisa_aa | mcfisa_b)) == 0)
+	return NULL;
+
+      /* MAC and EMAC code cannot be merged.  */
+      if ((~features & (mcfmac | mcfemac)) == 0)
+	return NULL;
+
+      return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (features));
     }
   else
     /* They are incompatible.  */
Index: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.87
diff -u -p -r1.87 elf32-m68k.c
--- bfd/elf32-m68k.c	6 Mar 2006 13:42:03 -0000	1.87
+++ bfd/elf32-m68k.c	14 Mar 2006 19:10:36 -0000
@@ -445,40 +445,24 @@ elf32_m68k_merge_private_bfd_data (ibfd,
 {
   flagword out_flags;
   flagword in_flags;
-  unsigned in_mach, out_mach;
+  flagword out_isa;
+  flagword in_isa;
+  const bfd_arch_info_type *arch_info;
   
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return FALSE;
 
-  in_mach = bfd_get_mach (ibfd);
-  out_mach = bfd_get_mach (obfd);
-  if (!out_mach || !in_mach)
-    /* One is unknown, copy the input machine.  */
-    out_mach = in_mach;
-  else if (in_mach != out_mach)
-    {
-      if (in_mach <= bfd_mach_m68060 && out_mach <= bfd_mach_m68060)
-	{
-	  /* Merge m68k machine. */
-	  if (in_mach > out_mach)
-	    out_mach = in_mach;
-	}
-      else if (in_mach >= bfd_mach_mcf_isa_a_nodiv
-	       && out_mach >= bfd_mach_mcf_isa_a_nodiv)
-	/* Merge cf machine.  */
-	out_mach = bfd_m68k_features_to_mach
-	  (bfd_m68k_mach_to_features (in_mach)
-	   | bfd_m68k_mach_to_features (out_mach));
-      else
-	/* They are incompatible.  */
-	return FALSE;
-    }
-  bfd_set_arch_mach (obfd, bfd_arch_m68k, out_mach);
-  
-  in_flags  = elf_elfheader (ibfd)->e_flags;
-  out_flags = elf_elfheader (obfd)->e_flags;
+  /* Get the merged machine.  This checks for incompatibility between
+     Coldfire & non-Coldfire flags, incompability between different
+     Coldfire ISAs, and incompability between different MAC types.  */
+  arch_info = bfd_arch_get_compatible (ibfd, obfd, FALSE);
+  if (!arch_info)
+    return FALSE;
 
+  bfd_set_arch_mach (obfd, bfd_arch_m68k, arch_info->mach);
+  
+  in_flags = elf_elfheader (ibfd)->e_flags;
   if (!elf_flags_init (obfd))
     {
       elf_flags_init (obfd) = TRUE;
@@ -486,54 +470,12 @@ elf32_m68k_merge_private_bfd_data (ibfd,
     }
   else
     {
-      flagword isa_in = in_flags & EF_M68K_ISA_MASK;
-      flagword isa_out = out_flags & EF_M68K_ISA_MASK;
-      
-      
-      /* Copy legacy flags.  */
-      out_flags |= in_flags & (EF_M68K_CPU32 | EF_M68K_M68000 | EF_M68K_CFV4E);
-
-      if ((isa_in | isa_out)
-	  && ((in_flags | out_flags) & (EF_M68K_CPU32 | EF_M68K_M68000)))
-	/* Mixing m68k and cf is not allowed */
-	return FALSE;
-      
-      if (isa_in)
-	{
-	  if (isa_out)
-	    {
-	      if (isa_out == EF_M68K_ISA_A_PLUS
-		  && (isa_in == EF_M68K_ISA_B_NOUSP
-		      || isa_in == EF_M68K_ISA_B))
-		/* Cannot mix A+ and B */
-		return FALSE;
-	      if (isa_in == EF_M68K_ISA_A_PLUS
-		  && (isa_out == EF_M68K_ISA_B_NOUSP
-		      || isa_out == EF_M68K_ISA_B))
-		/* Cannot mix B and A+ */
-		return FALSE;
-	      
-	      if (isa_in > isa_out)
-		out_flags ^= isa_in ^ isa_out;
-
-	      out_flags |= in_flags & EF_M68K_FLOAT;
-	      if (in_flags & EF_M68K_MAC_MASK)
-		{
-		  if (!(out_flags & EF_M68K_MAC_MASK))
-		    out_flags |= in_flags & EF_M68K_MAC_MASK;
-		  else if ((out_flags & EF_M68K_MAC_MASK)
-			   != (in_flags & EF_M68K_MAC_MASK))
-		    /* Cannot mix MACs */
-		    return FALSE;
-		}
-	    }
-	  else
-	    {
-	      /* Copy the coldfire bits.  */
-	      out_flags &= ~EF_M68K_CF_MASK;
-	      out_flags |= in_flags & EF_M68K_CF_MASK;
-	    }
-	}
+      out_flags = elf_elfheader (obfd)->e_flags;
+      in_isa = (in_flags & EF_M68K_ISA_MASK);
+      out_isa = (out_flags & EF_M68K_ISA_MASK);
+      if (in_isa > out_isa)
+	out_flags ^= in_isa ^ out_isa;
+      out_flags |= in_flags ^ in_isa;
     }
   elf_elfheader (obfd)->e_flags = out_flags;
 
Index: gas/config/tc-m68k.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68k.c,v
retrieving revision 1.72
diff -u -p -r1.72 tc-m68k.c
--- gas/config/tc-m68k.c	6 Mar 2006 13:42:04 -0000	1.72
+++ gas/config/tc-m68k.c	14 Mar 2006 19:10:37 -0000
@@ -432,7 +432,7 @@ static const struct m68k_cpu m68k_cpus[]
   { cpu32|m68881,				cpu_cpu32, "cpu32",  0},
   { mcfisa_a,					cpu_cf5200, "5200", 0},
   { mcfisa_a|mcfhwdiv|mcfmac,			cpu_cf5206e, "5206e", 0},
-  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp,	cpu_cf5208, "5208", 0},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,	cpu_cf5208, "5208", 0},
   { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp,	cpu_cf5213, "5213", 0},
   { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,cpu_cf521x, "521x", 0},
   { mcfisa_a|mcfhwdiv|mcfemac,		cpu_cf5249, "5249", 0},
@@ -473,7 +473,7 @@ static const struct m68k_cpu m68k_cpus[]
   { mcfisa_a,					cpu_cf5200, "5202", 1},
   { mcfisa_a,					cpu_cf5200, "5204", 1},
   { mcfisa_a,					cpu_cf5200, "5206", 1},
-  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp,	cpu_cf5208, "5207", 1},
+  { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,	cpu_cf5208, "5207", 1},
   { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp,	cpu_cf5213, "5211", 1},
   { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfmac|mcfusp,	cpu_cf5213, "5212", 1},
   { mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp,	cpu_cf521x, "5214", 1},
Index: ld/testsuite/ld-m68k/m68k.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-m68k/m68k.exp,v
retrieving revision 1.1
diff -u -p -r1.1 m68k.exp
--- ld/testsuite/ld-m68k/m68k.exp	6 Mar 2006 13:42:05 -0000	1.1
+++ ld/testsuite/ld-m68k/m68k.exp	14 Mar 2006 19:10:38 -0000
@@ -45,3 +45,11 @@ set m68k_mergeok_tests {
 	{isab.s isab-float.s} {{objdump -p isab-float.d}} "isab-float"}}
 
 run_ld_link_tests $m68k_mergeok_tests
+
+run_dump_test "merge-error-1a"
+run_dump_test "merge-error-1b"
+run_dump_test "merge-error-1c"
+run_dump_test "merge-error-1d"
+run_dump_test "merge-error-1e"
+run_dump_test "merge-ok-1a"
+run_dump_test "merge-ok-1b"
Index: ld/testsuite/ld-m68k/merge-error-1a.d
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-error-1a.d
diff -N ld/testsuite/ld-m68k/merge-error-1a.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-error-1a.d	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1,4 @@
+#source: merge-error-1a.s -mcpu=cpu32
+#source: merge-error-1b.s -mcpu=68000
+#ld: -r
+#warning: .*
Index: ld/testsuite/ld-m68k/merge-error-1a.s
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-error-1a.s
diff -N ld/testsuite/ld-m68k/merge-error-1a.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-error-1a.s	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1 @@
+	rts
Index: ld/testsuite/ld-m68k/merge-error-1b.d
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-error-1b.d
diff -N ld/testsuite/ld-m68k/merge-error-1b.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-error-1b.d	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1,4 @@
+#source: merge-error-1a.s -mcpu=cpu32
+#source: merge-error-1b.s -mcpu=5207
+#ld: -r
+#warning: .*
Index: ld/testsuite/ld-m68k/merge-error-1b.s
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-error-1b.s
diff -N ld/testsuite/ld-m68k/merge-error-1b.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-error-1b.s	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1 @@
+	rts
Index: ld/testsuite/ld-m68k/merge-error-1c.d
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-error-1c.d
diff -N ld/testsuite/ld-m68k/merge-error-1c.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-error-1c.d	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1,4 @@
+#source: merge-error-1a.s -march=isaaplus
+#source: merge-error-1b.s -march=isab
+#ld: -r
+#warning: .*
Index: ld/testsuite/ld-m68k/merge-error-1d.d
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-error-1d.d
diff -N ld/testsuite/ld-m68k/merge-error-1d.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-error-1d.d	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1,4 @@
+#source: merge-error-1a.s -march=isaa -mmac
+#source: merge-error-1b.s -march=isaa -memac
+#ld: -r
+#warning: .*
Index: ld/testsuite/ld-m68k/merge-error-1e.d
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-error-1e.d
diff -N ld/testsuite/ld-m68k/merge-error-1e.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-error-1e.d	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1,4 @@
+#source: merge-error-1a.s -march=isaa -mno-div -mmac
+#source: merge-error-1b.s -march=isaa -mno-div -memac
+#ld: -r
+#warning: .*
Index: ld/testsuite/ld-m68k/merge-ok-1a.d
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-ok-1a.d
diff -N ld/testsuite/ld-m68k/merge-ok-1a.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-ok-1a.d	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1,6 @@
+#source: merge-error-1a.s -mcpu=5207
+#source: merge-error-1b.s -mcpu=528x
+#ld: -r
+#objdump: -p
+#...
+private flags = 23: \[isa A\+\] \[emac\]
Index: ld/testsuite/ld-m68k/merge-ok-1b.d
===================================================================
RCS file: ld/testsuite/ld-m68k/merge-ok-1b.d
diff -N ld/testsuite/ld-m68k/merge-ok-1b.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-m68k/merge-ok-1b.d	14 Mar 2006 19:10:38 -0000
@@ -0,0 +1,6 @@
+#source: merge-error-1a.s -march=isaa -mno-div -mmac
+#source: merge-error-1b.s -march=isaa -mno-div -mfloat
+#ld: -r
+#objdump: -p
+#...
+private flags = 8051: \[cfv4e\] \[isa A\] \[nodiv\] \[float\] \[mac\]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]