/* * 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 #include #include #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 knob_output_file; void activate() { string filename = knob_output_file.Value(); out = new std::ofstream(filename.c_str()); PIN_AddThreadStartFunction(reinterpret_cast(thread_begin), this); PIN_AddThreadFiniFunction(reinterpret_cast(thread_end), this); TRACE_AddInstrumentFunction(reinterpret_cast(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(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; }