mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-24 05:59:45 +00:00
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:
parent
ad15637598
commit
cc2965bada
@ -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");
|
||||
|
@ -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];
|
||||
|
@ -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)]
|
||||
|
@ -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)),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
'
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user