// File: /workspace/github_c_makefile_star2_O2/seojangho[P]clee/simclist.c
// Function: list_dump_filedescriptor
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) {
    struct list_entry_s *x;
    void *ser_buf;
    uint32_t bufsize;
    struct timeval timeofday;
    struct list_dump_header_s header;

    if (l->attrs.meter == NULL && l->attrs.serializer == NULL) {
        errno = ENOTTY;
        return -1;
    }

    /****       DUMP FORMAT      ****

    [ ver   timestamp   |  totlen   numels  elemlen     hash    |   DATA ]
    
    where DATA can be:
    @ for constant-size list (element size is constant; elemlen > 0)
    [ elem    elem    ...    elem ]
    @ for other lists (element size dictated by element_meter each time; elemlen <= 0)
    [ size elem     size elem       ...     size elem ]
    
    all integers are encoded in NETWORK BYTE FORMAT
    *****/


    /* prepare HEADER */
    /* version */
    header.ver = htons( SIMCLIST_DUMPFORMAT_VERSION );

    /* timestamp */
    gettimeofday(&timeofday, NULL);
    header.timestamp = (int64_t)timeofday.tv_sec * 1000000 + (int64_t)timeofday.tv_usec;
    header.timestamp = hton64(header.timestamp);

    header.rndterm = htonl((int32_t)get_random());

    /* total list size is postprocessed afterwards */

    /* number of elements */
    header.numels = htonl(l->numels);

    /* include an hash, if possible */
    if (l->attrs.hasher != NULL) {
        if (htonl(list_hash(l, & header.listhash)) != 0) {
            /* could not compute list hash! */
            return -1;
        }
    } else {
        header.listhash = htonl(0);
    }

    header.totlistlen = header.elemlen = 0;

    /* leave room for the header at the beginning of the file */
    if (lseek(fd, SIMCLIST_DUMPFORMAT_HEADERLEN, SEEK_SET) < 0) {
        /* errno set by lseek() */
        return -1;
    }

    /* write CONTENT */
    if (l->numels > 0) {
        /* SPECULATE that the list has constant element size */
        
        if (l->attrs.serializer != NULL) {  /* user user-specified serializer */
            /* get preliminary length of serialized element in header.elemlen */
            ser_buf = l->attrs.serializer(l->head_sentinel->next->data, & header.elemlen);
            free(ser_buf);
            /* request custom serialization of each element */
            for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) {
                ser_buf = l->attrs.serializer(x->data, &bufsize);
                header.totlistlen += bufsize;
                if (header.elemlen != 0) {      /* continue on speculation */
                    if (header.elemlen != bufsize) {
                        free(ser_buf);
                        /* constant element length speculation broken! */
                        header.elemlen = 0;
                        header.totlistlen = 0;
                        x = l->head_sentinel;
                        if (lseek(fd, SIMCLIST_DUMPFORMAT_HEADERLEN, SEEK_SET) < 0) {
                            /* errno set by lseek() */
                            return -1;
                        }
                        /* restart from the beginning */
                        continue;
                    }
                    /* speculation confirmed */
                    WRITE_ERRCHECK(fd, ser_buf, bufsize);
                } else {                        /* speculation found broken */
                    WRITE_ERRCHECK(fd, & bufsize, sizeof(size_t));
                    WRITE_ERRCHECK(fd, ser_buf, bufsize);
                }
                free(ser_buf);
            }
        } else if (l->attrs.meter != NULL) {
            header.elemlen = (uint32_t)l->attrs.meter(l->head_sentinel->next->data);

            /* serialize the element straight from its data */
            for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) {
                bufsize = l->attrs.meter(x->data);
                header.totlistlen += bufsize;
                if (header.elemlen != 0) {
                    if (header.elemlen != bufsize) {
                        /* constant element length speculation broken! */
                        header.elemlen = 0;
                        header.totlistlen = 0;
                        x = l->head_sentinel;
                        /* restart from the beginning */
                        continue;
                    }
                    WRITE_ERRCHECK(fd, x->data, bufsize);
                } else {
                    WRITE_ERRCHECK(fd, &bufsize, sizeof(size_t));
                    WRITE_ERRCHECK(fd, x->data, bufsize);
                }
            }
        }
        /* adjust endianness */
        header.elemlen = htonl(header.elemlen);
        header.totlistlen = htonl(header.totlistlen);
    }

    /* write random terminator */
    WRITE_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm));        /* list terminator */


    /* write header */
    lseek(fd, 0, SEEK_SET);

    WRITE_ERRCHECK(fd, & header.ver, sizeof(header.ver));                        /* version */
    WRITE_ERRCHECK(fd, & header.timestamp, sizeof(header.timestamp));            /* timestamp */
    WRITE_ERRCHECK(fd, & header.rndterm, sizeof(header.rndterm));                /* random terminator */

    WRITE_ERRCHECK(fd, & header.totlistlen, sizeof(header.totlistlen));          /* total length of elements */
    WRITE_ERRCHECK(fd, & header.numels, sizeof(header.numels));                  /* number of elements */
    WRITE_ERRCHECK(fd, & header.elemlen, sizeof(header.elemlen));                /* size of each element, or 0 for independent */
    WRITE_ERRCHECK(fd, & header.listhash, sizeof(header.listhash));             /* list hash, or 0 for "ignore" */


    /* possibly store total written length in "len" */
    if (len != NULL) {
        *len = sizeof(header) + ntohl(header.totlistlen);
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdx, %r15
movl %esi, %ebp
movq %rdi, %r13
movq 0x50(%rdi), %rbx
pushq $-0x1
popq %r12
testq %rbx, %rbx
jne 0x4a06
cmpq $0x0, 0x68(%r13)
je 0x4b61
movw $0x100, 0x10(%rsp)      # imm = 0x100
leaq 0x58(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0x30b0
imulq $0xf4240, (%r14), %rax  # imm = 0xF4240
addq 0x8(%r14), %rax
bswapq %rax
movq %rax, 0x18(%rsp)
callq 0x31e0
bswapl %eax
movl %eax, 0x20(%rsp)
movl 0x18(%r13), %r14d
movl %r14d, %eax
bswapl %eax
movl %eax, 0x28(%rsp)
cmpq $0x0, 0x60(%r13)
je 0x4a65
leaq 0x30(%rsp), %rsi
movq %r13, %rdi
callq 0x47dd
testl %eax, %eax
jne 0x4d46
jmp 0x4a6a
andl $0x0, 0x30(%rsp)
andl $0x0, 0x2c(%rsp)
andl $0x0, 0x24(%rsp)
pushq $0x1e
popq %rsi
movl %ebp, %edi
xorl %edx, %edx
callq 0x30a0
testq %rax, %rax
js 0x4d46
movq %r15, 0x50(%rsp)
testl %r14d, %r14d
je 0x4c69
movq 0x68(%r13), %r15
testq %r15, %r15
je 0x4b71
movq (%r13), %rbx
movq 0x8(%rbx), %rax
movq (%rax), %rdi
leaq 0x2c(%rsp), %rsi
callq *%r15
movq %rax, %rdi
callq 0x3030
movq 0x8(%r13), %r13
leaq 0xc(%rsp), %r12
movq %rbx, 0x38(%rsp)
movq 0x8(%rbx), %rbx
cmpq %r13, %rbx
je 0x4c37
movq (%rbx), %rdi
movq %r12, %rsi
callq *%r15
movl 0xc(%rsp), %edx
addl %edx, 0x24(%rsp)
movq %rax, %r14
movl 0x2c(%rsp), %eax
testl %eax, %eax
je 0x4b27
cmpl %edx, %eax
je 0x4b41
movq %r14, %rdi
callq 0x3030
andl $0x0, 0x2c(%rsp)
andl $0x0, 0x24(%rsp)
movl %ebp, %edi
pushq $0x1e
popq %rsi
xorl %edx, %edx
callq 0x30a0
movq 0x38(%rsp), %rbx
testq %rax, %rax
jns 0x4acd
jmp 0x4d42
movl %ebp, %edi
movq %r12, %rsi
pushq $0x8
popq %rdx
callq 0x3070
testq %rax, %rax
js 0x4d42
movl 0xc(%rsp), %edx
movl %ebp, %edi
movq %r14, %rsi
callq 0x3070
testq %rax, %rax
js 0x4d42
movq %r14, %rdi
callq 0x3030
jmp 0x4acd
callq 0x3040
movl $0x19, (%rax)
jmp 0x4d46
testq %rbx, %rbx
je 0x4c46
movq (%r13), %r12
movq 0x8(%r12), %rax
movq (%rax), %rdi
callq *%rbx
movq 0x8(%r13), %rcx
movq %rcx, 0x38(%rsp)
movq %r12, 0x40(%rsp)
xorl %r13d, %r13d
movq %rax, 0x48(%rsp)
movl %eax, %r14d
movl 0xc(%rsp), %r15d
movq 0x8(%r12), %r12
cmpq 0x38(%rsp), %r12
je 0x4c4d
movq (%r12), %rdi
callq *%rbx
movq %rax, %r15
addl %r15d, %r13d
testl %r14d, %r14d
je 0x4be4
cmpl %r15d, %r14d
jne 0x4c1c
movq (%r12), %rsi
movl %r15d, %edx
movl %ebp, %edi
callq 0x3070
testq %rax, %rax
jns 0x4ba6
jmp 0x4d3d
movl %r15d, 0xc(%rsp)
movl %ebp, %edi
leaq 0xc(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x3070
testq %rax, %rax
js 0x4d42
movq (%r12), %rsi
movl %r15d, %edx
movl %ebp, %edi
callq 0x3070
xorl %r14d, %r14d
testq %rax, %rax
jns 0x4ba1
jmp 0x4d42
movl %r15d, 0xc(%rsp)
andl $0x0, 0x2c(%rsp)
andl $0x0, 0x24(%rsp)
xorl %eax, %eax
movq 0x40(%rsp), %r12
jmp 0x4b96
movl 0x24(%rsp), %r13d
movl 0x2c(%rsp), %eax
pushq $-0x1
popq %r12
jmp 0x4c5b
xorl %r13d, %r13d
xorl %eax, %eax
jmp 0x4c5b
movl %r15d, 0xc(%rsp)
pushq $-0x1
popq %r12
movq 0x48(%rsp), %rax
bswapl %eax
movl %eax, 0x2c(%rsp)
bswapl %r13d
movl %r13d, 0x24(%rsp)
leaq 0x20(%rsp), %r15
pushq $0x4
popq %rdx
movl %ebp, %edi
movq %r15, %rsi
callq 0x3070
testq %rax, %rax
js 0x4d46
movl %ebp, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x30a0
leaq 0x10(%rsp), %rsi
pushq $0x2
popq %rdx
movl %ebp, %edi
callq 0x3070
testq %rax, %rax
js 0x4d46
leaq 0x18(%rsp), %rsi
pushq $0x8
popq %rdx
movl %ebp, %edi
callq 0x3070
testq %rax, %rax
js 0x4d46
pushq $0x4
popq %rdx
movl %ebp, %edi
movq %r15, %rsi
callq 0x3070
testq %rax, %rax
js 0x4d46
leaq 0x24(%rsp), %rsi
pushq $0x4
popq %rdx
movl %ebp, %edi
callq 0x3070
testq %rax, %rax
js 0x4d46
leaq 0x28(%rsp), %rsi
pushq $0x4
popq %rdx
movl %ebp, %edi
callq 0x3070
testq %rax, %rax
js 0x4d46
pushq $0x4
popq %rdx
movl %ebp, %edi
leaq 0x2c(%rsp), %rsi
callq 0x3070
testq %rax, %rax
js 0x4d46
leaq 0x30(%rsp), %rsi
pushq $0x4
popq %rdx
movl %ebp, %edi
callq 0x3070
testq %rax, %rax
js 0x4d46
xorl %r12d, %r12d
movq 0x50(%rsp), %rcx
testq %rcx, %rcx
je 0x4d46
movl 0x24(%rsp), %eax
bswapl %eax
addq $0x28, %rax
movq %rax, (%rcx)
jmp 0x4d46
movl %r15d, 0xc(%rsp)
pushq $-0x1
popq %r12
movl %r12d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq