// File: /workspace/github_cpp_makefile_star2_O3/davmac314[P]dinit/src/control.cc
// Function: control_conn_t::query_load_mech()
bool control_conn_t::query_load_mech()
{
    rbuf.consume(1);
    chklen = 0;

    if (services->get_set_type_id() == SSET_TYPE_DIRLOAD) {
        dirload_service_set *dss = static_cast<dirload_service_set *>(services);
        std::vector<char> reppkt;
        reppkt.resize(2 + sizeof(uint32_t) * 2);  // packet type, loader type, packet size, # dirs
        reppkt[0] = (char)cp_rply::LOADER_MECH;
        reppkt[1] = SSET_TYPE_DIRLOAD;

        // Number of directories in load path:
        uint32_t sdirs = dss->get_service_dir_count();
        std::memcpy(reppkt.data() + 2 + sizeof(uint32_t), &sdirs, sizeof(sdirs));

        // Our current working directory, which above are relative to:
        // leave sizeof(uint32_t) for size, which we'll fill in afterwards:
        std::size_t curpos = reppkt.size() + sizeof(uint32_t);
#ifdef PATH_MAX
        uint32_t try_path_size = PATH_MAX;
#else
        uint32_t try_path_size = 2048;
#endif
        char *wd;
        while (true) {
            std::size_t total_size = curpos + std::size_t(try_path_size);
            if (total_size < curpos) {
                // Overflow. In theory we could now limit to size_t max, but the size must already
                // be crazy long; let's abort.
                char ack_rep[] = { (char)cp_rply::NAK };
                if (! queue_packet(ack_rep, 1)) return false;
                return true;
            }
            reppkt.resize(total_size);
            wd = getcwd(reppkt.data() + curpos, try_path_size);
            if (wd != nullptr) break;

            // Keep doubling the path size we try until it's big enough, or we get numeric overflow
            uint32_t new_try_path_size = try_path_size * uint32_t(2u);
            if (new_try_path_size < try_path_size) {
                // Overflow.
                char ack_rep[] = { (char)cp_rply::NAK };
                return queue_packet(ack_rep, 1);
            }
            try_path_size = new_try_path_size;
        }

        uint32_t wd_len = std::strlen(reppkt.data() + curpos);
        reppkt.resize(curpos + std::size_t(wd_len));
        std::memcpy(reppkt.data() + curpos - sizeof(uint32_t), &wd_len, sizeof(wd_len));

        // Each directory in the load path:
        for (int i = 0; uint32_t(i) < sdirs; i++) {
            const char *sdir = dss->get_service_dir(i);
            uint32_t dlen = std::strlen(sdir);
            auto cursize = reppkt.size();
            reppkt.resize(cursize + sizeof(dlen) + dlen);
            std::memcpy(reppkt.data() + cursize, &dlen, sizeof(dlen));
            std::memcpy(reppkt.data() + cursize + sizeof(dlen), sdir, dlen);
        }

        // Total packet size:
        uint32_t fsize = reppkt.size();
        std::memcpy(reppkt.data() + 2, &fsize, sizeof(fsize));

        if (! queue_packet(std::move(reppkt))) return false;
        return true;
    }
    else {
        // If we don't know how to deal with the service set type, send a NAK reply:
        char ack_rep[] = { (char)cp_rply::NAK };
        return queue_packet(ack_rep, 1);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
movl 0x480(%rdi), %eax
leal 0x1(%rax), %ecx
addl $0xfffffc01, %eax       # imm = 0xFFFFFC01
cmpl $0x400, %ecx            # imm = 0x400
cmovbl %ecx, %eax
movl %eax, 0x480(%rdi)
decl 0x484(%rdi)
movl $0x0, 0x7c(%rdi)
movq 0x70(%rdi), %rdi
movq (%rdi), %rax
callq *0x20(%rax)
cmpl $0x1, %eax
jne 0x29ddc
movq 0x70(%rbx), %r14
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rdi
movaps %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movl $0xa, %esi
callq 0x1c190
movq 0x10(%rsp), %rax
movb $0x40, (%rax)
movq 0x10(%rsp), %rax
movb $0x1, 0x1(%rax)
movq 0x50(%r14), %r12
movq %r14, 0x30(%rsp)
subq 0x48(%r14), %r12
shrq $0x4, %r12
movq 0x10(%rsp), %rax
movl %r12d, 0x6(%rax)
movq 0x18(%rsp), %rsi
subq 0x10(%rsp), %rsi
leaq 0x4(%rsi), %r13
addq $0x1004, %rsi           # imm = 0x1004
cmpq %r13, %rsi
jb 0x29dac
movl $0x1000, %r15d          # imm = 0x1000
movl $0x1000, %ebp           # imm = 0x1000
leaq 0x10(%rsp), %r14
movq %r14, %rdi
callq 0x1c190
movq 0x10(%rsp), %rdi
addq %r13, %rdi
movq %rbp, %rsi
callq 0x8300
testq %rax, %rax
jne 0x29e04
testl %r15d, %r15d
js 0x29dac
addl %r15d, %r15d
movq %r13, %rsi
movq %r15, %rbp
addq %r15, %rsi
jae 0x29d7c
leaq 0xf(%rsp), %rsi
movb $0x33, (%rsi)
movq %rbx, %rdi
movl $0x1, %edx
callq 0x28036
movl %eax, %ebx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x29df3
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x8620
jmp 0x29df3
leaq 0x10(%rsp), %rsi
movb $0x33, (%rsi)
movq %rbx, %rdi
movl $0x1, %edx
callq 0x28036
movl %eax, %ebx
movl %ebx, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x10(%rsp), %r15
movq (%r15), %rdi
addq %r13, %rdi
callq 0x8230
movq %rax, %r14
movl %r14d, %esi
addq %r13, %rsi
movq %r15, %rdi
callq 0x1c190
movq 0x10(%rsp), %rax
movl %r14d, -0x4(%rax,%r13)
testl %r12d, %r12d
je 0x29ea5
movl %r12d, %eax
shlq $0x4, %rax
movq %rax, 0x28(%rsp)
xorl %ebp, %ebp
movq 0x30(%rsp), %rax
movq 0x48(%rax), %rax
movq (%rax,%rbp), %r15
movq %r15, %rdi
callq 0x8230
movq %rax, %r13
movq 0x18(%rsp), %r14
subq 0x10(%rsp), %r14
movl %r13d, %r12d
leaq (%r12,%r14), %rsi
addq $0x4, %rsi
leaq 0x10(%rsp), %rdi
callq 0x1c190
movq 0x10(%rsp), %rax
movl %r13d, (%rax,%r14)
movq 0x10(%rsp), %rax
leaq (%rax,%r14), %rdi
addq $0x4, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x84d0
addq $0x10, %rbp
cmpq %rbp, 0x28(%rsp)
jne 0x29e42
leaq 0x10(%rsp), %rsi
movl 0x8(%rsi), %eax
movq (%rsi), %rcx
subl %ecx, %eax
movl %eax, 0x2(%rcx)
movq %rbx, %rdi
callq 0x2acb2
jmp 0x29dc1
jmp 0x29ec8
jmp 0x29ec8
jmp 0x29ec8
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x29ee2
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x8620
movq %rbx, %rdi
callq 0x8ab0