// File: /workspace/github_c_makefile_star2_O2/melynx[P]peekaboo/libpeekaboo/libpeekaboo.c
// Function: get_peekaboo_insn
peekaboo_insn_t *get_peekaboo_insn(const size_t id, peekaboo_trace_t *trace)
{
	// insn is the peekaboo instruction record
	peekaboo_insn_t *insn = malloc(sizeof(peekaboo_insn_t));
	size_t regfile_size = get_regfile_size(trace);
	insn->regfile = malloc(regfile_size);
	insn->arch = trace->internal->arch;

	
	// populate the address for the instruction
	insn->addr = get_addr(id, trace);

	// get the rawbytes for the instruction
	bytes_map_t *bytes_map = find_bytes_map(insn->addr, trace);
	if (!bytes_map) PEEKABOO_DIE("libpeekaboo: Error. Cannot find instruction (ID:%ld) at 0x%"PRIx64" in bytes_map. Terminated!\n", id, insn->addr);
	insn->size = bytes_map->size;
	memcpy(insn->rawbytes, bytes_map->rawbytes, 16);

	// get the number of mem operands
	insn->num_mem = get_num_mem(id, trace);
	if (insn->num_mem > 8) PEEKABOO_DIE("libpeekaboo: Error. Instruction (ID:%ld) at 0x%"PRIx64" has more than 8 memory ops. Terminated!\n", id, insn->addr);
	int fseek_return = fseek(trace->memrefs_offsets, (id-1) * sizeof(size_t), SEEK_SET);
	size_t memfile_offset;
	size_t fread_bytes = fread(&memfile_offset, sizeof(size_t), 1, trace->memrefs_offsets);
	errno = 0;
	if (memfile_offset != (size_t) -1)
	{
		fseek(trace->memfile, memfile_offset, SEEK_SET);
		const size_t memfile_size = (trace->internal->version < 3) ? (sizeof(uint64_t) * 3) : sizeof(memfile_t);
		for (uint32_t idx = 0; idx<insn->num_mem; idx++)
		{
			fread_bytes = fread(&insn->mem[idx], memfile_size, 1, trace->memfile);

			// Trace memory broken checker
        	if (!(insn->mem[idx].status==0 || insn->mem[idx].status==1)) 
            	PEEKABOO_DIE("Abort! Broken memrefs_offsets. Remove memrefs_offsets in trace folder and try again.\n");
		}
	}

	// read the regfile...
	fseek(trace->regfile, (id-1) * regfile_size, SEEK_SET);
	fread_bytes = fread(insn->regfile, regfile_size, 1, trace->regfile);

	// done! return
	return insn;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r13
movq %rdi, %rbx
movl $0x138, %edi            # imm = 0x138
callq 0x3210
movq %rax, %r12
movq 0x38(%r13), %r14
movq 0x10(%r14), %r15
movq %r15, %rdi
callq 0x3210
movq %rax, 0x130(%r12)
movl (%r14), %eax
movl %eax, 0x128(%r12)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x3230
movq %rax, %r14
movq %rax, (%r12)
movq %rax, %rdi
movq %r13, %rsi
callq 0x30b0
testq %rax, %rax
je 0x422a
movq %r15, 0x8(%rsp)
movl 0x8(%rax), %ecx
movq %rcx, 0x8(%r12)
movups 0xc(%rax), %xmm0
movups %xmm0, 0x10(%r12)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x3050
movq %rax, 0x20(%r12)
cmpq $0x9, %rax
jae 0x423d
movq %r12, %r15
movq 0x30(%r13), %rdi
movq %rbx, (%rsp)
leaq -0x8(,%rbx,8), %rsi
xorl %r12d, %r12d
xorl %edx, %edx
callq 0x3240
movq %r13, %rbp
movq 0x30(%r13), %rcx
leaq 0x10(%rsp), %r13
pushq $0x8
popq %rsi
pushq $0x1
popq %rdx
movq %r13, %rdi
callq 0x30e0
callq 0x3090
andl $0x0, (%rax)
movq (%r13), %rsi
cmpq $-0x1, %rsi
movq %r15, %rbx
je 0x41e7
movq 0x20(%rbp), %rdi
xorl %edx, %edx
callq 0x3240
movq 0x38(%rbp), %rax
xorl %ecx, %ecx
cmpl $0x3, 0x58(%rax)
setae %cl
leaq 0x18(,%rcx,8), %r13
movq %rbx, %r14
addq $0x28, %r14
movl %r12d, %r12d
cmpq %r12, 0x20(%rbx)
jbe 0x41e7
movq %r12, %rbx
shlq $0x5, %rbx
leaq (%r14,%rbx), %rdi
movq 0x20(%rbp), %rcx
movq %r13, %rsi
pushq $0x1
popq %rdx
callq 0x30e0
incl %r12d
cmpl $0x2, 0x14(%r14,%rbx)
movq %r15, %rbx
jb 0x4192
movq 0x5e26(%rip), %rax      # 0x9ff0
movq (%rax), %rcx
leaq 0x204b(%rip), %rdi      # 0x621f
pushq $0x55
popq %rsi
pushq $0x1
popq %rdx
callq 0x3290
pushq $0x1
popq %rdi
callq 0x3280
movq (%rsp), %rsi
decq %rsi
movq 0x10(%rbp), %rdi
movq 0x8(%rsp), %r14
imulq %r14, %rsi
xorl %edx, %edx
callq 0x3240
movq 0x130(%rbx), %rdi
movq 0x10(%rbp), %rcx
pushq $0x1
popq %rdx
movq %r14, %rsi
callq 0x30e0
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x5dbf(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1f30(%rip), %rsi      # 0x616b
jmp 0x424e
movq 0x5dac(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x1f76(%rip), %rsi      # 0x61c4
movq %rbx, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x31c0
jmp 0x41df