Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid random access values for operands in not-yet-specified instructions. #2259

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions arch/X86/X86ATTInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64
uint8_t count, i;
const uint8_t *arr = X86_get_op_access(h, id, eflags);

// initialize access
memset(access, 0, CS_X86_MAXIMUM_OPERAND_SIZE * sizeof(access[0]));

if (!arr) {
access[0] = 0;
return;
Expand Down Expand Up @@ -313,7 +316,7 @@ static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
int reg;

if (MI->csh->detail_opt) {
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
Expand Down Expand Up @@ -351,7 +354,7 @@ static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
{
if (MI->csh->detail_opt) {
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
Expand Down Expand Up @@ -437,7 +440,7 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
int reg;

if (MI->csh->detail_opt) {
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
Expand Down Expand Up @@ -563,7 +566,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
if (MI->csh->doing_mem) {
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_register_map(reg);
} else {
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = X86_register_map(reg);
Expand Down Expand Up @@ -712,7 +715,7 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
int64_t DispVal = 1;

if (MI->csh->detail_opt) {
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
Expand Down Expand Up @@ -877,7 +880,7 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
}

if (MI->csh->detail_opt) {
uint8_t access[6] = {0};
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE] = {0};

// some instructions need to supply immediate 1 in the first op
switch(MCInst_getOpcode(MI)) {
Expand Down Expand Up @@ -983,7 +986,7 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
MI->flat_insn->detail->x86.operands[1].type = X86_OP_REG;
MI->flat_insn->detail->x86.operands[1].reg = reg2;
MI->flat_insn->detail->x86.operands[1].size = MI->csh->regsize_map[reg2];
MI->flat_insn->detail->x86.operands[0].access = access2;
MI->flat_insn->detail->x86.operands[1].access = access2;
MI->flat_insn->detail->x86.op_count = 2;
}
}
Expand Down
2 changes: 1 addition & 1 deletion arch/X86/X86InstPrinterCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#include "../../MCInst.h"
#include "../../SStream.h"

#define CS_X86_MAXIMUM_OPERAND_SIZE 6

void printSSEAVXCC(MCInst *MI, unsigned Op, SStream *O);
void printXOPCC(MCInst *MI, unsigned Op, SStream *O);
void printRoundingControl(MCInst *MI, unsigned Op, SStream *O);

#endif

21 changes: 12 additions & 9 deletions arch/X86/X86IntelInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64
uint8_t i;
const uint8_t *arr = X86_get_op_access(h, id, eflags);

// initialize access
memset(access, 0, CS_X86_MAXIMUM_OPERAND_SIZE * sizeof(access[0]));

if (!arr) {
access[0] = 0;
return;
Expand All @@ -456,7 +459,7 @@ static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)

if (MI->csh->detail_opt) {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
Expand Down Expand Up @@ -496,7 +499,7 @@ static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
{
if (MI->csh->detail_opt) {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
Expand Down Expand Up @@ -592,7 +595,7 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)

if (MI->csh->detail_opt) {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
Expand Down Expand Up @@ -649,7 +652,7 @@ static void printU8Imm(MCInst *MI, unsigned Op, SStream *O)

if (MI->csh->detail_opt) {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
Expand Down Expand Up @@ -714,7 +717,7 @@ void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
reg = X86_insn_reg_intel(MCInst_getOpcode(MI), &access1);
if (MI->csh->detail_opt) {
#ifndef CAPSTONE_DIET
uint8_t access[6] = {0};
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE] = {0};
#endif

// first op can be embedded in the asm by llvm.
Expand Down Expand Up @@ -771,7 +774,7 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)

if (MI->csh->detail_opt) {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
Expand Down Expand Up @@ -810,7 +813,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_register_map(reg);
} else {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
Expand Down Expand Up @@ -897,7 +900,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
} else {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
Expand Down Expand Up @@ -937,7 +940,7 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)

if (MI->csh->detail_opt) {
#ifndef CAPSTONE_DIET
uint8_t access[6];
uint8_t access[CS_X86_MAXIMUM_OPERAND_SIZE];
#endif

MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
Expand Down
3 changes: 1 addition & 2 deletions arch/X86/X86MappingInsnOp.inc
Original file line number Diff line number Diff line change
Expand Up @@ -16915,7 +16915,7 @@

{ /* X86_VCMPSSZrr_Int, X86_INS_VCMP: vcmp */
0,
{ 0 }
{ CS_AC_WRITE, CS_AC_READ, CS_AC_READ, 0 }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the regression test along with this change, which only fixes the rr variant of vcmpunordss. Let me know if these access values can also be generated by tablegen.

Copy link
Collaborator

@Rot127 Rot127 Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the access details can be generated. But x86 is not "officially" supported by auto-sync currently.
But the access information should theoretically generate fine.

You need to build our llvm-tblgen (see docs) and run

llvm-tblgen --gen-asm-matcher --printerLang=CCS -I ./llvm/lib/Target/X86/ -I ./llvm/include/ ./llvm/lib/Target/X86/X86.td

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you still want to generate these things, please do it in another PR. So it is nicely distinct from the changes here.

},

{ /* X86_VCMPSSZrr_Intk, X86_INS_VCMP: vcmp */
Expand Down Expand Up @@ -75697,4 +75697,3 @@
X86_EFLAGS_MODIFY_ZF | X86_EFLAGS_RESET_CF | X86_EFLAGS_RESET_OF | X86_EFLAGS_RESET_SF | X86_EFLAGS_RESET_PF | X86_EFLAGS_RESET_AF,
{ 0 }
},

4 changes: 4 additions & 0 deletions suite/cstest/issues.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
!# issue 2258 vcmpunordss incorrect read/modified register
!# CS_ARCH_X86, CS_MODE_64, CS_OPT_DETAIL
0x62,0xd1,0x56,0x08,0xc2,0xca,0x03 == vcmpunordss k1, xmm5, xmm10 ; operands[0].access: WRITE ; operands[1].access: READ ; operands[2].access: READ

!# issue 2062 repz Prefix
!# CS_ARCH_X86, CS_MODE_64, CS_OPT_DETAIL
0xf3,0xc3 == repz ret ; Prefix:0xf3 0x00 0x00 0x00
Expand Down
Loading