original_code:
struct TLSProtocol *
tls_data_set_list(struct TLSProtocol *tls_data, int alpn, const char** list, size_t list_len) {
    if (alpn) {
        tls_data->alpn_protocol_list = list;
        tls_data->alpn_list_len = list_len;
        tls_data->match_mode.tls_match_alpn = 1;
    } else {
        tls_data->sni_hostname_list = list;
        tls_data->sni_list_len = list_len;
        tls_data->match_mode.tls_match_sni = 1;
    }
    return tls_data;
}

canonical_original_code:
struct TLSProtocol *tls_data_set_list(struct TLSProtocol *tls_data, int alpn, char **list, unsigned long list_len) {
    if (alpn) {
        tls_data->alpn_protocol_list = list;
        tls_data->alpn_list_len = list_len;
        tls_data->match_mode.tls_match_alpn = 1;
    } else {
        tls_data->sni_hostname_list = list;
        tls_data->sni_list_len = list_len;
        tls_data->match_mode.tls_match_sni = 1;
    }
    return tls_data;
}

variable_types: alpn int


repo: yrutschle/sslh

decompiled_code:
void tcp_protocol_list_init()
{
__int64 v0; // r12
unsigned __int64 v1; // rbp
__int64 v2; // r13
size_t v3; // rbx

if ( cfg[22] )
{
v0 = 0LL;
v1 = 0LL;
do
{
v2 = cfg[23] + v0;
if ( !*(_DWORD *)(v2 + 40) )
{
v3 = 8LL * ++tcp_protocols_len;
tcp_protocols = realloc(tcp_protocols, v3);
*(_QWORD *)((char *)tcp_protocols + v3 - 8) = v2;
}
++v1;
v0 += 168LL;
}
while ( cfg[22] > v1 );
}
}

canonical_decompiled_code:
void func0()
{
__int64 v0; // r12
unsigned __int64 v1; // rbp
__int64 v2; // r13
size_t v3; // rbx

if ( cfg[22] )
{
v0 = 0LL;
v1 = 0LL;
do
{
v2 = cfg[23] + v0;
if ( !*(_DWORD *)(v2 + 40) )
{
v3 = 8LL * ++tcp_protocols_len;
tcp_protocols = realloc(tcp_protocols, v3);
*(_QWORD *)((char *)tcp_protocols + v3 - 8) = v2;
}
++v1;
v0 += 168LL;
}
while ( cfg[22] > v1 );
}
}

original_code:
static void tcp_protocol_list_init(void)
{
    for (int i = 0; i < cfg.protocols_len; i++) {
        struct sslhcfg_protocols_item* p = &cfg.protocols[i];
        if (!p->is_udp) {
            tcp_protocols_len++;
            tcp_protocols = realloc(tcp_protocols, tcp_protocols_len * sizeof(*tcp_protocols));
            tcp_protocols[tcp_protocols_len-1] = p;
        }
    }
}

canonical_original_code:
static void tcp_protocol_list_init()
{
    for (int i = 0; i < cfg.protocols_len; i++) {
        struct sslhcfg_protocols_item *p = &cfg.protocols[i];
        if (!p->is_udp) {
            tcp_protocols_len++;
            tcp_protocols = realloc(tcp_protocols, tcp_protocols_len * sizeof(*tcp_protocols));
            tcp_protocols[tcp_protocols_len-1] = p;
        }
    }
}

variable_types: i int

variable_types: struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *saddr; void *data; struct dl_list { struct connection { int type; struct sslhcfg_protocols_item *proto; enum connection_state { ST_PROBING=1, ST_SHOVELING=2 } state; long probe_timeout; struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; } q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; } *head; struct connection *tail; } timeouts; } *

return_type: void

user_defined_types: struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo *saddr; void *data; struct dl_list timeouts; }

user_defined_types: struct dl_list { struct connection *head; struct connection *tail; }

user_defined_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }

user_defined_types: struct connection { int type; struct sslhcfg_protocols_item *proto; enum connection_state state; long probe_timeout; struct queue q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; }


decompiled_code:
void tcp_sanity_check()
{
__int64 v0; // rcx
_DWORD *v1; // rax
__int64 v2; // rdx

v0 = cfg[20];
if ( v0 )
{
v1 = (_DWORD *)(cfg[21] + 16LL);
v2 = 0LL;
while ( *v1 )
{
++v2;
v1 += 6;
if ( v2 == v0 )
return;
}
if ( !tcp_protocols_len )
{
print_message(
msg_config_error,
*((_QWORD *)&msg_config_error + 1),
"At least one TCP target protocol must be specified.\n");
exit(2);
}
}
}

canonical_decompiled_code:
void func1()
{
__int64 v0; // rcx
_DWORD *v1; // rax
__int64 v2; // rdx

v0 = cfg[20];
if ( v0 )
{
v1 = (_DWORD *)(cfg[21] + 16LL);
v2 = 0LL;
while ( *v1 )
{
++v2;
v1 += 6;
if ( v2 == v0 )
return;
}
if ( !tcp_protocols_len )
{
print_message(
msg_config_error,
*((_QWORD *)&msg_config_error + 1),
"At least one TCP target protocol must be specified.\n");
exit(2);
}
}
}

original_code:
static void tcp_sanity_check(void)
{
    int tcp_present = 0;
    for (int i = 0; i < cfg.listen_len; i++) {
        struct sslhcfg_listen_item* p = &cfg.listen[i];
        if (!p->is_udp) {
            tcp_present = 1;
            break;
        }
    }
    if (tcp_present && !tcp_protocols_len) {
        print_message(msg_config_error, "At least one TCP target protocol must be specified.\n");
        exit(2);
    }
}

canonical_original_code:
static void tcp_sanity_check()
{
    int tcp_present = 0;
    for (int i = 0; i < cfg.listen_len; i++) {
        struct sslhcfg_listen_item *p = &cfg.listen[i];
        if (!p->is_udp) {
            tcp_present = 1;
            break;
        }
    }
    if (tcp_present && !tcp_protocols_len) {
        print_message(msg_config_error, "At least one TCP target protocol must be specified.\n");
        exit(2);
    }
}

variable_types: struct sslhcfg_listen_item { char *host; char *port; int is_udp; int keepalive; } *


decompiled_code:
__int64 __fastcall probe_client_protocol(__int64 a1)
{
ssize_t v1; // rax
__int64 result; // rax
_BYTE v3[8200]; // [rsp+0h] [rbp-2008h] BYREF

v1 = read(*(_DWORD *)(a1 + 32), v3, 0x2000uLL);
if ( v1 > 0 )
{
defer_write(a1 + 64, v3, (unsigned int)v1);
result = probe_buffer(
*(_QWORD *)(a1 + 72),
*(unsigned int *)(a1 + 88),
tcp_protocols,
(unsigned int)tcp_protocols_len,
a1 + 8);
}
else
{
*(_QWORD *)(a1 + 8) = cfg[23] + 168LL * cfg[22] - 168;
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
ssize_t v1; // rax
__int64 result; // rax
_BYTE v3[8200]; // [rsp+0h] [rbp-2008h] BYREF

v1 = read(*(_DWORD *)(a1 + 32), v3, 0x2000uLL);
if ( v1 > 0 )
{
defer_write(a1 + 64, v3, (unsigned int)v1);
result = probe_buffer(
*(_QWORD *)(a1 + 72),
*(unsigned int *)(a1 + 88),
tcp_protocols,
(unsigned int)tcp_protocols_len,
a1 + 8);
}
else
{
*(_QWORD *)(a1 + 8) = cfg[23] + 168LL * cfg[22] - 168;
result = 1LL;
}
return result;
}

original_code:
int probe_client_protocol(struct connection *cnx)
{
    char buffer[8192];
    ssize_t n;
    n = read(cnx->q[0].fd, buffer, sizeof(buffer));
    if (n > 0) {
        defer_write(&cnx->q[1], buffer, n);
        return probe_buffer(cnx->q[1].begin_deferred_data,
                            cnx->q[1].deferred_data_size,
                            tcp_protocols, tcp_protocols_len,
                            &cnx->proto
                            );
    }
    cnx->proto = &cfg.protocols[cfg.protocols_len-1];
    return PROBE_MATCH;
}

canonical_original_code:
int probe_client_protocol(struct connection *cnx)
{
    char buffer[8192];
    long n;
    n = read(cnx->q[0].fd, buffer, sizeof(buffer));
    if (n > 0) {
        defer_write(&cnx->q[1], buffer, n);
        return probe_buffer(cnx->q[1].begin_deferred_data,
                            cnx->q[1].deferred_data_size,
                            tcp_protocols, tcp_protocols_len,
                            &cnx->proto
                            );
    }
    cnx->proto = &cfg.protocols[cfg.protocols_len-1];
    return PROBE_MATCH;
}

variable_types: struct connection { int type; struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *saddr; void *data; struct dl_list { struct connection *head; struct connection *tail; } timeouts; } *proto; enum connection_state { ST_PROBING=1, ST_SHOVELING=2 } state; long probe_timeout; struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; } q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; } *

variable_types:
buffer
char [8192]

variable_types: n long

return_type: int


decompiled_code:
void tcp_init()
{
tcp_protocol_list_init();
tcp_sanity_check();
}

canonical_decompiled_code:
void func3()
{
func0();
func1();
}

original_code:
void tcp_init(void)
{
    tcp_protocol_list_init();
    tcp_sanity_check();
}


original_code:
static void list_remove(dl_list* list, struct connection* cnx)
{
    if (list->head == cnx) list->head = cnx->timeout_next;
    if (list->tail == cnx) list->tail = cnx->timeout_prev;
    if (cnx->timeout_prev)
        cnx->timeout_prev->timeout_next = cnx->timeout_next;
    if (cnx->timeout_next)
        cnx->timeout_next->timeout_prev = cnx->timeout_prev;
}

canonical_original_code:
static void list_remove(struct dl_list *list, struct connection *cnx)
{
    if (list->head == cnx) list->head = cnx->timeout_next;
    if (list->tail == cnx) list->tail = cnx->timeout_prev;
    if (cnx->timeout_prev)
        cnx->timeout_prev->timeout_next = cnx->timeout_next;
    if (cnx->timeout_next)
        cnx->timeout_next->timeout_prev = cnx->timeout_prev;
}

variable_types: struct dl_list { struct connection { int type; struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *saddr; void *data; struct dl_list timeouts; } *proto; enum connection_state { ST_PROBING=1, ST_SHOVELING=2 } state; long probe_timeout; struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; } q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; } *head; struct connection *tail; } *

variable_types:
cnx
struct connection *


decompiled_code:
int __fastcall cnx_cmp(__int64 a1, __int64 a2)
{
unsigned int v2; // edx
int result; // eax

v2 = *(_DWORD *)(a1 + 112);
if ( v2 == *(_DWORD *)(a2 + 112) )
result = memcmp((const void *)(a1 + 96), (const void *)(a2 + 96), v2);
else
result = -1;
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, __int64 a2)
{
unsigned int v2; // edx
int result; // eax

v2 = *(_DWORD *)(a1 + 112);
if ( v2 == *(_DWORD *)(a2 + 112) )
result = memcmp((const void *)(a1 + 96), (const void *)(a2 + 96), v2);
else
result = -1;
return result;
}

original_code:
static int cnx_cmp(struct connection* cnx1, struct connection* cnx2)
{
    struct sockaddr* addr1 = &cnx1->client_addr;
    socklen_t addrlen1 = cnx1->addrlen;
    struct sockaddr* addr2 = &cnx2->client_addr;
    socklen_t addrlen2 = cnx2->addrlen;
    if (addrlen1 != addrlen2) return -1;
    return memcmp(addr1, addr2, addrlen1);
}

canonical_original_code:
static int cnx_cmp(struct connection *cnx1, struct connection *cnx2)
{
    struct sockaddr *addr1 = &cnx1->client_addr;
    unsigned int addrlen1 = cnx1->addrlen;
    struct sockaddr *addr2 = &cnx2->client_addr;
    unsigned int addrlen2 = cnx2->addrlen;
    if (addrlen1 != addrlen2) return -1;
    return memcmp(addr1, addr2, addrlen1);
}

variable_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; } *

user_defined_types: enum connection_state { ST_PROBING=1, ST_SHOVELING=2 }

user_defined_types: struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; }


decompiled_code:
void udp_protocol_list_init()
{
__int64 v0; // r12
unsigned __int64 v1; // rbp
__int64 v2; // r13
size_t v3; // rbx

if ( cfg[22] )
{
v0 = 0LL;
v1 = 0LL;
do
{
v2 = cfg[23] + v0;
if ( *(_DWORD *)(v2 + 40) )
{
v3 = 8LL * ++udp_protocols_len;
udp_protocols = realloc(udp_protocols, v3);
*(_QWORD *)((char *)udp_protocols + v3 - 8) = v2;
}
++v1;
v0 += 168LL;
}
while ( cfg[22] > v1 );
}
}

canonical_decompiled_code:
void func4()
{
__int64 v0; // r12
unsigned __int64 v1; // rbp
__int64 v2; // r13
size_t v3; // rbx

if ( cfg[22] )
{
v0 = 0LL;
v1 = 0LL;
do
{
v2 = cfg[23] + v0;
if ( *(_DWORD *)(v2 + 40) )
{
v3 = 8LL * ++udp_protocols_len;
udp_protocols = realloc(udp_protocols, v3);
*(_QWORD *)((char *)udp_protocols + v3 - 8) = v2;
}
++v1;
v0 += 168LL;
}
while ( cfg[22] > v1 );
}
}

original_code:
static void udp_protocol_list_init(void)
{
    for (int i = 0; i < cfg.protocols_len; i++) {
        struct sslhcfg_protocols_item* p = &cfg.protocols[i];
        if (p->is_udp) {
            udp_protocols_len++;
            udp_protocols = realloc(udp_protocols, udp_protocols_len * sizeof(*udp_protocols));
            udp_protocols[udp_protocols_len-1] = p;
        }
    }
}

canonical_original_code:
static void udp_protocol_list_init()
{
    for (int i = 0; i < cfg.protocols_len; i++) {
        struct sslhcfg_protocols_item *p = &cfg.protocols[i];
        if (p->is_udp) {
            udp_protocols_len++;
            udp_protocols = realloc(udp_protocols, udp_protocols_len * sizeof(*udp_protocols));
            udp_protocols[udp_protocols_len-1] = p;
        }
    }
}

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }


decompiled_code:
void udp_sanity_check()
{
__int64 v0; // rcx
_DWORD *v1; // rax
__int64 v2; // rdx

v0 = cfg[20];
if ( v0 )
{
v1 = (_DWORD *)(cfg[21] + 16LL);
v2 = 0LL;
while ( !*v1 )
{
++v2;
v1 += 6;
if ( v2 == v0 )
return;
}
if ( !udp_protocols_len )
{
print_message(
msg_config_error,
*((_QWORD *)&msg_config_error + 1),
"At least one UDP target protocol must be specified.\n");
exit(2);
}
}
}

canonical_decompiled_code:
void func5()
{
__int64 v0; // rcx
_DWORD *v1; // rax
__int64 v2; // rdx

v0 = cfg[20];
if ( v0 )
{
v1 = (_DWORD *)(cfg[21] + 16LL);
v2 = 0LL;
while ( !*v1 )
{
++v2;
v1 += 6;
if ( v2 == v0 )
return;
}
if ( !udp_protocols_len )
{
print_message(
msg_config_error,
*((_QWORD *)&msg_config_error + 1),
"At least one UDP target protocol must be specified.\n");
exit(2);
}
}
}

original_code:
static void udp_sanity_check(void)
{
    int udp_present = 0;
    for (int i = 0; i < cfg.listen_len; i++) {
        struct sslhcfg_listen_item* p = &cfg.listen[i];
        if (p->is_udp) {
            udp_present = 1;
            break;
        }
    }
    if (udp_present && !udp_protocols_len) {
        print_message(msg_config_error, "At least one UDP target protocol must be specified.\n");
        exit(2);
    }
}

canonical_original_code:
static void udp_sanity_check()
{
    int udp_present = 0;
    for (int i = 0; i < cfg.listen_len; i++) {
        struct sslhcfg_listen_item *p = &cfg.listen[i];
        if (p->is_udp) {
            udp_present = 1;
            break;
        }
    }
    if (udp_present && !udp_protocols_len) {
        print_message(msg_config_error, "At least one UDP target protocol must be specified.\n");
        exit(2);
    }
}

user_defined_types: struct sslhcfg_listen_item { char *host; char *port; int is_udp; int keepalive; }


decompiled_code:
__int64 __fastcall hash_make_key(__int64 a1)
{
__int16 v1; // ax

v1 = *(_WORD *)(a1 + 96);
if ( v1 == 2 )
return *(unsigned __int16 *)(a1 + 98);
if ( v1 == 10 )
return *(unsigned __int16 *)(a1 + 98);
return (unsigned int)*(char *)(a1 + 98);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int16 v1; // ax

v1 = *(_WORD *)(a1 + 96);
if ( v1 == 2 )
return *(unsigned __int16 *)(a1 + 98);
if ( v1 == 10 )
return *(unsigned __int16 *)(a1 + 98);
return (unsigned int)*(char *)(a1 + 98);
}

original_code:
static int hash_make_key(hash_item new)
{
    struct sockaddr* addr = &new->client_addr;
    struct sockaddr_in* addr4;
    struct sockaddr_in6* addr6;
    int out;
    switch (addr->sa_family) {
    case 2:
        addr4 = (struct sockaddr_in*)addr;
        out = addr4->sin_port;
        break;
    case 10:
        addr6 = (struct sockaddr_in6*)addr;
        out = addr6->sin6_port;
        break;
    default:
        out = ((char*)addr)[2];
        break;
    }
    return out;
}

canonical_original_code:
static int hash_make_key(struct connection *new)
{
    struct sockaddr *addr = &new->client_addr;
    struct sockaddr_in *addr4;
    struct sockaddr_in6 *addr6;
    int out;
    switch (addr->sa_family) {
    case 2:
        addr4 = (struct sockaddr_in *)addr;
        out = addr4->sin_port;
        break;
    case 10:
        addr6 = (struct sockaddr_in6 *)addr;
        out = addr6->sin6_port;
        break;
    default:
        out = ((char *)addr)[2];
        break;
    }
    return out;
}

variable_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; } *

variable_types: struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; } sin6_addr; unsigned int sin6_scope_id; } *

variable_types: out int

user_defined_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; unsigned char sin_zero[-1]; }

user_defined_types: struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr sin6_addr; unsigned int sin6_scope_id; }


decompiled_code:
void __fastcall collection_destroy(void *ptr)
{
gap_destroy(*(_QWORD *)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
gap_destroy(*(_QWORD *)ptr);
free(ptr);
}

original_code:
void collection_destroy(cnx_collection* collection)
{
    gap_destroy(collection->fd2cnx);
    free(collection);
}

canonical_original_code:
void collection_destroy(struct cnx_collection *collection)
{
    gap_destroy(collection->fd2cnx);
    free(collection);
}

variable_types: struct cnx_collection { struct gap_array { int len; void **array; } *fd2cnx; } *

user_defined_types: struct cnx_collection { struct gap_array *fd2cnx; }


decompiled_code:
__int64 __fastcall collection_add_fd(__int64 *a1, __int64 a2, int a3)
{
gap_set(*a1, a3, a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1, __int64 a2, int a3)
{
func1(*a1, a3, a2);
return 0LL;
}

original_code:
int collection_add_fd(cnx_collection* collection, struct connection* cnx, int fd)
{
    gap_set(collection->fd2cnx, fd, cnx);
    return 0;
}

canonical_original_code:
int collection_add_fd(struct cnx_collection *collection, struct connection *cnx, int fd)
{
    gap_set(collection->fd2cnx, fd, cnx);
    return 0;
}

variable_types: fd int

user_defined_types: struct gap_array { int len; void **array; }


decompiled_code:
__int64 __fastcall collection_remove_cnx(__int64 *a1, _DWORD *a2)
{
int v3; // esi
int v4; // esi

v3 = a2[8];
if ( v3 != -1 )
gap_set(*a1, v3, 0LL);
v4 = a2[16];
if ( v4 != -1 )
gap_set(*a1, v4, 0LL);
free(a2);
return 0LL;
}

original_code:
int collection_remove_cnx(cnx_collection* collection, struct connection *cnx)
{
    if (cnx->q[0].fd != -1)
        gap_set(collection->fd2cnx, cnx->q[0].fd, ((void *)0));
    if (cnx->q[1].fd != -1)
        gap_set(collection->fd2cnx, cnx->q[1].fd, ((void *)0));
    free(cnx);
    return 0;
}

canonical_original_code:
int collection_remove_cnx(struct cnx_collection *collection, struct connection *cnx)
{
    if (cnx->q[0].fd != -1)
        gap_set(collection->fd2cnx, cnx->q[0].fd, ((void *)0));
    if (cnx->q[1].fd != -1)
        gap_set(collection->fd2cnx, cnx->q[1].fd, ((void *)0));
    free(cnx);
    return 0;
}


decompiled_code:
__int64 __fastcall collection_get_cnx_from_fd(__int64 *a1, int a2)
{
return gap_get(*a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 *a1, int a2)
{
return func0(*a1, a2);
}

original_code:
struct connection* collection_get_cnx_from_fd(struct cnx_collection* collection, int fd)
{
    return gap_get(collection->fd2cnx, fd);
}

canonical_original_code:
struct connection *collection_get_cnx_from_fd(struct cnx_collection *collection, int fd)
{
    return gap_get(collection->fd2cnx, fd);
}

return_type: struct connection { int type; struct sslhcfg_protocols_item { char *name; char *host; char *port; int service_is_present; char *service; int is_udp; int udp_timeout; int fork; int tfo_ok; int transparent; int resolve_on_forward; int log_level; int keepalive; unsigned long sni_hostnames_len; char **sni_hostnames; unsigned long alpn_protocols_len; char **alpn_protocols; unsigned long regex_patterns_len; char **regex_patterns; int minlength_is_present; int minlength; int (*probe)(char *, long, struct sslhcfg_protocols_item *); struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *saddr; void *data; struct dl_list { struct connection *head; struct connection *tail; } timeouts; } *proto; enum connection_state { ST_PROBING=1, ST_SHOVELING=2 } state; long probe_timeout; struct queue { int fd; void *begin_deferred_data; void *deferred_data; int deferred_data_size; } q[2]; struct sockaddr client_addr; unsigned int addrlen; int local_endpoint; long last_active; struct connection *timeout_prev; int target_sock; } *


decompiled_code:
__int64 __fastcall fd_out_of_range(int a1)
{
__int64 result; // rax

result = 0LL;
if ( a1 > 1023 )
{
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"too many open file descriptor to monitor them all -- dropping connection\n");
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1)
{
__int64 result; // rax

result = 0LL;
if ( a1 > 1023 )
{
print_message(
msg_system_error,
*((_QWORD *)&msg_system_error + 1),
"too many open file descriptor to monitor them all -- dropping connection\n");
result = 1LL;
}
return result;
}

original_code:
static int fd_out_of_range(int fd) {
    if (fd >= 1024) {
        print_message(msg_system_error, "too many open file descriptor to monitor them all -- dropping connection\n");
        return 1;
    }
    return 0;
}


decompiled_code:
__int64 __fastcall watchers_add_read(__int64 a1, int a2)
{
__int64 result; // rax

result = a2 / 64;
*(_QWORD *)(a1 + 8 * result) |= 1LL << (a2 % 64);
if ( *(_DWORD *)(a1 + 256) < a2 )
*(_DWORD *)(a1 + 256) = a2 + 1;
return result;
}

original_code:
void watchers_add_read(watchers* w, int fd)
{
    ((void) (((&w->fds_r)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
    if (fd > w->max_fd)
        w->max_fd = fd + 1;
}

canonical_original_code:
void watchers_add_read(struct watchers *w, int fd)
{
    ((void) (((&w->fds_r)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
    if (fd > w->max_fd)
        w->max_fd = fd + 1;
}

variable_types: struct watchers { struct fd_set { long fds_bits[-1]; } fds_r; int max_fd; } *

user_defined_types: struct watchers { struct fd_set fds_r; int max_fd; }


decompiled_code:
__int64 __fastcall watchers_init(__int64 *a1, int *a2, int a3)
{
void *v4; // rax
void *v5; // rdx
__int64 result; // rax
int *v7; // rbx
__int64 v8; // r12

v4 = malloc(0x108uLL);
*a1 = (__int64)v4;
if ( !v4 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-select.c", 55LL);
perror("malloc");
exit(1);
}
v5 = v4;
result = 0LL;
memset(v5, 0, 0x108uLL);
memset(v5, 0, 0x80uLL);
memset((void *)(*a1 + 128), 0, 0x80uLL);
if ( a3 > 0 )
{
v7 = a2;
v8 = (__int64)&a2[2 * (a3 - 1) + 2];
do
{
watchers_add_read(*a1, *v7);
result = set_nonblock((unsigned int)*v7);
v7 += 2;
}
while ( v7 != (int *)v8 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1, int *a2, int a3)
{
void *v4; // rax
void *v5; // rdx
__int64 result; // rax
int *v7; // rbx
__int64 v8; // r12

v4 = malloc(0x108uLL);
*a1 = (__int64)v4;
if ( !v4 )
{
print_message(msg_system_error, *((_QWORD *)&msg_system_error + 1), "%s:%d:", "sslh-select.c", 55LL);
perror("malloc");
exit(1);
}
v5 = v4;
result = 0LL;
memset(v5, 0, 0x108uLL);
memset(v5, 0, 0x80uLL);
memset((void *)(*a1 + 128), 0, 0x80uLL);
if ( a3 > 0 )
{
v7 = a2;
v8 = (__int64)&a2[2 * (a3 - 1) + 2];
do
{
func2(*a1, *v7);
result = set_nonblock((unsigned int)*v7);
v7 += 2;
}
while ( v7 != (int *)v8 );
}
return result;
}

original_code:
static void watchers_init(watchers** w, struct listen_endpoint* listen_sockets,
                          int num_addr_listen)
{
    *w = malloc(sizeof(**w));
    if (!*w) { print_message(msg_system_error, "%s:%d:", "sslh-select.c", 55); perror("malloc"); exit(1); };
    memset(*w, 0, sizeof(**w));
    do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&(*w)->fds_r)->fds_bits)[0]) : "memory"); } while (0);
    do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&(*w)->fds_w)->fds_bits)[0]) : "memory"); } while (0);
    for (int i = 0; i < num_addr_listen; i++) {
        watchers_add_read(*w, listen_sockets[i].socketfd);
        set_nonblock(listen_sockets[i].socketfd);
    }
}

canonical_original_code:
static void watchers_init(struct watchers **w, struct listen_endpoint *listen_sockets, int num_addr_listen)
{
    *w = malloc(sizeof(**w));
    if (!*w) { print_message(msg_system_error, "%s:%d:", "sslh-select.c", 55); perror("malloc"); exit(1); };
    memset(*w, 0, sizeof(**w));
    do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&(*w)->fds_r)->fds_bits)[0]) : "memory"); } while (0);
    do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&(*w)->fds_w)->fds_bits)[0]) : "memory"); } while (0);
    for (int i = 0; i < num_addr_listen; i++) {
        watchers_add_read(*w, listen_sockets[i].socketfd);
        set_nonblock(listen_sockets[i].socketfd);
    }
}

variable_types: struct watchers { struct fd_set { long fds_bits[-1]; } fds_r; int max_fd; } **

variable_types: struct listen_endpoint { int socketfd; int type; } *


decompiled_code:
__int64 __fastcall watchers_del_read(__int64 a1, int a2)
{
__int64 result; // rax

result = a2 / 64;
*(_QWORD *)(a1 + 8 * result) &= __ROL8__(-2LL, a2 % 64);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, int a2)
{
__int64 result; // rax

result = a2 / 64;
*(_QWORD *)(a1 + 8 * result) &= __ROL8__(-2LL, a2 % 64);
return result;
}

original_code:
void watchers_del_read(watchers* w, int fd)
{
    ((void) (((&w->fds_r)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
}

canonical_original_code:
void watchers_del_read(struct watchers *w, int fd)
{
    ((void) (((&w->fds_r)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
}


decompiled_code:
__int64 __fastcall watchers_add_write(__int64 a1, int a2)
{
__int64 result; // rax

result = a2 / 64;
*(_QWORD *)(a1 + 8 * result + 128) |= 1LL << (a2 % 64);
if ( *(_DWORD *)(a1 + 256) < a2 )
*(_DWORD *)(a1 + 256) = a2 + 1;
return result;
}

original_code:
void watchers_add_write(watchers* w, int fd)
{
    ((void) (((&w->fds_w)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
    if (fd > w->max_fd)
        w->max_fd = fd + 1;
}

canonical_original_code:
void watchers_add_write(struct watchers *w, int fd)
{
    ((void) (((&w->fds_w)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
    if (fd > w->max_fd)
        w->max_fd = fd + 1;
}


decompiled_code:
__int64 __fastcall watchers_del_write(__int64 a1, int a2)
{
__int64 result; // rax

result = a2 / 64;
*(_QWORD *)(a1 + 8 * result + 128) &= __ROL8__(-2LL, a2 % 64);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, int a2)
{
__int64 result; // rax

result = a2 / 64;
*(_QWORD *)(a1 + 8 * result + 128) &= __ROL8__(-2LL, a2 % 64);
return result;
}

original_code:
void watchers_del_write(watchers* w, int fd)
{
    ((void) (((&w->fds_w)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
}

canonical_original_code:
void watchers_del_write(struct watchers *w, int fd)
{
    ((void) (((&w->fds_w)->fds_bits)[((fd) / (8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) (1UL << ((fd) % (8 * (int) sizeof (__fd_mask)))))));
}


decompiled_code:
void __noreturn start_shoveler()
{
print_message(msg_config_error, *((_QWORD *)&msg_config_error + 1), "inetd mode is not supported in select mode\n");
exit(1);
}

canonical_decompiled_code:
void __noreturn func8()
{
print_message(msg_config_error, *((_QWORD *)&msg_config_error + 1), "inetd mode is not supported in select mode\n");
exit(1);
}

original_code:
void start_shoveler(int listen_socket) {
    print_message(msg_config_error, "inetd mode is not supported in select mode\n");
    exit(1);
}


decompiled_code:
int __fastcall cmp_item(__int64 a1, __int64 a2)
{
return strcmp((const char *)(a1 + 4), (const char *)(a2 + 4));
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1, __int64 a2)
{
return strcmp((const char *)(a1 + 4), (const char *)(a2 + 4));
}

original_code:
static int cmp_item(hash_item item1, hash_item item2)
{
    return strcmp(item1->str, item2->str);
}

canonical_original_code:
static int cmp_item(struct hash_item *item1, struct hash_item *item2)
{
    return strcmp(item1->str, item2->str);
}

variable_types: struct hash_item { int wanted_index; char str[16]; } *


main

canonical_name: main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // r12
const char *v5; // rbx
const char *v6; // r15
FILE *v7; // r14
unsigned int v8; // er13
const void *v9; // rax
unsigned int *v10; // rbx
const char *v11; // rbp
char v12[57]; // [rsp+Fh] [rbp-39h] BYREF

v3 = hash_init(32LL, hash_make_key, cmp_item);
if ( argc != 3 )
{
fwrite("Usage: htest <script file> <dump file>\n", 1uLL, 0x27uLL, stderr);
exit(1);
}
v4 = v3;
v5 = argv[1];
v6 = argv[2];
v7 = fopen(v5, "r");
v8 = 0;
if ( !v7 )
{
perror(v5);
exit(1);
}
while ( 1 )
{
v10 = (unsigned int *)malloc(0x14uLL);
v12[0] = 32;
++v8;
v11 = (const char *)(v10 + 1);
htest_next_key((__int64)v7, (__int64)v12, (__int64)v10, (__int64)(v10 + 1));
fprintf(stderr, "action %d: %c %d %s\n", v8, (unsigned int)v12[0], *v10, (const char *)v10 + 4);
if ( v12[0] == 113 )
break;
if ( v12[0] > 113 )
{
if ( v12[0] == 115 )
{
fwrite("searching\n", 1uLL, 0xAuLL, stderr);
v9 = (const void *)hash_find(v4, v10);
fprintf(stderr, "searching %d[%s]: %p\n", *v10, v11, v9);
}
}
else if ( v12[0] == 97 )
{
fprintf(stderr, "inserting [%s] at %d\n", v11, *v10);
hash_insert(v4, v10);
}
else if ( v12[0] == 100 )
{
fprintf(stderr, "removing [%s] at %d\n", v11, *v10);
hash_remove(v4, v10);
}
hash_dump(v4, v6);
}
exit(1);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // r12
const char *v5; // rbx
const char *v6; // r15
FILE *v7; // r14
unsigned int v8; // er13
const void *v9; // rax
unsigned int *v10; // rbx
const char *v11; // rbp
char v12[57]; // [rsp+Fh] [rbp-39h] BYREF

v3 = hash_init(32LL, hash_make_key, cmp_item);
if ( argc != 3 )
{
fwrite("Usage: htest <script file> <dump file>\n", 1uLL, 0x27uLL, stderr);
exit(1);
}
v4 = v3;
v5 = argv[1];
v6 = argv[2];
v7 = fopen(v5, "r");
v8 = 0;
if ( !v7 )
{
perror(v5);
exit(1);
}
while ( 1 )
{
v10 = (unsigned int *)malloc(0x14uLL);
v12[0] = 32;
++v8;
v11 = (const char *)(v10 + 1);
func2((__int64)v7, (__int64)v12, (__int64)v10, (__int64)(v10 + 1));
fprintf(stderr, "action %d: %c %d %s\n", v8, (unsigned int)v12[0], *v10, (const char *)v10 + 4);
if ( v12[0] == 113 )
break;
if ( v12[0] > 113 )
{
if ( v12[0] == 115 )
{
fwrite("searching\n", 1uLL, 0xAuLL, stderr);
v9 = (const void *)hash_find(v4, v10);
fprintf(stderr, "searching %d[%s]: %p\n", *v10, v11, v9);
}
}
else if ( v12[0] == 97 )
{
fprintf(stderr, "inserting [%s] at %d\n", v11, *v10);
hash_insert(v4, v10);
}
else if ( v12[0] == 100 )
{
fprintf(stderr, "removing [%s] at %d\n", v11, *v10);
hash_remove(v4, v10);
}
hash_dump(v4, v6);
}
exit(1);
}

original_code:
int main(int argc, char *argv[])
{
   extern char *optarg;
   extern int optind;
   int num_addr_listen;
   struct listen_endpoint *listen_sockets;
   memset(&cfg, 0, sizeof(cfg));
   if (echocfg_cl_parse(argc, argv, &cfg))
       exit(1);
   echocfg_fprint(stdout, &cfg, 0);
   num_addr_listen = start_listen_sockets(&listen_sockets);
   main_loop(listen_sockets, num_addr_listen);
   return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
optarg
char *

variable_types: optind int

user_defined_types: struct listen_endpoint { int socketfd; int type; }


decompiled_code:
__int64 __fastcall hash_make_key(unsigned int *a1)
{
return *a1;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int *a1)
{
return *a1;
}

original_code:
static int hash_make_key(hash_item item)
{
    return item->wanted_index;
}

canonical_original_code:
static int hash_make_key(struct hash_item *item)
{
    return item->wanted_index;
}

user_defined_types: struct hash_item { int wanted_index; char str[16]; }


decompiled_code:
__int64 __fastcall gap_extend(int *a1)
{
int v1; // ebp
void *v2; // rax
int v3; // edx
__int64 v4; // rax

v1 = *a1 + gap_len_alloc(8);
v2 = realloc(*((void **)a1 + 1), 8 * v1);
if ( !v2 )
return 0xFFFFFFFFLL;
*((_QWORD *)a1 + 1) = v2;
v3 = *a1;
if ( v1 > *a1 )
{
v4 = 8LL * v3;
do
{
*(_QWORD *)(*((_QWORD *)a1 + 1) + v4) = 0LL;
v4 += 8LL;
}
while ( v4 != 8 * (v3 + (unsigned __int64)(unsigned int)(v1 + ~v3) + 1) );
}
*a1 = v1;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(int *a1)
{
int v1; // ebp
void *v2; // rax
int v3; // edx
__int64 v4; // rax

v1 = *a1 + func0(8);
v2 = realloc(*((void **)a1 + 1), 8 * v1);
if ( !v2 )
return 0xFFFFFFFFLL;
*((_QWORD *)a1 + 1) = v2;
v3 = *a1;
if ( v1 > *a1 )
{
v4 = 8LL * v3;
do
{
*(_QWORD *)(*((_QWORD *)a1 + 1) + v4) = 0LL;
v4 += 8LL;
}
while ( v4 != 8 * (v3 + (unsigned __int64)(unsigned int)(v1 + ~v3) + 1) );
}
*a1 = v1;
return 0LL;
}

original_code:
int gap_extend(gap_array* gap)
{
    int elem_size = sizeof(gap->array[0]);
    int new_length = gap->len + gap_len_alloc(elem_size);
    void** new = realloc(gap->array, new_length * elem_size);
    if (!new) return -1;
    gap->array = new;
    for (int i = gap->len; i < new_length; i++) {
        gap->array[i] = ((void *)0);
    }
    gap->len = new_length;
    return 0;
}

canonical_original_code:
int gap_extend(struct gap_array *gap)
{
    int elem_size = sizeof(gap->array[0]);
    int new_length = gap->len + gap_len_alloc(elem_size);
    void **new = realloc(gap->array, new_length * elem_size);
    if (!new) return -1;
    gap->array = new;
    for (int i = gap->len; i < new_length; i++) {
        gap->array[i] = ((void *)0);
    }
    gap->len = new_length;
    return 0;
}

variable_types: struct gap_array { int len; void **array; } *

variable_types:
new
void **

variable_types: i int


decompiled_code:
void __fastcall gap_destroy(void *ptr)
{
free(*((void **)ptr + 1));
free(ptr);
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
free(*((void **)ptr + 1));
free(ptr);
}

original_code:
void gap_destroy(gap_array* gap)
{
    free(gap->array);
    free(gap);
}

canonical_original_code:
void gap_destroy(struct gap_array *gap)
{
    free(gap->array);
    free(gap);
}


decompiled_code:
__int64 __fastcall gap_remove_ptr(__int64 a1, __int64 a2, int a3)
{
__int64 v4; // rax
__int64 v6; // rdx

if ( a3 <= 0 )
return 0xFFFFFFFFLL;
v4 = 0LL;
while ( *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8 * v4) != a2 )
{
if ( ++v4 == a3 )
return 0xFFFFFFFFLL;
}
if ( a3 <= (int)v4 )
return 0xFFFFFFFFLL;
if ( a3 - 1 <= (int)v4 )
return 0LL;
v6 = 8LL * (int)v4 + 8;
do
{
*(_QWORD *)(*(_QWORD *)(a1 + 8) + v6 - 8) = *(_QWORD *)(*(_QWORD *)(a1 + 8) + v6);
v6 += 8LL;
}
while ( v6 != 8 * ((int)v4 + (unsigned __int64)(unsigned int)(a3 - 2 - v4) + 2) );
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2, int a3)
{
__int64 v4; // rax
__int64 v6; // rdx

if ( a3 <= 0 )
return 0xFFFFFFFFLL;
v4 = 0LL;
while ( *(_QWORD *)(*(_QWORD *)(a1 + 8) + 8 * v4) != a2 )
{
if ( ++v4 == a3 )
return 0xFFFFFFFFLL;
}
if ( a3 <= (int)v4 )
return 0xFFFFFFFFLL;
if ( a3 - 1 <= (int)v4 )
return 0LL;
v6 = 8LL * (int)v4 + 8;
do
{
*(_QWORD *)(*(_QWORD *)(a1 + 8) + v6 - 8) = *(_QWORD *)(*(_QWORD *)(a1 + 8) + v6);
v6 += 8LL;
}
while ( v6 != 8 * ((int)v4 + (unsigned __int64)(unsigned int)(a3 - 2 - v4) + 2) );
return 0LL;
}

original_code:
int gap_remove_ptr(gap_array* gap, void* ptr, int len)
{
    int start, i;
    for (i = 0; i < len; i++)
        if (gap->array[i] == ptr)
            break;
    if (i < len)
        start = i;
    else
        return -1;
    for (i = start; i < len - 1; i++) {
        gap->array[i] = gap->array[i+1];
    }
    return 0;
}

canonical_original_code:
int gap_remove_ptr(struct gap_array *gap, void *ptr, int len)
{
    int start; int i;
    for (i = 0; i < len; i++)
        if (gap->array[i] == ptr)
            break;
    if (i < len)
        start = i;
    else
        return -1;
    for (i = start; i < len - 1; i++) {
        gap->array[i] = gap->array[i+1];
    }
    return 0;
}

variable_types:
ptr
void *

variable_types: len int

variable_types: start int


decompiled_code:
__int64 __fastcall watchers_del_read(__int64 *a1, int a2)
{
__int64 result; // rax

result = gap_get(*a1, a2);
if ( result )
result = ev_io_stop(loop, result);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 *a1, int a2)
{
__int64 result; // rax

result = func0(*a1, a2);
if ( result )
result = ev_io_stop(loop, result);
return result;
}


decompiled_code:
__int64 __fastcall watchers_del_write(__int64 a1, int a2)
{
__int64 result; // rax

result = gap_get(*(_QWORD *)(a1 + 8), a2);
if ( result )
result = ev_io_stop(loop, result);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, int a2)
{
__int64 result; // rax

result = func0(*(_QWORD *)(a1 + 8), a2);
if ( result )
result = ev_io_stop(loop, result);
return result;
}


original_code:
int lx_apply(rb_node *root, void (*func)(lx_node *)) {
 int i, j;
 i = 0;
 void lx_cb(rb_node *n) {
  lx_node *lx, *tmp;
  lx = ((n)->val);
  while (((void *)0) != lx) {
   tmp = ((lx)->next);
   func(lx);
   lx = tmp;
   ++i;
  }
 }
 j = rb_apply(root, lx_cb);
 if (-1 == j) return -1;
 return i;
}

canonical_original_code:
int lx_apply(struct _rb_node *root, void (*func)(struct _lx_node *)) {
 int i; int j;
 i = 0;
 void lx_cb(rb_node *n) {
  struct _lx_node *lx; struct _lx_node *tmp;
  lx = ((n)->val);
  while (((void *)0) != lx) {
   tmp = ((lx)->next);
   func(lx);
   lx = tmp;
   ++i;
  }
 }
 j = rb_apply(root, lx_cb);
 if (-1 == j) return -1;
 return i;
}

variable_types: struct _rb_node { struct _rb_node *left; int color; void *val; } *

variable_types: void (*)(struct _lx_node { struct _lx_node *next; char *str; void *val; } *)

variable_types: j int


decompiled_code:
__int64 __fastcall lx_insert(__int64 *a1, const char *a2, __int64 a3)
{
__int64 v5; // rdi
__int64 v6; // rax
__int64 result; // rax
_QWORD *v8; // rbx
__int64 v9; // rdx
_QWORD *v10; // rbx
__int64 v11; // rax
__int64 v12; // rsi
unsigned int v13; // [rsp+4h] [rbp-24h] BYREF
__int64 v14[4]; // [rsp+8h] [rbp-20h] BYREF

v5 = *a1;
if ( v5 )
{
v6 = lx_lookup2(v5, a2, v14, &v13);
if ( v14[0] && v6 )
{
*(_QWORD *)(v6 + 24) = a3;
result = 0LL;
}
else
{
v10 = lx_nalloc((__int64)a2, a3);
if ( v10 )
{
if ( v14[0] )
{
v11 = *(_QWORD *)(v14[0] + 32);
*v10 = v11;
if ( v11 )
*(_QWORD *)(v11 + 8) = v10;
*(_QWORD *)(v14[0] + 32) = v10;
result = 1LL;
}
else
{
v12 = rb_nalloc(v13, v10);
v14[0] = v12;
if ( v12 )
{
rb_insert(a1, v12);
result = 1LL;
}
else
{
free(v10);
result = 0xFFFFFFFFLL;
}
}
}
else
{
result = 0xFFFFFFFFLL;
}
}
}
else
{
v13 = hash(a2);
v8 = lx_nalloc((__int64)a2, a3);
result = 0xFFFFFFFFLL;
if ( v8 )
{
v9 = rb_nalloc(v13, v8);
*a1 = v9;
result = 1LL;
if ( !v9 )
{
free(v8);
result = 0xFFFFFFFFLL;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1, const char *a2, __int64 a3)
{
__int64 v5; // rdi
__int64 v6; // rax
__int64 result; // rax
_QWORD *v8; // rbx
__int64 v9; // rdx
_QWORD *v10; // rbx
__int64 v11; // rax
__int64 v12; // rsi
unsigned int v13; // [rsp+4h] [rbp-24h] BYREF
__int64 v14[4]; // [rsp+8h] [rbp-20h] BYREF

v5 = *a1;
if ( v5 )
{
v6 = func1(v5, a2, v14, &v13);
if ( v14[0] && v6 )
{
*(_QWORD *)(v6 + 24) = a3;
result = 0LL;
}
else
{
v10 = lx_nalloc((__int64)a2, a3);
if ( v10 )
{
if ( v14[0] )
{
v11 = *(_QWORD *)(v14[0] + 32);
*v10 = v11;
if ( v11 )
*(_QWORD *)(v11 + 8) = v10;
*(_QWORD *)(v14[0] + 32) = v10;
result = 1LL;
}
else
{
v12 = rb_nalloc(v13, v10);
v14[0] = v12;
if ( v12 )
{
rb_insert(a1, v12);
result = 1LL;
}
else
{
free(v10);
result = 0xFFFFFFFFLL;
}
}
}
else
{
result = 0xFFFFFFFFLL;
}
}
}
else
{
v13 = hash(a2);
v8 = lx_nalloc((__int64)a2, a3);
result = 0xFFFFFFFFLL;
if ( v8 )
{
v9 = rb_nalloc(v13, v8);
*a1 = v9;
result = 1LL;
if ( !v9 )
{
free(v8);
result = 0xFFFFFFFFLL;
}
}
}
return result;
}

original_code:
int lx_insert(rb_node **root, char *str, void *val) {
 lx_node *lx;
 rb_node *n;
 int key;
 if (((void *)0) == *root) {
  key = hash(str);
  lx = lx_nalloc(str, val);
  if (((void *)0) == lx)
   return -1;
  else if (((void *)0) == (*root = rb_nalloc(key, lx))) {
   free(lx);
   return -1;
  }
  return 1;
 }
 lx = lx_lookup2(*root, str, &n, &key);
 if ((((void *)0) != n) && (((void *)0) != lx)) {
  ((lx)->val) = val;
  return 0;
 }
 lx = lx_nalloc(str, val);
 if (((void *)0) == lx) return -1;
 if (((void *)0) == n) {
  n = rb_nalloc(key, lx);
  if (((void *)0) == n) {
   free(lx);
   return -1;
  }
  rb_insert(root, n);
 } else {
  if (((void *)0) != (((lx)->next) = ((n)->val))) ((((lx)->next))->prev) = lx;
  ((n)->val) = lx;
 }
 return 1;
}

canonical_original_code:
int lx_insert(struct _rb_node **root, char *str, void *val) {
 struct _lx_node *lx;
 struct _rb_node *n;
 int key;
 if (((void *)0) == *root) {
  key = hash(str);
  lx = lx_nalloc(str, val);
  if (((void *)0) == lx)
   return -1;
  else if (((void *)0) == (*root = rb_nalloc(key, lx))) {
   free(lx);
   return -1;
  }
  return 1;
 }
 lx = lx_lookup2(*root, str, &n, &key);
 if ((((void *)0) != n) && (((void *)0) != lx)) {
  ((lx)->val) = val;
  return 0;
 }
 lx = lx_nalloc(str, val);
 if (((void *)0) == lx) return -1;
 if (((void *)0) == n) {
  n = rb_nalloc(key, lx);
  if (((void *)0) == n) {
   free(lx);
   return -1;
  }
  rb_insert(root, n);
 } else {
  if (((void *)0) != (((lx)->next) = ((n)->val))) ((((lx)->next))->prev) = lx;
  ((n)->val) = lx;
 }
 return 1;
}

variable_types: struct _rb_node { struct _rb_node *left; int color; void *val; } **

variable_types:
str
char *

variable_types:
val
void *

variable_types: struct _lx_node { struct _lx_node *next; char *str; void *val; } *

variable_types: key int


decompiled_code:
__int64 __fastcall lx_lookup(__int64 a1, const char *a2, __int64 *a3)
{
__int64 result; // rax
unsigned int v5; // [rsp+4h] [rbp-14h] BYREF
__int64 v6; // [rsp+8h] [rbp-10h] BYREF

result = 0LL;
if ( a1 )
{
a1 = lx_lookup2(a1, a2, &v6, &v5);
result = 0LL;
if ( a1 )
{
a1 = *(_QWORD *)(a1 + 24);
result = 1LL;
}
}
*a3 = a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, const char *a2, __int64 *a3)
{
__int64 result; // rax
unsigned int v5; // [rsp+4h] [rbp-14h] BYREF
__int64 v6; // [rsp+8h] [rbp-10h] BYREF

result = 0LL;
if ( a1 )
{
a1 = func1(a1, a2, &v6, &v5);
result = 0LL;
if ( a1 )
{
a1 = *(_QWORD *)(a1 + 24);
result = 1LL;
}
}
*a3 = a1;
return result;
}

original_code:
int lx_lookup(rb_node *root, char *str, void **val) {
 lx_node *lx;
        rb_node *n;
        int key;
 if ((((void *)0) != root) &&
     (((void *)0) != (lx = lx_lookup2(root, str, &n, &key)))) {
  *val = ((lx)->val);
  return 1;
 }
 *val = ((void *)0);
 return 0;
}

canonical_original_code:
int lx_lookup(struct _rb_node *root, char *str, void **val) {
 struct _lx_node *lx;
        struct _rb_node *n;
        int key;
 if ((((void *)0) != root) &&
     (((void *)0) != (lx = lx_lookup2(root, str, &n, &key)))) {
  *val = ((lx)->val);
  return 1;
 }
 *val = ((void *)0);
 return 0;
}

variable_types:
val
void **

user_defined_types: struct _rb_node { struct _rb_node *left; int color; void *val; }

user_defined_types: struct _lx_node { struct _lx_node *next; char *str; void *val; }


decompiled_code:
__int64 __fastcall lx_remove(__int64 *a1, const char *a2, _QWORD *a3)
{
__int64 v4; // rdi
__int64 result; // rax
_QWORD *v7; // rdi
_QWORD *v8; // rax
void *v9; // rax
unsigned int v10; // [rsp+4h] [rbp-24h] BYREF
__int64 v11[4]; // [rsp+8h] [rbp-20h] BYREF

v4 = *a1;
result = 0LL;
if ( v4 )
{
v7 = (_QWORD *)lx_lookup2(v4, a2, v11, &v10);
result = 0LL;
if ( v7 )
{
*a3 = v7[3];
v8 = (_QWORD *)v7[1];
if ( v8 )
*v8 = *v7;
else
*(_QWORD *)(v11[0] + 32) = *v7;
if ( *v7 )
*(_QWORD *)(*v7 + 8LL) = v7[1];
free(v7);
result = 1LL;
if ( !*(_QWORD *)(v11[0] + 32) )
{
v9 = (void *)rb_remove(a1);
free(v9);
result = 1LL;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 *a1, const char *a2, _QWORD *a3)
{
__int64 v4; // rdi
__int64 result; // rax
_QWORD *v7; // rdi
_QWORD *v8; // rax
void *v9; // rax
unsigned int v10; // [rsp+4h] [rbp-24h] BYREF
__int64 v11[4]; // [rsp+8h] [rbp-20h] BYREF

v4 = *a1;
result = 0LL;
if ( v4 )
{
v7 = (_QWORD *)func1(v4, a2, v11, &v10);
result = 0LL;
if ( v7 )
{
*a3 = v7[3];
v8 = (_QWORD *)v7[1];
if ( v8 )
*v8 = *v7;
else
*(_QWORD *)(v11[0] + 32) = *v7;
if ( *v7 )
*(_QWORD *)(*v7 + 8LL) = v7[1];
free(v7);
result = 1LL;
if ( !*(_QWORD *)(v11[0] + 32) )
{
v9 = (void *)rb_remove(a1);
free(v9);
result = 1LL;
}
}
}
return result;
}

original_code:
int lx_remove(rb_node **root, char *str, void **val) {
 lx_node *lx;
        rb_node *n;
        int key;
 if ((((void *)0) != *root) &&
     (((void *)0) != (lx = lx_lookup2(*root, str, &n, &key)))) {
  *val = ((lx)->val);
  if (((void *)0) != ((lx)->prev)) ((((lx)->prev))->next) = ((lx)->next);
  else ((n)->val) = ((lx)->next);
  if (((void *)0) != ((lx)->next))
   ((((lx)->next))->prev) = ((lx)->prev);
  free(lx);
  if (((void *)0) == ((n)->val)) {
   n = rb_remove(root, n);
   free(n);
  }
  return 1;
 }
 return 0;
}

canonical_original_code:
int lx_remove(struct _rb_node **root, char *str, void **val) {
 struct _lx_node *lx;
        struct _rb_node *n;
        int key;
 if ((((void *)0) != *root) &&
     (((void *)0) != (lx = lx_lookup2(*root, str, &n, &key)))) {
  *val = ((lx)->val);
  if (((void *)0) != ((lx)->prev)) ((((lx)->prev))->next) = ((lx)->next);
  else ((n)->val) = ((lx)->next);
  if (((void *)0) != ((lx)->next))
   ((((lx)->next))->prev) = ((lx)->prev);
  free(lx);
  if (((void *)0) == ((n)->val)) {
   n = rb_remove(root, n);
   free(n);
  }
  return 1;
 }
 return 0;
}


original_code:
inline static void rb_remove_bal(rb_node **root, rb_node *n) {
 rb_node *sibling;
 if (!((n)->parent))
  return;
 sibling = ((n == ((((n)->parent))->left)) ? (((((n)->parent))->right)) : (((((n)->parent))->left)));
 if (1 == ((sibling) ? (((sibling)->color)) : (0))) {
  ((((n)->parent))->color) = 1;
  ((sibling)->color) = 0;
  if (n == ((((n)->parent))->left))
   rb_rotate_left(root, ((n)->parent));
  else
   rb_rotate_right(root, ((n)->parent));
  sibling = ((n == ((((n)->parent))->left)) ? (((((n)->parent))->right)) : (((((n)->parent))->left)));
 }
 if (0 == ((((n)->parent)) ? (((((n)->parent))->color)) : (0)) &&
     0 == ((sibling) ? (((sibling)->color)) : (0)) &&
     0 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0)) &&
     0 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0))) {
  ((sibling)->color) = 1;
  rb_remove_bal(root, ((n)->parent));
  return;
 }
 if (1 == ((((n)->parent)) ? (((((n)->parent))->color)) : (0)) &&
     0 == ((sibling) ? (((sibling)->color)) : (0)) &&
     0 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0)) &&
     0 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0))) {
  ((sibling)->color) = 1;
  ((((n)->parent))->color) = 0;
 } else {
  if (((((n)->parent))->left) == n &&
      0 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0)) &&
      1 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0))) {
   ((sibling)->color) = 1;
   ((((sibling)->left))->color) = 0;
   rb_rotate_right(root, sibling);
  } else if (((((n)->parent))->right) == n &&
      0 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0)) &&
      1 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0))) {
   ((sibling)->color) = 1;
   ((((sibling)->right))->color) = 0;
   rb_rotate_left(root, sibling);
  }
  sibling = ((n == ((((n)->parent))->left)) ? (((((n)->parent))->right)) : (((((n)->parent))->left)));
  ((sibling)->color) = ((((n)->parent)) ? (((((n)->parent))->color)) : (0));
  ((((n)->parent))->color) = 0;
  if (((((n)->parent))->left) == n) {
   ((((sibling)->right))->color) = 0;
   rb_rotate_left(root, ((n)->parent));
  } else {
   ((((sibling)->left))->color) = 0;
   rb_rotate_right(root, ((n)->parent));
  }
 }
}

canonical_original_code:
inline static void rb_remove_bal(struct _rb_node **root, struct _rb_node *n) {
 struct _rb_node *sibling;
 if (!((n)->parent))
  return;
 sibling = ((n == ((((n)->parent))->left)) ? (((((n)->parent))->right)) : (((((n)->parent))->left)));
 if (1 == ((sibling) ? (((sibling)->color)) : (0))) {
  ((((n)->parent))->color) = 1;
  ((sibling)->color) = 0;
  if (n == ((((n)->parent))->left))
   rb_rotate_left(root, ((n)->parent));
  else
   rb_rotate_right(root, ((n)->parent));
  sibling = ((n == ((((n)->parent))->left)) ? (((((n)->parent))->right)) : (((((n)->parent))->left)));
 }
 if (0 == ((((n)->parent)) ? (((((n)->parent))->color)) : (0)) &&
     0 == ((sibling) ? (((sibling)->color)) : (0)) &&
     0 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0)) &&
     0 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0))) {
  ((sibling)->color) = 1;
  rb_remove_bal(root, ((n)->parent));
  return;
 }
 if (1 == ((((n)->parent)) ? (((((n)->parent))->color)) : (0)) &&
     0 == ((sibling) ? (((sibling)->color)) : (0)) &&
     0 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0)) &&
     0 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0))) {
  ((sibling)->color) = 1;
  ((((n)->parent))->color) = 0;
 } else {
  if (((((n)->parent))->left) == n &&
      0 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0)) &&
      1 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0))) {
   ((sibling)->color) = 1;
   ((((sibling)->left))->color) = 0;
   rb_rotate_right(root, sibling);
  } else if (((((n)->parent))->right) == n &&
      0 == ((((sibling)->left)) ? (((((sibling)->left))->color)) : (0)) &&
      1 == ((((sibling)->right)) ? (((((sibling)->right))->color)) : (0))) {
   ((sibling)->color) = 1;
   ((((sibling)->right))->color) = 0;
   rb_rotate_left(root, sibling);
  }
  sibling = ((n == ((((n)->parent))->left)) ? (((((n)->parent))->right)) : (((((n)->parent))->left)));
  ((sibling)->color) = ((((n)->parent)) ? (((((n)->parent))->color)) : (0));
  ((((n)->parent))->color) = 0;
  if (((((n)->parent))->left) == n) {
   ((((sibling)->right))->color) = 0;
   rb_rotate_left(root, ((n)->parent));
  } else {
   ((((sibling)->left))->color) = 0;
   rb_rotate_right(root, ((n)->parent));
  }
 }
}

variable_types:
n
struct _rb_node *


decompiled_code:
__int64 __fastcall rb_uncle(__int64 a1)
{
__int64 v1; // rdx
__int64 *v2; // rcx
__int64 result; // rax

if ( !a1 )
return 0LL;
v1 = *(_QWORD *)(a1 + 16);
if ( !v1 )
return 0LL;
v2 = *(__int64 **)(v1 + 16);
if ( !v2 )
return 0LL;
result = *v2;
if ( v1 == *v2 )
result = v2[1];
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
__int64 v1; // rdx
__int64 *v2; // rcx
__int64 result; // rax

if ( !a1 )
return 0LL;
v1 = *(_QWORD *)(a1 + 16);
if ( !v1 )
return 0LL;
v2 = *(__int64 **)(v1 + 16);
if ( !v2 )
return 0LL;
result = *v2;
if ( v1 == *v2 )
result = v2[1];
return result;
}

original_code:
inline static rb_node * rb_uncle(rb_node *n) {
        rb_node *grandparent;
        if (!(grandparent = (((n) && (((n)->parent))) ? (((((n)->parent))->parent)) : (((void *)0)))))
                return ((void *)0);
        if (((n)->parent) == ((grandparent)->left))
                return ((grandparent)->right);
        return ((grandparent)->left);
}

canonical_original_code:
inline static struct _rb_node *rb_uncle(struct _rb_node *n) {
        struct _rb_node *grandparent;
        if (!(grandparent = (((n) && (((n)->parent))) ? (((((n)->parent))->parent)) : (((void *)0)))))
                return ((void *)0);
        if (((n)->parent) == ((grandparent)->left))
                return ((grandparent)->right);
        return ((grandparent)->left);
}

return_type: struct _rb_node { struct _rb_node *left; int color; void *val; } *


original_code:
inline static void rb_insert_bal(rb_node **root, rb_node *n) {
 rb_node *grandparent, *uncle;
 if (*root == n)
  ((n)->color) = 0;
 else if (1 == ((((n)->parent)) ? (((((n)->parent))->color)) : (0))) {
  uncle = rb_uncle(n);
  grandparent = (((n) && (((n)->parent))) ? (((((n)->parent))->parent)) : (((void *)0)));
  if (1 == ((uncle) ? (((uncle)->color)) : (0))) {
   ((((n)->parent))->color) = ((uncle)->color) = 0;
   ((grandparent)->color) = 1;
   rb_insert_bal(root, grandparent);
   return;
  }
  if ((n == ((((n)->parent))->right)) &&
      (((n)->parent) == ((grandparent)->left))) {
   rb_rotate_left(root, ((n)->parent));
   n = ((n)->left);
  } else if ((n == ((((n)->parent))->left)) &&
      (((n)->parent) == ((grandparent)->right))) {
   rb_rotate_right(root, ((n)->parent));
   n = ((n)->right);
  }
  grandparent = (((n) && (((n)->parent))) ? (((((n)->parent))->parent)) : (((void *)0)));
  ((((n)->parent))->color) = 0;
  ((grandparent)->color) = 1;
  if ((n == ((((n)->parent))->left)) &&
      (((n)->parent) == ((grandparent)->left)))
   rb_rotate_right(root, grandparent);
  else
   rb_rotate_left(root, grandparent);
 }
}

canonical_original_code:
inline static void rb_insert_bal(struct _rb_node **root, struct _rb_node *n) {
 struct _rb_node *grandparent; struct _rb_node *uncle;
 if (*root == n)
  ((n)->color) = 0;
 else if (1 == ((((n)->parent)) ? (((((n)->parent))->color)) : (0))) {
  uncle = rb_uncle(n);
  grandparent = (((n) && (((n)->parent))) ? (((((n)->parent))->parent)) : (((void *)0)));
  if (1 == ((uncle) ? (((uncle)->color)) : (0))) {
   ((((n)->parent))->color) = ((uncle)->color) = 0;
   ((grandparent)->color) = 1;
   rb_insert_bal(root, grandparent);
   return;
  }
  if ((n == ((((n)->parent))->right)) &&
      (((n)->parent) == ((grandparent)->left))) {
   rb_rotate_left(root, ((n)->parent));
   n = ((n)->left);
  } else if ((n == ((((n)->parent))->left)) &&
      (((n)->parent) == ((grandparent)->right))) {
   rb_rotate_right(root, ((n)->parent));
   n = ((n)->right);
  }
  grandparent = (((n) && (((n)->parent))) ? (((((n)->parent))->parent)) : (((void *)0)));
  ((((n)->parent))->color) = 0;
  ((grandparent)->color) = 1;
  if ((n == ((((n)->parent))->left)) &&
      (((n)->parent) == ((grandparent)->left)))
   rb_rotate_right(root, grandparent);
  else
   rb_rotate_left(root, grandparent);
 }
}


original_code:
int rb_apply(rb_node *n, void (*func)(rb_node *)) {
 int i, j, size, sp;
 rb_node **stack;
 stack = ((void *)0);
 i = size = sp = 0;
 while (((void *)0) != n) {
  j = 0;
  if (((void *)0) != ((n)->right)) j++;
  if (((void *)0) != ((n)->left)) j++;
  if (sp + j >= size) {
   size += 2<<4;
   stack = realloc(stack, size * sizeof(rb_node *));
   if (((void *)0) == stack) return -1;
  }
  if (((n)->right)) stack[sp++] = ((n)->right);
  if (((n)->left)) stack[sp++] = ((n)->left);
  if (func) func(n);
  ++i;
  if (0 == sp) n = ((void *)0);
  else n = stack[--sp];
 }
 if (stack) free(stack);
 return i;
}

canonical_original_code:
int rb_apply(struct _rb_node *n, void (*func)(struct _rb_node *)) {
 int i; int j; int size; int sp;
 struct _rb_node **stack;
 stack = ((void *)0);
 i = size = sp = 0;
 while (((void *)0) != n) {
  j = 0;
  if (((void *)0) != ((n)->right)) j++;
  if (((void *)0) != ((n)->left)) j++;
  if (sp + j >= size) {
   size += 2<<4;
   stack = realloc(stack, size * sizeof(struct _rb_node *));
   if (((void *)0) == stack) return -1;
  }
  if (((n)->right)) stack[sp++] = ((n)->right);
  if (((n)->left)) stack[sp++] = ((n)->left);
  if (func) func(n);
  ++i;
  if (0 == sp) n = ((void *)0);
  else n = stack[--sp];
 }
 if (stack) free(stack);
 return i;
}

variable_types:
func
void (*)(struct _rb_node *)

variable_types: size int

variable_types: sp int


decompiled_code:
__int64 __fastcall rb_rapply(_QWORD *a1, void (__fastcall *a2)(_QWORD *))
{
__int64 result; // rax
int v3; // ebx
int v4; // ebx

result = 0LL;
if ( a1 )
{
v3 = rb_rapply(*a1);
v4 = rb_rapply(a1[1]) + v3;
if ( a2 )
a2(a1);
result = (unsigned int)(v4 + 1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(_QWORD *a1, void (__fastcall *a2)(_QWORD *))
{
__int64 result; // rax
int v3; // ebx
int v4; // ebx

result = 0LL;
if ( a1 )
{
v3 = func5(*a1);
v4 = func5(a1[1]) + v3;
if ( a2 )
a2(a1);
result = (unsigned int)(v4 + 1);
}
return result;
}

original_code:
int rb_rapply(rb_node *n, void (*func)(rb_node *)) {
 int i = 0;
 if (((void *)0) != n) {
  i += rb_rapply(((n)->left), func);
  i += rb_rapply(((n)->right), func);
  if (func) func(n);
  ++i;
 }
 return i;
}

canonical_original_code:
int rb_rapply(struct _rb_node *n, void (*func)(struct _rb_node *)) {
 int i = 0;
 if (((void *)0) != n) {
  i += rb_rapply(((n)->left), func);
  i += rb_rapply(((n)->right), func);
  if (func) func(n);
  ++i;
 }
 return i;
}

variable_types: i int


original_code:
void rb_insert(rb_node **root, rb_node *n) {
 rb_node *current, *parent;
 current = *root;
 while (((void *)0) != current) {
  parent = current;
  if (((n)->key) < ((current)->key)) current = ((current)->left);
  else current = ((current)->right);
 }
 ((n)->parent) = ((n)->left) = ((n)->right) = ((void *)0);
 ((n)->color) = 1;
 if (((void *)0) == *root)
  *root = n;
 else {
  ((n)->parent) = parent;
  if (((n)->key) < ((parent)->key)) ((parent)->left) = n;
  else ((parent)->right) = n;
 }
 rb_insert_bal(root, n);
}

canonical_original_code:
void rb_insert(struct _rb_node **root, struct _rb_node *n) {
 struct _rb_node *current; struct _rb_node *parent;
 current = *root;
 while (((void *)0) != current) {
  parent = current;
  if (((n)->key) < ((current)->key)) current = ((current)->left);
  else current = ((current)->right);
 }
 ((n)->parent) = ((n)->left) = ((n)->right) = ((void *)0);
 ((n)->color) = 1;
 if (((void *)0) == *root)
  *root = n;
 else {
  ((n)->parent) = parent;
  if (((n)->key) < ((parent)->key)) ((parent)->left) = n;
  else ((parent)->right) = n;
 }
 rb_insert_bal(root, n);
}