// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x138, %edi            # imm = 0x138
callq 0x41f0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4280
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x41f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x130(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl (%rax), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x128(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x4210
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x40a0
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x58f5
movq 0x4721(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
movq -0x8(%rbp), %rdx
movq -0x18(%rbp), %rax
movq (%rax), %rcx
leaq 0x1786(%rip), %rsi      # 0x706a
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
movq -0x28(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
movq 0xc(%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x14(%rcx), %rcx
movq %rcx, 0x18(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x4050
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x18(%rbp), %rax
cmpq $0x8, 0x20(%rax)
jbe 0x596e
movq 0x46a8(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
movq -0x8(%rbp), %rdx
movq -0x18(%rbp), %rax
movq (%rax), %rcx
leaq 0x1766(%rip), %rsi      # 0x70c3
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x8(%rbp), %rsi
subq $0x1, %rsi
shlq $0x3, %rsi
xorl %edx, %edx
callq 0x4220
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rcx
leaq -0x38(%rbp), %rdi
movl $0x8, %esi
movl $0x1, %edx
callq 0x40c0
movq %rax, -0x40(%rbp)
callq 0x4080
movl $0x0, (%rax)
cmpq $-0x1, -0x38(%rbp)
je 0x5a9c
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
callq 0x4220
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl 0x58(%rax), %edx
movl $0x20, %eax
movl $0x18, %ecx
cmpl $0x3, %edx
cmovbq %rcx, %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0x5a9a
movq -0x18(%rbp), %rdi
addq $0x28, %rdi
movl -0x4c(%rbp), %eax
shlq $0x5, %rax
addq %rax, %rdi
movq -0x48(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rcx
movl $0x1, %edx
callq 0x40c0
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x0, 0x14(%rax)
je 0x5a8a
movq -0x18(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x1, 0x14(%rax)
je 0x5a8a
movq 0x4581(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
leaq 0x16a5(%rip), %rsi      # 0x711e
movb $0x0, %al
callq 0x4190
movl $0x1, %edi
callq 0x4260
jmp 0x5a8c
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x59fb
jmp 0x5a9c
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x8(%rbp), %rsi
subq $0x1, %rsi
imulq -0x20(%rbp), %rsi
xorl %edx, %edx
callq 0x4220
movq -0x18(%rbp), %rax
movq 0x130(%rax), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rcx
movl $0x1, %edx
callq 0x40c0
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)