// File: coduin[P]epiphany-bin-info/epiphany-bin-info.cpp
// Function: main
int main(int argc, char* argv[]) {
    if (cmdOptionExists(argv, argv + argc, "-h")) {
        showHelp(argv[0]);
        return 0;
    }

    // Retrieve the filename
    if ((argc <= 1) || (argv[argc - 1] == NULL) || (argv[argc - 1][0] == '-')) {
        showHelp(argv[0]);
        return 1;
    }

    if (cmdOptionExists(argv, argv + argc, "-p"))
        showProgramHeaders = true;

    if (cmdOptionExists(argv, argv + argc, "-sec"))
        showSections = true;

    if (cmdOptionExists(argv, argv + argc, "-s"))
        showSymbols = true;

    if (cmdOptionExists(argv, argv + argc, "-a")) {
        showProgramHeaders = true;
        showSections = true;
        showSymbols = true;
    }

    if (cmdOptionExists(argv, argv + argc, "--nodemangle")) {
        demangleNames = false;
    }

    if (isatty(fileno(stdout)))
        colorOutput = true;

    std::ifstream file(argv[argc - 1], ios::binary);

    if (!file.is_open()) {
        cerr << "Could not open file " << argv[1] << endl;
        return 1;
    }

    streampos fsize = 0;
    file.seekg(0, ios::beg);
    fsize = file.tellg();
    file.seekg(0, ios::end);
    fsize = file.tellg() - fsize;
    file.seekg(0, ios::beg);

    char* buffer = new char[fsize];
    file.read(buffer, fsize);
    file.close();

    int ret = parseFile(buffer, fsize);
    delete[] buffer;

    if (ret) {
        cerr << "Error while parsing file '" << argv[argc - 1] << "'" << endl;
        cerr << "File is not a valid Epiphany executable." << endl;
    }

    return ret;
}

// Assembly:
subq $0x4d8, %rsp            # imm = 0x4D8
movl $0x0, 0x4d4(%rsp)
movl %edi, 0x4d0(%rsp)
movq %rsi, 0x4c8(%rsp)
movq 0x4c8(%rsp), %rax
movq %rax, 0x148(%rsp)
movslq 0x4d0(%rsp), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0x150(%rsp)
leaq 0x4a7(%rsp), %rdi
movq %rdi, 0x158(%rsp)
callq 0x23b0
movq 0x158(%rsp), %rdx
leaq 0x47aa(%rip), %rsi      # 0x8453
leaq 0x4a8(%rsp), %rdi
callq 0x49d0
jmp 0x3cb8
movq 0x150(%rsp), %rsi
movq 0x148(%rsp), %rdi
leaq 0x4a8(%rsp), %rdx
callq 0x3af0
movb %al, 0x147(%rsp)
jmp 0x3cde
leaq 0x4a8(%rsp), %rdi
callq 0x2140
leaq 0x4a7(%rsp), %rdi
callq 0x2230
movb 0x147(%rsp), %al
testb $0x1, %al
jne 0x3d05
jmp 0x3d6e
movq 0x4c8(%rsp), %rax
movq (%rax), %rdi
callq 0x3b30
movl $0x0, 0x4d4(%rsp)
jmp 0x4678
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3d5c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x4a8(%rsp), %rdi
callq 0x2140
leaq 0x4a7(%rsp), %rdi
callq 0x2230
jmp 0x4687
cmpl $0x1, 0x4d0(%rsp)
jle 0x3db5
movq 0x4c8(%rsp), %rax
movl 0x4d0(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
cmpq $0x0, (%rax,%rcx,8)
je 0x3db5
movq 0x4c8(%rsp), %rax
movl 0x4d0(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x3dd5
movq 0x4c8(%rsp), %rax
movq (%rax), %rdi
callq 0x3b30
movl $0x1, 0x4d4(%rsp)
jmp 0x4678
movq 0x4c8(%rsp), %rax
movq %rax, 0x128(%rsp)
movslq 0x4d0(%rsp), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0x130(%rsp)
leaq 0x46f(%rsp), %rdi
movq %rdi, 0x138(%rsp)
callq 0x23b0
movq 0x138(%rsp), %rdx
leaq 0x4639(%rip), %rsi      # 0x8456
leaq 0x470(%rsp), %rdi
callq 0x49d0
jmp 0x3e2c
movq 0x130(%rsp), %rsi
movq 0x128(%rsp), %rdi
leaq 0x470(%rsp), %rdx
callq 0x3af0
movb %al, 0x127(%rsp)
jmp 0x3e52
leaq 0x470(%rsp), %rdi
callq 0x2140
leaq 0x46f(%rsp), %rdi
callq 0x2230
movb 0x127(%rsp), %al
testb $0x1, %al
jne 0x3e79
jmp 0x3ecb
movb $0x1, 0x73a2(%rip)      # 0xb222
jmp 0x3ecb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3eb9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x470(%rsp), %rdi
callq 0x2140
leaq 0x46f(%rsp), %rdi
callq 0x2230
jmp 0x4687
movq 0x4c8(%rsp), %rax
movq %rax, 0x108(%rsp)
movslq 0x4d0(%rsp), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0x110(%rsp)
leaq 0x447(%rsp), %rdi
movq %rdi, 0x118(%rsp)
callq 0x23b0
movq 0x118(%rsp), %rdx
leaq 0x4546(%rip), %rsi      # 0x8459
leaq 0x448(%rsp), %rdi
callq 0x49d0
jmp 0x3f22
movq 0x110(%rsp), %rsi
movq 0x108(%rsp), %rdi
leaq 0x448(%rsp), %rdx
callq 0x3af0
movb %al, 0x107(%rsp)
jmp 0x3f48
leaq 0x448(%rsp), %rdi
callq 0x2140
leaq 0x447(%rsp), %rdi
callq 0x2230
movb 0x107(%rsp), %al
testb $0x1, %al
jne 0x3f6f
jmp 0x3fc1
movb $0x1, 0x72ad(%rip)      # 0xb223
jmp 0x3fc1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x3faf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x448(%rsp), %rdi
callq 0x2140
leaq 0x447(%rsp), %rdi
callq 0x2230
jmp 0x4687
movq 0x4c8(%rsp), %rax
movq %rax, 0xe8(%rsp)
movslq 0x4d0(%rsp), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0xf0(%rsp)
leaq 0x41f(%rsp), %rdi
movq %rdi, 0xf8(%rsp)
callq 0x23b0
movq 0xf8(%rsp), %rdx
leaq 0x4455(%rip), %rsi      # 0x845e
leaq 0x420(%rsp), %rdi
callq 0x49d0
jmp 0x4018
movq 0xf0(%rsp), %rsi
movq 0xe8(%rsp), %rdi
leaq 0x420(%rsp), %rdx
callq 0x3af0
movb %al, 0xe7(%rsp)
jmp 0x403e
leaq 0x420(%rsp), %rdi
callq 0x2140
leaq 0x41f(%rsp), %rdi
callq 0x2230
movb 0xe7(%rsp), %al
testb $0x1, %al
jne 0x4065
jmp 0x40b7
movb $0x1, 0x71b8(%rip)      # 0xb224
jmp 0x40b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x40a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x420(%rsp), %rdi
callq 0x2140
leaq 0x41f(%rsp), %rdi
callq 0x2230
jmp 0x4687
movq 0x4c8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movslq 0x4d0(%rsp), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0xd0(%rsp)
leaq 0x3f7(%rsp), %rdi
movq %rdi, 0xd8(%rsp)
callq 0x23b0
movq 0xd8(%rsp), %rdx
leaq 0x4362(%rip), %rsi      # 0x8461
leaq 0x3f8(%rsp), %rdi
callq 0x49d0
jmp 0x410e
movq 0xd0(%rsp), %rsi
movq 0xc8(%rsp), %rdi
leaq 0x3f8(%rsp), %rdx
callq 0x3af0
movb %al, 0xc7(%rsp)
jmp 0x4134
leaq 0x3f8(%rsp), %rdi
callq 0x2140
leaq 0x3f7(%rsp), %rdi
callq 0x2230
movb 0xc7(%rsp), %al
testb $0x1, %al
jne 0x415b
jmp 0x41bb
movb $0x1, 0x70c0(%rip)      # 0xb222
movb $0x1, 0x70ba(%rip)      # 0xb223
movb $0x1, 0x70b4(%rip)      # 0xb224
jmp 0x41bb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x41a9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x3f8(%rsp), %rdi
callq 0x2140
leaq 0x3f7(%rsp), %rdi
callq 0x2230
jmp 0x4687
movq 0x4c8(%rsp), %rax
movq %rax, 0xa8(%rsp)
movslq 0x4d0(%rsp), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, 0xb0(%rsp)
leaq 0x3cf(%rsp), %rdi
movq %rdi, 0xb8(%rsp)
callq 0x23b0
movq 0xb8(%rsp), %rdx
leaq 0x4261(%rip), %rsi      # 0x8464
leaq 0x3d0(%rsp), %rdi
callq 0x49d0
jmp 0x4212
movq 0xb0(%rsp), %rsi
movq 0xa8(%rsp), %rdi
leaq 0x3d0(%rsp), %rdx
callq 0x3af0
movb %al, 0xa7(%rsp)
jmp 0x4238
leaq 0x3d0(%rsp), %rdi
callq 0x2140
leaq 0x3cf(%rsp), %rdi
callq 0x2230
movb 0xa7(%rsp), %al
testb $0x1, %al
jne 0x425f
jmp 0x42b1
movb $0x0, 0x6fa2(%rip)      # 0xb208
jmp 0x42b1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x429f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x3d0(%rsp), %rdi
callq 0x2140
leaq 0x3cf(%rsp), %rdi
callq 0x2230
jmp 0x4687
movq 0x6cf8(%rip), %rax      # 0xafb0
movq (%rax), %rdi
callq 0x2220
movl %eax, %edi
callq 0x2390
cmpl $0x0, %eax
je 0x42d3
movb $0x1, 0x6f4e(%rip)      # 0xb221
movq 0x4c8(%rsp), %rax
movl 0x4d0(%rsp), %ecx
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x1c0(%rsp), %rdi
movq %rdi, 0x98(%rsp)
movl $0x4, %edx
callq 0x23d0
movq 0x98(%rsp), %rdi
callq 0x2350
movb %al, 0xa6(%rsp)
jmp 0x431b
movb 0xa6(%rsp), %al
testb $0x1, %al
jne 0x43c3
jmp 0x432c
movq 0x6cbd(%rip), %rdi      # 0xaff0
leaq 0x4137(%rip), %rsi      # 0x8471
callq 0x21d0
movq %rax, 0x90(%rsp)
jmp 0x4349
movq 0x90(%rsp), %rdi
movq 0x4c8(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x21d0
movq %rax, 0x88(%rsp)
jmp 0x436c
movq 0x88(%rsp), %rdi
movq 0x6c45(%rip), %rsi      # 0xafc0
callq 0x2200
jmp 0x4382
movl $0x1, 0x4d4(%rsp)
movl $0x1, 0x1bc(%rsp)
jmp 0x466b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0x1c0(%rsp), %rdi
callq 0x2080
jmp 0x4687
xorl %eax, %eax
movl %eax, %esi
leaq 0x1a0(%rsp), %rdi
callq 0x4a90
jmp 0x43d6
xorl %edx, %edx
movl %edx, %esi
leaq 0x1c0(%rsp), %rdi
callq 0x22f0
jmp 0x43e9
leaq 0x1c0(%rsp), %rdi
callq 0x2380
movq %rdx, 0x78(%rsp)
movq %rax, 0x80(%rsp)
jmp 0x4405
movq 0x78(%rsp), %rax
movq 0x80(%rsp), %rcx
movq %rcx, 0x190(%rsp)
movq %rax, 0x198(%rsp)
movups 0x190(%rsp), %xmm0
movaps %xmm0, 0x1a0(%rsp)
xorl %eax, %eax
movl %eax, %esi
leaq 0x1c0(%rsp), %rdi
movl $0x2, %edx
callq 0x22f0
jmp 0x444a
leaq 0x1c0(%rsp), %rdi
callq 0x2380
movq %rdx, 0x68(%rsp)
movq %rax, 0x70(%rsp)
jmp 0x4463
movq 0x68(%rsp), %rax
movq 0x70(%rsp), %rcx
movq %rcx, 0x170(%rsp)
movq %rax, 0x178(%rsp)
leaq 0x170(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x4ac0
movq %rax, 0x60(%rsp)
jmp 0x4499
movq 0x60(%rsp), %rsi
leaq 0x180(%rsp), %rdi
callq 0x4a90
jmp 0x44ad
movups 0x180(%rsp), %xmm0
movaps %xmm0, 0x1a0(%rsp)
xorl %edx, %edx
movl %edx, %esi
leaq 0x1c0(%rsp), %rdi
callq 0x22f0
jmp 0x44d0
leaq 0x1a0(%rsp), %rdi
callq 0x4ae0
movq %rax, 0x58(%rsp)
jmp 0x44e4
movq 0x58(%rsp), %rdi
callq 0x2030
movq %rax, 0x50(%rsp)
jmp 0x44f5
movq 0x50(%rsp), %rax
movq %rax, 0x168(%rsp)
movq 0x168(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq 0x1a0(%rsp), %rdi
callq 0x4ae0
movq %rax, 0x48(%rsp)
jmp 0x4523
movq 0x48(%rsp), %rdx
movq 0x40(%rsp), %rsi
leaq 0x1c0(%rsp), %rdi
callq 0x22b0
jmp 0x453c
leaq 0x1c0(%rsp), %rdi
callq 0x2060
jmp 0x454b
movq 0x168(%rsp), %rax
movq %rax, 0x30(%rsp)
leaq 0x1a0(%rsp), %rdi
callq 0x4ae0
movq %rax, 0x38(%rsp)
jmp 0x456c
movq 0x38(%rsp), %rsi
movq 0x30(%rsp), %rdi
callq 0x3790
movl %eax, 0x2c(%rsp)
jmp 0x4581
movl 0x2c(%rsp), %eax
movl %eax, 0x164(%rsp)
movq 0x168(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x45a9
movq 0x20(%rsp), %rdi
callq 0x22c0
cmpl $0x0, 0x164(%rsp)
je 0x4652
movq 0x6a32(%rip), %rdi      # 0xaff0
leaq 0x3ec1(%rip), %rsi      # 0x8486
callq 0x21d0
movq %rax, 0x18(%rsp)
jmp 0x45d1
movq 0x18(%rsp), %rdi
movq 0x4c8(%rsp), %rax
movl 0x4d0(%rsp), %ecx
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
callq 0x21d0
movq %rax, 0x10(%rsp)
jmp 0x45fa
movq 0x10(%rsp), %rdi
leaq 0x3e99(%rip), %rsi      # 0x849f
callq 0x21d0
movq %rax, 0x8(%rsp)
jmp 0x4612
movq 0x8(%rsp), %rdi
movq 0x69a2(%rip), %rsi      # 0xafc0
callq 0x2200
jmp 0x4625
movq 0x69c4(%rip), %rdi      # 0xaff0
leaq 0x3e6e(%rip), %rsi      # 0x84a1
callq 0x21d0
movq %rax, (%rsp)
jmp 0x463e
movq (%rsp), %rdi
movq 0x6977(%rip), %rsi      # 0xafc0
callq 0x2200
jmp 0x4650
jmp 0x4652
movl 0x164(%rsp), %eax
movl %eax, 0x4d4(%rsp)
movl $0x1, 0x1bc(%rsp)
leaq 0x1c0(%rsp), %rdi
callq 0x2080
movl 0x4d4(%rsp), %eax
addq $0x4d8, %rsp            # imm = 0x4D8
retq
movq 0x498(%rsp), %rdi
callq 0x23a0
nopw %cs:(%rax,%rax)
nop