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)
73 #define PAGE_MASK (~0xfff)
74 #define GET_PAGE_INDEX(x) ((x)&PAGE_MASK)
76 #define CACHELINE_MASK (~63)
77 #define GET_CACHELINE_INDEX(x) ((x)&CACHELINE_MASK)
83 #ifdef ENABLE_SAMPLING
85 #define WINDOW_ENABLE 1000000
86 #define WINDOW_DISABLE 100000000
87 #define WINDOW_CLEAN 10
90 #define DECODE_DEAD(data) static_cast<uint8_t>(((data)&0xffffffffffffffff) >> 32)
91 #define DECODE_KILL(data) (static_cast<ContextHandle_t>((data)&0x00000000ffffffff))
94 #define MAKE_CONTEXT_PAIR(a, b) (((uint64_t)(a) << 32) | ((uint64_t)(b)))
157 #ifdef MULTI_THREADED
167 PIN_ERROR(
"Pin tool to gather calling context on each load and store.\n" + KNOB_BASE::StringKnobSummary() +
"\n");
178 char* envPath = getenv(
"CCTLIB_CLIENT_OUTPUT_FILE");
182 snprintf(name,
sizeof(name),
"%s", envPath);
185 gethostname(name + strlen(name),
MAX_FILE_PATH - strlen(name));
186 pid_t pid = getpid();
187 sprintf(name + strlen(name),
"%d", pid);
188 cerr <<
"\n Creating log file at:" << name <<
"\n";
193 for (
int i = 0; i < argc; i++) {
201 xed_state_init(&
LoadSpyGlobals.xedState, XED_MACHINE_MODE_LONG_64, (xed_address_width_enum_t)0, XED_ADDRESS_WIDTH_64b);
231 #ifdef USE_COLLECT_PAGE_CACHE
237 static unordered_map<uint64_t, DataLogs> PageRedMap[
THREAD_MAX];
238 static unordered_map<uint64_t, DataLogs> CacheRedMap[
THREAD_MAX];
239 static inline void AddToPageRedTable(uint64_t key, uint16_t
value, uint16_t total, THREADID threadId)
__attribute__((always_inline,
flatten));
240 static inline void AddToPageRedTable(uint64_t key, uint16_t
value, uint16_t total, THREADID threadId) {
241 #ifdef MULTI_THREADED
244 unordered_map<uint64_t, DataLogs>::iterator it = PageRedMap[threadId].find(key);
245 if (it == PageRedMap[threadId].end()) {
249 PageRedMap[threadId][key] = log;
251 it->second.red +=
value;
252 it->second.tot += total;
254 #ifdef MULTI_THREADED
259 static inline void AddToCacheRedTable(uint64_t key, uint16_t
value, uint16_t total, THREADID threadId)
__attribute__((always_inline,
flatten));
260 static inline void AddToCacheRedTable(uint64_t key, uint16_t
value, uint16_t total, THREADID threadId) {
261 #ifdef MULTI_THREADED
264 unordered_map<uint64_t, DataLogs>::iterator it = CacheRedMap[threadId].find(key);
265 if (it == CacheRedMap[threadId].end()) {
269 CacheRedMap[threadId][key] = log;
271 it->second.red +=
value;
272 it->second.tot += total;
274 #ifdef MULTI_THREADED
280 static inline void AddToRedTable(uint64_t key, uint16_t
value, uint32_t byteMap, uint16_t total, THREADID threadId) {
281 #ifdef MULTI_THREADED
284 unordered_map<uint64_t, RedLogs>::iterator it =
RedMap[threadId].find(key);
285 if (it ==
RedMap[threadId].end()) {
293 RedMap[threadId][key] = log;
297 it->second.tot += total;
298 it->second.fred += (
value == total);
299 it->second.redByteMap &= byteMap;
304 #ifdef MULTI_THREADED
309 static inline void AddToApproximateRedTable(uint64_t key, uint32_t byteMapMan, uint32_t byteMapExp, uint32_t byteMapSign, uint16_t total, uint16_t zeros, uint16_t nums, uint8_t size, THREADID threadId)
__attribute__((always_inline,
flatten));
310 static inline void AddToApproximateRedTable(uint64_t key, uint32_t byteMapMan, uint32_t byteMapExp, uint32_t byteMapSign, uint16_t total, uint16_t zeros, uint16_t nums, uint8_t size, THREADID threadId) {
311 #ifdef MULTI_THREADED
314 unordered_map<uint64_t, ApproxRedLogs>::iterator it =
ApproxRedMap[threadId].find(key);
332 it->second.
fred += zeros;
333 it->second.ftot += nums;
334 it->second.redByteMapMan &= byteMapMan;
335 it->second.redByteMapExp &= byteMapExp;
336 it->second.redByteMapSign &= byteMapSign;
342 #ifdef MULTI_THREADED
348 #ifdef ENABLE_SAMPLING
350 static ADDRINT IfEnableSample(THREADID threadId) {
359 xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xedd);
361 case XED_ICLASS_FLDENV:
362 case XED_ICLASS_FNSTENV:
363 case XED_ICLASS_FNSAVE:
364 case XED_ICLASS_FLDCW:
365 case XED_ICLASS_FNSTCW:
366 case XED_ICLASS_FXRSTOR:
367 case XED_ICLASS_FXRSTOR64:
368 case XED_ICLASS_FXSAVE:
369 case XED_ICLASS_FXSAVE64:
377 xed_decoded_inst_t xedd;
380 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
381 xed_category_enum_t cat = xed_decoded_inst_get_category(&xedd);
383 case XED_CATEGORY_AES:
384 case XED_CATEGORY_CONVERT:
385 case XED_CATEGORY_PCLMULQDQ:
386 case XED_CATEGORY_SSE:
387 case XED_CATEGORY_AVX2:
388 case XED_CATEGORY_AVX:
389 case XED_CATEGORY_MMX:
390 case XED_CATEGORY_DATAXFER: {
393 const xed_inst_t* xi = xed_decoded_inst_inst(&xedd);
394 int noperands = xed_inst_noperands(xi);
396 for (
int i = 0; i < noperands; i++) {
397 const xed_operand_t* op = xed_inst_operand(xi, i);
398 xed_operand_enum_t op_name = xed_operand_name(op);
399 if (XED_OPERAND_MEM0 == op_name) {
404 if (memOpIdx == -1) {
409 xed_operand_element_type_enum_t eType = xed_decoded_inst_operand_element_type(&xedd, memOpIdx);
411 case XED_OPERAND_ELEMENT_TYPE_FLOAT16:
412 case XED_OPERAND_ELEMENT_TYPE_SINGLE:
413 case XED_OPERAND_ELEMENT_TYPE_DOUBLE:
414 case XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE:
415 case XED_OPERAND_ELEMENT_TYPE_LONGBCD:
421 case XED_CATEGORY_X87_ALU:
422 case XED_CATEGORY_FCMOV:
427 case XED_CATEGORY_XSAVE:
428 case XED_CATEGORY_AVX2GATHER:
429 case XED_CATEGORY_STRINGOP:
434 assert(0 &&
"failed to disassemble instruction");
441 xed_decoded_inst_t xedd;
444 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
445 xed_iclass_enum_t iclassType = xed_decoded_inst_get_iclass(&xedd);
446 if (iclassType >= XED_ICLASS_F2XM1 && iclassType <= XED_ICLASS_FYL2XP1) {
449 if (iclassType >= XED_ICLASS_VBROADCASTSD && iclassType <= XED_ICLASS_VDPPS) {
452 if (iclassType >= XED_ICLASS_VRCPPS && iclassType <= XED_ICLASS_VSQRTSS) {
455 if (iclassType >= XED_ICLASS_VSUBPD && iclassType <= XED_ICLASS_VXORPS) {
458 switch (iclassType) {
459 case XED_ICLASS_ADDPD:
460 case XED_ICLASS_ADDPS:
461 case XED_ICLASS_ADDSD:
462 case XED_ICLASS_ADDSS:
463 case XED_ICLASS_ADDSUBPD:
464 case XED_ICLASS_ADDSUBPS:
465 case XED_ICLASS_ANDNPD:
466 case XED_ICLASS_ANDNPS:
467 case XED_ICLASS_ANDPD:
468 case XED_ICLASS_ANDPS:
469 case XED_ICLASS_BLENDPD:
470 case XED_ICLASS_BLENDPS:
471 case XED_ICLASS_BLENDVPD:
472 case XED_ICLASS_BLENDVPS:
473 case XED_ICLASS_CMPPD:
474 case XED_ICLASS_CMPPS:
475 case XED_ICLASS_CMPSD:
476 case XED_ICLASS_CMPSD_XMM:
477 case XED_ICLASS_COMISD:
478 case XED_ICLASS_COMISS:
479 case XED_ICLASS_CVTDQ2PD:
480 case XED_ICLASS_CVTDQ2PS:
481 case XED_ICLASS_CVTPD2PS:
482 case XED_ICLASS_CVTPI2PD:
483 case XED_ICLASS_CVTPI2PS:
484 case XED_ICLASS_CVTPS2PD:
485 case XED_ICLASS_CVTSD2SS:
486 case XED_ICLASS_CVTSI2SD:
487 case XED_ICLASS_CVTSI2SS:
488 case XED_ICLASS_CVTSS2SD:
489 case XED_ICLASS_DIVPD:
490 case XED_ICLASS_DIVPS:
491 case XED_ICLASS_DIVSD:
492 case XED_ICLASS_DIVSS:
493 case XED_ICLASS_DPPD:
494 case XED_ICLASS_DPPS:
495 case XED_ICLASS_HADDPD:
496 case XED_ICLASS_HADDPS:
497 case XED_ICLASS_HSUBPD:
498 case XED_ICLASS_HSUBPS:
499 case XED_ICLASS_MAXPD:
500 case XED_ICLASS_MAXPS:
501 case XED_ICLASS_MAXSD:
502 case XED_ICLASS_MAXSS:
503 case XED_ICLASS_MINPD:
504 case XED_ICLASS_MINPS:
505 case XED_ICLASS_MINSD:
506 case XED_ICLASS_MINSS:
507 case XED_ICLASS_MOVAPD:
508 case XED_ICLASS_MOVAPS:
509 case XED_ICLASS_MOVD:
510 case XED_ICLASS_MOVHLPS:
511 case XED_ICLASS_MOVHPD:
512 case XED_ICLASS_MOVHPS:
513 case XED_ICLASS_MOVLHPS:
514 case XED_ICLASS_MOVLPD:
515 case XED_ICLASS_MOVLPS:
516 case XED_ICLASS_MOVMSKPD:
517 case XED_ICLASS_MOVMSKPS:
518 case XED_ICLASS_MOVNTPD:
519 case XED_ICLASS_MOVNTPS:
520 case XED_ICLASS_MOVNTSD:
521 case XED_ICLASS_MOVNTSS:
522 case XED_ICLASS_MOVSD:
523 case XED_ICLASS_MOVSD_XMM:
524 case XED_ICLASS_MOVSS:
525 case XED_ICLASS_MULPD:
526 case XED_ICLASS_MULPS:
527 case XED_ICLASS_MULSD:
528 case XED_ICLASS_MULSS:
529 case XED_ICLASS_ORPD:
530 case XED_ICLASS_ORPS:
531 case XED_ICLASS_ROUNDPD:
532 case XED_ICLASS_ROUNDPS:
533 case XED_ICLASS_ROUNDSD:
534 case XED_ICLASS_ROUNDSS:
535 case XED_ICLASS_SHUFPD:
536 case XED_ICLASS_SHUFPS:
537 case XED_ICLASS_SQRTPD:
538 case XED_ICLASS_SQRTPS:
539 case XED_ICLASS_SQRTSD:
540 case XED_ICLASS_SQRTSS:
541 case XED_ICLASS_SUBPD:
542 case XED_ICLASS_SUBPS:
543 case XED_ICLASS_SUBSD:
544 case XED_ICLASS_SUBSS:
545 case XED_ICLASS_VADDPD:
546 case XED_ICLASS_VADDPS:
547 case XED_ICLASS_VADDSD:
548 case XED_ICLASS_VADDSS:
549 case XED_ICLASS_VADDSUBPD:
550 case XED_ICLASS_VADDSUBPS:
551 case XED_ICLASS_VANDNPD:
552 case XED_ICLASS_VANDNPS:
553 case XED_ICLASS_VANDPD:
554 case XED_ICLASS_VANDPS:
555 case XED_ICLASS_VBLENDPD:
556 case XED_ICLASS_VBLENDPS:
557 case XED_ICLASS_VBLENDVPD:
558 case XED_ICLASS_VBLENDVPS:
559 case XED_ICLASS_VBROADCASTSD:
560 case XED_ICLASS_VBROADCASTSS:
561 case XED_ICLASS_VCMPPD:
562 case XED_ICLASS_VCMPPS:
563 case XED_ICLASS_VCMPSD:
564 case XED_ICLASS_VCMPSS:
565 case XED_ICLASS_VCOMISD:
566 case XED_ICLASS_VCOMISS:
567 case XED_ICLASS_VCVTDQ2PD:
568 case XED_ICLASS_VCVTDQ2PS:
569 case XED_ICLASS_VCVTPD2PS:
570 case XED_ICLASS_VCVTPH2PS:
571 case XED_ICLASS_VCVTPS2PD:
572 case XED_ICLASS_VCVTSD2SS:
573 case XED_ICLASS_VCVTSI2SD:
574 case XED_ICLASS_VCVTSI2SS:
575 case XED_ICLASS_VCVTSS2SD:
576 case XED_ICLASS_VDIVPD:
577 case XED_ICLASS_VDIVPS:
578 case XED_ICLASS_VDIVSD:
579 case XED_ICLASS_VDIVSS:
580 case XED_ICLASS_VDPPD:
581 case XED_ICLASS_VDPPS:
582 case XED_ICLASS_VMASKMOVPD:
583 case XED_ICLASS_VMASKMOVPS:
584 case XED_ICLASS_VMAXPD:
585 case XED_ICLASS_VMAXPS:
586 case XED_ICLASS_VMAXSD:
587 case XED_ICLASS_VMAXSS:
588 case XED_ICLASS_VMINPD:
589 case XED_ICLASS_VMINPS:
590 case XED_ICLASS_VMINSD:
591 case XED_ICLASS_VMINSS:
592 case XED_ICLASS_VMOVAPD:
593 case XED_ICLASS_VMOVAPS:
594 case XED_ICLASS_VMOVD:
595 case XED_ICLASS_VMOVHLPS:
596 case XED_ICLASS_VMOVHPD:
597 case XED_ICLASS_VMOVHPS:
598 case XED_ICLASS_VMOVLHPS:
599 case XED_ICLASS_VMOVLPD:
600 case XED_ICLASS_VMOVLPS:
601 case XED_ICLASS_VMOVMSKPD:
602 case XED_ICLASS_VMOVMSKPS:
603 case XED_ICLASS_VMOVNTPD:
604 case XED_ICLASS_VMOVNTPS:
605 case XED_ICLASS_VMOVSD:
606 case XED_ICLASS_VMOVSS:
607 case XED_ICLASS_VMOVUPD:
608 case XED_ICLASS_VMOVUPS:
609 case XED_ICLASS_VMULPD:
610 case XED_ICLASS_VMULPS:
611 case XED_ICLASS_VMULSD:
612 case XED_ICLASS_VMULSS:
613 case XED_ICLASS_VORPD:
614 case XED_ICLASS_VORPS:
615 case XED_ICLASS_VPABSD:
616 case XED_ICLASS_VPADDD:
617 case XED_ICLASS_VPCOMD:
618 case XED_ICLASS_VPCOMUD:
619 case XED_ICLASS_VPERMILPD:
620 case XED_ICLASS_VPERMILPS:
621 case XED_ICLASS_VPERMPD:
622 case XED_ICLASS_VPERMPS:
623 case XED_ICLASS_VPGATHERDD:
624 case XED_ICLASS_VPGATHERQD:
625 case XED_ICLASS_VPHADDBD:
626 case XED_ICLASS_VPHADDD:
627 case XED_ICLASS_VPHADDUBD:
628 case XED_ICLASS_VPHADDUWD:
629 case XED_ICLASS_VPHADDWD:
630 case XED_ICLASS_VPHSUBD:
631 case XED_ICLASS_VPHSUBWD:
632 case XED_ICLASS_VPINSRD:
633 case XED_ICLASS_VPMACSDD:
634 case XED_ICLASS_VPMACSSDD:
635 case XED_ICLASS_VPMASKMOVD:
636 case XED_ICLASS_VPMAXSD:
637 case XED_ICLASS_VPMAXUD:
638 case XED_ICLASS_VPMINSD:
639 case XED_ICLASS_VPMINUD:
640 case XED_ICLASS_VPROTD:
641 case XED_ICLASS_VPSUBD:
642 case XED_ICLASS_XORPD:
643 case XED_ICLASS_XORPS:
650 assert(0 &&
"failed to disassemble instruction");
656 xed_decoded_inst_t xedd;
659 if (XED_ERROR_NONE == xed_decode(&xedd, (
const xed_uint8_t*)(
ip), 15)) {
660 xed_operand_element_type_enum_t TypeOperand = xed_decoded_inst_operand_element_type(&xedd, oper);
661 if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_SINGLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_FLOAT16)
663 if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_DOUBLE) {
666 if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE) {
669 assert(0 &&
"float instruction with unknown operand\n");
672 assert(0 &&
"failed to disassemble instruction\n");
743 template <
int start,
int end,
int incr>
745 static __attribute__((always_inline))
bool Body(
const function<
bool(
const int)>& func) {
759 template <
int end,
int incr>
761 static __attribute__((always_inline))
bool Body(
const function<
void(
const int)>& func) {
775 template <
int start,
int end,
int step>
781 template <
int end,
int step>
793 uint32_t exponent : 8;
794 uint32_t mantisa : 23;
806 uint64_t exponent : 11;
807 uint64_t mantisa : 52;
842 template <
int start,
int end,
int step>
847 uint32_t man = (*(
reinterpret_cast<float_cast*
>(&addr[start]))).parts.mantisa;
848 uint8_t exp = (*(
reinterpret_cast<float_cast*
>(&addr[start]))).parts.exponent;
850 }
else if (step == 8) {
851 uint64_t man = (*(
reinterpret_cast<double_cast*
>(&addr[start]))).parts.mantisa;
852 uint32_t exp = (*(
reinterpret_cast<double_cast*
>(&addr[start]))).parts.exponent;
855 assert(0 &&
"Not Supportted floating size! now only support for FP32 or FP64.");
861 template <
int end,
int step>
868 template <
int start,
int end,
int incr>
870 static __attribute__((always_inline)) uint64_t BodyByteMapMan(uint8_t* addr) {
873 uint32_t man = (*(
reinterpret_cast<float_cast*
>(&addr[start]))).parts.mantisa;
875 }
else if (incr == 8) {
876 uint64_t man = (*(
reinterpret_cast<double_cast*
>(&addr[start]))).parts.mantisa;
879 assert(0 &&
"Not Supportted floating size! now only support for FP32 or FP64.");
884 static __attribute__((always_inline)) uint64_t BodyByteMapExp(uint8_t* addr) {
887 uint8_t exp = (*(
reinterpret_cast<float_cast*
>(&addr[start]))).parts.exponent;
889 }
else if (incr == 8) {
890 uint32_t exp = (*(
reinterpret_cast<double_cast*
>(&addr[start]))).parts.exponent;
893 assert(0 &&
"Not Supportted floating size! now only support for FP32 or FP64.");
898 static __attribute__((always_inline)) uint64_t BodyByteMapSign(uint8_t* addr) {
901 uint8_t sign = (*(
reinterpret_cast<float_cast*
>(&addr[start]))).parts.sign;
903 }
else if (incr == 8) {
904 uint8_t sign = (*(
reinterpret_cast<double_cast*
>(&addr[start]))).parts.sign;
907 assert(0 &&
"Not Supportted floating size! now only support for FP32 or FP64.");
929 template <
int end,
int incr>
931 static __attribute__((always_inline)) uint64_t BodyByteMapMan(uint8_t* addr) {
934 static __attribute__((always_inline)) uint64_t BodyByteMapExp(uint8_t* addr) {
937 static __attribute__((always_inline)) uint64_t BodyByteMapSign(uint8_t* addr) {
948 template <
class T, u
int32_t AccessLen,
bool isApprox>
951 uint8_t* bytes =
static_cast<uint8_t*
>(addr);
957 uint8_t* bytes =
static_cast<uint8_t*
>(addr);
961 uint8_t* bytes =
static_cast<uint8_t*
>(addr);
962 uint32_t rednum =
UnrolledCount<0, AccessLen,
sizeof(T)>::BodyRedZero(bytes);
967 static __attribute__((always_inline)) VOID CheckNByteValueAfterRead(
void* addr, uint32_t opaqueHandle, THREADID threadId) {
969 printf(
"\nINFO : In Check NBytes Value After Read\n");
974 uint32_t redbyteNum = getRedNum(addr);
976 uint8_t* bytes =
static_cast<uint8_t*
>(addr);
981 AddToApproximateRedTable((uint64_t)curCtxtHandle, man, exp, sign, AccessLen, zeros, AccessLen /
sizeof(T),
sizeof(T), threadId);
983 AddToApproximateRedTable((uint64_t)curCtxtHandle, 0, 0, 0, AccessLen, 0, AccessLen /
sizeof(T),
sizeof(T), threadId);
986 uint32_t redbyteNum = getRedNum(addr);
988 uint32_t redbyteMap = getRedMap(addr);
996 printf(
"\nINFO : Exit Check NBytes Value After Read\n");
1026 static inline VOID
CheckAfterLargeRead(
void* addr, UINT32 accessLen, uint32_t opaqueHandle, THREADID threadId) {
1027 #ifdef DEBUG_ZEROSPY
1028 printf(
"\nINFO : In Check After Large Read\n");
1029 if (accessLen > 32) {
1030 printf(
"ERROR : AccessLen too large : %d\n", accessLen);
1031 assert(0 && (accessLen <= 32));
1043 uint8_t* bytes =
static_cast<uint8_t*
>(addr);
1044 uint32_t redbytesNum = 0;
1045 for (
int i = accessLen - 1; i >= 0; --i) {
1046 if (bytes[i] != 0) {
1053 uint32_t redbyteMap = 0;
1054 if (bytes[0] == 0) {
1057 for (UINT32 i = 1; i < accessLen; ++i) {
1058 if (bytes[i] == 0) {
1059 redbyteMap |= (1 << i);
1078 #ifdef DEBUG_ZEROSPY
1079 printf(
"\nINFO : Exit Check After Large Read\n");
1083 #ifdef ENABLE_SAMPLING
1085 #define HANDLE_CASE(T, ACCESS_LEN, IS_APPROX) \
1086 INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID, IARG_END); \
1087 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)
1089 #define HANDLE_LARGE() \
1090 INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID, IARG_END); \
1091 INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)CheckAfterLargeRead, IARG_MEMORYOP_EA, memOp, IARG_MEMORYREAD_SIZE, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END)
1094 #define HANDLE_CASE(T, ACCESS_LEN, IS_APPROX) \
1095 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)
1100 #define HANDLE_LARGE() \
1101 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)CheckAfterLargeRead, IARG_MEMORYOP_EA, memOp, IARG_MEMORYREAD_SIZE, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END)
1107 UINT32 memOperands = INS_MemoryOperandCount(ins);
1108 for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
1109 if (INS_MemoryOperandIsRead(ins, memOp)) {
1119 static __attribute__((always_inline))
void InstrumentReadValueBeforeAndAfterLoading(INS ins, UINT32 memOp, uint32_t opaqueHandle) {
1120 #ifdef DEBUG_ZEROSPY
1121 printf(
"\nINFO : In InstrumentReadValueBeforeAndAfterLoading\n");
1123 UINT32 refSize = INS_MemoryOperandSize(ins, memOp);
1126 unsigned int operSize =
FloatOperandSize(INS_Address(ins), INS_MemoryOperandIndexToOperandIndex(ins, memOp));
1130 assert(0 &&
"memory read floating data with unexptected small size");
1151 assert(0 &&
"handle large mem read with unexpected operand size\n");
1165 assert(0 &&
"handle large mem read with unexpected operand size\n");
1170 assert(0 &&
"unexpected large memory read\n");
1175 #ifdef SKIP_SMALLCASE
1201 #ifdef DEBUG_ZEROSPY
1202 printf(
"\nINFO : Exit InstrumentReadValueBeforeAndAfterLoading\n");
1210 if (INS_IsFarJump(ins) || INS_IsDirectFarJump(ins) ||
INS_IsMaskedJump(ins))
1212 else if (INS_IsRet(ins) || INS_IsIRet(ins))
1214 else if (INS_IsCall(ins) || INS_IsSyscall(ins))
1216 else if (INS_IsBranch(ins) || INS_IsRDTSC(ins) || INS_IsNop(ins))
1218 else if (INS_IsPrefetch(ins))
1224 if (INS_Mnemonic(ins) ==
"XSAVEC")
1226 if (INS_Mnemonic(ins) ==
"XSAVE")
1228 if (INS_Mnemonic(ins) ==
"XRSTOR")
1234 #ifdef DEBUG_ZEROSPY
1235 printf(
"\nINFO : In InstrumentInsCallback\n");
1236 if (!INS_HasFallThrough(ins)) {
1237 printf(
"\nINFO : Exit InstrumentInsCallback !INS_HasFallThrough\n");
1241 printf(
"\nINFO : Exit InstrumentInsCallback INS_IsIgnorable\n");
1244 if (INS_IsControlFlow(ins) || INS_IsRet(ins)) {
1245 printf(
"\nINFO : Exit InstrumentInsCallback INS_IsControlFlow(ins) || INS_IsRet(ins)\n");
1249 if (!INS_HasFallThrough(ins))
1253 if (INS_IsControlFlow(ins) || INS_IsRet(ins))
1262 LoadSpyInstrument::InstrumentReadValueBeforeAndAfterLoading(ins, whichOp, opaqueHandle);
1264 UINT32 memOperands = INS_MemoryOperandCount(ins);
1265 for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
1266 if (!INS_MemoryOperandIsRead(ins, memOp))
1268 LoadSpyInstrument::InstrumentReadValueBeforeAndAfterLoading(ins, memOp, opaqueHandle);
1271 #ifdef DEBUG_ZEROSPY
1272 printf(
"\nINFO : Exit InstrumentInsCallback\n");
1278 #ifdef ENABLE_SAMPLING
1279 #error Sampling should not be enabled as it has not been tested yet!
1280 inline VOID UpdateAndCheck(uint32_t count, uint32_t bytes, THREADID threadId) {
1301 inline VOID
Update(uint32_t count, uint32_t bytes, THREADID threadId) {
1312 for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
1313 uint32_t totInsInBbl = BBL_NumIns(bbl);
1314 uint32_t totBytes = 0;
1315 for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {
1316 if (!INS_HasFallThrough(ins))
1320 if (INS_IsControlFlow(ins) || INS_IsRet(ins))
1323 if (INS_IsMemoryRead(ins)) {
1328 if (BBL_InsTail(bbl) == BBL_InsHead(bbl)) {
1329 BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)UpdateAndCheck, IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END);
1331 BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)UpdateAndCheck, IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END);
1334 BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)UpdateAndCheck, IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END);
1337 BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)
Update, IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END);
1346 inline VOID
Update(uint32_t bytes, THREADID threadId) {
1347 #ifdef DEBUG_ZEROSPY
1348 printf(
"\nINFO : In Update\n");
1352 #ifdef DEBUG_ZEROSPY
1353 printf(
"\nINFO : Exit Update\n");
1359 #ifdef DEBUG_ZEROSPY
1360 printf(
"\nINFO : In InstrumentTrace\n");
1362 for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
1363 uint32_t totBytes = 0;
1364 for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {
1365 if (!INS_HasFallThrough(ins))
1369 if (INS_IsControlFlow(ins) || INS_IsRet(ins))
1372 if (INS_IsMemoryRead(ins)) {
1376 BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)
Update, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_END);
1378 #ifdef DEBUG_ZEROSPY
1379 printf(
"\nINFO : Exit InstrumentTrace\n");
1404 #ifdef USE_COLLECT_PAGE_CACHE
1415 #define LEVEL_1_RED_THRESHOLD 0.90
1416 #define LEVEL_2_RED_THRESHOLD 0.70
1417 #define LEVEL_3_RED_THRESHOLD 0.50
1420 vector<DRedData> tmpList;
1421 vector<DRedData>::iterator tmpIt;
1423 uint64_t grandTotalRedundantBytes = 0;
1424 uint64_t grandTotalRedundantPage_level1 = 0;
1425 uint64_t grandTotalRedundantPage_level2 = 0;
1426 uint64_t grandTotalRedundantPage_level3 = 0;
1427 uint64_t grandTotalPage = 0;
1429 float minrate = 100;
1430 fprintf(
gTraceFile,
"\n--------------- Dumping PAGE Redundancy Info ----------------\n");
1431 fprintf(
gTraceFile,
"\n*************** Dump Data from Thread %d ****************\n", threadId);
1433 for (unordered_map<uint64_t, DataLogs>::iterator it = PageRedMap[threadId].begin(); it != PageRedMap[threadId].end(); ++it) {
1434 DRedData tmp = {(*it).first, (*it).second.red, (*it).second.tot};
1435 tmpList.push_back(tmp);
1436 grandTotalRedundantBytes += tmp.
frequency;
1445 grandTotalRedundantPage_level1++;
1448 grandTotalRedundantPage_level2++;
1451 grandTotalRedundantPage_level3++;
1457 fprintf(
gTraceFile,
"\n Total redundant bytes = %f %%, rate range from [%f, %f] %%\n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad, minrate * 100, maxrate * 100);
1459 fprintf(
gTraceFile,
"\n Total redundant bytes (local redundant rate > %f %%) = %f %%\n",
LEVEL_1_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level1 * 100.0 / grandTotalPage);
1460 fprintf(
gTraceFile,
"\n Total redundant bytes (local redundant rate > %f %%) = %f %%\n",
LEVEL_2_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level2 * 100.0 / grandTotalPage);
1461 fprintf(
gTraceFile,
"\n Total redundant bytes (local redundant rate > %f %%) = %f %%\n",
LEVEL_3_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level3 * 100.0 / grandTotalPage);
1462 #ifdef PRINT_ALL_PAGE_INFO
1465 for (vector<DRedData>::iterator listIt = tmpList.begin(); listIt != tmpList.end(); ++listIt) {
1467 fprintf(
gTraceFile,
"\n\n======= PAGE %lx : (%f) %% of total Redundant, with local redundant %f %% (%ld Bytes / %ld Bytes) ======\n",
1469 (*listIt).frequency * 100.0 / grandTotalRedundantBytes,
1470 (*listIt).frequency * 100.0 / (*listIt).ltot,
1471 (*listIt).frequency, (*listIt).ltot);
1478 fprintf(
gTraceFile,
"\n------------ Dumping Page Redundancy Info Finish -------------\n");
1482 vector<DRedData> tmpList;
1483 vector<DRedData>::iterator tmpIt;
1485 uint64_t grandTotalRedundantBytes = 0;
1486 uint64_t grandTotalRedundantPage_level1 = 0;
1487 uint64_t grandTotalRedundantPage_level2 = 0;
1488 uint64_t grandTotalRedundantPage_level3 = 0;
1489 uint64_t grandTotalPage = 0;
1491 float minrate = 100;
1492 fprintf(
gTraceFile,
"\n--------------- Dumping CACHE Redundancy Info ----------------\n");
1493 fprintf(
gTraceFile,
"\n*************** Dump Data from Thread %d ****************\n", threadId);
1495 for (unordered_map<uint64_t, DataLogs>::iterator it = CacheRedMap[threadId].begin(); it != CacheRedMap[threadId].end(); ++it) {
1496 DRedData tmp = {(*it).first, (*it).second.red, (*it).second.tot};
1497 tmpList.push_back(tmp);
1498 grandTotalRedundantBytes += tmp.
frequency;
1507 grandTotalRedundantPage_level1++;
1510 grandTotalRedundantPage_level2++;
1513 grandTotalRedundantPage_level3++;
1519 fprintf(
gTraceFile,
"\n Total redundant bytes = %f, rate range from [%f, %f] %%\n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad, minrate * 100, maxrate * 100);
1521 fprintf(
gTraceFile,
"\n Total redundant bytes (local redundant rate > %f %%) = %f %%\n",
LEVEL_1_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level1 * 100.0 / grandTotalPage);
1522 fprintf(
gTraceFile,
"\n Total redundant bytes (local redundant rate > %f %%) = %f %%\n",
LEVEL_2_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level2 * 100.0 / grandTotalPage);
1523 fprintf(
gTraceFile,
"\n Total redundant bytes (local redundant rate > %f %%) = %f %%\n",
LEVEL_3_RED_THRESHOLD * 100.0, grandTotalRedundantPage_level3 * 100.0 / grandTotalPage);
1524 #ifdef PRINT_ALL_PAGE_INFO
1527 for (vector<DRedData>::iterator listIt = tmpList.begin(); listIt != tmpList.end(); ++listIt) {
1529 fprintf(
gTraceFile,
"\n\n======= CACHE %lx : (%f) %% of total Redundant, with local redundant %f %% (%ld Bytes / %ld Bytes) ======\n",
1531 (*listIt).frequency * 100.0 / grandTotalRedundantBytes,
1532 (*listIt).frequency * 100.0 / (*listIt).ltot,
1533 (*listIt).frequency, (*listIt).ltot);
1540 fprintf(
gTraceFile,
"\n------------ Dumping CACHE Redundancy Info Finish -------------\n");
1550 #ifdef SKIP_SMALLACCESS
1551 #define LOGGING_THRESHOLD 100
1554 vector<RedundacyData> tmpList;
1555 vector<RedundacyData>::iterator tmpIt;
1557 uint64_t grandTotalRedundantBytes = 0;
1558 uint64_t grandTotalRedundantIns = 0;
1559 tmpList.reserve(
RedMap[threadId].size());
1560 printf(
"Dumping INTEGER Redundancy Info... Total num : %ld\n",
RedMap[threadId].size());
1562 fprintf(
gTraceFile,
"\n--------------- Dumping INTEGER Redundancy Info ----------------\n");
1563 fprintf(
gTraceFile,
"\n*************** Dump Data from Thread %d ****************\n", threadId);
1567 fprintf(
gTraceFile,
"\n*************** Merging Redundancy Info, The Caller Prefix Printed is useless ****************\n");
1568 for (unordered_map<uint64_t, RedLogs>::iterator it =
RedMap[threadId].begin(); it !=
RedMap[threadId].end(); ++it) {
1570 if (100 * count /
RedMap[threadId].size() != rep) {
1571 rep = 100 * count /
RedMap[threadId].size();
1572 printf(
"%ld%% Finish, current list size = %ld\n", rep, tmpList.size());
1575 grandTotalRedundantBytes += (*it).second.red;
1576 #ifdef SKIP_SMALLACCESS
1577 if ((*it).second.tot > LOGGING_THRESHOLD * ((*it).second.AccessLen))
1583 for (tmpIt = tmpList.begin(); tmpIt != tmpList.end(); ++tmpIt) {
1584 if ((*tmpIt).cntxt == 0) {
1592 (*tmpIt).frequency += (*it).second.red;
1593 (*tmpIt).all0freq += (*it).second.fred;
1594 (*tmpIt).ltot += (*it).second.tot;
1595 (*tmpIt).byteMap &= (*it).second.redByteMap;
1597 grandTotalRedundantIns += 1;
1602 if (tmpIt == tmpList.end()) {
1605 tmpList.push_back(tmp);
1609 for (unordered_map<uint64_t, RedLogs>::iterator it =
RedMap[threadId].begin(); it !=
RedMap[threadId].end(); ++it) {
1611 if (100 * count /
RedMap[threadId].size() != rep) {
1612 rep = 100 * count /
RedMap[threadId].size();
1613 printf(
"%ld%% Finish\n", rep);
1617 tmpList.push_back(tmp);
1618 grandTotalRedundantBytes += tmp.
frequency;
1623 printf(
"Extracted Raw data, now sorting...\n");
1626 fprintf(
gTraceFile,
"\n Total redundant bytes = %f %%\n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad);
1627 fprintf(
gTraceFile,
"\n INFO : Total redundant bytes = %f %% (%ld / %ld) \n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad, grandTotalRedundantBytes,
ClientGetTLS(threadId)->bytesLoad);
1630 printf(
"Sorted, Now generating reports...\n");
1633 for (vector<RedundacyData>::iterator listIt = tmpList.begin(); listIt != tmpList.end(); ++listIt) {
1635 fprintf(
gTraceFile,
"\n\n======= (%f) %% of total Redundant, with local redundant %f %% (%ld Bytes / %ld Bytes) ======\n",
1636 (*listIt).frequency * 100.0 / grandTotalRedundantBytes,
1637 (*listIt).frequency * 100.0 / (*listIt).ltot,
1638 (*listIt).frequency, (*listIt).ltot);
1639 fprintf(
gTraceFile,
"\n\n======= with All Zero Redundant %f %% (%ld / %ld) ======\n",
1640 (*listIt).all0freq * (*listIt).accessLen * 100.0 / (*listIt).ltot,
1641 (*listIt).all0freq, (*listIt).ltot / (*listIt).accessLen);
1642 fprintf(
gTraceFile,
"\n======= Redundant byte map : [0] ");
1643 for (uint32_t i = 0; i < (*listIt).accessLen; ++i) {
1644 if ((*listIt).byteMap & (1 << i)) {
1650 fprintf(
gTraceFile,
" [AccessLen=%d] =======\n", (*listIt).accessLen);
1651 fprintf(
gTraceFile,
"\n---------------------Redundant load with---------------------------\n");
1658 fprintf(
gTraceFile,
"\n------------ Dumping INTEGER Redundancy Info Finish -------------\n");
1659 printf(
"INTEGER Report dumped\n");
1664 vector<ApproxRedundacyData> tmpList;
1665 vector<ApproxRedundacyData>::iterator tmpIt;
1667 uint64_t grandTotalRedundantBytes = 0;
1668 uint64_t grandTotalRedundantIns = 0;
1669 fprintf(
gTraceFile,
"\n--------------- Dumping Approximation Redundancy Info ----------------\n");
1670 fprintf(
gTraceFile,
"\n*************** Dump Data(delta=%.2f%%) from Thread %d ****************\n",
delta * 100, threadId);
1672 fprintf(
gTraceFile,
"\n*************** Merging Approximation Redundancy Info, The Caller Prefix Printed is useless ****************\n");
1673 for (unordered_map<uint64_t, ApproxRedLogs>::iterator it =
ApproxRedMap[threadId].begin(); it !=
ApproxRedMap[threadId].end(); ++it) {
1674 grandTotalRedundantBytes += (*it).second.fred * (*it).second.AccessLen;
1675 #ifdef SKIP_SMALLACCESS
1677 if ((*it).second.ftot > LOGGING_THRESHOLD)
1682 for (tmpIt = tmpList.begin(); tmpIt != tmpList.end(); ++tmpIt) {
1683 if (cur == 0 || ((*tmpIt).cntxt) == 0) {
1692 (*tmpIt).all0freq += (*it).second.fred;
1694 (*tmpIt).ftot += (*it).second.ftot;
1695 #ifndef NO_APPROXMAP
1696 (*tmpIt).byteMapMan &= (*it).second.redByteMapMan;
1697 (*tmpIt).byteMapExp &= (*it).second.redByteMapExp;
1698 (*tmpIt).byteMapSign &= (*it).second.redByteMapSign;
1700 grandTotalRedundantIns += 1;
1704 if (tmpIt == tmpList.end()) {
1705 ApproxRedundacyData tmp = {
static_cast<ContextHandle_t>((*it).first), (*it).second.fred, (*it).second.ftot, (*it).second.redByteMapMan, (*it).second.redByteMapExp, (*it).second.redByteMapSign, (*it).second.AccessLen, (*it).second.size};
1706 tmpList.push_back(tmp);
1719 fprintf(
gTraceFile,
"\n Total redundant bytes = %f %%\n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad);
1720 fprintf(
gTraceFile,
"\n INFO : Total redundant bytes = %f %% (%ld / %ld) \n", grandTotalRedundantBytes * 100.0 /
ClientGetTLS(threadId)->bytesLoad, grandTotalRedundantBytes,
ClientGetTLS(threadId)->bytesLoad);
1724 for (vector<ApproxRedundacyData>::iterator listIt = tmpList.begin(); listIt != tmpList.end(); ++listIt) {
1727 fprintf(
gTraceFile,
"\n======= (%f) %% of total Redundant, with local redundant %f %% (%ld Zeros / %ld Reads) ======\n",
1728 (*listIt).all0freq * 100.0 / grandTotalRedundantBytes,
1729 (*listIt).all0freq * 100.0 / (*listIt).ftot,
1730 (*listIt).all0freq, (*listIt).ftot);
1737 #ifndef NO_APPROXMAP
1738 fprintf(
gTraceFile,
"\n======= Redundant byte map : [mantiss | exponent | sign] ========\n");
1740 if ((*listIt).size == 4) {
1741 fprintf(
gTraceFile, ((*listIt).byteMapMan & (4)) ?
"00 " :
"XX ");
1742 fprintf(
gTraceFile, ((*listIt).byteMapMan & (2)) ?
"00 " :
"XX ");
1743 fprintf(
gTraceFile, ((*listIt).byteMapMan & (1)) ?
"00 | " :
"XX | ");
1744 fprintf(
gTraceFile, ((*listIt).byteMapExp & (1)) ?
"00 | " :
"XX | ");
1745 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1)) ?
"0 " :
"X ");
1746 for (uint32_t i = 1; i < (*listIt).accessLen / 4; i++) {
1748 fprintf(
gTraceFile, ((*listIt).byteMapMan & (4 << (3 * i))) ?
"00 " :
"XX ");
1749 fprintf(
gTraceFile, ((*listIt).byteMapMan & (2 << (3 * i))) ?
"00 " :
"XX ");
1750 fprintf(
gTraceFile, ((*listIt).byteMapMan & (1 << (3 * i))) ?
"00 | " :
"XX | ");
1751 fprintf(
gTraceFile, ((*listIt).byteMapExp & (1 << (i))) ?
"00 | " :
"XX | ");
1752 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1 << i)) ?
"0 " :
"X ");
1755 fprintf(
gTraceFile, ((*listIt).byteMapMan & (64)) ?
"00 " :
"XX ");
1756 fprintf(
gTraceFile, ((*listIt).byteMapMan & (32)) ?
"00 " :
"XX ");
1757 fprintf(
gTraceFile, ((*listIt).byteMapMan & (16)) ?
"00 " :
"XX ");
1758 fprintf(
gTraceFile, ((*listIt).byteMapMan & (8)) ?
"00 " :
"XX ");
1759 fprintf(
gTraceFile, ((*listIt).byteMapMan & (4)) ?
"00 " :
"XX ");
1760 fprintf(
gTraceFile, ((*listIt).byteMapMan & (2)) ?
"00 " :
"XX ");
1761 fprintf(
gTraceFile, ((*listIt).byteMapMan & (1)) ?
"00 | " :
"XX | ");
1762 fprintf(
gTraceFile, ((*listIt).byteMapExp & (2)) ?
"00 " :
"XX ");
1763 fprintf(
gTraceFile, ((*listIt).byteMapExp & (1)) ?
"00 | " :
"XX | ");
1764 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1)) ?
"0 " :
"X ");
1765 for (uint32_t i = 1; i < (*listIt).accessLen / 8; i++) {
1770 fprintf(
gTraceFile, ((*listIt).byteMapMan & (uint64_t{64} << (7 * i))) ?
"00 " :
"XX ");
1771 fprintf(
gTraceFile, ((*listIt).byteMapMan & (uint64_t{32} << (7 * i))) ?
"00 " :
"XX ");
1772 fprintf(
gTraceFile, ((*listIt).byteMapMan & (uint64_t{16} << (7 * i))) ?
"00 " :
"XX ");
1773 fprintf(
gTraceFile, ((*listIt).byteMapMan & (uint64_t{8} << (7 * i))) ?
"00 " :
"XX ");
1774 fprintf(
gTraceFile, ((*listIt).byteMapMan & (uint64_t{4} << (7 * i))) ?
"00 " :
"XX ");
1775 fprintf(
gTraceFile, ((*listIt).byteMapMan & (uint64_t{2} << (7 * i))) ?
"00 " :
"XX ");
1776 fprintf(
gTraceFile, ((*listIt).byteMapMan & (uint64_t{1} << (7 * i))) ?
"00 | " :
"XX | ");
1777 fprintf(
gTraceFile, ((*listIt).byteMapExp & (2 << (2 * i))) ?
"00 " :
"XX ");
1778 fprintf(
gTraceFile, ((*listIt).byteMapExp & (1 << (2 * i))) ?
"00 | " :
"XX | ");
1779 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1 << i)) ?
"0 " :
"X ");
1783 if ((*listIt).size == 4) {
1784 fprintf(
gTraceFile, ((*listIt).byteMapMan & (1)) ?
"00 " :
"XX ");
1785 fprintf(
gTraceFile, ((*listIt).byteMapMan & (2)) ?
"00 " :
"XX ");
1786 fprintf(
gTraceFile, ((*listIt).byteMapMan & (4)) ?
"00 | " :
"XX | ");
1787 fprintf(
gTraceFile, ((*listIt).byteMapExp & (1)) ?
"00 | " :
"XX | ");
1788 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1)) ?
"0 " :
"X ");
1789 for (uint32_t i = 1; i < (*listIt).accessLen / 4; i++) {
1791 fprintf(
gTraceFile, ((*listIt).byteMapMan & (1 << (3 * i))) ?
"00 " :
"XX ");
1792 fprintf(
gTraceFile, ((*listIt).byteMapMan & (2 << (3 * i))) ?
"00 " :
"XX ");
1793 fprintf(
gTraceFile, ((*listIt).byteMapMan & (4 << (3 * i))) ?
"00 | " :
"XX | ");
1794 fprintf(
gTraceFile, ((*listIt).byteMapExp & (2 << (i))) ?
"00 | " :
"XX | ");
1795 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1 << i)) ?
"0 " :
"X ");
1798 fprintf(
gTraceFile, ((*listIt).byteMapMan & (1)) ?
"00 " :
"XX ");
1799 fprintf(
gTraceFile, ((*listIt).byteMapMan & (2)) ?
"00 " :
"XX ");
1800 fprintf(
gTraceFile, ((*listIt).byteMapMan & (4)) ?
"00 " :
"XX ");
1801 fprintf(
gTraceFile, ((*listIt).byteMapMan & (8)) ?
"00 " :
"XX ");
1802 fprintf(
gTraceFile, ((*listIt).byteMapMan & (16)) ?
"00 " :
"XX ");
1803 fprintf(
gTraceFile, ((*listIt).byteMapMan & (32)) ?
"00 " :
"XX ");
1804 fprintf(
gTraceFile, ((*listIt).byteMapMan & (64)) ?
"00 | " :
"XX | ");
1805 fprintf(
gTraceFile, ((*listIt).byteMapExp & (1)) ?
"00 " :
"XX ");
1806 fprintf(
gTraceFile, ((*listIt).byteMapExp & (2)) ?
"00 | " :
"XX | ");
1807 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1)) ?
"0 " :
"X ");
1808 for (uint32_t i = 1; i < (*listIt).accessLen / 8; i++) {
1810 fprintf(
gTraceFile, ((*listIt).byteMapMan & (1 << (7 * i))) ?
"00 " :
"XX ");
1811 fprintf(
gTraceFile, ((*listIt).byteMapMan & (2 << (7 * i))) ?
"00 " :
"XX ");
1812 fprintf(
gTraceFile, ((*listIt).byteMapMan & (4 << (7 * i))) ?
"00 " :
"XX ");
1813 fprintf(
gTraceFile, ((*listIt).byteMapMan & (8 << (7 * i))) ?
"00 " :
"XX ");
1814 fprintf(
gTraceFile, ((*listIt).byteMapMan & (16 << (7 * i))) ?
"00 " :
"XX ");
1815 fprintf(
gTraceFile, ((*listIt).byteMapMan & (32 << (7 * i))) ?
"00 " :
"XX ");
1816 fprintf(
gTraceFile, ((*listIt).byteMapMan & (64 << (7 * i))) ?
"00 | " :
"XX | ");
1817 fprintf(
gTraceFile, ((*listIt).byteMapExp & (1 << (2 * i))) ?
"00 " :
"XX ");
1818 fprintf(
gTraceFile, ((*listIt).byteMapExp & (2 << (2 * i))) ?
"00 | " :
"XX | ");
1819 fprintf(
gTraceFile, ((*listIt).byteMapSign & (1 << i)) ?
"0 " :
"X ");
1824 fprintf(
gTraceFile,
"\n===== [AccessLen=%d, typesize=%d] =======\n", (*listIt).accessLen, (*listIt).size);
1825 fprintf(
gTraceFile,
"\n---------------------Redundant load with---------------------------\n");
1833 fprintf(
gTraceFile,
"\n------------ Dumping Approximation Redundancy Info Finish -------------\n");
1896 printf(
"\nImage %s Unloading...\n", IMG_Name(img).c_str());
1898 fprintf(
gTraceFile,
"\n TODO .. Multi-threading is not well supported.");
1899 THREADID threadid = PIN_ThreadId();
1900 fprintf(
gTraceFile,
"\nUnloading %s", IMG_Name(img).c_str());
1903 printf(
"Now locking client for updating...\n");
1907 printf(
"Client locked, now generate report\n");
1910 printf(
"Generate Floating point report\n");
1913 printf(
"all generated\n");
1915 #ifdef USE_COLLECT_PAGE_CACHE
1920 printf(
"Unlocked\n");
1923 RedMap[threadid].clear();
1925 printf(
"...Finish\n");
1929 static VOID
ThreadFiniFunc(THREADID threadid,
const CONTEXT* ctxt, INT32 code, VOID* v) {
1940 uint64_t redReadTmp = 0;
1941 uint64_t approxRedReadTmp = 0;
1943 unordered_map<uint64_t, RedLogs>::iterator it;
1944 if (!
RedMap[i].empty()) {
1945 for (it =
RedMap[i].begin(); it !=
RedMap[i].end(); ++it) {
1946 redReadTmp += (*it).second.red;
1949 unordered_map<uint64_t, ApproxRedLogs>::iterator ait;
1952 approxRedReadTmp += (*ait).second.fred;
1979 RedMap[threadid].reserve(10000000);
1982 #ifdef MULTI_THREADED
1999 if (PIN_Init(argc, argv))
2024 PIN_AddFiniFunction(
FiniFunc,
nullptr);
#define INTERESTING_INS_ALL
uint8_t ** gL1PageTable[LEVEL_1_PAGE_TABLE_SIZE]
uint8_t * GetOrCreateShadowBaseAddress(void *address)
int PinCCTLibInit(IsInterestingInsFptr isInterestingIns, FILE *logFile, CCTLibInstrumentInsCallback userCallback, VOID *userCallbackArg, BOOL doDataCentric=false)
hpcrun_metricFlags_t flags
VOID PrintFullCallingContext(const ContextHandle_t ctxtHandle)
bool HaveSameCallerPrefix(ContextHandle_t ctxt1, ContextHandle_t ctxt2)
bool IsSameSourceLine(ContextHandle_t ctxt1, ContextHandle_t ctxt2)
ContextHandle_t GetContextHandle(const THREADID id, const uint32_t slot)
static USIZE INS_MemoryReadSize(INS ins)
static BOOL INS_IsMaskedJump(INS ins)
static BOOL INS_IsIndirectBranchOrCall(INS ins)
struct RedSpyThreadData __attribute__
uint8_t value[MAX_WRITE_OP_LENGTH]
#define LEVEL_2_PAGE_TABLE_SIZE
#define LEVEL_1_PAGE_TABLE_SLOT(addr)
#define LEVEL_1_PAGE_TABLE_SIZE
#define LEVEL_2_PAGE_TABLE_SLOT(addr)
static __attribute__((always_inline)) void InstrumentReadValueBeforeAndAfterLoading(INS ins
static __attribute__((always_inline)) uint64_t BodyByteMapExp(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyZeros(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyMap(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyByteMapSign(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyByteMapMan(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyByteMapSign(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyByteMapMan(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyMap(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyZeros(uint8_t *addr)
static __attribute__((always_inline)) uint64_t BodyByteMapExp(uint8_t *addr)
static __attribute__((always_inline)) bool BodyContextCheck(ContextHandle_t *__restrict__ prevIP)
static __attribute__((always_inline)) uint32_t BodyIsZero(uint8_t *addr)
static __attribute__((always_inline)) bool Body(const function< void(const int)> &func)
static __attribute__((always_inline)) uint32_t BodyByteMap(uint8_t *addr)
static __attribute__((always_inline)) bool Body(const function< bool(const int)> &func)
static __attribute__((always_inline)) uint32_t BodyByteMap(uint8_t *addr)
static __attribute__((always_inline)) bool BodyContextCheck(ContextHandle_t *__restrict__ prevIP)
static bool Body(const function< bool(const int)> &func)
static __attribute__((always_inline)) uint32_t BodyIsZero(uint8_t *addr)
static __attribute__((always_inline)) uint32_t BodyRedZero(uint8_t *addr)
static __attribute__((always_inline)) uint32_t BodyRedZero(uint8_t *addr)
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
static __attribute__((always_inline)) uint64_t getRedNum(void *addr)
static __attribute__((always_inline)) uint64_t getRedMap(void *addr)
static bool DRedundacyCompare(const struct DRedData &first, const struct DRedData &second)
#define LEVEL_1_RED_THRESHOLD
#define LEVEL_2_RED_THRESHOLD
#define LEVEL_3_RED_THRESHOLD
static void PrintCacheRedundancy(THREADID threadId)
static void PrintPageRedundancy(THREADID threadId)
uint64_t computeMetricVal(void *metric)
static void ClientInit(int argc, char *argv[])
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 void PrintRedundancyPairs(THREADID threadId)
static const uint64_t READ_ACCESS_STATES[]
static void AddToApproximateRedTable(uint64_t key, uint32_t byteMapMan, uint32_t byteMapExp, uint32_t byteMapSign, uint16_t total, uint16_t zeros, uint16_t nums, uint8_t size, THREADID threadId) __attribute__((always_inline
#define ONE_BYTE_READ_ACTION
static bool RedundacyCompare(const struct RedundacyData &first, const struct RedundacyData &second)
int redload_approx_metric_id
static bool IsFloatInstructionOld(ADDRINT ip)
static unordered_map< uint64_t, ApproxRedLogs > ApproxRedMap[THREAD_MAX]
#define EIGHT_BYTE_READ_ACTION
#define TWO_BYTE_READ_ACTION
struct @17 LoadSpyGlobals
static void AddToRedTable(uint64_t key, uint16_t value, uint32_t byteMap, uint16_t total, THREADID threadId) __attribute__((always_inline
static uint16_t FloatOperandSize(ADDRINT ip, uint32_t oper)
static const uint8_t OVERFLOW_CHECK[]
#define MAKE_CONTEXT_PAIR(a, b)
VOID Update(uint32_t bytes, THREADID threadId)
#define DECODE_DEAD(data)
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)
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 PrintApproximationRedundancyPairs(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)
static bool ApproxRedundacyCompare(const struct ApproxRedundacyData &first, const struct ApproxRedundacyData &second)
#define ONE_BYTE_WRITE_ACTION
#define FOUR_BYTE_WRITE_ACTION
#define DECODE_KILL(data)
static TLS_KEY client_tls_key
static VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)