diff --git a/decode.c b/decode.c index 28dd995..329b156 100644 --- a/decode.c +++ b/decode.c @@ -570,6 +570,8 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, uintptr_t address, } else if (UNLIKELY(imm_control != 0)) { + struct Operand* operand = &instr->operands[DESC_IMM_IDX(desc)]; + uint8_t imm_size; if (DESC_IMM_BYTE(desc)) { @@ -583,6 +585,14 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, uintptr_t address, { imm_size = 3; } +#if defined(ARCH_X86_64) + else if (mode == DECODE_64 && UNLIKELY(imm_control == 4)) + { + // Jumps are always 8 or 32 bit on x86-64. + imm_size = 4; + operand->size = 8; + } +#endif else if (prefixes & PREFIX_OPSZ) { imm_size = 2; @@ -634,7 +644,6 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, uintptr_t address, instr->immediate += instr->address + off; } - struct Operand* operand = &instr->operands[DESC_IMM_IDX(desc)]; if (UNLIKELY(imm_control == 5)) { operand->type = OT_REG; diff --git a/tests/decode-jmp.txt b/tests/decode-jmp.txt new file mode 100644 index 0000000..fab1bfc --- /dev/null +++ b/tests/decode-jmp.txt @@ -0,0 +1,4 @@ +decode32 e900000000 [JMP imm4:0x1234005] +decode32 66e90100 [JMP imm2:0x4005] +decode64 e900000000 [JMP imm8:0x1234005] +decode64 66e900000000 [JMP imm8:0x1234006] diff --git a/tests/meson.build b/tests/meson.build index 0fb7b3a..8912fbf 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -19,6 +19,7 @@ testcases = [ ['enter', 'decode-enter.sh'], ['imul', 'decode-imul.sh'], ['inc', 'decode-inc.sh'], + ['jmp', 'decode-jmp.txt'], ['movsx', 'decode-movsx.sh'], ['ret', 'decode-ret.sh'],