Fix a couple of corner-cases with rarely used m68k instructions. (#1344)

* Bump the "cs_insn.bytes[]" size to 24 (from 16) to support M680x0 instructions with full EA (maximum 11 words)
Added a test for this in test_m68k.s

* Bump the "cs_detail.regs_read[]" size to 16 (from 12) to support M680x0 instructions with full REG_BITS (Dn+An = 16)

* m68k: use immediate mode syntax (#$0) for movem/fmovem instructions with empty register list

* update bindings to match changes to cs_insn and cs_detail
This commit is contained in:
Erik Hemming 2019-01-21 09:55:05 +01:00 committed by Nguyen Anh Quynh
parent ad15637598
commit cc2965bada
10 changed files with 26 additions and 15 deletions

View File

@ -108,6 +108,11 @@ static void registerBits(SStream* O, const cs_m68k_op* op)
buffer[0] = 0;
if (!data) {
SStream_concat(O, "%s", "#$0");
return;
}
printRegbitsRange(buffer, data & 0xff, "d");
printRegbitsRange(buffer, (data >> 8) & 0xff, "a");
printRegbitsRange(buffer, (data >> 16) & 0xff, "fp");

View File

@ -55,7 +55,7 @@ public class Capstone {
public _cs_detail.ByReference cs_detail;
public _cs_insn() {
bytes = new byte[16];
bytes = new byte[24];
mnemonic = new byte[32];
op_str = new byte[160];
java.util.Arrays.fill(mnemonic, (byte) 0);
@ -78,7 +78,7 @@ public class Capstone {
public static class ByReference extends _cs_detail implements Structure.ByReference {};
// list of all implicit registers being read.
public short[] regs_read = new short[12];
public short[] regs_read = new short[16];
public byte regs_read_count;
// list of all implicit registers being written.
public short[] regs_write = new short[20];

View File

@ -55,7 +55,7 @@ function Initialize-Capstone {
public uint id;
public ulong address;
public ushort size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
public byte[] bytes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string mnemonic;
@ -68,7 +68,7 @@ function Initialize-Capstone {
[StructLayout(LayoutKind.Sequential)]
public struct cs_detail
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] regs_read;
public byte regs_read_count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]

View File

@ -350,7 +350,7 @@ class _cs_arch(ctypes.Union):
class _cs_detail(ctypes.Structure):
_fields_ = (
('regs_read', ctypes.c_uint16 * 12),
('regs_read', ctypes.c_uint16 * 16),
('regs_read_count', ctypes.c_ubyte),
('regs_write', ctypes.c_uint16 * 20),
('regs_write_count', ctypes.c_ubyte),
@ -364,7 +364,7 @@ class _cs_insn(ctypes.Structure):
('id', ctypes.c_uint),
('address', ctypes.c_uint64),
('size', ctypes.c_uint16),
('bytes', ctypes.c_ubyte * 16),
('bytes', ctypes.c_ubyte * 24),
('mnemonic', ctypes.c_char * 32),
('op_str', ctypes.c_char * 160),
('detail', ctypes.POINTER(_cs_detail)),

View File

@ -20,7 +20,7 @@ cdef extern from "<capstone/capstone.h>":
unsigned int id
uint64_t address
uint16_t size
uint8_t bytes[16]
uint8_t bytes[24]
char mnemonic[32]
char op_str[160]
cs_detail *detail

View File

@ -19,7 +19,7 @@ Option Explicit
'Copyright: FireEye 2017
'Public Type cs_detail
' regs_read(0 To 11) As Byte ' list of implicit registers read by this insn UNSIGNED
' regs_read(0 To 15) As Byte ' list of implicit registers read by this insn UNSIGNED
' regs_read_count As Byte ' number of implicit registers read by this insn UNSIGNED
' regs_write(0 To 19) As Byte ' list of implicit registers modified by this insn UNSIGNED
' regs_write_count As Byte ' number of implicit registers modified by this insn UNSIGNED

View File

@ -31,7 +31,7 @@ Option Explicit
' align As Long 'not sure why it needs this..but it does..
' address As Currency ' Address (EIP) of this instruction available even when CS_OPT_DETAIL = CS_OPT_OFF UNSIGNED
' size As Integer ' Size of this instruction available even when CS_OPT_DETAIL = CS_OPT_OFF UNSIGNED
' bytes(0 To 15) As Byte ' Machine bytes of this instruction, with number of bytes indicated by @size above available even when CS_OPT_DETAIL = CS_OPT_OFF
' bytes(0 To 23) As Byte ' Machine bytes of this instruction, with number of bytes indicated by @size above available even when CS_OPT_DETAIL = CS_OPT_OFF
' mnemonic(0 To 31) As Byte ' Ascii text of instruction mnemonic available even when CS_OPT_DETAIL = CS_OPT_OFF
' op_str(0 To 159) As Byte ' Ascii text of instruction operands available even when CS_OPT_DETAIL = CS_OPT_OFF
'

View File

@ -88,7 +88,7 @@ End Enum
'NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
Public Type cs_detail
regs_read(0 To 11) As Byte ' list of implicit registers read by this insn UNSIGNED
regs_read(0 To 15) As Byte ' list of implicit registers read by this insn UNSIGNED
regs_read_count As Byte ' number of implicit registers read by this insn UNSIGNED
regs_write(0 To 19) As Byte ' list of implicit registers modified by this insn UNSIGNED
regs_write_count As Byte ' number of implicit registers modified by this insn UNSIGNED
@ -97,7 +97,7 @@ Public Type cs_detail
End Type
'typedef struct cs_detail {
' uint8_t regs_read[12]; // list of implicit registers read by this insn
' uint8_t regs_read[16]; // list of implicit registers read by this insn
' uint8_t regs_read_count; // number of implicit registers read by this insn
'
' uint8_t regs_write[20]; // list of implicit registers modified by this insn
@ -131,7 +131,7 @@ Public Type cs_insn
align As Long 'not sure why it needs this..but it does..
address As Currency ' Address (EIP) of this instruction available even when CS_OPT_DETAIL = CS_OPT_OFF UNSIGNED
size As Integer ' Size of this instruction available even when CS_OPT_DETAIL = CS_OPT_OFF UNSIGNED
bytes(0 To 15) As Byte ' Machine bytes of this instruction, with number of bytes indicated by @size above available even when CS_OPT_DETAIL = CS_OPT_OFF
bytes(0 To 23) As Byte ' Machine bytes of this instruction, with number of bytes indicated by @size above available even when CS_OPT_DETAIL = CS_OPT_OFF
mnemonic(0 To 31) As Byte ' Ascii text of instruction mnemonic available even when CS_OPT_DETAIL = CS_OPT_OFF
op_str(0 To 159) As Byte ' Ascii text of instruction operands available even when CS_OPT_DETAIL = CS_OPT_OFF

View File

@ -286,7 +286,7 @@ typedef struct cs_opt_skipdata {
/// if cs_detail changes, in particular if a field is added after the union,
/// then update arch/ARCH/ARCHDisassembler.c accordingly
typedef struct cs_detail {
uint16_t regs_read[12]; ///< list of implicit registers read by this insn
uint16_t regs_read[16]; ///< list of implicit registers read by this insn
uint8_t regs_read_count; ///< number of implicit registers read by this insn
uint16_t regs_write[20]; ///< list of implicit registers modified by this insn
@ -333,7 +333,7 @@ typedef struct cs_insn {
/// Machine bytes of this instruction, with number of bytes indicated by @size above
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
uint8_t bytes[16];
uint8_t bytes[24];
/// Ascii text of instruction mnemonic
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF

View File

@ -2,6 +2,7 @@
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <assert.h>
#include <capstone/platform.h>
#include <capstone/capstone.h>
@ -134,6 +135,9 @@ static void print_insn_detail(cs_insn *ins)
printf("\t\toperands[%u].type: FP_DOUBLE\n", i);
printf("\t\t\toperands[%u].dimm: %lf\n", i, op->dimm);
break;
case M68K_OP_REG_BITS:
printf("\t\toperands[%u].type: REG_BITS = $%x\n", i, op->register_bits);
}
}
@ -142,7 +146,7 @@ static void print_insn_detail(cs_insn *ins)
static void test()
{
#define M68K_CODE "\x4C\x00\x54\x04\x48\xe7\xe0\x30\x4C\xDF\x0C\x07\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
#define M68K_CODE "\xf0\x10\xf0\x00\x48\xaf\xff\xff\x7f\xff\x11\xb0\x01\x37\x7f\xff\xff\xff\x12\x34\x56\x78\x01\x33\x10\x10\x10\x10\x32\x32\x32\x32\x4C\x00\x54\x04\x48\xe7\xe0\x30\x4C\xDF\x0C\x07\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
struct platform platforms[] = {
{
CS_ARCH_M68K,
@ -177,6 +181,8 @@ static void test()
printf("Disasm:\n");
for (j = 0; j < count; j++) {
assert(address == insn[j].address && "this means the size of the previous instruction was incorrect");
address += insn[j].size;
printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
print_insn_detail(&insn[j]);
}