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.
217 lines
8.2 KiB
217 lines
8.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.
|
|
*/
|
|
|
|
/*
|
|
* Test use of IARG_MULTI_MEMORYACCESS_EA on non-vgather* instructions
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "pin.H"
|
|
|
|
typedef struct memaccess {
|
|
ADDRINT memAddr;
|
|
UINT32 accessType; // 1==read, 2==read2, 3==write
|
|
INT32 memAccessSize;
|
|
} MEM_ACCESS;
|
|
|
|
typedef struct memaccessrec
|
|
{
|
|
int numMemAccesses;
|
|
ADDRINT ip;
|
|
MEM_ACCESS memAccesses[2];
|
|
} MEM_ACCESS_REC;
|
|
|
|
MEM_ACCESS_REC memAccessRec;
|
|
|
|
BOOL haveReadAccess = FALSE;
|
|
BOOL haveRead2Access = FALSE;
|
|
BOOL haveWriteAccess = FALSE;
|
|
BOOL haveReadAndWriteAccess = FALSE;
|
|
|
|
VOID RecordMemoryAcess(ADDRINT ip, UINT32 accessType, ADDRINT memAddr, INT32 memAccessSize)
|
|
{
|
|
if (memAccessRec.numMemAccesses > 0)
|
|
{
|
|
ASSERTX(ip==memAccessRec.ip);
|
|
}
|
|
ASSERTX(memAccessRec.numMemAccesses<2);
|
|
memAccessRec.ip = ip;
|
|
memAccessRec.memAccesses[memAccessRec.numMemAccesses].accessType = accessType;
|
|
memAccessRec.memAccesses[memAccessRec.numMemAccesses].memAddr = memAddr;
|
|
memAccessRec.memAccesses[memAccessRec.numMemAccesses].memAccessSize = memAccessSize;
|
|
memAccessRec.numMemAccesses++;
|
|
}
|
|
|
|
int CompareMemAccess (MEM_ACCESS *memAccess, PIN_MEM_ACCESS_INFO *pinMemAccessInfo)
|
|
{
|
|
if (memAccess->accessType==2)
|
|
{
|
|
haveRead2Access = TRUE;
|
|
}
|
|
else if (memAccess->accessType == 1)
|
|
{
|
|
haveReadAccess = TRUE;
|
|
}
|
|
else
|
|
{
|
|
haveWriteAccess = TRUE;
|
|
}
|
|
return ((memAccess->memAddr==pinMemAccessInfo->memoryAddress)
|
|
&&(memAccess->memAccessSize==(INT32)(pinMemAccessInfo->bytesAccessed))
|
|
&& ((pinMemAccessInfo->memopType==PIN_MEMOP_LOAD &&
|
|
(memAccess->accessType==1 || memAccess->accessType==2))
|
|
|| (pinMemAccessInfo->memopType==PIN_MEMOP_STORE && memAccess->accessType==3)));
|
|
}
|
|
|
|
VOID CompareMultiMemAccess(ADDRINT ip, PIN_MULTI_MEM_ACCESS_INFO* multiMemAccessInfo)
|
|
{
|
|
/*printf ("offsetof(PIN_MULTI_MEM_ACCESS_INFO, memop) %x\noffsetof(PIN_MEM_ACCESS_INFO, memoryAddress) %x\noffsetof(PIN_MEM_ACCESS_INFO, memopType) %x\noffsetof(PIN_MEM_ACCESS_INFO, bytesAccessed) %x\noffsetof(PIN_MEM_ACCESS_INFO, maskOn) %x\n",
|
|
offsetof(PIN_MULTI_MEM_ACCESS_INFO, memop),
|
|
offsetof(PIN_MEM_ACCESS_INFO, memoryAddress),
|
|
offsetof(PIN_MEM_ACCESS_INFO, memopType),
|
|
offsetof(PIN_MEM_ACCESS_INFO, bytesAccessed),
|
|
offsetof(PIN_MEM_ACCESS_INFO, maskOn));*/
|
|
if ((int)multiMemAccessInfo->numberOfMemops != memAccessRec.numMemAccesses)
|
|
{
|
|
printf ("got different number of mem accesses at ip %p multiMemAccessInfo->numberOfMemops %d memAccessRec.numMemAccesses %d\n",
|
|
(void *)ip, multiMemAccessInfo->numberOfMemops, memAccessRec.numMemAccesses);
|
|
fflush (stdout);
|
|
exit (1);
|
|
}
|
|
if (memAccessRec.ip != ip)
|
|
{
|
|
printf ("got different ips ip %p memAccessRec.ip %p\n",
|
|
(void *)ip, (void *)memAccessRec.ip);
|
|
fflush (stdout);
|
|
exit (1);
|
|
}
|
|
|
|
|
|
if (memAccessRec.numMemAccesses == 1)
|
|
{
|
|
PIN_MEM_ACCESS_INFO *pinMemAccessInfo = &(multiMemAccessInfo->memop[0]);
|
|
if (!CompareMemAccess(&memAccessRec.memAccesses[0], pinMemAccessInfo))
|
|
{
|
|
printf ("different mem accesses at ip %p\n", (void *)ip);
|
|
printf (" memAccessRec.accessType %d multiAccess.accessType %d\n", memAccessRec.memAccesses[0].accessType, pinMemAccessInfo->memopType);
|
|
printf (" memAccessRec.memAddr %p multiAccess.memAddr %p\n", (void *)memAccessRec.memAccesses[0].memAddr, (void *)pinMemAccessInfo->memoryAddress);
|
|
printf (" memAccessRec.memAccessSize %d multiAccess.memAccessSize %d\n", memAccessRec.memAccesses[0].memAccessSize,
|
|
pinMemAccessInfo->bytesAccessed);
|
|
fflush (stdout);
|
|
exit (1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (memAccessRec.memAccesses[1].accessType == 1 && memAccessRec.memAccesses[0].accessType==3)
|
|
{
|
|
haveReadAndWriteAccess = TRUE;
|
|
}
|
|
else if (memAccessRec.memAccesses[0].accessType == 1 && memAccessRec.memAccesses[1].accessType==3)
|
|
{
|
|
haveReadAndWriteAccess = TRUE;
|
|
}
|
|
|
|
if (! ((CompareMemAccess(&memAccessRec.memAccesses[0], &(multiMemAccessInfo->memop[0]))
|
|
&& CompareMemAccess(&memAccessRec.memAccesses[1], &(multiMemAccessInfo->memop[1])))
|
|
||(CompareMemAccess(&memAccessRec.memAccesses[0], &(multiMemAccessInfo->memop[1]))
|
|
&& CompareMemAccess(&memAccessRec.memAccesses[1], &(multiMemAccessInfo->memop[0])))))
|
|
{
|
|
printf ("different mem accesses at ip %p\n", (void *)ip);
|
|
printf (" memAccessRec[0].accessType %d memAccessRec[1].accessType %d\n", memAccessRec.memAccesses[0].accessType, memAccessRec.memAccesses[1].accessType);
|
|
printf (" memAccessRec[0].memAddr %p memAccessRec[1].memAddr %p\n", (void *)memAccessRec.memAccesses[0].memAddr, (void *)memAccessRec.memAccesses[1].memAddr);
|
|
printf (" memAccessRec[0].memAccessSize %d memAccessRec[1].memAccessSize %d\n", memAccessRec.memAccesses[0].memAccessSize,
|
|
memAccessRec.memAccesses[1].memAccessSize);
|
|
printf (" multiMemAccessInfo->memop[0].memopType %d multiMemAccessInfo->memop[1].memopType %d\n", multiMemAccessInfo->memop[0].memopType, multiMemAccessInfo->memop[1].memopType);
|
|
printf (" multiMemAccessInfo->memop[0].memoryAddress %p multiMemAccessInfo->memop[1].memoryAddress %p\n",
|
|
(void *)multiMemAccessInfo->memop[0].memoryAddress, (void *)multiMemAccessInfo->memop[1].memoryAddress);
|
|
printf (" multiMemAccessInfo->memop[0].bytesAccessed %d multiMemAccessInfo->memop[1].bytesAccessed %d\n", multiMemAccessInfo->memop[0].bytesAccessed, multiMemAccessInfo->memop[1].bytesAccessed);
|
|
fflush (stdout);
|
|
exit (1);
|
|
}
|
|
}
|
|
memAccessRec.numMemAccesses = 0;
|
|
}
|
|
|
|
// Is called for every instruction
|
|
VOID Instruction(INS ins, VOID *v)
|
|
{
|
|
BOOL hasMemoryAccess = FALSE;
|
|
|
|
if (INS_IsMemoryRead(ins))
|
|
{
|
|
hasMemoryAccess = TRUE;
|
|
INS_InsertCall(
|
|
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemoryAcess,
|
|
IARG_INST_PTR,
|
|
IARG_UINT32, 1,
|
|
IARG_MEMORYREAD_EA,
|
|
IARG_MEMORYREAD_SIZE,
|
|
IARG_END);
|
|
|
|
}
|
|
|
|
if (INS_HasMemoryRead2(ins))
|
|
{
|
|
hasMemoryAccess = TRUE;
|
|
INS_InsertCall(
|
|
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemoryAcess,
|
|
IARG_INST_PTR,
|
|
IARG_UINT32, 2,
|
|
IARG_MEMORYREAD2_EA,
|
|
IARG_MEMORYREAD_SIZE,
|
|
IARG_END);
|
|
}
|
|
|
|
if (INS_IsMemoryWrite(ins))
|
|
{
|
|
hasMemoryAccess = TRUE;
|
|
INS_InsertCall(
|
|
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemoryAcess,
|
|
IARG_INST_PTR,
|
|
IARG_UINT32, 3,
|
|
IARG_MEMORYWRITE_EA,
|
|
IARG_MEMORYWRITE_SIZE,
|
|
IARG_END);
|
|
}
|
|
if (hasMemoryAccess)
|
|
{
|
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)CompareMultiMemAccess,
|
|
IARG_INST_PTR,
|
|
IARG_MULTI_MEMORYACCESS_EA,
|
|
IARG_END);
|
|
}
|
|
}
|
|
|
|
VOID Fini(INT32 code, VOID *v)
|
|
{
|
|
if (!(haveReadAccess && haveRead2Access && haveWriteAccess && haveReadAndWriteAccess))
|
|
{
|
|
printf ("missing check of an accesstype haveReadAccess %d haveRead2Access %d haveWriteAccess %d haveReadAndWriteAccess %d\n",
|
|
haveReadAccess, haveRead2Access, haveWriteAccess, haveReadAndWriteAccess);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
PIN_Init(argc, argv);
|
|
|
|
|
|
INS_AddInstrumentFunction(Instruction, 0);
|
|
PIN_AddFiniFunction(Fini, 0);
|
|
memAccessRec.numMemAccesses = 0;
|
|
// Never returns
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|