diff options
author | Anton Kolesov <Anton.Kolesov@synopsys.com> | 2017-03-17 18:37:42 +0300 |
---|---|---|
committer | Anton Kolesov <Anton.Kolesov@synopsys.com> | 2017-05-30 16:51:14 +0300 |
commit | 64984c22f7045d53590f816e7ba0b9b9fa1dbbe7 (patch) | |
tree | 33a06f27d6ef29f23547b47f44e7e04e931937a2 /bfd/cpu-arc.c | |
parent | 37cd38778dfb73d28e533fd1ddabb88b4b3a5771 (diff) | |
download | gdb-64984c22f7045d53590f816e7ba0b9b9fa1dbbe7.zip gdb-64984c22f7045d53590f816e7ba0b9b9fa1dbbe7.tar.gz gdb-64984c22f7045d53590f816e7ba0b9b9fa1dbbe7.tar.bz2 |
[ARC] Implement compatible function for ARC BFD architectures
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.
Diffstat (limited to 'bfd/cpu-arc.c')
-rw-r--r-- | bfd/cpu-arc.c | 47 |
1 files changed, 46 insertions, 1 deletions
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); +} |