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