// File: /workspace/github_c_makefile_star2_O0/melynx[P]peekaboo/read_trace.c
// Function: print_peekaboo_insn
void print_peekaboo_insn(peekaboo_insn_t *insn, 
                         peekaboo_trace_t *peekaboo_trace_ptr, 
                         const size_t insn_idx,
                         const bool target,
                         const bool print_syscall_info)
{
    // Print instruction index
    printf("[%lu] ", insn_idx);

    if (!print_memory && !print_register)
        if (target) 
        {
            for (uint8_t idx = (uint8_t)log10f(insn_idx); idx < digits - 1; idx++) printf("-");
            printf(">");
        }
        else
            for (uint8_t idx = (uint8_t)log10f(insn_idx); idx < digits; idx++) printf(" ");

    if (!print_syscall_info)
    {
        // Print instruction ea
        printf("0x%"PRIx64"", insn->addr);
            
        // Print Rawbytes
        printf(":\t ");

        for (uint8_t rawbyte_idx = 0; rawbyte_idx < insn->size; rawbyte_idx++)
        {
            if (insn->rawbytes[rawbyte_idx] < 16) printf("0");
            printf("%"PRIx8" ", insn->rawbytes[rawbyte_idx]);
        }
        
        // Pretty print 
        for (uint8_t idx = insn->size; idx < 8; idx++) printf("   ");
        printf("\t");
    }


    // Is this syscall?
    if (insn->size == 2 && insn->rawbytes[0]=='\x0f' && insn->rawbytes[1]=='\x05')
    {
        // Yes, syscall. Print it!
        size_t trace_length = get_num_insn(peekaboo_trace_ptr);
        size_t next_insn_idx = insn_idx + 1;
        const regfile_amd64_t *regfile_ptr = (regfile_amd64_t *) insn->regfile;
        uint64_t rvalue;
        if (next_insn_idx > trace_length)
            rvalue = 0;
        else
        {
            peekaboo_insn_t *next_insn = get_peekaboo_insn(next_insn_idx, peekaboo_trace_ptr);
            regfile_ptr = (regfile_amd64_t *) next_insn->regfile;
            rvalue = regfile_ptr->gpr.reg_rax;
            free_peekaboo_insn(next_insn);
        }
        if (0!=amd64_syscall_pp(insn->regfile, rvalue, print_syscall_info))
        {
            // Syscall analysis failed.
            printf("Syscall analysis failed");
        }
        printf("\n");
        return;
    }

    // Print disassemble for instructions using libopcodes
    #ifdef ASM
    {
        // Disasmble the instruction
        int rvalue = disassemble_raw((enum ARCH)peekaboo_trace_ptr->internal->arch, false, insn->rawbytes, insn->size);
        if(rvalue != 0) PEEKABOO_DIE("Libopcodes disasm error!\n");
    }
    #else 
    #ifdef ASM_CAPSTONE
    {
        cs_insn *capstone_insn;
        size_t count = cs_disasm(capstone_handler, insn->rawbytes, insn->size, insn->addr, 0, &capstone_insn);
        if (count == 0)
        {
            printf("Capstone Error");
        }
        else
        {
            printf("%s\t%s", capstone_insn[0].mnemonic, capstone_insn[0].op_str);
            cs_free(capstone_insn, count);
        }
    }
    #endif //ASM_CAPSTONE
    #endif // ASM
    printf("\n");

    // Print memory ops
    if (print_memory && (insn->num_mem > 0))
    {
        for (uint32_t mem_idx = 0; mem_idx < insn->num_mem; mem_idx++)
        {
            printf("\t");
            printf(insn->mem[mem_idx].status ? "Memory Write: " : "Memory Read: ");
            if (insn->mem[mem_idx].status) 
                write_bytes+=insn->mem[mem_idx].size; 
            else
                read_bytes+=insn->mem[mem_idx].size; 
            printf("%d bytes @ 0x%lx\n", insn->mem[mem_idx].size, insn->mem[mem_idx].addr);

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

    // Print GPR
    if (print_register) regfile_pp(insn);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
andb $0x1, %cl
movb %cl, -0x19(%rbp)
andb $0x1, %al
movb %al, -0x1a(%rbp)
movq -0x18(%rbp), %rsi
leaq 0x379a(%rip), %rdi      # 0x8167
movb $0x0, %al
callq 0x40b0
testb $0x1, 0x874d(%rip)      # 0xd128
jne 0x4af1
testb $0x1, 0x8741(%rip)      # 0xd129
jne 0x4af1
testb $0x1, -0x19(%rbp)
je 0x4a7c
movq -0x18(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x54(%rbp)
testq %rax, %rax
movss %xmm0, -0x50(%rbp)
js 0x4a31
movss -0x54(%rbp), %xmm0
movss %xmm0, -0x50(%rbp)
movss -0x50(%rbp), %xmm0
callq 0x4150
cvttss2si %xmm0, %eax
movb %al, -0x1b(%rbp)
movzbl -0x1b(%rbp), %eax
movzbl 0x86e3(%rip), %ecx      # 0xd130
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x4a6c
leaq 0x3713(%rip), %rdi      # 0x816e
movb $0x0, %al
callq 0x40b0
movb -0x1b(%rbp), %al
addb $0x1, %al
movb %al, -0x1b(%rbp)
jmp 0x4a42
leaq 0x36fd(%rip), %rdi      # 0x8170
movb $0x0, %al
callq 0x40b0
jmp 0x4aef
movq -0x18(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x5c(%rbp)
testq %rax, %rax
movss %xmm0, -0x58(%rbp)
js 0x4ab5
movss -0x5c(%rbp), %xmm0
movss %xmm0, -0x58(%rbp)
movss -0x58(%rbp), %xmm0
callq 0x4150
cvttss2si %xmm0, %eax
movb %al, -0x1c(%rbp)
movzbl -0x1c(%rbp), %eax
movzbl 0x865f(%rip), %ecx      # 0xd130
cmpl %ecx, %eax
jge 0x4aed
leaq 0x3698(%rip), %rdi      # 0x8174
movb $0x0, %al
callq 0x40b0
movb -0x1c(%rbp), %al
addb $0x1, %al
movb %al, -0x1c(%rbp)
jmp 0x4ac6
jmp 0x4aef
jmp 0x4af1
testb $0x1, -0x1a(%rbp)
jne 0x4baf
movq -0x8(%rbp), %rax
movq (%rax), %rsi
leaq 0x3d72(%rip), %rdi      # 0x887b
movb $0x0, %al
callq 0x40b0
leaq 0x365b(%rip), %rdi      # 0x8172
movb $0x0, %al
callq 0x40b0
movb $0x0, -0x1d(%rbp)
movzbl -0x1d(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x4b75
movq -0x8(%rbp), %rax
movzbl -0x1d(%rbp), %ecx
movzbl 0x10(%rax,%rcx), %eax
cmpl $0x10, %eax
jge 0x4b50
leaq 0x4d39(%rip), %rdi      # 0x9882
movb $0x0, %al
callq 0x40b0
movq -0x8(%rbp), %rax
movzbl -0x1d(%rbp), %ecx
movzbl 0x10(%rax,%rcx), %esi
leaq 0x3612(%rip), %rdi      # 0x8176
movb $0x0, %al
callq 0x40b0
movb -0x1d(%rbp), %al
addb $0x1, %al
movb %al, -0x1d(%rbp)
jmp 0x4b22
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movb %al, -0x1e(%rbp)
movzbl -0x1e(%rbp), %eax
cmpl $0x8, %eax
jge 0x4ba1
leaq 0x35ea(%rip), %rdi      # 0x817a
movb $0x0, %al
callq 0x40b0
movb -0x1e(%rbp), %al
addb $0x1, %al
movb %al, -0x1e(%rbp)
jmp 0x4b80
leaq 0x35d6(%rip), %rdi      # 0x817e
movb $0x0, %al
callq 0x40b0
movq -0x8(%rbp), %rax
cmpq $0x2, 0x8(%rax)
jne 0x4c96
movq -0x8(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0xf, %eax
jne 0x4c96
movq -0x8(%rbp), %rax
movzbl 0x11(%rax), %eax
cmpl $0x5, %eax
jne 0x4c96
movq -0x10(%rbp), %rdi
callq 0x6560
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x130(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x28(%rbp), %rax
jbe 0x4c1c
movq $0x0, -0x40(%rbp)
jmp 0x4c51
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x7200
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq 0x130(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rdi
callq 0x7550
movq -0x8(%rbp), %rax
movq 0x130(%rax), %rdi
movq -0x40(%rbp), %rsi
movb -0x1a(%rbp), %al
andb $0x1, %al
movzbl %al, %edx
callq 0x5ec0
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0x4c83
leaq 0x3504(%rip), %rdi      # 0x8180
movb $0x0, %al
callq 0x40b0
leaq 0x48cc(%rip), %rdi      # 0x9556
movb $0x0, %al
callq 0x40b0
jmp 0x4e25
leaq 0x48b9(%rip), %rdi      # 0x9556
movb $0x0, %al
callq 0x40b0
testb $0x1, 0x847d(%rip)      # 0xd128
je 0x4e13
movq -0x8(%rbp), %rax
cmpq $0x0, 0x20(%rax)
jbe 0x4e13
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0x4e11
leaq 0x349f(%rip), %rdi      # 0x817e
movb $0x0, %al
callq 0x40b0
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x14(%rax), %ecx
leaq 0x34a5(%rip), %rdi      # 0x81a7
leaq 0x348f(%rip), %rax      # 0x8198
cmpl $0x0, %ecx
cmovneq %rax, %rdi
movb $0x0, %al
callq 0x40b0
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x0, 0x14(%rax)
je 0x4d54
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x10(%rax), %eax
addq 0x83ed(%rip), %rax      # 0xd138
movq %rax, 0x83e6(%rip)      # 0xd138
jmp 0x4d77
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x10(%rax), %eax
addq 0x83d0(%rip), %rax      # 0xd140
movq %rax, 0x83c9(%rip)      # 0xd140
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x10(%rax), %esi
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movq (%rax), %rdx
leaq 0x340d(%rip), %rdi      # 0x81b5
movb $0x0, %al
callq 0x40b0
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x0, 0x14(%rax)
je 0x4e01
movq -0x8(%rbp), %rax
addq $0x28, %rax
movl -0x4c(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x1, 0x14(%rax)
je 0x4e01
movq 0x8212(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x33d7(%rip), %rsi      # 0x81c7
movb $0x0, %al
callq 0x4130
movl $0x1, %edi
callq 0x4200
jmp 0x4e03
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x4cc7
jmp 0x4e13
testb $0x1, 0x830f(%rip)      # 0xd129
je 0x4e25
movq -0x8(%rbp), %rdi
callq 0x74b0
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)