// File: /workspace/github_c_makefile_star2_O3/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
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movq $0x0, 0xe0(%rdi)
movq %rsi, %rdi
callq 0x1f4f0
leaq 0x3c342(%rip), %rdx     # 0x9970f
leaq 0x4(%rsp), %r15
movq %r14, %rdi
movl %eax, %esi
movl $0x2, %ecx
movq %r15, %r8
callq 0x29056
movq %rax, %r14
cmpl $0x0, (%r15)
jle 0x5d8a5
xorl %r12d, %r12d
xorl %esi, %esi
movq (%r14,%r12,8), %r13
cmpl $0x2f, -0x8(%r13)
jb 0x5d476
movl (%r13), %eax
movl $0x5f6e7572, %ecx       # imm = 0x5F6E7572
xorl %ecx, %eax
movl 0x3(%r13), %ecx
movl $0x3a64695f, %edx       # imm = 0x3A64695F
xorl %edx, %ecx
orl %eax, %ecx
jne 0x5d476
movl %esi, %ebp
movq 0x10(%rbx), %rdi
leaq 0x7(%r13), %r15
testq %rdi, %rdi
je 0x5d463
movl $0x28, %edx
movq %r15, %rsi
callq 0x1f340
testl %eax, %eax
movl %ebp, %esi
je 0x5d476
movl $0x2, %edi
leaq 0x420f9(%rip), %rsi     # 0x9f542
movq %rbx, %rdx
leaq 0x41c1b(%rip), %rcx     # 0x9f06e
xorl %eax, %eax
callq 0x5b0ac
movq 0x10(%rbx), %rdi
callq 0x2850d
movl $0x28, %esi
movq %r15, %rdi
callq 0x283f4
movq %rax, 0x10(%rbx)
movl %ebp, %esi
testb $0x1, (%rbx)
jne 0x5d481
movl -0x8(%r13), %eax
jmp 0x5d4a5
movl -0x8(%r13), %eax
cmpl $0x7, %eax
jb 0x5d4f7
movl (%r13), %ecx
movl $0x76616c73, %edx       # imm = 0x76616C73
xorl %edx, %ecx
movzbl 0x4(%r13), %edx
xorl $0x65, %edx
orl %ecx, %edx
je 0x5d6ec
cmpl $0x20, %eax
jb 0x5d4f7
movdqu (%r13), %xmm0
pcmpeqb 0x41908(%rip), %xmm0    # 0x9edc0
movdqu 0xe(%r13), %xmm1
pcmpeqb 0x418ea(%rip), %xmm1    # 0x9edb0
pand %xmm0, %xmm1
pmovmskb %xmm1, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x5d4f7
movl %esi, %ebp
leaq 0x1f(%r13), %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x1fa70
movl %ebp, %esi
imulq $0x3e8, %rax, %rax      # imm = 0x3E8
movq %rax, 0xe0(%rbx)
movq (%r13), %rax
movabsq $0x73616d3a656c6f72, %rcx # imm = 0x73616D3A656C6F72
xorq %rcx, %rax
movq 0x3(%r13), %rcx
movabsq $0x72657473616d3a65, %rdx # imm = 0x72657473616D3A65
xorq %rdx, %rcx
orq %rax, %rcx
je 0x5d6d1
movq (%r13), %rax
movabsq $0x616c733a656c6f72, %rcx # imm = 0x616C733A656C6F72
xorq %rcx, %rax
movzwl 0x8(%r13), %ecx
xorq $0x6576, %rcx           # imm = 0x6576
orq %rax, %rcx
sete %al
cmpl $0x2, %esi
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x5d6d6
movl -0x8(%r13), %ebp
movl $0x2, %esi
cmpl $0xc, %ebp
jb 0x5d6d6
movq (%r13), %rax
movabsq $0x685f72657473616d, %rcx # imm = 0x685F72657473616D
xorq %rcx, %rax
movl 0x8(%r13), %ecx
xorq $0x3a74736f, %rcx       # imm = 0x3A74736F
orq %rax, %rcx
je 0x5d778
movq (%r13), %rax
movabsq $0x705f72657473616d, %rcx # imm = 0x705F72657473616D
xorq %rcx, %rax
movl 0x8(%r13), %ecx
xorq $0x3a74726f, %rcx       # imm = 0x3A74726F
orq %rax, %rcx
jne 0x5d5df
leaq 0xc(%r13), %rdi
callq 0x1f710
movl $0x2, %esi
cmpl %eax, 0x108(%rbx)
je 0x5d5df
movl %eax, 0x108(%rbx)
callq 0x23461
movl $0x2, %esi
movq %rax, 0xb8(%rbx)
movl -0x8(%r13), %ebp
cmpl $0x13, %ebp
jb 0x5d635
movdqu (%r13), %xmm0
pcmpeqb 0x417ee(%rip), %xmm0    # 0x9ede0
movdqu 0x3(%r13), %xmm1
pcmpeqb 0x417d0(%rip), %xmm1    # 0x9edd0
pand %xmm0, %xmm1
pmovmskb %xmm1, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x5d63e
leaq 0x13(%r13), %rdi
leaq 0x386a4(%rip), %rsi     # 0x95cbe
callq 0x1f2e0
movl $0x2, %esi
xorl %ecx, %ecx
testl %eax, %eax
setne %cl
movl %ecx, 0x10c(%rbx)
movl -0x8(%r13), %ebp
cmpl $0xf, %ebp
jb 0x5d6d6
movq (%r13), %rax
movabsq $0x72705f6576616c73, %rcx # imm = 0x72705F6576616C73
xorq %rcx, %rax
movq 0x7(%r13), %rcx
movabsq $0x3a797469726f6972, %rdx # imm = 0x3A797469726F6972
xorq %rdx, %rcx
orq %rax, %rcx
jne 0x5d67d
leaq 0xf(%r13), %rdi
callq 0x1f710
movl $0x2, %esi
movl %eax, 0xe8(%rbx)
movl -0x8(%r13), %ebp
cmpl $0x12, %ebp
jb 0x5d6d6
movdqu (%r13), %xmm0
pcmpeqb 0x41760(%rip), %xmm0    # 0x9edf0
movzwl 0x10(%r13), %eax
movd %eax, %xmm1
pcmpeqb 0x4175f(%rip), %xmm1    # 0x9ee00
pand %xmm0, %xmm1
pmovmskb %xmm1, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x5d6d6
addq $0x12, %r13
movq %r13, %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x1fa00
movl $0x2, %esi
movq %rax, 0x110(%rbx)
jmp 0x5d6d6
movl $0x1, %esi
incq %r12
movslq 0x4(%rsp), %rax
cmpq %rax, %r12
jl 0x5d3f6
jmp 0x5d8a7
movl %esi, (%rsp)
callq 0x1f550
movl (%rsp), %esi
movq (%rax), %rax
movsbq 0x5(%r13), %rcx
testb $0x8, 0x1(%rax,%rcx,2)
je 0x5d47b
movq %r13, %rdi
leaq 0x41e36(%rip), %rsi     # 0x9f54a
callq 0x1f660
testq %rax, %rax
je 0x5d7d8
movq %rax, %rbp
movq %r13, %rdi
leaq 0x41e1f(%rip), %rsi     # 0x9f54e
callq 0x1f660
testq %rax, %rax
je 0x5d89d
movq %rax, %r15
addq $0x3, %rbp
movq %rbp, %rdi
movl $0x2c, %esi
callq 0x1f790
testq %rax, %rax
je 0x5d759
movb $0x0, (%rax)
addq $0x5, %r15
movq %r15, %rdi
movl $0x2c, %esi
callq 0x1f790
testq %rax, %rax
jne 0x5d825
jmp 0x5d828
movq 0x100(%rbx), %r15
testq %r15, %r15
je 0x5d79d
leaq 0xc(%r13), %rdi
movq %r15, %rsi
callq 0x1f2e0
movl $0x2, %esi
testl %eax, %eax
je 0x5d58d
movq %r15, %rdi
callq 0x2850d
leaq 0xc(%r13), %rdi
callq 0x28486
movq %rax, 0x100(%rbx)
callq 0x23461
movl $0x2, %esi
movq %rax, 0xb8(%rbx)
movl -0x8(%r13), %ebp
cmpl $0xc, %ebp
jae 0x5d58d
jmp 0x5d6d6
movq %r13, %rdi
movl $0x3a, %esi
callq 0x1f790
testq %rax, %rax
je 0x5d89d
movq %rax, %rbp
incq %rbp
movq %rbp, %rdi
movl $0x2c, %esi
callq 0x1f790
testq %rax, %rax
je 0x5d89d
movq %rax, %r15
movb $0x0, (%rax)
incq %r15
movq %r15, %rdi
movl $0x2c, %esi
callq 0x1f790
testq %rax, %rax
je 0x5d89d
movb $0x0, (%rax)
movq %r15, %rdi
callq 0x1f710
movq %rbx, %rdi
movq %rbp, %rsi
movl %eax, %edx
callq 0x5be88
testq %rax, %rax
movl (%rsp), %esi
jne 0x5d47b
movq %r15, %rdi
callq 0x1f710
movl 0xd0(%rbx), %r8d
xorl %edi, %edi
movl $0x2, %esi
movq %rbp, %rdx
movl %eax, %ecx
movq %rbx, %r9
callq 0x5bb77
movl (%rsp), %esi
testq %rax, %rax
je 0x5d47b
movl $0x2, %edi
leaq 0x417ed(%rip), %rsi     # 0x9f071
movq %rax, %rdx
leaq 0x417e0(%rip), %rcx     # 0x9f06e
xorl %eax, %eax
callq 0x5b0ac
movl (%rsp), %esi
jmp 0x5d47b
movl (%rsp), %esi
jmp 0x5d6d6
xorl %esi, %esi
movl %esi, %r12d
callq 0x23461
movq %rax, 0xa0(%rbx)
movl 0x4(%rsp), %esi
movq %r14, %rdi
callq 0x2921e
movl %r12d, %esi
cmpl 0xa8(%rbx), %r12d
je 0x5d94b
callq 0x23461
movl %r12d, %edx
movq %rax, 0xb0(%rbx)
movl %r12d, 0xa8(%rbx)
cmpl $0x2, %r12d
jne 0x5d8f9
callq 0x23461
movl %r12d, %edx
movq %rax, 0xb8(%rbx)
movl (%rbx), %eax
movl %eax, %ecx
andl $0x3, %ecx
cmpl %edx, %ecx
leaq 0x41cd2(%rip), %rcx     # 0x9f5db
leaq 0x41cd8(%rip), %rsi     # 0x9f5e8
cmoveq %rcx, %rsi
cmpl $0x1, %edx
leaq 0x3f529(%rip), %r9      # 0x9ce47
leaq 0x3f555(%rip), %rcx     # 0x9ce7a
movq %rcx, %r8
cmoveq %r9, %r8
testb $0x1, %al
cmoveq %rcx, %r9
leaq 0x41cbc(%rip), %rcx     # 0x9f5f5
movl $0x1, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
movl %r12d, %esi
cmpl $0x0, 0x80fa6(%rip)     # 0xde8f8
je 0x5d963
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl (%rbx), %eax
movl %eax, %ecx
shrb %cl
cmpl $0x1, %esi
sete %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x5da26
movq 0xf8(%rbx), %rdi
testb $-0x80, (%rdi)
je 0x5dae7
cmpl $0x4, 0x130(%rdi)
jne 0x5dae7
movq 0x128(%rdi), %rax
movq %rax, 0x18(%rdi)
movl $0x5, 0x130(%rdi)
callq 0x23461
movq 0xf8(%rbx), %rcx
movq %rax, 0x138(%rcx)
callq 0x5c4d7
leaq 0x41c45(%rip), %rsi     # 0x9f610
leaq 0x4169c(%rip), %r14     # 0x9f06e
movl $0x3, %edi
movq %rbx, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x5b0ac
movq 0xf8(%rbx), %rdx
leaq 0x41c2e(%rip), %rsi     # 0x9f620
movl $0x3, %edi
movq %r14, %rcx
xorl %eax, %eax
callq 0x5b0ac
movq 0x20(%rbx), %r8
movq 0xf8(%rbx), %rdi
movq 0x20(%rdi), %rcx
leaq 0x41d38(%rip), %rdx     # 0x9f74f
movl $0x20000, %esi          # imm = 0x20000
callq 0x5bad8
jmp 0x5db68
shrb %al
cmpl $0x2, %esi
sete %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x5db68
movl 0x108(%rbx), %ecx
movq 0xf8(%rbx), %r14
movq 0x20(%r14), %rax
cmpl 0x8(%rax), %ecx
jne 0x5da66
movq 0x100(%rbx), %rdi
movq (%rax), %rsi
callq 0x1f2e0
testl %eax, %eax
je 0x5db68
movq 0x148(%r14), %r15
movq %r14, %rdi
callq 0x5d36a
testl %eax, %eax
je 0x5db68
movq 0x88(%rbx), %r14
movq 0x90(%rbx), %rax
cmpq %r14, %rax
cmovgq %rax, %r14
testq %r14, %r14
je 0x5daa8
callq 0x23461
subq %r14, %rax
cmpq %r15, %rax
jle 0x5db68
callq 0x23461
subq 0xb8(%rbx), %rax
cmpq %r15, %rax
jle 0x5db68
movq 0xf8(%rbx), %rax
movq 0x20(%rax), %rax
movq (%rax), %rsi
movl 0x8(%rax), %edx
movq %rbx, %rdi
callq 0x5dc3b
testl %eax, %eax
jne 0x5db68
leaq 0x41b6b(%rip), %rsi     # 0x9f650
jmp 0x5db52
callq 0x5d36a
testl %eax, %eax
je 0x5db68
movq 0x88(%rbx), %r14
movq 0x90(%rbx), %rax
cmpq %r14, %rax
cmovgq %rax, %r14
testq %r14, %r14
je 0x5db1a
callq 0x23461
subq %r14, %rax
cmpq $0x1f41, %rax           # imm = 0x1F41
jl 0x5db68
callq 0x23461
subq 0xb0(%rbx), %rax
cmpq $0x1f41, %rax           # imm = 0x1F41
jl 0x5db68
movq 0xf8(%rbx), %rax
movq 0x20(%rax), %rax
movq (%rax), %rsi
movl 0x8(%rax), %edx
movq %rbx, %rdi
callq 0x5dc3b
testl %eax, %eax
jne 0x5db68
leaq 0x41aec(%rip), %rsi     # 0x9f63e
leaq 0x41515(%rip), %rcx     # 0x9f06e
movl $0x2, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
movl (%rbx), %ebp
testl $0x600, %ebp            # imm = 0x600
je 0x5d954
movl %ebp, %eax
andl $0x2, %eax
je 0x5d954
cmpl $0x2, %r12d
jne 0x5d954
btl $0x9, %ebp
jae 0x5dbf4
movq 0x100(%rbx), %rdi
testq %rdi, %rdi
je 0x5dbf4
movq 0xf8(%rbx), %rax
movq 0x158(%rax), %rax
movq 0x20(%rax), %r14
movq (%r14), %rsi
callq 0x1f880
testl %eax, %eax
jne 0x5dbf4
movl 0x108(%rbx), %eax
cmpl 0x8(%r14), %eax
jne 0x5dbf4
andl $0xfffff9ff, %ebp       # imm = 0xFFFFF9FF
orl $0x400, %ebp            # imm = 0x400
movl %ebp, (%rbx)
leaq 0x41a86(%rip), %rsi     # 0x9f662
leaq 0x4148b(%rip), %rcx     # 0x9f06e
movl $0x2, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
movl (%rbx), %ebp
btl $0xa, %ebp
jae 0x5d954
cmpl $0x0, 0x10c(%rbx)
jne 0x5d954
andl $0xfffff3ff, %ebp       # imm = 0xFFFFF3FF
orl $0x800, %ebp            # imm = 0x800
movl %ebp, (%rbx)
leaq 0x41a57(%rip), %rsi     # 0x9f677
leaq 0x41447(%rip), %rcx     # 0x9f06e
movl $0x2, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5b0ac
jmp 0x5d954