Skip to content

Commit 4195382

Browse files
authored
X86: Fix four AT&T operand-detail and text defects (#3042)
* Record the implicit CL operand of the AT&T memory shift and rotate forms * Keep the unsigned display mask out of the AT&T immediate operand detail * Stop the AT&T immediate size fixup overwriting a size already set * Zero the operand slot before filling it in the AT&T implicit inserts * Add x86 AT&T operand detail tests * Zero the register info allocated by the x86 global init
1 parent 85a618e commit 4195382

4 files changed

Lines changed: 151 additions & 5 deletions

File tree

arch/X86/X86ATTInstPrinter.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,9 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
695695
SStream_concat(O, "$%" PRIu64, imm);
696696
} else {
697697
if (MI->csh->imm_unsigned) {
698+
// the mask is for display only: the value
699+
// stored in detail must stay unmasked
700+
int64_t p = imm;
698701
if (opsize) {
699702
switch (opsize) {
700703
default:
@@ -703,15 +706,15 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
703706
// making it effectively always positive.
704707
// So this switch is never reached.
705708
case 2:
706-
imm &= 0xffff;
709+
p &= 0xffff;
707710
break;
708711
case 4:
709-
imm &= 0xffffffff;
712+
p &= 0xffffffff;
710713
break;
711714
}
712715
}
713716

714-
SStream_concat(O, "$0x%" PRIx64, imm);
717+
SStream_concat(O, "$0x%" PRIx64, p);
715718
} else {
716719
if (imm ==
717720
0x8000000000000000LL) // imm == -imm
@@ -1055,9 +1058,13 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
10551058
.size;
10561059
}
10571060
}
1058-
} else
1061+
} else if (!MI->flat_insn->detail->x86.operands[0].size) {
1062+
// AT&T sets has_imm without a size (printPCRelImm,
1063+
// op_addImm) and relies on this; printOperand does set
1064+
// one, so it must not be overwritten here
10591065
MI->flat_insn->detail->x86.operands[0].size =
10601066
MI->imm_size;
1067+
}
10611068
}
10621069

10631070
if (MI->csh->detail_opt) {
@@ -1138,6 +1145,8 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
11381145
(ARR_SIZE(MI->flat_insn->detail->x86
11391146
.operands) -
11401147
1));
1148+
memset(&(MI->flat_insn->detail->x86.operands[0]), 0,
1149+
sizeof(MI->flat_insn->detail->x86.operands[0]));
11411150
MI->flat_insn->detail->x86.operands[0].type =
11421151
X86_OP_IMM;
11431152
MI->flat_insn->detail->x86.operands[0].imm = 1;
@@ -1161,6 +1170,8 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
11611170
(ARR_SIZE(MI->flat_insn->detail->x86
11621171
.operands) -
11631172
1));
1173+
memset(&(MI->flat_insn->detail->x86.operands[0]), 0,
1174+
sizeof(MI->flat_insn->detail->x86.operands[0]));
11641175
MI->flat_insn->detail->x86.operands[0].type =
11651176
X86_OP_REG;
11661177
MI->flat_insn->detail->x86.operands[0].reg = reg;

arch/X86/X86Mapping.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,43 +1484,75 @@ static const struct insn_reg insn_regs_att[] = {
14841484
{ X86_PUSHGS64, X86_REG_GS, CS_AC_READ },
14851485
{ X86_PUSHSS16, X86_REG_SS, CS_AC_READ },
14861486
{ X86_PUSHSS32, X86_REG_SS, CS_AC_READ },
1487+
{ X86_RCL16mCL, X86_REG_CL, CS_AC_READ },
14871488
{ X86_RCL16rCL, X86_REG_CL, CS_AC_READ },
1489+
{ X86_RCL32mCL, X86_REG_CL, CS_AC_READ },
14881490
{ X86_RCL32rCL, X86_REG_CL, CS_AC_READ },
1491+
{ X86_RCL64mCL, X86_REG_CL, CS_AC_READ },
14891492
{ X86_RCL64rCL, X86_REG_CL, CS_AC_READ },
1493+
{ X86_RCL8mCL, X86_REG_CL, CS_AC_READ },
14901494
{ X86_RCL8rCL, X86_REG_CL, CS_AC_READ },
1495+
{ X86_RCR16mCL, X86_REG_CL, CS_AC_READ },
14911496
{ X86_RCR16rCL, X86_REG_CL, CS_AC_READ },
1497+
{ X86_RCR32mCL, X86_REG_CL, CS_AC_READ },
14921498
{ X86_RCR32rCL, X86_REG_CL, CS_AC_READ },
1499+
{ X86_RCR64mCL, X86_REG_CL, CS_AC_READ },
14931500
{ X86_RCR64rCL, X86_REG_CL, CS_AC_READ },
1501+
{ X86_RCR8mCL, X86_REG_CL, CS_AC_READ },
14941502
{ X86_RCR8rCL, X86_REG_CL, CS_AC_READ },
1503+
{ X86_ROL16mCL, X86_REG_CL, CS_AC_READ },
14951504
{ X86_ROL16rCL, X86_REG_CL, CS_AC_READ },
1505+
{ X86_ROL32mCL, X86_REG_CL, CS_AC_READ },
14961506
{ X86_ROL32rCL, X86_REG_CL, CS_AC_READ },
1507+
{ X86_ROL64mCL, X86_REG_CL, CS_AC_READ },
14971508
{ X86_ROL64rCL, X86_REG_CL, CS_AC_READ },
1509+
{ X86_ROL8mCL, X86_REG_CL, CS_AC_READ },
14981510
{ X86_ROL8rCL, X86_REG_CL, CS_AC_READ },
1511+
{ X86_ROR16mCL, X86_REG_CL, CS_AC_READ },
14991512
{ X86_ROR16rCL, X86_REG_CL, CS_AC_READ },
1513+
{ X86_ROR32mCL, X86_REG_CL, CS_AC_READ },
15001514
{ X86_ROR32rCL, X86_REG_CL, CS_AC_READ },
1515+
{ X86_ROR64mCL, X86_REG_CL, CS_AC_READ },
15011516
{ X86_ROR64rCL, X86_REG_CL, CS_AC_READ },
1517+
{ X86_ROR8mCL, X86_REG_CL, CS_AC_READ },
15021518
{ X86_ROR8rCL, X86_REG_CL, CS_AC_READ },
1519+
{ X86_SAL16mCL, X86_REG_CL, CS_AC_READ },
15031520
{ X86_SAL16rCL, X86_REG_CL, CS_AC_READ },
1521+
{ X86_SAL32mCL, X86_REG_CL, CS_AC_READ },
15041522
{ X86_SAL32rCL, X86_REG_CL, CS_AC_READ },
1523+
{ X86_SAL64mCL, X86_REG_CL, CS_AC_READ },
15051524
{ X86_SAL64rCL, X86_REG_CL, CS_AC_READ },
1525+
{ X86_SAL8mCL, X86_REG_CL, CS_AC_READ },
15061526
{ X86_SAL8rCL, X86_REG_CL, CS_AC_READ },
1527+
{ X86_SAR16mCL, X86_REG_CL, CS_AC_READ },
15071528
{ X86_SAR16rCL, X86_REG_CL, CS_AC_READ },
1529+
{ X86_SAR32mCL, X86_REG_CL, CS_AC_READ },
15081530
{ X86_SAR32rCL, X86_REG_CL, CS_AC_READ },
1531+
{ X86_SAR64mCL, X86_REG_CL, CS_AC_READ },
15091532
{ X86_SAR64rCL, X86_REG_CL, CS_AC_READ },
1533+
{ X86_SAR8mCL, X86_REG_CL, CS_AC_READ },
15101534
{ X86_SAR8rCL, X86_REG_CL, CS_AC_READ },
1535+
{ X86_SHL16mCL, X86_REG_CL, CS_AC_READ },
15111536
{ X86_SHL16rCL, X86_REG_CL, CS_AC_READ },
1537+
{ X86_SHL32mCL, X86_REG_CL, CS_AC_READ },
15121538
{ X86_SHL32rCL, X86_REG_CL, CS_AC_READ },
1539+
{ X86_SHL64mCL, X86_REG_CL, CS_AC_READ },
15131540
{ X86_SHL64rCL, X86_REG_CL, CS_AC_READ },
1541+
{ X86_SHL8mCL, X86_REG_CL, CS_AC_READ },
15141542
{ X86_SHL8rCL, X86_REG_CL, CS_AC_READ },
15151543
{ X86_SHLD16mrCL, X86_REG_CL, CS_AC_READ },
15161544
{ X86_SHLD16rrCL, X86_REG_CL, CS_AC_READ },
15171545
{ X86_SHLD32mrCL, X86_REG_CL, CS_AC_READ },
15181546
{ X86_SHLD32rrCL, X86_REG_CL, CS_AC_READ },
15191547
{ X86_SHLD64mrCL, X86_REG_CL, CS_AC_READ },
15201548
{ X86_SHLD64rrCL, X86_REG_CL, CS_AC_READ },
1549+
{ X86_SHR16mCL, X86_REG_CL, CS_AC_READ },
15211550
{ X86_SHR16rCL, X86_REG_CL, CS_AC_READ },
1551+
{ X86_SHR32mCL, X86_REG_CL, CS_AC_READ },
15221552
{ X86_SHR32rCL, X86_REG_CL, CS_AC_READ },
1553+
{ X86_SHR64mCL, X86_REG_CL, CS_AC_READ },
15231554
{ X86_SHR64rCL, X86_REG_CL, CS_AC_READ },
1555+
{ X86_SHR8mCL, X86_REG_CL, CS_AC_READ },
15241556
{ X86_SHR8rCL, X86_REG_CL, CS_AC_READ },
15251557
{ X86_SHRD16mrCL, X86_REG_CL, CS_AC_READ },
15261558
{ X86_SHRD16rrCL, X86_REG_CL, CS_AC_READ },

arch/X86/X86Module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
cs_err X86_global_init(cs_struct *ud)
1414
{
1515
MCRegisterInfo *mri;
16-
mri = cs_mem_malloc(sizeof(*mri));
16+
mri = cs_mem_calloc(1, sizeof(*mri));
1717
if (!mri)
1818
return CS_ERR_MEM;
1919

tests/details/x86.yaml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6752,3 +6752,106 @@ test_cases:
67526752
eflags: [ X86_EFLAGS_MODIFY_AF, X86_EFLAGS_MODIFY_CF, X86_EFLAGS_MODIFY_OF, X86_EFLAGS_MODIFY_PF, X86_EFLAGS_MODIFY_SF, X86_EFLAGS_MODIFY_ZF, ]
67536753
regs_read: [ eax, rsi, esi ]
67546754
regs_write: [ eax, rflags ]
6755+
-
6756+
input:
6757+
# The implicit CL of the memory-form shift/rotate group is recorded in
6758+
# AT&T mode too, and rcl no longer gets an immediate 1 in its place.
6759+
bytes: [0xd3, 0x23, 0xd3, 0x13]
6760+
arch: "x86"
6761+
options: [ CS_OPT_DETAIL, CS_MODE_64, CS_OPT_SYNTAX_ATT ]
6762+
address: 0x1000
6763+
expected:
6764+
insns:
6765+
-
6766+
asm_text: "shll %cl, (%rbx)"
6767+
details:
6768+
x86:
6769+
operands:
6770+
-
6771+
type: X86_OP_REG
6772+
reg: cl
6773+
size: 1
6774+
access: CS_AC_READ
6775+
-
6776+
type: X86_OP_MEM
6777+
mem_base: rbx
6778+
size: 4
6779+
access: CS_AC_READ_WRITE
6780+
-
6781+
# No access on the memory operand: ROL/RCL/ROR *mCL are missing
6782+
# CS_AC_WRITE in X86MappingInsnOp.inc, unlike their register forms
6783+
# and unlike SHL/SAR/SHR *mCL. That is a separate defect, so this
6784+
# case must not pin it.
6785+
asm_text: "rcll %cl, (%rbx)"
6786+
details:
6787+
x86:
6788+
operands:
6789+
-
6790+
type: X86_OP_REG
6791+
reg: cl
6792+
size: 1
6793+
access: CS_AC_READ
6794+
-
6795+
type: X86_OP_MEM
6796+
mem_base: rbx
6797+
size: 4
6798+
-
6799+
input:
6800+
# The unsigned-display mask is not stored in the operand detail.
6801+
bytes: [0x83, 0xf8, 0xab]
6802+
arch: "x86"
6803+
options: [ CS_OPT_DETAIL, CS_MODE_64, CS_OPT_SYNTAX_ATT, CS_OPT_UNSIGNED ]
6804+
address: 0x1000
6805+
expected:
6806+
insns:
6807+
-
6808+
asm_text: "cmpl $0xffffffab, %eax"
6809+
details:
6810+
x86:
6811+
operands:
6812+
-
6813+
type: X86_OP_IMM
6814+
imm: -0x55
6815+
size: 4
6816+
-
6817+
type: X86_OP_REG
6818+
reg: eax
6819+
size: 4
6820+
access: CS_AC_READ
6821+
-
6822+
input:
6823+
# push takes its size from the fixup, which the guard leaves reachable.
6824+
bytes: [0x6a, 0x48]
6825+
arch: "x86"
6826+
options: [ CS_OPT_DETAIL, CS_MODE_64, CS_OPT_SYNTAX_ATT ]
6827+
address: 0x1000
6828+
expected:
6829+
insns:
6830+
-
6831+
asm_text: "pushq $0x48"
6832+
details:
6833+
x86:
6834+
operands:
6835+
-
6836+
type: X86_OP_IMM
6837+
imm: 0x48
6838+
size: 8
6839+
-
6840+
input:
6841+
# The size fixup must not overwrite the size printOperand derived from
6842+
# X86_immediate_size: aam's immediate is one byte, not the operand width.
6843+
bytes: [0xd4, 0x59]
6844+
arch: "x86"
6845+
options: [ CS_OPT_DETAIL, CS_MODE_32, CS_OPT_SYNTAX_ATT ]
6846+
address: 0x1000
6847+
expected:
6848+
insns:
6849+
-
6850+
asm_text: "aam $0x59"
6851+
details:
6852+
x86:
6853+
operands:
6854+
-
6855+
type: X86_OP_IMM
6856+
imm: 0x59
6857+
size: 1

0 commit comments

Comments
 (0)