// File: jstaursky[P]hutch/src/hutch.cpp
// Function: Hutch::inspectPreviousInstruction(unsigned long, unsigned long, Hutch_Instructions&, bool (*)(PcodeData))
vector<Instruction>
Hutch::inspectPreviousInstruction (uintb offset, uintb limit,
                                   Hutch_Instructions& insn,
                                   bool (*select) (PcodeData))
{
    vector<Instruction> res;

    resetMark (offset, insn);
    if (insn.getMark ()->address - 1 == 0)
        return {};

    for (auto r = 1; (r != limit) && ((offset - r) > 0) &&
                     disassemble_iter (offset - r, &insn);
         ++r)
        ;
    for (auto rinsn = insn.getMark () - 1; rinsn != insn.current (); --rinsn) {
        // For ROP:
        // Need to determine whether the instruction ends immediately prior to
        // the marked/c3(ret) instruction for instruction to be useful.
        if (select == nullptr) {
            if ((rinsn->address + rinsn->bytelength) ==
                insn.getMark ()->address)
                res.push_back (*rinsn);
            continue;
        }
        // Only add those instructions that meet the alignment requirement
        // described above AND satisfy whatever condition the fptr "select" imposes.
        if (bool isSelected = false;
            (rinsn->address + rinsn->bytelength) == insn.getMark ()->address) {
            for (auto p : rinsn->pcode) {
                isSelected = select (p);
                if (isSelected) {
                    res.push_back (*rinsn);
                    break;
                }
            }
        }
    }
    return res;
}

// Assembly:
subq $0x178, %rsp            # imm = 0x178
movq %rdi, 0x70(%rsp)
movq %rdi, %rax
movq %rax, 0x78(%rsp)
movq %rdi, 0x170(%rsp)
movq %rsi, 0x168(%rsp)
movq %rdx, 0x160(%rsp)
movq %rcx, 0x158(%rsp)
movq %r8, 0x150(%rsp)
movq %r9, 0x148(%rsp)
movq 0x168(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0x130(%rsp), %rdi
callq 0xd0cb0
movq 0x80(%rsp), %rdi
movq 0x160(%rsp), %rsi
movq 0x150(%rsp), %rdx
callq 0xe0d50
jmp 0x1715f0
movq 0x150(%rsp), %rdi
callq 0xdba00
movq %rax, 0x68(%rsp)
jmp 0x171604
movq 0x68(%rsp), %rax
movq %rax, 0x118(%rsp)
leaq 0x118(%rsp), %rdi
callq 0xd8060
movq (%rax), %rax
subq $0x1, %rax
cmpq $0x0, %rax
jne 0x17167c
movq 0x70(%rsp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0xd36e0
movq 0x70(%rsp), %rdi
callq 0xd0cb0
movl $0x1, 0x114(%rsp)
jmp 0x1719f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
leaq 0x130(%rsp), %rdi
callq 0xd5d10
jmp 0x171a0f
movl $0x1, 0x110(%rsp)
movslq 0x110(%rsp), %rcx
xorl %eax, %eax
cmpq 0x158(%rsp), %rcx
movb %al, 0x67(%rsp)
je 0x1716fa
movq 0x160(%rsp), %rcx
movslq 0x110(%rsp), %rax
subq %rax, %rcx
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, 0x67(%rsp)
jbe 0x1716fa
movq 0x80(%rsp), %rdi
movq 0x160(%rsp), %rsi
movslq 0x110(%rsp), %rax
subq %rax, %rsi
movq 0x150(%rsp), %rdx
callq 0xdddb0
movl %eax, 0x60(%rsp)
jmp 0x1716ec
movl 0x60(%rsp), %eax
cmpl $0x0, %eax
setne %al
movb %al, 0x67(%rsp)
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0x171704
jmp 0x17171c
jmp 0x171706
movl 0x110(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x110(%rsp)
jmp 0x171687
movq 0x150(%rsp), %rdi
callq 0xdba00
movq %rax, 0x58(%rsp)
jmp 0x171730
movq 0x58(%rsp), %rax
movq %rax, 0x100(%rsp)
leaq 0x100(%rsp), %rdi
movl $0x1, %esi
callq 0xdc130
movq %rax, 0x108(%rsp)
movq 0x150(%rsp), %rdi
callq 0xe08f0
movq %rax, 0x50(%rsp)
jmp 0x17176b
movq 0x50(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x108(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0xd65b0
testb $0x1, %al
jne 0x171796
jmp 0x1719d8
cmpq $0x0, 0x148(%rsp)
jne 0x17183e
leaq 0x108(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0xd8060
movq 0x30(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x38(%rsp)
callq 0xd8060
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq 0x8(%rcx), %rcx
addq %rcx, %rax
movq %rax, 0x40(%rsp)
movq 0x150(%rsp), %rdi
callq 0xdba00
movq %rax, 0x48(%rsp)
jmp 0x1717f1
movq 0x48(%rsp), %rax
movq %rax, 0xf0(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0xd8060
movq %rax, %rcx
movq 0x40(%rsp), %rax
cmpq (%rcx), %rax
jne 0x171839
leaq 0x108(%rsp), %rdi
callq 0xd8f80
movq %rax, %rsi
leaq 0x130(%rsp), %rdi
callq 0xe1040
jmp 0x171837
jmp 0x171839
jmp 0x1719c6
movb $0x0, 0xef(%rsp)
leaq 0x108(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0xd8060
movq 0x10(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x18(%rsp)
callq 0xd8060
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq 0x8(%rcx), %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
movq 0x150(%rsp), %rdi
callq 0xdba00
movq %rax, 0x28(%rsp)
jmp 0x171892
movq 0x28(%rsp), %rax
movq %rax, 0xe0(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0xd8060
movq %rax, %rcx
movq 0x20(%rsp), %rax
cmpq (%rcx), %rax
jne 0x1719c4
leaq 0x108(%rsp), %rdi
callq 0xd8060
addq $0x30, %rax
movq %rax, 0xd8(%rsp)
movq 0xd8(%rsp), %rdi
callq 0xdc290
movq %rax, 0xd0(%rsp)
movq 0xd8(%rsp), %rdi
callq 0xdcc40
movq %rax, 0xc8(%rsp)
leaq 0xd0(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0xd84a0
testb $0x1, %al
jne 0x17191e
jmp 0x1719c2
leaq 0xd0(%rsp), %rdi
callq 0xdbf10
movq %rax, %rsi
leaq 0xa8(%rsp), %rdi
callq 0xd2a10
jmp 0x17193d
movq 0x148(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0xd2a10
jmp 0x171961
movq 0x8(%rsp), %rax
leaq 0x88(%rsp), %rdi
callq *%rax
movb %al, 0x7(%rsp)
jmp 0x171976
movb 0x7(%rsp), %al
andb $0x1, %al
movb %al, 0xef(%rsp)
testb $0x1, 0xef(%rsp)
je 0x1719ae
leaq 0x108(%rsp), %rdi
callq 0xd8f80
movq %rax, %rsi
leaq 0x130(%rsp), %rdi
callq 0xe1040
jmp 0x1719ac
jmp 0x1719c2
jmp 0x1719b0
leaq 0xd0(%rsp), %rdi
callq 0xce8b0
jmp 0x171900
jmp 0x1719c4
jmp 0x1719c6
leaq 0x108(%rsp), %rdi
callq 0xdd3e0
jmp 0x171757
movq 0x70(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0xd3690
movl $0x1, 0x114(%rsp)
leaq 0x130(%rsp), %rdi
callq 0xd5d10
movq 0x78(%rsp), %rax
addq $0x178, %rsp            # imm = 0x178
retq
movq 0x128(%rsp), %rdi
callq 0xe0be0
nopl (%rax)