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.

148 lines
3.8 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.
*/
// leave.cpp -- testing the leave instruction's memory address
#include <iostream>
#include <iomanip>
#include <fstream>
#include "pin.H"
extern "C" {
#include "xed-interface.h"
using std::cerr;
using std::string;
using std::endl;
}
class simple_test_t
{
public:
simple_test_t()
: knob_output_file(KNOB_MODE_WRITEONCE,"pintool", "o",
"leave.out", "specify profile file name")
{
out = 0;
}
~simple_test_t()
{
if (out)
out->close();
}
std::ofstream* out;
KNOB<string> knob_output_file;
void activate()
{
string filename = knob_output_file.Value();
out = new std::ofstream(filename.c_str());
PIN_AddThreadStartFunction(reinterpret_cast<THREAD_START_CALLBACK>(thread_begin),
this);
PIN_AddThreadFiniFunction(reinterpret_cast<THREAD_FINI_CALLBACK>(thread_end),
this);
TRACE_AddInstrumentFunction(reinterpret_cast<TRACE_INSTRUMENT_CALLBACK>(instrument_trace),
this);
*out << "tool activated" << endl;
}
static void thread_begin(THREADID tid, CONTEXT *ctxt, INT32 flags, simple_test_t* pthis)
{
}
static void thread_end(THREADID tid, const CONTEXT *ctxt, INT32 code, simple_test_t* pthis)
{
}
static void print_memop(ADDRINT memea,
ADDRINT memsize,
ADDRINT pc,
THREADID tid,
simple_test_t* pthis ) {
*pthis->out
<< std::hex << std::setw(sizeof(ADDRINT)*2)
<< pc
<< " TID: "
<< std::setw(2)
<< tid
<< " LEAVE memea: "
<< std::setw(sizeof(ADDRINT)*2)
<< memea
<< " length " << memsize
<< std::endl;
}
void instrument_instruction(INS ins)
{
*out << "INSTRUMENT: "
<< std::setw(16)
<< std::hex
<< INS_Address(ins)
<< std::dec
<< " "
<< INS_Disassemble(ins) << std::endl;
INS_InsertCall(ins, IPOINT_BEFORE,
AFUNPTR(print_memop),
IARG_MEMORYREAD_EA,
IARG_MEMORYREAD_SIZE,
IARG_INST_PTR,
IARG_THREAD_ID,
IARG_PTR, this,
IARG_END);
}
static bool check_for_leave(INS ins, simple_test_t* pthis) {
xed_iclass_enum_t iclass = static_cast<xed_iclass_enum_t>(INS_Opcode(ins));
if (iclass == XED_ICLASS_LEAVE)
return true;
return false;
}
static void instrument_trace(TRACE trace, simple_test_t* pthis) {
for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl))
for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins))
if (check_for_leave(ins, pthis))
pthis->instrument_instruction(ins);
}
}; // class
int usage()
{
cerr << "Usage: ..." << endl;
cerr << KNOB_BASE::StringKnobSummary() << endl;
return 1;
}
int main(int argc, char * argv[])
{
static simple_test_t t; // must be before usage...
PIN_InitSymbols();
if (PIN_Init(argc, argv))
return usage();
t.activate();
// Never returns
PIN_StartProgram();
return 0;
}