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.
354 lines
11 KiB
354 lines
11 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.
|
|
*/
|
|
|
|
|
|
/* ===================================================================== */
|
|
/*! @file
|
|
*
|
|
* This file shows how functions with floating point arguments can be wrapped.
|
|
* FP wrappers are not supported in Pin yet.
|
|
*/
|
|
|
|
/* ===================================================================== */
|
|
#include "pin.H"
|
|
#include <iostream>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
struct DOUBLE_STRUCT
|
|
{
|
|
int _d0;
|
|
int _d1;
|
|
};
|
|
|
|
/*
|
|
* A wrapper for
|
|
* int func(int, float, int)
|
|
*/
|
|
int fp_func3_wrapper( CONTEXT * ctxt, AFUNPTR fp_func3_ptr, int i1, float f2, int i3 )
|
|
{
|
|
|
|
int res;
|
|
#ifdef TARGET_IA32
|
|
printf("fp_func3_wrapper parameters: %d, %f, %d\n", i1, f2, i3);
|
|
fflush(stdout);
|
|
|
|
/*
|
|
* parameter of type "float" is on stack and located in 4 bytes like integer
|
|
*/
|
|
int f2_int = *(int *)(&f2);
|
|
PIN_CallApplicationFunction( ctxt, PIN_ThreadId(),
|
|
CALLINGSTD_DEFAULT, fp_func3_ptr, NULL,
|
|
PIN_PARG(int), &res,
|
|
PIN_PARG(int), i1,
|
|
PIN_PARG(int), f2_int,
|
|
PIN_PARG(int), i3,
|
|
PIN_PARG_END() );
|
|
#else
|
|
|
|
/*
|
|
* all fp parameters are in xmm registers
|
|
* take them from the context
|
|
*/
|
|
FPSTATE fpState;
|
|
PIN_GetContextFPState(ctxt, &fpState);
|
|
memcpy(&f2, &fpState.fxsave_legacy._xmms[0], sizeof(f2));
|
|
printf("fp_func3_wrapper parameters: %d, %f, %d\n", i1, f2, i3);
|
|
fflush(stdout);
|
|
|
|
// all fp args are in xmm regs in context - do not pass any args to the app function
|
|
PIN_CallApplicationFunction( ctxt, PIN_ThreadId(),
|
|
CALLINGSTD_DEFAULT, fp_func3_ptr, NULL,
|
|
PIN_PARG(int), &res,
|
|
PIN_PARG(int), i1,
|
|
PIN_PARG(int), i3,
|
|
PIN_PARG_END() );
|
|
#endif
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
/*
|
|
* A wrapper for
|
|
* float func(double, float, int, double)
|
|
*/
|
|
float fp_func4_wrapper( CONTEXT * ctxt, AFUNPTR fp_ptr, double d1, float f2, int i3, double d4)
|
|
{
|
|
float resf;
|
|
|
|
#ifdef TARGET_IA32
|
|
printf("fp_func4_wrapper parameters: %e, %f, %d, %e\n", d1, f2, i3, d4);
|
|
fflush(stdout);
|
|
|
|
/*
|
|
* parameter of type "double" is on stack and located in 8 bytes
|
|
*/
|
|
DOUBLE_STRUCT *d_param1 = (DOUBLE_STRUCT *)&d1;
|
|
DOUBLE_STRUCT *d_param4 = (DOUBLE_STRUCT *)&d4;
|
|
|
|
|
|
/*
|
|
* parameter of type "float" is on stack and located in 4 bytes like integer
|
|
*/
|
|
int f2_int = *(int *)(&f2);
|
|
PIN_CallApplicationFunction( ctxt, PIN_ThreadId(),
|
|
CALLINGSTD_DEFAULT, fp_ptr, NULL,
|
|
PIN_PARG(float), &resf,
|
|
PIN_PARG(int), d_param1->_d0, // lower part of d1
|
|
PIN_PARG(int), d_param1->_d1, // upper part of d1
|
|
PIN_PARG(int), f2_int,
|
|
PIN_PARG(int), i3,
|
|
PIN_PARG(int), d_param4->_d0, // lower part of d4
|
|
PIN_PARG(int), d_param4->_d1, // upper part of d4
|
|
PIN_PARG_END() );
|
|
|
|
#else
|
|
FPSTATE fpState;
|
|
|
|
/*
|
|
* all fp parameters are in xmm registers
|
|
* take them from the context
|
|
*/
|
|
PIN_GetContextFPState(ctxt, &fpState);
|
|
memcpy(&d1, &fpState.fxsave_legacy._xmms[0], sizeof(d1));
|
|
memcpy(&f2, &fpState.fxsave_legacy._xmms[1], sizeof(f2));
|
|
memcpy(&d4, &fpState.fxsave_legacy._xmms[2], sizeof(d4));
|
|
|
|
|
|
printf("fp_func4_wrapper parameters: %e, %f, %d, %e\n", d1, f2, i3, d4);
|
|
fflush(stdout);
|
|
|
|
// all fp args are in xmm regs in context - only pass the int args to the app function
|
|
PIN_CallApplicationFunction( ctxt, PIN_ThreadId(),
|
|
CALLINGSTD_DEFAULT, fp_ptr, NULL,
|
|
PIN_PARG(float), &resf,
|
|
PIN_PARG(int), i3,
|
|
PIN_PARG_END() );
|
|
|
|
#endif
|
|
printf("fp_func4_wrapper result: %f\n", resf);
|
|
fflush(stdout);
|
|
|
|
return resf;
|
|
}
|
|
|
|
|
|
double fp_func1_wrapper( CONTEXT * ctxt, AFUNPTR fp_ptr, double d1)
|
|
{
|
|
double resd;
|
|
|
|
#ifdef TARGET_IA32
|
|
printf("fp_func1_wrapper parameters: %e\n", d1);
|
|
fflush(stdout);
|
|
|
|
/*
|
|
* parameter of type "double" is on stack and located in 8 bytes
|
|
*/
|
|
DOUBLE_STRUCT *d_param1 = (DOUBLE_STRUCT *)&d1;
|
|
|
|
|
|
PIN_CallApplicationFunction( ctxt, PIN_ThreadId(),
|
|
CALLINGSTD_DEFAULT, fp_ptr, NULL,
|
|
PIN_PARG(double), &resd,
|
|
PIN_PARG(int), d_param1->_d0,
|
|
PIN_PARG(int), d_param1->_d1,
|
|
PIN_PARG_END() );
|
|
|
|
|
|
#else
|
|
FPSTATE fpState;
|
|
|
|
/*
|
|
* all fp parameters are in xmm registers
|
|
* take them from the context
|
|
*/
|
|
|
|
PIN_GetContextFPState(ctxt, &fpState);
|
|
memcpy(&d1, &fpState.fxsave_legacy._xmms[0], sizeof(d1));
|
|
printf("fp_func1_wrapper parameters: %e\n", d1);
|
|
fflush(stdout);
|
|
// all fp args are in xmm regs in context - do not pass any args to the app function
|
|
PIN_CallApplicationFunction( ctxt, PIN_ThreadId(),
|
|
CALLINGSTD_DEFAULT, fp_ptr, NULL,
|
|
PIN_PARG(double), &resd,
|
|
PIN_PARG_END() );
|
|
|
|
|
|
#endif
|
|
|
|
printf("fp_func1_wrapper result: %e\n", resd);
|
|
fflush(stdout);
|
|
|
|
return resd;
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
VOID ImageLoad(IMG img, VOID *v)
|
|
{
|
|
/*
|
|
* Instrument function
|
|
* int func3(double, float, int, double)
|
|
*/
|
|
RTN rtn = RTN_FindByName(img, "fp_func3");
|
|
if (RTN_Valid(rtn))
|
|
{
|
|
//printf("Replace fp_func3\n");
|
|
#ifdef TARGET_IA32
|
|
PROTO proto_func3 = PROTO_Allocate( PIN_PARG(int), CALLINGSTD_DEFAULT,
|
|
"fp_func3", PIN_PARG(int), PIN_PARG(int),
|
|
PIN_PARG(int), PIN_PARG_END() );
|
|
|
|
RTN_ReplaceSignature(
|
|
rtn, AFUNPTR(fp_func3_wrapper),
|
|
IARG_PROTOTYPE, proto_func3,
|
|
IARG_CONTEXT,
|
|
IARG_ORIG_FUNCPTR,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 1,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 2,
|
|
IARG_END);
|
|
#else // TARGET_IA32E
|
|
PROTO proto_func3 = PROTO_Allocate( PIN_PARG(int), CALLINGSTD_DEFAULT,
|
|
"fp_func3", PIN_PARG(int), PIN_PARG(int),
|
|
PIN_PARG_END() );
|
|
|
|
RTN_ReplaceSignature(
|
|
rtn, AFUNPTR(fp_func3_wrapper),
|
|
IARG_PROTOTYPE, proto_func3,
|
|
IARG_CONTEXT,
|
|
IARG_ORIG_FUNCPTR,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 1,
|
|
IARG_END);
|
|
|
|
#endif
|
|
|
|
PROTO_Free( proto_func3 );
|
|
}
|
|
|
|
rtn = RTN_FindByName(img, "fp_func4");
|
|
if (RTN_Valid(rtn))
|
|
{
|
|
//printf("Replace fp_func4\n");
|
|
//
|
|
// float fp_func4(double d1, float f2, int i3, double d4)
|
|
//
|
|
#ifdef TARGET_IA32
|
|
PROTO proto_func4 = PROTO_Allocate( PIN_PARG(float), CALLINGSTD_DEFAULT,
|
|
"fp_func4",
|
|
PIN_PARG(int), // double p1
|
|
PIN_PARG(int), // double p2
|
|
PIN_PARG(int), // float
|
|
PIN_PARG(int), // int
|
|
PIN_PARG(int), // double p1
|
|
PIN_PARG(int), // double p2
|
|
|
|
PIN_PARG_END() );
|
|
|
|
RTN_ReplaceSignature(
|
|
rtn, AFUNPTR(fp_func4_wrapper),
|
|
IARG_PROTOTYPE, proto_func4,
|
|
IARG_CONTEXT,
|
|
IARG_ORIG_FUNCPTR,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 1,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 2,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 3,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 4,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 5,
|
|
IARG_END);
|
|
#else
|
|
// only i3 is in register, other parameters in xmm
|
|
PROTO proto_func4 = PROTO_Allocate( PIN_PARG(float), CALLINGSTD_DEFAULT,
|
|
"fp_func4",
|
|
PIN_PARG(int),
|
|
PIN_PARG_END() );
|
|
|
|
RTN_ReplaceSignature(
|
|
rtn, AFUNPTR(fp_func4_wrapper),
|
|
IARG_PROTOTYPE, proto_func4,
|
|
IARG_CONTEXT,
|
|
IARG_ORIG_FUNCPTR,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
|
|
IARG_END);
|
|
|
|
#endif
|
|
|
|
PROTO_Free( proto_func4 );
|
|
}
|
|
|
|
rtn = RTN_FindByName(img, "fp_func1");
|
|
if (RTN_Valid(rtn))
|
|
{
|
|
//printf("Replace fp_func1\n");
|
|
//
|
|
// double fp_func1(double d1)
|
|
//
|
|
#ifdef TARGET_IA32
|
|
|
|
// d1 on stack, 8 bytes
|
|
// passed as 2 integers
|
|
PROTO proto_func1 = PROTO_Allocate( PIN_PARG(double), CALLINGSTD_DEFAULT,
|
|
"fp_func1",
|
|
PIN_PARG(int), // d1 lower
|
|
PIN_PARG(int), // d1 upper
|
|
PIN_PARG_END() );
|
|
|
|
RTN_ReplaceSignature(
|
|
rtn, AFUNPTR(fp_func1_wrapper),
|
|
IARG_PROTOTYPE, proto_func1,
|
|
IARG_CONTEXT,
|
|
IARG_ORIG_FUNCPTR,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 1,
|
|
IARG_END);
|
|
#else
|
|
// all parameters in xmm, will be taken from context; nothing to be passed
|
|
PROTO proto_func1 = PROTO_Allocate( PIN_PARG(double), CALLINGSTD_DEFAULT,
|
|
"fp_func1",
|
|
PIN_PARG_END() );
|
|
|
|
RTN_ReplaceSignature(
|
|
rtn, AFUNPTR(fp_func1_wrapper),
|
|
IARG_PROTOTYPE, proto_func1,
|
|
IARG_CONTEXT,
|
|
IARG_ORIG_FUNCPTR,
|
|
IARG_END);
|
|
|
|
#endif
|
|
|
|
PROTO_Free( proto_func1 );
|
|
}
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
int main(INT32 argc, CHAR *argv[])
|
|
{
|
|
PIN_InitSymbols();
|
|
|
|
PIN_Init(argc, argv);
|
|
|
|
IMG_AddInstrumentFunction(ImageLoad, 0);
|
|
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
/* eof */
|
|
/* ===================================================================== */
|
|
|