// File: /workspace/github_c_makefile_star2_O2/mrkite[P]regs/src/disasm.cc
// Function: Disassembler::disassemble(std::vector<Segment, std::allocator<Segment>>, std::vector<Entry, std::allocator<Entry>>)
bool Disassembler::disassemble(std::vector<Segment> segments,
                          std::vector<Entry> entries) {
  Scanner scanner(segments, symbols, fingerprints);
  // trace all entry points
  for (auto &entry : entries) {
    if (!scanner.trace(entry, std::bind(&Disassembler::decodeInst, this,
                                        ph::_1, ph::_2))) {
      std::cerr << "Failed to trace execution flow" << std::endl;
      return false;
    }
  }
  // build the basic blocks
  if (!scanner.basicBlocks()) {
    std::cerr << "Failed to calculate basic blocks" << std::endl;
    return false;
  }
  // disassemble each segment
  for (auto &segment : segments) {
    std::string fname = "seg" + std::to_string(segment.segnum);
    std::ofstream f(fname, std::ios::out | std::ios::binary | std::ios::trunc);
    if (!f.is_open()) {
      std::cerr << "Failed to open '" << fname << "' for writing" << std::endl;
      return false;
    }
    f << "Segment " << hex(segment.segnum, 2) << " "
      << segment.name << std::endl;
    if (!scanner.disassemble(f, segment.mapped,
                             segment.mapped + segment.length,
                             std::bind(&Disassembler::printInst, this,
                                       ph::_1))) {
      std::cerr << "Disassembly failed" << std::endl;
      return false;
    }
    f.close();
  }
  return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3f8, %rsp            # imm = 0x3F8
movq %rdx, %r15
movq %rdi, %rbx
leaq 0x30(%rsp), %rdi
movq %rsi, 0x8(%rsp)
callq 0x60be
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x9838
movq %rbx, %r13
leaq 0x30(%rbx), %rsi
leaq 0x20(%rsp), %r14
movq %r14, %rdi
callq 0x6260
leaq 0xf8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x88(%rsp), %rdx
movq %r14, %rcx
callq 0x10ae4
leaq 0x28(%rsp), %rdi
callq 0x61e4
leaq 0x88(%rsp), %rdi
callq 0x6274
leaq 0x30(%rsp), %rdi
callq 0x6118
movq (%r15), %r12
movq 0x8(%r15), %rbx
leaq 0xd8(%rsp), %r15
leaq 0xf8(%rsp), %rbp
cmpq %rbx, %r12
je 0xaf46
leaq 0x351(%rip), %rax       # 0xb22c
movq %rax, 0x1f8(%rsp)
andq $0x0, 0x200(%rsp)
movq %r13, 0x208(%rsp)
movq %r15, %rdi
leaq 0x1f8(%rsp), %rsi
callq 0xc5c2
movq %rbp, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x10baa
movl %eax, %r14d
movq %r15, %rdi
callq 0xc6ce
addq $0xc, %r12
testb %r14b, %r14b
jne 0xaecf
movq 0x150bb(%rip), %rdi     # 0x1ffe8
leaq 0x95ec(%rip), %rsi      # 0x14520
callq 0x5200
movq %rax, %rdi
callq 0x5150
jmp 0xb156
leaq 0xf8(%rsp), %rdi
callq 0x11212
testb %al, %al
movq %r13, 0x18(%rsp)
je 0xb0dd
movq 0x8(%rsp), %rax
movq (%rax), %r15
movq 0x8(%rax), %rax
movq %rax, 0x8(%rsp)
leaq 0x1f8(%rsp), %rbp
leaq 0xb8(%rsp), %r13
leaq 0x9604(%rip), %rbx      # 0x1458c
movq 0x15059(%rip), %rax     # 0x1ffe8
movq %rax, 0x10(%rsp)
cmpq 0x8(%rsp), %r15
je 0xb0fa
movswl 0x1c(%r15), %esi
movq %rbp, %rdi
callq 0xc62d
leaq 0x68(%rsp), %r14
movq %r14, %rdi
leaq 0x95a5(%rip), %rsi      # 0x14560
movq %rbp, %rdx
callq 0xc609
movq %rbp, %rdi
callq 0x5140
movq %rbp, %rdi
movq %r14, %rsi
pushq $0x34
popq %rdx
callq 0x5430
leaq 0x268(%rsp), %rdi
callq 0x50a0
testb %al, %al
je 0xb0fe
movq %rbp, %rdi
leaq 0x958b(%rip), %rsi      # 0x14583
callq 0x5200
movq %rax, %r12
movq %rbx, %r14
movq %r13, %rbx
movswl 0x1c(%r15), %edx
leaq 0x48(%rsp), %r13
movq %r13, %rdi
movq 0x18(%rsp), %rsi
pushq $0x2
popq %rcx
callq 0xb834
movq %r12, %rdi
movq %r13, %rsi
callq 0x51f0
movq %rax, %rdi
leaq 0x9e68(%rip), %rsi      # 0x14e9d
callq 0x5200
addq $0x28, %r15
movq %rax, %rdi
movq %r15, %rsi
callq 0x51f0
movq %rax, %rdi
callq 0x5150
movq %r13, %rdi
callq 0x5140
movl -0x20(%r15), %r12d
movq %r13, %rsi
movl 0x38(%r15), %r13d
leaq 0x9a5(%rip), %rax       # 0xba10
movq %rax, 0x48(%rsp)
andq $0x0, 0x50(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x58(%rsp)
movq %rbx, %rdi
callq 0xc686
addl %r13d, %r12d
leaq 0xf8(%rsp), %rdi
movq %rbp, %rsi
movl %r13d, %edx
movl %r12d, %ecx
movq %rbx, %r8
callq 0x11702
movl %eax, %r12d
movq %rbx, %r13
movq %rbx, %rdi
callq 0xc6ce
testb %r12b, %r12b
movq %r14, %rbx
je 0xb12a
movq %rbp, %rdi
callq 0x52f0
movq %rbp, %rdi
callq 0x5320
leaq 0x68(%rsp), %rdi
callq 0x5140
addq $0x40, %r15
jmp 0xaf94
movq 0x14f04(%rip), %rdi     # 0x1ffe8
leaq 0x9454(%rip), %rsi      # 0x1453f
callq 0x5200
movq %rax, %rdi
callq 0x5150
jmp 0xb156
movb $0x1, %bl
jmp 0xb158
movq 0x14ee3(%rip), %rdi     # 0x1ffe8
leaq 0x9458(%rip), %rsi      # 0x14564
callq 0x5200
leaq 0x68(%rsp), %rsi
movq %rax, %rdi
callq 0x51f0
movq %rax, 0x10(%rsp)
leaq 0x944b(%rip), %rbx      # 0x14575
movq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x5200
movq %rax, %rdi
callq 0x5150
leaq 0x1f8(%rsp), %rdi
callq 0x5320
leaq 0x68(%rsp), %rdi
callq 0x5140
xorl %ebx, %ebx
leaq 0xf8(%rsp), %rdi
callq 0xc6ea
movl %ebx, %eax
addq $0x3f8, %rsp            # imm = 0x3F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xb1d7
jmp 0xb214
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x61e4
leaq 0x88(%rsp), %rdi
callq 0x6274
jmp 0xb19f
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x6118
jmp 0xb224
jmp 0xb214
jmp 0xb1d7
jmp 0xb1d7
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0xc6ce
jmp 0xb1e9
jmp 0xb214
movq %rax, %rbx
jmp 0xb1f6
movq %rax, %rbx
leaq 0x1f8(%rsp), %rdi
jmp 0xb1fb
movq %rax, %rbx
jmp 0xb1e9
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x5140
leaq 0x1f8(%rsp), %rdi
callq 0x5320
leaq 0x68(%rsp), %rdi
callq 0x5140
jmp 0xb217
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0xc6ce
jmp 0xb217
movq %rax, %rbx
leaq 0xf8(%rsp), %rdi
callq 0xc6ea
movq %rbx, %rdi
callq 0x53c0