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.
138 lines
4.6 KiB
138 lines
4.6 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 "pin.H"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
using std::cerr;
|
|
using std::string;
|
|
using std::endl;
|
|
|
|
typedef struct {
|
|
THREADID tid;
|
|
ADDRINT pc;
|
|
ADDRINT nextAddress;
|
|
UINT32 readRegCount;
|
|
UINT32 writeRegCount;
|
|
ADDRINT instrSize;
|
|
CHAR type;
|
|
} FooBar;
|
|
|
|
FooBar accessInfo;
|
|
|
|
LOCALVAR std::ofstream log_inl;
|
|
|
|
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
|
|
"o", "inlined-stack-arg.out", "output file");
|
|
|
|
#if defined(TARGET_LINUX) && defined(TARGET_IA32E) && !defined(__INTEL_COMPILER)
|
|
// New GCC compilers (on 64 bits) do optimizations to RecordFirstInstructionInfo() (below) which today deny us from doing
|
|
// "stack value" optimization (See knob opt_stack_param_failure_assert, _disableStackOptimization and
|
|
// _canDeleteArgPushsAndArgStackUpdates for more details about the optimization).
|
|
// Therefore we use a pragma equivalent for -mno-sse2 compiler directive to turn off these optimizations.
|
|
// See comments below inside RecordFirstInstructionInfo() for more information)
|
|
# pragma GCC push_options
|
|
# pragma GCC target ("no-sse2")
|
|
#endif // #if defined(TARGET_LINUX) && defined(TARGET_IA32E) && !defined(__INTEL_COMPILER)
|
|
|
|
VOID RecordFirstInstructionInfo(UINT32 tid,
|
|
ADDRINT pcval,
|
|
ADDRINT nxtaddr,
|
|
UINT32 rregcnt,
|
|
UINT32 wregcnt,
|
|
ADDRINT inssz,
|
|
CHAR type)
|
|
{
|
|
accessInfo.tid = tid;
|
|
accessInfo.pc = pcval;
|
|
accessInfo.nextAddress = nxtaddr;
|
|
accessInfo.readRegCount = rregcnt;
|
|
accessInfo.writeRegCount = wregcnt;
|
|
accessInfo.instrSize = inssz;
|
|
accessInfo.type = type;
|
|
/*
|
|
* Note that this function is considered simple and is expected to be inlineable and in addition "stack value" optimization
|
|
* (KnobStackValueOpt) is also expected to work for this function on some tests (:inlined-stack-arg.test).
|
|
* However new compilers may do all kind of optimizations which will deny the "stack value" optimization. Currently added
|
|
* compiler directive flags (where needed) to deny these compiler optimizations which kill our optimization (at least until
|
|
* will be able to perform our optimization).
|
|
* Another option will be to write this function ourself in assembly. On one hand it is very logical since we want to test our
|
|
* current optimization and it is hard to do that if the compiler keeps doing new things which interfere our compiler
|
|
* optimizer.
|
|
* On the other hand letting the compiler do optimizations introduces new compiler optimizations which we need to be aware
|
|
* about in order to make updates to our optimizer (for example instructions which uses XMM registers which we didn't
|
|
* handle before)
|
|
*/
|
|
}
|
|
|
|
#if defined(TARGET_LINUX) && defined(TARGET_IA32E) && !defined(__INTEL_COMPILER)
|
|
# pragma GCC pop_options
|
|
#endif // #if defined(TARGET_LINUX) && defined(TARGET_IA32E) && !defined(__INTEL_COMPILER)
|
|
|
|
INT32 Usage()
|
|
{
|
|
cerr <<
|
|
"This tests if the stack arguments are passed correctly by an inlined analysis function"
|
|
"\n";
|
|
|
|
cerr << endl;
|
|
|
|
return -1;
|
|
}
|
|
|
|
VOID Instruction(INS ins, VOID *v)
|
|
{
|
|
|
|
ADDRINT nextAddr = INS_NextAddress(ins);
|
|
UINT32 maxRRegs = INS_MaxNumRRegs(ins);
|
|
UINT32 maxWRegs = INS_MaxNumWRegs(ins);
|
|
USIZE sz = INS_Size(ins);
|
|
|
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordFirstInstructionInfo,
|
|
IARG_THREAD_ID,
|
|
IARG_INST_PTR,
|
|
IARG_ADDRINT, nextAddr,
|
|
IARG_UINT32, maxRRegs,
|
|
IARG_UINT32, maxWRegs,
|
|
IARG_ADDRINT, sz,
|
|
IARG_UINT32, 'r', IARG_END);
|
|
}
|
|
|
|
VOID Fini(INT32 code, VOID *v)
|
|
{
|
|
log_inl << "Type " << accessInfo.type << "\n";
|
|
log_inl.close();
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
if( PIN_Init(argc,argv) )
|
|
{
|
|
return Usage();
|
|
}
|
|
|
|
string logfile = KnobOutputFile.Value();
|
|
|
|
log_inl.open(logfile.c_str());
|
|
|
|
INS_AddInstrumentFunction(Instruction, 0);
|
|
PIN_AddFiniFunction(Fini, 0);
|
|
|
|
// Never returns
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
/* eof */
|
|
/* ===================================================================== */
|