18 #include <unordered_set>
20 #include <unordered_map>
27 #include <xmmintrin.h>
28 #include <immintrin.h>
31 #include "xed-interface.h"
32 #include "xed-common-hdrs.h"
35 #include <google/sparse_hash_map>
36 #include <google/dense_hash_map>
42 #define READ_ACTION (0)
43 #define WRITE_ACTION (0xff)
45 #define ONE_BYTE_READ_ACTION (0)
46 #define TWO_BYTE_READ_ACTION (0)
47 #define FOUR_BYTE_READ_ACTION (0)
48 #define EIGHT_BYTE_READ_ACTION (0)
50 #define ONE_BYTE_WRITE_ACTION (0xff)
51 #define TWO_BYTE_WRITE_ACTION (0xffff)
52 #define FOUR_BYTE_WRITE_ACTION (0xffffffff)
53 #define EIGHT_BYTE_WRITE_ACTION (0xffffffffffffffff)
55 #define IS_ACCESS_WITHIN_PAGE_BOUNDARY(accessAddr, accessLen) (PAGE_OFFSET((accessAddr)) <= (PAGE_OFFSET_MASK - (accessLen)))
58 #define MAX_REDUNDANT_CONTEXTS_TO_LOG (1000)
59 #define THREAD_MAX (1024)
61 #define ENCODE_ADDRESS_AND_ACCESS_LEN(addr, len) ((addr) | (((uint64_t)(len)) << 48))
62 #define DECODE_ADDRESS(addrAndLen) ((addrAndLen) & ((1L << 48) - 1))
63 #define DECODE_ACCESS_LEN(addrAndLen) ((addrAndLen) >> 48)
66 #define MAX_WRITE_OP_LENGTH (512)
67 #define MAX_WRITE_OPS_IN_INS (8)
68 #define MAX_REG_LENGTH (64)
70 #define MAX_SIMD_LENGTH (64)
71 #define MAX_SIMD_REGS (32)
110 #ifdef MULTI_THREADED
120 PIN_ERROR(
"Pin tool to gather calling context on each load and store.\n" + KNOB_BASE::StringKnobSummary() +
"\n");
131 char* envPath = getenv(
"CCTLIB_CLIENT_OUTPUT_FILE");
135 snprintf(name,
sizeof(name),
"%s", envPath);
138 gethostname(name + strlen(name),
MAX_FILE_PATH - strlen(name));
139 pid_t pid = getpid();
140 sprintf(name + strlen(name),
"%d", pid);
141 cerr <<
"\n Creating log file at:" << name <<
"\n";
146 for (
int i = 0; i < argc; i++) {
154 xed_state_init(&
LoadSpyGlobals.xedState, XED_MACHINE_MODE_LONG_64, (xed_address_width_enum_t)0, XED_ADDRESS_WIDTH_64b);
162 #define CACHELINE_ALIGNMENT 64
164 #define PAGE_ALIGNMENT 0x1000
166 #define CACHELINE_MASK (~63)
167 #define PAGE_MASK (~0xfff)
168 #define ISSAMECACHELINE(addr, accesslen) (((uint64_t)(addr) & (CACHELINE_ALIGNMENT - 1)) + (uint64_t)(accesslen) < CACHELINE_ALIGNMENT)
170 #define GET_CACHELINE_INDEX(x) ((x)&CACHELINE_MASK)
171 #define GET_PAGE_INDEX(x) ((x)&PAGE_MASK)
173 #define GET_CACHELINE_INNER_INDEX(x) ((x) & (CACHELINE_ALIGNMENT - 1))
174 #define GET_PAGE_INNER_INDEX(x) ((x) & (PAGE_ALIGNMENT - 1))
176 #define STATE_NONZERO 0
178 #define STATE_NOVISIT 2
179 #define VAL2STAT(value) (value == 0)
193 #ifdef MULTI_THREADED
196 unordered_map<uint64_t, RedLogs>::iterator it =
RedMap[threadId].find(key);
197 if (it ==
RedMap[threadId].end()) {
203 RedMap[threadId][key] = log;
206 it->second.zeroreads += zero;
208 it->second.state &= zero;
210 #ifdef MULTI_THREADED
217 xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xedd);
219 case XED_ICLASS_FLDENV:
220 case XED_ICLASS_FNSTENV:
221 case XED_ICLASS_FNSAVE:
222 case XED_ICLASS_FLDCW:
223 case XED_ICLASS_FNSTCW:
224 case XED_ICLASS_FXRSTOR:
225 case XED_ICLASS_FXRSTOR64:
226 case XED_ICLASS_FXSAVE:
227 case XED_ICLASS_FXSAVE64:
235 xed_decoded_inst_t xedd;
238 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
239 xed_category_enum_t cat = xed_decoded_inst_get_category(&xedd);
241 case XED_CATEGORY_AES:
242 case XED_CATEGORY_CONVERT:
243 case XED_CATEGORY_PCLMULQDQ:
244 case XED_CATEGORY_SSE:
245 case XED_CATEGORY_AVX2:
246 case XED_CATEGORY_AVX:
247 case XED_CATEGORY_MMX:
248 case XED_CATEGORY_DATAXFER: {
251 const xed_inst_t* xi = xed_decoded_inst_inst(&xedd);
252 int noperands = xed_inst_noperands(xi);
254 for (
int i = 0; i < noperands; i++) {
255 const xed_operand_t* op = xed_inst_operand(xi, i);
256 xed_operand_enum_t op_name = xed_operand_name(op);
257 if (XED_OPERAND_MEM0 == op_name) {
262 if (memOpIdx == -1) {
267 xed_operand_element_type_enum_t eType = xed_decoded_inst_operand_element_type(&xedd, memOpIdx);
269 case XED_OPERAND_ELEMENT_TYPE_FLOAT16:
270 case XED_OPERAND_ELEMENT_TYPE_SINGLE:
271 case XED_OPERAND_ELEMENT_TYPE_DOUBLE:
272 case XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE:
273 case XED_OPERAND_ELEMENT_TYPE_LONGBCD:
279 case XED_CATEGORY_X87_ALU:
280 case XED_CATEGORY_FCMOV:
285 case XED_CATEGORY_XSAVE:
286 case XED_CATEGORY_AVX2GATHER:
287 case XED_CATEGORY_STRINGOP:
292 assert(0 &&
"failed to disassemble instruction");
299 xed_decoded_inst_t xedd;
302 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
303 xed_iclass_enum_t iclassType = xed_decoded_inst_get_iclass(&xedd);
304 if (iclassType >= XED_ICLASS_F2XM1 && iclassType <= XED_ICLASS_FYL2XP1) {
307 if (iclassType >= XED_ICLASS_VBROADCASTSD && iclassType <= XED_ICLASS_VDPPS) {
310 if (iclassType >= XED_ICLASS_VRCPPS && iclassType <= XED_ICLASS_VSQRTSS) {
313 if (iclassType >= XED_ICLASS_VSUBPD && iclassType <= XED_ICLASS_VXORPS) {
316 switch (iclassType) {
317 case XED_ICLASS_ADDPD:
318 case XED_ICLASS_ADDPS:
319 case XED_ICLASS_ADDSD:
320 case XED_ICLASS_ADDSS:
321 case XED_ICLASS_ADDSUBPD:
322 case XED_ICLASS_ADDSUBPS:
323 case XED_ICLASS_ANDNPD:
324 case XED_ICLASS_ANDNPS:
325 case XED_ICLASS_ANDPD:
326 case XED_ICLASS_ANDPS:
327 case XED_ICLASS_BLENDPD:
328 case XED_ICLASS_BLENDPS:
329 case XED_ICLASS_BLENDVPD:
330 case XED_ICLASS_BLENDVPS:
331 case XED_ICLASS_CMPPD:
332 case XED_ICLASS_CMPPS:
333 case XED_ICLASS_CMPSD:
334 case XED_ICLASS_CMPSD_XMM:
335 case XED_ICLASS_COMISD:
336 case XED_ICLASS_COMISS:
337 case XED_ICLASS_CVTDQ2PD:
338 case XED_ICLASS_CVTDQ2PS:
339 case XED_ICLASS_CVTPD2PS:
340 case XED_ICLASS_CVTPI2PD:
341 case XED_ICLASS_CVTPI2PS:
342 case XED_ICLASS_CVTPS2PD:
343 case XED_ICLASS_CVTSD2SS:
344 case XED_ICLASS_CVTSI2SD:
345 case XED_ICLASS_CVTSI2SS:
346 case XED_ICLASS_CVTSS2SD:
347 case XED_ICLASS_DIVPD:
348 case XED_ICLASS_DIVPS:
349 case XED_ICLASS_DIVSD:
350 case XED_ICLASS_DIVSS:
351 case XED_ICLASS_DPPD:
352 case XED_ICLASS_DPPS:
353 case XED_ICLASS_HADDPD:
354 case XED_ICLASS_HADDPS:
355 case XED_ICLASS_HSUBPD:
356 case XED_ICLASS_HSUBPS:
357 case XED_ICLASS_MAXPD:
358 case XED_ICLASS_MAXPS:
359 case XED_ICLASS_MAXSD:
360 case XED_ICLASS_MAXSS:
361 case XED_ICLASS_MINPD:
362 case XED_ICLASS_MINPS:
363 case XED_ICLASS_MINSD:
364 case XED_ICLASS_MINSS:
365 case XED_ICLASS_MOVAPD:
366 case XED_ICLASS_MOVAPS:
367 case XED_ICLASS_MOVD:
368 case XED_ICLASS_MOVHLPS:
369 case XED_ICLASS_MOVHPD:
370 case XED_ICLASS_MOVHPS:
371 case XED_ICLASS_MOVLHPS:
372 case XED_ICLASS_MOVLPD:
373 case XED_ICLASS_MOVLPS:
374 case XED_ICLASS_MOVMSKPD:
375 case XED_ICLASS_MOVMSKPS:
376 case XED_ICLASS_MOVNTPD:
377 case XED_ICLASS_MOVNTPS:
378 case XED_ICLASS_MOVNTSD:
379 case XED_ICLASS_MOVNTSS:
380 case XED_ICLASS_MOVSD:
381 case XED_ICLASS_MOVSD_XMM:
382 case XED_ICLASS_MOVSS:
383 case XED_ICLASS_MULPD:
384 case XED_ICLASS_MULPS:
385 case XED_ICLASS_MULSD:
386 case XED_ICLASS_MULSS:
387 case XED_ICLASS_ORPD:
388 case XED_ICLASS_ORPS:
389 case XED_ICLASS_ROUNDPD:
390 case XED_ICLASS_ROUNDPS:
391 case XED_ICLASS_ROUNDSD:
392 case XED_ICLASS_ROUNDSS:
393 case XED_ICLASS_SHUFPD:
394 case XED_ICLASS_SHUFPS:
395 case XED_ICLASS_SQRTPD:
396 case XED_ICLASS_SQRTPS:
397 case XED_ICLASS_SQRTSD:
398 case XED_ICLASS_SQRTSS:
399 case XED_ICLASS_SUBPD:
400 case XED_ICLASS_SUBPS:
401 case XED_ICLASS_SUBSD:
402 case XED_ICLASS_SUBSS:
403 case XED_ICLASS_VADDPD:
404 case XED_ICLASS_VADDPS:
405 case XED_ICLASS_VADDSD:
406 case XED_ICLASS_VADDSS:
407 case XED_ICLASS_VADDSUBPD:
408 case XED_ICLASS_VADDSUBPS:
409 case XED_ICLASS_VANDNPD:
410 case XED_ICLASS_VANDNPS:
411 case XED_ICLASS_VANDPD:
412 case XED_ICLASS_VANDPS:
413 case XED_ICLASS_VBLENDPD:
414 case XED_ICLASS_VBLENDPS:
415 case XED_ICLASS_VBLENDVPD:
416 case XED_ICLASS_VBLENDVPS:
417 case XED_ICLASS_VBROADCASTSD:
418 case XED_ICLASS_VBROADCASTSS:
419 case XED_ICLASS_VCMPPD:
420 case XED_ICLASS_VCMPPS:
421 case XED_ICLASS_VCMPSD:
422 case XED_ICLASS_VCMPSS:
423 case XED_ICLASS_VCOMISD:
424 case XED_ICLASS_VCOMISS:
425 case XED_ICLASS_VCVTDQ2PD:
426 case XED_ICLASS_VCVTDQ2PS:
427 case XED_ICLASS_VCVTPD2PS:
428 case XED_ICLASS_VCVTPH2PS:
429 case XED_ICLASS_VCVTPS2PD:
430 case XED_ICLASS_VCVTSD2SS:
431 case XED_ICLASS_VCVTSI2SD:
432 case XED_ICLASS_VCVTSI2SS:
433 case XED_ICLASS_VCVTSS2SD:
434 case XED_ICLASS_VDIVPD:
435 case XED_ICLASS_VDIVPS:
436 case XED_ICLASS_VDIVSD:
437 case XED_ICLASS_VDIVSS:
438 case XED_ICLASS_VDPPD:
439 case XED_ICLASS_VDPPS:
440 case XED_ICLASS_VMASKMOVPD:
441 case XED_ICLASS_VMASKMOVPS:
442 case XED_ICLASS_VMAXPD:
443 case XED_ICLASS_VMAXPS:
444 case XED_ICLASS_VMAXSD:
445 case XED_ICLASS_VMAXSS:
446 case XED_ICLASS_VMINPD:
447 case XED_ICLASS_VMINPS:
448 case XED_ICLASS_VMINSD:
449 case XED_ICLASS_VMINSS:
450 case XED_ICLASS_VMOVAPD:
451 case XED_ICLASS_VMOVAPS:
452 case XED_ICLASS_VMOVD:
453 case XED_ICLASS_VMOVHLPS:
454 case XED_ICLASS_VMOVHPD:
455 case XED_ICLASS_VMOVHPS:
456 case XED_ICLASS_VMOVLHPS:
457 case XED_ICLASS_VMOVLPD:
458 case XED_ICLASS_VMOVLPS:
459 case XED_ICLASS_VMOVMSKPD:
460 case XED_ICLASS_VMOVMSKPS:
461 case XED_ICLASS_VMOVNTPD:
462 case XED_ICLASS_VMOVNTPS:
463 case XED_ICLASS_VMOVSD:
464 case XED_ICLASS_VMOVSS:
465 case XED_ICLASS_VMOVUPD:
466 case XED_ICLASS_VMOVUPS:
467 case XED_ICLASS_VMULPD:
468 case XED_ICLASS_VMULPS:
469 case XED_ICLASS_VMULSD:
470 case XED_ICLASS_VMULSS:
471 case XED_ICLASS_VORPD:
472 case XED_ICLASS_VORPS:
473 case XED_ICLASS_VPABSD:
474 case XED_ICLASS_VPADDD:
475 case XED_ICLASS_VPCOMD:
476 case XED_ICLASS_VPCOMUD:
477 case XED_ICLASS_VPERMILPD:
478 case XED_ICLASS_VPERMILPS:
479 case XED_ICLASS_VPERMPD:
480 case XED_ICLASS_VPERMPS:
481 case XED_ICLASS_VPGATHERDD:
482 case XED_ICLASS_VPGATHERQD:
483 case XED_ICLASS_VPHADDBD:
484 case XED_ICLASS_VPHADDD:
485 case XED_ICLASS_VPHADDUBD:
486 case XED_ICLASS_VPHADDUWD:
487 case XED_ICLASS_VPHADDWD:
488 case XED_ICLASS_VPHSUBD:
489 case XED_ICLASS_VPHSUBWD:
490 case XED_ICLASS_VPINSRD:
491 case XED_ICLASS_VPMACSDD:
492 case XED_ICLASS_VPMACSSDD:
493 case XED_ICLASS_VPMASKMOVD:
494 case XED_ICLASS_VPMAXSD:
495 case XED_ICLASS_VPMAXUD:
496 case XED_ICLASS_VPMINSD:
497 case XED_ICLASS_VPMINUD:
498 case XED_ICLASS_VPROTD:
499 case XED_ICLASS_VPSUBD:
500 case XED_ICLASS_XORPD:
501 case XED_ICLASS_XORPS:
508 assert(0 &&
"failed to disassemble instruction");
514 xed_decoded_inst_t xedd;
517 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
518 xed_operand_element_type_enum_t TypeOperand = xed_decoded_inst_operand_element_type(&xedd, oper);
519 if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_SINGLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_FLOAT16)
521 if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_DOUBLE) {
524 if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE) {
527 assert(0 &&
"float instruction with unknown operand\n");
530 assert(0 &&
"failed to disassemble instruction\n");
539 template <
int start,
int end,
int step>
545 template <
int end,
int step>
552 template <
class T, u
int32_t AccessLen,
bool isApprox>
554 static __attribute__((always_inline)) VOID CheckNByteValueAfterRead(
void* addr, uint32_t opaqueHandle, THREADID threadId) {
556 printf(
"\nINFO : In Check NBytes Value After Read\n");
558 uint8_t* bytes =
static_cast<uint8_t*
>(addr);
560 uint32_t rednum =
UnrolledCount<0, AccessLen,
sizeof(T)>::BodyRedZero(bytes);
562 uint8_t zero = (rednum == AccessLen);
569 uint8_t zero = bytes[0] == 0;
570 uint32_t rednum = zero;
572 zero &= bytes[i] == 0;
577 zero = bytes[i] == 0;
579 for (i = i + 1; i < AccessLen; ++i) {
580 zero &= bytes[i] == 0;
587 printf(
"\nINFO : Exit Check NBytes Value After Read\n");
592 static inline VOID
CheckAfterLargeRead(
void* addr, UINT32 accessLen, uint32_t opaqueHandle, THREADID threadId) {
594 printf(
"\nINFO : In Check After Large Read\n");
595 if (accessLen > 32) {
596 printf(
"ERROR : AccessLen too large : %d\n", accessLen);
597 assert(0 && (accessLen <= 32));
600 uint8_t* bytes =
static_cast<uint8_t*
>(addr);
602 uint8_t zero = bytes[0] == 0;
603 uint32_t rednum = zero;
605 zero &= bytes[i] == 0;
610 zero = bytes[i] == 0;
612 for (i = i + 1; i < accessLen; ++i) {
613 zero &= bytes[i] == 0;
618 printf(
"\nINFO : Exit Check After Large Read\n");
622 #ifdef ENABLE_SAMPLING
624 #define HANDLE_CASE(T, ACCESS_LEN, IS_APPROX) \
625 INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID, IARG_END); \
626 INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)ZeroSpyAnalysis<T, (ACCESS_LEN), (IS_APPROX)>::CheckNByteValueAfterRead, IARG_MEMORYOP_EA, memOp, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR, IARG_END)
628 #define HANDLE_LARGE() \
629 INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID, IARG_END); \
630 INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)CheckAfterLargeRead, IARG_MEMORYOP_EA, memOp, IARG_MEMORYREAD_SIZE, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END)
633 #define HANDLE_CASE(T, ACCESS_LEN, IS_APPROX) \
634 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)ZeroSpyAnalysis<T, (ACCESS_LEN), (IS_APPROX)>::CheckNByteValueAfterRead, IARG_MEMORYOP_EA, memOp, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR, IARG_END)
639 #define HANDLE_LARGE() \
640 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)CheckAfterLargeRead, IARG_MEMORYOP_EA, memOp, IARG_MEMORYREAD_SIZE, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END)
646 UINT32 memOperands = INS_MemoryOperandCount(ins);
647 for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
648 if (INS_MemoryOperandIsRead(ins, memOp)) {
658 static __attribute__((always_inline))
void InstrumentReadValueBeforeAndAfterLoading(INS ins, UINT32 memOp, uint32_t opaqueHandle) {
660 printf(
"\nINFO : In InstrumentReadValueBeforeAndAfterLoading\n");
662 UINT32 refSize = INS_MemoryOperandSize(ins, memOp);
665 unsigned int operSize =
FloatOperandSize(INS_Address(ins), INS_MemoryOperandIndexToOperandIndex(ins, memOp));
669 assert(0 &&
"memory read floating data with unexptected small size");
690 assert(0 &&
"handle large mem read with unexpected operand size\n");
704 assert(0 &&
"handle large mem read with unexpected operand size\n");
709 assert(0 &&
"unexpected large memory read\n");
714 #ifdef SKIP_SMALLCASE
741 printf(
"\nINFO : Exit InstrumentReadValueBeforeAndAfterLoading\n");
749 if (INS_IsFarJump(ins) || INS_IsDirectFarJump(ins) ||
INS_IsMaskedJump(ins))
751 else if (INS_IsRet(ins) || INS_IsIRet(ins))
753 else if (INS_IsCall(ins) || INS_IsSyscall(ins))
755 else if (INS_IsBranch(ins) || INS_IsRDTSC(ins) || INS_IsNop(ins))
757 else if (INS_IsPrefetch(ins))
763 if (INS_Mnemonic(ins) ==
"XSAVEC")
765 if (INS_Mnemonic(ins) ==
"XSAVE")
767 if (INS_Mnemonic(ins) ==
"XRSTOR")
774 printf(
"\nINFO : In InstrumentInsCallback\n");
775 if (!INS_HasFallThrough(ins)) {
776 printf(
"\nINFO : Exit InstrumentInsCallback !INS_HasFallThrough\n");
780 printf(
"\nINFO : Exit InstrumentInsCallback INS_IsIgnorable\n");
783 if (INS_IsControlFlow(ins) || INS_IsRet(ins)) {
784 printf(
"\nINFO : Exit InstrumentInsCallback INS_IsControlFlow(ins) || INS_IsRet(ins)\n");
788 if (!INS_HasFallThrough(ins))
792 if (INS_IsControlFlow(ins) || INS_IsRet(ins))
801 LoadSpyInstrument::InstrumentReadValueBeforeAndAfterLoading(ins, whichOp, opaqueHandle);
803 UINT32 memOperands = INS_MemoryOperandCount(ins);
804 for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
805 if (!INS_MemoryOperandIsRead(ins, memOp))
807 LoadSpyInstrument::InstrumentReadValueBeforeAndAfterLoading(ins, memOp, opaqueHandle);
811 printf(
"\nINFO : Exit InstrumentInsCallback\n");
815 inline VOID
Update(uint32_t bytes, THREADID threadId) {
817 printf(
"\nINFO : In Update\n");
822 printf(
"\nINFO : Exit Update\n");
829 printf(
"\nINFO : In InstrumentTrace\n");
831 for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
832 uint32_t totBytes = 0;
833 for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {
834 if (!INS_HasFallThrough(ins))
838 if (INS_IsControlFlow(ins) || INS_IsRet(ins))
841 if (INS_IsMemoryRead(ins)) {
845 BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)
Update, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_END);
848 printf(
"\nINFO : Exit InstrumentTrace\n");
864 #define LEVEL_1_RED_THRESHOLD 0.90
865 #define LEVEL_2_RED_THRESHOLD 0.70
866 #define LEVEL_3_RED_THRESHOLD 0.50
867 #define PRINT_ALL_PAGE_INFO
870 vector<DRedData> tmpList;
871 vector<DRedData>::iterator tmpIt;
872 unordered_map<uint64_t, DRedData> tmpMap;
873 unordered_map<uint64_t, DRedData>::iterator tmpMapIt;
875 uint64_t grandTotalRedundantBytes = 0;
876 uint64_t grandTotalRedundantPage_level1 = 0;
877 uint64_t grandTotalRedundantPage_level2 = 0;
878 uint64_t grandTotalRedundantPage_level3 = 0;
879 uint64_t grandTotalPage = 0;
880 uint64_t all0page = 0;
883 fprintf(
gTraceFile,
"\n--------------- Dumping PAGE Redundancy Info ----------------\n");
884 fprintf(
gTraceFile,
"\n*************** Dump Data from Thread %d ****************\n", threadId);
886 for (unordered_map<uint64_t, RedLogs>::iterator it =
RedMap[threadId].begin(); it !=
RedMap[threadId].end(); ++it) {
888 tmpMapIt = tmpMap.find(key);
889 if (tmpMapIt == tmpMap.end()) {
890 DRedData tmp = {key, (*it).second.zerobytes, (*it).second.zeroreads, (*it).second.reads, (*it).second.
state};
893 (*tmpMapIt).second.
frequency += (*it).second.zerobytes;
894 (*tmpMapIt).second.all0freq += (*it).second.zeroreads;
895 (*tmpMapIt).second.ltot += (*it).second.reads;
896 (*tmpMapIt).second.state &= (*it).second.state;
899 for (unordered_map<uint64_t, DRedData>::iterator it = tmpMap.begin(); it != tmpMap.end(); ++it) {
901 tmpList.push_back(tmp);
902 grandTotalRedundantBytes += tmp.
frequency;
913 grandTotalRedundantPage_level1++;
916 grandTotalRedundantPage_level2++;
919 grandTotalRedundantPage_level3++;
925 fprintf(
gTraceFile,
"\n Total redundant bytes = %f %%, rate range from [%f, %f] %%\n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad, minrate * 100, maxrate * 100);
927 fprintf(
gTraceFile,
"\n Total redundant Pages (Only Reading 0s) = %f %%\n", all0page * 100.0 / grandTotalPage);
928 fprintf(
gTraceFile,
"\n Total redundant Pages (local redundant rate > %f %%) = %f %%\n",
LEVEL_1_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level1 * 100.0 / grandTotalPage);
929 fprintf(
gTraceFile,
"\n Total redundant Pages (local redundant rate > %f %%) = %f %%\n",
LEVEL_2_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level2 * 100.0 / grandTotalPage);
930 fprintf(
gTraceFile,
"\n Total redundant Pages (local redundant rate > %f %%) = %f %%\n",
LEVEL_3_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level3 * 100.0 / grandTotalPage);
931 #ifdef PRINT_ALL_PAGE_INFO
934 for (vector<DRedData>::iterator listIt = tmpList.begin(); listIt != tmpList.end(); ++listIt) {
936 fprintf(
gTraceFile,
"\n\n======= PAGE %lx : (%f) %% of total Redundant (%ld Bytes), all zero ratio %f %% (%ld Zeros / %ld Reads) ======\n",
938 (*listIt).frequency * 100.0 / grandTotalRedundantBytes,
940 (*listIt).all0freq * 100.0 / (*listIt).ltot,
941 (*listIt).all0freq, (*listIt).ltot);
948 fprintf(
gTraceFile,
"\n------------ Dumping Page Redundancy Info Finish -------------\n");
952 vector<DRedData> tmpList;
953 vector<DRedData>::iterator tmpIt;
955 uint64_t grandTotalRedundantBytes = 0;
956 uint64_t grandTotalRedundantPage_level1 = 0;
957 uint64_t grandTotalRedundantPage_level2 = 0;
958 uint64_t grandTotalRedundantPage_level3 = 0;
959 uint64_t grandTotalPage = 0;
960 uint64_t all0page = 0;
963 fprintf(
gTraceFile,
"\n--------------- Dumping CACHE Redundancy Info ----------------\n");
964 fprintf(
gTraceFile,
"\n*************** Dump Data from Thread %d ****************\n", threadId);
966 for (unordered_map<uint64_t, RedLogs>::iterator it =
RedMap[threadId].begin(); it !=
RedMap[threadId].end(); ++it) {
967 DRedData tmp = {(*it).first, (*it).second.zerobytes, (*it).second.zeroreads, (*it).second.reads, (*it).second.
state};
968 tmpList.push_back(tmp);
969 grandTotalRedundantBytes += tmp.
frequency;
980 grandTotalRedundantPage_level1++;
983 grandTotalRedundantPage_level2++;
986 grandTotalRedundantPage_level3++;
992 fprintf(
gTraceFile,
"\n Total redundant bytes = %f %%, rate range from [%f, %f] %%\n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad, minrate * 100, maxrate * 100);
994 fprintf(
gTraceFile,
"\n Total redundant Caches (Only Reading 0s) = %f %%\n", all0page * 100.0 / grandTotalPage);
995 fprintf(
gTraceFile,
"\n Total redundant Caches (local redundant rate > %f %%) = %f %%\n",
LEVEL_1_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level1 * 100.0 / grandTotalPage);
996 fprintf(
gTraceFile,
"\n Total redundant Caches (local redundant rate > %f %%) = %f %%\n",
LEVEL_2_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level2 * 100.0 / grandTotalPage);
997 fprintf(
gTraceFile,
"\n Total redundant Caches (local redundant rate > %f %%) = %f %%\n",
LEVEL_3_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level3 * 100.0 / grandTotalPage);
998 #ifdef PRINT_ALL_PAGE_INFO
1001 for (vector<DRedData>::iterator listIt = tmpList.begin(); listIt != tmpList.end(); ++listIt) {
1003 fprintf(
gTraceFile,
"\n\n======= CACHE %lx : (%f) %% of total Redundant (%ld Bytes), all zero ratio %f %% (%ld Zeros / %ld Reads) ======\n",
1005 (*listIt).frequency * 100.0 / grandTotalRedundantBytes,
1006 (*listIt).frequency,
1007 (*listIt).all0freq * 100.0 / (*listIt).ltot,
1008 (*listIt).all0freq, (*listIt).ltot);
1015 fprintf(
gTraceFile,
"\n------------ Dumping CACHE Redundancy Info Finish -------------\n");
1079 printf(
"\nImage %s Unloading...\n", IMG_Name(img).c_str());
1081 fprintf(
gTraceFile,
"\n TODO .. Multi-threading is not well supported.");
1082 THREADID threadid = PIN_ThreadId();
1083 fprintf(
gTraceFile,
"\nUnloading %s", IMG_Name(img).c_str());
1084 if (
RedMap[threadid].empty())
1090 printf(
"Unlocked\n");
1093 RedMap[threadid].clear();
1094 printf(
"...Finish\n");
1098 static VOID
ThreadFiniFunc(THREADID threadid,
const CONTEXT* ctxt, INT32 code, VOID* v) {
1109 uint64_t redReadTmp = 0;
1110 uint64_t approxRedReadTmp = 0;
1112 unordered_map<uint64_t, RedLogs>::iterator it;
1113 if (!
RedMap[i].empty()) {
1114 for (it =
RedMap[i].begin(); it !=
RedMap[i].end(); ++it) {
1115 redReadTmp += (*it).second.zerobytes;
1142 RedMap[threadid].reserve(10000000);
1144 #ifdef MULTI_THREADED
1161 if (PIN_Init(argc, argv))
1186 PIN_AddFiniFunction(
FiniFunc,
nullptr);
#define INTERESTING_INS_ALL
int PinCCTLibInit(IsInterestingInsFptr isInterestingIns, FILE *logFile, CCTLibInstrumentInsCallback userCallback, VOID *userCallbackArg, BOOL doDataCentric=false)
hpcrun_metricFlags_t flags
static USIZE INS_MemoryReadSize(INS ins)
static BOOL INS_IsMaskedJump(INS ins)
struct RedSpyThreadData __attribute__
uint8_t value[MAX_WRITE_OP_LENGTH]
static __attribute__((always_inline)) void InstrumentReadValueBeforeAndAfterLoading(INS ins
static __attribute__((always_inline)) uint32_t BodyRedZero(uint8_t *addr)
static __attribute__((always_inline)) uint32_t BodyRedZero(uint8_t *addr)
static __attribute__((always_inline)) VOID CheckNByteValueAfterRead(void *addr
AddToRedTable(GET_CACHELINE_INDEX((uint64_t) addr), rednum, zero, threadId)
AddToRedTable(key, rednum, zero, threadId)
uint64_t computeMetricVal(void *metric)
static bool DRedundacyCompare(const struct DRedData &first, const struct DRedData &second)
static void ClientInit(int argc, char *argv[])
#define LEVEL_1_RED_THRESHOLD
int main(int argc, char *argv[])
uint64_t grandTotBytesRedLoad
#define MAX_REDUNDANT_CONTEXTS_TO_LOG
static unordered_map< uint64_t, RedLogs > RedMap[THREAD_MAX]
static int GetNumReadOperandsInIns(INS ins, UINT32 &whichOp)
static VOID ImageUnload(IMG img, VOID *v)
#define HANDLE_CASE(T, ACCESS_LEN, IS_APPROX)
static RedSpyThreadData * gSingleThreadedTData
#define EIGHT_BYTE_WRITE_ACTION
static const uint64_t READ_ACCESS_STATES[]
#define ONE_BYTE_READ_ACTION
int redload_approx_metric_id
static bool IsFloatInstructionOld(ADDRINT ip)
#define EIGHT_BYTE_READ_ACTION
#define TWO_BYTE_READ_ACTION
static void AddToRedTable(uint64_t key, uint16_t value, uint16_t zero, THREADID threadId) __attribute__((always_inline
static uint16_t FloatOperandSize(ADDRINT ip, uint32_t oper)
static const uint8_t OVERFLOW_CHECK[]
#define LEVEL_2_RED_THRESHOLD
#define LEVEL_3_RED_THRESHOLD
VOID Update(uint32_t bytes, THREADID threadId)
#define GET_CACHELINE_INDEX(x)
#define ISSAMECACHELINE(addr, accesslen)
static VOID InstrumentInsCallback(INS ins, VOID *v, const uint32_t opaqueHandle)
static void InstrumentTrace(TRACE trace, void *f)
static void InitThreadData(RedSpyThreadData *tdata)
static bool INS_IsIgnorable(INS ins)
RedSpyThreadData * ClientGetTLS(const THREADID threadId)
#define GET_PAGE_INDEX(x)
static bool IsFloatInstructionAndOkToApproximate(ADDRINT ip)
static VOID FiniFunc(INT32 code, VOID *v)
#define TWO_BYTE_WRITE_ACTION
static const uint64_t WRITE_ACCESS_STATES[]
static VOID CheckAfterLargeRead(void *addr, UINT32 accessLen, uint32_t opaqueHandle, THREADID threadId)
uint64_t grandTotBytesLoad
#define FOUR_BYTE_READ_ACTION
static void PrintCacheRedundancy(THREADID threadId)
uint64_t grandTotBytesApproxRedLoad
static VOID ThreadFiniFunc(THREADID threadid, const CONTEXT *ctxt, INT32 code, VOID *v)
static bool IsOkToApproximate(xed_decoded_inst_t &xedd)
#define ONE_BYTE_WRITE_ACTION
static void PrintPageRedundancy(THREADID threadId)
#define FOUR_BYTE_WRITE_ACTION
static TLS_KEY client_tls_key
static VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
struct @16 LoadSpyGlobals