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.

136 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.
*/
#include <iostream>
#include <fstream>
#include "pin.H"
using std::string;
const ADDRINT BaseValue = 0x80808000;
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "reg_inst_gx.out", "trace file");
std::ofstream Out;
PIN_LOCK Lock;
VOID Error(std::string where, THREADID tid, UINT32 r, ADDRINT expect, ADDRINT val)
{
PIN_GetLock(&Lock, 1);
Out << "Mismatch " << where << ": tid=" << std::dec << tid << " (G" << r << ")" <<
", Expect " << std::hex << expect << ", Got " << std::hex << val << std::endl;
PIN_ReleaseLock(&Lock);
}
VOID ThreadStart(THREADID tid, CONTEXT *ctxt, int flags, VOID *v)
{
for (UINT32 r = 0; r <= 9; r++)
PIN_SetContextReg(ctxt, REG(REG_INST_G0 + r), BaseValue + tid + r);
}
VOID ThreadFini(THREADID tid, const CONTEXT *ctxt, INT32 code, VOID *v)
{
for (UINT32 r = 0; r <= 9; r++)
{
ADDRINT val = PIN_GetContextReg(ctxt, REG(REG_INST_G0 + r));
ADDRINT expect = BaseValue + tid + r;
if (expect != val)
Error("at thread exit", tid, r, expect, val);
}
}
VOID OnIns(THREADID tid,
#if defined(TARGET_IA32) || defined(TARGET_IA32E)
CONTEXT *ctxt,
#endif
ADDRINT g0, ADDRINT g1, ADDRINT g2, ADDRINT g3, ADDRINT g4,
ADDRINT g5, ADDRINT g6, ADDRINT g7, ADDRINT g8, ADDRINT g9)
{
ADDRINT gx[10];
gx[0] = g0;
gx[1] = g1;
gx[2] = g2;
gx[3] = g3;
gx[4] = g4;
gx[5] = g5;
gx[6] = g6;
gx[7] = g7;
gx[8] = g8;
gx[9] = g9;
for (UINT32 r = 0; r <= 9; r++)
{
ADDRINT expect = BaseValue + tid + r;
if (expect != gx[r])
Error("on IARG_REG_VALUE", tid, r, expect, gx[r]);
#if defined(TARGET_IA32) || defined(TARGET_IA32E)
ADDRINT val = PIN_GetContextReg(ctxt, REG(REG_INST_G0 + r));
if (expect != val)
Error("on IARG_CONTEXT", tid, r, expect, val);
#endif
}
}
VOID Instruction(INS ins,void * unused)
{
// Instrumenting every instruction is too slow.
//
static UINT32 Count = 0;
if (++Count < 100)
return;
Count = 0;
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)OnIns,
IARG_THREAD_ID,
#if defined(TARGET_IA32) || defined(TARGET_IA32E)
IARG_CONTEXT,
#endif
IARG_REG_VALUE, REG_INST_G0,
IARG_REG_VALUE, REG_INST_G1,
IARG_REG_VALUE, REG_INST_G2,
IARG_REG_VALUE, REG_INST_G3,
IARG_REG_VALUE, REG_INST_G4,
IARG_REG_VALUE, REG_INST_G5,
IARG_REG_VALUE, REG_INST_G6,
IARG_REG_VALUE, REG_INST_G7,
IARG_REG_VALUE, REG_INST_G8,
IARG_REG_VALUE, REG_INST_G9,
IARG_END);
}
VOID Fini(INT32 code, VOID *v)
{
Out << "(eof)" << std::endl;
Out.close();
}
int main(INT32 argc, CHAR **argv)
{
PIN_InitLock(&Lock);
PIN_Init(argc, argv);
PIN_InitLock(&Lock);
Out.open(KnobOutputFile.Value().c_str());
PIN_AddThreadStartFunction(ThreadStart, 0);
PIN_AddThreadFiniFunction(ThreadFini, 0);
INS_AddInstrumentFunction(Instruction, 0);
PIN_AddFiniFunction(Fini, 0);
// Never returns
PIN_StartProgram();
return 0;
}