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.
This commit is contained in:
parent
bc1f8cdaf4
commit
f04265eceb
6 changed files with 63 additions and 28 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2015-09-22 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* rx.h (enum RX_Size): Add RX_Bad_Size entry.
|
||||||
|
|
||||||
2015-09-09 Daniel Santos <daniel.santos@pobox.com>
|
2015-09-09 Daniel Santos <daniel.santos@pobox.com>
|
||||||
|
|
||||||
* visium.h (gen_reg_table): Make static.
|
* visium.h (gen_reg_table): Make static.
|
||||||
|
|
|
@ -38,6 +38,8 @@ typedef enum
|
||||||
RX_SWord,
|
RX_SWord,
|
||||||
RX_3Byte,
|
RX_3Byte,
|
||||||
RX_Long,
|
RX_Long,
|
||||||
|
RX_Bad_Size,
|
||||||
|
RX_MAX_SIZE
|
||||||
} RX_Size;
|
} RX_Size;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
2015-09-22 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* 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 <anton@samba.org>
|
2015-09-22 Anton Blanchard <anton@samba.org>
|
||||||
|
|
||||||
* ppc-opc.c (powerpc_opcodes): Add mfdscr, mfctrl, mtdscr and mtctrl.
|
* ppc-opc.c (powerpc_opcodes): Add mfdscr, mfctrl, mtdscr and mtctrl.
|
||||||
|
|
|
@ -50,7 +50,7 @@ static int bwl[] =
|
||||||
RX_Byte,
|
RX_Byte,
|
||||||
RX_Word,
|
RX_Word,
|
||||||
RX_Long,
|
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[] =
|
static int sbwl[] =
|
||||||
|
@ -58,15 +58,15 @@ static int sbwl[] =
|
||||||
RX_SByte,
|
RX_SByte,
|
||||||
RX_SWord,
|
RX_SWord,
|
||||||
RX_Long,
|
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_UByte,
|
||||||
RX_UWord,
|
RX_UWord,
|
||||||
RX_Long,
|
RX_Bad_Size,/* Bogus instructions can have a size field set to 2. */
|
||||||
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 memex[] =
|
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 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 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 P(t, n) rx->op[n].size = (t!=3) ? RX_UByte : RX_Long;
|
||||||
|
|
||||||
#define F(f) store_flags(rx, f)
|
#define F(f) store_flags(rx, f)
|
||||||
|
@ -4085,7 +4085,7 @@ rx_decode_opcode (unsigned long pc AU,
|
||||||
}
|
}
|
||||||
SYNTAX("movu%s %1, %0");
|
SYNTAX("movu%s %1, %0");
|
||||||
#line 355 "rx-decode.opc"
|
#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;
|
break;
|
||||||
|
@ -6171,7 +6171,7 @@ rx_decode_opcode (unsigned long pc AU,
|
||||||
}
|
}
|
||||||
SYNTAX("movu%s %1, %0");
|
SYNTAX("movu%s %1, %0");
|
||||||
#line 352 "rx-decode.opc"
|
#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;
|
break;
|
||||||
|
@ -9887,7 +9887,7 @@ rx_decode_opcode (unsigned long pc AU,
|
||||||
}
|
}
|
||||||
SYNTAX("movu%s %1, %0");
|
SYNTAX("movu%s %1, %0");
|
||||||
#line 358 "rx-decode.opc"
|
#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);
|
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");
|
SYNTAX("movu%s [%1, %2], %0");
|
||||||
#line 341 "rx-decode.opc"
|
#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;
|
break;
|
||||||
|
|
|
@ -49,7 +49,7 @@ static int bwl[] =
|
||||||
RX_Byte,
|
RX_Byte,
|
||||||
RX_Word,
|
RX_Word,
|
||||||
RX_Long,
|
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[] =
|
static int sbwl[] =
|
||||||
|
@ -57,15 +57,15 @@ static int sbwl[] =
|
||||||
RX_SByte,
|
RX_SByte,
|
||||||
RX_SWord,
|
RX_SWord,
|
||||||
RX_Long,
|
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_UByte,
|
||||||
RX_UWord,
|
RX_UWord,
|
||||||
RX_Long,
|
RX_Bad_Size,/* Bogus instructions can have a size field set to 2. */
|
||||||
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 memex[] =
|
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 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 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 P(t, n) rx->op[n].size = (t!=3) ? RX_UByte : RX_Long;
|
||||||
|
|
||||||
#define F(f) store_flags(rx, f)
|
#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_____;
|
ID(movbir); sBWL(sz); DR(rdst); SRR(isrc); S2R(bsrc); F_____;
|
||||||
|
|
||||||
/** 1111 1110 11sz isrc bsrc rdst movu%s [%1, %2], %0 */
|
/** 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 */
|
/** 1111 1101 0010 0p sz rdst rsrc mov%s %1, %0 */
|
||||||
ID(mov); sBWL (sz); SR(rsrc); F_____;
|
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);
|
OP(1, p ? RX_Operand_Predec : RX_Operand_Postinc, rsrc, 0);
|
||||||
|
|
||||||
/** 1011 w dsp a src b dst movu%s %1, %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 */
|
/** 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 */
|
/** 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);
|
OP(1, p ? RX_Operand_Predec : RX_Operand_Postinc, rsrc, 0);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -48,14 +48,14 @@ rx_get_byte (void * vdata)
|
||||||
return buf[0];
|
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", "<error>"
|
||||||
};
|
};
|
||||||
|
|
||||||
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", "<error>"
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const * register_names[] =
|
static char const * register_names[] =
|
||||||
|
@ -64,10 +64,10 @@ static char const * register_names[] =
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||||
/* control register */
|
/* control register */
|
||||||
"psw", "pc", "usp", "fpsw", "", "", "", "wr",
|
"psw", "pc", "usp", "fpsw", NULL, NULL, NULL, NULL,
|
||||||
"bpsw", "bpc", "isp", "fintv", "intb", "", "", "",
|
"bpsw", "bpc", "isp", "fintv", "intb", NULL, NULL, NULL,
|
||||||
"pbp", "pben", "", "", "", "", "", "",
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
"bbpsw", "bbpc", "", "", "", "", "", ""
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const * condition_names[] =
|
static char const * condition_names[] =
|
||||||
|
@ -104,6 +104,23 @@ print_insn_rx (bfd_vma addr, disassemble_info * dis)
|
||||||
#define PS (dis->stream)
|
#define PS (dis->stream)
|
||||||
#define PC(c) PR (PS, "%c", c)
|
#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++)
|
for (s = opcode.syntax; *s; s++)
|
||||||
{
|
{
|
||||||
if (*s != '%')
|
if (*s != '%')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue