From 5385baba39d1f8f070ccc428ed4a56d1082f51a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Gro=C3=9F?= Date: Fri, 5 May 2017 03:02:58 +0200 Subject: [PATCH] Implemented read and write access to the YMM registers (#819) --- bindings/python/unicorn/unicorn.py | 21 +++++++++++++++++ qemu/target-i386/unicorn.c | 36 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/bindings/python/unicorn/unicorn.py b/bindings/python/unicorn/unicorn.py index 0a21c15d..de7a6135 100644 --- a/bindings/python/unicorn/unicorn.py +++ b/bindings/python/unicorn/unicorn.py @@ -223,6 +223,15 @@ class uc_x86_xmm(ctypes.Structure): ("high_qword", ctypes.c_uint64), ] +class uc_x86_ymm(ctypes.Structure): + """256-bit ymm register""" + _fields_ = [ + ("first_qword", ctypes.c_uint64), + ("second_qword", ctypes.c_uint64), + ("third_qword", ctypes.c_uint64), + ("fourth_qword", ctypes.c_uint64), + ] + class uc_arm64_neon128(ctypes.Structure): """128-bit neon register""" _fields_ = [ @@ -314,6 +323,12 @@ class Uc(object): if status != uc.UC_ERR_OK: raise UcError(status) return reg.low_qword | (reg.high_qword << 64) + if reg_id in range(x86_const.UC_X86_REG_YMM0, x86_const.UC_X86_REG_YMM0+8): + reg = uc_x86_ymm() + status = _uc.uc_reg_read(self._uch, reg_id, ctypes.byref(reg)) + if status != uc.UC_ERR_OK: + raise UcError(status) + return reg.first_qword | (reg.second_qword << 64) | (reg.third_qword << 128) | (reg.fourth_qword << 192) if reg_id is x86_const.UC_X86_REG_MSR: if opt is None: raise UcError(uc.UC_ERR_ARG) @@ -359,6 +374,12 @@ class Uc(object): reg = uc_x86_xmm() reg.low_qword = value & 0xffffffffffffffff reg.high_qword = value >> 64 + if reg_id in range(x86_const.UC_X86_REG_YMM0, x86_const.UC_X86_REG_YMM0+8): + reg = uc_x86_ymm() + reg.first_qword = value & 0xffffffffffffffff + reg.second_qword = (value >> 64) & 0xffffffffffffffff + reg.third_qword = (value >> 128) & 0xffffffffffffffff + reg.fourth_qword = value >> 192 if reg_id is x86_const.UC_X86_REG_MSR: reg = uc_x86_msr() reg.rid = value[0] diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index 8af79649..08ea9a11 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -283,6 +283,24 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun dst[1] = reg->_d[1]; continue; } + case UC_X86_REG_YMM0: + case UC_X86_REG_YMM1: + case UC_X86_REG_YMM2: + case UC_X86_REG_YMM3: + case UC_X86_REG_YMM4: + case UC_X86_REG_YMM5: + case UC_X86_REG_YMM6: + case UC_X86_REG_YMM7: + { + float64 *dst = (float64*)value; + XMMReg *lo_reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_YMM0]; + XMMReg *hi_reg = &X86_CPU(uc, mycpu)->env.ymmh_regs[regid - UC_X86_REG_YMM0]; + dst[0] = lo_reg->_d[0]; + dst[1] = lo_reg->_d[1]; + dst[2] = hi_reg->_d[0]; + dst[3] = hi_reg->_d[1]; + continue; + } } switch(uc->mode) { @@ -804,6 +822,24 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i reg->_d[1] = src[1]; continue; } + case UC_X86_REG_YMM0: + case UC_X86_REG_YMM1: + case UC_X86_REG_YMM2: + case UC_X86_REG_YMM3: + case UC_X86_REG_YMM4: + case UC_X86_REG_YMM5: + case UC_X86_REG_YMM6: + case UC_X86_REG_YMM7: + { + float64 *src = (float64*)value; + XMMReg *lo_reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_YMM0]; + XMMReg *hi_reg = &X86_CPU(uc, mycpu)->env.ymmh_regs[regid - UC_X86_REG_YMM0]; + lo_reg->_d[0] = src[0]; + lo_reg->_d[1] = src[1]; + hi_reg->_d[0] = src[2]; + hi_reg->_d[1] = src[3]; + continue; + } } switch(uc->mode) {