// File: /workspace/github_cpp_makefile_star2_O3/SamKG[P]Flush-Reload-Sidechannel/receiver.cpp
// Function: main
int main(int argc, char **argv)
{
	// Put your covert channel setup code here
	int fd = open("sender",O_RDONLY);
	char* mapped = (char*) mmap(NULL, 0x20000, PROT_READ, MAP_PRIVATE, fd, 0);
	// I think using uint64_t prevents prefetching
	int num_ptrs = 0;
	ADDR_PTR probe_ptrs[100];
	int mult = 15;
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_0 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_1 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_2 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_3 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_4 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_5 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_6 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_7 + mult*CACHE_LINE_SIZE);
	probe_ptrs[num_ptrs++] = (uint64_t)(mapped + ADDR_8 + mult*CACHE_LINE_SIZE);
	printf("Please press enter.\n");

	char text_buf[2];
	fgets(text_buf, sizeof(text_buf), stdin);

	printf("Receiver now listening.\n");
	int hitcnt = 0;
	bool listening = true;
	int hits[100];
	while (listening) {
		//spy flushes
		for (int i = 0 ; i < 100 ; i++){
			hits[i] = 0;
		}
		//spy waits TIME_SLOT time
		for (int i = 0 ; i < SLOT_WINDOW_COUNT;  i++){
			for (int i = 0 ; i < num_ptrs ; i++){
				flush_one_block(probe_ptrs[i]);
			}
			CYCLES start_t = get_highres_time();
			while(get_highres_time() - start_t <= TIME_SLOT){
			}
			//spy reloads
			for (int i = 0 ; i < num_ptrs ; i++){
				CYCLES time = probe_one_block(probe_ptrs[i]);
				if ( time < TIME_CUTOFF){
					hits[i]++;
					//printf("HIT %d\t%d\t%d\n",i,hitcnt++,time);
				}
			}
		}
		
		if (hits[0] >= SLOT_HIT_CUTOFF){
			// 0 bit means we have a message!
			int bitstr = 0;
			for (int i = 1 ; i < num_ptrs ; i++){
				if (hits[i] >= SLOT_HIT_CUTOFF){
					//printf("HIT BIT %d\n",i);
					bitstr |= 1<<(i-1);	
				}
			}
			printf("%c",(char)bitstr);
			fflush(stdout);
		}

	}

	printf("Receiver finished.\n");

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x4d8, %rsp            # imm = 0x4D8
leaq 0xe90(%rip), %rdi       # 0x2040
xorl %esi, %esi
xorl %eax, %eax
callq 0x1040
movl $0x20000, %esi          # imm = 0x20000
xorl %edi, %edi
movl $0x1, %edx
movl $0x2, %ecx
movl %eax, %r8d
xorl %r9d, %r9d
callq 0x1090
leaq 0x1536(%rax), %rcx
movq %rcx, 0x20(%rsp)
leaq 0x26bd(%rax), %rcx
movq %rcx, 0x28(%rsp)
leaq 0x3844(%rax), %rcx
movq %rcx, 0x30(%rsp)
leaq 0x49cb(%rax), %rcx
movq %rcx, 0x38(%rsp)
leaq 0x5b52(%rax), %rcx
movq %rcx, 0x40(%rsp)
leaq 0x6cd9(%rax), %rcx
movq %rcx, 0x48(%rsp)
leaq 0x7e60(%rax), %rcx
movq %rcx, 0x50(%rsp)
leaq 0x8fe7(%rax), %rcx
movq %rcx, 0x58(%rsp)
addq $0xa16e, %rax           # imm = 0xA16E
movq %rax, 0x60(%rsp)
leaq 0xe00(%rip), %rdi       # 0x2047
callq 0x1070
movq 0x2d8d(%rip), %rax      # 0x3fe0
movq (%rax), %rdx
leaq 0xe(%rsp), %rdi
movl $0x2, %esi
callq 0x1080
leaq 0xdef(%rip), %rdi       # 0x205b
callq 0x1070
leaq 0x340(%rsp), %rbx
movq 0x2d48(%rip), %r14      # 0x3fc8
movl $0x190, %edx            # imm = 0x190
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1030
xorl %ebp, %ebp
xorl %r15d, %r15d
movq 0x20(%rsp,%r15,8), %rdi
callq 0x1436
incq %r15
cmpq $0x9, %r15
jne 0x1294
callq 0x138e
movq %rax, 0x18(%rsp)
callq 0x138e
subq 0x18(%rsp), %rax
cmpq $0x9c5, %rax            # imm = 0x9C5
jb 0x12b1
xorl %r15d, %r15d
movq 0x20(%rsp,%r15,8), %rdi
callq 0x13b2
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
cmpq $0xc7, %rax
ja 0x12ea
incl 0x340(%rsp,%r15,4)
incq %r15
cmpq $0x9, %r15
jne 0x12c6
incl %ebp
cmpl $0xa, %ebp
jne 0x1291
cmpl $0x2, 0x340(%rsp)
jl 0x1280
movdqu 0x344(%rsp), %xmm0
movdqu 0x354(%rsp), %xmm1
movdqa 0xcee(%rip), %xmm2      # 0x2010
pcmpgtd %xmm2, %xmm0
pand 0xcf2(%rip), %xmm0      # 0x2020
pcmpgtd %xmm2, %xmm1
pand 0xcf6(%rip), %xmm1      # 0x2030
por %xmm0, %xmm1
pshufd $0xee, %xmm1, %xmm0     # xmm0 = xmm1[2,3,2,3]
por %xmm1, %xmm0
pshufd $0x55, %xmm0, %xmm1     # xmm1 = xmm0[1,1,1,1]
por %xmm0, %xmm1
movd %xmm1, %eax
movsbl %al, %edi
callq 0x1060
movq (%r14), %rdi
callq 0x1050
jmp 0x1280
nopl (%rax)