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

/*
* 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;
}