Skip to content

M68K: Float disassembly (immediate) broken on BigEndian targets #1710

Closed
@michalsc

Description

@michalsc

Due to the way the code for m68k disassembler is written it outputs broken numbers when disassembling float immediate numbers, e.g. following output is created:

fmul.s  #0.00000E-322, fp5

instead of

fmul.s  #0.69314E0, fp5

This is due to the union (include/capstone/m68k.h):

/// Instruction operand
typedef struct cs_m68k_op {
	union {
		uint64_t imm;               ///< immediate value for IMM operand
		double dimm; 		    ///< double imm
		float simm; 		    ///< float imm
		m68k_reg reg;		    ///< register value for REG operand
		cs_m68k_op_reg_pair reg_pair; ///< register pair in one operand
	};
        ...

The layout of the union members on both little and big endian is as follows:

x x x x x x x x       uint64_t imm
x x x x x x x x       double dimm;
x x x x . . . .       float simm;

Therefore, storing little endian integer, decoded from instruction stream, into 64-bit field imm allows one to read 32-bit float from the very same position. There, the least significant bytes come first. On big endian however, storing 32-bit number in 64-bit variable imm will zero out the top 32 bits, which are the location where float is read from.

I have a fix ready, but it assumes existence of __BYTE_ORDER__ define (supported by gcc) as well as __ORDER_LITTLE_ENDIAN__ or __ORDER_BIG_ENDIAN__.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions