You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.5 KiB
179 lines
4.5 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
|
|
.data
|
|
|
|
.extern gprval
|
|
.extern agprval
|
|
.extern stval
|
|
.extern astval
|
|
.extern xmmval
|
|
.extern axmmval
|
|
#ifdef CONTEXT_USING_AVX
|
|
.extern ymmval
|
|
.extern aymmval
|
|
#endif
|
|
#ifdef CONTEXT_USING_AVX512F
|
|
.extern zmmval
|
|
.extern azmmval
|
|
.extern opmaskval
|
|
.extern aopmaskval
|
|
#endif
|
|
.extern fpSaveArea
|
|
|
|
.text
|
|
|
|
# void ChangeRegsWrapper();
|
|
# This wrapper saves and restores the registers used by ChangeRegs.
|
|
# This is done in the wrapper since we want ChangeRegs to actually
|
|
# change the register values but not to affect the application itself.
|
|
# The tool may intercept ChangeRegs and replace it with its own function.
|
|
#
|
|
# Register usage:
|
|
# eax - used (implicitly) by xsave
|
|
# ebx - used for testing the gpr values
|
|
# ecx - used for holding a pointer to the fp save area (used by fxsave)
|
|
# edx - used (implicitly) by xsave
|
|
# st0 - used (implicitly) for loading a value to the FPU stack
|
|
# st2 - used for testing the FPU values
|
|
# xmm0 - used for testing the sse (xmm) values
|
|
# ymm1 - used for testing the avx (ymm) values
|
|
# zmm5 - used for testing the avx512 (zmm) values
|
|
# k3 - used for testing the opmask register values
|
|
#ifndef TARGET_MAC
|
|
.type ChangeRegsWrapper, @function
|
|
#endif
|
|
.global ChangeRegsWrapper
|
|
ChangeRegsWrapper:
|
|
# Save the necessary GPRs
|
|
push %eax
|
|
push %ebx
|
|
push %ecx
|
|
push %edx
|
|
|
|
#ifdef CONTEXT_USING_AVX512F
|
|
# Save the necessary mask registers
|
|
kmovw %k3, %eax
|
|
push %eax
|
|
#endif
|
|
|
|
# Allign the fpSaveArea
|
|
lea fpSaveArea, %ecx
|
|
add $0x40,%ecx
|
|
and $0xffffffc0,%ecx
|
|
# Save the floating-point state
|
|
#if defined(CONTEXT_USING_AVX) || defined(CONTEXT_USING_AVX512F)
|
|
push %edx
|
|
xor %edx, %edx
|
|
mov $7, %eax
|
|
xsave (%ecx)
|
|
#else
|
|
fxsave (%ecx)
|
|
#endif
|
|
|
|
# Now call ChangeRegs - do the actual test.
|
|
# The tool may intercept this function and modify the register values itself.
|
|
call ChangeRegs
|
|
|
|
# Placeholder for PIN_ExecuteAt
|
|
call ExecuteAt
|
|
|
|
# Save the modified values to memory so the tool can ispect them.
|
|
# This is relevant only when the tool modifies the values.
|
|
call SaveRegsToMem
|
|
|
|
# Restore the floating-point state
|
|
#if defined(CONTEXT_USING_AVX) || defined(CONTEXT_USING_AVX512F)
|
|
mov $7, %eax
|
|
xrstor (%ecx)
|
|
pop %edx
|
|
#else
|
|
fxrstor (%ecx)
|
|
#endif
|
|
|
|
#ifdef CONTEXT_USING_AVX512F
|
|
# Restore the mask registers
|
|
pop %eax
|
|
kmovw %eax, %k3
|
|
#endif
|
|
|
|
# Restore the GPRs
|
|
pop %edx
|
|
pop %ecx
|
|
pop %ebx
|
|
pop %eax
|
|
ret
|
|
|
|
# void ChangeRegs();
|
|
# For register usage see ChangeRegsWrapper above.
|
|
#ifndef TARGET_MAC
|
|
.type ChangeRegs, @function
|
|
#endif
|
|
.global ChangeRegs
|
|
ChangeRegs:
|
|
# TEST: load the new value to ebx
|
|
mov gprval, %ebx
|
|
# prepare the test value at the top of the FPU stack
|
|
fldt stval
|
|
# TEST: load the new value to st2
|
|
fst %st(2)
|
|
# TEST: load the new value to xmm0
|
|
movdqu xmmval, %xmm0
|
|
#ifdef CONTEXT_USING_AVX
|
|
# TEST: load the new value to ymm1
|
|
vmovdqu ymmval, %ymm1
|
|
#endif
|
|
#ifdef CONTEXT_USING_AVX512F
|
|
# TEST: load the new value to zmm5
|
|
vmovdqu32 zmmval, %zmm5
|
|
# TEST: load the new value to k3
|
|
kmovw opmaskval, %k3
|
|
#endif
|
|
ret
|
|
|
|
# void ExecuteAt();
|
|
#ifndef TARGET_MAC
|
|
.type ExecuteAt, @function
|
|
#endif
|
|
.global ExecuteAt
|
|
ExecuteAt:
|
|
ret
|
|
|
|
# void SaveRegsToMem();
|
|
# Save the necessary registers to memory.
|
|
# The tool will then compare the value stored in memory to the ones it expects to find.
|
|
# For register usage see ChangeRegsWrapper above.
|
|
#ifndef TARGET_MAC
|
|
.type SaveRegsToMem, @function
|
|
#endif
|
|
.global SaveRegsToMem
|
|
SaveRegsToMem:
|
|
# TEST: store the new value of ebx
|
|
mov %ebx, agprval
|
|
# prepare the test value at the top of the FPU stack
|
|
fld %st(2)
|
|
# TEST: store the new value of st2
|
|
fstpt astval
|
|
# TEST: store the new value of xmm0
|
|
movdqu %xmm0, axmmval
|
|
#ifdef CONTEXT_USING_AVX
|
|
# TEST: store the new value of ymm1
|
|
vmovdqu %ymm1, aymmval
|
|
#endif
|
|
#ifdef CONTEXT_USING_AVX512F
|
|
# TEST: store the new value of zmm5
|
|
vmovdqu32 %zmm5, azmmval
|
|
# TEST: store the new value of k3
|
|
kmovw %k3, aopmaskval
|
|
#endif
|
|
ret
|