This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/4] [ARC] Implement compatible function for ARC BFD architectures
- From: Anton Kolesov <Anton dot Kolesov at synopsys dot com>
- To: binutils at sourceware dot org
- Cc: Anton Kolesov <Anton dot Kolesov at synopsys dot com>, Francois Bedard <Francois dot Bedard at synopsys dot com>, Claudiu Zissulescu <Claudiu dot Zissulescu at synopsys dot com>, Cupertino Miranda <Cupertino dot Miranda at synopsys dot com>
- Date: Tue, 23 May 2017 14:43:57 +0300
- Subject: [PATCH 2/4] [ARC] Implement compatible function for ARC BFD architectures
- Authentication-results: sourceware.org; auth=none
- References: <20170523114359.23737-1-Anton.Kolesov@synopsys.com>
The general rule for bfd_arch_info_type->compatible (A, B) is that if A and B
are compatible, then this function should return architecture that is more
"feature-rich", that is, can run both A and B. ARCv2, EM and HS all has same
mach number, so bfd_default_compatible assumes they are the same, and returns
an A. That causes issues with GDB, because GDB assumes that if machines are
compatible, then "compatible ()" always returns same machine regardless of
argument order. As a result GDB gets confused because, for example,
compatible(ARCv2, EM) returns ARCv2, but compatible(EM, ARCv2) returns EM,
hence GDB is not sure if they are compatible and prints a warning.
bfd/ChangeLog:
yyyy-mm-dd Anton Kolesov Anton.Kolesov@synopsys.com
cpu-arc.c (arc_compatible): New function.
---
bfd/cpu-arc.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/bfd/cpu-arc.c b/bfd/cpu-arc.c
index 83648f1..cd0883a 100644
--- a/bfd/cpu-arc.c
+++ b/bfd/cpu-arc.c
@@ -23,6 +23,9 @@
#include "bfd.h"
#include "libbfd.h"
+static const bfd_arch_info_type *
+arc_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b);
+
#define ARC(mach, print_name, default_p, next) \
{ \
32, /* 32 bits in a word */ \
@@ -34,7 +37,7 @@
print_name, \
4, /* section alignment power */ \
default_p, \
- bfd_default_compatible, \
+ arc_compatible, \
bfd_default_scan, \
bfd_arch_default_fill, \
next, \
@@ -53,3 +56,45 @@ static const bfd_arch_info_type arch_info_struct[] =
const bfd_arch_info_type bfd_arc_arch =
ARC (bfd_mach_arc_arc600, "ARC600", TRUE, &arch_info_struct[0]);
+
+/* ARC-specific "compatible" function. The general rule is that if A and B are
+ compatible, then this function should return architecture that is more
+ "feature-rich", that is, can run both A and B. ARCv2, EM and HS all has
+ same mach number, so bfd_default_compatible assumes they are the same, and
+ returns an A. That causes issues with GDB, because GDB assumes that if
+ machines are compatible, then "compatible ()" always returns same machine
+ regardless of argument order. As a result GDB gets confused because, for
+ example, compatible (ARCv2, EM) returns ARCv2, but compatible (EM, ARCv2)
+ returns EM, hence GDB is not sure if they are compatible and prints a
+ warning. */
+
+static const bfd_arch_info_type *
+arc_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
+{
+ const bfd_arch_info_type * const em = &arch_info_struct[5];
+ const bfd_arch_info_type * const hs = &arch_info_struct[6];
+
+ /* Trivial case where a and b is the same instance. Some callers already
+ check this condition but some do not and get an invalid result. */
+ if (a == b)
+ return a;
+
+ /* If a & b are for different architecture we can do nothing. */
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->bits_per_word != b->bits_per_word)
+ return NULL;
+
+ /* ARCv2|EM and EM. */
+ if ((a->mach == bfd_mach_arc_arcv2 && b == em)
+ || (b->mach == bfd_mach_arc_arcv2 && a == em))
+ return em;
+
+ /* ARCv2|HS and HS. */
+ if ((a->mach == bfd_mach_arc_arcv2 && b == hs)
+ || (b->mach == bfd_mach_arc_arcv2 && a == hs))
+ return hs;
+
+ return bfd_default_compatible (a, b);
+}
--
2.8.3