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

[X86] Incorrect explicit read/modified registers for vcmpunordss and others #2258

Closed
mur47x111 opened this issue Jan 23, 2024 · 1 comment
Closed
Labels
Milestone

Comments

@mur47x111
Copy link
Contributor

cstool/cstool -d -s x64 "62 f1 76 08 c2 c9 03" may yield different results:

        op_count: 3
                operands[0].type: REG = k1
                operands[0].size: 2
                operands[1].type: REG = xmm1
                operands[1].size: 16
                operands[2].type: REG = xmm1
                operands[2].size: 16
...
        op_count: 3
                operands[0].type: REG = k1
                operands[0].size: 2
                operands[1].type: REG = xmm1
                operands[1].size: 16
                operands[2].type: REG = xmm1
                operands[2].size: 16
        Registers read: xmm1
...
        op_count: 3
                operands[0].type: REG = k1
                operands[0].size: 2
                operands[1].type: REG = xmm1
                operands[1].size: 16
                operands[2].type: REG = xmm1
                operands[2].size: 16
        Registers read: xmm1
        Registers modified: xmm1

This is due to incorrect operand access values specified for instructions such as vcmpunordss. IIUC, operand access values are maintained in capstone/arch/X86/X86MappingInsnOp.inc and copied to the new X86MappingInsnOp.inc generated by tablegen, see

def print_entry(arch, insn_id, mnem, mapping, mnem_can_be_wrong):
insn = "%s_%s" %(arch, insn_id)
# first, try to find this entry in old MappingInsn.inc file
for i in range(len(mapping)):
if mapping[i].startswith('{') and '/*' in mapping[i]:
#print(mapping[i])
tmp = mapping[i].split('/*')
tmp = tmp[1].strip()
tmp = tmp.split(',')
#print("insn2 = |%s|" %tmp.strip())
if tmp[0].strip() == insn:
if not mnem_can_be_wrong:
print('''
{\t/* %s, %s_INS_%s: %s */
\t%s
\t%s
},'''% (insn, arch, mnem, mnem.lower(), mapping[i + 1].strip(), mapping[i + 2].strip()))
else:
print('''
{\t/* %s, %s
\t%s
\t%s
},'''% (insn, ''.join(tmp[1:]).strip(), mapping[i + 1].strip(), mapping[i + 2].strip()))
return
print('''
{\t/* %s, %s_INS_%s: %s */
\t0,
\t{ 0 }
},'''% (insn, arch, mnem, mnem.lower()))
. New instructions are associated with default access value { 0 }. X86IntelInstPrinter or X86ATTInstPrinter uses a stack allocated array for storing the access values. This array is never initialized and only the first element is set to 0. When requesting access value for second/third operands in such instructions, it then fetches random values stored in the un-initialized array, and thus yield random results.

@Rot127
Copy link
Collaborator

Rot127 commented Apr 24, 2024

closed with #2259

@Rot127 Rot127 closed this as completed Apr 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants