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.

124 lines
3.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.
*/
// The tool callapp9.cpp and application inner.c showed a bug with the way REG_INST_G0
// is handled. That register should have the value "1" when executing code
// from PIN_CallApplicationFunction() and the value "0" when executing other
// code. However, after execution returns from the replaced function, REG_INST_G0
// continued to have the value "1". The correct behavior is is for REG_INST_G0
// to have the value "0" when it returns from the replacement function.
//
// The correct output is:
// At Inner G0=0
// Calling replaced Replaced()
// REPLACE_Replaced: REG_INST_G0=1
// At Inner G0=1
// REPLACE_Replaced: REG_INST_G0=1
// Returning from replaced Replaced()
// i=2
// At Inner G0=0
#include <stdio.h>
#include "pin.H"
KNOB<BOOL> KnobUseIargConstContext(KNOB_MODE_WRITEONCE, "pintool",
"const_context", "0", "use IARG_CONST_CONTEXT");
static REG scratchReg;
int REPLACE_Replaced(CONTEXT *context, THREADID tid, AFUNPTR func)
{
int ret;
fprintf(stderr, "Calling replaced Replaced()\n");
fflush(stderr);
CONTEXT writableContext, *ctxt;
if (KnobUseIargConstContext)
{ // need to copy the ctxt into a writable context
PIN_SaveContext(context, &writableContext);
ctxt = &writableContext;
}
else
{
ctxt = context;
}
PIN_SetContextReg(ctxt, scratchReg, 1);
fprintf(stderr, "REPLACE_Replaced: REG_INST_G0=0x%lx\n", (unsigned long)PIN_GetContextReg(ctxt, scratchReg));
fflush(stderr);
PIN_CallApplicationFunction(ctxt, tid, CALLINGSTD_DEFAULT, func, NULL,
PIN_PARG(int), &ret,
PIN_PARG_END());
fprintf(stderr, "REPLACE_Replaced: REG_INST_G0=0x%lx\n", (unsigned long)PIN_GetContextReg(ctxt, scratchReg));
fprintf(stderr, "Returning from replaced Replaced()\n");
fflush(stderr);
return ret;
}
void AtInner(ADDRINT g0)
{
fprintf(stderr, "At Inner G0=%d\n", (int)g0);
fflush(stderr);
}
VOID Image(IMG img, void *v)
{
RTN rtn = RTN_FindByName(img, "Replaced");
if (RTN_Valid(rtn))
{
PROTO proto = PROTO_Allocate(PIN_PARG(int), CALLINGSTD_DEFAULT, "Replaced", PIN_PARG_END());
RTN_ReplaceSignature(rtn, AFUNPTR(REPLACE_Replaced),
IARG_PROTOTYPE, proto,
(KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT,
IARG_THREAD_ID,
IARG_ORIG_FUNCPTR,
IARG_END);
PROTO_Free(proto);
}
rtn = RTN_FindByName(img, "Inner");
if (RTN_Valid(rtn))
{
RTN_Open(rtn);
RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(AtInner), IARG_REG_VALUE, scratchReg, IARG_END);
RTN_Close(rtn);
}
}
VOID OnThread(THREADID threadIndex, CONTEXT *ctxt, INT32 flags, VOID *v)
{
PIN_SetContextReg(ctxt, scratchReg, 0);
}
int main(int argc, char **argv)
{
PIN_Init(argc, argv);
PIN_InitSymbols();
scratchReg = PIN_ClaimToolRegister();
if (!REG_valid(scratchReg))
{
fprintf (stderr, "Cannot allocate a scratch register.\n");
return 1;
}
PIN_AddThreadStartFunction(OnThread, 0);
IMG_AddInstrumentFunction(Image, 0);
PIN_StartProgram();
return 0;
}