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.
192 lines
4.3 KiB
192 lines
4.3 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "pin.H"
|
|
|
|
/*
|
|
* Tests:
|
|
* before, after, and fall through instrumentation
|
|
* multiple instrumentation for the same instruction
|
|
* inlined and non-inlined
|
|
* references to global variables (RIP relative addressing in inlined function)
|
|
*
|
|
*/
|
|
|
|
int beforeVal = 0;
|
|
int afterVal = 0;
|
|
int takenVal = 0;
|
|
|
|
void beforeCall()
|
|
{
|
|
beforeVal = 1;
|
|
}
|
|
|
|
void beforeCheck()
|
|
{
|
|
if (beforeVal != 1)
|
|
{
|
|
fprintf(stderr,"Before failed\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
void afterCall()
|
|
{
|
|
afterVal = 2;
|
|
}
|
|
|
|
void afterCheck()
|
|
{
|
|
if (afterVal != 2)
|
|
{
|
|
fprintf(stderr,"After failed\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
void takenCall()
|
|
{
|
|
takenVal = 3;
|
|
}
|
|
|
|
void takenCheck()
|
|
{
|
|
if (takenVal != 3)
|
|
{
|
|
fprintf(stderr,"Taken failed\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
const INT32 phigh = 100;
|
|
const INT32 pdefault = 200;
|
|
const INT32 plow = 300;
|
|
|
|
UINT32 pri[10];
|
|
UINT32 pri_count = 0;
|
|
|
|
VOID RecordPriority(UINT32 val)
|
|
{
|
|
pri[pri_count] = val;
|
|
pri_count++;
|
|
}
|
|
|
|
UINT32 pri_val[] =
|
|
{
|
|
phigh,
|
|
phigh+1,
|
|
pdefault,
|
|
pdefault+1,
|
|
pdefault+2,
|
|
pdefault+3,
|
|
plow,
|
|
plow+1
|
|
};
|
|
|
|
VOID printAll(INT32 length)
|
|
{
|
|
for (INT32 i = 0; i < length; i++)
|
|
{
|
|
fprintf(stderr,"%d\n",pri[i]);
|
|
}
|
|
}
|
|
|
|
VOID CheckPriority()
|
|
{
|
|
UINT32 length = sizeof(pri_val)/sizeof(pri_val[0]);
|
|
|
|
if (pri_count != length)
|
|
{
|
|
fprintf(stderr,"Bad count expected %d, got %d\n", length, pri_count);
|
|
printAll(length);
|
|
exit(1);
|
|
}
|
|
|
|
if (memcmp(pri_val, pri, sizeof(pri_val)) != 0)
|
|
{
|
|
fprintf(stderr,"Bad pri\n");
|
|
printAll(length);
|
|
exit(1);
|
|
}
|
|
|
|
pri_count = 0;
|
|
}
|
|
|
|
VOID Priority(IPOINT ipoint, INS ins)
|
|
{
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_UINT32, plow, IARG_END);
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_UINT32, plow+1, IARG_END);
|
|
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_CALL_ORDER, CALL_ORDER_DEFAULT, IARG_UINT32, pdefault, IARG_END);
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_CALL_ORDER, CALL_ORDER_DEFAULT, IARG_UINT32, pdefault+1, IARG_END);
|
|
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_UINT32, pdefault+2, IARG_END);
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_UINT32, pdefault+3, IARG_END);
|
|
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_UINT32, phigh, IARG_END);
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(RecordPriority), IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_UINT32, phigh+1, IARG_END);
|
|
|
|
INS_InsertCall(ins, ipoint, AFUNPTR(CheckPriority), IARG_CALL_ORDER, CALL_ORDER_LAST, IARG_END);
|
|
}
|
|
|
|
|
|
|
|
VOID Ins(INS ins, VOID *v)
|
|
{
|
|
static bool before = false, after = false, taken = false;
|
|
|
|
if (!before)
|
|
{
|
|
|
|
INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(beforeCall), IARG_END);
|
|
INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(beforeCheck), IARG_END);
|
|
|
|
Priority(IPOINT_BEFORE, ins);
|
|
|
|
before = true;
|
|
}
|
|
|
|
if (!after && INS_IsValidForIpointAfter(ins))
|
|
{
|
|
INS_InsertCall(ins, IPOINT_AFTER, AFUNPTR(afterCall), IARG_END);
|
|
INS_InsertCall(ins, IPOINT_AFTER, AFUNPTR(afterCheck), IARG_END);
|
|
|
|
Priority(IPOINT_AFTER, ins);
|
|
|
|
after = true;
|
|
}
|
|
|
|
if (!taken && INS_IsValidForIpointTakenBranch(ins))
|
|
{
|
|
INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(takenCall), IARG_END);
|
|
INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(takenCheck), IARG_END);
|
|
|
|
Priority(IPOINT_TAKEN_BRANCH, ins);
|
|
|
|
taken = true;
|
|
}
|
|
}
|
|
|
|
int main(INT32 argc, CHAR **argv)
|
|
{
|
|
PIN_Init(argc, argv);
|
|
|
|
INS_AddInstrumentFunction(Ins, 0);
|
|
|
|
// Never returns
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|