// File: /workspace/github_cpp_makefile_star2_O2/davmac314[P]dinit/src/dinit.cc
// Function: dinit_main(int, char**)
int dinit_main(int argc, char **argv)
{
    using namespace std;
    
    am_system_mgr = (getpid() == 1);
    am_system_init = (getuid() == 0);
    
    struct options opts;

    // if we are PID 1 and user id 0, we are *most probably* the system init. (Or on linux at least, we
    // could instead be in a container; then we expect -o argument and unset this then).
    opts.process_sys_args = am_system_mgr && am_system_init;

    const char * &env_file = opts.env_file;
    bool &control_socket_path_set = opts.control_socket_path_set;
    bool &env_file_set = opts.env_file_set;
    bool &log_specified = opts.log_specified;
    service_dir_opt &service_dir_opts = opts.service_dir_opts;
    list<const char *> &services_to_start = opts.services_to_start;

    for (int i = 1; i < argc; i++) {
        int p = process_commandline_arg(argv, argc, i, opts);
        if (p == -1) {
            // clean exit
            return 0;
        }
        if (p == 1) {
            // error exit
            return 1;
        }
    }

    if (am_system_mgr) {
        // setup STDIN, STDOUT, STDERR so that we can use them
        int onefd = open("/dev/console", O_RDONLY, 0);
        if (onefd != -1) {
            dup2(onefd, 0);
        }
        int twofd = open("/dev/console", O_RDWR, 0);
        if (twofd != -1) {
            dup2(twofd, 1);
            dup2(twofd, 2);
        }
        
        if (onefd > 2) close(onefd);
        if (twofd > 2) close(twofd);

        if (! env_file_set) {
            env_file = env_file_path;
        }

        // we will assume an empty cgroups root path
        #if SUPPORT_CGROUPS
        have_cgroups_path = true;
        #endif
    }

    /* Set up signal handlers etc */
    sigset_t sigwait_set;
    if (am_system_mgr) {
        // Block all signals in system manager mode - don't want to chance provoking a signal that
        // will suspend or terminate the process
        sigfillset(&sigwait_set);
    }
    else {
        sigemptyset(&sigwait_set);
        sigaddset(&sigwait_set, SIGCHLD);
        sigaddset(&sigwait_set, SIGINT);
        sigaddset(&sigwait_set, SIGTERM);
    }
    sigprocmask(SIG_BLOCK, &sigwait_set, &orig_signal_mask);

    // Terminal access control signals - we ignore these so that dinit can't be
    // suspended if it writes to the terminal after some other process has claimed
    // ownership of it.
    signal(SIGTSTP, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTTOU, SIG_IGN);
    
    signal(SIGPIPE, SIG_IGN);
    
    event_loop.init();

    if (!am_system_init && !control_socket_path_set) {
        const char * rundir = getenv("XDG_RUNTIME_DIR");
        const char * sockname = "dinitctl";
        if (rundir == nullptr) {
            rundir = service_dir_opt::get_user_home();
            sockname = ".dinitctl";
        }
        if (rundir != nullptr) {
            control_socket_str = rundir;
            control_socket_str.push_back('/');
            control_socket_str += sockname;
            control_socket_path = control_socket_str.c_str();
        }
    }
    
    if (services_to_start.empty()) {
        services_to_start.push_back("boot");
    }

    // Set up signal handlers
    callback_signal_handler sigterm_watcher {sigterm_cb};
    callback_signal_handler sigint_watcher;
    callback_signal_handler sigquit_watcher;

    if (am_system_mgr) {
        sigint_watcher.set_cb_func(sigint_reboot_cb);
        sigquit_watcher.set_cb_func(sigquit_cb);
    }
    else {
        sigint_watcher.set_cb_func(sigterm_cb);
    }

    sigint_watcher.add_watch(event_loop, SIGINT);
    sigterm_watcher.add_watch(event_loop, SIGTERM);
    
    if (am_system_mgr) {
        // PID 1: we may ask for console input; SIGQUIT exec's shutdown
        console_input_io.add_watch(event_loop, STDIN_FILENO, dasynq::IN_EVENTS, false);
        sigquit_watcher.add_watch(event_loop, SIGQUIT);
        // (If not PID 1, we instead just let SIGQUIT perform the default action.)
    }

    init_log(log_is_syslog);
    log_flush_timer.add_timer(event_loop, dasynq::clock_type::MONOTONIC);

    #if SUPPORT_CGROUPS
    if (!have_cgroups_path) {
        find_cgroup_path();
        // We will press on if the cgroup root path could not be identified, since services might
        // not require cgroups anyway and/or might only specify absolute cgroups paths.
    }
    #endif

    // Try to open control socket (may fail due to readonly filesystem, we ignore that if we are
    // system init)
    if (!open_control_socket(!am_system_init)) {
        flush_log();
        return EXIT_FAILURE;
    }
    
#ifdef __linux__
    if (am_system_mgr) {
        // Disable non-critical kernel output to console
        klogctl(6 /* SYSLOG_ACTION_CONSOLE_OFF */, nullptr, 0);
        // Make ctrl+alt+del combination send SIGINT to PID 1 (this process)
        reboot(RB_DISABLE_CAD);
    }

    // Mark ourselves as a subreaper. This means that if a process we start double-forks, the
    // orphaned child will re-parent to us rather than to PID 1 (although that could be us too).
    prctl(PR_SET_CHILD_SUBREAPER, 1);
#elif defined(__FreeBSD__) || defined(__DragonFly__)
    // Documentation (man page) for this kind-of sucks. PROC_REAP_ACQUIRE "acquires the reaper status for
    // the current process" but does that mean the first two arguments still need valid values to be
    // supplied? We'll play it safe and explicitly target our own process:
    procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL);
#endif
    
    service_dir_opts.build_paths(am_system_init);

    // Start requested services

    services = new dirload_service_set(std::move(service_dir_opts.get_paths()));

    setup_log_console_handoff(services);

    if (am_system_init) {
        log(loglevel_t::NOTICE, false, "Starting system");
    }
    
    // If a log file was specified, open it now.
    if (log_specified) {
        setup_external_log();
        if (!am_system_init && !external_log_open) {
            flush_log(); // flush console messages
            return EXIT_FAILURE;
        }
    }

    if (env_file != nullptr) {
        read_env_file(env_file, true, main_env, false);
    }

    for (auto svc : services_to_start) {
        try {
            services->start_service(svc);
            // Note in general if we fail to start a service we don't need any special error handling,
            // since we either leave other services running or, if it was the only service, then no
            // services will be running and we will process normally (reboot if system process,
            // exit if user process).
        }
        catch (service_not_found &snf) {
            log(loglevel_t::ERROR, snf.service_name, ": could not find service description.");
        }
        catch (service_description_exc &sde) {
            log_service_load_failure(sde);
        }
        catch (service_load_exc &sle) {
            log(loglevel_t::ERROR, sle.service_name, ": error loading: ", sle.exc_description);
        }
        catch (std::bad_alloc &badalloce) {
            log(loglevel_t::ERROR, "Out of memory when trying to start service: ", svc, ".");
            break;
        }
    }

    // Notify readiness just before the event loop starts (and after services
    // are scheduled to start). If the socket is not ready yet (may be in case
    // of read-only file system), we will report it when it is.
    control_socket_ready();
    
    run_event_loop:
    
    // Process events until all services have terminated.
    while (services->count_active_services() != 0) {
        event_loop.run();
    }

    shutdown_type_t shutdown_type = services->get_shutdown_type();
    if (shutdown_type == shutdown_type_t::REMAIN) {
        goto run_event_loop;
    }
    
    if (am_system_mgr) {
        log_msg_begin(loglevel_t::NOTICE, "No more active services.");
        
        if (shutdown_type == shutdown_type_t::REBOOT) {
            log_msg_end(" Will reboot.");
        }
        if (shutdown_type == shutdown_type_t::SOFTREBOOT) {
            log_msg_end(" Will soft-reboot.");
        }
        else if (shutdown_type == shutdown_type_t::HALT) {
            log_msg_end(" Will halt.");
        }
        else if (shutdown_type == shutdown_type_t::POWEROFF) {
            log_msg_end(" Will power down.");
        }
        else if (shutdown_type == shutdown_type_t::KEXEC) {
            log_msg_end(" Will kexec.");
        }
        else if (shutdown_type == shutdown_type_t::NONE) {
            log_msg_end(" Will handle boot failure.");
        }
    }

    flush_log();
    bool need_log_flush = false;
    close_control_socket();
    
    if (am_system_mgr) {
        if (shutdown_type == shutdown_type_t::SOFTREBOOT) {
            sync(); // Sync to minimise data loss in case soft-boot fails

            execv(dinit_exec, argv);
            log(loglevel_t::ERROR, error_exec_dinit, strerror(errno));

            // if we get here, soft reboot failed; reboot normally
            log(loglevel_t::ERROR, "Could not soft-reboot. Will attempt reboot.");
            shutdown_type = shutdown_type_t::REBOOT;
            need_log_flush = true;
        }

        if (shutdown_type == shutdown_type_t::NONE) {
            // Services all stopped but there was no shutdown issued. Inform user, wait for ack, and
            // re-start boot sequence.
            sync(); // Sync to minimise data loss if user elects to power off / hard reset
            if (auto_recovery) {
                try {
                    services->start_service("recovery");
                }
                catch (std::exception &exc) {
                    log(loglevel_t::ERROR, "Unable to start recovery service: ", exc.what());
                    // As the following prompt UI could be inaccessible flush the log again already
                    flush_log();
                }
            }
            confirm_restart_boot();
            if (services->count_active_services() != 0) {
                // Recovery service started
                goto run_event_loop;
            }
            shutdown_type = services->get_shutdown_type();
            if (shutdown_type == shutdown_type_t::NONE) {
                try {
                    services->start_service("boot");
                    goto run_event_loop; // yes, the "evil" goto
                }
                catch (...) {
                    // Couldn't start boot service, let's reboot the system
                    log(loglevel_t::ERROR, "Could not start 'boot' service. Will attempt reboot.");
                    need_log_flush = true;
                    shutdown_type = shutdown_type_t::REBOOT;
                }
            }
        }
        
        if (need_log_flush) {
            // In case of error since the log was previously flushed, flush again now
            flush_log();
        }

        const char * cmd_arg;
        if (shutdown_type == shutdown_type_t::HALT) {
            cmd_arg = "-h";
        }
        else if (shutdown_type == shutdown_type_t::REBOOT) {
            cmd_arg = "-r";
        }
        else if (shutdown_type == shutdown_type_t::KEXEC) {
            cmd_arg = "-k";
        }
        else {
            // power off.
            cmd_arg = "-p";
        }
        
        // Fork and execute dinit-reboot.
        execl(shutdown_exec.c_str(), shutdown_exec.c_str(), "--system", cmd_arg, nullptr);
        log(loglevel_t::ERROR, error_exec_sd, strerror(errno));
        
        // PID 1 must not actually exit, although we should never reach this point:
        while (true) {
            event_loop.run();
        }
    }
    else if (shutdown_type == shutdown_type_t::REBOOT) {
        // Non-system-process. If we got SIGINT, let's die due to it:
        sigset_t sigwait_set_int;
        sigemptyset(&sigwait_set_int);
        sigaddset(&sigwait_set_int, SIGINT);
        raise(SIGINT);
        sigprocmask(SIG_UNBLOCK, &sigwait_set_int, NULL);
    }
    
    return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x368, %rsp            # imm = 0x368
movq %rsi, 0x8(%rsp)
movl %edi, %r15d
callq 0x8920
cmpl $0x1, %eax
sete 0x3cd4c(%rip)           # 0x45d10
callq 0x82d0
xorl %ecx, %ecx
testl %eax, %eax
sete %cl
sete 0x3cd3a(%rip)           # 0x45d11
leaq 0x28(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
leaq 0x58(%rsp), %rax
andl $0x0, -0x38(%rax)
andq $0x0, -0x40(%rax)
movq %rax, 0x8(%rax)
movq %rax, (%rax)
andq $0x0, 0x10(%rax)
xorl %edx, %edx
cmpb $0x0, 0x3cd03(%rip)     # 0x45d10
cmovel %edx, %ecx
movb %cl, -0x35(%rax)
pushq $0x1
popq %r12
leaq 0x70(%rsp), %r14
leaq 0x2e8(%rsp), %rbx
leaq 0xf0(%rsp), %r13
leaq 0x24421(%rip), %rbp     # 0x2d454
leaq 0x244bf(%rip), %rax     # 0x2d4f9
movq %rax, 0x10(%rsp)
movl %r15d, (%rsp)
movl %r12d, 0x70(%rsp)
cmpl %r15d, %r12d
jge 0x9686
movq 0x8(%rsp), %rcx
movq %rcx, 0xf0(%rsp)
movl %r15d, 0x2e8(%rsp)
movq %r14, 0x240(%rsp)
movq %rbx, 0x248(%rsp)
movq %r13, 0x250(%rsp)
movslq %r12d, %rax
movq (%rcx,%rax,8), %r15
movzbl (%r15), %ecx
cmpl $0x2d, %ecx
je 0x90ca
testl %ecx, %ecx
je 0x97e9
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,8), %r12
cmpb $0x1, 0x23(%rsp)
jne 0x934a
movq %r15, %rdi
leaq 0x249a8(%rip), %rsi     # 0x2da5c
callq 0x8880
testl %eax, %eax
movl (%rsp), %r15d
jne 0x941d
jmp 0x934e
movq %r15, %rdi
leaq 0x241a5(%rip), %rsi     # 0x2d279
callq 0x8880
testl %eax, %eax
je 0x9360
movb 0x1(%r15), %r13b
cmpb $0x65, %r13b
jne 0x90f6
cmpb $0x0, 0x2(%r15)
je 0x9360
movq %r15, %rdi
leaq 0x241b3(%rip), %rsi     # 0x2d2b3
callq 0x8880
testl %eax, %eax
je 0x939e
cmpb $0x64, %r13b
jne 0x911e
cmpb $0x0, 0x2(%r15)
je 0x939e
movq %r15, %rdi
leaq 0x240ad(%rip), %rsi     # 0x2d1d5
callq 0x8880
testl %eax, %eax
je 0x93dc
cmpb $0x73, %r13b
jne 0x9146
cmpb $0x0, 0x2(%r15)
je 0x93dc
movq %r15, %rdi
leaq 0x241a5(%rip), %rsi     # 0x2d2f5
callq 0x8880
testl %eax, %eax
je 0x93e5
cmpb $0x6d, %r13b
jne 0x916e
cmpb $0x0, 0x2(%r15)
je 0x93e5
movq %r15, %rdi
leaq 0x2418a(%rip), %rsi     # 0x2d302
callq 0x8880
testl %eax, %eax
je 0x93f3
cmpb $0x75, %r13b
jne 0x9196
cmpb $0x0, 0x2(%r15)
je 0x93f3
movq %r15, %rdi
leaq 0x24169(%rip), %rsi     # 0x2d309
callq 0x8880
testl %eax, %eax
je 0x93fc
cmpb $0x6f, %r13b
jne 0x91be
cmpb $0x0, 0x2(%r15)
je 0x93fc
movq %r15, %rdi
leaq 0x2414d(%rip), %rsi     # 0x2d315
callq 0x8880
testl %eax, %eax
je 0x940a
cmpb $0x72, %r13b
jne 0x91e6
cmpb $0x0, 0x2(%r15)
je 0x940a
movq %r15, %rdi
leaq 0x24135(%rip), %rsi     # 0x2d325
callq 0x8880
testl %eax, %eax
je 0x942a
cmpb $0x70, %r13b
jne 0x920e
cmpb $0x0, 0x2(%r15)
je 0x942a
movq %r15, %rdi
leaq 0x2414d(%rip), %rsi     # 0x2d365
callq 0x8880
testl %eax, %eax
je 0x9465
cmpb $0x46, %r13b
jne 0x9236
cmpb $0x0, 0x2(%r15)
je 0x9465
movq %r15, %rdi
leaq 0x241d2(%rip), %rsi     # 0x2d412
callq 0x8880
testl %eax, %eax
je 0x9514
cmpb $0x6c, %r13b
jne 0x925e
cmpb $0x0, 0x2(%r15)
je 0x9514
movq %r15, %rdi
leaq 0x241e4(%rip), %rsi     # 0x2d44c
callq 0x8880
testl %eax, %eax
je 0x9556
cmpb $0x71, %r13b
jne 0x9286
cmpb $0x0, 0x2(%r15)
je 0x9556
movq %r15, %rdi
movq %rbp, %rsi
callq 0x8880
testl %eax, %eax
je 0x9573
movq %r15, %rdi
leaq 0x241c1(%rip), %rsi     # 0x2d464
callq 0x8880
testl %eax, %eax
je 0x95bc
movq %r15, %rdi
leaq 0x241b6(%rip), %rsi     # 0x2d470
callq 0x8880
testl %eax, %eax
je 0x9601
cmpb $0x62, %r13b
jne 0x92d8
cmpb $0x0, 0x2(%r15)
je 0x9601
movq %r15, %rdi
leaq 0x241ce(%rip), %rsi     # 0x2d4b0
callq 0x8880
testl %eax, %eax
je 0x964b
cmpb $0x74, %r13b
jne 0x9300
cmpb $0x0, 0x2(%r15)
je 0x964b
movq %r15, %rdi
leaq 0x241de(%rip), %rsi     # 0x2d4e8
callq 0x8880
testl %eax, %eax
je 0x9d4b
movq %r15, %rdi
leaq 0x241d1(%rip), %rsi     # 0x2d4f2
callq 0x8880
testl %eax, %eax
leaq 0xf0(%rsp), %r13
je 0x9d8c
cmpb $0x0, 0x23(%rsp)
movl (%rsp), %r15d
jne 0x941d
jmp 0x9da5
movl (%rsp), %r15d
leaq 0x58(%rsp), %rdi
movq %r12, %rsi
callq 0xc81c
jmp 0x941d
incl %r12d
movl %r12d, 0x70(%rsp)
movl (%rsp), %r15d
cmpl %r15d, %r12d
jge 0x97f2
movslq %r12d, %rax
movq 0x8(%rsp), %rcx
movq (%rcx,%rax,8), %rax
cmpb $0x0, (%rax)
je 0x97f2
movb $0x1, 0x21(%rsp)
movq %rax, 0x18(%rsp)
leaq 0xf0(%rsp), %r13
jmp 0x941d
incl %r12d
movl %r12d, 0x70(%rsp)
movl (%rsp), %r15d
cmpl %r15d, %r12d
jge 0x97fb
movslq %r12d, %rax
movq 0x8(%rsp), %rcx
movq (%rcx,%rax,8), %rsi
cmpb $0x0, (%rsi)
je 0x97fb
leaq 0x28(%rsp), %rdi
callq 0xc80a
leaq 0xf0(%rsp), %r13
jmp 0x941d
movb $0x1, 0x3c92e(%rip)     # 0x45d11
jmp 0x9411
movb $0x1, 0x3c924(%rip)     # 0x45d10
movb $0x0, 0x23(%rsp)
jmp 0x9411
movb $0x0, 0x3c917(%rip)     # 0x45d11
jmp 0x9411
xorl %eax, %eax
movb %al, 0x3c90c(%rip)      # 0x45d10
movb %al, 0x23(%rsp)
jmp 0x9411
movb $0x1, 0x3c90f(%rip)     # 0x45d20
leaq 0xf0(%rsp), %r13
movl (%rsp), %r15d
movl 0x70(%rsp), %r12d
incl %r12d
jmp 0x9043
incl %r12d
movl %r12d, 0x70(%rsp)
movl (%rsp), %r15d
cmpl %r15d, %r12d
jge 0x9cdf
movslq %r12d, %rax
movq 0x8(%rsp), %rcx
movq (%rcx,%rax,8), %rax
cmpb $0x0, (%rax)
je 0x9cdf
movq %rax, 0x3c18d(%rip)     # 0x455e8
movb $0x1, 0x20(%rsp)
jmp 0x9394
incl %r12d
movl %r12d, 0x70(%rsp)
movl (%rsp), %r15d
cmpl %r15d, %r12d
jge 0x9d03
andq $0x0, 0x198(%rsp)
movslq %r12d, %rax
movq 0x8(%rsp), %rcx
movq (%rcx,%rax,8), %rdi
leaq 0x198(%rsp), %rsi
pushq $0xa
popq %rdx
callq 0x81a0
movq 0x198(%rsp), %rcx
movq 0xf0(%rsp), %rdx
movslq 0x70(%rsp), %rsi
cmpq (%rdx,%rsi,8), %rcx
je 0x9ceb
cmpb $0x0, (%rcx)
jne 0x9ceb
movl %eax, 0x3c113(%rip)     # 0x455e0
movl %eax, %edi
pushq $0x1
popq %rsi
xorl %eax, %eax
callq 0x8380
leaq 0xf0(%rsp), %r13
movl 0x3c0f9(%rip), %edi     # 0x455e0
testl %edi, %edi
je 0x9d1b
testl %eax, %eax
js 0x9d1b
cmpl $0x3, %edi
jl 0x941d
orl $0x1, %eax
pushq $0x2
popq %rsi
movl %eax, %edx
xorl %eax, %eax
callq 0x8380
jmp 0x941d
incl %r12d
movl %r12d, 0x70(%rsp)
movl (%rsp), %r15d
cmpl %r15d, %r12d
jge 0x9d0f
movslq %r12d, %rax
movq 0x8(%rsp), %rcx
movq (%rcx,%rax,8), %rax
cmpb $0x0, (%rax)
je 0x9d0f
movq %rax, 0x3c0ab(%rip)     # 0x455f0
movb $0x1, %al
movb %al, 0x3c7c5(%rip)      # 0x45d12
movb %al, 0x22(%rsp)
jmp 0x9394
leaq 0x3c173(%rip), %rax     # 0x456d0
movb $0x0, (%rax)
leaq 0x3c161(%rip), %rax     # 0x456c8
movl $0x4, 0x4(%rax)
jmp 0x9411
leaq 0x240(%rsp), %rdi
leaq 0x23ed2(%rip), %rbp     # 0x2d454
movq %rbp, %rsi
leaq 0x198(%rsp), %rdx
callq 0xaae6
leaq 0xf0(%rsp), %r13
movl (%rsp), %r15d
testb %al, %al
je 0x980e
movl 0x198(%rsp), %eax
leaq 0x3c114(%rip), %rcx     # 0x456c8
movl %eax, 0x4(%rcx)
jmp 0x941d
leaq 0x240(%rsp), %rdi
leaq 0x23e99(%rip), %rsi     # 0x2d464
leaq 0x198(%rsp), %rdx
callq 0xaae6
leaq 0xf0(%rsp), %r13
movl (%rsp), %r15d
testb %al, %al
je 0x980e
movl 0x198(%rsp), %eax
leaq 0x3c0ce(%rip), %rcx     # 0x456c8
movl %eax, (%rcx)
jmp 0x941d
incl %r12d
movl %r12d, 0x70(%rsp)
movl (%rsp), %r15d
cmpl %r15d, %r12d
jge 0x9d33
movslq %r12d, %rax
movq 0x8(%rsp), %rcx
movq (%rcx,%rax,8), %rsi
cmpb $0x0, (%rsi)
leaq 0xf0(%rsp), %r13
je 0x9d33
leaq 0x3c606(%rip), %rdi     # 0x45c40
callq 0x8b30
movb $0x1, 0x3c61a(%rip)     # 0x45c60
jmp 0x941d
incl %r12d
movl %r12d, 0x70(%rsp)
movl (%rsp), %r15d
cmpl %r15d, %r12d
jge 0x9d3f
movslq %r12d, %rax
movq 0x8(%rsp), %rdx
movq (%rdx,%rax,8), %rcx
cmpb $0x0, (%rcx)
leaq 0xf0(%rsp), %r13
je 0x9d3f
leaq (%rdx,%rax,8), %r12
jmp 0x934e
movb 0x3c684(%rip), %al      # 0x45d10
cmpb $0x1, %al
jne 0x9721
leaq 0x23989(%rip), %rdi     # 0x2d024
xorl %esi, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x8450
movl %eax, %ebp
cmpl $-0x1, %eax
je 0x96b6
movl %ebp, %edi
xorl %esi, %esi
callq 0x8590
leaq 0x23967(%rip), %rdi     # 0x2d024
pushq $0x2
popq %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x8450
movl %eax, %r15d
cmpl $-0x1, %eax
je 0x96e7
pushq $0x1
popq %rsi
movl %r15d, %edi
callq 0x8590
pushq $0x2
popq %rsi
movl %r15d, %edi
callq 0x8590
cmpl $0x3, %ebp
jl 0x96f3
movl %ebp, %edi
callq 0x8b50
cmpl $0x3, %r15d
jl 0x9701
movl %r15d, %edi
callq 0x8b50
cmpb $0x0, 0x21(%rsp)
jne 0x9714
leaq 0x24444(%rip), %rax     # 0x2db53
movq %rax, 0x18(%rsp)
movb $0x1, 0x3c545(%rip)     # 0x45c60
movb 0x3c5ef(%rip), %al      # 0x45d10
testb $0x1, %al
je 0x9734
leaq 0x2e8(%rsp), %rdi
callq 0x8190
jmp 0x9765
leaq 0x2e8(%rsp), %r15
movq %r15, %rdi
callq 0x8760
pushq $0x11
popq %rsi
movq %r15, %rdi
callq 0x8960
pushq $0x2
popq %rsi
movq %r15, %rdi
callq 0x8960
pushq $0xf
popq %rsi
movq %r15, %rdi
callq 0x8960
leaq 0x3c434(%rip), %rdx     # 0x45ba0
leaq 0x2e8(%rsp), %rsi
xorl %edi, %edi
callq 0x8280
pushq $0x14
popq %rdi
pushq $0x1
popq %r15
movq %r15, %rsi
callq 0x8700
pushq $0x15
popq %rdi
movq %r15, %rsi
callq 0x8700
pushq $0x16
popq %rdi
movq %r15, %rsi
callq 0x8700
pushq $0xd
popq %rdi
movq %r15, %rsi
callq 0x8700
leaq 0x3c27e(%rip), %rdi     # 0x45a30
callq 0xd79e
cmpb $0x0, 0x3c553(%rip)     # 0x45d11
jne 0x9863
cmpb $0x0, 0x20(%rsp)
jne 0x9863
leaq 0x2385b(%rip), %rdi     # 0x2d031
callq 0x8720
testq %rax, %rax
je 0x9817
leaq 0x2385b(%rip), %r15     # 0x2d042
jmp 0x9828
leaq 0x24241(%rip), %rsi     # 0x2da31
jmp 0x9802
leaq 0x23a8b(%rip), %rsi     # 0x2d284
jmp 0x9802
leaq 0x23ac0(%rip), %rsi     # 0x2d2c2
movq 0x3b7df(%rip), %rdi     # 0x44fe8
callq 0x85d0
pushq $0x1
popq %r14
jmp 0x9c2c
callq 0x2a388
testq %rax, %rax
je 0x9863
leaq 0x23819(%rip), %r15     # 0x2d041
leaq 0x3c3f1(%rip), %rdi     # 0x45c20
movq %rax, %rsi
callq 0x8b30
leaq 0x3c3e2(%rip), %rdi     # 0x45c20
pushq $0x2f
popq %rsi
callq 0x8510
leaq 0x3c3d3(%rip), %rdi     # 0x45c20
movq %r15, %rsi
callq 0x8b20
movq 0x3c3c4(%rip), %rax     # 0x45c20
movq %rax, 0x3bd85(%rip)     # 0x455e8
leaq 0x58(%rsp), %rax
cmpq %rax, 0x58(%rsp)
jne 0x988b
leaq 0x237d5(%rip), %rax     # 0x2d04b
leaq 0x240(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x58(%rsp), %rdi
callq 0xad2a
andl $0x0, 0x248(%rsp)
leaq 0x3a75e(%rip), %rax     # 0x43ff8
movq %rax, 0x240(%rsp)
leaq 0xa43(%rip), %rcx       # 0xa2ec
movq %rcx, 0x2e0(%rsp)
leaq 0xf0(%rsp), %rdi
andl $0x0, 0x8(%rdi)
movq %rax, (%rdi)
andl $0x0, 0x1a0(%rsp)
movq %rax, 0x198(%rsp)
xorl %eax, %eax
cmpb $0x0, 0x3c437(%rip)     # 0x45d10
leaq 0xa2a(%rip), %rdx       # 0xa30a
cmovneq %rdx, %rax
movq %rax, 0x238(%rsp)
leaq 0xa08(%rip), %rax       # 0xa2fb
cmoveq %rcx, %rax
movq %rax, 0xa0(%rdi)
leaq 0x3c12b(%rip), %rsi     # 0x45a30
pushq $0x2
popq %rdx
pushq $0x32
popq %rcx
callq 0xad36
leaq 0x3c119(%rip), %rsi     # 0x45a30
leaq 0x240(%rsp), %rdi
pushq $0xf
popq %rdx
pushq $0x32
popq %rcx
callq 0xad36
cmpb $0x1, 0x3c3df(%rip)     # 0x45d10
jne 0x996c
leaq 0x3c356(%rip), %rdi     # 0x45c90
leaq 0x3c0ef(%rip), %rsi     # 0x45a30
pushq $0x1
popq %rcx
pushq $0x32
popq %r9
xorl %edx, %edx
xorl %r8d, %r8d
callq 0xad4e
leaq 0x3c0d7(%rip), %rsi     # 0x45a30
leaq 0x198(%rsp), %rdi
pushq $0x3
popq %rdx
pushq $0x32
popq %rcx
callq 0xad36
movzbl 0x3c39f(%rip), %edi     # 0x45d12
xorl $0x1, %edi
callq 0x28b7c
leaq 0x3c336(%rip), %rdi     # 0x45cb8
leaq 0x3c0a7(%rip), %rsi     # 0x45a30
pushq $0x1
popq %r14
pushq $0x32
popq %rcx
movl %r14d, %edx
callq 0xad6e
cmpb $0x0, 0x3c2c1(%rip)     # 0x45c60
jne 0x9aa1
leaq 0x24451(%rip), %rdi     # 0x2ddfd
xorl %esi, %esi
xorl %eax, %eax
callq 0x8450
movl %eax, %ebx
cmpl $-0x1, %eax
je 0x9aa1
leaq 0x70(%rsp), %rdi
pushq $0x40
popq %rbp
leaq 0x7(%rsp), %rdx
movq %rbp, %rsi
callq 0xd552
xorl %r14d, %r14d
pushq $-0x1
popq %r13
xorl %r12d, %r12d
xorl %r15d, %r15d
movq 0x70(%rsp), %rsi
addq %r15, %rsi
movq %rbp, %rdx
subq %r15, %rdx
movl %ebx, %edi
callq 0x88e0
cmpq $-0x1, %rax
je 0x9c4b
testq %rax, %rax
je 0x9c5b
movq %rbp, %r8
movq 0x70(%rsp), %rcx
movq %rax, %rdx
movq %r15, %rsi
movq %r13, %rbp
subq $0x1, %rdx
jb 0x9a4f
movb (%rcx,%rsi), %dil
cmpb $0xa, %dil
jne 0x9a30
movq %rsi, %rbp
jmp 0x9a4a
cmpq $-0x1, %rbp
jne 0x9a7d
cmpb $0x3a, %dil
jne 0x9a47
incq %r14
cmpq $0x2, %r14
cmoveq %rsi, %r12
movq %r13, %rbp
incq %rsi
jmp 0x9a1b
cmpq $-0x1, %rbp
jne 0x9c61
addq %rax, %r15
movq %r8, %rbp
cmpq %r8, %r15
jne 0x99e2
addq %rbp, %rbp
leaq 0x70(%rsp), %rdi
movq %rbp, %rsi
callq 0xd58e
jmp 0x99e2
leaq 0x2438b(%rip), %rsi     # 0x2de0f
pushq $0x2
popq %rdi
callq 0x28d42
movl %ebx, %edi
pushq $0x1
popq %r14
callq 0x8b50
leaq 0x70(%rsp), %rdi
callq 0xd5d0
movzbl 0x3c269(%rip), %edi     # 0x45d11
xorl $0x1, %edi
callq 0xa347
testb %al, %al
je 0x9c27
cmpb $0x1, 0x3c251(%rip)     # 0x45d10
jne 0x9ad4
pushq $0x6
popq %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x8b70
xorl %edi, %edi
callq 0x8500
pushq $0x24
popq %rdi
pushq $0x1
popq %r14
movl %r14d, %esi
xorl %eax, %eax
callq 0x87d0
movzbl 0x3c225(%rip), %esi     # 0x45d11
leaq 0x28(%rsp), %rdi
callq 0x2a3d8
pushq $0x60
popq %rdi
callq 0x85f0
movq %rax, %r12
leaq 0x40(%rsp), %rsi
movq %rax, %rdi
callq 0xad8a
movq %r12, 0x3c203(%rip)     # 0x45d18
movq %r12, %rdi
callq 0x28c6b
cmpb $0x1, 0x3c1ed(%rip)     # 0x45d11
jne 0x9b37
leaq 0x23523(%rip), %rdx     # 0x2d050
pushq $0x1
popq %rdi
xorl %esi, %esi
callq 0x28e05
cmpb $0x1, 0x22(%rsp)
jne 0x9b59
callq 0xa657
cmpb $0x0, 0x3c1c7(%rip)     # 0x45d11
jne 0x9b59
cmpb $0x0, 0x3c045(%rip)     # 0x45b98
je 0x9c27
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x9b74
leaq 0x3e2a6(%rip), %rdx     # 0x47e10
pushq $0x1
popq %rsi
xorl %ecx, %ecx
callq 0x2b120
leaq 0x23524(%rip), %r15     # 0x2d09f
leaq 0x2350b(%rip), %r12     # 0x2d08d
leaq 0x58(%rsp), %r14
movq (%r14), %r14
leaq 0x58(%rsp), %rax
cmpq %rax, %r14
je 0x9e17
movq 0x10(%r14), %rbp
movq 0x3c175(%rip), %rdi     # 0x45d18
movq %rbp, %rsi
callq 0xadca
jmp 0x9b87
movq %rax, %r13
cmpl $0x5, %edx
jne 0x9bd4
movq %r13, %rdi
callq 0x8200
movq %rax, %rdi
callq 0xad04
movq %r15, %rdi
callq 0x28f31
callq 0x8a40
jmp 0x9b87
cmpl $0x4, %edx
jne 0x9bf0
movq %r13, %rdi
callq 0x8200
movq %rax, %rdi
callq 0xade0
callq 0x8a40
jmp 0x9b87
cmpl $0x3, %edx
jne 0x9dde
movq %r13, %rdi
callq 0x8200
leaq 0x20(%rax), %r13
movq %rax, %rdi
callq 0xad04
movq %r12, %rdi
callq 0x28f17
movq %r13, %rdi
callq 0xacf4
callq 0x8a40
jmp 0x9b87
callq 0xa5fb
leaq 0x18(%rsp), %rdi
callq 0xaf36
movl %r14d, %eax
addq $0x368, %rsp            # imm = 0x368
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %ebx, %edi
pushq $0x1
popq %r14
callq 0x8b50
jmp 0x9a97
incq %r15
movq %r15, %rbp
movl %ebx, %edi
callq 0x8b50
cmpq $0x2, %r14
jb 0x9cc7
movq %rbp, %rax
subq %r12, %rax
cmpq $0x1, %rax
je 0x9cc7
movq 0x70(%rsp), %rax
cmpb $0x2f, 0x1(%rax,%r12)
jne 0x9cc7
andq $0x0, 0x3bfb9(%rip)     # 0x45c48
leaq 0x3bfaa(%rip), %rdi     # 0x45c40
movq 0x3bfa3(%rip), %rax     # 0x45c40
movb $0x0, (%rax)
addq $0x2, %r12
subq %r12, %rbp
addq 0x70(%rsp), %r12
movq %r12, %rsi
movq %rbp, %rdx
pushq $0x1
popq %r14
callq 0x8070
movb $0x1, 0x3bf9e(%rip)     # 0x45c60
jmp 0x9a97
leaq 0x24178(%rip), %rsi     # 0x2de46
pushq $0x2
popq %rdi
callq 0x28d42
pushq $0x1
popq %r14
jmp 0x9a97
leaq 0x2364d(%rip), %rsi     # 0x2d333
jmp 0x9802
movq 0x3b2f6(%rip), %rdi     # 0x44fe8
leaq 0x23677(%rip), %rsi     # 0x2d370
callq 0x85d0
jmp 0x980e
leaq 0x236d9(%rip), %rsi     # 0x2d3e3
jmp 0x9802
leaq 0x23707(%rip), %rsi     # 0x2d41d
jmp 0x9802
movq 0x3b2c6(%rip), %rdi     # 0x44fe8
leaq 0x2367f(%rip), %rsi     # 0x2d3a8
callq 0x85d0
jmp 0x980e
leaq 0x23744(%rip), %rsi     # 0x2d47e
jmp 0x9802
leaq 0x23774(%rip), %rsi     # 0x2d4ba
jmp 0x9802
movq 0x3b21e(%rip), %rdi     # 0x44f70
leaq 0x23da4(%rip), %rsi     # 0x2dafd
callq 0x85d0
leaq 0x24429(%rip), %rsi     # 0x2e18e
movq %rax, %rdi
callq 0x85d0
pushq $0x2e
popq %rsi
movq %rax, %rdi
callq 0x86d0
movq %rax, %rdi
callq 0x82b0
leaq 0x23d85(%rip), %rax     # 0x2db0c
movq %rax, 0x10(%rsp)
movq 0x3b1dd(%rip), %rdi     # 0x44f70
movq 0x10(%rsp), %rsi
callq 0x85d0
xorl %r14d, %r14d
jmp 0x9c2c
movq 0x3b23c(%rip), %rdi     # 0x44fe8
leaq 0x23c61(%rip), %rsi     # 0x2da14
callq 0x85d0
movq 0xf0(%rsp), %rcx
movslq 0x70(%rsp), %rdx
movq (%rcx,%rdx,8), %rsi
movq %rax, %rdi
callq 0x85d0
movq %rax, %rdi
callq 0x82b0
jmp 0x980e
cmpl $0x2, %edx
jne 0xa2da
movq %r13, %rdi
callq 0x8200
leaq 0x2326a(%rip), %rsi     # 0x2d060
pushq $0x3
popq %rdi
callq 0x28e0a
movq %rbp, %rdi
callq 0x28f17
leaq 0x24cc5(%rip), %rdi     # 0x2ead2
callq 0x28f31
callq 0x8a40
callq 0xa830
leaq 0x24441(%rip), %rbx     # 0x2e264
movq 0x3b146(%rip), %r12     # 0x44f70
leaq 0x70(%rsp), %r14
leaq 0x3bbfa(%rip), %r15     # 0x45a30
pushq $-0x1
popq %rbp
movq 0x3bed8(%rip), %rax     # 0x45d18
cmpl $0x0, 0x8(%rax)
je 0x9e52
movq %r15, %rdi
movl %ebp, %esi
callq 0xaec6
jmp 0x9e39
movzbl 0x29(%rax), %r13d
cmpq $0x1, %r13
je 0x9e39
cmpb $0x1, 0x3beac(%rip)     # 0x45d10
jne 0x9e93
pushq $0x1
popq %rdi
leaq 0x23255(%rip), %rsi     # 0x2d0c5
callq 0x28e0a
cmpb $0x6, %r13b
ja 0x9e93
movzbl %r13b, %eax
pushq $0x7d
popq %rcx
btl %eax, %ecx
jae 0x9e93
movslq (%rbx,%r13,4), %rdi
addq %rbx, %rdi
callq 0x28f31
callq 0xa5fb
callq 0xa88d
cmpb $0x1, 0x3be6c(%rip)     # 0x45d10
jne 0xa16b
testl %r13d, %r13d
jne 0xa0ed
callq 0x85b0
cmpb $0x1, 0x3be61(%rip)     # 0x45d20
jne 0x9ed4
movq 0x3be50(%rip), %rdi     # 0x45d18
leaq 0x25128(%rip), %rsi     # 0x2eff7
callq 0xadca
movq %r12, %rdi
leaq 0x23d26(%rip), %rsi     # 0x2dc04
callq 0x85d0
xorl %edi, %edi
movq %r14, %rsi
callq 0x8690
testl %eax, %eax
je 0x9f1c
movq %r12, %rdi
leaq 0x23d4b(%rip), %rsi     # 0x2dc46
callq 0x85d0
movq %rax, %rdi
callq 0x82b0
movq 0x3be09(%rip), %rdi     # 0x45d18
pushq $0x2
popq %rsi
callq 0xcf1a
jmp 0xa078
andb $-0x3, 0x7c(%rsp)
xorl %edi, %edi
pushq $0x2
popq %rsi
movq %r14, %rdx
callq 0x87a0
xorl %edi, %edi
pushq $0x3
popq %rsi
xorl %eax, %eax
callq 0x8380
movl %eax, %r13d
movl %eax, %edx
orl $0x800, %edx            # imm = 0x800
xorl %edi, %edi
pushq $0x4
popq %rsi
xorl %eax, %eax
callq 0x8380
movq %r12, %rdi
leaq 0x23cf4(%rip), %rsi     # 0x2dc4f
callq 0x85d0
movq %rax, %rdi
callq 0x8410
leaq 0x3bd21(%rip), %rdi     # 0x45c90
movq %r15, %rsi
pushq $0x1
popq %rdx
callq 0xcf5c
movq %r15, %rdi
movl %ebp, %esi
callq 0xaec6
cmpb $0x0, 0x3bd97(%rip)     # 0x45d22
jne 0x9f9a
movq 0x3bd84(%rip), %rax     # 0x45d18
cmpb $0x0, 0x29(%rax)
je 0x9f7a
leaq 0x3bcef(%rip), %rdi     # 0x45c90
movq %r15, %rsi
xorl %edx, %edx
callq 0xcf5c
cmpb $0x1, 0x3bd70(%rip)     # 0x45d22
jne 0xa058
movb $0x0, 0x3bd63(%rip)     # 0x45d22
xorl %edi, %edi
leaq 0x7(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x88e0
cmpl $0x1, %eax
jne 0xa04f
movq %r12, %rdi
leaq 0x23b06(%rip), %rsi     # 0x2dae3
callq 0x85d0
movzbl 0x7(%rsp), %eax
andl $-0x21, %eax
cmpl $0x45, %eax
je 0xa004
cmpl $0x50, %eax
je 0xa03a
cmpl $0x52, %eax
je 0xa03e
cmpl $0x53, %eax
jne 0x9f51
jmp 0xa04f
movq 0x3bd0d(%rip), %rdi     # 0x45d18
leaq 0x24fe5(%rip), %rsi     # 0x2eff7
callq 0xadca
jmp 0xa04f
movq %rax, %rdi
callq 0x8200
movq %r12, %rdi
leaq 0x23c69(%rip), %rsi     # 0x2dc94
callq 0x85d0
callq 0x8a40
jmp 0x9f51
movb $0x3, %al
jmp 0xa040
movb $0x4, %al
movq 0x3bcd1(%rip), %rdi     # 0x45d18
movzbl %al, %esi
callq 0xcf1a
xorl %edi, %edi
xorl %esi, %esi
callq 0x8950
orb $0x2, 0x7c(%rsp)
xorl %edi, %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x87a0
xorl %edi, %edi
pushq $0x4
popq %rsi
movl %r13d, %edx
xorl %eax, %eax
callq 0x8380
movq 0x3bc99(%rip), %rdi     # 0x45d18
cmpl $0x0, 0x8(%rdi)
jne 0x9e39
movb 0x29(%rdi), %r13b
testb %r13b, %r13b
jne 0xa14d
leaq 0x22fae(%rip), %rsi     # 0x2d04b
callq 0xadca
jmp 0x9e39
movq %rax, %r13
cmpl $0x6, %edx
jne 0xa2da
movq %r13, %rdi
callq 0x8200
movq (%rax), %rcx
movq %rax, %rdi
callq *0x10(%rcx)
movq %rax, %r13
pushq $0x3
popq %rdi
leaq 0x230a0(%rip), %rsi     # 0x2d171
callq 0x28e0a
movq %r13, %rdi
callq 0x28f31
callq 0xa5fb
callq 0x8a40
jmp 0x9ed4
cmpl $0x5, %r13d
jne 0xa14d
callq 0x85b0
leaq 0x23e21(%rip), %rdi     # 0x2df20
movq 0x8(%rsp), %rsi
callq 0x8570
callq 0x8040
movl (%rax), %edi
callq 0x81c0
movq %rax, %rbx
leaq 0x23e0d(%rip), %rsi     # 0x2df2c
pushq $0x3
popq %rbp
movl %ebp, %edi
callq 0x28e0a
movq %rbx, %rdi
callq 0x28f31
leaq 0x2300d(%rip), %rsi     # 0x2d145
movl %ebp, %edi
callq 0x28d42
callq 0xa5fb
leaq 0x23081(%rip), %rcx     # 0x2d1cc
jmp 0xa1b5
addb $-0x2, %r13b
cmpb $0x4, %r13b
ja 0xa1ae
movzbl %r13b, %eax
leaq 0x2411e(%rip), %rdx     # 0x2e280
movslq (%rdx,%rax,4), %rcx
addq %rdx, %rcx
jmp 0xa1b5
xorl %r14d, %r14d
cmpb $0x4, %r13b
jne 0x9c2c
leaq 0x70(%rsp), %rbx
movq %rbx, %rdi
callq 0x8760
pushq $0x2
popq %rbp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x8960
movl %ebp, %edi
callq 0x8600
xorl %r14d, %r14d
pushq $0x1
popq %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x8280
jmp 0x9c2c
leaq 0x2301d(%rip), %rcx     # 0x2d1d2
leaq 0x23d8e(%rip), %rdi     # 0x2df4a
leaq 0x23012(%rip), %rdx     # 0x2d1d5
movq %rdi, %rsi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x8740
callq 0x8040
movl (%rax), %edi
callq 0x81c0
leaq 0x70(%rsp), %rdi
movq %rax, (%rdi)
callq 0xa8d4
leaq 0x3b840(%rip), %rbx     # 0x45a30
pushq $-0x1
popq %rbp
movq %rbx, %rdi
movl %ebp, %esi
callq 0xaec6
jmp 0xa1f3
jmp 0xa2d7
jmp 0xa2d7
jmp 0xa2d7
jmp 0xa2d7
movq %rax, %r13
callq 0x8a40
jmp 0xa2da
jmp 0xa2cf
jmp 0xa2d7
movq %rdx, %r13
movq %rax, %r12
pushq $-0x1
popq %rbx
jmp 0xa25a
jmp 0xa254
jmp 0xa254
jmp 0xa254
jmp 0xa254
movq %rdx, %r13
movq %rax, %r12
jmp 0xa264
jmp 0xa2d7
jmp 0xa2d7
jmp 0xa2d7
movq %rdx, %r13
movq %rax, %r12
leaq 0x70(%rsp), %rdi
callq 0xd5d0
movq %r12, %rdi
cmpl $0x2, %r13d
jne 0xa29b
callq 0x8200
cmpl $-0x1, %ebx
pushq $0x1
popq %r14
je 0xa282
movl %ebx, %edi
callq 0x8b50
leaq 0x23be2(%rip), %rsi     # 0x2de6b
pushq $0x2
popq %rdi
callq 0x28d42
callq 0x8a40
jmp 0x9aa1
callq 0xaebb
jmp 0xa2cf
jmp 0xa2d7
jmp 0xa2d7
jmp 0xa2d7
movq %rax, %rdi
callq 0x8200
leaq 0x22edd(%rip), %rsi     # 0x2d194
pushq $0x3
popq %rdi
callq 0x28d42
callq 0x8a40
jmp 0xa13f
jmp 0xa2d7
jmp 0xa2d7
jmp 0xa2cf
movq %rax, %rdi
callq 0xaebb
movq %rax, %r13
leaq 0x18(%rsp), %rdi
callq 0xaf36
movq %r13, %rdi
callq 0x8a90