x86: recognize xacquire prefix. issue #1477

This commit is contained in:
Nguyen Anh Quynh 2019-05-13 22:27:05 +08:00
parent 7d72c1e1da
commit d5dd80e979
6 changed files with 23 additions and 15 deletions

View File

@ -33,6 +33,7 @@ void MCInst_Init(MCInst *inst)
inst->popcode_adjust = 0;
inst->assembly[0] = '\0';
inst->wasm_data.type = WASM_OP_INVALID;
inst->xAcquireRelease = false;
}
void MCInst_clear(MCInst *inst)

View File

@ -116,6 +116,7 @@ struct MCInst {
unsigned char evm_data[32]; // for EVM PUSH operand
cs_wasm_op wasm_data; // for WASM operand
MCRegisterInfo *MRI;
bool xAcquireRelease; // X86 xacquire/xrelease
};
void MCInst_Init(MCInst *inst);

View File

@ -867,13 +867,8 @@ static int reader(const struct reader_info *info, uint8_t *byte, uint64_t addres
}
// copy x86 detail information from internal structure to public structure
static void update_pub_insn(cs_insn *pub, InternalInstruction *inter, uint8_t *prefixes)
static void update_pub_insn(cs_insn *pub, InternalInstruction *inter)
{
prefixes[0] = inter->prefix0;
prefixes[1] = inter->prefix1;
prefixes[2] = inter->prefix2;
prefixes[3] = inter->prefix3;
if (inter->vectorExtensionType != 0)
memcpy(pub->detail->x86.opcode, inter->vectorExtensionPrefix, sizeof(pub->detail->x86.opcode));
else {
@ -999,14 +994,16 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,
if (result) {
unsigned Flags = X86_IP_NO_PREFIX;
instr->imm_size = insn.immSize;
// copy all prefixes
instr->x86_prefix[0] = insn.prefix0;
instr->x86_prefix[1] = insn.prefix1;
instr->x86_prefix[2] = insn.prefix2;
instr->x86_prefix[3] = insn.prefix3;
instr->xAcquireRelease = insn.xAcquireRelease;
if (handle->detail) {
update_pub_insn(instr->flat_insn, &insn, instr->x86_prefix);
} else {
// still copy all prefixes
instr->x86_prefix[0] = insn.prefix0;
instr->x86_prefix[1] = insn.prefix1;
instr->x86_prefix[2] = insn.prefix2;
instr->x86_prefix[3] = insn.prefix3;
update_pub_insn(instr->flat_insn, &insn);
}
if (insn.hasAdSize)

View File

@ -471,7 +471,9 @@ static int readPrefixes(struct InternalInstruction* insn)
if (((nextByte == 0xf0) ||
((nextByte & 0xfe) == 0x86 || (nextByte & 0xf8) == 0x90))) {
insn->xAcquireRelease = true;
if (!(byte == 0xf3 && nextByte == 0x90)) // PAUSE instruction support
if (!(byte == 0xf3 && nextByte == 0x90) && // PAUSE instruction support
!(byte == 0xf2 && nextByte == 0xf0))
break;
}

View File

@ -1835,7 +1835,10 @@ bool X86_lockrep(MCInst *MI, SStream *O)
break;
case 0xf0:
#ifndef CAPSTONE_DIET
SStream_concat(O, "lock|");
if (MI->xAcquireRelease)
SStream_concat(O, "xacquire|lock|");
else
SStream_concat(O, "lock|");
#endif
break;
case 0xf2: // repne

View File

@ -1,3 +1,7 @@
!# issue 1477 X86 xacquire
!# CS_ARCH_X86, CS_MODE_64, None
0xf2,0xf0,0x31,0x1f == xacquire lock xor dword ptr [rdi], ebx
!# issue PPC JUMP group
!# CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN, CS_OPT_DETAIL
0x41,0x82,0x00,0x10 == beq 0x10 ; Groups: jump