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.
140 lines
4.2 KiB
140 lines
4.2 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.
|
|
*/
|
|
|
|
/* ===================================================================== */
|
|
/*
|
|
* Execute up to the first system call, and then replay it without re-executing it
|
|
* to demonstrate that PIN_ReplaySyscall does what it says on the can.
|
|
*/
|
|
|
|
/* ===================================================================== */
|
|
/*! @file
|
|
*/
|
|
|
|
#include "pin.H"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <stdlib.h>
|
|
using std::ofstream;
|
|
using std::cerr;
|
|
using std::string;
|
|
using std::endl;
|
|
|
|
|
|
/* ===================================================================== */
|
|
/* Commandline Switches */
|
|
/* ===================================================================== */
|
|
|
|
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
|
|
"o", "replay_syscall.out", "specify file name");
|
|
|
|
ofstream TraceFile;
|
|
/* ===================================================================== */
|
|
|
|
static INT32 Usage()
|
|
{
|
|
cerr <<
|
|
"This pin tool checks the operation of the PIN_ReplaySyscall function\n"
|
|
"By executing a test code until it has executed a system call, then\n"
|
|
"replaying the system call, and checking that the SYSCALL_ENTRY and SYSCALL_EXIT\n"
|
|
" callbacks are called."
|
|
"\n";
|
|
cerr << KNOB_BASE::StringKnobSummary();
|
|
cerr << endl;
|
|
return -1;
|
|
}
|
|
|
|
static int syscallCount = 0;
|
|
static int callbackCount = 0;
|
|
|
|
static CONTEXT savedContext;
|
|
SYSCALL_STANDARD savedStd;
|
|
|
|
// Function called before the system call. We call this twice to make sure that
|
|
// we see the callbacks in the correct order in all cases.
|
|
static VOID syscallBefore(THREADID tid, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v)
|
|
{
|
|
UINT32 callNumber = UINT32 (ADDRINT(v) & 0xffffffff);
|
|
|
|
TraceFile << callNumber << " syscallBefore (" << PIN_GetSyscallNumber(ctxt, std) << ")" << endl;
|
|
|
|
if (callNumber == 1 && syscallCount == 0)
|
|
{
|
|
PIN_SaveContext (ctxt, &savedContext);
|
|
savedStd = std;
|
|
}
|
|
|
|
callbackCount++;
|
|
}
|
|
|
|
static VOID syscallAfter(THREADID tid, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v)
|
|
{
|
|
UINT32 callNumber = UINT32 (ADDRINT(v) & 0xffffffff);
|
|
|
|
// Note that the result will be wrong teh second time around, since we don't bother to
|
|
// save and restore the context after the system call. That's OK, this test isn't about
|
|
// that, which is up to a replayig tool anyway, but about whether the callbacks get made...
|
|
TraceFile << callNumber << " syscallAfter: result (" << PIN_GetSyscallReturn(ctxt, std) << ")" << endl;
|
|
if (callNumber == 2)
|
|
syscallCount++;
|
|
|
|
callbackCount++;
|
|
}
|
|
|
|
static VOID syscallInstructionInstrumentation (THREADID tid, CONTEXT * ctxt)
|
|
{
|
|
if (syscallCount == 1)
|
|
{
|
|
TraceFile << "Replaying system call; actual call is " << PIN_GetSyscallNumber(ctxt,savedStd) << "\n";
|
|
PIN_ReplaySyscallEntry(tid, &savedContext, savedStd);
|
|
PIN_ReplaySyscallExit (tid, &savedContext, savedStd);
|
|
if (callbackCount == 8)
|
|
{
|
|
TraceFile.close();
|
|
exit(0);
|
|
}
|
|
else
|
|
{
|
|
TraceFile << "***Bad callback count " << callbackCount << " should be 8\n";
|
|
TraceFile.close();
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void instrumentInstruction(INS ins, VOID *v)
|
|
{
|
|
if (!INS_IsSyscall(ins))
|
|
return;
|
|
|
|
INS_InsertCall (ins, IPOINT_BEFORE, (AFUNPTR)syscallInstructionInstrumentation,
|
|
IARG_THREAD_ID, IARG_CONTEXT, IARG_END);
|
|
}
|
|
|
|
int main(int argc, CHAR *argv[])
|
|
{
|
|
if( PIN_Init(argc,argv) )
|
|
{
|
|
return Usage();
|
|
}
|
|
|
|
TraceFile.open(KnobOutputFile.Value().c_str());
|
|
|
|
PIN_AddSyscallEntryFunction(syscallBefore, (VOID *)1);
|
|
PIN_AddSyscallEntryFunction(syscallBefore, (VOID *)2);
|
|
PIN_AddSyscallExitFunction(syscallAfter, (VOID *)1);
|
|
PIN_AddSyscallExitFunction(syscallAfter, (VOID *)2);
|
|
|
|
INS_AddInstrumentFunction (instrumentInstruction, 0);
|
|
|
|
PIN_StartProgram();
|
|
}
|