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 avx does not work #1879

Open
shuffle2 opened this issue Sep 11, 2023 · 3 comments
Open

x86 avx does not work #1879

shuffle2 opened this issue Sep 11, 2023 · 3 comments

Comments

@shuffle2
Copy link
Contributor

shuffle2 commented Sep 11, 2023

here is some example code:

can this work somehow, or does unicorn need to be changed to support avx? I came across this problem in some project I was working on, and solved it a different way (without unicorn), since it didn't seem to work. But it would be nice to know what's going on.

#!/usr/bin/env python3
from unicorn import *
from unicorn.x86_const import *

'''
// documented as:
// __m256 _mm256_loadu_ps (float const * mem_addr)
// #include <immintrin.h>
// Instruction: vmovups ymm, m256
// CPUID Flags: AVX
vmovups ymm0, ymmword ptr [rax]
vmovups ymmword ptr [rbx], ymm0
'''
code = bytes.fromhex('C5FC1000C5FC1103')
code_cpuid = bytes.fromhex('0FA2')

uc = Uc(UC_ARCH_X86, UC_MODE_64)
# this line makes no difference
uc.ctl_set_cpu_model(UC_CPU_X86_EPYC_ROME)
uc.mem_map(0, 0x1000)
uc.mem_write(0, code)
uc.mem_write(0x100, code_cpuid)
uc.mem_map(0x10000, 0x1000)
uc.mem_write(0x10000, b'A'*0x20)

# get cpuid output
uc.reg_write(UC_X86_REG_EAX, 1)
uc.reg_write(UC_X86_REG_ECX, 0)
uc.emu_start(0x100, 0x100+len(code_cpuid))
r = [uc.reg_read(x) for x in (UC_X86_REG_EAX, UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDX)]
print(f'cpuid(eax=1,ecx=0): eax:{r[0]:8x} ebx:{r[1]:8x} ecx:{r[2]:8x} edx:{r[3]:8x}')
ecx = r[2]
xsave, osxsave, avx = (ecx >> 26) & 1, (ecx >> 27) & 1, (ecx >> 28) & 1
print(f'xsave:{xsave} osxsave:{osxsave} avx:{avx}')

# try the avx code
uc.reg_write(UC_X86_REG_RAX, 0x10000)
uc.reg_write(UC_X86_REG_RBX, 0x10100)
# will get UC_ERR_INSN_INVALID
uc.emu_start(0, len(code))
output = uc.mem_read(0x10100, 0x20)
print(output.hex())
assert output == b'A'*0x20

the output:

cpuid(eax=1,ecx=0): eax:  830f10 ebx:     800 ecx: 2182200 edx: 7088100
xsave:0 osxsave:0 avx:0
Traceback (most recent call last):
  File "unicorn_avx_test.py", line 35, in <module>
    uc.emu_start(0, len(code))
  File "C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\site-packages\unicorn\unicorn.py", line 547, in emu_start
    raise UcError(status)
unicorn.unicorn.UcError: Invalid instruction (UC_ERR_INSN_INVALID)
@wtdcode
Copy link
Member

wtdcode commented Sep 12, 2023

Conclusion:

  • osxsave could be enabled but you need to check cr4
  • avx is supported by tcg since v7.2.0 while we are v5.0.1

@shuffle2
Copy link
Contributor Author

Is it likely qemu would be updated? Or is that a big task?

@wtdcode
Copy link
Member

wtdcode commented Sep 12, 2023

Is it likely qemu would be updated? Or is that a big task?

I once worked on bumping qemu to 5.1.0. The work itself is not difficult or hard but just too tedious.

Actually probably we don't need to upgrade qemu but it's much easier to just port the avx decoding code back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants