From f04265eceb78a33e452faa8727562e96af374f39 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 22 Sep 2015 17:21:13 +0100 Subject: [PATCH] Enhance the RX disassembler to detect and report bad instructions. opcode * rx.h (enum RX_Size): Add RX_Bad_Size entry. opcodes * rx-decode.opc (bwl): Use RX_Bad_Size. (sbwl): Likewise. (ubwl): Likewise. Rename to ubw. (uBWL): Rename to uBW. Replace all references to uBWL with uBW. * rx-decode.c: Regenerate. * rx-dis.c (size_names): Add entry for RX_Bad_Size. (opsize_names): Likewise. (print_insn_rx): Detect and report RX_Bad_Size. --- include/opcode/ChangeLog | 4 ++++ include/opcode/rx.h | 2 ++ opcodes/ChangeLog | 12 ++++++++++++ opcodes/rx-decode.c | 20 ++++++++++---------- opcodes/rx-decode.opc | 20 ++++++++++---------- opcodes/rx-dis.c | 33 +++++++++++++++++++++++++-------- 6 files changed, 63 insertions(+), 28 deletions(-) diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 6fce0ac859..d81b604616 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2015-09-22 Nick Clifton + + * rx.h (enum RX_Size): Add RX_Bad_Size entry. + 2015-09-09 Daniel Santos * visium.h (gen_reg_table): Make static. diff --git a/include/opcode/rx.h b/include/opcode/rx.h index 41557b2f8c..4a2cb14ad4 100644 --- a/include/opcode/rx.h +++ b/include/opcode/rx.h @@ -38,6 +38,8 @@ typedef enum RX_SWord, RX_3Byte, RX_Long, + RX_Bad_Size, + RX_MAX_SIZE } RX_Size; typedef enum diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index dc3627e5eb..942cdcd23c 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,15 @@ +2015-09-22 Nick Clifton + + * rx-decode.opc (bwl): Use RX_Bad_Size. + (sbwl): Likewise. + (ubwl): Likewise. Rename to ubw. + (uBWL): Rename to uBW. + Replace all references to uBWL with uBW. + * rx-decode.c: Regenerate. + * rx-dis.c (size_names): Add entry for RX_Bad_Size. + (opsize_names): Likewise. + (print_insn_rx): Detect and report RX_Bad_Size. + 2015-09-22 Anton Blanchard * ppc-opc.c (powerpc_opcodes): Add mfdscr, mfctrl, mtdscr and mtctrl. diff --git a/opcodes/rx-decode.c b/opcodes/rx-decode.c index aae02a32c5..a4e278d964 100644 --- a/opcodes/rx-decode.c +++ b/opcodes/rx-decode.c @@ -50,7 +50,7 @@ static int bwl[] = RX_Byte, RX_Word, RX_Long, - 0 /* Bogus instructions can have a size field set to 3. */ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ }; static int sbwl[] = @@ -58,15 +58,15 @@ static int sbwl[] = RX_SByte, RX_SWord, RX_Long, - 0 /* Bogus instructions can have a size field set to 3. */ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ }; -static int ubwl[] = +static int ubw[] = { RX_UByte, RX_UWord, - RX_Long, - 0 /* Bogus instructions can have a size field set to 3. */ + RX_Bad_Size,/* Bogus instructions can have a size field set to 2. */ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ }; static int memex[] = @@ -132,7 +132,7 @@ static int dsp3map[] = { 8, 9, 10, 3, 4, 5, 6, 7 }; #define BWL(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = bwl[sz] #define sBWL(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = sbwl[sz] -#define uBWL(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = ubwl[sz] +#define uBW(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = ubw[sz] #define P(t, n) rx->op[n].size = (t!=3) ? RX_UByte : RX_Long; #define F(f) store_flags(rx, f) @@ -4085,7 +4085,7 @@ rx_decode_opcode (unsigned long pc AU, } SYNTAX("movu%s %1, %0"); #line 355 "rx-decode.opc" - ID(mov); uBWL(s); SD(ss, rsrc, s); DR(rdst); F_____; + ID(mov); uBW(s); SD(ss, rsrc, s); DR(rdst); F_____; } break; @@ -6171,7 +6171,7 @@ rx_decode_opcode (unsigned long pc AU, } SYNTAX("movu%s %1, %0"); #line 352 "rx-decode.opc" - ID(mov); uBWL(w); DR(dst); SIs(src, dsp*4+a*2+b, w); F_____; + ID(mov); uBW(w); DR(dst); SIs(src, dsp*4+a*2+b, w); F_____; } break; @@ -9887,7 +9887,7 @@ rx_decode_opcode (unsigned long pc AU, } SYNTAX("movu%s %1, %0"); #line 358 "rx-decode.opc" - ID(mov); uBWL (sz); DR(rdst); F_____; + ID(mov); uBW (sz); DR(rdst); F_____; OP(1, p ? RX_Operand_Predec : RX_Operand_Postinc, rsrc, 0); /*----------------------------------------------------------------------*/ @@ -13586,7 +13586,7 @@ rx_decode_opcode (unsigned long pc AU, } SYNTAX("movu%s [%1, %2], %0"); #line 341 "rx-decode.opc" - ID(movbi); uBWL(sz); DR(rdst); SRR(isrc); S2R(bsrc); F_____; + ID(movbi); uBW(sz); DR(rdst); SRR(isrc); S2R(bsrc); F_____; } break; diff --git a/opcodes/rx-decode.opc b/opcodes/rx-decode.opc index f9b0df43f2..7c641fa3ff 100644 --- a/opcodes/rx-decode.opc +++ b/opcodes/rx-decode.opc @@ -49,7 +49,7 @@ static int bwl[] = RX_Byte, RX_Word, RX_Long, - 0 /* Bogus instructions can have a size field set to 3. */ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ }; static int sbwl[] = @@ -57,15 +57,15 @@ static int sbwl[] = RX_SByte, RX_SWord, RX_Long, - 0 /* Bogus instructions can have a size field set to 3. */ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ }; -static int ubwl[] = +static int ubw[] = { RX_UByte, RX_UWord, - RX_Long, - 0 /* Bogus instructions can have a size field set to 3. */ + RX_Bad_Size,/* Bogus instructions can have a size field set to 2. */ + RX_Bad_Size /* Bogus instructions can have a size field set to 3. */ }; static int memex[] = @@ -131,7 +131,7 @@ static int dsp3map[] = { 8, 9, 10, 3, 4, 5, 6, 7 }; #define BWL(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = bwl[sz] #define sBWL(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = sbwl[sz] -#define uBWL(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = ubwl[sz] +#define uBW(sz) rx->op[0].size = rx->op[1].size = rx->op[2].size = rx->size = ubw[sz] #define P(t, n) rx->op[n].size = (t!=3) ? RX_UByte : RX_Long; #define F(f) store_flags(rx, f) @@ -338,7 +338,7 @@ rx_decode_opcode (unsigned long pc AU, ID(movbir); sBWL(sz); DR(rdst); SRR(isrc); S2R(bsrc); F_____; /** 1111 1110 11sz isrc bsrc rdst movu%s [%1, %2], %0 */ - ID(movbi); uBWL(sz); DR(rdst); SRR(isrc); S2R(bsrc); F_____; + ID(movbi); uBW(sz); DR(rdst); SRR(isrc); S2R(bsrc); F_____; /** 1111 1101 0010 0p sz rdst rsrc mov%s %1, %0 */ ID(mov); sBWL (sz); SR(rsrc); F_____; @@ -349,13 +349,13 @@ rx_decode_opcode (unsigned long pc AU, OP(1, p ? RX_Operand_Predec : RX_Operand_Postinc, rsrc, 0); /** 1011 w dsp a src b dst movu%s %1, %0 */ - ID(mov); uBWL(w); DR(dst); SIs(src, dsp*4+a*2+b, w); F_____; + ID(mov); uBW(w); DR(dst); SIs(src, dsp*4+a*2+b, w); F_____; /** 0101 1 s ss rsrc rdst movu%s %1, %0 */ - ID(mov); uBWL(s); SD(ss, rsrc, s); DR(rdst); F_____; + ID(mov); uBW(s); SD(ss, rsrc, s); DR(rdst); F_____; /** 1111 1101 0011 1p sz rsrc rdst movu%s %1, %0 */ - ID(mov); uBWL (sz); DR(rdst); F_____; + ID(mov); uBW (sz); DR(rdst); F_____; OP(1, p ? RX_Operand_Predec : RX_Operand_Postinc, rsrc, 0); /*----------------------------------------------------------------------*/ diff --git a/opcodes/rx-dis.c b/opcodes/rx-dis.c index 6260186957..cab0385d3c 100644 --- a/opcodes/rx-dis.c +++ b/opcodes/rx-dis.c @@ -48,14 +48,14 @@ rx_get_byte (void * vdata) return buf[0]; } -static char const * size_names[] = +static char const * size_names[RX_MAX_SIZE] = { - "", ".b", ".ub", ".b", ".w", ".uw", ".w", ".a", ".l" + "", ".b", ".ub", ".b", ".w", ".uw", ".w", ".a", ".l", "" }; -static char const * opsize_names[] = +static char const * opsize_names[RX_MAX_SIZE] = { - "", ".b", ".b", ".b", ".w", ".w", ".w", ".a", ".l" + "", ".b", ".b", ".b", ".w", ".w", ".w", ".a", ".l", "" }; static char const * register_names[] = @@ -64,10 +64,10 @@ static char const * register_names[] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", /* control register */ - "psw", "pc", "usp", "fpsw", "", "", "", "wr", - "bpsw", "bpc", "isp", "fintv", "intb", "", "", "", - "pbp", "pben", "", "", "", "", "", "", - "bbpsw", "bbpc", "", "", "", "", "", "" + "psw", "pc", "usp", "fpsw", NULL, NULL, NULL, NULL, + "bpsw", "bpc", "isp", "fintv", "intb", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static char const * condition_names[] = @@ -104,6 +104,23 @@ print_insn_rx (bfd_vma addr, disassemble_info * dis) #define PS (dis->stream) #define PC(c) PR (PS, "%c", c) + /* Detect illegal instructions. */ + if (opcode.op[0].size == RX_Bad_Size + || register_names [opcode.op[0].reg] == NULL + || register_names [opcode.op[1].reg] == NULL + || register_names [opcode.op[2].reg] == NULL) + { + bfd_byte buf[10]; + int i; + + PR (PS, ".byte "); + rx_data.dis->read_memory_func (rx_data.pc - rv, buf, rv, rx_data.dis); + + for (i = 0 ; i < rv; i++) + PR (PS, "0x%02x ", buf[i]); + return rv; + } + for (s = opcode.syntax; *s; s++) { if (*s != '%') -- 2.34.1