// File: /workspace/github_c_makefile_star2_O0/melynx[P]peekaboo/libpeekaboo/libpeekaboo.c
// Function: load_memrefs_offsets
void load_memrefs_offsets(char *dir_path, peekaboo_trace_t *trace)
{
	char path[MAX_PATH];
	snprintf(path, MAX_PATH, "%s/%s", dir_path, "memrefs_offsets");

	if (access(path, F_OK) == -1)
	{
		uint64_t base_offset = 0;

		/* KH: This is a ad-hoc patch to fix the bug in peekaboo_dr.
		 * When the application process forks, there are some residues
		 * in memfile buffer that can't be cleaned up.
		 * Thus, When read those traces, we need to find the real starting
		 * point of the memfile. We use base_offset to store it.
		 */
		if (trace->internal->version >= 3)
		{
			// Find the first instruction that has memory access
			uint64_t first_pc = 0x0;
			size_t trace_len = trace->internal->num_insns;
			size_t id=1;
			for(; id<=trace_len; id++)
			{
				size_t num_mem = get_num_mem(id, trace);
				if (num_mem == 0) continue;
				first_pc = get_addr(id, trace);
				break;
			}
			if (id > trace_len)
			{
				// A weird trace. It doesn't have any memory access. 
				// Do nothing but gives a warning.
				fprintf(stderr, "libpeekaboo: [Warning] No memory ops found in this trace.\n");
			}
			else
			{
				if (first_pc==0) PEEKABOO_DIE("libpeekaboo: zero pc for id %lu", id);
				fseek(trace->memfile, 0, SEEK_END);
				memfile_t mem;
				mem.pc = 0;
				errno = 0;
				fseek(trace->memfile, base_offset, SEEK_SET);
				size_t read_size = fread(&mem, sizeof(memfile_t), 1, trace->memfile);
				while(mem.pc!=first_pc && errno==0)
				{
					base_offset += sizeof(memfile_t);
					fseek(trace->memfile, base_offset, SEEK_SET);
					read_size = fread(&mem, sizeof(memfile_t), 1, trace->memfile);
				}
			}
		}
		if (base_offset!=0) fprintf(stderr, "libpeekaboo: (Trace from a child thread/process?) Re-align the memory offset, starting from %ld.\n", base_offset/sizeof(memfile_t));

		FILE *memrefs_offsets = fopen(path, "wb");
		if (!memrefs_offsets) PEEKABOO_DIE("libpeekaboo: Fail to open memref file!\n");

		memref_t buffer[1024];
		size_t write_buffer[1024];

		size_t read_size = 0;
		size_t offset = base_offset;

		rewind(trace->memrefs);
		do {
			read_size = fread(buffer, sizeof(memref_t), 1024, trace->memrefs);
			int x;
			for (x=0; x<read_size; x++)
			{
				if (buffer[x].length)
				{
					write_buffer[x] = offset;
					if (trace->internal->version < 3)
						// Memfiles in old versions are different
						offset += buffer[x].length * sizeof(uint64_t) * 3;
					else
						offset += buffer[x].length * sizeof(memfile_t);
				}
				else
				{
					write_buffer[x] = -1;
				}
			}
			fwrite(write_buffer, sizeof(size_t), read_size, memrefs_offsets);
		} while (read_size == 1024);
		rewind(trace->memrefs);
		fclose(memrefs_offsets);
	}
	trace->memrefs_offsets = fopen(path, "rb");

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3190, %rsp           # imm = 0x3190
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x217f(%rip), %rdx      # 0x6ec9
leaq 0x217e(%rip), %r8       # 0x6ecf
movb $0x0, %al
callq 0x4140
leaq -0x110(%rbp), %rdi
xorl %esi, %esi
callq 0x4230
cmpl $-0x1, %eax
jne 0x5132
movq $0x0, -0x118(%rbp)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x3, 0x58(%rax)
jb 0x4f67
movq $0x0, -0x120(%rbp)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x28(%rax), %rax
movq %rax, -0x128(%rbp)
movq $0x1, -0x130(%rbp)
movq -0x130(%rbp), %rax
cmpq -0x128(%rbp), %rax
ja 0x4e15
movq -0x130(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x4050
movq %rax, -0x138(%rbp)
cmpq $0x0, -0x138(%rbp)
jne 0x4de8
jmp 0x4e01
movq -0x130(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x4210
movq %rax, -0x120(%rbp)
jmp 0x4e15
movq -0x130(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x130(%rbp)
jmp 0x4db5
movq -0x130(%rbp), %rax
cmpq -0x128(%rbp), %rax
jbe 0x4e42
movq 0x51c4(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x20a9(%rip), %rsi      # 0x6edf
movb $0x0, %al
callq 0x4190
jmp 0x4f65
cmpq $0x0, -0x120(%rbp)
jne 0x4e75
movq 0x519d(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
movq -0x130(%rbp), %rdx
leaq 0x20b6(%rip), %rsi      # 0x6f1a
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x4220
movq $0x0, -0x140(%rbp)
callq 0x4080
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x118(%rbp), %rsi
xorl %edx, %edx
callq 0x4220
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rcx
leaq -0x158(%rbp), %rdi
movl $0x20, %esi
movl $0x1, %edx
callq 0x40c0
movq %rax, -0x160(%rbp)
movq -0x140(%rbp), %rcx
xorl %eax, %eax
cmpq -0x120(%rbp), %rcx
movb %al, -0x3185(%rbp)
je 0x4f05
callq 0x4080
cmpl $0x0, (%rax)
sete %al
movb %al, -0x3185(%rbp)
movb -0x3185(%rbp), %al
testb $0x1, %al
jne 0x4f11
jmp 0x4f63
movq -0x118(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x118(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x118(%rbp), %rsi
xorl %edx, %edx
callq 0x4220
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rcx
leaq -0x158(%rbp), %rdi
movl $0x20, %esi
movl $0x1, %edx
callq 0x40c0
movq %rax, -0x160(%rbp)
jmp 0x4edc
jmp 0x4f65
jmp 0x4f67
cmpq $0x0, -0x118(%rbp)
je 0x4f94
movq 0x5078(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
movq -0x118(%rbp), %rdx
shrq $0x5, %rdx
leaq 0x1fad(%rip), %rsi      # 0x6f3a
movb $0x0, %al
callq 0x4190
leaq -0x110(%rbp), %rdi
leaq 0x1e45(%rip), %rsi      # 0x6de7
callq 0x4250
movq %rax, -0x168(%rbp)
cmpq $0x0, -0x168(%rbp)
jne 0x4fda
movq 0x5031(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1fd3(%rip), %rsi      # 0x6f9c
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
movq $0x0, -0x3178(%rbp)
movq -0x118(%rbp), %rax
movq %rax, -0x3180(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x4130
leaq -0x1170(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
movl $0x4, %esi
movl $0x400, %edx            # imm = 0x400
callq 0x40c0
movq %rax, -0x3178(%rbp)
movl $0x0, -0x3184(%rbp)
movslq -0x3184(%rbp), %rax
cmpq -0x3178(%rbp), %rax
jae 0x50e9
movslq -0x3184(%rbp), %rax
cmpl $0x0, -0x1170(%rbp,%rax,4)
je 0x50c0
movq -0x3180(%rbp), %rcx
movslq -0x3184(%rbp), %rax
movq %rcx, -0x3170(%rbp,%rax,8)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x3, 0x58(%rax)
jae 0x509e
movslq -0x3184(%rbp), %rax
movl -0x1170(%rbp,%rax,4), %eax
shlq $0x3, %rax
imulq $0x3, %rax, %rax
addq -0x3180(%rbp), %rax
movq %rax, -0x3180(%rbp)
jmp 0x50be
movslq -0x3184(%rbp), %rax
movl -0x1170(%rbp,%rax,4), %eax
shlq $0x5, %rax
addq -0x3180(%rbp), %rax
movq %rax, -0x3180(%rbp)
jmp 0x50d3
movslq -0x3184(%rbp), %rax
movq $-0x1, -0x3170(%rbp,%rax,8)
jmp 0x50d5
movl -0x3184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3184(%rbp)
jmp 0x502f
leaq -0x3170(%rbp), %rdi
movq -0x3178(%rbp), %rdx
movq -0x168(%rbp), %rcx
movl $0x8, %esi
callq 0x4270
cmpq $0x400, -0x3178(%rbp) # imm = 0x400
je 0x5000
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x4130
movq -0x168(%rbp), %rdi
callq 0x40e0
leaq -0x110(%rbp), %rdi
leaq 0x1e84(%rip), %rsi      # 0x6fc4
callq 0x4250
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
addq $0x3190, %rsp           # imm = 0x3190
popq %rbp
retq
nopl (%rax)