// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelRefreshInstanceInfo
void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) {
    sds *lines;
    int numlines, j;
    int role = 0;

    /* The following fields must be reset to a given value in the case they
     * are not found at all in the INFO output. */
    // 将该变量重置为 0 ，避免 INFO 回复中无该值的情况
    ri->master_link_down_time = 0;

    /* Process line by line. */
    // 对 INFO 命令的回复进行逐行分析
    lines = sdssplitlen(info,strlen(info),"\r\n",2,&numlines);
    for (j = 0; j < numlines; j++) {
        sentinelRedisInstance *slave;
        sds l = lines[j];

        /* run_id:<40 hex chars>*/
        // 读取并分析 runid
        if (sdslen(l) >= 47 && !memcmp(l,"run_id:",7)) {

            // 新设置 runid
            if (ri->runid == NULL) {
                ri->runid = sdsnewlen(l+7,40);
            } else {
                // RUNID 不同，说明服务器已重启
                if (strncmp(ri->runid,l+7,40) != 0) {
                    sentinelEvent(REDIS_NOTICE,"+reboot",ri,"%@");

                    // 释放旧 ID ，设置新 ID
                    sdsfree(ri->runid);
                    ri->runid = sdsnewlen(l+7,40);
                }
            }
        }

        // 读取从服务器的 ip 和端口号
        /* old versions: slave0:<ip>,<port>,<state>
         * new versions: slave0:ip=127.0.0.1,port=9999,... */
        if ((ri->flags & SRI_MASTER) &&
            sdslen(l) >= 7 &&
            !memcmp(l,"slave",5) && isdigit(l[5]))
        {
            char *ip, *port, *end;

            if (strstr(l,"ip=") == NULL) {
                /* Old format. */
                ip = strchr(l,':'); if (!ip) continue;
                ip++; /* Now ip points to start of ip address. */
                port = strchr(ip,','); if (!port) continue;
                *port = '\0'; /* nul term for easy access. */
                port++; /* Now port points to start of port number. */
                end = strchr(port,','); if (!end) continue;
                *end = '\0'; /* nul term for easy access. */
            } else {
                /* New format. */
                ip = strstr(l,"ip="); if (!ip) continue;
                ip += 3; /* Now ip points to start of ip address. */
                port = strstr(l,"port="); if (!port) continue;
                port += 5; /* Now port points to start of port number. */
                /* Nul term both fields for easy access. */
                end = strchr(ip,','); if (end) *end = '\0';
                end = strchr(port,','); if (end) *end = '\0';
            }

            /* Check if we already have this slave into our table,
             * otherwise add it. */
            // 如果发现有新的从服务器出现，那么为它添加实例
            if (sentinelRedisInstanceLookupSlave(ri,ip,atoi(port)) == NULL) {
                if ((slave = createSentinelRedisInstance(NULL,SRI_SLAVE,ip,
                            atoi(port), ri->quorum, ri)) != NULL)
                {
                    sentinelEvent(REDIS_NOTICE,"+slave",slave,"%@");
                }
            }
        }

        /* master_link_down_since_seconds:<seconds> */
        // 读取主从服务器的断线时长
        // 这个只会在实例是从服务器，并且主从连接断开的情况下出现
        if (sdslen(l) >= 32 &&
            !memcmp(l,"master_link_down_since_seconds",30))
        {
            ri->master_link_down_time = strtoll(l+31,NULL,10)*1000;
        }

        /* role:<role> */
        // 读取实例的角色
        if (!memcmp(l,"role:master",11)) role = SRI_MASTER;
        else if (!memcmp(l,"role:slave",10)) role = SRI_SLAVE;

        // 处理从服务器
        if (role == SRI_SLAVE) {

            /* master_host:<host> */
            // 读入主服务器的 IP
            if (sdslen(l) >= 12 && !memcmp(l,"master_host:",12)) {
                if (ri->slave_master_host == NULL ||
                    strcasecmp(l+12,ri->slave_master_host))
                {
                    sdsfree(ri->slave_master_host);
                    ri->slave_master_host = sdsnew(l+12);
                    ri->slave_conf_change_time = mstime();
                }
            }

            /* master_port:<port> */
            // 读入主服务器的端口号
            if (sdslen(l) >= 12 && !memcmp(l,"master_port:",12)) {
                int slave_master_port = atoi(l+12);

                if (ri->slave_master_port != slave_master_port) {
                    ri->slave_master_port = slave_master_port;
                    ri->slave_conf_change_time = mstime();
                }
            }
            
            /* master_link_status:<status> */
            // 读入主服务器的状态
            if (sdslen(l) >= 19 && !memcmp(l,"master_link_status:",19)) {
                ri->slave_master_link_status =
                    (strcasecmp(l+19,"up") == 0) ?
                    SENTINEL_MASTER_LINK_STATUS_UP :
                    SENTINEL_MASTER_LINK_STATUS_DOWN;
            }

            /* slave_priority:<priority> */
            // 读入从服务器的优先级
            if (sdslen(l) >= 15 && !memcmp(l,"slave_priority:",15))
                ri->slave_priority = atoi(l+15);

            /* slave_repl_offset:<offset> */
            // 读入从服务器的复制偏移量
            if (sdslen(l) >= 18 && !memcmp(l,"slave_repl_offset:",18))
                ri->slave_repl_offset = strtoull(l+18,NULL,10);
        }
    }

    // 更新刷新 INFO 命令回复的时间
    ri->info_refresh = mstime();
    sdsfreesplitres(lines,numlines);

    /* ---------------------------- Acting half -----------------------------
     * Some things will not happen if sentinel.tilt is true, but some will
     * still be processed. 
     *
     * 如果 sentinel 进入了 TILT 模式，那么可能只有一部分动作会被执行
     */

    /* Remember when the role changed. */
    if (role != ri->role_reported) {
        ri->role_reported_time = mstime();
        ri->role_reported = role;
        if (role == SRI_SLAVE) ri->slave_conf_change_time = mstime();
        /* Log the event with +role-change if the new role is coherent or
         * with -role-change if there is a mismatch with the current config. */
        sentinelEvent(REDIS_VERBOSE,
            ((ri->flags & (SRI_MASTER|SRI_SLAVE)) == role) ?
            "+role-change" : "-role-change",
            ri, "%@ new reported role is %s",
            role == SRI_MASTER ? "master" : "slave",
            ri->flags & SRI_MASTER ? "master" : "slave");
    }

    /* None of the following conditions are processed when in tilt mode, so
     * return asap. */
    // 如果 Sentinel 正处于 TILT 模式，那么它不能执行以下的语句。
    if (sentinel.tilt) return;

    /* Handle master -> slave role switch. */
    // 实例被 Sentinel 标识为主服务器，但根据 INFO 命令的回复
    // 这个实例的身份为从服务器
    if ((ri->flags & SRI_MASTER) && role == SRI_SLAVE) {
        /* Nothing to do, but masters claiming to be slaves are
         * considered to be unreachable by Sentinel, so eventually
         * a failover will be triggered. */
        // 如果一个主服务器变为从服务器，那么 Sentinel 将这个主服务器看作是不可用的
    }

    /* Handle slave -> master role switch. */
    // 处理从服务器转变为主服务器的情况
    if ((ri->flags & SRI_SLAVE) && role == SRI_MASTER) {
        /* If this is a promoted slave we can change state to the
         * failover state machine. */

        // 如果这是被选中升级为新主服务器的从服务器
        // 那么更新相关的故障转移属性
        if ((ri->master->flags & SRI_FAILOVER_IN_PROGRESS) &&
            (ri->master->failover_state ==
                SENTINEL_FAILOVER_STATE_WAIT_PROMOTION))
        {
            /* Now that we are sure the slave was reconfigured as a master
             * set the master configuration epoch to the epoch we won the
             * election to perform this failover. This will force the other
             * Sentinels to update their config (assuming there is not
             * a newer one already available). */
            // 这是一个被 Sentinel 发送 SLAVEOF no one 之后由从服务器变为主服务器的实例
            // 将这个新主服务器的配置纪元设置为 Sentinel 赢得领头选举的纪元
            // 这一操作会强制其他 Sentinel 更新它们自己的配置
            // （假设没有一个更新的纪元存在的话）
            // 更新从服务器的主服务器（已下线）的配置纪元
            ri->master->config_epoch = ri->master->failover_epoch;
            // 设置从服务器的主服务器（已下线）的故障转移状态
            // 这个状态会让从服务器开始同步新的主服务器
            ri->master->failover_state = SENTINEL_FAILOVER_STATE_RECONF_SLAVES;
            // 更新从服务器的主服务器（已下线）的故障转移状态变更时间
            ri->master->failover_state_change_time = mstime();
            // 将当前 Sentinel 状态保存到配置文件里面
            sentinelFlushConfig();
            // 发送事件
            sentinelEvent(REDIS_WARNING,"+promoted-slave",ri,"%@");
            sentinelEvent(REDIS_WARNING,"+failover-state-reconf-slaves",
                ri->master,"%@");
            // 执行脚本
            sentinelCallClientReconfScript(ri->master,SENTINEL_LEADER,
                "start",ri->master->addr,ri->addr);

        // 这个实例由从服务器变为了主服务器，并且没有进入 TILT 模式
        // （可能是因为重启造成的，或者之前的下线主服务器重新上线了）
        } else {
            /* A slave turned into a master. We want to force our view and
             * reconfigure as slave. Wait some time after the change before
             * going forward, to receive new configs if any. */
            // 如果一个从服务器变为了主服务器，那么我们会考虑将它变回一个从服务器

            // 将 PUBLISH 命令的发送时间乘以 4 ，给于一定缓冲时间
            mstime_t wait_time = SENTINEL_PUBLISH_PERIOD*4;

            // 如果这个实例的主服务器运作正常
            // 并且实例在一段时间内没有进入过 SDOWN 状态或者 ODOWN 状态
            // 并且实例报告它是主服务器的时间已经超过 wait_time
            if (sentinelMasterLooksSane(ri->master) &&
               sentinelRedisInstanceNoDownFor(ri,wait_time) &&
               mstime() - ri->role_reported_time > wait_time)
            {
                // 重新将实例设置为从服务器
                int retval = sentinelSendSlaveOf(ri,
                        ri->master->addr->ip,
                        ri->master->addr->port);
                
                // 发送事件
                if (retval == REDIS_OK)
                    sentinelEvent(REDIS_NOTICE,"+convert-to-slave",ri,"%@");
            }
        }
    }

    /* Handle slaves replicating to a different master address. */
    // 让从服务器重新复制回正确的主服务器
    if ((ri->flags & SRI_SLAVE) &&
        role == SRI_SLAVE &&
        // 从服务器现在的主服务器地址和 Sentinel 保存的信息不一致
        (ri->slave_master_port != ri->master->addr->port ||
         strcasecmp(ri->slave_master_host,ri->master->addr->ip)))
    {
        mstime_t wait_time = ri->master->failover_timeout;

        /* Make sure the master is sane before reconfiguring this instance
         * into a slave. */
        // 1) 检查实例的主服务器状态是否正常
        // 2) 检查实例在给定时间内是否进入过 SDOWN 或者 ODOWN 状态
        // 3) 检查实例身份变更的时长是否已经超过了指定时长
        // 如果是的话，执行代码。。。
        if (sentinelMasterLooksSane(ri->master) &&
            sentinelRedisInstanceNoDownFor(ri,wait_time) &&
            mstime() - ri->slave_conf_change_time > wait_time)
        {
            // 重新将实例指向原本的主服务器
            int retval = sentinelSendSlaveOf(ri,
                    ri->master->addr->ip,
                    ri->master->addr->port);

            if (retval == REDIS_OK)
                sentinelEvent(REDIS_NOTICE,"+fix-slave-config",ri,"%@");
        }
    }

    /* Detect if the slave that is in the process of being reconfigured
     * changed state. */
    // Sentinel 监视的实例为从服务器，并且已经向它发送 SLAVEOF 命令
    if ((ri->flags & SRI_SLAVE) && role == SRI_SLAVE &&
        (ri->flags & (SRI_RECONF_SENT|SRI_RECONF_INPROG)))
    {
        /* SRI_RECONF_SENT -> SRI_RECONF_INPROG. */
        // 将 SENT 状态改为 INPROG 状态，表示同步正在进行
        if ((ri->flags & SRI_RECONF_SENT) &&
            ri->slave_master_host &&
            strcmp(ri->slave_master_host,
                    ri->master->promoted_slave->addr->ip) == 0 &&
            ri->slave_master_port == ri->master->promoted_slave->addr->port)
        {
            ri->flags &= ~SRI_RECONF_SENT;
            ri->flags |= SRI_RECONF_INPROG;
            sentinelEvent(REDIS_NOTICE,"+slave-reconf-inprog",ri,"%@");
        }

        /* SRI_RECONF_INPROG -> SRI_RECONF_DONE */
        // 将 INPROG 状态改为 DONE 状态，表示同步已完成
        if ((ri->flags & SRI_RECONF_INPROG) &&
            ri->slave_master_link_status == SENTINEL_MASTER_LINK_STATUS_UP)
        {
            ri->flags &= ~SRI_RECONF_INPROG;
            ri->flags |= SRI_RECONF_DONE;
            sentinelEvent(REDIS_NOTICE,"+slave-reconf-done",ri,"%@");
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r14
movq %rdi, %rbx
andq $0x0, 0xe0(%rdi)
movq %rsi, %rdi
callq 0x1f4f0
leaq 0x36e6e(%rip), %rdx     # 0x8f6d3
pushq $0x2
popq %rcx
leaq 0xc(%rsp), %r8
movq %r14, %rdi
movl %eax, %esi
callq 0x27b60
movq %rax, 0x10(%rsp)
pushq $0x2c
popq %r15
xorl %ebp, %ebp
xorl %r12d, %r12d
movslq 0xc(%rsp), %rax
cmpq %rax, %rbp
jge 0x58c8d
movq 0x10(%rsp), %rax
movq (%rax,%rbp,8), %r13
cmpl $0x2f, -0x8(%r13)
jb 0x58908
movq %r13, %rdi
leaq 0x3cc01(%rip), %rsi     # 0x954ae
pushq $0x7
popq %rdx
callq 0x1f6a0
testl %eax, %eax
jne 0x58908
movq 0x10(%rbx), %rdi
leaq 0x7(%r13), %r14
testq %rdi, %rdi
je 0x588f9
movq %r14, %rsi
pushq $0x28
popq %rdx
callq 0x1f340
testl %eax, %eax
je 0x58908
pushq $0x2
popq %rdi
leaq 0x3cbd7(%rip), %rsi     # 0x954b6
movq %rbx, %rdx
leaq 0x3c6f9(%rip), %rcx     # 0x94fe2
xorl %eax, %eax
callq 0x5678f
movq 0x10(%rbx), %rdi
callq 0x271f7
movq %r14, %rdi
pushq $0x28
popq %rsi
callq 0x27158
movq %rax, 0x10(%rbx)
testb $0x1, (%rbx)
jne 0x58913
movl -0x8(%r13), %r14d
jmp 0x58937
movl -0x8(%r13), %r14d
cmpl $0x7, %r14d
jb 0x5896f
movq %r13, %rdi
leaq 0x3a513(%rip), %rsi     # 0x92e3a
pushq $0x5
popq %rdx
callq 0x1f6a0
testl %eax, %eax
je 0x58add
cmpl $0x20, %r14d
jb 0x5896f
movq %r13, %rdi
leaq 0x3cb81(%rip), %rsi     # 0x954c8
pushq $0x1e
popq %rdx
callq 0x1f6a0
testl %eax, %eax
jne 0x5896f
leaq 0x1f(%r13), %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x1fa70
imulq $0x3e8, %rax, %rax      # imm = 0x3E8
movq %rax, 0xe0(%rbx)
movq %r13, %rdi
leaq 0x3cb6e(%rip), %rsi     # 0x954e7
pushq $0xb
popq %rdx
callq 0x1f6a0
pushq $0x1
popq %rcx
testl %eax, %eax
je 0x58c82
movq %r13, %rdi
leaq 0x3cb5d(%rip), %rsi     # 0x954f3
pushq $0xa
popq %rdx
callq 0x1f6a0
testl %eax, %eax
sete %al
cmpl $0x2, %r12d
sete %dl
orb %al, %dl
movl %r12d, %ecx
cmpb $0x1, %dl
jne 0x58c82
movl -0x8(%r13), %r12d
pushq $0x2
popq %rcx
cmpl $0xc, %r12d
jb 0x58c82
movq %r13, %rdi
leaq 0x3cb2b(%rip), %rsi     # 0x954fe
pushq $0xc
popq %rdx
callq 0x1f6a0
testl %eax, %eax
je 0x58b69
movq %r13, %rdi
leaq 0x3cb1e(%rip), %rsi     # 0x9550b
pushq $0xc
popq %rdx
callq 0x1f6a0
testl %eax, %eax
jne 0x58a20
leaq 0xc(%r13), %rdi
callq 0x1f710
cmpl %eax, 0x108(%rbx)
je 0x58a20
movl %eax, 0x108(%rbx)
callq 0x22843
movq %rax, 0xb8(%rbx)
movl -0x8(%r13), %r12d
cmpl $0x13, %r12d
jb 0x58a5d
movq %r13, %rdi
leaq 0x3cae8(%rip), %rsi     # 0x95518
pushq $0x13
popq %rdx
callq 0x1f6a0
testl %eax, %eax
jne 0x58a6a
leaq 0x13(%r13), %rdi
leaq 0x33237(%rip), %rsi     # 0x8bc7e
callq 0x1f2e0
xorl %ecx, %ecx
testl %eax, %eax
setne %cl
movl %ecx, 0x10c(%rbx)
movl -0x8(%r13), %r12d
pushq $0x2
popq %rcx
cmpl $0xf, %r12d
jb 0x58c82
movq %r13, %rdi
leaq 0x3cab8(%rip), %rsi     # 0x9552c
pushq $0xf
popq %rdx
callq 0x1f6a0
testl %eax, %eax
jne 0x58a93
leaq 0xf(%r13), %rdi
callq 0x1f710
movl %eax, 0xe8(%rbx)
movl -0x8(%r13), %r12d
pushq $0x2
popq %rcx
cmpl $0x12, %r12d
jb 0x58c82
movq %r13, %rdi
leaq 0x3ca92(%rip), %rsi     # 0x9553c
pushq $0x12
popq %rdx
callq 0x1f6a0
pushq $0x2
popq %rcx
testl %eax, %eax
jne 0x58c82
addq $0x12, %r13
movq %r13, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x1fa00
movq %rax, 0x110(%rbx)
pushq $0x2
popq %rcx
jmp 0x58c82
callq 0x1f550
movq (%rax), %rax
movsbq 0x5(%r13), %rcx
testb $0x8, 0x1(%rax,%rcx,2)
je 0x5890d
movq %r13, %rdi
leaq 0x3c9bf(%rip), %rsi     # 0x954be
callq 0x1f660
testq %rax, %rax
je 0x58bc3
movq %rax, %r14
movq %r13, %rdi
leaq 0x3c9a8(%rip), %rsi     # 0x954c2
callq 0x1f660
testq %rax, %rax
je 0x58c7f
movq %rax, (%rsp)
addq $0x3, %r14
movq %r14, %rdi
movl %r15d, %esi
callq 0x1f790
testq %rax, %rax
je 0x58b43
movb $0x0, (%rax)
movq (%rsp), %rdi
addq $0x5, %rdi
movq %rdi, (%rsp)
movl %r15d, %esi
callq 0x1f790
testq %rax, %rax
jne 0x58c0b
movq (%rsp), %rcx
jmp 0x58c12
movq 0x100(%rbx), %r14
testq %r14, %r14
je 0x58b89
leaq 0xc(%r13), %rdi
movq %r14, %rsi
callq 0x1f2e0
testl %eax, %eax
je 0x589e3
movq %r14, %rdi
callq 0x271f7
leaq 0xc(%r13), %rdi
callq 0x271cd
movq %rax, 0x100(%rbx)
callq 0x22843
movq %rax, 0xb8(%rbx)
movl -0x8(%r13), %r12d
pushq $0x2
popq %rcx
cmpl $0xc, %r12d
jae 0x589e3
jmp 0x58c82
movq %r13, %rdi
pushq $0x3a
popq %rsi
callq 0x1f790
testq %rax, %rax
je 0x58c7f
movq %rax, %r14
incq %r14
movq %r14, %rdi
movl %r15d, %esi
callq 0x1f790
testq %rax, %rax
je 0x58c7f
movb $0x0, (%rax)
incq %rax
movq %rax, (%rsp)
movq %rax, %rdi
pushq $0x2c
popq %rsi
callq 0x1f790
testq %rax, %rax
je 0x58c7f
movq (%rsp), %rcx
movb $0x0, (%rax)
movq %rcx, %rdi
movq %rcx, (%rsp)
callq 0x1f710
movq %rbx, %rdi
movq %r14, %rsi
movl %eax, %edx
callq 0x57458
testq %rax, %rax
jne 0x5890d
movq (%rsp), %rdi
callq 0x1f710
movl 0xd0(%rbx), %r8d
xorl %edi, %edi
pushq $0x2
popq %rsi
movq %r14, %rdx
movl %eax, %ecx
movq %rbx, %r9
callq 0x5715c
testq %rax, %rax
je 0x5890d
pushq $0x2
popq %rdi
leaq 0x3c37c(%rip), %rsi     # 0x94fe5
movq %rax, %rdx
leaq 0x3c36f(%rip), %rcx     # 0x94fe2
xorl %eax, %eax
callq 0x5678f
jmp 0x5890d
movl %r12d, %ecx
incq %rbp
movl %ecx, %r12d
jmp 0x58885
callq 0x22843
movq %rax, 0xa0(%rbx)
movl 0xc(%rsp), %esi
movq 0x10(%rsp), %rdi
callq 0x27d1e
cmpl 0xa8(%rbx), %r12d
je 0x58d24
callq 0x22843
movq %rax, 0xb0(%rbx)
movl %r12d, 0xa8(%rbx)
cmpl $0x2, %r12d
jne 0x58cd5
callq 0x22843
movq %rax, 0xb8(%rbx)
movl (%rbx), %eax
movl %eax, %ecx
andl $0x3, %ecx
cmpl %r12d, %ecx
leaq 0x3c869(%rip), %rcx     # 0x9554f
leaq 0x3c86f(%rip), %rsi     # 0x9555c
cmoveq %rcx, %rsi
cmpl $0x1, %r12d
leaq 0x3a10b(%rip), %r9      # 0x92e07
leaq 0x3a137(%rip), %rcx     # 0x92e3a
movq %rcx, %r8
cmoveq %r9, %r8
testb $0x1, %al
cmoveq %rcx, %r9
leaq 0x3c852(%rip), %rcx     # 0x95569
pushq $0x1
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
cmpl $0x0, 0x82bcd(%rip)     # 0xdb8f8
je 0x58d3c
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb (%rbx), %al
shrb %al
cmpl $0x1, %r12d
sete %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x58e5e
movq 0xf8(%rbx), %rdi
testb $-0x80, (%rdi)
je 0x58df8
cmpl $0x4, 0x130(%rdi)
jne 0x58df8
movq 0x128(%rdi), %rax
movq %rax, 0x18(%rdi)
movl $0x5, 0x130(%rdi)
callq 0x22843
movq 0xf8(%rbx), %rcx
movq %rax, 0x138(%rcx)
callq 0x57a25
leaq 0x3c7e1(%rip), %rsi     # 0x95584
leaq 0x3c238(%rip), %r14     # 0x94fe2
pushq $0x3
popq %rbp
movl %ebp, %edi
movq %rbx, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x5678f
movq 0xf8(%rbx), %rdx
leaq 0x3c7ca(%rip), %rsi     # 0x95594
movl %ebp, %edi
movq %r14, %rcx
xorl %eax, %eax
callq 0x5678f
movq 0x20(%rbx), %r8
movq 0xf8(%rbx), %rdi
movq 0x20(%rdi), %rcx
leaq 0x3c8d7(%rip), %rdx     # 0x956c3
movl $0x20000, %esi          # imm = 0x20000
callq 0x570b0
jmp 0x58e5e
callq 0x58802
testl %eax, %eax
je 0x58e5e
movl $0x1f40, %esi           # imm = 0x1F40
movq %rbx, %rdi
callq 0x57aa8
testl %eax, %eax
je 0x58e5e
callq 0x22843
subq 0xb0(%rbx), %rax
cmpq $0x1f41, %rax           # imm = 0x1F41
jl 0x58e5e
movq 0xf8(%rbx), %rax
movq 0x20(%rax), %rax
movq (%rax), %rsi
movl 0x8(%rax), %edx
movq %rbx, %rdi
callq 0x58fd6
testl %eax, %eax
jne 0x58e5e
leaq 0x3c768(%rip), %rsi     # 0x955b2
leaq 0x3c191(%rip), %rcx     # 0x94fe2
pushq $0x2
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
cmpl $0x2, %r12d
sete %al
movb (%rbx), %cl
shrb %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x58f08
movl 0x108(%rbx), %ecx
movq 0xf8(%rbx), %r15
movq 0x20(%r15), %rax
cmpl 0x8(%rax), %ecx
jne 0x58e9d
movq 0x100(%rbx), %rdi
movq (%rax), %rsi
callq 0x1f2e0
testl %eax, %eax
je 0x58f08
movq 0x148(%r15), %r14
movq %r15, %rdi
callq 0x58802
testl %eax, %eax
je 0x58f08
movq %rbx, %rdi
movq %r14, %rsi
callq 0x57aa8
testl %eax, %eax
je 0x58f08
callq 0x22843
subq 0xb8(%rbx), %rax
cmpq %r14, %rax
jle 0x58f08
movq 0xf8(%rbx), %rax
movq 0x20(%rax), %rax
movq (%rax), %rsi
movl 0x8(%rax), %edx
movq %rbx, %rdi
callq 0x58fd6
testl %eax, %eax
jne 0x58f08
leaq 0x3c6d0(%rip), %rsi     # 0x955c4
leaq 0x3c0e7(%rip), %rcx     # 0x94fe2
pushq $0x2
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
movl (%rbx), %ebp
testw $0x600, %bp             # imm = 0x600
je 0x58d2d
movl %ebp, %eax
andl $0x2, %eax
je 0x58d2d
cmpl $0x2, %r12d
jne 0x58d2d
btl $0x9, %ebp
jae 0x58f91
movq 0x100(%rbx), %rdi
testq %rdi, %rdi
je 0x58f91
movq 0xf8(%rbx), %rax
movq 0x158(%rax), %rax
movq 0x20(%rax), %r14
movq (%r14), %rsi
callq 0x1f880
testl %eax, %eax
jne 0x58f91
movl 0x108(%rbx), %eax
cmpl 0x8(%r14), %eax
jne 0x58f91
andl $0xfffff9ff, %ebp       # imm = 0xFFFFF9FF
orl $0x400, %ebp            # imm = 0x400
movl %ebp, (%rbx)
leaq 0x3c65b(%rip), %rsi     # 0x955d6
leaq 0x3c060(%rip), %rcx     # 0x94fe2
pushq $0x2
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
movl (%rbx), %ebp
btl $0xa, %ebp
jae 0x58d2d
cmpl $0x0, 0x10c(%rbx)
jne 0x58d2d
andl $0xfffff3ff, %ebp       # imm = 0xFFFFF3FF
orl $0x800, %ebp            # imm = 0x800
movl %ebp, (%rbx)
leaq 0x3c62e(%rip), %rsi     # 0x955eb
leaq 0x3c01e(%rip), %rcx     # 0x94fe2
pushq $0x2
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5678f
jmp 0x58d2d