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.

95 lines
3.0 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 "init_alarm.H"
#include "control_manager.H"
using namespace CONTROLLER;
/// @cond INTERNAL_DOXYGEN
VOID INIT_ALARM::Activate(CONTROL_MANAGER* manager){
_manager = manager;
memset(_start_thread,0,sizeof(_start_thread));
_disabled = FALSE;
PIN_CALLBACK thread_start = PIN_AddThreadStartFunction(ThreadStart, this);
// other tools working with the controller might do some initialization in their
// thread start callback.
// need to make sure we are been call AFTER all thread start callbacks were called.
CALLBACK_SetExecutionOrder(thread_start, CALL_ORDER_LAST);
TRACE_AddInstrumentFunction(OnTrace, this);
}
VOID INIT_ALARM::ThreadStart(THREADID tid, CONTEXT *ctxt, INT32 flags, VOID *v){
INIT_ALARM *me = static_cast<INIT_ALARM*>(v);
me->_start_thread[tid] = TRUE;
ADDRINT first_ip = PIN_GetContextReg(ctxt, REG_INST_PTR);
me->_thread_first_ip.insert(first_ip);
// this IP might be already instrumented, so we need to reset
// the instrumentations on it's BB.
PIN_RemoveInstrumentationInRange(first_ip, first_ip+15);
}
VOID INIT_ALARM::OnTrace(TRACE trace, VOID *vthis){
INIT_ALARM *me = static_cast<INIT_ALARM*>(vthis);
INS ins = BBL_InsHead(TRACE_BblHead(trace));
ADDRINT first_ip = INS_Address(ins);
if (me->_thread_first_ip.find(first_ip) == me->_thread_first_ip.end()){
// the first instruction of the TARCE is not the first instruction of
// any new created thread
return;
}
INS_InsertIfCall(
ins, IPOINT_BEFORE, AFUNPTR(ShouldStart),
IARG_CALL_ORDER, me->_manager->GetInsOrder(),
IARG_ADDRINT, me,
IARG_THREAD_ID,
IARG_END);
if (me->_manager->PassContext())
{
INS_InsertThenCall(
ins, IPOINT_BEFORE, AFUNPTR(Start),
IARG_CALL_ORDER, me->_manager->GetInsOrder(),
IARG_CONTEXT,
IARG_INST_PTR,
IARG_THREAD_ID,
IARG_ADDRINT, me,
IARG_END);
}
else
{
INS_InsertThenCall(
ins, IPOINT_BEFORE, AFUNPTR(Start),
IARG_CALL_ORDER, me->_manager->GetInsOrder(),
IARG_ADDRINT, static_cast<ADDRINT>(0),
IARG_INST_PTR,
IARG_THREAD_ID,
IARG_ADDRINT, me,
IARG_END);
}
}
VOID INIT_ALARM::Start(CONTEXT *ctxt, ADDRINT ip, THREADID tid, VOID *vthis){
INIT_ALARM *me = static_cast<INIT_ALARM*>(vthis);
me->_start_thread[tid] = FALSE;
me->_manager->Fire(EVENT_START,ctxt,Addrint2VoidStar(ip),tid,TRUE);
}
/// @endcond