original_code:
void handle_error(request_t *q, char *name, int errno)
{
 char buf[8192], body[8192],errnum[8192],msg[8192],title[8192];
 sprintf(body, "<html><title>XMJ error</title>\r\n");
 switch(errno)
 {
 case NO501:
  strcpy(errnum,"501");
  strcpy(msg,"We doesnt implement the method");
  strcpy(title,"Not Implemented");
  break;
 case NO403:
  strcpy(errnum,"403");
  strcpy(msg,"The read/run operation is denied");
  strcpy(title,"Forbidden");
  break;
 case NO404:
  strcpy(errnum,"404");
  strcpy(msg,"Counldnt find the resource file");
  strcpy(title,"Not found");
  break;
 }
 sprintf(body,"%s%s: %s\r\n",body,errnum,title);
 sprintf(body,"%s<p>%s : %s</p>\r\n",body, msg, name);
 sprintf(buf, "%s %s %s\r\n",q->ver,errnum,title);
 io_writen(q->io, buf, strlen(buf));
 sprintf(buf, "Content-type: text/html\r\n");
 io_writen(q->io, buf, strlen(buf));
 sprintf(buf, "Content-length: %d\r\n\r\n",(int)strlen(body));
 io_writen(q->io, buf, strlen(buf));
 io_writen(q->io, body, strlen(body));
}

canonical_original_code:
void handle_error(struct __request_t *q, char *name, int errno)
{
 char buf[8192]; char body[8192]; char errnum[8192]; char msg[8192]; char title[8192];
 sprintf(body, "<html><title>XMJ error</title>\r\n");
 switch(errno)
 {
 case NO501:
  strcpy(errnum,"501");
  strcpy(msg,"We doesnt implement the method");
  strcpy(title,"Not Implemented");
  break;
 case NO403:
  strcpy(errnum,"403");
  strcpy(msg,"The read/run operation is denied");
  strcpy(title,"Forbidden");
  break;
 case NO404:
  strcpy(errnum,"404");
  strcpy(msg,"Counldnt find the resource file");
  strcpy(title,"Not found");
  break;
 }
 sprintf(body,"%s%s: %s\r\n",body,errnum,title);
 sprintf(body,"%s<p>%s : %s</p>\r\n",body, msg, name);
 sprintf(buf, "%s %s %s\r\n",q->ver,errnum,title);
 io_writen(q->io, buf, strlen(buf));
 sprintf(buf, "Content-type: text/html\r\n");
 io_writen(q->io, buf, strlen(buf));
 sprintf(buf, "Content-length: %d\r\n\r\n",(int)strlen(body));
 io_writen(q->io, buf, strlen(buf));
 io_writen(q->io, body, strlen(body));
}

variable_types:
name
char *

variable_types: errno int

variable_types:
body
char [8192]

variable_types:
errnum
char [8192]

variable_types:
msg
char [8192]

variable_types:
title
char [8192]


debugPrint

repo: pkuderov/farach-suffix-tree

decompiled_code:
int __fastcall debugPrint(char *format)
{
int result; // eax

result = DEBUG;
if ( DEBUG )
{
fprintf(stdout, format, 0LL);
result = fflush(stdout);
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(char *format)
{
int result; // eax

result = DEBUG;
if ( DEBUG )
{
fprintf(stdout, format, 0LL);
result = fflush(stdout);
}
return result;
}

original_code:
inline void debugPrint(const char *s)
{
    do { if (DEBUG) { fprintf(stdout, s, ((void *)0)); fflush(stdout); }} while (0);
}

canonical_original_code:
inline void debugPrint(char *s)
{
    do { if (DEBUG) { fprintf(stdout, s, ((void *)0)); fflush(stdout); }} while (0);
}

variable_types:
s
char *

return_type: void


debugArr

decompiled_code:
int __fastcall debugArr(unsigned int *a1, int a2)
{
unsigned int *v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdx

debugPrint("[");
if ( a2 > 0 )
{
if ( DEBUG )
{
fprintf(stdout, "%d", *a1);
fflush(stdout);
}
if ( a2 != 1 )
{
v2 = a1 + 1;
v3 = (__int64)&a1[a2 - 2 + 2];
do
{
while ( !DEBUG )
{
if ( ++v2 == (unsigned int *)v3 )
return debugPrint("]\n");
}
v4 = *v2++;
fprintf(stdout, ", %d", v4);
fflush(stdout);
}
while ( v2 != (unsigned int *)v3 );
}
}
return debugPrint("]\n");
}

canonical_decompiled_code:
int __fastcall func1(unsigned int *a1, int a2)
{
unsigned int *v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdx

func0("[");
if ( a2 > 0 )
{
if ( DEBUG )
{
fprintf(stdout, "%d", *a1);
fflush(stdout);
}
if ( a2 != 1 )
{
v2 = a1 + 1;
v3 = (__int64)&a1[a2 - 2 + 2];
do
{
while ( !DEBUG )
{
if ( ++v2 == (unsigned int *)v3 )
return func0("]\n");
}
v4 = *v2++;
fprintf(stdout, ", %d", v4);
fflush(stdout);
}
while ( v2 != (unsigned int *)v3 );
}
}
return func0("]\n");
}

original_code:
void debugArr(int *a, int n)
{
    debugPrint("[");
    if (n > 0)
    {
        do { if (DEBUG) { fprintf(stdout, "%d", a[0]); fflush(stdout); }} while (0);
        for (int i = 1; i < n; i++)
        {
            do { if (DEBUG) { fprintf(stdout, ", %d", a[i]); fflush(stdout); }} while (0);
        }
    }
    debugPrint("]\n");
}

variable_types:
a
int *

variable_types: n int

variable_types: i int


debugInt

decompiled_code:
int __fastcall debugInt(unsigned int a1)
{
int result; // eax

result = DEBUG;
if ( DEBUG )
{
fprintf(stdout, "%d\n", a1);
result = fflush(stdout);
}
return result;
}

canonical_decompiled_code:
int __fastcall func2(unsigned int a1)
{
int result; // eax

result = DEBUG;
if ( DEBUG )
{
fprintf(stdout, "%d\n", a1);
result = fflush(stdout);
}
return result;
}

original_code:
inline void debugInt(int x)
{
    do { if (DEBUG) { fprintf(stdout, "%d\n", x); fflush(stdout); }} while (0);
}

variable_types: x int


debugIntVar

decompiled_code:
int __fastcall debugIntVar(unsigned int a1, const char *a2)
{
int result; // eax

result = DEBUG;
if ( DEBUG )
{
fprintf(stdout, "%s = %d\n", a2, a1);
result = fflush(stdout);
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(unsigned int a1, const char *a2)
{
int result; // eax

result = DEBUG;
if ( DEBUG )
{
fprintf(stdout, "%s = %d\n", a2, a1);
result = fflush(stdout);
}
return result;
}

original_code:
inline void debugIntVar(int x, const char *s)
{
    do { if (DEBUG) { fprintf(stdout, "%s = %d\n", s, x); fflush(stdout); }} while (0);
}

canonical_original_code:
inline void debugIntVar(int x, char *s)
{
    do { if (DEBUG) { fprintf(stdout, "%s = %d\n", s, x); fflush(stdout); }} while (0);
}


ConcatStrings

decompiled_code:
char *__fastcall ConcatStrings(void *src, void *a2)
{
size_t v2; // rbx
size_t v3; // rbp
char *v4; // r12

v2 = strlen((const char *)src);
v3 = strlen((const char *)a2);
v4 = (char *)malloc(v2 + v3 + 1);
memcpy(v4, src, v2);
memcpy(&v4[v2], a2, v3 + 1);
return v4;
}

canonical_decompiled_code:
char *__fastcall func4(void *src, void *a2)
{
size_t v2; // rbx
size_t v3; // rbp
char *v4; // r12

v2 = strlen((const char *)src);
v3 = strlen((const char *)a2);
v4 = (char *)malloc(v2 + v3 + 1);
memcpy(v4, src, v2);
memcpy(&v4[v2], a2, v3 + 1);
return v4;
}

original_code:
char *ConcatStrings(const char *s1, const char *s2)
{
    char *s = malloc(strlen(s1) + strlen(s2) + 1);
    strcpy(s, s1);
    strcpy(s + strlen(s1), s2);
    return s;
}

canonical_original_code:
char *ConcatStrings(char *s1, char *s2)
{
    char *s = malloc(strlen(s1) + strlen(s2) + 1);
    strcpy(s, s1);
    strcpy(s + strlen(s1), s2);
    return s;
}

return_type: char *


MemFree

decompiled_code:
void __fastcall MemFree(void *a1)
{
if ( a1 )
free(a1);
}

canonical_decompiled_code:
void __fastcall func5(void *a1)
{
if ( a1 )
free(a1);
}

original_code:
inline void MemFree(void *a)
{
    if (a) free(a);
}

variable_types:
a
void *


decompiled_code:
__int64 __fastcall Log2(int a1)
{
unsigned int v1; // ecx

v1 = 0;
if ( a1 > 1 )
{
do
++v1;
while ( 1 << v1 < a1 );
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func6(int a1)
{
unsigned int v1; // ecx

v1 = 0;
if ( a1 > 1 )
{
do
++v1;
while ( 1 << v1 < a1 );
}
return v1;
}

original_code:
int Log2(int x)
{
 int res = 0;
 while (1 << res < x)
        res++;
 return res;
}

variable_types: res int

return_type: int


Swap

decompiled_code:
__int64 __fastcall Swap(_DWORD *a1, _DWORD *a2)
{
__int64 result; // rax

result = (unsigned int)*a1;
*a1 = *a2;
*a2 = result;
return result;
}

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

result = (unsigned int)*a1;
*a1 = *a2;
*a2 = result;
return result;
}

original_code:
void Swap(int *x, int *y)
{
    int t = *x;
    *x = *y;
    *y = t;
}

variable_types:
x
int *

variable_types:
y
int *

variable_types: t int


FreeDynamicArray

decompiled_code:
void __fastcall FreeDynamicArray(void **a1)
{
if ( a1 )
{
MemFree(a1[1]);
MemFree(a1);
}
}

canonical_decompiled_code:
void __fastcall func8(void **a1)
{
if ( a1 )
{
func5(a1[1]);
func5(a1);
}
}

original_code:
void FreeDynamicArray(DynamicArray *arr)
{
    if (!arr)
        return;
    MemFree(arr->a);
    MemFree(arr);
}

canonical_original_code:
void FreeDynamicArray(struct _dynamicArray *arr)
{
    if (!arr)
        return;
    MemFree(arr->a);
    MemFree(arr);
}

variable_types: struct _dynamicArray { int count; int *a; } *


LastInDynamicArray

decompiled_code:
__int64 __fastcall LastInDynamicArray(int *a1)
{
return *((_QWORD *)a1 + 1) + 4LL * *a1 - 4;
}

canonical_decompiled_code:
__int64 __fastcall func9(int *a1)
{
return *((_QWORD *)a1 + 1) + 4LL * *a1 - 4;
}

original_code:
inline int *LastInDynamicArray(DynamicArray *arr)
{
    return (arr->a + arr->count - 1);
}

canonical_original_code:
inline int *LastInDynamicArray(struct _dynamicArray *arr)
{
    return (arr->a + arr->count - 1);
}

return_type: int *

user_defined_types: struct _dynamicArray { int count; int *a; }


PushToDynamicArray

decompiled_code:
__int64 __fastcall PushToDynamicArray(int *a1, int a2)
{
__int64 result; // rax
void *v4; // rdi
_DWORD *v5; // rax
_DWORD *v6; // rdi

result = *a1;
v4 = (void *)*((_QWORD *)a1 + 1);
if ( (_DWORD)result != a1[1] )
goto LABEL_2;
v5 = realloc(v4, 8LL * (_DWORD)result);
v6 = v5;
if ( !v5 )
{
v4 = (void *)*((_QWORD *)a1 + 1);
result = *a1;
LABEL_2:
*((_DWORD *)v4 + result) = a2;
++*a1;
return result;
}
*((_QWORD *)a1 + 1) = v5;
result = *a1;
a1[1] *= 2;
v6[result] = a2;
++*a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(int *a1, int a2)
{
__int64 result; // rax
void *v4; // rdi
_DWORD *v5; // rax
_DWORD *v6; // rdi

result = *a1;
v4 = (void *)*((_QWORD *)a1 + 1);
if ( (_DWORD)result != a1[1] )
goto LABEL_2;
v5 = realloc(v4, 8LL * (_DWORD)result);
v6 = v5;
if ( !v5 )
{
v4 = (void *)*((_QWORD *)a1 + 1);
result = *a1;
LABEL_2:
*((_DWORD *)v4 + result) = a2;
++*a1;
return result;
}
*((_QWORD *)a1 + 1) = v5;
result = *a1;
a1[1] *= 2;
v6[result] = a2;
++*a1;
return result;
}

original_code:
void PushToDynamicArray(DynamicArray *arr, int x)
{
    if (arr->count == arr->capacity)
    {
        int *t = realloc(arr->a, 2 * arr->capacity * sizeof *t);
        if (t)
        {
            arr->a = t;
            arr->capacity = arr->capacity << 1;
        }
    }
    arr->a[arr->count] = x;
    ++(arr->count);
}

canonical_original_code:
void PushToDynamicArray(struct _dynamicArray *arr, int x)
{
    if (arr->count == arr->capacity)
    {
        int *t = realloc(arr->a, 2 * arr->capacity * sizeof *t);
        if (t)
        {
            arr->a = t;
            arr->capacity = arr->capacity << 1;
        }
    }
    arr->a[arr->count] = x;
    ++(arr->count);
}

variable_types:
t
int *


PopFromDynamicArray

decompiled_code:
__int64 __fastcall PopFromDynamicArray(__int64 a1)
{
__int64 v1; // rdx
int v2; // eax

v1 = *(_QWORD *)(a1 + 8);
v2 = *(_DWORD *)a1 - 1;
*(_DWORD *)a1 = v2;
return *(unsigned int *)(v1 + 4LL * v2);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
__int64 v1; // rdx
int v2; // eax

v1 = *(_QWORD *)(a1 + 8);
v2 = *(_DWORD *)a1 - 1;
*(_DWORD *)a1 = v2;
return *(unsigned int *)(v1 + 4LL * v2);
}

original_code:
int PopFromDynamicArray(DynamicArray *arr)
{
    return arr->a[--(arr->count)];
}

canonical_original_code:
int PopFromDynamicArray(struct _dynamicArray *arr)
{
    return arr->a[--(arr->count)];
}


FreeDynamicQueue

decompiled_code:
void __fastcall FreeDynamicQueue(void **a1)
{
if ( a1 )
{
MemFree(a1[2]);
MemFree(a1);
}
}

canonical_decompiled_code:
void __fastcall func12(void **a1)
{
if ( a1 )
{
func5(a1[2]);
func5(a1);
}
}

original_code:
void FreeDynamicQueue(DynamicQueue *queue)
{
    if (!queue)
        return;
    MemFree(queue->a);
    MemFree(queue);
}

canonical_original_code:
void FreeDynamicQueue(struct _dynamicQueue *queue)
{
    if (!queue)
        return;
    MemFree(queue->a);
    MemFree(queue);
}

variable_types: struct _dynamicQueue { int top; int *a; } *


PushToDynamicQueue

original_code:
void PushToDynamicQueue(DynamicQueue *queue, int x)
{
    if (queue->count == queue->capacity)
    {
        int *t = realloc(queue->a, 2 * queue->capacity * sizeof *t);
        if (t)
        {
            queue->a = t;
            if (queue->top <= queue->bottom)
            {
                if (queue->top < (queue->capacity - queue->bottom))
                {
                    memcpy(queue->a + queue->capacity, queue->a, queue->top * sizeof *queue->a);
                    queue->top += queue->capacity;
                }
                else
                {
                    memcpy(queue->a + queue->bottom + queue->capacity, queue->a + queue->bottom, (queue->capacity - queue->bottom) * sizeof *queue->a);
                    queue->bottom += queue->capacity;
                }
            }
            queue->capacity = queue->capacity << 1;
        }
    }
    queue->a[queue->top] = x;
    ++(queue->top);
    ++(queue->count);
    if (queue->top == queue->capacity)
        queue->top = 0;
}

canonical_original_code:
void PushToDynamicQueue(struct _dynamicQueue *queue, int x)
{
    if (queue->count == queue->capacity)
    {
        int *t = realloc(queue->a, 2 * queue->capacity * sizeof *t);
        if (t)
        {
            queue->a = t;
            if (queue->top <= queue->bottom)
            {
                if (queue->top < (queue->capacity - queue->bottom))
                {
                    memcpy(queue->a + queue->capacity, queue->a, queue->top * sizeof *queue->a);
                    queue->top += queue->capacity;
                }
                else
                {
                    memcpy(queue->a + queue->bottom + queue->capacity, queue->a + queue->bottom, (queue->capacity - queue->bottom) * sizeof *queue->a);
                    queue->bottom += queue->capacity;
                }
            }
            queue->capacity = queue->capacity << 1;
        }
    }
    queue->a[queue->top] = x;
    ++(queue->top);
    ++(queue->count);
    if (queue->top == queue->capacity)
        queue->top = 0;
}

user_defined_types: struct _dynamicQueue { int top; int *a; }


PeekToDynamicQueue

decompiled_code:
__int64 __fastcall PeekToDynamicQueue(__int64 a1)
{
return *(unsigned int *)(*(_QWORD *)(a1 + 16) + 4LL * *(int *)(a1 + 4));
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1)
{
return *(unsigned int *)(*(_QWORD *)(a1 + 16) + 4LL * *(int *)(a1 + 4));
}

original_code:
inline int PeekToDynamicQueue(DynamicQueue *queue)
{
    return queue->a[queue->bottom];
}

canonical_original_code:
inline int PeekToDynamicQueue(struct _dynamicQueue *queue)
{
    return queue->a[queue->bottom];
}


PopFromDynamicQueue

decompiled_code:
__int64 __fastcall PopFromDynamicQueue(_DWORD *a1)
{
unsigned int v1; // eax
unsigned int v2; // er8
int v3; // eax

v1 = PeekToDynamicQueue((__int64)a1);
--a1[2];
v2 = v1;
v3 = a1[1] + 1;
a1[1] = v3;
if ( v3 == a1[3] )
a1[1] = 0;
return v2;
}

original_code:
int PopFromDynamicQueue(DynamicQueue *queue)
{
    int x = PeekToDynamicQueue(queue);
    ++(queue->bottom);
    --(queue->count);
    if (queue->bottom == queue->capacity)
        queue->bottom = 0;
    return x;
}

canonical_original_code:
int PopFromDynamicQueue(struct _dynamicQueue *queue)
{
    int x = PeekToDynamicQueue(queue);
    ++(queue->bottom);
    --(queue->count);
    if (queue->bottom == queue->capacity)
        queue->bottom = 0;
    return x;
}


FreeDfsPosition

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

if ( a1 )
{
FreeDynamicArray(*(_QWORD *)(a1 + 32));
result = MemFree(a1);
}
return result;
}

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

if ( a1 )
{
FreeDynamicArray(*(_QWORD *)(a1 + 32));
result = MemFree(a1);
}
return result;
}

original_code:
void FreeDfsPosition(DfsPosition *p)
{
    if (!p)
        return;
    FreeDynamicArray(p->lastChild);
    MemFree(p);
}

canonical_original_code:
void FreeDfsPosition(struct _dfsPosition *p)
{
    if (!p)
        return;
    FreeDynamicArray(p->lastChild);
    MemFree(p);
}

variable_types: struct _dfsPosition { struct _suffixTree { int count; struct _suffixTreeNode { int parent; int *children; int childrenCount; } *nodes; struct _suffixArray { int n; int *lcp; int *suffixToRank; } *suffixArray; } *tree; int treeType; int *s; int ind; struct _dynamicArray { int count; int *a; } *lastChild; int lastDfsLeaf; } *

user_defined_types: struct _dfsPosition { struct _suffixTree *tree; int treeType; int *s; int ind; struct _dynamicArray *lastChild; int lastDfsLeaf; }

user_defined_types: struct _suffixTree { int count; struct _suffixTreeNode *nodes; struct _suffixArray *suffixArray; }


EndOfDfs

decompiled_code:
_BOOL8 __fastcall EndOfDfs(__int64 a1)
{
_BOOL8 result; // rax

if ( *(_DWORD *)(a1 + 28) )
result = 0LL;
else
result = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 16LL) + 24LL) == *(_DWORD *)LastInDynamicArray(*(_QWORD *)(a1 + 32));
return result;
}

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

if ( *(_DWORD *)(a1 + 28) )
result = 0LL;
else
result = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 16LL) + 24LL) == *(_DWORD *)LastInDynamicArray(*(_QWORD *)(a1 + 32));
return result;
}

original_code:
inline int EndOfDfs(DfsPosition *p)
{
    return 0 == p->ind && *LastInDynamicArray(p->lastChild) == p->tree->nodes[0].childrenCount;
}

canonical_original_code:
inline int EndOfDfs(struct _dfsPosition *p)
{
    return 0 == p->ind && *LastInDynamicArray(p->lastChild) == p->tree->nodes[0].childrenCount;
}

user_defined_types: struct _suffixTreeNode { int parent; int *children; int childrenCount; }

user_defined_types: struct _suffixArray { int n; int *lcp; int *suffixToRank; }


GetChildIndex

decompiled_code:
__int64 __fastcall GetChildIndex(__int64 a1)
{
__int64 v1; // rbx

v1 = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 16LL) + 32LL * *(int *)(a1 + 28) + 16);
return *(unsigned int *)(v1 + 4LL * *(int *)LastInDynamicArray(*(_QWORD *)(a1 + 32)));
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
__int64 v1; // rbx

v1 = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 16LL) + 32LL * *(int *)(a1 + 28) + 16);
return *(unsigned int *)(v1 + 4LL * *(int *)LastInDynamicArray(*(_QWORD *)(a1 + 32)));
}

original_code:
inline int GetChildIndex(DfsPosition *p)
{
    return p->tree->nodes[p->ind].children[*LastInDynamicArray(p->lastChild)];
}

canonical_original_code:
inline int GetChildIndex(struct _dfsPosition *p)
{
    return p->tree->nodes[p->ind].children[*LastInDynamicArray(p->lastChild)];
}


GetEdgeLength

decompiled_code:
__int64 __fastcall GetEdgeLength(int *a1)
{
__int64 v1; // rbp

v1 = *(_QWORD *)(*(_QWORD *)a1 + 16LL);
return (unsigned int)(*(_DWORD *)(v1 + 32LL * (int)GetChildIndex((__int64)a1) + 8) - *(_DWORD *)(v1 + 32LL * a1[7] + 8));
}

original_code:
inline int GetEdgeLength(DfsPosition *p)
{
    return p->tree->nodes[GetChildIndex(p)].depth - p->tree->nodes[p->ind].depth;
}

canonical_original_code:
inline int GetEdgeLength(struct _dfsPosition *p)
{
    return p->tree->nodes[GetChildIndex(p)].depth - p->tree->nodes[p->ind].depth;
}


GetFirstCharOfChildEdge

decompiled_code:
__int64 __fastcall GetFirstCharOfChildEdge(__int64 a1)
{
_DWORD *v1; // rax
__int64 v2; // rbx
__int64 v4; // r12

v1 = (_DWORD *)LastInDynamicArray(*(_QWORD *)(a1 + 32));
v2 = *(_QWORD *)(*(_QWORD *)a1 + 16LL);
if ( *v1 >= *(_DWORD *)(v2 + 32LL * *(int *)(a1 + 28) + 24) )
return *(unsigned int *)(*(_QWORD *)(a1 + 16) + 4LL * *(int *)(a1 + 24));
v4 = *(_QWORD *)(a1 + 16);
return *(unsigned int *)(v4 + 4LL * *(int *)(v2 + 32LL * (int)GetChildIndex(a1) + 4));
}

original_code:
inline int GetFirstCharOfChildEdge(DfsPosition *p)
{
    return *LastInDynamicArray(p->lastChild) < p->tree->nodes[p->ind].childrenCount
        ? p->s[p->tree->nodes[GetChildIndex(p)].from]
        : p->s[p->n];
}

canonical_original_code:
inline int GetFirstCharOfChildEdge(struct _dfsPosition *p)
{
    return *LastInDynamicArray(p->lastChild) < p->tree->nodes[p->ind].childrenCount
        ? p->s[p->tree->nodes[GetChildIndex(p)].from]
        : p->s[p->n];
}


CompareAndSwapDfsPositions

decompiled_code:
__int64 __fastcall CompareAndSwapDfsPositions(__int64 *a1, __int64 *a2)
{
int *v3; // rdi
__int64 v4; // r13
__int64 v5; // rdx
int v6; // eax
__int64 result; // rax
unsigned int v8; // er8
int v9; // ebx
int v10; // ecx

v3 = (int *)*a1;
v4 = *a2;
v5 = *(_QWORD *)(*(_QWORD *)v3 + 16LL) + 32LL * v3[7];
v6 = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)*a2 + 16LL) + 32LL * *(int *)(*a2 + 28) + 8);
if ( *(_DWORD *)(v5 + 8) == v6 )
{
v9 = GetFirstCharOfChildEdge((__int64)v3);
v10 = GetFirstCharOfChildEdge(v4);
if ( v9 > v10 )
SwapPositions(a1, a2);
result = v9 != v10;
}
else if ( *(_DWORD *)(v5 + 8) < v6 )
{
SwapPositions(a1, a2);
result = v8;
}
else
{
result = 1LL;
}
return result;
}

original_code:
int CompareAndSwapDfsPositions(DfsPosition **ppx, DfsPosition **ppy)
{
    DfsPosition *px = *ppx, *py = *ppy;
    if (px->tree->nodes[px->ind].depth == py->tree->nodes[py->ind].depth)
    {
        int cx = GetFirstCharOfChildEdge(px);
        int cy = GetFirstCharOfChildEdge(py);
        if (cx > cy)
            SwapPositions(ppx, ppy);
        return cx != cy;
    }
    else
    {
        if (px->tree->nodes[px->ind].depth < py->tree->nodes[py->ind].depth)
            SwapPositions(ppx, ppy);
        return 1;
    }
}

canonical_original_code:
int CompareAndSwapDfsPositions(struct _dfsPosition **ppx, struct _dfsPosition **ppy)
{
    struct _dfsPosition *px = *ppx; struct _dfsPosition *py = *ppy;
    if (px->tree->nodes[px->ind].depth == py->tree->nodes[py->ind].depth)
    {
        int cx = GetFirstCharOfChildEdge(px);
        int cy = GetFirstCharOfChildEdge(py);
        if (cx > cy)
            SwapPositions(ppx, ppy);
        return cx != cy;
    }
    else
    {
        if (px->tree->nodes[px->ind].depth < py->tree->nodes[py->ind].depth)
            SwapPositions(ppx, ppy);
        return 1;
    }
}

variable_types: struct _dfsPosition { struct _suffixTree { int count; struct _suffixTreeNode { int parent; int *children; int childrenCount; } *nodes; struct _suffixArray { int n; int *lcp; int *suffixToRank; } *suffixArray; } *tree; int treeType; int *s; int ind; struct _dynamicArray { int count; int *a; } *lastChild; int lastDfsLeaf; } **

variable_types:
ppy
struct _dfsPosition **

variable_types: cx int

variable_types: cy int


NextStepOfDfs

decompiled_code:
__int64 __fastcall NextStepOfDfs(__int64 a1, int a2)
{
__int64 v3; // rcx
_DWORD *v4; // rdi
_DWORD *v5; // rax
_DWORD *v6; // r9
__int64 v7; // rdx
__int64 v8; // r8
int *v9; // rax
int v11; // eax
__int64 v12; // rdi

if ( *(_DWORD *)LastInDynamicArray(*(_QWORD *)(a1 + 32)) < *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 16LL)
+ 32LL * *(int *)(a1 + 28)
+ 24) )
{
v11 = GetChildIndex(a1);
v12 = *(_QWORD *)(a1 + 32);
*(_DWORD *)(a1 + 28) = v11;
PushToDynamicArray(v12, 0LL);
}
while ( 1 )
{
v6 = (_DWORD *)LastInDynamicArray(*(_QWORD *)(a1 + 32));
v7 = *(_QWORD *)(*(_QWORD *)a1 + 16LL);
v8 = *(int *)(a1 + 28);
v9 = (int *)(v7 + 32 * v8);
if ( *v6 < v9[6] )
{
LODWORD(v8) = 1;
return (unsigned int)v8;
}
if ( !(_DWORD)v8 )
return (unsigned int)v8;
v3 = *v9;
if ( *(_DWORD *)(v7 + 32 * v3 + 8) < a2 )
break;
v4 = *(_DWORD **)(a1 + 32);
*(_DWORD *)(a1 + 28) = v3;
--*v4;
v5 = (_DWORD *)LastInDynamicArray(v4);
++*v5;
}
return 0LL;
}

original_code:
int NextStepOfDfs(DfsPosition *p, int minDepth)
{
    if (*LastInDynamicArray(p->lastChild) < p->tree->nodes[p->ind].childrenCount)
    {
        p->ind = GetChildIndex(p);
        PushToDynamicArray(p->lastChild, 0);
    }
    while (*LastInDynamicArray(p->lastChild) >= p->tree->nodes[p->ind].childrenCount)
    {
        if (p->ind == 0 || p->tree->nodes[p->tree->nodes[p->ind].parent].depth < minDepth)
            return 0;
        p->ind = p->tree->nodes[p->ind].parent;
        --(p->lastChild->count);
        ++(*LastInDynamicArray(p->lastChild));
    }
    return 1;
}

canonical_original_code:
int NextStepOfDfs(struct _dfsPosition *p, int minDepth)
{
    if (*LastInDynamicArray(p->lastChild) < p->tree->nodes[p->ind].childrenCount)
    {
        p->ind = GetChildIndex(p);
        PushToDynamicArray(p->lastChild, 0);
    }
    while (*LastInDynamicArray(p->lastChild) >= p->tree->nodes[p->ind].childrenCount)
    {
        if (p->ind == 0 || p->tree->nodes[p->tree->nodes[p->ind].parent].depth < minDepth)
            return 0;
        p->ind = p->tree->nodes[p->ind].parent;
        --(p->lastChild->count);
        ++(*LastInDynamicArray(p->lastChild));
    }
    return 1;
}

variable_types: minDepth int


FreePrefixTree

decompiled_code:
__int64 __fastcall FreePrefixTree(__int64 a1)
{
return MemFree(*(_QWORD *)(a1 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return MemFree(*(_QWORD *)(a1 + 8));
}

original_code:
void FreePrefixTree(PrefixTree *pTree)
{
    MemFree(pTree->nodes);
}

canonical_original_code:
void FreePrefixTree(struct _prefixTree *pTree)
{
    MemFree(pTree->nodes);
}

variable_types: struct _prefixTree { int count; struct _prefixTreeNode { int rank; int children[28]; } *nodes; } *

user_defined_types: struct _prefixTree { int count; struct _prefixTreeNode *nodes; }


AllocateNextIndexInPrefixTree

original_code:
void AllocateNextIndexInPrefixTree(PrefixTree *pTree)
{
    int i = pTree->count;
    if (i == pTree->capacity)
    {
        PrefixTreeNode *t = realloc(pTree->nodes, 2 * pTree->capacity * sizeof *pTree->nodes);
        if (t)
        {
            pTree->nodes = t;
            pTree->capacity = pTree->capacity << 1;
        }
        else
            printf("bad prefix tree nodes realloc\n");
    }
    pTree->nodes[i].rank = -1;
    for (int j = 0; j < 28; j++)
        pTree->nodes[i].children[j] = -1;
    pTree->count++;
}

canonical_original_code:
void AllocateNextIndexInPrefixTree(struct _prefixTree *pTree)
{
    int i = pTree->count;
    if (i == pTree->capacity)
    {
        struct _prefixTreeNode *t = realloc(pTree->nodes, 2 * pTree->capacity * sizeof *pTree->nodes);
        if (t)
        {
            pTree->nodes = t;
            pTree->capacity = pTree->capacity << 1;
        }
        else
            printf("bad prefix tree nodes realloc\n");
    }
    pTree->nodes[i].rank = -1;
    for (int j = 0; j < 28; j++)
        pTree->nodes[i].children[j] = -1;
    pTree->count++;
}

variable_types: i int

variable_types: struct _prefixTreeNode { int rank; int children[28]; } *

variable_types: j int


InitializePrefixTree

decompiled_code:
void __fastcall InitializePrefixTree(__int64 a1, int a2)
{
void *v2; // rax

*(_DWORD *)(a1 + 4) = a2;
*(_DWORD *)a1 = 0;
v2 = malloc(116LL * a2);
*(_QWORD *)(a1 + 8) = v2;
if ( v2 )
AllocateNextIndexInPrefixTree((int *)a1);
else
puts("bad malloc in InitializePrefixTree");
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1, int a2)
{
void *v2; // rax

*(_DWORD *)(a1 + 4) = a2;
*(_DWORD *)a1 = 0;
v2 = malloc(116LL * a2);
*(_QWORD *)(a1 + 8) = v2;
if ( v2 )
func1((int *)a1);
else
puts("bad malloc in InitializePrefixTree");
}

original_code:
void InitializePrefixTree(PrefixTree *pTree, int capacity)
{
    pTree->count = 0;
    pTree->capacity = capacity;
    pTree->nodes = malloc(capacity * sizeof *pTree->nodes);
    if (pTree->nodes)
    {
        AllocateNextIndexInPrefixTree(pTree);
    }
    else
        printf("bad malloc in InitializePrefixTree\n");
}

canonical_original_code:
void InitializePrefixTree(struct _prefixTree *pTree, int capacity)
{
    pTree->count = 0;
    pTree->capacity = capacity;
    pTree->nodes = malloc(capacity * sizeof *pTree->nodes);
    if (pTree->nodes)
    {
        AllocateNextIndexInPrefixTree(pTree);
    }
    else
        printf("bad malloc in InitializePrefixTree\n");
}

variable_types: capacity int

user_defined_types: struct _prefixTreeNode { int rank; int children[28]; }


CompleteBuildingPrefixTree

decompiled_code:
__int64 __fastcall CompleteBuildingPrefixTree(__int64 a1, int a2, _DWORD *a3)
{
__int64 v3; // r13
__int64 v5; // rax
int v6; // ebx
__int64 result; // rax
__int64 v8; // rsi
int v9; // ecx

v3 = 116LL * a2;
v5 = *(_QWORD *)(a1 + 8);
if ( *(_DWORD *)(v5 + v3) == 1 )
{
v9 = (*a3)++;
*(_DWORD *)(v5 + 116LL * a2) = v9;
}
v6 = 0;
while ( 1 )
{
result = v5 + 4LL * v6;
v8 = *(unsigned int *)(v3 + result + 4);
if ( (int)v8 >= 0 )
result = CompleteBuildingPrefixTree(a1, v8, a3);
if ( ++v6 == 28 )
break;
v5 = *(_QWORD *)(a1 + 8);
}
return result;
}

original_code:
void CompleteBuildingPrefixTree(PrefixTree *pTree, int i, int *rank)
{
    if (1 == pTree->nodes[i].rank)
        pTree->nodes[i].rank = (*rank)++;
    for (int j = 0; j < 28; j++)
    {
        if (pTree->nodes[i].children[j] >= 0)
            CompleteBuildingPrefixTree(pTree, pTree->nodes[i].children[j], rank);
    }
}

canonical_original_code:
void CompleteBuildingPrefixTree(struct _prefixTree *pTree, int i, int *rank)
{
    if (1 == pTree->nodes[i].rank)
        pTree->nodes[i].rank = (*rank)++;
    for (int j = 0; j < 28; j++)
    {
        if (pTree->nodes[i].children[j] >= 0)
            CompleteBuildingPrefixTree(pTree, pTree->nodes[i].children[j], rank);
    }
}

variable_types:
rank
int *


GetIndexOfLetterInPrefixTree

decompiled_code:
__int64 __fastcall GetIndexOfLetterInPrefixTree(__int64 a1, char *a2, int a3)
{
__int64 v3; // r8
__int64 v4; // rax
int v5; // edx
__int64 v6; // rcx
unsigned int *v8; // rax

if ( a3 <= 0 )
{
v8 = *(unsigned int **)(a1 + 8);
}
else
{
v3 = (__int64)&a2[a3 - 1 + 1];
v4 = 0LL;
do
{
v5 = *a2 - 65;
if ( v5 < 0 )
_assert_fail("c >= 0", "prefix_tree.c", 0x5Fu, "GetIndexOfLetterInPrefixTree");
v6 = *(_QWORD *)(a1 + 8);
v4 = *(int *)(v6 + 116 * v4 + 4LL * v5 + 4);
if ( (int)v4 < 0 )
return 0xFFFFFFFFLL;
++a2;
}
while ( a2 != (char *)v3 );
v8 = (unsigned int *)(v6 + 116 * v4);
}
return *v8;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, char *a2, int a3)
{
__int64 v3; // r8
__int64 v4; // rax
int v5; // edx
__int64 v6; // rcx
unsigned int *v8; // rax

if ( a3 <= 0 )
{
v8 = *(unsigned int **)(a1 + 8);
}
else
{
v3 = (__int64)&a2[a3 - 1 + 1];
v4 = 0LL;
do
{
v5 = *a2 - 65;
if ( v5 < 0 )
_assert_fail("c >= 0", "prefix_tree.c", 0x5Fu, "GetIndexOfLetterInPrefixTree");
v6 = *(_QWORD *)(a1 + 8);
v4 = *(int *)(v6 + 116 * v4 + 4LL * v5 + 4);
if ( (int)v4 < 0 )
return 0xFFFFFFFFLL;
++a2;
}
while ( a2 != (char *)v3 );
v8 = (unsigned int *)(v6 + 116 * v4);
}
return *v8;
}

original_code:
int GetIndexOfLetterInPrefixTree(PrefixTree *pTree, char *s, int n)
{
    int c, ind = 0;
    for (int i = 0; i < n; i++)
    {
        c = s[i] - 'A';
        ((c >= 0) ? (void) (0) : __assert_fail ("c >= 0", "prefix_tree.c", 95, __extension__ __PRETTY_FUNCTION__));
        if (pTree->nodes[ind].children[c] >= 0)
            ind = pTree->nodes[ind].children[c];
        else
            return -1;
    }
    return pTree->nodes[ind].rank;
}

canonical_original_code:
int GetIndexOfLetterInPrefixTree(struct _prefixTree *pTree, char *s, int n)
{
    int c; int ind = 0;
    for (int i = 0; i < n; i++)
    {
        c = s[i] - 'A';
        ((c >= 0) ? (void) (0) : __assert_fail ("c >= 0", "prefix_tree.c", 95, __extension__ __PRETTY_FUNCTION__));
        if (pTree->nodes[ind].children[c] >= 0)
            ind = pTree->nodes[ind].children[c];
        else
            return -1;
    }
    return pTree->nodes[ind].rank;
}

variable_types:
s
char *

variable_types: n int

variable_types: c int

variable_types: ind int


repo: pllopis/libxenvchan

decompiled_code:
__int64 __fastcall do_send(__int64 a1, char *a2, size_t a3)
{
int v5; // eax
__int64 v6; // rdi
__int64 v7; // r15
size_t v8; // rbx
__int64 v9; // rax
_DWORD *v10; // rax
bool v11; // sf
__int64 result; // rax
void *v13; // rax
_DWORD *v14; // [rsp+8h] [rbp-38h]

v14 = (_DWORD *)wr_prod_isra_0(*(_QWORD *)(a1 + 56));
v5 = wr_ring_size_isra_0(*(_DWORD *)(a1 + 72));
v6 = *(_QWORD *)(a1 + 64);
v7 = *v14 & (v5 - 1);
v8 = v5 - (int)v7;
if ( v8 > a3 )
v8 = (int)a3;
v9 = wr_ring_isra_0(v6);
memcpy((void *)(v9 + v7), a2, v8);
if ( a3 > v8 )
{
v13 = (void *)wr_ring_isra_0(*(_QWORD *)(a1 + 64));
memcpy(v13, &a2[v8], a3 - v8);
}
v10 = (_DWORD *)wr_prod_isra_0(*(_QWORD *)(a1 + 56));
*v10 += a3;
v11 = do_notify_isra_0(*(_DWORD *)(a1 + 16), *(_DWORD *)(a1 + 20)) < 0;
result = 0xFFFFFFFFLL;
if ( !v11 )
result = (unsigned int)a3;
return result;
}

original_code:
static int do_send(struct libvchan *ctrl, const void *data, size_t size)
{
   int real_idx = (*_wr_prod(ctrl)) & (wr_ring_size(ctrl) - 1);
   int avail_contig = wr_ring_size(ctrl) - real_idx;
   if (0) {
       char metainfo[32];
       struct iovec iov[2];
       iov[0].iov_base = metainfo;
       iov[0].iov_len = snprintf(metainfo, 32, "vchan wr %d/%d", ctrl->other_domain_id, ctrl->device_number);
       iov[1].iov_base = (void *)data;
       iov[1].iov_len = size;
       writev(-1, iov, 2);
   }
   if (avail_contig > size)
       avail_contig = size;
   memcpy(wr_ring(ctrl) + real_idx, data, avail_contig);
   if (avail_contig < size)
   {
       memcpy(wr_ring(ctrl), data + avail_contig, size - avail_contig);
   }
   asm volatile("" ::: "memory");
   (*_wr_prod(ctrl)) += size;
   asm volatile("" ::: "memory");
   if (do_notify(ctrl) < 0)
       return -1;
   return size;
}

canonical_original_code:
static int do_send(struct libvchan *ctrl, void *data, unsigned long size)
{
   int real_idx = (*_wr_prod(ctrl)) & (wr_ring_size(ctrl) - 1);
   int avail_contig = wr_ring_size(ctrl) - real_idx;
   if (0) {
       char metainfo[32];
       struct iovec iov[2];
       iov[0].iov_base = metainfo;
       iov[0].iov_len = snprintf(metainfo, 32, "vchan wr %d/%d", ctrl->other_domain_id, ctrl->device_number);
       iov[1].iov_base = (void *)data;
       iov[1].iov_len = size;
       writev(-1, iov, 2);
   }
   if (avail_contig > size)
       avail_contig = size;
   memcpy(wr_ring(ctrl) + real_idx, data, avail_contig);
   if (avail_contig < size)
   {
       memcpy(wr_ring(ctrl), data + avail_contig, size - avail_contig);
   }
   asm volatile("" ::: "memory");
   (*_wr_prod(ctrl)) += size;
   asm volatile("" ::: "memory");
   if (do_notify(ctrl) < 0)
       return -1;
   return size;
}

variable_types: struct libvchan { int other_domain_id; int device_number; struct vchan_interface { struct ring_shared { unsigned int cons; } left; unsigned short left_order; unsigned char cli_live; unsigned short debug; unsigned int grants[]; } *ring; int event_fd; unsigned int event_port; int is_server; int server_persist; int blocking; struct libvchan_ring { struct ring_shared *shr; void *buffer; int order; } read; } *

variable_types:
data
void *

variable_types:
size
unsigned long

variable_types:
metainfo
char [32]

variable_types: struct iovec { void *iov_base; unsigned long iov_len; } [2]

user_defined_types: struct libvchan { int other_domain_id; int device_number; struct vchan_interface *ring; int event_fd; unsigned int event_port; int is_server; int server_persist; int blocking; struct libvchan_ring read; }

user_defined_types: struct vchan_interface { struct ring_shared left; unsigned short left_order; unsigned char cli_live; unsigned short debug; unsigned int grants[]; }


decompiled_code:
__int64 __fastcall do_recv(__int64 a1, char *a2, size_t a3)
{
int v4; // eax
int v5; // er13
size_t v6; // rbx
__int64 v7; // rax
_DWORD *v8; // rax
bool v9; // sf
__int64 result; // rax
const void *v11; // rax
_DWORD *v12; // [rsp+8h] [rbp-38h]

v12 = (_DWORD *)rd_cons_isra_0(*(_QWORD *)(a1 + 32));
v4 = rd_ring_size_isra_0(*(_DWORD *)(a1 + 48));
v5 = *v12 & (v4 - 1);
v6 = v4 - v5;
if ( v6 > a3 )
v6 = (int)a3;
v7 = rd_ring_isra_0(*(_QWORD *)(a1 + 40));
memcpy(a2, (const void *)(v7 + v5), v6);
if ( a3 > v6 )
{
v11 = (const void *)rd_ring_isra_0(*(_QWORD *)(a1 + 40));
memcpy(&a2[v6], v11, a3 - v6);
}
v8 = (_DWORD *)rd_cons_isra_0(*(_QWORD *)(a1 + 32));
*v8 += a3;
v9 = do_notify_isra_0(*(_DWORD *)(a1 + 16), *(_DWORD *)(a1 + 20)) < 0;
result = 0xFFFFFFFFLL;
if ( !v9 )
result = (unsigned int)a3;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, char *a2, size_t a3)
{
int v4; // eax
int v5; // er13
size_t v6; // rbx
__int64 v7; // rax
_DWORD *v8; // rax
bool v9; // sf
__int64 result; // rax
const void *v11; // rax
_DWORD *v12; // [rsp+8h] [rbp-38h]

v12 = (_DWORD *)func8(*(_QWORD *)(a1 + 32));
v4 = func1(*(_DWORD *)(a1 + 48));
v5 = *v12 & (v4 - 1);
v6 = v4 - v5;
if ( v6 > a3 )
v6 = (int)a3;
v7 = func4(*(_QWORD *)(a1 + 40));
memcpy(a2, (const void *)(v7 + v5), v6);
if ( a3 > v6 )
{
v11 = (const void *)func4(*(_QWORD *)(a1 + 40));
memcpy(&a2[v6], v11, a3 - v6);
}
v8 = (_DWORD *)func8(*(_QWORD *)(a1 + 32));
*v8 += a3;
v9 = func0(*(_DWORD *)(a1 + 16), *(_DWORD *)(a1 + 20)) < 0;
result = 0xFFFFFFFFLL;
if ( !v9 )
result = (unsigned int)a3;
return result;
}

original_code:
static int do_recv(struct libvchan *ctrl, void *data, size_t size)
{
   int real_idx = (*_rd_cons(ctrl)) & (rd_ring_size(ctrl) - 1);
   int avail_contig = rd_ring_size(ctrl) - real_idx;
   if (avail_contig > size)
       avail_contig = size;
   asm volatile("" ::: "memory");
   memcpy(data, rd_ring(ctrl) + real_idx, avail_contig);
   if (avail_contig < size)
   {
       memcpy(data + avail_contig, rd_ring(ctrl), size - avail_contig);
   }
   (*_rd_cons(ctrl)) += size;
   if (0) {
       char metainfo[32];
       struct iovec iov[2];
       iov[0].iov_base = metainfo;
       iov[0].iov_len = snprintf(metainfo, 32, "vchan rd %d/%d", ctrl->other_domain_id, ctrl->device_number);
       iov[1].iov_base = data;
       iov[1].iov_len = size;
       writev(-1, iov, 2);
   }
   asm volatile("" ::: "memory");
   if (do_notify(ctrl) < 0)
       return -1;
   return size;
}

canonical_original_code:
static int do_recv(struct libvchan *ctrl, void *data, unsigned long size)
{
   int real_idx = (*_rd_cons(ctrl)) & (rd_ring_size(ctrl) - 1);
   int avail_contig = rd_ring_size(ctrl) - real_idx;
   if (avail_contig > size)
       avail_contig = size;
   asm volatile("" ::: "memory");
   memcpy(data, rd_ring(ctrl) + real_idx, avail_contig);
   if (avail_contig < size)
   {
       memcpy(data + avail_contig, rd_ring(ctrl), size - avail_contig);
   }
   (*_rd_cons(ctrl)) += size;
   if (0) {
       char metainfo[32];
       struct iovec iov[2];
       iov[0].iov_base = metainfo;
       iov[0].iov_len = snprintf(metainfo, 32, "vchan rd %d/%d", ctrl->other_domain_id, ctrl->device_number);
       iov[1].iov_base = data;
       iov[1].iov_len = size;
       writev(-1, iov, 2);
   }
   asm volatile("" ::: "memory");
   if (do_notify(ctrl) < 0)
       return -1;
   return size;
}

user_defined_types: struct iovec { void *iov_base; unsigned long iov_len; }

user_defined_types: struct libvchan_ring { struct ring_shared *shr; void *buffer; int order; }

user_defined_types: struct ring_shared { unsigned int cons; }


decompiled_code:
__int64 __fastcall libvchan_data_ready(__int64 a1)
{
__int64 v1; // r12
int v2; // ebx

v1 = *(_QWORD *)(a1 + 32);
v2 = rd_prod_isra_0(v1);
return (unsigned int)(v2 - *(_DWORD *)rd_cons_isra_0(v1));
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
__int64 v1; // r12
int v2; // ebx

v1 = *(_QWORD *)(a1 + 32);
v2 = func10(v1);
return (unsigned int)(v2 - *(_DWORD *)func8(v1));
}

original_code:
int libvchan_data_ready(struct libvchan *ctrl)
{
   return rd_prod(ctrl) - (*_rd_cons(ctrl));
}


decompiled_code:
__int64 __fastcall libvchan_buffer_space(__int64 a1)
{
int v1; // eax
unsigned int *v2; // r13
int v3; // ebx
int v4; // er12

v1 = wr_ring_size_isra_0(*(_DWORD *)(a1 + 72));
v2 = *(unsigned int **)(a1 + 56);
v3 = v1;
v4 = wr_cons_isra_0(v2);
return (unsigned int)(v3 + v4 - *(_DWORD *)wr_prod_isra_0((__int64)v2));
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1)
{
int v1; // eax
unsigned int *v2; // r13
int v3; // ebx
int v4; // er12

v1 = func2(*(_DWORD *)(a1 + 72));
v2 = *(unsigned int **)(a1 + 56);
v3 = v1;
v4 = func5(v2);
return (unsigned int)(v3 + v4 - *(_DWORD *)func6((__int64)v2));
}

original_code:
int libvchan_buffer_space(struct libvchan *ctrl)
{
   return wr_ring_size(ctrl) - ((*_wr_prod(ctrl)) - wr_cons(ctrl));
}


decompiled_code:
__int64 __fastcall libvchan_wait(__int64 a1)
{
unsigned int v1; // er8
char buf[20]; // [rsp+Ch] [rbp-14h] BYREF

v1 = read(*(_DWORD *)(a1 + 16), buf, 4uLL);
if ( v1 != -1 )
{
write(*(_DWORD *)(a1 + 16), buf, 4uLL);
v1 = 0;
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1)
{
unsigned int v1; // er8
char buf[20]; // [rsp+Ch] [rbp-14h] BYREF

v1 = read(*(_DWORD *)(a1 + 16), buf, 4uLL);
if ( v1 != -1 )
{
write(*(_DWORD *)(a1 + 16), buf, 4uLL);
v1 = 0;
}
return v1;
}

original_code:
int libvchan_wait(struct libvchan *ctrl)
{
   int ret;
   uint32_t dummy;
   ret = read(ctrl->event_fd, &dummy, sizeof(dummy));
   if (ret == -1)
       return -1;
   write(ctrl->event_fd, &dummy, sizeof(dummy));
   return 0;
}

canonical_original_code:
int libvchan_wait(struct libvchan *ctrl)
{
   int ret;
   unsigned int dummy;
   ret = read(ctrl->event_fd, &dummy, sizeof(dummy));
   if (ret == -1)
       return -1;
   write(ctrl->event_fd, &dummy, sizeof(dummy));
   return 0;
}

variable_types: ret int

variable_types:
dummy
unsigned int


original_code:
int libvchan_is_open(struct libvchan* ctrl)
{
   if (ctrl->is_server)
       return ctrl->server_persist || ctrl->ring->cli_live;
   else
       return ctrl->ring->srv_live;
}

canonical_original_code:
int libvchan_is_open(struct libvchan *ctrl)
{
   if (ctrl->is_server)
       return ctrl->server_persist || ctrl->ring->cli_live;
   else
       return ctrl->ring->srv_live;
}


decompiled_code:
__int64 __fastcall libvchan_send(__int64 a1, char *a2, size_t a3)
{
while ( 1 )
{
if ( !(unsigned int)libvchan_is_open(a1) )
return 0xFFFFFFFFLL;
if ( (int)libvchan_buffer_space(a1) >= a3 )
return do_send(a1, a2, a3);
if ( (*(_BYTE *)(a1 + 24) & 4) == 0 )
break;
if ( (unsigned int)wr_ring_size_isra_0(*(_DWORD *)(a1 + 72)) < a3 || (unsigned int)libvchan_wait(a1) )
return 0xFFFFFFFFLL;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1, char *a2, size_t a3)
{
while ( 1 )
{
if ( !(unsigned int)func14(a1) )
return 0xFFFFFFFFLL;
if ( (int)func12(a1) >= a3 )
return func7(a1, a2, a3);
if ( (*(_BYTE *)(a1 + 24) & 4) == 0 )
break;
if ( (unsigned int)func2(*(_DWORD *)(a1 + 72)) < a3 || (unsigned int)func13(a1) )
return 0xFFFFFFFFLL;
}
return 0LL;
}

original_code:
int libvchan_send(struct libvchan *ctrl, const void *data, size_t size)
{
   int avail;
   while (1) {
       if (!libvchan_is_open(ctrl))
           return -1;
       avail = libvchan_buffer_space(ctrl);
       if (size <= avail)
           return do_send(ctrl, data, size);
       if (!ctrl->blocking)
           return 0;
       if (size > wr_ring_size(ctrl))
           return -1;
       if (libvchan_wait(ctrl))
           return -1;
   }
}

canonical_original_code:
int libvchan_send(struct libvchan *ctrl, void *data, unsigned long size)
{
   int avail;
   while (1) {
       if (!libvchan_is_open(ctrl))
           return -1;
       avail = libvchan_buffer_space(ctrl);
       if (size <= avail)
           return do_send(ctrl, data, size);
       if (!ctrl->blocking)
           return 0;
       if (size > wr_ring_size(ctrl))
           return -1;
       if (libvchan_wait(ctrl))
           return -1;
   }
}

variable_types: avail int


decompiled_code:
__int64 __fastcall libvchan_write(__int64 a1, char *a2, unsigned __int64 a3)
{
__int64 v4; // rbx
int v5; // eax
__int64 result; // rax
int v7; // eax
size_t v8; // rdx

if ( !(unsigned int)libvchan_is_open(a1) )
return 0xFFFFFFFFLL;
if ( (*(_BYTE *)(a1 + 24) & 4) != 0 )
{
v4 = 0LL;
while ( 1 )
{
v5 = libvchan_buffer_space(a1);
if ( v4 + v5 > a3 )
v5 = a3 - v4;
if ( v5 )
{
v4 += (int)do_send(a1, &a2[v4], v5);
if ( v4 == a3 )
return (unsigned int)v4;
}
else if ( v4 == a3 )
{
return (unsigned int)v4;
}
if ( (unsigned int)libvchan_wait(a1) || !(unsigned int)libvchan_is_open(a1) )
return 0xFFFFFFFFLL;
}
}
v7 = libvchan_buffer_space(a1);
v8 = a3;
if ( v7 <= a3 )
v8 = v7;
result = 0LL;
if ( v8 )
result = do_send(a1, a2, v8);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1, char *a2, unsigned __int64 a3)
{
__int64 v4; // rbx
int v5; // eax
__int64 result; // rax
int v7; // eax
size_t v8; // rdx

if ( !(unsigned int)func14(a1) )
return 0xFFFFFFFFLL;
if ( (*(_BYTE *)(a1 + 24) & 4) != 0 )
{
v4 = 0LL;
while ( 1 )
{
v5 = func12(a1);
if ( v4 + v5 > a3 )
v5 = a3 - v4;
if ( v5 )
{
v4 += (int)func7(a1, &a2[v4], v5);
if ( v4 == a3 )
return (unsigned int)v4;
}
else if ( v4 == a3 )
{
return (unsigned int)v4;
}
if ( (unsigned int)func13(a1) || !(unsigned int)func14(a1) )
return 0xFFFFFFFFLL;
}
}
v7 = func12(a1);
v8 = a3;
if ( v7 <= a3 )
v8 = v7;
result = 0LL;
if ( v8 )
result = func7(a1, a2, v8);
return result;
}

original_code:
int libvchan_write(struct libvchan *ctrl, const void *data, size_t size)
{
   int avail;
   if (!libvchan_is_open(ctrl))
       return -1;
   if (ctrl->blocking) {
       size_t pos = 0;
       while (1) {
           avail = libvchan_buffer_space(ctrl);
           if (pos + avail > size)
               avail = size - pos;
           if (avail)
               pos += do_send(ctrl, data + pos, avail);
           if (pos == size)
               return pos;
           if (libvchan_wait(ctrl))
               return -1;
           if (!libvchan_is_open(ctrl))
               return -1;
       }
   } else {
       avail = libvchan_buffer_space(ctrl);
       if (size > avail)
           size = avail;
       if (size == 0)
           return 0;
       return do_send(ctrl, data, size);
   }
}

canonical_original_code:
int libvchan_write(struct libvchan *ctrl, void *data, unsigned long size)
{
   int avail;
   if (!libvchan_is_open(ctrl))
       return -1;
   if (ctrl->blocking) {
       unsigned long pos = 0;
       while (1) {
           avail = libvchan_buffer_space(ctrl);
           if (pos + avail > size)
               avail = size - pos;
           if (avail)
               pos += do_send(ctrl, data + pos, avail);
           if (pos == size)
               return pos;
           if (libvchan_wait(ctrl))
               return -1;
           if (!libvchan_is_open(ctrl))
               return -1;
       }
   } else {
       avail = libvchan_buffer_space(ctrl);
       if (size > avail)
           size = avail;
       if (size == 0)
           return 0;
       return do_send(ctrl, data, size);
   }
}

variable_types:
pos
unsigned long


decompiled_code:
__int64 __fastcall libvchan_recv(__int64 a1, char *a2, size_t a3)
{
while ( 1 )
{
if ( (int)libvchan_data_ready(a1) >= a3 )
return do_recv(a1, a2, a3);
if ( !(unsigned int)libvchan_is_open(a1) )
return 0xFFFFFFFFLL;
if ( (*(_BYTE *)(a1 + 24) & 4) == 0 )
break;
if ( (unsigned int)rd_ring_size_isra_0(*(_DWORD *)(a1 + 48)) < a3 || (unsigned int)libvchan_wait(a1) )
return 0xFFFFFFFFLL;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func17(__int64 a1, char *a2, size_t a3)
{
while ( 1 )
{
if ( (int)func11(a1) >= a3 )
return func9(a1, a2, a3);
if ( !(unsigned int)func14(a1) )
return 0xFFFFFFFFLL;
if ( (*(_BYTE *)(a1 + 24) & 4) == 0 )
break;
if ( (unsigned int)func1(*(_DWORD *)(a1 + 48)) < a3 || (unsigned int)func13(a1) )
return 0xFFFFFFFFLL;
}
return 0LL;
}

original_code:
int libvchan_recv(struct libvchan *ctrl, void *data, size_t size)
{
   while (1) {
       int avail = libvchan_data_ready(ctrl);
       if (size <= avail)
           return do_recv(ctrl, data, size);
       if (!libvchan_is_open(ctrl))
           return -1;
       if (!ctrl->blocking)
           return 0;
       if (size > rd_ring_size(ctrl))
           return -1;
       if (libvchan_wait(ctrl))
           return -1;
   }
}

canonical_original_code:
int libvchan_recv(struct libvchan *ctrl, void *data, unsigned long size)
{
   while (1) {
       int avail = libvchan_data_ready(ctrl);
       if (size <= avail)
           return do_recv(ctrl, data, size);
       if (!libvchan_is_open(ctrl))
           return -1;
       if (!ctrl->blocking)
           return 0;
       if (size > rd_ring_size(ctrl))
           return -1;
       if (libvchan_wait(ctrl))
           return -1;
   }
}


decompiled_code:
__int64 __fastcall libvchan_read(__int64 a1, char *a2, size_t a3)
{
int v4; // eax
unsigned int v5; // er12

while ( 1 )
{
v4 = libvchan_data_ready(a1);
v5 = v4;
if ( v4 )
break;
if ( !(unsigned int)libvchan_is_open(a1) )
return (unsigned int)-1;
if ( (*(_BYTE *)(a1 + 24) & 4) == 0 )
return v5;
if ( (unsigned int)libvchan_wait(a1) )
return (unsigned int)-1;
}
if ( v4 <= a3 )
a3 = v4;
return do_recv(a1, a2, a3);
}

canonical_decompiled_code:
__int64 __fastcall func18(__int64 a1, char *a2, size_t a3)
{
int v4; // eax
unsigned int v5; // er12

while ( 1 )
{
v4 = func11(a1);
v5 = v4;
if ( v4 )
break;
if ( !(unsigned int)func14(a1) )
return (unsigned int)-1;
if ( (*(_BYTE *)(a1 + 24) & 4) == 0 )
return v5;
if ( (unsigned int)func13(a1) )
return (unsigned int)-1;
}
if ( v4 <= a3 )
a3 = v4;
return func9(a1, a2, a3);
}

original_code:
int libvchan_read(struct libvchan *ctrl, void *data, size_t size)
{
   while (1) {
       int avail = libvchan_data_ready(ctrl);
       if (avail && size > avail)
           size = avail;
       if (avail)
           return do_recv(ctrl, data, size);
       if (!libvchan_is_open(ctrl))
           return -1;
       if (!ctrl->blocking)
           return 0;
       if (libvchan_wait(ctrl))
           return -1;
   }
}

canonical_original_code:
int libvchan_read(struct libvchan *ctrl, void *data, unsigned long size)
{
   while (1) {
       int avail = libvchan_data_ready(ctrl);
       if (avail && size > avail)
           size = avail;
       if (avail)
           return do_recv(ctrl, data, size);
       if (!libvchan_is_open(ctrl))
           return -1;
       if (!ctrl->blocking)
           return 0;
       if (libvchan_wait(ctrl))
           return -1;
   }
}


decompiled_code:
__int64 __fastcall libvchan_fd_for_select(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func19(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

original_code:
int libvchan_fd_for_select(struct libvchan *ctrl)
{
   return ctrl->event_fd;
}


original_code:
void libvchan_close(struct libvchan *ctrl)
{
   if (!ctrl)
       return;
   if (ctrl->ring) {
       if (ctrl->is_server)
           ctrl->ring->srv_live = 0;
       else
           ctrl->ring->cli_live = 0;
       munmap(ctrl->ring, 4096);
   }
   if (ctrl->event_fd != -1) {
       if (ctrl->event_port > 0 && ctrl->ring)
           do_notify(ctrl);
       close(ctrl->event_fd);
   }
   if (ctrl->read.order >= 12)
       munmap(ctrl->read.buffer, 1 << ctrl->read.order);
   if (ctrl->write.order >= 12)
       munmap(ctrl->write.buffer, 1 << ctrl->write.order);
   free(ctrl);
}


main

canonical_name: main

repo: plumbum/easyface

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // er12
unsigned __int16 *v4; // rbx
int v5; // ebp
__int64 v6; // rsi
size_t v7; // rax
__int64 v8; // rdx
size_t v9; // rax
unsigned __int16 v10; // [rsp+Eh] [rbp-1BAh] BYREF
__int16 v11[16]; // [rsp+10h] [rbp-1B8h] BYREF
char v12[128]; // [rsp+30h] [rbp-198h] BYREF
char s[280]; // [rsp+B0h] [rbp-118h] BYREF

v3 = 0;
modbus_init_rtu(v12, "/dev/ttyUSB1", 19200LL, "none", 8LL, 1LL);
modbus_set_debug(v12, 0LL);
if ( (unsigned int)modbus_connect(v12) != -1 )
{
while ( 1 )
{
v10 = 0;
read_input_registers(v12, 1LL, 0x4000LL, 1LL, &v10);
usleep(0x4E20u);
if ( v10 )
{
read_input_registers(v12, 1LL, 16385LL, v10, v11);
usleep(0x4E20u);
printf("Scancode (%d):", v10);
if ( v10 )
{
v4 = (unsigned __int16 *)v11;
v5 = 0;
do
{
v6 = *v4;
if ( (_WORD)v6 != 0xFFFF )
{
printf(" 0x%02x", v6);
sprintf(s, "[0x%02x]", *v4);
v7 = strlen(s);
preset_multiple_registers(v12, 1LL, 385LL, (unsigned int)(v7 >> 1) + 1, s);
usleep(0x4E20u);
}
++v5;
++v4;
}
while ( v10 > v5 );
}
printf("\r\n");
}
v8 = v3++;
sprintf(s, "(%d)", v8);
v9 = strlen(s);
preset_multiple_registers(v12, 1LL, 257LL, (unsigned int)(v9 >> 1) + 1, s);
usleep(0x4E20u);
}
}
puts("ERROR Connection failed");
exit(1);
}

original_code:
int main(void)
{
        int ret;
        int nb_fail;
        int nb_loop;
        int addr;
        int nb;
        uint8_t *tab_rq_status;
        uint8_t *tab_rp_status;
        uint16_t *tab_rq_registers;
        uint16_t *tab_rp_registers;
        modbus_param_t mb_param;
        modbus_init_rtu(&mb_param, "/dev/ttyUSB1", 19200, "none", 8, 1);
        modbus_set_debug(&mb_param, 0);
        if (modbus_connect(&mb_param) == -1) {
                printf("ERROR Connection failed\n");
                exit(1);
        }
        nb = 0x16 - 0x11;
        tab_rq_status = (uint8_t *) malloc(nb * sizeof(uint8_t));
        memset(tab_rq_status, 0, nb * sizeof(uint8_t));
        tab_rp_status = (uint8_t *) malloc(nb * sizeof(uint8_t));
        memset(tab_rp_status, 0, nb * sizeof(uint8_t));
        tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
        memset(tab_rq_registers, 0, nb * sizeof(uint16_t));
        tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
        memset(tab_rp_registers, 0, nb * sizeof(uint16_t));
        uint16_t readed[16];
        uint16_t scan_cnt;
        char message[256];
        int cnt = 0;
        while(1)
        {
            scan_cnt = 0;
            ret = read_input_registers(&mb_param, 0x01, 0x4000, 1, &scan_cnt);
            usleep(20000);
            if(scan_cnt > 0)
            {
                ret = read_input_registers(&mb_param, 0x01, 0x4001, scan_cnt, readed);
                usleep(20000);
                int i;
                printf("Scancode (%d):", scan_cnt);
                for(i=0; i<scan_cnt; i++)
                {
                    if(readed[i] != 0xFFFF)
                    {
                        printf(" 0x%02x", readed[i]);
                        sprintf(message, "[0x%02x]", readed[i]);
                        ret = preset_multiple_registers(&mb_param, 0x01,
                                                        3<<7 | 1, strlen(message)/2+1, message);
                        usleep(20000);
                    }
                }
                printf("\r\n", readed[i]);
            }
            sprintf(message, "(%d)", cnt++);
            ret = preset_multiple_registers(&mb_param, 0x01,
                                            2<<7 | 1, strlen(message)/2+1, message);
            usleep(20000);
        }
        return 0;
        free(tab_rq_status);
        free(tab_rp_status);
        free(tab_rq_registers);
        free(tab_rp_registers);
        modbus_close(&mb_param);
        return 0;
}

canonical_original_code:
int main()
{
        int ret;
        int nb_fail;
        int nb_loop;
        int addr;
        int nb;
        unsigned char *tab_rq_status;
        unsigned char *tab_rp_status;
        unsigned short *tab_rq_registers;
        unsigned short *tab_rp_registers;
        struct modbus_param_t mb_param;
        modbus_init_rtu(&mb_param, "/dev/ttyUSB1", 19200, "none", 8, 1);
        modbus_set_debug(&mb_param, 0);
        if (modbus_connect(&mb_param) == -1) {
                printf("ERROR Connection failed\n");
                exit(1);
        }
        nb = 0x16 - 0x11;
        tab_rq_status = (unsigned char *) malloc(nb * sizeof(unsigned char));
        memset(tab_rq_status, 0, nb * sizeof(unsigned char));
        tab_rp_status = (unsigned char *) malloc(nb * sizeof(unsigned char));
        memset(tab_rp_status, 0, nb * sizeof(unsigned char));
        tab_rq_registers = (unsigned short *) malloc(nb * sizeof(unsigned short));
        memset(tab_rq_registers, 0, nb * sizeof(unsigned short));
        tab_rp_registers = (unsigned short *) malloc(nb * sizeof(unsigned short));
        memset(tab_rp_registers, 0, nb * sizeof(unsigned short));
        unsigned short readed[16];
        unsigned short scan_cnt;
        char message[256];
        int cnt = 0;
        while(1)
        {
            scan_cnt = 0;
            ret = read_input_registers(&mb_param, 0x01, 0x4000, 1, &scan_cnt);
            usleep(20000);
            if(scan_cnt > 0)
            {
                ret = read_input_registers(&mb_param, 0x01, 0x4001, scan_cnt, readed);
                usleep(20000);
                int i;
                printf("Scancode (%d):", scan_cnt);
                for(i=0; i<scan_cnt; i++)
                {
                    if(readed[i] != 0xFFFF)
                    {
                        printf(" 0x%02x", readed[i]);
                        sprintf(message, "[0x%02x]", readed[i]);
                        ret = preset_multiple_registers(&mb_param, 0x01,
                                                        3<<7 | 1, strlen(message)/2+1, message);
                        usleep(20000);
                    }
                }
                printf("\r\n", readed[i]);
            }
            sprintf(message, "(%d)", cnt++);
            ret = preset_multiple_registers(&mb_param, 0x01,
                                            2<<7 | 1, strlen(message)/2+1, message);
            usleep(20000);
        }
        return 0;
        free(tab_rq_status);
        free(tab_rp_status);
        free(tab_rq_registers);
        free(tab_rp_registers);
        modbus_close(&mb_param);
        return 0;
}

variable_types: addr int

variable_types: nb int

variable_types: struct modbus_param_t { int fd; enum type_com_t { RTU=0, TCP=1 } type_com; int debug; int header_length; int checksum_length; int port; char device[16]; int baud; unsigned char data_bit; unsigned char stop_bit; char parity[5]; unsigned char error_handling; char ip[16]; struct termios { unsigned int c_iflag; unsigned int c_oflag; unsigned int c_cflag; unsigned int c_lflag; unsigned char c_line; unsigned char c_cc[32]; unsigned int c_ispeed; unsigned int c_ospeed; } old_tios; }

variable_types:
readed
unsigned short [16]

variable_types:
message
char [256]

variable_types: cnt int

variable_types: i int

user_defined_types: struct modbus_param_t { int fd; enum type_com_t type_com; int debug; int header_length; int checksum_length; int port; char device[16]; int baud; unsigned char data_bit; unsigned char stop_bit; char parity[5]; unsigned char error_handling; char ip[16]; struct termios old_tios; }


repo: pmeinhardt/libgopro

decompiled_code:
__int64 __fastcall gopro_camera_receive(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 v4; // r12

v4 = a3 * a2;
if ( (unsigned int)vbuffer_append(a4, a1, a3 * a2) )
v4 = 0LL;
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 v4; // r12

v4 = a3 * a2;
if ( (unsigned int)vbuffer_append(a4, a1, a3 * a2) )
v4 = 0LL;
return v4;
}

original_code:
size_t gopro_camera_receive(char *data, size_t size, size_t n, void *context) {
  vbuffer *buffer = (vbuffer *)context;
  int err = vbuffer_append(buffer, data, size * n);
  return (err == 0) ? size * n : 0;
}

canonical_original_code:
unsigned long gopro_camera_receive(char *data, unsigned long size, unsigned long n, void *context) {
  struct vbuffer *buffer = (vbuffer *)context;
  int err = vbuffer_append(buffer, data, size * n);
  return (err == 0) ? size * n : 0;
}

variable_types:
data
char *

variable_types:
n
unsigned long

variable_types:
context
void *

variable_types: struct vbuffer { void *data; unsigned long capacity; unsigned long length; } *

variable_types: err int

return_type: unsigned long


decompiled_code:
void __fastcall gopro_camera_free(void *ptr)
{
void *v2; // rdi
void *v3; // rdi

if ( !ptr )
_assert_fail("cam", "src/camera.c", 0x37u, "gopro_camera_free");
if ( *((_QWORD *)ptr + 2) )
gopro_client_free();
v2 = *(void **)ptr;
if ( *(_QWORD *)ptr )
free(v2);
v3 = (void *)*((_QWORD *)ptr + 1);
if ( v3 )
free(v3);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
void *v2; // rdi
void *v3; // rdi

if ( !ptr )
_assert_fail("cam", "src/camera.c", 0x37u, "gopro_camera_free");
if ( *((_QWORD *)ptr + 2) )
gopro_client_free();
v2 = *(void **)ptr;
if ( *(_QWORD *)ptr )
free(v2);
v3 = (void *)*((_QWORD *)ptr + 1);
if ( v3 )
free(v3);
free(ptr);
}

original_code:
void gopro_camera_free(gopro_camera *cam) {
  ((void) sizeof ((cam) ? 1 : 0), __extension__ ({ if (cam) ; else __assert_fail ("cam", "src/camera.c", 55, __extension__ __PRETTY_FUNCTION__); }));
  if (cam->client != ((void *)0)) gopro_client_free(cam->client);
  if (cam->ipaddr != ((void *)0)) free(cam->ipaddr);
  if (cam->password != ((void *)0)) free(cam->password);
  free(cam);
}

canonical_original_code:
void gopro_camera_free(struct gopro_camera *cam) {
  ((void) sizeof ((cam) ? 1 : 0), __extension__ ({ if (cam) ; else __assert_fail ("cam", "src/camera.c", 55, __extension__ __PRETTY_FUNCTION__); }));
  if (cam->client != ((void *)0)) gopro_client_free(cam->client);
  if (cam->ipaddr != ((void *)0)) free(cam->ipaddr);
  if (cam->password != ((void *)0)) free(cam->password);
  free(cam);
}

variable_types: struct gopro_camera { char *ipaddr; char *password; void *client; } *


decompiled_code:
// attributes: thunk
void gopro_camera_free_url(void *ptr)
{
free(ptr);
}

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

original_code:
void gopro_camera_free_url(char *url) {
  free(url);
}

variable_types:
url
char *


decompiled_code:
char *__fastcall gopro_camera_build_url(const char **a1, const char *a2)
{
const char *v2; // r14
const char *v3; // r13
int v4; // er12
size_t v5; // rbx
int v6; // eax
char *v7; // r12
char *v8; // rax
size_t v9; // rdx
size_t v10; // rbx

v2 = *a1;
v3 = a1[1];
v4 = strlen(*a1);
v5 = strlen(a2);
v6 = strlen(v3);
v7 = (char *)malloc(v6 + v4 + (int)v5 + 19);
*(_QWORD *)v7 = 0x2F2F3A70747468LL;
v8 = stpcpy(v7 + 7, v2);
v9 = v5;
*(_QWORD *)v8 = 0x2F6172656D61632FLL;
v10 = v8 - v7 + v5;
memcpy(v8 + 8, a2, v9);
*(_DWORD *)&v7[v10 + 8] = 4027455;
strcpy(&v7[v10 + 11], v3);
return v7;
}

canonical_decompiled_code:
char *__fastcall func3(const char **a1, const char *a2)
{
const char *v2; // r14
const char *v3; // r13
int v4; // er12
size_t v5; // rbx
int v6; // eax
char *v7; // r12
char *v8; // rax
size_t v9; // rdx
size_t v10; // rbx

v2 = *a1;
v3 = a1[1];
v4 = strlen(*a1);
v5 = strlen(a2);
v6 = strlen(v3);
v7 = (char *)malloc(v6 + v4 + (int)v5 + 19);
*(_QWORD *)v7 = 0x2F2F3A70747468LL;
v8 = stpcpy(v7 + 7, v2);
v9 = v5;
*(_QWORD *)v8 = 0x2F6172656D61632FLL;
v10 = v8 - v7 + v5;
memcpy(v8 + 8, a2, v9);
*(_DWORD *)&v7[v10 + 8] = 4027455;
strcpy(&v7[v10 + 11], v3);
return v7;
}

original_code:
char *gopro_camera_build_url(gopro_camera *cam, char *action) {
  char *host = cam->ipaddr;
  char *pass = cam->password;
  int buflen = strlen(host) + strlen(action) + strlen(pass) + 19;
  char *url = (char *)malloc(buflen);
  url[0] = '\0';
  strcat(url, "http://");
  strcat(url, host);
  strcat(url, "/camera/");
  strcat(url, action);
  strcat(url, "?t=");
  strcat(url, pass);
  return url;
}

canonical_original_code:
char *gopro_camera_build_url(struct gopro_camera *cam, char *action) {
  char *host = cam->ipaddr;
  char *pass = cam->password;
  int buflen = strlen(host) + strlen(action) + strlen(pass) + 19;
  char *url = (char *)malloc(buflen);
  url[0] = '\0';
  strcat(url, "http://");
  strcat(url, host);
  strcat(url, "/camera/");
  strcat(url, action);
  strcat(url, "?t=");
  strcat(url, pass);
  return url;
}

variable_types:
action
char *

variable_types:
host
char *

variable_types:
pass
char *

variable_types: buflen int

user_defined_types: struct gopro_camera { char *ipaddr; char *password; void *client; }


decompiled_code:
char *__fastcall gopro_camera_build_param_url(const char **a1, const char *a2, char a3)
{
char *v4; // rbp
int v5; // eax
char *v6; // r12
const char *v7; // rbp
size_t v8; // rax
char v10[26]; // [rsp+Eh] [rbp-1Ah] BYREF

v4 = gopro_camera_build_url(a1, a2);
v5 = strlen(v4);
v6 = (char *)malloc(v5 + 6);
strcpy(v6, v4);
gopro_camera_free_url(v4);
v10[0] = a3;
v10[1] = 0;
v7 = (const char *)curl_easy_escape(0LL, v10, 1LL);
v8 = strlen(v6);
*(_DWORD *)&v6[v8] = 4026406;
strcpy(&v6[v8 + 3], v7);
curl_free(v7);
return v6;
}

canonical_decompiled_code:
char *__fastcall func4(const char **a1, const char *a2, char a3)
{
char *v4; // rbp
int v5; // eax
char *v6; // r12
const char *v7; // rbp
size_t v8; // rax
char v10[26]; // [rsp+Eh] [rbp-1Ah] BYREF

v4 = func3(a1, a2);
v5 = strlen(v4);
v6 = (char *)malloc(v5 + 6);
strcpy(v6, v4);
func2(v4);
v10[0] = a3;
v10[1] = 0;
v7 = (const char *)curl_easy_escape(0LL, v10, 1LL);
v8 = strlen(v6);
*(_DWORD *)&v6[v8] = 4026406;
strcpy(&v6[v8 + 3], v7);
curl_free(v7);
return v6;
}

original_code:
char *gopro_camera_build_param_url(gopro_camera *cam, char *action, char par) {
  char *base = gopro_camera_build_url(cam, action);
  int buflen = strlen(base) + 6;
  char *url = (char *)malloc(buflen);
  url[0] = '\0';
  strcat(url, base);
  gopro_camera_free_url(base);
  char pstr[2];
  pstr[0] = par;
  pstr[1] = '\0';
  char *penc = curl_easy_escape(((void *)0), pstr, 1);
  strcat(url, "&p=");
  strcat(url, penc);
  curl_free(penc);
  return url;
}

canonical_original_code:
char *gopro_camera_build_param_url(struct gopro_camera *cam, char *action, char par) {
  char *base = gopro_camera_build_url(cam, action);
  int buflen = strlen(base) + 6;
  char *url = (char *)malloc(buflen);
  url[0] = '\0';
  strcat(url, base);
  gopro_camera_free_url(base);
  char pstr[2];
  pstr[0] = par;
  pstr[1] = '\0';
  char *penc = curl_easy_escape(((void *)0), pstr, 1);
  strcat(url, "&p=");
  strcat(url, penc);
  curl_free(penc);
  return url;
}

variable_types: par char

variable_types:
base
char *

variable_types:
pstr
char [2]

variable_types:
penc
char *


decompiled_code:
__int64 __fastcall gopro_camera_send(__int64 a1, const char *a2)
{
char *v2; // rbp
unsigned int v3; // er12

if ( !a2 )
_assert_fail("action", "src/camera.c", 0x72u, "gopro_camera_send");
if ( !a1 )
_assert_fail("cam", "src/camera.c", 0x73u, "gopro_camera_send");
v2 = gopro_camera_build_url((const char **)a1, a2);
v3 = gopro_client_get(*(_QWORD *)(a1 + 16), v2, 0LL, 0LL);
gopro_camera_free_url(v2);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, const char *a2)
{
char *v2; // rbp
unsigned int v3; // er12

if ( !a2 )
_assert_fail("action", "src/camera.c", 0x72u, "gopro_camera_send");
if ( !a1 )
_assert_fail("cam", "src/camera.c", 0x73u, "gopro_camera_send");
v2 = func3((const char **)a1, a2);
v3 = gopro_client_get(*(_QWORD *)(a1 + 16), v2, 0LL, 0LL);
func2(v2);
return v3;
}

original_code:
int gopro_camera_send(gopro_camera *cam, char *action) {
  ((void) sizeof ((action) ? 1 : 0), __extension__ ({ if (action) ; else __assert_fail ("action", "src/camera.c", 114, __extension__ __PRETTY_FUNCTION__); }));
  ((void) sizeof ((cam) ? 1 : 0), __extension__ ({ if (cam) ; else __assert_fail ("cam", "src/camera.c", 115, __extension__ __PRETTY_FUNCTION__); }));
  char *url = gopro_camera_build_url(cam, action);
  int code = gopro_client_get((gopro_client *)(cam->client), url, ((void *)0), ((void *)0));
  gopro_camera_free_url(url);
  return code;
}

canonical_original_code:
int gopro_camera_send(struct gopro_camera *cam, char *action) {
  ((void) sizeof ((action) ? 1 : 0), __extension__ ({ if (action) ; else __assert_fail ("action", "src/camera.c", 114, __extension__ __PRETTY_FUNCTION__); }));
  ((void) sizeof ((cam) ? 1 : 0), __extension__ ({ if (cam) ; else __assert_fail ("cam", "src/camera.c", 115, __extension__ __PRETTY_FUNCTION__); }));
  char *url = gopro_camera_build_url(cam, action);
  int code = gopro_client_get((gopro_client *)(cam->client), url, ((void *)0), ((void *)0));
  gopro_camera_free_url(url);
  return code;
}

variable_types: code int


decompiled_code:
__int64 __fastcall gopro_camera_send_param(__int64 a1, const char *a2, char a3)
{
char *v3; // rbp
unsigned int v4; // er12

if ( !a2 )
_assert_fail("action", "src/camera.c", 0x7Du, "gopro_camera_send_param");
if ( !a1 )
_assert_fail("cam", "src/camera.c", 0x7Eu, "gopro_camera_send_param");
v3 = gopro_camera_build_param_url((const char **)a1, a2, a3);
v4 = gopro_client_get(*(_QWORD *)(a1 + 16), v3, 0LL, 0LL);
gopro_camera_free_url(v3);
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, const char *a2, char a3)
{
char *v3; // rbp
unsigned int v4; // er12

if ( !a2 )
_assert_fail("action", "src/camera.c", 0x7Du, "gopro_camera_send_param");
if ( !a1 )
_assert_fail("cam", "src/camera.c", 0x7Eu, "gopro_camera_send_param");
v3 = func4((const char **)a1, a2, a3);
v4 = gopro_client_get(*(_QWORD *)(a1 + 16), v3, 0LL, 0LL);
func2(v3);
return v4;
}

original_code:
int gopro_camera_send_param(gopro_camera *cam, char *action, int param) {
  ((void) sizeof ((action) ? 1 : 0), __extension__ ({ if (action) ; else __assert_fail ("action", "src/camera.c", 125, __extension__ __PRETTY_FUNCTION__); }));
  ((void) sizeof ((cam) ? 1 : 0), __extension__ ({ if (cam) ; else __assert_fail ("cam", "src/camera.c", 126, __extension__ __PRETTY_FUNCTION__); }));
  char *url = gopro_camera_build_param_url(cam, action, param);
  int code = gopro_client_get((gopro_client *)(cam->client), url, ((void *)0), ((void *)0));
  gopro_camera_free_url(url);
  return code;
}

canonical_original_code:
int gopro_camera_send_param(struct gopro_camera *cam, char *action, int param) {
  ((void) sizeof ((action) ? 1 : 0), __extension__ ({ if (action) ; else __assert_fail ("action", "src/camera.c", 125, __extension__ __PRETTY_FUNCTION__); }));
  ((void) sizeof ((cam) ? 1 : 0), __extension__ ({ if (cam) ; else __assert_fail ("cam", "src/camera.c", 126, __extension__ __PRETTY_FUNCTION__); }));
  char *url = gopro_camera_build_param_url(cam, action, param);
  int code = gopro_client_get((gopro_client *)(cam->client), url, ((void *)0), ((void *)0));
  gopro_camera_free_url(url);
  return code;
}

variable_types: param int


decompiled_code:
__int64 __fastcall gopro_camera_get_status(__int64 a1, _DWORD *a2)
{
__int64 v2; // r15
__int64 v3; // rbp
char *v4; // r13
__int64 result; // rax

v2 = *(_QWORD *)(a1 + 16);
v3 = vbuffer_create(32LL);
v4 = gopro_camera_build_url((const char **)a1, "se");
if ( (unsigned int)gopro_client_get(v2, v4, v3, gopro_camera_receive) )
{
gopro_camera_free_url(v4);
vbuffer_free(v3);
result = 1LL;
}
else
{
if ( *(_QWORD *)(v3 + 16) <= 0x1EuLL )
_assert_fail("buffer->length >= 31", "src/camera.c", 0xA2u, "gopro_camera_get_status");
gopro_status_parse(a2, *(char **)v3);
gopro_camera_free_url(v4);
vbuffer_free(v3);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, _DWORD *a2)
{
__int64 v2; // r15
__int64 v3; // rbp
char *v4; // r13
__int64 result; // rax

v2 = *(_QWORD *)(a1 + 16);
v3 = vbuffer_create(32LL);
v4 = func3((const char **)a1, "se");
if ( (unsigned int)gopro_client_get(v2, v4, v3, gopro_camera_receive) )
{
func2(v4);
vbuffer_free(v3);
result = 1LL;
}
else
{
if ( *(_QWORD *)(v3 + 16) <= 0x1EuLL )
_assert_fail("buffer->length >= 31", "src/camera.c", 0xA2u, "gopro_camera_get_status");
func7(a2, *(char **)v3);
func2(v4);
vbuffer_free(v3);
result = 0LL;
}
return result;
}

original_code:
int gopro_camera_get_status(gopro_camera *cam, gopro_status *status) {
  gopro_client_cb *callback = (gopro_client_cb *)gopro_camera_receive;
  gopro_client *client = (gopro_client *)(cam->client);
  vbuffer *buffer = vbuffer_create(32);
  char *url = gopro_camera_build_url(cam, "se");
  int err = gopro_client_get(client, url, buffer, callback);
  if (err != 0) {
    gopro_camera_free_url(url);
    vbuffer_free(buffer);
    return 1;
  }
  ((void) sizeof ((buffer->length >= 31) ? 1 : 0), __extension__ ({ if (buffer->length >= 31) ; else __assert_fail ("buffer->length >= 31", "src/camera.c", 162, __extension__ __PRETTY_FUNCTION__); }));
  gopro_status_parse(status, buffer->data);
  gopro_camera_free_url(url);
  vbuffer_free(buffer);
  return 0;
}

canonical_original_code:
int gopro_camera_get_status(struct gopro_camera *cam, struct gopro_status *status) {
  unsigned long (**callback)(char *, unsigned long, unsigned long, void *) = (gopro_client_cb *)gopro_camera_receive;
  struct gopro_client *client = (gopro_client *)(cam->client);
  struct vbuffer *buffer = vbuffer_create(32);
  char *url = gopro_camera_build_url(cam, "se");
  int err = gopro_client_get(client, url, buffer, callback);
  if (err != 0) {
    gopro_camera_free_url(url);
    vbuffer_free(buffer);
    return 1;
  }
  ((void) sizeof ((buffer->length >= 31) ? 1 : 0), __extension__ ({ if (buffer->length >= 31) ; else __assert_fail ("buffer->length >= 31", "src/camera.c", 162, __extension__ __PRETTY_FUNCTION__); }));
  gopro_status_parse(status, buffer->data);
  gopro_camera_free_url(url);
  vbuffer_free(buffer);
  return 0;
}

variable_types: struct gopro_status { int photo_count; int video_count; } *

variable_types: unsigned long (**)(char *, unsigned long, unsigned long, void *)

variable_types:
client
struct gopro_client { void *curl; } *

user_defined_types: struct vbuffer { void *data; unsigned long capacity; unsigned long length; }


decompiled_code:
__int64 __fastcall gopro_camera_start_capture(__int64 a1)
{
return gopro_camera_send_param(a1, "SH", 1);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
return func6(a1, "SH", 1);
}

original_code:
int gopro_camera_start_capture(gopro_camera *cam) {
  return gopro_camera_send_param(cam, "SH", 1);
}

canonical_original_code:
int gopro_camera_start_capture(struct gopro_camera *cam) {
  return gopro_camera_send_param(cam, "SH", 1);
}


decompiled_code:
__int64 __fastcall gopro_camera_stop_capture(__int64 a1)
{
return gopro_camera_send_param(a1, "SH", 0);
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
return func6(a1, "SH", 0);
}

original_code:
int gopro_camera_stop_capture(gopro_camera *cam) {
  return gopro_camera_send_param(cam, "SH", 0);
}

canonical_original_code:
int gopro_camera_stop_capture(struct gopro_camera *cam) {
  return gopro_camera_send_param(cam, "SH", 0);
}


decompiled_code:
__int64 __fastcall gopro_camera_set_mode(__int64 a1, char a2)
{
return gopro_camera_send_param(a1, "CM", a2);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1, char a2)
{
return func6(a1, "CM", a2);
}

original_code:
int gopro_camera_set_mode(gopro_camera *cam, gopro_mode mode) {
  return gopro_camera_send_param(cam, "CM", mode);
}

canonical_original_code:
int gopro_camera_set_mode(struct gopro_camera *cam, enum gopro_mode mode) {
  return gopro_camera_send_param(cam, "CM", mode);
}

variable_types: enum gopro_mode { GOPRO_MODE_VIDEO=0, GOPRO_MODE_PHOTO=1, GOPRO_MODE_BURST=2, GOPRO_MODE_TIMELAPSE=3, GOPRO_MODE_MENU=7 }


decompiled_code:
__int64 __fastcall gopro_camera_set_video_mode(__int64 a1)
{
return gopro_camera_set_mode(a1, 0);
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1)
{
return func11(a1, 0);
}

original_code:
int gopro_camera_set_video_mode(gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_VIDEO);
}

canonical_original_code:
int gopro_camera_set_video_mode(struct gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_VIDEO);
}


decompiled_code:
__int64 __fastcall gopro_camera_set_photo_mode(__int64 a1)
{
return gopro_camera_set_mode(a1, 1);
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1)
{
return func11(a1, 1);
}

original_code:
int gopro_camera_set_photo_mode(gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_PHOTO);
}

canonical_original_code:
int gopro_camera_set_photo_mode(struct gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_PHOTO);
}


decompiled_code:
__int64 __fastcall gopro_camera_set_burst_mode(__int64 a1)
{
return gopro_camera_set_mode(a1, 2);
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1)
{
return func11(a1, 2);
}

original_code:
int gopro_camera_set_burst_mode(gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_BURST);
}

canonical_original_code:
int gopro_camera_set_burst_mode(struct gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_BURST);
}


decompiled_code:
__int64 __fastcall gopro_camera_set_timelapse_mode(__int64 a1)
{
return gopro_camera_set_mode(a1, 3);
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1)
{
return func11(a1, 3);
}

original_code:
int gopro_camera_set_timelapse_mode(gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_TIMELAPSE);
}

canonical_original_code:
int gopro_camera_set_timelapse_mode(struct gopro_camera *cam) {
  return gopro_camera_set_mode(cam, GOPRO_MODE_TIMELAPSE);
}


decompiled_code:
__int64 __fastcall gopro_camera_set_head_up(__int64 a1)
{
return gopro_camera_send_param(a1, "UP", 0);
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1)
{
return func6(a1, "UP", 0);
}

original_code:
int gopro_camera_set_head_up(gopro_camera *cam) {
  return gopro_camera_send_param(cam, "UP", 0);
}

canonical_original_code:
int gopro_camera_set_head_up(struct gopro_camera *cam) {
  return gopro_camera_send_param(cam, "UP", 0);
}


decompiled_code:
__int64 __fastcall gopro_camera_set_head_down(__int64 a1)
{
return gopro_camera_send_param(a1, "UP", 1);
}

canonical_decompiled_code:
__int64 __fastcall func17(__int64 a1)
{
return func6(a1, "UP", 1);
}

original_code:
int gopro_camera_set_head_down(gopro_camera *cam) {
  return gopro_camera_send_param(cam, "UP", 1);
}

canonical_original_code:
int gopro_camera_set_head_down(struct gopro_camera *cam) {
  return gopro_camera_send_param(cam, "UP", 1);
}


decompiled_code:
__int64 __fastcall gopro_camera_delete_last(__int64 a1)
{
return gopro_camera_send(a1, "DL");
}

canonical_decompiled_code:
__int64 __fastcall func18(__int64 a1)
{
return func5(a1, "DL");
}

original_code:
int gopro_camera_delete_last(gopro_camera *cam) {
  return gopro_camera_send(cam, "DL");
}

canonical_original_code:
int gopro_camera_delete_last(struct gopro_camera *cam) {
  return gopro_camera_send(cam, "DL");
}


decompiled_code:
__int64 __fastcall gopro_camera_delete_all(__int64 a1)
{
return gopro_camera_send(a1, "DA");
}

canonical_decompiled_code:
__int64 __fastcall func19(__int64 a1)
{
return func5(a1, "DA");
}

original_code:
int gopro_camera_delete_all(gopro_camera *cam) {
  return gopro_camera_send(cam, "DA");
}

canonical_original_code:
int gopro_camera_delete_all(struct gopro_camera *cam) {
  return gopro_camera_send(cam, "DA");
}


decompiled_code:
void __fastcall vbuffer_free(void *ptr)
{
void *v2; // rdi

v2 = *(void **)ptr;
if ( v2 )
free(v2);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func0(void *ptr)
{
void *v2; // rdi

v2 = *(void **)ptr;
if ( v2 )
free(v2);
free(ptr);
}

original_code:
void vbuffer_free(vbuffer *buffer) {
  if (buffer->data != ((void *)0)) free(buffer->data);
  free(buffer);
}

canonical_original_code:
void vbuffer_free(struct vbuffer *buffer) {
  if (buffer->data != ((void *)0)) free(buffer->data);
  free(buffer);
}

variable_types: struct vbuffer { void *data; unsigned long capacity; unsigned long length; } *


decompiled_code:
__int64 __fastcall vbuffer_resize(__int64 a1, size_t a2)
{
void *v2; // r12
size_t v3; // rbx
void *v4; // rax
__int64 result; // rax

if ( *(_QWORD *)(a1 + 8) == a2 )
return 0LL;
v2 = *(void **)a1;
v3 = a2;
v4 = malloc(a2);
*(_QWORD *)a1 = v4;
if ( v4 )
{
*(_QWORD *)(a1 + 8) = a2;
if ( v2 )
{
if ( *(_QWORD *)(a1 + 16) <= a2 )
v3 = *(_QWORD *)(a1 + 16);
memcpy(v4, v2, v3);
*(_QWORD *)(a1 + 16) = v3;
free(v2);
}
result = 0LL;
}
else
{
perror("Error allocating memory for buffer resize");
*(_QWORD *)a1 = v2;
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, size_t a2)
{
void *v2; // r12
size_t v3; // rbx
void *v4; // rax
__int64 result; // rax

if ( *(_QWORD *)(a1 + 8) == a2 )
return 0LL;
v2 = *(void **)a1;
v3 = a2;
v4 = malloc(a2);
*(_QWORD *)a1 = v4;
if ( v4 )
{
*(_QWORD *)(a1 + 8) = a2;
if ( v2 )
{
if ( *(_QWORD *)(a1 + 16) <= a2 )
v3 = *(_QWORD *)(a1 + 16);
memcpy(v4, v2, v3);
*(_QWORD *)(a1 + 16) = v3;
free(v2);
}
result = 0LL;
}
else
{
perror("Error allocating memory for buffer resize");
*(_QWORD *)a1 = v2;
result = 1LL;
}
return result;
}

original_code:
int vbuffer_resize(vbuffer *buffer, size_t new_capacity) {
  size_t copylen;
  void *backup;
  if (new_capacity == buffer->capacity) return 0;
  backup = buffer->data;
  buffer->data = malloc(new_capacity);
  if (buffer->data == ((void *)0)) {
    perror("Error allocating memory for buffer resize");
    buffer->data = backup;
    return 1;
  }
  buffer->capacity = new_capacity;
  if (backup != ((void *)0)) {
    copylen = (new_capacity < buffer->length) ? new_capacity : buffer->length;
    memcpy(buffer->data, backup, copylen);
    buffer->length = copylen;
    free(backup);
  }
  return 0;
}

canonical_original_code:
int vbuffer_resize(struct vbuffer *buffer, unsigned long new_capacity) {
  unsigned long copylen;
  void *backup;
  if (new_capacity == buffer->capacity) return 0;
  backup = buffer->data;
  buffer->data = malloc(new_capacity);
  if (buffer->data == ((void *)0)) {
    perror("Error allocating memory for buffer resize");
    buffer->data = backup;
    return 1;
  }
  buffer->capacity = new_capacity;
  if (backup != ((void *)0)) {
    copylen = (new_capacity < buffer->length) ? new_capacity : buffer->length;
    memcpy(buffer->data, backup, copylen);
    buffer->length = copylen;
    free(backup);
  }
  return 0;
}

variable_types:
copylen
unsigned long

variable_types:
backup
void *


decompiled_code:
__int64 __fastcall vbuffer_append(_QWORD *a1, const void *a2, size_t a3)
{
__int64 v5; // rdi
int v6; // er8
__int64 result; // rax

v5 = a1[2];
if ( a1[1] < v5 + a3 )
{
v6 = vbuffer_resize((__int64)a1, v5 + a3);
result = 1LL;
if ( v6 )
return result;
v5 = a1[2];
}
memcpy((void *)(*a1 + v5), a2, a3);
a1[2] += a3;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1, const void *a2, size_t a3)
{
__int64 v5; // rdi
int v6; // er8
__int64 result; // rax

v5 = a1[2];
if ( a1[1] < v5 + a3 )
{
v6 = func1((__int64)a1, v5 + a3);
result = 1LL;
if ( v6 )
return result;
v5 = a1[2];
}
memcpy((void *)(*a1 + v5), a2, a3);
a1[2] += a3;
return 0LL;
}

original_code:
int vbuffer_append(vbuffer *buffer, void *data, size_t n) {
  size_t new_capacity;
  int err;
  if (buffer->capacity < buffer->length + n) {
    new_capacity = buffer->length + n;
    err = vbuffer_resize(buffer, new_capacity);
    if (err != 0) return 1;
  }
  void *end = ((char *)buffer->data) + buffer->length;
  memcpy(end, data, n);
  buffer->length += n;
  return 0;
}

canonical_original_code:
int vbuffer_append(struct vbuffer *buffer, void *data, unsigned long n) {
  unsigned long new_capacity;
  int err;
  if (buffer->capacity < buffer->length + n) {
    new_capacity = buffer->length + n;
    err = vbuffer_resize(buffer, new_capacity);
    if (err != 0) return 1;
  }
  void *end = ((char *)buffer->data) + buffer->length;
  memcpy(end, data, n);
  buffer->length += n;
  return 0;
}

variable_types:
data
void *

variable_types:
n
unsigned long

variable_types: err int

variable_types:
end
void *


decompiled_code:
void __fastcall gopro_client_free(void *ptr)
{
if ( !ptr )
_assert_fail("client", "src/client.c", 0x1Cu, "gopro_client_free");
if ( *(_QWORD *)ptr )
curl_easy_cleanup();
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
if ( !ptr )
_assert_fail("client", "src/client.c", 0x1Cu, "gopro_client_free");
if ( *(_QWORD *)ptr )
curl_easy_cleanup();
free(ptr);
}

original_code:
void gopro_client_free(gopro_client *client) {
  ((void) sizeof ((client) ? 1 : 0), __extension__ ({ if (client) ; else __assert_fail ("client", "src/client.c", 28, __extension__ __PRETTY_FUNCTION__); }));
  if (client->curl != ((void *)0)) curl_easy_cleanup(client->curl);
  free(client);
}

canonical_original_code:
void gopro_client_free(struct gopro_client *client) {
  ((void) sizeof ((client) ? 1 : 0), __extension__ ({ if (client) ; else __assert_fail ("client", "src/client.c", 28, __extension__ __PRETTY_FUNCTION__); }));
  if (client->curl != ((void *)0)) curl_easy_cleanup(client->curl);
  free(client);
}


decompiled_code:
_QWORD *gopro_client_create()
{
_QWORD *v0; // r12
__int64 v1; // rax
void *v3; // rdi

v0 = malloc(8uLL);
if ( v0 )
{
v1 = curl_easy_init();
*v0 = v1;
if ( !v1 )
{
fwrite("Error allocating curl handle\n", 1uLL, 0x1DuLL, stderr);
v3 = v0;
v0 = 0LL;
gopro_client_free(v3);
}
}
else
{
perror("Error allocating client object");
}
return v0;
}

canonical_decompiled_code:
_QWORD *func2()
{
_QWORD *v0; // r12
__int64 v1; // rax
void *v3; // rdi

v0 = malloc(8uLL);
if ( v0 )
{
v1 = curl_easy_init();
*v0 = v1;
if ( !v1 )
{
fwrite("Error allocating curl handle\n", 1uLL, 0x1DuLL, stderr);
v3 = v0;
v0 = 0LL;
func1(v3);
}
}
else
{
perror("Error allocating client object");
}
return v0;
}

original_code:
gopro_client *gopro_client_create() {
  gopro_client *client = (gopro_client *)malloc(sizeof(gopro_client));
  if (client == ((void *)0)) {
    perror("Error allocating client object");
    return ((void *)0);
  }
  client->curl = curl_easy_init();
  if (client->curl == ((void *)0)) {
    fprintf(stderr, "Error allocating curl handle\n");
    gopro_client_free(client);
    return ((void *)0);
  }
  return client;
}

canonical_original_code:
struct gopro_client *gopro_client_create() {
  struct gopro_client *client = (gopro_client *)malloc(sizeof(gopro_client));
  if (client == ((void *)0)) {
    perror("Error allocating client object");
    return ((void *)0);
  }
  client->curl = curl_easy_init();
  if (client->curl == ((void *)0)) {
    fprintf(stderr, "Error allocating curl handle\n");
    gopro_client_free(client);
    return ((void *)0);
  }
  return client;
}

return_type: struct gopro_client { void *curl; } *


repo: pmem/linux-examples

decompiled_code:
void *__fastcall pmem_map_fit(int fd, size_t a2)
{
void *v2; // rax
void *v3; // r12

v2 = mmap(0LL, a2, 3, 2, fd, 0LL);
if ( v2 == (void *)-1LL )
return 0LL;
v3 = v2;
PM_base = (__int64)v2;
PM_fd = dup(fd);
return v3;
}

canonical_decompiled_code:
void *__fastcall func0(int fd, size_t a2)
{
void *v2; // rax
void *v3; // r12

v2 = mmap(0LL, a2, 3, 2, fd, 0LL);
if ( v2 == (void *)-1LL )
return 0LL;
v3 = v2;
PM_base = (__int64)v2;
PM_fd = dup(fd);
return v3;
}

original_code:
void *
pmem_map_fit(int fd, size_t len)
{
 void *base;
 if ((base = mmap(((void *)0), len, 0x1|0x2, 0x02,
     fd, 0)) == ((void *) -1))
  return ((void *)0);
 PM_base = (uintptr_t)base;
 PM_fd = dup(fd);
 return base;
}

canonical_original_code:
void *pmem_map_fit(int fd, unsigned long len)
{
 void *base;
 if ((base = mmap(((void *)0), len, 0x1|0x2, 0x02,
     fd, 0)) == ((void *) -1))
  return ((void *)0);
 PM_base = (unsigned long)base;
 PM_fd = dup(fd);
 return base;
}

variable_types: fd int

variable_types:
len
unsigned long

variable_types:
base
void *

return_type: void *


decompiled_code:
void pmem_drain_pm_stores_fit()
{
;
}

canonical_decompiled_code:
void func1()
{
;
}

original_code:
void
pmem_drain_pm_stores_fit(void)
{
}

canonical_original_code:
void pmem_drain_pm_stores_fit()
{
}


decompiled_code:
void __fastcall pmem_flush_cache_fit(__int64 a1, __int64 a2)
{
unsigned __int64 v2; // rbp
char *v3; // rbx
int *v4; // rax

if ( !PM_base )
fatal(0LL, "pmem_fit.c", 99LL, "pmem_flush_cache_fit", "pmem_map hasn't been called");
v2 = a1 + a2;
v3 = (char *)(a1 & 0xFFFFFFFFFFFFFFC0LL);
if ( (a1 & 0xFFFFFFFFFFFFFFC0LL) < a1 + a2 )
{
do
{
while ( pwrite(PM_fd, v3, 0x40uLL, (__off_t)&v3[-PM_base]) >= 0 )
{
v3 += 64;
if ( (unsigned __int64)v3 >= v2 )
return;
}
v4 = _errno_location();
v3 += 64;
fatal(
(unsigned int)*v4,
"pmem_fit.c",
109LL,
"pmem_flush_cache_fit",
"pwrite len %d offset %lu",
a2,
a1 - PM_base);
}
while ( (unsigned __int64)v3 < v2 );
}
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1, __int64 a2)
{
unsigned __int64 v2; // rbp
char *v3; // rbx
int *v4; // rax

if ( !PM_base )
fatal(0LL, "pmem_fit.c", 99LL, "pmem_flush_cache_fit", "pmem_map hasn't been called");
v2 = a1 + a2;
v3 = (char *)(a1 & 0xFFFFFFFFFFFFFFC0LL);
if ( (a1 & 0xFFFFFFFFFFFFFFC0LL) < a1 + a2 )
{
do
{
while ( pwrite(PM_fd, v3, 0x40uLL, (__off_t)&v3[-PM_base]) >= 0 )
{
v3 += 64;
if ( (unsigned __int64)v3 >= v2 )
return;
}
v4 = _errno_location();
v3 += 64;
fatal(
(unsigned int)*v4,
"pmem_fit.c",
109LL,
"pmem_flush_cache_fit",
"pwrite len %d offset %lu",
a2,
a1 - PM_base);
}
while ( (unsigned __int64)v3 < v2 );
}
}

original_code:
void
pmem_flush_cache_fit(void *addr, size_t len, int flags)
{
 uintptr_t uptr;
 if (!PM_base)
  fatal(0, "pmem_fit.c", 99, __func__, "pmem_map hasn't been called");
 for (uptr = (uintptr_t)addr & ~(64 - 1);
   uptr < (uintptr_t)addr + len; uptr += 64)
  if (pwrite(PM_fd, (void *)uptr, 64, uptr - PM_base) < 0)
   fatal((*__errno_location ()), "pmem_fit.c", 109, __func__, "pwrite len %d offset %lu", len, addr - PM_base);
}

canonical_original_code:
void pmem_flush_cache_fit(void *addr, unsigned long len, int flags)
{
 unsigned long uptr;
 if (!PM_base)
  fatal(0, "pmem_fit.c", 99, __func__, "pmem_map hasn't been called");
 for (uptr = (unsigned long)addr & ~(64 - 1);
   uptr < (unsigned long)addr + len; uptr += 64)
  if (pwrite(PM_fd, (void *)uptr, 64, uptr - PM_base) < 0)
   fatal((*__errno_location ()), "pmem_fit.c", 109, __func__, "pwrite len %d offset %lu", len, addr - PM_base);
}

variable_types:
addr
void *

variable_types: flags int

variable_types:
uptr
unsigned long


decompiled_code:
void __fastcall pmem_persist_fit(__int64 a1, __int64 a2)
{
pmem_flush_cache_fit(a1, a2);
_mm_sfence();
pmem_drain_pm_stores_fit();
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1, __int64 a2)
{
func2(a1, a2);
_mm_sfence();
func1();
}

original_code:
void
pmem_persist_fit(void *addr, size_t len, int flags)
{
 pmem_flush_cache_fit(addr, len, flags);
 __builtin_ia32_sfence();
 pmem_drain_pm_stores_fit();
}

canonical_original_code:
void pmem_persist_fit(void *addr, unsigned long len, int flags)
{
 pmem_flush_cache_fit(addr, len, flags);
 __builtin_ia32_sfence();
 pmem_drain_pm_stores_fit();
}


decompiled_code:
__int64 __fastcall tree_insert_subtree(_QWORD *a1, const char *a2)
{
__int64 v3; // rbx
int v4; // eax
size_t v5; // rax
__int64 v6; // r13
__int64 v7; // r14
__int64 v8; // rdi
int *v10; // rax

while ( 1 )
{
debug("tree.c", 98LL, "tree_insert_subtree", "*rootp_ = %lx", *a1);
if ( !*a1 )
break;
v3 = Pmp + *a1;
v4 = strcmp(a2, (const char *)(v3 + 20));
if ( !v4 )
{
++*(_DWORD *)(v3 + 16);
pmem_persist(v3 + 16, 4LL, 0LL);
return debug("tree.c", 123LL, "tree_insert_subtree", "new count=%u", *(unsigned int *)(Pmp + *a1 + 16));
}
a1 = (_QWORD *)(v3 + 8);
if ( v4 < 0 )
a1 = (_QWORD *)v3;
}
v5 = strlen(a2);
v6 = pmemalloc_reserve(Pmp, v5 + 25);
if ( !v6 )
{
v10 = _errno_location();
fatal((unsigned int)*v10, "tree.c", 107LL, "tree_insert_subtree", "pmem_alloc");
}
v7 = Pmp;
v8 = Pmp + v6;
*(_QWORD *)(v8 + 8) = 0LL;
v8 += 20LL;
*(_QWORD *)(v8 - 20) = 0LL;
*(_DWORD *)(v8 - 4) = 1;
strcpy((char *)v8, a2);
pmemalloc_onactive(v7, v6, a1, v6);
pmemalloc_activate(Pmp, v6);
return debug("tree.c", 117LL, "tree_insert_subtree", "new node inserted, count=1");
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1, const char *a2)
{
__int64 v3; // rbx
int v4; // eax
size_t v5; // rax
__int64 v6; // r13
__int64 v7; // r14
__int64 v8; // rdi
int *v10; // rax

while ( 1 )
{
debug("tree.c", 98LL, "tree_insert_subtree", "*rootp_ = %lx", *a1);
if ( !*a1 )
break;
v3 = Pmp + *a1;
v4 = strcmp(a2, (const char *)(v3 + 20));
if ( !v4 )
{
++*(_DWORD *)(v3 + 16);
pmem_persist(v3 + 16, 4LL, 0LL);
return debug("tree.c", 123LL, "tree_insert_subtree", "new count=%u", *(unsigned int *)(Pmp + *a1 + 16));
}
a1 = (_QWORD *)(v3 + 8);
if ( v4 < 0 )
a1 = (_QWORD *)v3;
}
v5 = strlen(a2);
v6 = pmemalloc_reserve(Pmp, v5 + 25);
if ( !v6 )
{
v10 = _errno_location();
fatal((unsigned int)*v10, "tree.c", 107LL, "tree_insert_subtree", "pmem_alloc");
}
v7 = Pmp;
v8 = Pmp + v6;
*(_QWORD *)(v8 + 8) = 0LL;
v8 += 20LL;
*(_QWORD *)(v8 - 20) = 0LL;
*(_DWORD *)(v8 - 4) = 1;
strcpy((char *)v8, a2);
pmemalloc_onactive(v7, v6, a1, v6);
pmemalloc_activate(Pmp, v6);
return debug("tree.c", 117LL, "tree_insert_subtree", "new node inserted, count=1");
}

original_code:
static void
tree_insert_subtree(struct tnode **rootp_, const char *s)
{
 int diff;
 debug("tree.c", 98, __func__, "*rootp_ = %lx", (uintptr_t)*rootp_);
 if (*rootp_ == ((void *)0)) {
  struct tnode *tnp_;
  size_t slen = strlen(s) + 1;
  if ((tnp_ = pmemalloc_reserve(Pmp, sizeof(*tnp_) +
      slen)) == ((void *)0))
   fatal((*__errno_location ()), "tree.c", 107, __func__, "pmem_alloc");
  ((typeof(tnp_))(Pmp + (uintptr_t)tnp_))->left_ =
  ((typeof(tnp_))(Pmp + (uintptr_t)tnp_))->right_ = ((void *)0);
  ((typeof(tnp_))(Pmp + (uintptr_t)tnp_))->count = 1;
  strcpy(((typeof(tnp_))(Pmp + (uintptr_t)tnp_))->s, s);
  pmemalloc_onactive(Pmp, tnp_, (void **)rootp_, tnp_);
  pmemalloc_activate(Pmp, tnp_);
  debug("tree.c", 117, __func__, "new node inserted, count=1");
 } else if ((diff = strcmp(s, ((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->s)) == 0) {
  ((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->count++;
  pmem_persist(&((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->count, sizeof(unsigned), 0);
  debug("tree.c", 123, __func__, "new count=%u", ((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->count);
 } else if (diff < 0) {
  tree_insert_subtree(&((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->left_, s);
 } else {
  tree_insert_subtree(&((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->right_, s);
 }
}

canonical_original_code:
static void tree_insert_subtree(struct tnode **rootp_, char *s)
{
 int diff;
 debug("tree.c", 98, __func__, "*rootp_ = %lx", (unsigned long)*rootp_);
 if (*rootp_ == ((void *)0)) {
  struct tnode *tnp_;
  unsigned long slen = strlen(s) + 1;
  if ((tnp_ = pmemalloc_reserve(Pmp, sizeof(*tnp_) +
      slen)) == ((void *)0))
   fatal((*__errno_location ()), "tree.c", 107, __func__, "pmem_alloc");
  ((typeof(tnp_))(Pmp + (unsigned long)tnp_))->left_ =
  ((typeof(tnp_))(Pmp + (unsigned long)tnp_))->right_ = ((void *)0);
  ((typeof(tnp_))(Pmp + (unsigned long)tnp_))->count = 1;
  strcpy(((typeof(tnp_))(Pmp + (unsigned long)tnp_))->s, s);
  pmemalloc_onactive(Pmp, tnp_, (void **)rootp_, tnp_);
  pmemalloc_activate(Pmp, tnp_);
  debug("tree.c", 117, __func__, "new node inserted, count=1");
 } else if ((diff = strcmp(s, ((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->s)) == 0) {
  ((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->count++;
  pmem_persist(&((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->count, sizeof(unsigned int), 0);
  debug("tree.c", 123, __func__, "new count=%u", ((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->count);
 } else if (diff < 0) {
  tree_insert_subtree(&((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->left_, s);
 } else {
  tree_insert_subtree(&((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->right_, s);
 }
}

variable_types: struct tnode { struct tnode *left_; struct tnode *right_; unsigned int count; char s[]; } **

variable_types:
s
char *

variable_types: diff int

variable_types:
slen
unsigned long


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

while ( 1 )
{
result = debug("tree.c", 152LL, "tree_walk_subtree", "root_ = %lx", a1);
if ( !a1 )
break;
tree_walk_subtree(*(_QWORD *)(Pmp + a1));
printf("%5d %s\n", *(unsigned int *)(a1 + Pmp + 16), (const char *)(a1 + Pmp + 20));
a1 = *(_QWORD *)(Pmp + a1 + 8);
}
return result;
}

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

while ( 1 )
{
result = debug("tree.c", 152LL, "tree_walk_subtree", "root_ = %lx", a1);
if ( !a1 )
break;
func1(*(_QWORD *)(Pmp + a1));
printf("%5d %s\n", *(unsigned int *)(a1 + Pmp + 16), (const char *)(a1 + Pmp + 20));
a1 = *(_QWORD *)(Pmp + a1 + 8);
}
return result;
}

original_code:
static void
tree_walk_subtree(struct tnode *root_)
{
 debug("tree.c", 152, __func__, "root_ = %lx", (uintptr_t)root_);
 if (root_) {
  tree_walk_subtree(((typeof(root_))(Pmp + (uintptr_t)root_))->left_);
  printf("%5d %s\n",
    ((typeof(root_))(Pmp + (uintptr_t)root_))->count,
    ((typeof(root_))(Pmp + (uintptr_t)root_))->s);
  tree_walk_subtree(((typeof(root_))(Pmp + (uintptr_t)root_))->right_);
 }
}

canonical_original_code:
static void tree_walk_subtree(struct tnode *root_)
{
 debug("tree.c", 152, __func__, "root_ = %lx", (unsigned long)root_);
 if (root_) {
  tree_walk_subtree(((typeof(root_))(Pmp + (unsigned long)root_))->left_);
  printf("%5d %s\n",
    ((typeof(root_))(Pmp + (unsigned long)root_))->count,
    ((typeof(root_))(Pmp + (unsigned long)root_))->s);
  tree_walk_subtree(((typeof(root_))(Pmp + (unsigned long)root_))->right_);
 }
}

variable_types: struct tnode { struct tnode *left_; struct tnode *right_; unsigned int count; char s[]; } *


decompiled_code:
__int64 __fastcall tree_free_subtree(_QWORD *a1)
{
__int64 result; // rax
__int64 v3; // rdi

result = debug("tree.c", 187LL, "tree_free_subtree", "*rootp_ = %lx", *a1);
v3 = *a1;
if ( v3 )
{
tree_free_subtree(Pmp + v3);
tree_free_subtree(Pmp + *a1 + 8);
pmemalloc_onfree(Pmp, *a1, a1, 0LL);
result = pmemalloc_free(Pmp, *a1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1)
{
__int64 result; // rax
__int64 v3; // rdi

result = debug("tree.c", 187LL, "tree_free_subtree", "*rootp_ = %lx", *a1);
v3 = *a1;
if ( v3 )
{
func2(Pmp + v3);
func2(Pmp + *a1 + 8);
pmemalloc_onfree(Pmp, *a1, a1, 0LL);
result = pmemalloc_free(Pmp, *a1);
}
return result;
}

original_code:
static void
tree_free_subtree(struct tnode **rootp_)
{
 debug("tree.c", 187, __func__, "*rootp_ = %lx", (uintptr_t)*rootp_);
 if (*rootp_ != ((void *)0)) {
  tree_free_subtree(&((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->left_);
  tree_free_subtree(&((typeof(*rootp_))(Pmp + (uintptr_t)*rootp_))->right_);
  pmemalloc_onfree(Pmp, (void *)*rootp_, (void **)rootp_, ((void *)0));
  pmemalloc_free(Pmp, (void *)*rootp_);
 }
}

canonical_original_code:
static void tree_free_subtree(struct tnode **rootp_)
{
 debug("tree.c", 187, __func__, "*rootp_ = %lx", (unsigned long)*rootp_);
 if (*rootp_ != ((void *)0)) {
  tree_free_subtree(&((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->left_);
  tree_free_subtree(&((typeof(*rootp_))(Pmp + (unsigned long)*rootp_))->right_);
  pmemalloc_onfree(Pmp, (void *)*rootp_, (void **)rootp_, ((void *)0));
  pmemalloc_free(Pmp, (void *)*rootp_);
 }
}

user_defined_types: struct tnode { struct tnode *left_; struct tnode *right_; unsigned int count; char s[]; }