// File: /workspace/github_c_makefile_star2_O3/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, %r14
movq %rdi, %r12
movl $0x138, %edi            # imm = 0x138
callq 0x3200
movq %rax, %rbx
movq 0x38(%r14), %r15
movq 0x10(%r15), %rbp
movq %rbp, %rdi
callq 0x3200
movq %rax, 0x130(%rbx)
movl (%r15), %eax
movl %eax, 0x128(%rbx)
movq %r12, %rdi
movq %r14, %rsi
callq 0x3220
movq %rax, %r13
movq %rax, (%rbx)
movq 0x38(%r14), %rcx
movq 0x20(%rcx), %rax
cmpq $0x20, %rax
jb 0x431d
movq 0x18(%rcx), %rcx
shrq $0x5, %rax
addq $0xc, %rcx
cmpq %r13, -0xc(%rcx)
je 0x4328
addq $0x20, %rcx
decq %rax
jne 0x430e
movq %r12, %rdi
movq %r13, %rsi
callq 0x3561
movq %rbp, 0x8(%rsp)
movl -0x4(%rcx), %eax
movq %rax, 0x8(%rbx)
movups (%rcx), %xmm0
movups %xmm0, 0x10(%rbx)
movq %r12, %rdi
movq %r14, %rsi
callq 0x3050
movq %rax, 0x20(%rbx)
cmpq $0x9, %rax
jae 0x444c
movq %rax, %rbp
movq 0x30(%r14), %rdi
movq %r12, (%rsp)
leaq -0x8(,%r12,8), %rsi
xorl %edx, %edx
callq 0x3230
movq 0x30(%r14), %rcx
leaq 0x10(%rsp), %r13
movl $0x8, %esi
movl $0x1, %edx
movq %r13, %rdi
callq 0x30d0
callq 0x3090
movl $0x0, (%rax)
movq (%r13), %rsi
cmpq $-0x1, %rsi
je 0x4402
movq 0x20(%r14), %rdi
xorl %edx, %edx
callq 0x3230
movq 0x38(%r14), %rcx
xorl %eax, %eax
cmpl $0x3, 0x58(%rcx)
setae %cl
testq %rbp, %rbp
je 0x4402
movb %cl, %al
leaq 0x18(,%rax,8), %r13
movq %rbx, %rbp
addq $0x28, %rbp
movl $0x1, %r12d
xorl %r15d, %r15d
shlq $0x5, %r15
leaq (%r15,%rbp), %rdi
movq 0x20(%r14), %rcx
movl $0x1, %edx
movq %r13, %rsi
callq 0x30d0
cmpl $0x2, 0x14(%rbp,%r15)
jae 0x4447
movl %r12d, %r15d
incl %r12d
cmpq %r15, 0x20(%rbx)
ja 0x43d5
movq (%rsp), %rsi
decq %rsi
movq 0x10(%r14), %rdi
movq 0x8(%rsp), %r15
imulq %r15, %rsi
xorl %edx, %edx
callq 0x3230
movq 0x130(%rbx), %rdi
movq 0x10(%r14), %rcx
movl $0x1, %edx
movq %r15, %rsi
callq 0x30d0
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x3515
movq %r12, %rdi
movq %r13, %rsi
callq 0x353a