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.
135 lines
3.7 KiB
135 lines
3.7 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.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <sched.h>
|
|
#include "pin.H"
|
|
|
|
using std::cout;
|
|
using std::cerr;
|
|
using std::endl;
|
|
using std::flush;
|
|
|
|
|
|
typedef void (*AppFunSig)(unsigned int, pid_t);
|
|
AppFunSig OrigThreadInit = NULL;
|
|
AppFunSig OrigThreadFini = NULL;
|
|
|
|
|
|
static RTN GetProbableRtn(IMG img, const char* name)
|
|
{
|
|
RTN rtn = RTN_FindByName(img, name);
|
|
if (!RTN_Valid(rtn))
|
|
{
|
|
cerr << "TOOL ERROR: Unable to find the function \"" << name << "\"" << endl;
|
|
PIN_ExitProcess(101);
|
|
}
|
|
if (!RTN_IsSafeForProbedInsertion(rtn))
|
|
{
|
|
cerr << "TOOL ERROR: The function \"" << name << "\" is not safe for probe insertion" << endl;
|
|
PIN_ExitProcess(102);
|
|
}
|
|
return rtn;
|
|
}
|
|
|
|
|
|
static RTN GetReplacableRtn(IMG img, const char* name)
|
|
{
|
|
RTN rtn = RTN_FindByName(img, name);
|
|
if (!RTN_Valid(rtn))
|
|
{
|
|
cerr << "TOOL ERROR: Unable to find the function \"" << name << "\"" << endl;
|
|
PIN_ExitProcess(103);
|
|
}
|
|
if (!RTN_IsSafeForProbedReplacement(rtn))
|
|
{
|
|
cerr << "TOOL ERROR: The function \"" << name << "\" is not safe for replacement" << endl;
|
|
PIN_ExitProcess(104);
|
|
}
|
|
return rtn;
|
|
}
|
|
|
|
|
|
static void OnSecondaryThreadInit(unsigned int threadNum, pid_t tid)
|
|
{
|
|
PIN_LockClient();
|
|
if (NULL == OrigThreadInit)
|
|
{
|
|
cerr << "TOOL ERROR: Attempting to call SecondaryThreadInit but it is a NULL pointer" << endl;
|
|
PIN_ExitProcess(105);
|
|
}
|
|
OrigThreadInit(threadNum, tid);
|
|
PIN_UnlockClient();
|
|
}
|
|
|
|
|
|
static void OnSecondaryThreadFini(unsigned int threadNum, pid_t tid)
|
|
{
|
|
PIN_LockClient();
|
|
if (NULL == OrigThreadFini)
|
|
{
|
|
cerr << "TOOL ERROR: Attempting to call SecondaryThreadFini but it is a NULL pointer" << endl;
|
|
PIN_ExitProcess(106);
|
|
}
|
|
OrigThreadFini(threadNum, tid);
|
|
PIN_UnlockClient();
|
|
}
|
|
|
|
|
|
static void OnSecondaryThreadWork()
|
|
{
|
|
PIN_LockClient();
|
|
cout << "TOOL: (" << PIN_GetTid() << ") executing OnSecondaryThreadWork" << endl << flush;
|
|
sched_yield();
|
|
PIN_UnlockClient();
|
|
}
|
|
|
|
|
|
static void OnReleaseThreads(ADDRINT doRelease)
|
|
{
|
|
PIN_LockClient();
|
|
*((bool*)doRelease) = true;
|
|
cout << "TOOL: Released the threads, now waiting a few seconds for them to reach the lock." << endl;
|
|
PIN_Sleep(5*1000);
|
|
PIN_UnlockClient();
|
|
}
|
|
|
|
|
|
static VOID Image(IMG img, VOID* v)
|
|
{
|
|
if (!IMG_IsMainExecutable(img)) return;
|
|
|
|
RTN secondaryThreadInitRtn = GetReplacableRtn(img, "SecondaryThreadInit");
|
|
OrigThreadInit = (AppFunSig)RTN_ReplaceProbed(secondaryThreadInitRtn, AFUNPTR(OnSecondaryThreadInit));
|
|
|
|
RTN secondaryThreadFiniRtn = GetReplacableRtn(img, "SecondaryThreadFini");
|
|
OrigThreadFini = (AppFunSig)RTN_ReplaceProbed(secondaryThreadFiniRtn, AFUNPTR(OnSecondaryThreadFini));
|
|
|
|
RTN secondaryThreadWorkRtn = GetProbableRtn(img, "SecondaryThreadWork");
|
|
RTN_InsertCallProbed(secondaryThreadWorkRtn, IPOINT_BEFORE, AFUNPTR(OnSecondaryThreadWork), IARG_END);
|
|
|
|
RTN releaseThreadsRtn = GetProbableRtn(img, "ReleaseThreads");
|
|
RTN_InsertCallProbed(releaseThreadsRtn, IPOINT_BEFORE, AFUNPTR(OnReleaseThreads),
|
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END);
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
PIN_Init(argc,argv);
|
|
PIN_InitSymbols();
|
|
|
|
IMG_AddInstrumentFunction(Image, 0);
|
|
|
|
PIN_StartProgram(); // never returns
|
|
return 0;
|
|
}
|