LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_write
static int funk_write(struct multiboot *mboot,
                      struct databuf *dbuf,
                      int memtype)
{
    struct funk_privdata *funk = (struct funk_privdata *)mboot->privdata;
    char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";

    uint16_t pos = 0;
    while (pos < dbuf->length)
    {
        mboot->progress_cb(progress_msg, pos, dbuf->length);

        uint16_t len = (memtype == MEMTYPE_FLASH) ? funk->flashpage : WRITE_BLOCK_SIZE;

        len = MIN(len, dbuf->length - pos);

        if (funk_write_memory(funk, dbuf->data + pos, len, memtype, pos))
        {
            mboot->progress_cb(progress_msg, -1, -1);
            return -1;
        }

        pos += len;
    }

    mboot->progress_cb(progress_msg, pos, dbuf->length);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r12
movq %rdi, %rbp
movq 0x8(%rdi), %r13
movl %edx, 0x4(%rsp)
cmpl $0x1, %edx
leaq 0x3a6b(%rip), %rax      # 0x84d8
leaq 0x3a72(%rip), %r14      # 0x84e6
cmoveq %rax, %r14
leaq 0x8(%rsi), %rax
movq %rax, 0x30(%rsp)
xorl %r15d, %r15d
movq %rdi, 0x20(%rsp)
movq %r14, 0x10(%rsp)
movq %rsi, 0x18(%rsp)
movzwl %r15w, %r15d
movl 0x4(%r12), %ebx
movq %r14, %rdi
movl %r15d, %esi
movl %ebx, %edx
callq *0x18(%rbp)
cmpl %r15d, %ebx
jbe 0x4bc8
pushq $0x20
popq %rax
cmpl $0x1, 0x4(%rsp)
jne 0x4abf
movzwl 0x20(%r13), %eax
movl 0x4(%r12), %ebx
subl %r15d, %ebx
cmpl %ebx, %eax
cmovbl %eax, %ebx
movl %r15d, %r12d
movq 0x30(%rsp), %rax
leaq (%rax,%r12), %rsi
cmpb $0x2, 0x4(%rsp)
jne 0x4afe
movzwl %bx, %edx
movq %r13, %rdi
pushq $0x2
popq %rcx
movl %r15d, %r8d
callq 0x51be
movl %ebx, %ecx
movl %eax, %ebx
movq 0x18(%rsp), %r12
jmp 0x4bae
movslq 0x20(%r13), %rcx
leal -0x1(%rcx), %eax
testl %r15d, %eax
jne 0x4bdb
movq %rsi, 0x8(%rsp)
movq %rcx, 0x28(%rsp)
movq %rcx, %rdi
callq 0x21d0
testq %rax, %rax
je 0x4bf8
movq %rax, %r14
movl %ebx, %ebp
movl %ebx, %ebx
movq %rax, %rdi
movq 0x8(%rsp), %rsi
movq %rbx, %rdx
callq 0x21b0
addq %r14, %rbx
movl %ebp, 0x8(%rsp)
movq 0x28(%rsp), %rax
subl %ebp, %eax
movslq %eax, %rdx
movq %rbx, %rdi
movl $0xff, %esi
callq 0x2120
xorl %ebp, %ebp
movslq 0x20(%r13), %rax
cmpq %rax, %rbp
jge 0x4b91
leaq (%r14,%rbp), %rsi
leal (%r12,%rbp), %eax
movzwl %ax, %r8d
movzbl 0x4(%rsp), %ecx
movq %r13, %rdi
pushq $0x20
popq %rdx
callq 0x51be
addq $0x20, %rbp
testl %eax, %eax
jns 0x4b60
movl %eax, %ebx
jmp 0x4b93
xorl %ebx, %ebx
movq %r14, %rdi
callq 0x2030
movq 0x20(%rsp), %rbp
movq 0x10(%rsp), %r14
movq 0x18(%rsp), %r12
movl 0x8(%rsp), %ecx
addl %ecx, %r15d
testl %ebx, %ebx
je 0x4a93
pushq $-0x1
popq %rbx
movq %r14, %rdi
movl %ebx, %esi
movl %ebx, %edx
callq *0x18(%rbp)
jmp 0x4bca
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8416(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x4434(%rip), %rsi      # 0x9020
movl %r15d, %edx
xorl %eax, %eax
callq 0x2180
jmp 0x4bb9
leaq 0x3e34(%rip), %rdi      # 0x8a33
callq 0x2240
movq 0x10(%rsp), %r14
jmp 0x4bb9
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_optarg_cb
static int funk_optarg_cb(int val, const char *arg, void *privdata)
{
    struct funk_privdata *funk = (struct funk_privdata *)privdata;

    switch (val)
    {
        case 'a': /* address */
            {
                char *endptr;

                funk->address = strtol(arg, &endptr, 16);
                if (*endptr != '\0' || funk->address < 0x00 || funk->address > 0xFF) {
                    fprintf(stderr, "invalid address: '%s'\n", arg);
                    return -1;
                }
            }
            break;

        case 'd': /* device */
            if (funk->device != NULL) {
                fprintf(stderr, "invalid device: '%s'\n", optarg);
                return -1;
            }

            funk->device = strdup(optarg);
            if (funk->device == NULL) {
                perror("strdup()");
                return -1;
            }
            break;

        case 'h':
        case '?': /* error */
            fprintf(stderr, "Usage: funkboot [options]\n"
                "  -a <address>                 - selects rfm12 address (0x00 - 0xFF)\n"
                "  -d <device>                  - selects funkbridge device\n"
                "  -r <flash|eeprom>:<file>     - reads flash/eeprom to file   (.bin | .hex | -)\n"
                "  -w <flash|eeprom>:<file>     - write flash/eeprom from file (.bin | .hex)\n"
                "  -n                           - disable verify after write\n"
                "  -p <0|1|2>                   - progress bar mode\n"
                "\n"
                "Example: funkboot -d /dev/ttyUSB0 -a 0x22 -w flash:blmc.hex -w eeprom:blmc_eeprom.hex\n"
                "\n");
            return -1;

        default:
            return 1;
    }

    return 0;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rdx, %r14
cmpl $0x61, %edi
je 0x4c69
cmpl $0x64, %edi
je 0x4c32
cmpl $0x3f, %edi
je 0x4c96
cmpl $0x68, %edi
je 0x4c96
pushq $0x1
jmp 0x4cf0
cmpq $0x0, (%r14)
jne 0x4cb6
movq 0x8391(%rip), %rax      # 0xcfd0
movq (%rax), %rdi
callq 0x2290
movq %rax, %rcx
movq %rax, (%r14)
xorl %eax, %eax
testq %rcx, %rcx
jne 0x4cf1
leaq 0x341b(%rip), %rdi      # 0x807a
callq 0x2240
jmp 0x4cee
movq %rsi, %rbx
leaq 0x8(%rsp), %r15
pushq $0x10
popq %rdx
movq %rsi, %rdi
movq %r15, %rsi
callq 0x21a0
movl %eax, 0x10(%r14)
movq (%r15), %rcx
cmpb $0x0, (%rcx)
jne 0x4cd3
cmpl $0x100, %eax            # imm = 0x100
jae 0x4cd3
xorl %eax, %eax
jmp 0x4cf1
movq 0x835b(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x3e30(%rip), %rdi      # 0x8ad7
pushq $0x1
popq %rdx
movl $0x1fd, %esi            # imm = 0x1FD
callq 0x2280
jmp 0x4cee
movq 0x833b(%rip), %rax      # 0xcff8
movq (%rax), %rdi
movq 0x8309(%rip), %rax      # 0xcfd0
movq (%rax), %rdx
leaq 0x3393(%rip), %rsi      # 0x8064
jmp 0x4ce7
movq 0x831e(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x3369(%rip), %rsi      # 0x804d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x2180
pushq $-0x1
popq %rax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_switch_application
static int funk_switch_application(struct funk_privdata *funk,
                                   uint8_t application)
{
    struct rfm12_pkt packet;

    packet.dest_address         = funk->address;
    packet.source_address       = 0xCC;             // TODO: changed in bridge
    packet.data_length          = 0x04;
    packet.header_checksum      = 0xCC;             // TODO: calced in bridge
    packet.msg.command          = MSG_CMD_SWITCHAPP_REQUEST;
    packet.msg.seqnum           = ++funk->seqnum;   // TODO: retransmit in bridge?
    packet.msg.cause            = CAUSE_SUCCESS;
    packet.msg.p.switchapp.app  = application;

    int ret = funk_send_packet(funk, &packet, 4 + packet.data_length);
    if (ret < 0)
    {
        fprintf(stderr, "funk_switch_application(): funk_send_packet()\n");
        return ret;
    }

    int response_size = sizeof(packet);
    ret = funk_recv_packet(funk, &packet, &response_size);
    if (ret < 0)
    {
        fprintf(stderr, "funk_switch_application(): funk_recv_packet()\n");
        return ret;
    }

    if ((packet.msg.command != MSG_CMD_SWITCHAPP_RESPONSE) ||
        (packet.msg.cause != CAUSE_SUCCESS)
       )
    {
        return -1;
    }

    return 0;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x38, %rsp
movq %rdi, %r14
movb 0x10(%rdi), %cl
leaq 0xd(%rsp), %rax
movb %cl, (%rax)
movl $0x20cc04cc, 0x1(%rax)  # imm = 0x20CC04CC
movl 0x18(%rdi), %ecx
incl %ecx
movl %ecx, 0x18(%rdi)
movb %cl, 0x5(%rax)
movb $0x0, 0x6(%rax)
movb %sil, 0x7(%rax)
pushq $0x8
popq %rdx
movq %rax, %rsi
callq 0x500b
testl %eax, %eax
js 0x4d6f
leaq 0x8(%rsp), %rdx
movl $0x2b, (%rdx)
leaq 0xd(%rsp), %rsi
movq %r14, %rdi
callq 0x5072
testl %eax, %eax
js 0x4d8f
movb 0x11(%rsp), %al
xorb $-0x20, %al
xorl %ebx, %ebx
orb 0x13(%rsp), %al
setne %bl
negl %ebx
movl %ebx, %eax
addq $0x38, %rsp
popq %rbx
popq %r14
retq
movl %eax, %ebx
movq 0x8280(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x412a(%rip), %rdi      # 0x8eac
pushq $0x2e
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
jmp 0x4d65
movq 0x8262(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x413b(%rip), %rdi      # 0x8edb
pushq $0x2e
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
pushq $-0x1
popq %rbx
jmp 0x4d65
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_bridge_send
static int funk_bridge_send(struct funk_privdata *funk,
                            uint8_t *header,
                            uint8_t headerlength,
                            uint8_t *data,
                            uint8_t datalength)
{
    if (headerlength > 0)
    {
        if (write(funk->fd, header, headerlength) != headerlength)
        {
            return -1;
        }
    }

    if (datalength > 0)
    {
        if (write(funk->fd, data, datalength) != datalength)
        {
            return -1;
        }
    }

#if (FUNK_BRIDGE_DEBUG == 1)
    char *dump = funk_print_data(data, datalength);
    printf("funk_bridge_send() cmd=0x%02x length=0x%02x\n%s\n", header[0], datalength, dump);
    free(dump);
#endif

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %ecx, %ebp
movq %rdx, %r14
movq %rdi, %r15
movl 0x8(%rdi), %edi
pushq $0x2
popq %rdx
callq 0x2090
pushq $-0x1
popq %rbx
cmpq $0x2, %rax
jne 0x4df2
testb %bpl, %bpl
je 0x4df0
movl 0x8(%r15), %edi
movzbl %bpl, %r15d
movq %r14, %rsi
movq %r15, %rdx
callq 0x2090
cmpq %r15, %rax
jne 0x4df2
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_serial_read
static int funk_serial_read(int fd, void *data, int size)
{
    int pos = 0;

    while (1)
    {
        fd_set fdset;
        struct timeval timeout = { .tv_sec = 1, .tv_usec = 0 };

        FD_ZERO(&fdset);
        FD_SET(fd, &fdset);

        int ret = select(fd +1, &fdset, NULL, NULL, &timeout);
        if (ret == -1)
        {
            perror("select");
            return -1;

        }
        else if (ret == 0)
        {
            break;
        }
        else if (FD_ISSET(fd, &fdset))
        {
            int len = read(fd, data + pos, size - pos);
            if (len < 0)
            {
                return -1;

            }
            else
            {
                pos += len;
                if (pos == size)
                {
                    break;
                }
            }
        }
    }

    return pos;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movl %edx, %ebx
movq %rsi, 0x8(%rsp)
movl %edi, %r12d
pushq $0x40
popq %rcx
movl %edi, %eax
cltd
idivl %ecx
movslq %eax, %r13
shll $0x6, %eax
movl %edi, %ecx
subl %eax, %ecx
pushq $0x1
popq %r14
shlq %cl, %r14
leal 0x1(%r12), %ebp
xorl %r15d, %r15d
movups 0x414f(%rip), %xmm0     # 0x90b8
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
cmpq $0x10, %rax
je 0x4f81
andq $0x0, 0x28(%rsp,%rax,8)
incq %rax
jmp 0x4f70
orq %r14, 0x28(%rsp,%r13,8)
movl %ebp, %edi
leaq 0x28(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
leaq 0x10(%rsp), %r8
callq 0x21c0
testl %eax, %eax
je 0x4fe8
cmpl $-0x1, %eax
je 0x4ffd
testq %r14, 0x28(%rsp,%r13,8)
je 0x4fd9
movl %r15d, %esi
addq 0x8(%rsp), %rsi
movl %ebx, %eax
subl %r15d, %eax
movslq %eax, %rdx
movl %r12d, %edi
callq 0x2150
addl %eax, %r15d
xorl %ecx, %ecx
cmpl %ebx, %r15d
sete %dl
testl %eax, %eax
js 0x4fe4
movb %dl, %cl
leal (%rcx,%rcx,2), %eax
jmp 0x4fdb
xorl %eax, %eax
testl %eax, %eax
je 0x4f62
cmpl $0x3, %eax
je 0x4fe8
pushq $-0x1
popq %r15
movl %r15d, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3453(%rip), %rdi      # 0x8457
callq 0x2240
jmp 0x4fe4
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_send_packet
static int funk_send_packet(struct funk_privdata *funk,
                            struct rfm12_pkt *pkt,
                            int length)
{
    uint8_t request[] = { BRIDGE_CMD_TRANSMIT, length };

    int ret = funk_bridge_send(funk, request, sizeof(request), (uint8_t *)pkt, length);
    if (ret < 0)
    {
        return ret;
    }

    uint8_t cause = BRIDGE_CAUSE_SUCCESS;
    ret = funk_bridge_recv(funk, request[0], &cause, NULL, 0);
    if (ret != 0)
    {
        return -1;
    }

#if (FUNK_PACKET_DEBUG == 1)
    char *dump = funk_print_data((uint8_t *)pkt, length);
    printf("funk_send_packet() cause=0x%02x length=0x%02x\n%s\n",
           cause, length, dump);

    free(dump);
#endif

    return (cause != BRIDGE_CAUSE_SUCCESS);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rsi, %rax
movq %rdi, %r14
leaq 0xe(%rsp), %rsi
movb $0x54, (%rsi)
movb %dl, 0x1(%rsi)
movzbl %dl, %ecx
movq %rax, %rdx
callq 0x4db0
testl %eax, %eax
js 0x5063
leaq 0xd(%rsp), %r15
movb $0x0, (%r15)
xorl %ebx, %ebx
pushq $0x54
popq %rsi
movq %r14, %rdi
movq %r15, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x4dff
xorl %ecx, %ecx
cmpb $0x0, (%r15)
setne %cl
negl %eax
sbbl %ebx, %ebx
orl %ecx, %ebx
jmp 0x5066
pushq $-0x1
popq %rbx
movl %ebx, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_recv_packet
static int funk_recv_packet(struct funk_privdata *funk,
                            struct rfm12_pkt *pkt,
                            int *length)
{
    uint8_t request[] = { BRIDGE_CMD_RECEIVE, 0 };

    int ret = funk_bridge_send(funk, request, sizeof(request), NULL, 0);
    if (ret < 0)
    {
        return ret;
    }

    uint8_t cause = BRIDGE_CAUSE_SUCCESS;
    ret = funk_bridge_recv(funk, request[0], &cause, (uint8_t *)pkt, *length);
    if (ret < 0)
    {
        return -1;
    }

    *length = ret;

#if (FUNK_PACKET_DEBUG == 1)
    char *dump = funk_print_data((uint8_t *)pkt, *length);
    printf("funk_recv_packet() cause=0x%02x length=0x%02x\n%s\n", cause, *length, dump);
    free(dump);
#endif

    return (cause != BRIDGE_CAUSE_SUCCESS);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r15
leaq 0xe(%rsp), %rsi
movw $0x52, (%rsi)
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x4db0
testl %eax, %eax
js 0x50c6
leaq 0xd(%rsp), %rdx
movb $0x0, (%rdx)
movl (%rbx), %r8d
pushq $0x52
popq %rsi
movq %r15, %rdi
movq %r14, %rcx
callq 0x4dff
testl %eax, %eax
js 0x50c6
movl %eax, (%rbx)
xorl %eax, %eax
cmpb $0x0, 0xd(%rsp)
setne %al
jmp 0x50c9
pushq $-0x1
popq %rax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: funk_read_memory
static int funk_read_memory(struct funk_privdata *funk,
                            uint8_t *buffer,
                            uint16_t size,
                            uint8_t memtype,
                            uint16_t address)
{
    struct rfm12_pkt packet;

    packet.dest_address         = funk->address;
    packet.source_address       = 0xCC;             // TODO: changed in bridge
    packet.data_length          = 0x07;
    packet.header_checksum      = 0xCC;             // TODO: calced in bridge
    packet.msg.command          = MSG_CMD_READ_REQUEST;
    packet.msg.seqnum           = ++funk->seqnum;   // TODO: retransmit in bridge?
    packet.msg.cause            = CAUSE_SUCCESS;
    packet.msg.p.read_req.address   = address;
    packet.msg.p.read_req.mem_type  = memtype;
    packet.msg.p.read_req.size      = size;

    int ret = funk_send_packet(funk, &packet, 4 + packet.data_length);
    if (ret < 0) {
        fprintf(stderr, "funk_read_memory(): funk_send_packet()\n");
        return ret;
    }

    int response_size = sizeof(packet);
    ret = funk_recv_packet(funk, &packet, &response_size);
    if (ret < 0) {
        fprintf(stderr, "funk_read_memory(): funk_recv_packet()\n");
        return ret;
    }

    if ((packet.msg.command != MSG_CMD_READ_RESPONSE) ||
        (packet.msg.cause != CAUSE_SUCCESS)
       )
    {
        return -1;
    }

    memcpy(buffer, packet.msg.p.read_rsp.data, MIN(packet.data_length -3, size));

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x38, %rsp
movl %edx, %ebp
movq %rsi, %rbx
movq %rdi, %r15
movb 0x10(%rdi), %al
leaq 0xd(%rsp), %rsi
movb %al, (%rsi)
movl $0x23cc07cc, 0x1(%rsi)  # imm = 0x23CC07CC
movl 0x18(%rdi), %eax
incl %eax
movl %eax, 0x18(%rdi)
movb %al, 0x5(%rsi)
movb $0x0, 0x6(%rsi)
movw %r8w, 0x7(%rsi)
movb %cl, 0x9(%rsi)
movb %bpl, 0xa(%rsi)
pushq $0xb
popq %rdx
callq 0x500b
testl %eax, %eax
js 0x517b
leaq 0x8(%rsp), %rdx
movl $0x2b, (%rdx)
leaq 0xd(%rsp), %rsi
movq %r15, %rdi
callq 0x5072
testl %eax, %eax
js 0x519c
cmpb $-0x1d, 0x11(%rsp)
pushq $-0x1
popq %r14
jne 0x516d
cmpb $0x0, 0x13(%rsp)
jne 0x516d
leaq 0x14(%rsp), %rsi
movzbl -0x5(%rsi), %eax
addl $-0x3, %eax
movzwl %bp, %ecx
cmpl %ecx, %eax
cmovgel %ecx, %eax
movslq %eax, %rdx
movq %rbx, %rdi
callq 0x21b0
xorl %r14d, %r14d
movl %r14d, %eax
addq $0x38, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %r14d
movq 0x7e73(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x3e21(%rip), %rdi      # 0x8fb0
pushq $0x27
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
jmp 0x516d
movq 0x7e55(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x3e2b(%rip), %rdi      # 0x8fd8
pushq $0x27
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
pushq $-0x1
popq %r14
jmp 0x516d
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/funkboot.c
// Function: _funk_write_memory
static int __funk_write_memory(struct funk_privdata *funk,
                               uint8_t *buffer,
                               uint16_t size,
                               uint8_t memtype,
                               uint16_t address)
{
    struct rfm12_pkt packet;

    packet.dest_address         = funk->address;
    packet.source_address       = 0xCC;             // TODO: changed in bridge
    packet.data_length          = 0x07 + size;
    packet.header_checksum      = 0xCC;             // TODO: calced in bridge
    packet.msg.command          = MSG_CMD_WRITE_REQUEST;
    packet.msg.seqnum           = ++funk->seqnum;   // TODO: retransmit in bridge?
    packet.msg.cause            = CAUSE_SUCCESS;
    packet.msg.p.write_req.address   = address;
    packet.msg.p.write_req.mem_type  = memtype;
    packet.msg.p.write_req.size      = size;

    memcpy(packet.msg.p.write_req.data, buffer, size);

    int ret = funk_send_packet(funk, &packet, 4 + packet.data_length);
    if (ret < 0)
    {
        fprintf(stderr, "funk_write_memory(): funk_send_packet()\n");
        return ret;
    }

    int response_size = sizeof(packet);
    ret = funk_recv_packet(funk, &packet, &response_size);
    if (ret < 0)
    {
        fprintf(stderr, "funk_write_memory(): funk_recv_packet()\n");
        return ret;
    }

    if ((packet.msg.command != MSG_CMD_WRITE_RESPONSE) ||
        (packet.msg.cause != CAUSE_SUCCESS)
       )
    {
        return -1;
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
movb 0x10(%rdi), %al
leaq 0x18(%rsp), %rdi
movb %al, -0xb(%rdi)
movb $-0x34, -0xa(%rdi)
leal 0x7(%rdx), %ebp
movb %bpl, -0x9(%rdi)
movw $0x24cc, -0x8(%rdi)     # imm = 0x24CC
movl 0x18(%rbx), %eax
incl %eax
movl %eax, 0x18(%rbx)
movb %al, -0x6(%rdi)
movb $0x0, -0x5(%rdi)
movw %r8w, -0x4(%rdi)
movb %cl, -0x2(%rdi)
movb %dl, -0x1(%rdi)
movl %edx, %edx
callq 0x21b0
movzbl %bpl, %edx
addl $0x4, %edx
leaq 0xd(%rsp), %rsi
movq %rbx, %rdi
callq 0x500b
testl %eax, %eax
js 0x5253
leaq 0x8(%rsp), %rdx
movl $0x2b, (%rdx)
leaq 0xd(%rsp), %rsi
movq %rbx, %rdi
callq 0x5072
testl %eax, %eax
js 0x5273
movb 0x11(%rsp), %al
xorb $-0x1c, %al
xorl %ebp, %ebp
orb 0x13(%rsp), %al
setne %bpl
negl %ebp
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %rbp
retq
movl %eax, %ebp
movq 0x7d9c(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x3dfe(%rip), %rdi      # 0x9064
pushq $0x28
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
jmp 0x524a
movq 0x7d7e(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x3e09(%rip), %rdi      # 0x908d
pushq $0x28
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
pushq $-0x1
popq %rbp
jmp 0x524a
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_alloc
static struct multiboot * mpm_alloc(void)
{
    struct multiboot * mboot = malloc(sizeof(struct multiboot));
    if (mboot == NULL)
    {
        return NULL;
    }

    memset(mboot, 0x00, sizeof(struct multiboot));
    mboot->ops  = &mpm_ops;

    struct mpm_privdata *mpm = malloc(sizeof(struct mpm_privdata));
    if (mpm == NULL)
    {
        free(mboot);
        return NULL;
    }

    memset(mpm, 0x00, sizeof(struct mpm_privdata));
    mpm->device  = NULL;
    mpm->address = 0;

    optarg_register(mpm_optargs, ARRAY_SIZE(mpm_optargs),
                    mpm_optarg_cb, (void *)mpm);

    mboot->privdata = mpm;
    return mboot;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
pushq $0x1
popq %rdi
pushq $0x20
popq %rsi
callq 0x2160
testq %rax, %rax
je 0x52ef
movq %rax, %rbx
leaq 0x81de(%rip), %rax      # 0xd490
movq %rax, (%rbx)
pushq $0x1
popq %rdi
pushq $0x58
popq %rsi
callq 0x2160
testq %rax, %rax
je 0x52e7
movq %rax, %r14
leaq 0x8211(%rip), %rdi      # 0xd4e0
leaq 0x743(%rip), %rdx       # 0x5a19
pushq $0x2
popq %rsi
movq %rax, %rcx
callq 0x6544
movq %r14, 0x8(%rbx)
jmp 0x52f1
movq %rbx, %rdi
callq 0x2030
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_close
static int mpm_close(struct multiboot *mboot)
{
    struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;

    if (mpm->connected)
    {
        mpm_switch_application(mpm, BOOTTYPE_APPLICATION);
    }

    mpm_close_device(mpm);
    return 0;
}

// Assembly:
pushq %rbx
movq 0x8(%rdi), %rbx
cmpl $0x0, 0xc(%rbx)
je 0x563c
movq %rbx, %rdi
movl $0x80, %esi
callq 0x5b11
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x22c0
movl 0x8(%rbx), %edi
leaq 0x18(%rbx), %rdx
xorl %esi, %esi
callq 0x2200
movl 0x8(%rbx), %edi
callq 0x2140
xorl %eax, %eax
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_read
static int mpm_read(struct multiboot *mboot,
                    struct databuf *dbuf, int memtype)
{
    struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
    char *progress_msg = (memtype == MEMTYPE_FLASH) ? "reading flash" : "reading eeprom";

    uint16_t pos = 0;
    uint16_t size = (memtype == MEMTYPE_FLASH) ? mpm->flashsize : mpm->eepromsize;

    while (pos < size)
    {
        mboot->progress_cb(progress_msg, pos, size);

        uint16_t len = MIN(READ_BLOCK_SIZE, size - pos);
        if (mpm_read_memory(mpm, dbuf->data + pos, len, memtype, pos))
        {
            mboot->progress_cb(progress_msg, -1, -1);
            return -1;
        }

        pos += len;
    }

    dbuf->length = pos;

    mboot->progress_cb(progress_msg, pos, size);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, 0x8(%rsp)
movq 0x8(%rdi), %rdi
xorl %eax, %eax
cmpl $0x1, %edx
setne %al
leaq 0x2dde(%rip), %rcx      # 0x8464
leaq 0x2de5(%rip), %r15      # 0x8472
cmoveq %rcx, %r15
movq %rdi, 0x20(%rsp)
movzwl 0x12(%rdi,%rax,4), %ebx
movq %rsi, 0x10(%rsp)
leaq 0x8(%rsi), %rax
movq %rax, 0x18(%rsp)
xorl %ebp, %ebp
movl $0x100, %r12d           # imm = 0x100
movzbl %dl, %r13d
movzwl %bp, %r14d
cmpw %bx, %r14w
jae 0x5711
movq %r15, %rdi
movl %r14d, %esi
movl %ebx, %edx
movq 0x8(%rsp), %rax
callq *0x18(%rax)
movl %ebx, %ebp
subl %r14d, %ebp
cmpl %r12d, %ebp
cmovgel %r12d, %ebp
movl %r14d, %esi
addq 0x18(%rsp), %rsi
movzwl %bp, %edx
movq 0x20(%rsp), %rdi
movl %r13d, %ecx
movl %r14d, %r8d
callq 0x5e95
addl %r14d, %ebp
testl %eax, %eax
je 0x56b5
pushq $-0x1
popq %rbp
movq %r15, %rdi
movl %ebp, %esi
movl %ebp, %edx
movq 0x8(%rsp), %rax
callq *0x18(%rax)
jmp 0x572c
movq 0x10(%rsp), %rax
movl %r14d, 0x4(%rax)
movq %r15, %rdi
movl %r14d, %esi
movl %ebx, %edx
movq 0x8(%rsp), %rax
callq *0x18(%rax)
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_verify
static int mpm_verify(struct multiboot *mboot,
                      struct databuf *dbuf, int memtype)
{
    struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
    char *progress_msg = (memtype == MEMTYPE_FLASH) ? "verifing flash" : "verifing eeprom";

    uint16_t pos = 0;
    uint8_t comp[READ_BLOCK_SIZE];

    while (pos < dbuf->length)
    {
        mboot->progress_cb(progress_msg, pos, dbuf->length);

        uint16_t len = MIN(READ_BLOCK_SIZE, dbuf->length - pos);
        if (mpm_read_memory(mpm, comp, len, memtype, pos))
        {
            mboot->progress_cb(progress_msg, -1, -1);
            return -1;
        }

        if (memcmp(comp, dbuf->data + pos, len) != 0x00)
        {
            mboot->progress_cb(progress_msg, -1, -1);
            fprintf(stderr, "verify failed at page 0x%04x!!\n", pos);
            return -1;
        }

        pos += len;
    }

    dbuf->length = pos;

    mboot->progress_cb(progress_msg, pos, dbuf->length);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x128, %rsp            # imm = 0x128
movq %rsi, %r12
movq %rdi, 0x8(%rsp)
movq 0x8(%rdi), %rax
movq %rax, 0x18(%rsp)
cmpl $0x1, %edx
leaq 0x2d31(%rip), %rax      # 0x849a
leaq 0x2d39(%rip), %r14      # 0x84a9
cmoveq %rax, %r14
leaq 0x8(%rsi), %rax
movq %rax, 0x10(%rsp)
xorl %ecx, %ecx
movzbl %dl, %ebp
leaq 0x20(%rsp), %rbx
movzwl %cx, %r15d
movl 0x4(%r12), %edx
cmpl %r15d, %edx
jbe 0x581e
movq %r14, %rdi
movl %r15d, %esi
movq 0x8(%rsp), %rax
callq *0x18(%rax)
movl 0x4(%r12), %r13d
subl %r15d, %r13d
movl $0x100, %eax            # imm = 0x100
cmpl %eax, %r13d
cmovael %eax, %r13d
movq 0x18(%rsp), %rdi
movq %rbx, %rsi
movl %r13d, %edx
movl %ebp, %ecx
movl %r15d, %r8d
callq 0x5e95
testl %eax, %eax
jne 0x5838
movl %r15d, %esi
addq 0x10(%rsp), %rsi
movl %r13d, %edx
movq %rbx, %rdi
callq 0x21e0
leal (%r15,%r13), %ecx
testl %eax, %eax
je 0x5787
pushq $-0x1
popq %rbx
movq %r14, %rdi
movl %ebx, %esi
movl %ebx, %edx
movq 0x8(%rsp), %rax
callq *0x18(%rax)
movq 0x77f0(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x37ee(%rip), %rsi      # 0x9000
movl %r15d, %edx
xorl %eax, %eax
callq 0x2180
jmp 0x584a
movl %r15d, 0x4(%r12)
movq %r14, %rdi
movl %r15d, %esi
movl %r15d, %edx
movq 0x8(%rsp), %rax
callq *0x18(%rax)
xorl %ebx, %ebx
jmp 0x584a
pushq $-0x1
popq %rbx
movq %r14, %rdi
movl %ebx, %esi
movl %ebx, %edx
movq 0x8(%rsp), %rax
callq *0x18(%rax)
movl %ebx, %eax
addq $0x128, %rsp            # imm = 0x128
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_write
static int mpm_write(struct multiboot *mboot,
                     struct databuf *dbuf, int memtype)
{
    struct mpm_privdata *mpm = (struct mpm_privdata *)mboot->privdata;
    char *progress_msg = (memtype == MEMTYPE_FLASH) ? "writing flash" : "writing eeprom";

    uint16_t pos = 0;
    while (pos < dbuf->length)
    {
        mboot->progress_cb(progress_msg, pos, dbuf->length);

        uint16_t len = (memtype == MEMTYPE_FLASH) ? mpm->flashpage : WRITE_BLOCK_SIZE;

        len = MIN(len, dbuf->length - pos);
        if (mpm_write_memory(mpm, dbuf->data + pos, len, memtype, pos))
        {
            mboot->progress_cb(progress_msg, -1, -1);
            return -1;
        }

        pos += len;
    }

    mboot->progress_cb(progress_msg, pos, dbuf->length);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %edx, %r13d
movq %rsi, %r14
movq %rdi, 0x28(%rsp)
movq 0x8(%rdi), %rax
movq %rax, 0x10(%rsp)
cmpl $0x1, %edx
leaq 0x2c4e(%rip), %rax      # 0x84d8
leaq 0x2c55(%rip), %rcx      # 0x84e6
cmoveq %rax, %rcx
movq %rcx, 0x20(%rsp)
leaq 0x8(%rsi), %rax
movq %rax, 0x30(%rsp)
xorl %ebx, %ebx
movl %edx, 0x1c(%rsp)
movq %rsi, 0x38(%rsp)
movzwl %bx, %ebx
movl 0x4(%r14), %ebp
movq 0x20(%rsp), %rdi
movl %ebx, %esi
movl %ebp, %edx
movq 0x28(%rsp), %rax
callq *0x18(%rax)
cmpl %ebx, %ebp
jbe 0x59e7
pushq $0x10
popq %rax
cmpl $0x1, %r13d
jne 0x58e0
movq 0x10(%rsp), %rax
movzbl 0x14(%rax), %eax
movl 0x4(%r14), %r15d
subl %ebx, %r15d
cmpl %r15d, %eax
cmovbl %eax, %r15d
movl %r15d, %r12d
cmpb $0x1, %r13b
jne 0x590e
movq 0x10(%rsp), %rax
movzbl 0x14(%rax), %r12d
leal -0x1(%r12), %eax
testl %ebx, %eax
jne 0x59fa
leal 0x5(%r12), %edi
movq %rdi, 0x40(%rsp)
callq 0x21d0
testq %rax, %rax
je 0x59d1
movq %rax, %rbp
movl %ebx, %esi
addq 0x30(%rsp), %rsi
movb %r13b, (%rax)
movb %bh, 0x1(%rax)
movb %bl, 0x2(%rax)
movb $0x0, 0x3(%rax)
movb %r12b, 0x4(%rax)
movq %rax, %r12
addq $0x5, %r12
movl %r15d, %r14d
movq %r12, %rdi
movq %r14, %rdx
callq 0x21b0
cmpb $0x1, %r13b
jne 0x5978
addq %r14, %r12
movq 0x10(%rsp), %rax
movzbl 0x14(%rax), %edx
subq %r14, %rdx
movq %r12, %rdi
movl $0xff, %esi
callq 0x2120
movzwl 0x40(%rsp), %ecx
movq 0x10(%rsp), %rdi
pushq $0x12
popq %rsi
movq %rbp, %rdx
callq 0x5b67
testl %eax, %eax
movl 0x1c(%rsp), %r13d
movq 0x38(%rsp), %r14
js 0x59d1
movq %rbp, %rdi
callq 0x2030
movb $0x0, 0xf(%rsp)
movq 0x10(%rsp), %rdi
pushq $0x12
popq %rsi
leaq 0xf(%rsp), %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x5c7b
testl %eax, %eax
js 0x59d1
addl %r15d, %ebx
cmpb $0x0, 0xf(%rsp)
je 0x58ae
pushq $-0x1
popq %rbx
movq 0x20(%rsp), %rdi
movl %ebx, %esi
movl %ebx, %edx
movq 0x28(%rsp), %rax
callq *0x18(%rax)
jmp 0x59e9
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x75f7(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x3954(%rip), %rsi      # 0x935f
movl %ebx, %edx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x2180
jmp 0x59d1
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_optarg_cb
static int mpm_optarg_cb(int val, const char *arg, void *privdata)
{
    struct mpm_privdata *mpm = (struct mpm_privdata *)privdata;

    switch (val)
    {
        case 'a': /* address */
            {
                char *endptr;
                mpm->address = strtol(arg, &endptr, 16);

                if (*endptr != '\0' || mpm->address < 0x01 || mpm->address > 0x7F)
                {
                    fprintf(stderr, "invalid address: '%s'\n", arg);
                    return -1;
                }
            }
            break;

        case 'd': /* device */
            if (mpm->device != NULL)
            {
                fprintf(stderr, "invalid device: '%s'\n", optarg);
                return -1;
            }

            mpm->device = strdup(optarg);
            if (mpm->device == NULL)
            {
                perror("strdup()");
                return -1;
            }
            break;

        case 'h':
        case '?': /* error */
            fprintf(stderr, "Usage: mpmboot [options]\n"
                "  -a <address>                 - selects mpm address (0x01 - 0xFF)\n"
                "  -d <device>                  - selects mpm device\n"
                "  -r <flash|eeprom>:<file>     - reads flash/eeprom to file   (.bin | .hex | -)\n"
                "  -w <flash|eeprom>:<file>     - write flash/eeprom from file (.bin | .hex)\n"
                "  -n                           - disable verify after write\n"
                "  -p <0|1|2>                   - progress bar mode\n"
                "\n"
                "Example: mpmboot -d /dev/ttyUSB0 -a 0x22 -w flash:blmc.hex -w eeprom:blmc_eeprom.hex\n"
                "\n");

            return -1;

        default:
            return 1;
    }

    return 0;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rdx, %r14
cmpl $0x61, %edi
je 0x5a7b
cmpl $0x64, %edi
je 0x5a40
cmpl $0x3f, %edi
je 0x5aac
cmpl $0x68, %edi
je 0x5aac
pushq $0x1
jmp 0x5b06
cmpq $0x0, (%r14)
jne 0x5ae2
movq 0x757f(%rip), %rax      # 0xcfd0
movq (%rax), %rdi
callq 0x2290
movq %rax, %rcx
movq %rax, (%r14)
xorl %eax, %eax
testq %rcx, %rcx
jne 0x5b07
leaq 0x2609(%rip), %rdi      # 0x807a
callq 0x2240
jmp 0x5b04
movq %rsi, %rbx
leaq 0x8(%rsp), %r15
pushq $0x10
popq %rdx
movq %rsi, %rdi
movq %r15, %rsi
callq 0x21a0
movb %al, 0x10(%r14)
movq (%r15), %rcx
cmpb $0x0, (%rcx)
jne 0x5acc
movzbl %al, %eax
addl $-0x80, %eax
cmpl $-0x80, %eax
jbe 0x5acc
xorl %eax, %eax
jmp 0x5b07
movq 0x7545(%rip), %rax      # 0xcff8
movq (%rax), %rcx
leaq 0x3613(%rip), %rdi      # 0x90d0
pushq $0x1
popq %rdx
movl $0x1f2, %esi            # imm = 0x1F2
callq 0x2280
jmp 0x5b04
movq 0x7525(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x2570(%rip), %rsi      # 0x804d
movq %rbx, %rdx
jmp 0x5afd
movq 0x750f(%rip), %rax      # 0xcff8
movq (%rax), %rdi
movq 0x74dd(%rip), %rax      # 0xcfd0
movq (%rax), %rdx
leaq 0x2567(%rip), %rsi      # 0x8064
xorl %eax, %eax
callq 0x2180
pushq $-0x1
popq %rax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_switch_application
static int mpm_switch_application(struct mpm_privdata *mpm,
                                  uint8_t application)
{
    uint8_t data[] = { application };

    int ret = mpm_send(mpm, CMD_SWITCH_APPLICATION, data, sizeof(data));
    if (ret < 0)
    {
        return ret;
    }

    uint8_t cause = CAUSE_SUCCESS;
    ret = mpm_recv(mpm, CMD_SWITCH_APPLICATION, &cause, NULL, 0);
    if (ret < 0)
    {
        return ret;
    }

    return (cause != CAUSE_SUCCESS);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x7(%rsp), %rdx
movb %sil, (%rdx)
pushq $0x1
popq %rcx
movl %ecx, %esi
callq 0x5b67
testl %eax, %eax
js 0x5b5c
leaq 0x6(%rsp), %r14
movb $0x0, (%r14)
pushq $0x1
popq %rsi
movq %rbx, %rdi
movq %r14, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x5c7b
movl %eax, %ecx
xorl %eax, %eax
cmpb $0x0, (%r14)
setne %al
testl %ecx, %ecx
cmovsl %ecx, %eax
jmp 0x5b5f
pushq $-0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_send
static int mpm_send(struct mpm_privdata *mpm, uint8_t command,
                    uint8_t *data, uint16_t length)
{
    struct termios tio;

    if (tcgetattr(mpm->fd, &tio) < 0)
    {
        perror("tcgetattr(tio)");
        return -1;
    }

    tio.c_cflag |= PARODD;

    if (tcsetattr(mpm->fd, TCSAFLUSH, &tio) < 0)
    {
        perror("tcsetattr(tio)");
        return -1;
    }

//     usleep(5000);

    uint8_t address = mpm->address;
    if (write(mpm->fd, &address, sizeof(address)) != sizeof(address))
    {
        perror("write(address)");
        return -1;
    }

    usleep(500);

    tio.c_cflag &= ~(PARODD);

    if (tcsetattr(mpm->fd, TCSAFLUSH, &tio) < 0)
    {
        perror("tcsetattr(tio)");
        return -1;
    }

    uint8_t header[3];
    header[0] = command;
    header[1] = (length >> 8) & 0xFF;
    header[2] = length & 0xFF;

    if (write(mpm->fd, header, sizeof(header)) != sizeof(header))
    {
        perror("write(header)");
        return -1;
    }

    if (data != NULL && length != 0)
    {
        if (write(mpm->fd, data, length) != length)
        {
            perror("write(data)");
            return -1;
        }
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x48, %rsp
movl %ecx, %ebx
movq %rdx, %r14
movl %esi, %ebp
movq %rdi, %r15
movl 0x8(%rdi), %edi
leaq 0xc(%rsp), %rsi
callq 0x21f0
testl %eax, %eax
js 0x5c4d
leaq 0xc(%rsp), %rdx
orb $0x2, 0x9(%rdx)
movl 0x8(%r15), %edi
pushq $0x2
popq %rsi
callq 0x2200
testl %eax, %eax
js 0x5c44
movb 0x10(%r15), %al
leaq 0x8(%rsp), %rsi
movb %al, (%rsi)
movl 0x8(%r15), %edi
pushq $0x1
popq %rdx
callq 0x2090
cmpq $0x1, %rax
jne 0x5c56
movl $0x1f4, %edi            # imm = 0x1F4
callq 0x22c0
leaq 0xc(%rsp), %rdx
andb $-0x3, 0x9(%rdx)
movl 0x8(%r15), %edi
pushq $0x2
popq %rsi
callq 0x2200
testl %eax, %eax
js 0x5c44
leaq 0x9(%rsp), %rsi
movb %bpl, (%rsi)
movb %bh, 0xa(%rsp)
movb %bl, 0x2(%rsi)
movl 0x8(%r15), %edi
pushq $0x3
popq %rdx
callq 0x2090
cmpq $0x3, %rax
jne 0x5c5f
testq %r14, %r14
sete %al
testw %bx, %bx
sete %cl
xorl %ebp, %ebp
orb %al, %cl
jne 0x5c6e
movl 0x8(%r15), %edi
movzwl %bx, %ebx
movq %r14, %rsi
movq %rbx, %rdx
callq 0x2090
cmpq %rbx, %rax
je 0x5c6e
leaq 0x36e6(%rip), %rdi      # 0x9328
jmp 0x5c66
leaq 0x36b1(%rip), %rdi      # 0x92fc
jmp 0x5c66
leaq 0x3699(%rip), %rdi      # 0x92ed
jmp 0x5c66
leaq 0x36ae(%rip), %rdi      # 0x930b
jmp 0x5c66
leaq 0x36b4(%rip), %rdi      # 0x931a
callq 0x2240
pushq $-0x1
popq %rbp
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/mpmboot.c
// Function: mpm_read_memory
static int mpm_read_memory(struct mpm_privdata *mpm,
                           uint8_t *buffer, uint16_t size,
                           uint8_t memtype, uint16_t address)
{
    uint8_t param[5] = {
        memtype,
        (address >> 8) & 0xFF,
        (address & 0xFF),
        (size >> 8) & 0xFF,
        (size & 0xFF)
    };

    int ret = mpm_send(mpm, CMD_READ_MEMORY, param, sizeof(param));
    if (ret < 0)
    {
        return ret;
    }

    uint8_t cause = CAUSE_SUCCESS;
    ret = mpm_recv(mpm, CMD_READ_MEMORY, &cause, buffer, size);
    if (ret < 0)
    {
        return ret;
    }

    return (cause != CAUSE_SUCCESS);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r15
movl %r8d, %eax
movl %edx, %ebx
movq %rdi, %r14
leaq 0x3(%rsp), %rdx
movb %cl, (%rdx)
movb %ah, 0x4(%rsp)
movb %al, 0x2(%rdx)
movb %bh, 0x6(%rsp)
movb %bl, 0x4(%rdx)
pushq $0x11
popq %rsi
pushq $0x5
popq %rcx
callq 0x5b67
testl %eax, %eax
js 0x5efe
leaq 0x2(%rsp), %r12
movb $0x0, (%r12)
movzwl %bx, %r8d
pushq $0x11
popq %rsi
movq %r14, %rdi
movq %r12, %rdx
movq %r15, %rcx
callq 0x5c7b
movl %eax, %ecx
xorl %eax, %eax
cmpb $0x0, (%r12)
setne %al
testl %ecx, %ecx
cmovsl %ecx, %eax
jmp 0x5f01
pushq $-0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
nopl (%rax)
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/multiboot.c
// Function: progress_mode1_cb
static void progress_mode1_cb(const char *msg, int pos, int size)
{
    if (pos != -1 && size > 0)
    {
        char stars[51];
        int i;
        int count = (pos * 50 / size);

        for (i = 0; i < 50; i++)
        {
            stars[i] = (i < count) ? '*' : ' ';
        }

        stars[50] = '\0';
        printf("%-15s: [%s] (%d)\r", msg, stars, pos);
    }

    if (pos == size)
    {
        printf("\n");
    }
}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x38, %rsp
movl %edx, %ebx
movl %esi, %ebp
cmpl $-0x1, %esi
sete %al
testl %edx, %edx
setle %cl
orb %al, %cl
jne 0x62b7
movq %rdi, %rsi
imull $0x32, %ebp, %eax
cltd
idivl %ebx
cltq
xorl %ecx, %ecx
pushq $0x2a
popq %rdx
pushq $0x20
popq %rdi
cmpq $0x32, %rcx
je 0x62a0
cmpq %rax, %rcx
movl %edi, %r8d
cmovll %edx, %r8d
movb %r8b, (%rsp,%rcx)
incq %rcx
jmp 0x6287
movq %rsp, %rdx
movb $0x0, 0x32(%rdx)
leaq 0x31e9(%rip), %rdi      # 0x9497
movl %ebp, %ecx
xorl %eax, %eax
callq 0x20f0
cmpl %ebx, %ebp
jne 0x62c3
pushq $0xa
popq %rdi
callq 0x2040
addq $0x38, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/multiboot.c
// Function: main_optarg_cb
static int main_optarg_cb(int val, const char *arg, void *privdata)
{
    struct multiboot *mboot = (struct multiboot *)privdata;

    switch (val)
    {
        case 'r': /* read */
            if ((mboot->ops->read == NULL) ||
                (add_action(mboot, ACTION_READ, arg) < 0)
               )
            {
                return -1;
            }
            break;

        case 'w': /* write */
            if ((mboot->ops->write == NULL) ||
                (add_action(mboot, ACTION_WRITE, arg) < 0)
               )
            {
                return -1;
            }
            break;

        case 'n': /* no verify after write */
            mboot->verify = 0;
            break;

        case 'p':
            switch (*arg)
            {
                case '0':
                    mboot->progress_cb = progress_mode0_cb;
                    break;

                case '1':
                    mboot->progress_cb = progress_mode1_cb;
                    break;

                case '2':
                    mboot->progress_cb = progress_mode2_cb;
                    break;

                default:
                    fprintf(stderr, "invalid progress bar mode: '%s'\n", arg);
                    return -1;
            }
            break;
    }

    return 0;
}

// Assembly:
pushq %rbx
addl $-0x6e, %edi
cmpl $0x9, %edi
ja 0x634d
movq %rsi, %rax
leaq 0x30c7(%rip), %rcx      # 0x93a4
movslq (%rcx,%rdi,4), %rsi
addq %rcx, %rsi
jmpq *%rsi
andl $0x0, 0x10(%rdx)
jmp 0x634d
movq (%rdx), %rcx
pushq $-0x1
popq %rbx
cmpq $0x0, 0x38(%rcx)
je 0x634f
pushq $0x1
jmp 0x6327
movzbl (%rax), %ecx
cmpl $0x32, %ecx
je 0x6339
cmpl $0x31, %ecx
je 0x6342
cmpl $0x30, %ecx
jne 0x6353
leaq 0x197(%rip), %rax       # 0x64ad
jmp 0x6349
movq (%rdx), %rcx
pushq $-0x1
popq %rbx
cmpq $0x0, 0x48(%rcx)
je 0x634f
pushq $0x2
popq %rsi
movq %rdx, %rdi
movq %rax, %rdx
callq 0x6373
testl %eax, %eax
jns 0x634d
jmp 0x634f
leaq 0x16e(%rip), %rax       # 0x64ae
jmp 0x6349
leaq -0xee(%rip), %rax       # 0x625b
movq %rax, 0x18(%rdx)
xorl %ebx, %ebx
movl %ebx, %eax
popq %rbx
retq
movq 0x6c9e(%rip), %rcx      # 0xcff8
movq (%rcx), %rdi
leaq 0x3168(%rip), %rsi      # 0x94cc
movq %rax, %rdx
xorl %eax, %eax
callq 0x2180
pushq $-0x1
popq %rbx
jmp 0x634f
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/multiboot.c
// Function: add_action
static int add_action(struct multiboot *mboot, int mode, const char *arg)
{
    struct mboot_action *action = malloc(sizeof(struct mboot_action));
    if (action == NULL)
    {
        perror("malloc()");
        return -1;
    }

    char *argcopy = strdup(arg);
    if (argcopy == NULL)
    {
        perror("strdup()");
        free(action);
        return -1;
    }

    char *tok = strtok(argcopy, ":");
    if (tok == NULL)
    {
        fprintf(stderr, "invalid argument: '%s'\n", arg);
        free(argcopy);
        free(action);
        return -1;
    }

    action->memtype = mboot->ops->get_memtype(mboot, tok);
    if (action->memtype == -1)
    {
        fprintf(stderr, "invalid memtype: '%s'\n", tok);
        free(argcopy);
        free(action);
        return -1;
    }

    tok = strtok(NULL, ":");
    if (tok == NULL)
    {
        fprintf(stderr, "invalid argument: '%s'\n", arg);
        free(argcopy);
        free(action);
        return -1;
    }

    action->filename = strdup(tok);
    if (action->filename == NULL)
    {
        perror("strdup()");
        free(argcopy);
        free(action);
        return -1;
    }

    action->mode = mode;

    list_add_tail(&action->list, &action_list);
    free(argcopy);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %r15
movl %esi, %ebp
movq %rdi, %r12
pushq $0x20
popq %rdi
callq 0x21d0
testq %rax, %rax
je 0x6446
movq %rax, %rbx
movq %r15, %rdi
callq 0x2290
testq %rax, %rax
je 0x6454
movq %rax, %r14
leaq 0x3138(%rip), %rsi      # 0x94ed
movq %rax, %rdi
callq 0x2250
testq %rax, %rax
je 0x6430
movq %rax, %r13
movq (%r12), %rax
movq %r12, %rdi
movq %r13, %rsi
callq *0x18(%rax)
movl %eax, 0x18(%rbx)
cmpl $-0x1, %eax
je 0x6462
leaq 0x3108(%rip), %rsi      # 0x94ed
xorl %edi, %edi
callq 0x2250
testq %rax, %rax
je 0x6430
movq %rax, %rdi
callq 0x2290
movq %rax, 0x10(%rbx)
testq %rax, %rax
je 0x647f
movl %ebp, 0x1c(%rbx)
movq 0x71dc(%rip), %rax      # 0xd5e8
leaq 0x71cd(%rip), %rcx      # 0xd5e0
movq %rbx, 0x71ce(%rip)      # 0xd5e8
movq %rcx, (%rbx)
movq %rax, 0x8(%rbx)
movq %rbx, (%rax)
movq %r14, %rdi
callq 0x2030
xorl %eax, %eax
jmp 0x649e
movq 0x6bc1(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x30ae(%rip), %rsi      # 0x94ef
movq %r15, %rdx
jmp 0x6476
leaq 0x25e6(%rip), %rdi      # 0x8a33
callq 0x2240
jmp 0x649b
leaq 0x1c1f(%rip), %rdi      # 0x807a
callq 0x2240
jmp 0x6493
movq 0x6b8f(%rip), %rax      # 0xcff8
movq (%rax), %rdi
leaq 0x3094(%rip), %rsi      # 0x9507
movq %r13, %rdx
xorl %eax, %eax
callq 0x2180
jmp 0x648b
leaq 0x1bf4(%rip), %rdi      # 0x807a
callq 0x2240
movq %r14, %rdi
callq 0x2030
movq %rbx, %rdi
callq 0x2030
pushq $-0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/multiboot.c
// Function: progress_mode2_cb
static void progress_mode2_cb(const char *msg, int pos, int size)
{
    static int old_count;

    if (pos != -1 && size > 0)
    {
        if (pos == 0)
        {
            old_count = 0;
            printf("%-15s: [", msg);

        }
        else if (pos <=size)
        {
            int i;
            int count = (pos * 50 / size);

            for (i = old_count; i < count; i++)
            {
                printf("*");
            }

            old_count = count;

            if (pos == size)
            {
                printf("] (%d)\n", pos);
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %esi, %ebx
cmpl $-0x1, %esi
sete %al
testl %edx, %edx
setle %cl
orb %al, %cl
jne 0x653a
testl %ebx, %ebx
je 0x64f7
movl %edx, %ebp
cmpl %edx, %ebx
jg 0x653a
imull $0x32, %ebx, %eax
cltd
idivl %ebp
movl %eax, %r14d
movl 0x71d3(%rip), %r12d     # 0xd6b4
pushq $0x2a
popq %r15
cmpl %r14d, %r12d
jge 0x6517
movl %r15d, %edi
callq 0x2040
incl %r12d
jmp 0x64e5
movq %rdi, %rsi
andl $0x0, 0x71b3(%rip)      # 0xd6b4
leaq 0x3016(%rip), %rdi      # 0x951e
xorl %eax, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x20f0
movl %r14d, 0x7196(%rip)     # 0xd6b4
cmpl %ebp, %ebx
jne 0x653a
leaq 0x2ffe(%rip), %rdi      # 0x9527
movl %ebx, %esi
xorl %eax, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x20f0
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/optarg.c
// Function: optarg_register
int optarg_register(const struct option *opts, int count,
                    int (* parser_cb)(int val, const char *arg, void *privdata),
                    void *privdata)
{
    struct optarg_entry *entry;

    entry = malloc(sizeof(struct optarg_entry));
    if (entry == NULL)
    {
        return -1;
    }

    entry->opts         = opts;     /* TODO: copy? */
    entry->count        = count;
    entry->parser_cb    = parser_cb;
    entry->privdata     = privdata;

    list_add_tail(&entry->list, &option_list);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rcx, %rbx
movq %rdx, %r14
movl %esi, %ebp
movq %rdi, %r15
pushq $0x30
popq %rdi
callq 0x21d0
testq %rax, %rax
je 0x6595
movq %r15, 0x10(%rax)
movl %ebp, 0x18(%rax)
movq %r14, 0x20(%rax)
movq %rbx, 0x28(%rax)
movq 0x707f(%rip), %rcx      # 0xd5f8
leaq 0x7070(%rip), %rdx      # 0xd5f0
movq %rax, 0x7071(%rip)      # 0xd5f8
movq %rdx, (%rax)
movq %rcx, 0x8(%rax)
movq %rax, (%rcx)
xorl %eax, %eax
jmp 0x6598
pushq $-0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/orempel[P]multiboot_tool/optarg.c
// Function: optarg_free
void optarg_free(void)
{
    struct optarg_entry *entry, *entry_tmp;

    list_for_each_entry_safe(entry, entry_tmp, &option_list, list)
    {
        list_del(&entry->list);
        free(entry);
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0x7042(%rip), %rdi      # 0xd5f0
leaq 0x703b(%rip), %rbx      # 0xd5f0
cmpq %rbx, %rdi
je 0x65d2
movq (%rdi), %r14
movq 0x8(%rdi), %rax
movq %rax, 0x8(%r14)
movq %r14, (%rax)
callq 0x2030
movq %r14, %rdi
jmp 0x65b5
addq $0x8, %rsp
popq %rbx
popq %r14
retq