CCTLib
Calling-context and data-object attribution library for Intel Pin
deadspy_pushpop_dead_tp.c
Go to the documentation of this file.
1 // Deadspy ISA edge case: push, adjust rsp, push same effective address.
2 // The two `pushq %rax` instructions both write 8 bytes at the SAME
3 // effective stack address because the intervening `addq $8, %rsp` rewinds
4 // the stack pointer between them. The second push dead-writes the first.
5 //
6 // This tests deadspy's ability to see through
7 // (a) rsp-relative addressing,
8 // (b) implicit RSP updates,
9 // (c) the address computed at instruction-time, not statically.
10 #include <stdint.h>
11 #define WORK_COUNT 10000
12 static volatile uint64_t sink;
13 int main(int argc, char** argv) {
14  (void)argc; (void)argv;
15  uint64_t v1 = 0x1111, v2 = 0x2222;
16  uint64_t acc = 0;
17  for (int i = 0; i < WORK_COUNT; ++i) {
18  // Reserve 16 bytes of scratch stack so we don't clobber return addr.
19  __asm__ __volatile__(
20  "subq $16, %%rsp\n\t"
21  "pushq %[v1]\n\t" // 8B write at rsp-8
22  "addq $8, %%rsp\n\t" // rewind rsp back
23  "pushq %[v2]\n\t" // 8B write at rsp-8 == same addr, dead
24  "popq %[out]\n\t" // read back v2
25  "addq $16, %%rsp\n\t" // release scratch
26  : [out] "=r"(acc)
27  : [v1] "r"(v1), [v2] "r"(v2)
28  : "memory", "cc");
29  (void)acc;
30  }
31  sink = acc;
32  return 0;
33 }
#define WORK_COUNT
int main(int argc, char **argv)
static volatile uint64_t sink