// File: /workspace/github_c_makefile_star2_O0/melynx[P]peekaboo/libpeekaboo/libpeekaboo.c
// Function: load_trace
void load_trace(char *dir_path, peekaboo_trace_t *trace_ptr)
{
	char path[MAX_PATH];

	// Load metadata first
	snprintf(path, MAX_PATH, "%s/%s", dir_path, "metafile");
	trace_ptr->metafile = fopen(path, "rb");
	if (trace_ptr->metafile == NULL) PEEKABOO_DIE("libpeekaboo: Unable to load %s\n", path);

	// Creates the internal data-structure to store the
	// meta-information about the loaded trace
	trace_ptr->internal = malloc(sizeof(peekaboo_internal_t));
	memset(trace_ptr->internal, 0, sizeof(peekaboo_internal_t));

	// Setup the information
	metadata_hdr_t meta;
	size_t fread_bytes = fread(&meta, sizeof(metadata_hdr_t), 1, trace_ptr->metafile);
	trace_ptr->internal->arch = meta.arch;
	trace_ptr->internal->version = meta.version;
	fprintf(stderr, "Trace's libpeekaboo version: %d\n", meta.version);
	fclose(trace_ptr->metafile);

	if (trace_ptr->internal->version >= 4)
	{
		// New trace format that can customize which registers to store
		if (trace_ptr->internal->arch == ARCH_AMD64)
		{
			trace_ptr->internal->storage_options.amd64.has_simd = meta.storage_options.amd64.has_simd;
			trace_ptr->internal->storage_options.amd64.has_fxsave = meta.storage_options.amd64.has_fxsave;
			fprintf(stderr, "Stored register: GPRs ");
			if (trace_ptr->internal->storage_options.amd64.has_simd) fprintf(stderr, "SIMD ");
			if (trace_ptr->internal->storage_options.amd64.has_fxsave) fprintf(stderr, "FXSAVE ");
			fprintf(stderr, "\n");
		}
	}
	else
	{
		// Trace version lower than 003, stores everything
		trace_ptr->internal->storage_options.amd64.has_simd = 1;
		trace_ptr->internal->storage_options.amd64.has_fxsave = 1;
	}

	switch (meta.arch)
	{
		case ARCH_AMD64:
			trace_ptr->internal->ptr_size = 8;
			trace_ptr->internal->regfile_size = sizeof(regfile_amd64_t);
			break;
		case ARCH_AARCH64:
			trace_ptr->internal->ptr_size = 8;
			trace_ptr->internal->regfile_size = sizeof(regfile_aarch64_t);
			break;
		case ARCH_X86:
			trace_ptr->internal->ptr_size = 4;
			trace_ptr->internal->regfile_size = sizeof(regfile_x86_t);
			break;
		default:
			trace_ptr->internal->ptr_size = 0;
			trace_ptr->internal->regfile_size = 0;
			break;
	}

	// Load bytes_map based on the version
	if (meta.version > 1)
		snprintf(path, MAX_PATH, "%s/../%s", dir_path, "insn.bytemap");
	else
		// Legacy trace format in Verion 1 which does not have separate folders for different threads.
		snprintf(path, MAX_PATH, "%s/%s", dir_path, "insn.bytemap");
	trace_ptr->bytes_map = fopen(path, "rb");
	if (trace_ptr->bytes_map == NULL) PEEKABOO_DIE("libpeekaboo: Unable to load bytes_map\n");

	// Load insn.trace, regfile, memfile, memrefs.
	snprintf(path, MAX_PATH, "%s/%s", dir_path, "insn.trace");
	trace_ptr->insn_trace = fopen(path, "rb");
	if (trace_ptr->insn_trace == NULL) PEEKABOO_DIE("libpeekaboo: Unable to load %s\n", path);
	snprintf(path, MAX_PATH, "%s/%s", dir_path, "regfile");
	trace_ptr->regfile = fopen(path, "rb");
	if (trace_ptr->regfile == NULL) PEEKABOO_DIE("libpeekaboo: Unable to load %s\n", path);
	snprintf(path, MAX_PATH, "%s/%s", dir_path, "memfile");
	trace_ptr->memfile = fopen(path, "rb");
	if (trace_ptr->memfile == NULL) PEEKABOO_DIE("libpeekaboo: Unable to load %s\n", path);
	snprintf(path, MAX_PATH, "%s/%s", dir_path, "memrefs");
	trace_ptr->memrefs = fopen(path, "rb");
	if (trace_ptr->memrefs == NULL) PEEKABOO_DIE("libpeekaboo: Unable to load %s\n", path);

	// Init for internal structure
	size_t trace_size = 0;
	size_t ptr_size = trace_ptr->internal->ptr_size;
	fseek(trace_ptr->insn_trace, 0, SEEK_END);
	trace_size = ftell(trace_ptr->insn_trace);
	rewind(trace_ptr->insn_trace);
	trace_ptr->internal->num_insns = trace_size/ptr_size;

	// loads the rawbytes map for the trace
	load_bytes_map(trace_ptr);

	// load memrefs_offsets. Create if not exist 
	load_memrefs_offsets(dir_path, trace_ptr);

	// All good. Ready to go~!
	return ;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x1d3f(%rip), %rdx      # 0x6ec9
leaq 0x1cab(%rip), %r8       # 0x6e3c
movb $0x0, %al
callq 0x4140
leaq -0x110(%rbp), %rdi
leaq 0x1e1e(%rip), %rsi      # 0x6fc4
callq 0x4250
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jne 0x51ea
movq 0x4e28(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq -0x110(%rbp), %rdx
leaq 0x1dee(%rip), %rsi      # 0x6fc7
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
movl $0x68, %edi
callq 0x41f0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
xorl %esi, %esi
movl $0x68, %edx
callq 0x4170
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rcx
leaq -0x120(%rbp), %rdi
movl $0x10, %esi
movl $0x1, %edx
callq 0x40c0
movq %rax, -0x128(%rbp)
movl -0x120(%rbp), %ecx
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl %ecx, (%rax)
movl -0x11c(%rbp), %ecx
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl %ecx, 0x58(%rax)
movq 0x4d90(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
movl -0x11c(%rbp), %edx
leaq 0x1d77(%rip), %rsi      # 0x6fe7
movb $0x0, %al
callq 0x4190
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x40e0
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x4, 0x58(%rax)
jb 0x5347
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x3, (%rax)
jne 0x5345
movl -0x118(%rbp), %ecx
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl %ecx, 0x60(%rax)
movl -0x114(%rbp), %ecx
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl %ecx, 0x64(%rax)
movq 0x4d20(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1d2e(%rip), %rsi      # 0x7008
movb $0x0, %al
callq 0x4190
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x0, 0x60(%rax)
je 0x5307
movq 0x4cfa(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1d1f(%rip), %rsi      # 0x701f
movb $0x0, %al
callq 0x4190
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x0, 0x64(%rax)
je 0x532d
movq 0x4cd4(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1cff(%rip), %rsi      # 0x7025
movb $0x0, %al
callq 0x4190
movq 0x4cbc(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1b4f(%rip), %rsi      # 0x6e8d
movb $0x0, %al
callq 0x4190
jmp 0x5365
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl $0x1, 0x60(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl $0x1, 0x64(%rax)
movl -0x120(%rbp), %eax
movl %eax, -0x13c(%rbp)
subl $0x1, %eax
je 0x53b4
jmp 0x5378
movl -0x13c(%rbp), %eax
subl $0x2, %eax
je 0x53d6
jmp 0x5385
movl -0x13c(%rbp), %eax
subl $0x3, %eax
jne 0x53f8
jmp 0x5392
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x8, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x490, 0x10(%rax)      # imm = 0x490
jmp 0x5418
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x8, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x318, 0x10(%rax)      # imm = 0x318
jmp 0x5418
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x4, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x20, 0x10(%rax)
jmp 0x5418
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq $0x0, 0x10(%rax)
cmpl $0x1, -0x11c(%rbp)
jbe 0x5448
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x1bf5(%rip), %rdx      # 0x702d
leaq 0x1bf7(%rip), %r8       # 0x7036
movb $0x0, %al
callq 0x4140
jmp 0x546d
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x1a6a(%rip), %rdx      # 0x6ec9
leaq 0x1bd0(%rip), %r8       # 0x7036
movb $0x0, %al
callq 0x4140
leaq -0x110(%rbp), %rdi
leaq 0x1b49(%rip), %rsi      # 0x6fc4
callq 0x4250
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x54b8
movq 0x4b53(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1b9c(%rip), %rsi      # 0x7043
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x19fa(%rip), %rdx      # 0x6ec9
leaq 0x1943(%rip), %r8       # 0x6e19
movb $0x0, %al
callq 0x4140
leaq -0x110(%rbp), %rdi
leaq 0x1ad9(%rip), %rsi      # 0x6fc4
callq 0x4250
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x552d
movq 0x4ae5(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq -0x110(%rbp), %rdx
leaq 0x1aab(%rip), %rsi      # 0x6fc7
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x1985(%rip), %rdx      # 0x6ec9
leaq 0x18d9(%rip), %r8       # 0x6e24
movb $0x0, %al
callq 0x4140
leaq -0x110(%rbp), %rdi
leaq 0x1a64(%rip), %rsi      # 0x6fc4
callq 0x4250
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x55a4
movq 0x4a6e(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq -0x110(%rbp), %rdx
leaq 0x1a34(%rip), %rsi      # 0x6fc7
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x190e(%rip), %rdx      # 0x6ec9
leaq 0x186a(%rip), %r8       # 0x6e2c
movb $0x0, %al
callq 0x4140
leaq -0x110(%rbp), %rdi
leaq 0x19ed(%rip), %rsi      # 0x6fc4
callq 0x4250
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
jne 0x561b
movq 0x49f7(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq -0x110(%rbp), %rdx
leaq 0x19bd(%rip), %rsi      # 0x6fc7
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rcx
movl $0x100, %esi            # imm = 0x100
leaq 0x1897(%rip), %rdx      # 0x6ec9
leaq 0x17fb(%rip), %r8       # 0x6e34
movb $0x0, %al
callq 0x4140
leaq -0x110(%rbp), %rdi
leaq 0x1976(%rip), %rsi      # 0x6fc4
callq 0x4250
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x5692
movq 0x4980(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq -0x110(%rbp), %rdx
leaq 0x1946(%rip), %rsi      # 0x6fc7
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
movq $0x0, -0x130(%rbp)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x4220
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x41a0
movq %rax, -0x130(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x4130
movq -0x130(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x138(%rbp)
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rdi
callq 0x4240
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x41b0
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopw %cs:(%rax,%rax)