decompiled_code:
int delete_slabs()
{
_QWORD *v0; // rbx
void *v1; // rdi
int result; // eax

v0 = first_slab;
if ( first_slab )
{
do
{
v1 = v0;
v0 = (_QWORD *)*v0;
result = munmap(v1, 0x100000uLL);
}
while ( v0 );
}
first_slab = 0LL;
current_slab = 0LL;
return result;
}

canonical_decompiled_code:
int func7()
{
_QWORD *v0; // rbx
void *v1; // rdi
int result; // eax

v0 = first_slab;
if ( first_slab )
{
do
{
v1 = v0;
v0 = (_QWORD *)*v0;
result = munmap(v1, 0x100000uLL);
}
while ( v0 );
}
first_slab = 0LL;
current_slab = 0LL;
return result;
}

original_code:
static void delete_slabs(void)
{
 struct symbol_slab *ss, *next;
 for (ss = first_slab; ss; ss = next) {
  next = ss->next;
  munmap(ss, (1024*1024));
 }
 current_slab = first_slab = ((void *)0);
}

canonical_original_code:
static void delete_slabs()
{
 struct symbol_slab *ss; struct symbol_slab *next;
 for (ss = first_slab; ss; ss = next) {
  next = ss->next;
  munmap(ss, (1024*1024));
 }
 current_slab = first_slab = ((void *)0);
}


repo: michich/lattop

decompiled_code:
__int64 build_arrays()
{
__int64 v0; // rbx
void *v1; // rax
__int64 v2; // rax
unsigned int v3; // ebx
__int64 i; // rdi
__int64 v5; // rdx

v0 = (unsigned int)n_symbols;
v1 = mmap(0LL, 16LL * (unsigned int)n_symbols, 3, 34, -1, 0LL);
if ( v1 == (void *)-1LL )
return 4294967284LL;
addr_name_arrays = v1;
addr_array = (__int64)v1;
v2 = (__int64)v1 + 8 * v0;
v3 = 0;
name_array = v2;
for ( i = rb_first(&addr2fun); i; i = rb_next() )
{
v5 = v3++;
*(_QWORD *)(addr_array + 8 * v5) = *(_QWORD *)(i + 24);
*(_QWORD *)(name_array + 8 * v5) = (char *)all_names + *(_QWORD *)(i + 32);
}
if ( n_symbols != v3 )
_assert_fail("i == n_symbols", "sym_translator.c", 0x119u, "build_arrays");
mprotect(addr_name_arrays, 16LL * v3, 1);
delete_slabs();
return 0LL;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 v0; // rbx
void *v1; // rax
__int64 v2; // rax
unsigned int v3; // ebx
__int64 i; // rdi
__int64 v5; // rdx

v0 = (unsigned int)n_symbols;
v1 = mmap(0LL, 16LL * (unsigned int)n_symbols, 3, 34, -1, 0LL);
if ( v1 == (void *)-1LL )
return 4294967284LL;
addr_name_arrays = v1;
addr_array = (__int64)v1;
v2 = (__int64)v1 + 8 * v0;
v3 = 0;
name_array = v2;
for ( i = rb_first(&addr2fun); i; i = rb_next() )
{
v5 = v3++;
*(_QWORD *)(addr_array + 8 * v5) = *(_QWORD *)(i + 24);
*(_QWORD *)(name_array + 8 * v5) = (char *)all_names + *(_QWORD *)(i + 32);
}
if ( n_symbols != v3 )
_assert_fail("i == n_symbols", "sym_translator.c", 0x119u, "build_arrays");
mprotect(addr_name_arrays, 16LL * v3, 1);
func7();
return 0LL;
}

original_code:
static int build_arrays(void)
{
 void *new_alloc;
 struct rb_node *node;
 unsigned i;
 new_alloc = mmap(((void *)0), n_symbols * (sizeof(unsigned long) + sizeof(char*)),
                  0x1|0x2, 0x02|0x20, -1, 0);
 if (new_alloc == ((void *) -1))
  return -12;
 addr_name_arrays = new_alloc;
 addr_array = (unsigned long*) addr_name_arrays;
 name_array = (char**)(addr_name_arrays + n_symbols * sizeof(unsigned long));
 i = 0;
 for (node = rb_first(&addr2fun); node; node = rb_next(node)) {
  struct symbol *symbol = (struct symbol *)((char *)(node) - (char *) &((struct symbol *)0)->rb_node);
  addr_array[i] = symbol->addr;
  name_array[i] = all_names + symbol->name_offset;
  i++;
 }
 ((void) sizeof ((i == n_symbols) ? 1 : 0), __extension__ ({ if (i == n_symbols) ; else __assert_fail ("i == n_symbols", "sym_translator.c", 281, __extension__ __PRETTY_FUNCTION__); }));
 mprotect(addr_name_arrays, n_symbols * (sizeof(unsigned long) + sizeof(char*)), 0x1);
 delete_slabs();
 return 0;
}

canonical_original_code:
static int build_arrays()
{
 void *new_alloc;
 struct rb_node *node;
 unsigned int i;
 new_alloc = mmap(((void *)0), n_symbols * (sizeof(unsigned long) + sizeof(char *)),
                  0x1|0x2, 0x02|0x20, -1, 0);
 if (new_alloc == ((void *) -1))
  return -12;
 addr_name_arrays = new_alloc;
 addr_array = (unsigned long *) addr_name_arrays;
 name_array = (char **)(addr_name_arrays + n_symbols * sizeof(unsigned long));
 i = 0;
 for (node = rb_first(&addr2fun); node; node = rb_next(node)) {
  struct symbol *symbol = (struct symbol *)((char *)(node) - (char *) &((struct symbol *)0)->rb_node);
  addr_array[i] = symbol->addr;
  name_array[i] = all_names + symbol->name_offset;
  i++;
 }
 ((void) sizeof ((i == n_symbols) ? 1 : 0), __extension__ ({ if (i == n_symbols) ; else __assert_fail ("i == n_symbols", "sym_translator.c", 281, __extension__ __PRETTY_FUNCTION__); }));
 mprotect(addr_name_arrays, n_symbols * (sizeof(unsigned long) + sizeof(char *)), 0x1);
 delete_slabs();
 return 0;
}

variable_types: struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } *

variable_types:
i
unsigned int

variable_types: struct symbol { struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } rb_node; unsigned long addr; long name_offset; } *

return_type: int

user_defined_types: struct symbol { struct rb_node rb_node; unsigned long addr; long name_offset; }


decompiled_code:
int delete_arrays()
{
int result; // eax

if ( all_names )
{
result = munmap(all_names, all_names_alloc);
all_names = 0LL;
}
if ( addr_name_arrays )
{
result = munmap(addr_name_arrays, 16LL * (unsigned int)n_symbols);
addr_array = 0LL;
name_array = 0LL;
addr_name_arrays = 0LL;
}
return result;
}

canonical_decompiled_code:
int func9()
{
int result; // eax

if ( all_names )
{
result = munmap(all_names, all_names_alloc);
all_names = 0LL;
}
if ( addr_name_arrays )
{
result = munmap(addr_name_arrays, 16LL * (unsigned int)n_symbols);
addr_array = 0LL;
name_array = 0LL;
addr_name_arrays = 0LL;
}
return result;
}

original_code:
static void delete_arrays(void)
{
 if (all_names) {
  munmap(all_names, all_names_alloc);
  all_names = ((void *)0);
 }
 if (addr_name_arrays) {
  munmap(addr_name_arrays, n_symbols * (sizeof(unsigned long) + sizeof(char*)));
  addr_array = ((void *)0);
  name_array = ((void *)0);
  addr_name_arrays = ((void *)0);
 }
}

canonical_original_code:
static void delete_arrays()
{
 if (all_names) {
  munmap(all_names, all_names_alloc);
  all_names = ((void *)0);
 }
 if (addr_name_arrays) {
  munmap(addr_name_arrays, n_symbols * (sizeof(unsigned long) + sizeof(char *)));
  addr_array = ((void *)0);
  name_array = ((void *)0);
  addr_name_arrays = ((void *)0);
 }
}

return_type: void


decompiled_code:
__int64 __fastcall sym_translator_lookup(unsigned __int64 a1)
{
__int64 v1; // r8
unsigned int v2; // edx
__int64 v3; // rcx
__int64 v5; // rax

v1 = addr_array;
if ( !addr_array )
return v1;
if ( !name_array )
return 0LL;
if ( !all_names )
return 0LL;
if ( !n_symbols )
return 0LL;
v2 = n_symbols - 1;
if ( *(_QWORD *)addr_array > a1 )
return 0LL;
v3 = 0LL;
if ( *(_QWORD *)(addr_array + 8LL * v2) <= a1 )
return *(_QWORD *)(name_array + 8LL * v2);
while ( v2 - (unsigned int)v3 > 1 )
{
v5 = (v2 + (unsigned int)v3) >> 1;
if ( *(_QWORD *)(addr_array + 8 * v5) > a1 )
v2 = v5;
if ( *(_QWORD *)(addr_array + 8 * v5) <= a1 )
v3 = v5;
}
return *(_QWORD *)(name_array + 8 * v3);
}

canonical_decompiled_code:
__int64 __fastcall func10(unsigned __int64 a1)
{
__int64 v1; // r8
unsigned int v2; // edx
__int64 v3; // rcx
__int64 v5; // rax

v1 = addr_array;
if ( !addr_array )
return v1;
if ( !name_array )
return 0LL;
if ( !all_names )
return 0LL;
if ( !n_symbols )
return 0LL;
v2 = n_symbols - 1;
if ( *(_QWORD *)addr_array > a1 )
return 0LL;
v3 = 0LL;
if ( *(_QWORD *)(addr_array + 8LL * v2) <= a1 )
return *(_QWORD *)(name_array + 8LL * v2);
while ( v2 - (unsigned int)v3 > 1 )
{
v5 = (v2 + (unsigned int)v3) >> 1;
if ( *(_QWORD *)(addr_array + 8 * v5) > a1 )
v2 = v5;
if ( *(_QWORD *)(addr_array + 8 * v5) <= a1 )
v3 = v5;
}
return *(_QWORD *)(name_array + 8 * v3);
}

original_code:
const char *sym_translator_lookup(unsigned long ip)
{
 unsigned low, high, middle;
 if (!addr_array || !name_array || !all_names || n_symbols == 0)
  return ((void *)0);
 low = 0;
 high = n_symbols - 1;
 if (ip < addr_array[low])
  return ((void *)0);
 if (ip >= addr_array[high])
  return name_array[high];
 while (high - low > 1) {
  middle = (low + high) / 2;
  if (addr_array[middle] <= ip)
   low = middle;
  else
   high = middle;
 }
 return name_array[low];
}

canonical_original_code:
char *sym_translator_lookup(unsigned long ip)
{
 unsigned int low; unsigned int high; unsigned int middle;
 if (!addr_array || !name_array || !all_names || n_symbols == 0)
  return ((void *)0);
 low = 0;
 high = n_symbols - 1;
 if (ip < addr_array[low])
  return ((void *)0);
 if (ip >= addr_array[high])
  return name_array[high];
 while (high - low > 1) {
  middle = (low + high) / 2;
  if (addr_array[middle] <= ip)
   low = middle;
  else
   high = middle;
 }
 return name_array[low];
}

variable_types:
ip
unsigned long

variable_types:
low
unsigned int

variable_types:
high
unsigned int

variable_types:
middle
unsigned int

return_type: char *


decompiled_code:
int sym_translator_fini()
{
delete_slabs();
return delete_arrays();
}

canonical_decompiled_code:
int func11()
{
func7();
return func9();
}

original_code:
void sym_translator_fini(void)
{
 delete_slabs();
 delete_arrays();
}

canonical_original_code:
void sym_translator_fini()
{
 delete_slabs();
 delete_arrays();
}


decompiled_code:
__int64 sym_translator_init()
{
unsigned int v0; // er12

v0 = parse_kallsyms();
if ( !v0 )
{
v0 = build_arrays();
if ( !v0 )
return 0LL;
}
sym_translator_fini();
return v0;
}

canonical_decompiled_code:
__int64 func12()
{
unsigned int v0; // er12

v0 = func6();
if ( !v0 )
{
v0 = func8();
if ( !v0 )
return 0LL;
}
func11();
return v0;
}

original_code:
int sym_translator_init(void)
{
 int r;
 r = parse_kallsyms();
 if (r)
  goto err;
 r = build_arrays();
 if (r)
  goto err;
 return 0;
err:
 sym_translator_fini();
 return r;
}

canonical_original_code:
int sym_translator_init()
{
 int r;
 r = parse_kallsyms();
 if (r)
  goto err;
 r = build_arrays();
 if (r)
  goto err;
 return 0;
err:
 sym_translator_fini();
 return r;
}

variable_types: r int


decompiled_code:
__int64 __fastcall start_reader(unsigned int a1)
{
__int64 v1; // rbx
__int64 v2; // rdi
__int64 v3; // rax
__int64 (*v4)(void); // rdx
unsigned int v5; // eax
unsigned int v6; // er12
unsigned int v7; // er12
char *v9; // rax

v1 = a1;
v2 = readers[a1];
if ( !v2 )
{
v7 = -12;
fwrite("Out of memory.\n", 1uLL, 0xFuLL, stderr);
return v7;
}
v3 = *(_QWORD *)v2;
v4 = *(__int64 (**)(void))(*(_QWORD *)v2 + 8LL);
if ( !v4 )
{
LABEL_5:
v7 = 0;
*(&poll_fds.fd + 2 * v1) = (*(__int64 (**)(void))(v3 + 16))();
*(&poll_fds.events + 4 * v1) = 1;
return v7;
}
v5 = v4();
v6 = v5;
if ( !v5 )
{
v3 = *(_QWORD *)readers[v1];
goto LABEL_5;
}
v9 = strerror(-v5);
fprintf(stderr, "Failed to start reader #%d: %s\n", (unsigned int)v1, v9);
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1)
{
__int64 v1; // rbx
__int64 v2; // rdi
__int64 v3; // rax
__int64 (*v4)(void); // rdx
unsigned int v5; // eax
unsigned int v6; // er12
unsigned int v7; // er12
char *v9; // rax

v1 = a1;
v2 = readers[a1];
if ( !v2 )
{
v7 = -12;
fwrite("Out of memory.\n", 1uLL, 0xFuLL, stderr);
return v7;
}
v3 = *(_QWORD *)v2;
v4 = *(__int64 (**)(void))(*(_QWORD *)v2 + 8LL);
if ( !v4 )
{
LABEL_5:
v7 = 0;
*(&poll_fds.fd + 2 * v1) = (*(__int64 (**)(void))(v3 + 16))();
*(&poll_fds.events + 4 * v1) = 1;
return v7;
}
v5 = v4();
v6 = v5;
if ( !v5 )
{
v3 = *(_QWORD *)readers[v1];
goto LABEL_5;
}
v9 = strerror(-v5);
fprintf(stderr, "Failed to start reader #%d: %s\n", (unsigned int)v1, v9);
return v6;
}

original_code:
static int start_reader(unsigned index)
{
 int r;
 if (!readers[index]) {
  fprintf(stderr, "Out of memory.\n");
  return -12;
 }
 if (readers[index]->ops->start) {
  r = readers[index]->ops->start(readers[index]);
  if (r) {
   fprintf(stderr, "Failed to start reader #%d: %s\n",
    index, strerror(-r));
   return r;
  }
 }
 poll_fds[index].fd = readers[index]->ops->get_fd(readers[index]);
 poll_fds[index].events = 0x001;
 return 0;
}

canonical_original_code:
static int start_reader(unsigned int index)
{
 int r;
 if (!readers[index]) {
  fprintf(stderr, "Out of memory.\n");
  return -12;
 }
 if (readers[index]->ops->start) {
  r = readers[index]->ops->start(readers[index]);
  if (r) {
   fprintf(stderr, "Failed to start reader #%d: %s\n",
    index, strerror(-r));
   return r;
  }
 }
 poll_fds[index].fd = readers[index]->ops->get_fd(readers[index]);
 poll_fds[index].events = 0x001;
 return 0;
}

variable_types:
index
unsigned int


decompiled_code:
void __fastcall __noreturn usage_and_exit(int status)
{
fwrite(
"Usage: lattop [-i INTERVAL] [-c COUNT] [-s SORT_BY] [-r]\n"
" -i, --interval=INTERVAL time in seconds between printouts (default: 5)\n"
" -c, --count=COUNT stop after COUNT printouts\n"
" -s, --sort=SORT_BY sort the output by one of:\n"
" 'max' maximum latency (default)\n"
" 'total' total latency\n"
" 'pid' pid of the process\n"
" -r, --reverse reverse the sort order\n"
" -m, --min-latency=MIN ignore latencies shorter than MIN microseconds\n"
" -M, --max-interruptible=MAX ignore latencies from interruptible sleeps longer\n"
" than MAX microseconds (default: 5000)\n"
" -p, --pid-filter=PID show only the process with the given PID\n",
1uLL,
0x319uLL,
stderr);
exit(status);
}

canonical_decompiled_code:
void __fastcall __noreturn func1(int status)
{
fwrite(
"Usage: lattop [-i INTERVAL] [-c COUNT] [-s SORT_BY] [-r]\n"
" -i, --interval=INTERVAL time in seconds between printouts (default: 5)\n"
" -c, --count=COUNT stop after COUNT printouts\n"
" -s, --sort=SORT_BY sort the output by one of:\n"
" 'max' maximum latency (default)\n"
" 'total' total latency\n"
" 'pid' pid of the process\n"
" -r, --reverse reverse the sort order\n"
" -m, --min-latency=MIN ignore latencies shorter than MIN microseconds\n"
" -M, --max-interruptible=MAX ignore latencies from interruptible sleeps longer\n"
" than MAX microseconds (default: 5000)\n"
" -p, --pid-filter=PID show only the process with the given PID\n",
1uLL,
0x319uLL,
stderr);
exit(status);
}

original_code:
static void usage_and_exit(int code)
{
 fprintf(stderr,
"Usage: lattop [-i INTERVAL] [-c COUNT] [-s SORT_BY] [-r]\n"
"  -i, --interval=INTERVAL      time in seconds between printouts (default: 5)\n"
"  -c, --count=COUNT            stop after COUNT printouts\n"
"  -s, --sort=SORT_BY           sort the output by one of:\n"
"                                'max'      maximum latency (default)\n"
"                                'total'    total latency\n"
"                                'pid'      pid of the process\n"
"  -r, --reverse                reverse the sort order\n"
"  -m, --min-latency=MIN        ignore latencies shorter than MIN microseconds\n"
"  -M, --max-interruptible=MAX  ignore latencies from interruptible sleeps longer\n"
"                               than MAX microseconds (default: 5000)\n"
"  -p, --pid-filter=PID         show only the process with the given PID\n");
 exit(code);
}

variable_types: code int


decompiled_code:
int __fastcall parse_argv(int argc, char **argv)
{
int result; // eax
char *v4; // r12
int v5; // eax
int *v6; // rax
char *v7; // rdi
int *v8; // r12
int *v9; // rax
char *v10; // rdi
int *v11; // r12
unsigned __int64 v12; // rax
int v13; // ecx
int *v14; // rax
char *v15; // rdi
int *v16; // r12
unsigned __int64 v17; // rax
int v18; // edx
int longind; // [rsp+4h] [rbp-24h] BYREF
char *endptr[4]; // [rsp+8h] [rbp-20h] BYREF

longind = 0;
while ( 1 )
{
result = getopt_long(argc, argv, "i:c:s:rm:M:p:h", &long_options_2, &longind);
if ( result == -1 )
break;
switch ( result )
{
case 'M':
v14 = _errno_location();
v15 = optarg;
*v14 = 0;
v16 = v14;
v17 = strtoull(v15, endptr, 10);
v18 = *v16;
arg_max_interruptible_delay = v17;
if ( v18 || endptr[0] == optarg || *endptr[0] )
goto LABEL_33;
arg_max_interruptible_delay = 1000 * v17;
continue;
case 'c':
arg_count = atoi(optarg);
if ( arg_interval < 0 )
{
fwrite("Count must be positive (or zero for infinite).\n", 1uLL, 0x2FuLL, stderr);
exit(1);
}
continue;
case 'h':
usage_and_exit(0);
case 'i':
arg_interval = atoi(optarg);
if ( arg_interval <= 0 )
{
fwrite("Interval must be a positive number.\n", 1uLL, 0x24uLL, stderr);
exit(1);
}
continue;
case 'm':
v9 = _errno_location();
v10 = optarg;
*v9 = 0;
v11 = v9;
v12 = strtoull(v10, endptr, 10);
v13 = *v11;
arg_min_delay = v12;
if ( v13 || endptr[0] == optarg || *endptr[0] )
{
LABEL_33:
fprintf(stderr, "Invalid delay specification '%s'\n", optarg);
LABEL_8:
exit(1);
}
arg_min_delay = 1000 * v12;
break;
case 'p':
v6 = _errno_location();
v7 = optarg;
*v6 = 0;
v8 = v6;
arg_pid_filter = strtoul(v7, endptr, 10);
if ( !*v8 && endptr[0] != optarg && !*endptr[0] )
continue;
fprintf(stderr, "Invalid PID specification '%s'\n", optarg);
goto LABEL_8;
case 'r':
arg_reverse = 1;
continue;
case 's':
v4 = optarg;
v5 = strcasecmp(optarg, "max");
if ( !v5 )
goto LABEL_27;
if ( !strcasecmp(v4, "total") )
{
v5 = 1;
}
else
{
if ( strcasecmp(v4, "pid") )
{
fprintf(stderr, "Unknown sort type '%s'. Must be one of: max, total, pid\n", v4);
goto LABEL_8;
}
v5 = 2;
}
LABEL_27:
arg_sort = v5;
break;
default:
goto LABEL_31;
}
}
if ( optind < argc )
LABEL_31:
usage_and_exit(1);
return result;
}

canonical_decompiled_code:
int __fastcall func2(int argc, char **argv)
{
int result; // eax
char *v4; // r12
int v5; // eax
int *v6; // rax
char *v7; // rdi
int *v8; // r12
int *v9; // rax
char *v10; // rdi
int *v11; // r12
unsigned __int64 v12; // rax
int v13; // ecx
int *v14; // rax
char *v15; // rdi
int *v16; // r12
unsigned __int64 v17; // rax
int v18; // edx
int longind; // [rsp+4h] [rbp-24h] BYREF
char *endptr[4]; // [rsp+8h] [rbp-20h] BYREF

longind = 0;
while ( 1 )
{
result = getopt_long(argc, argv, "i:c:s:rm:M:p:h", &long_options_2, &longind);
if ( result == -1 )
break;
switch ( result )
{
case 'M':
v14 = _errno_location();
v15 = optarg;
*v14 = 0;
v16 = v14;
v17 = strtoull(v15, endptr, 10);
v18 = *v16;
arg_max_interruptible_delay = v17;
if ( v18 || endptr[0] == optarg || *endptr[0] )
goto LABEL_33;
arg_max_interruptible_delay = 1000 * v17;
continue;
case 'c':
arg_count = atoi(optarg);
if ( arg_interval < 0 )
{
fwrite("Count must be positive (or zero for infinite).\n", 1uLL, 0x2FuLL, stderr);
exit(1);
}
continue;
case 'h':
func1(0);
case 'i':
arg_interval = atoi(optarg);
if ( arg_interval <= 0 )
{
fwrite("Interval must be a positive number.\n", 1uLL, 0x24uLL, stderr);
exit(1);
}
continue;
case 'm':
v9 = _errno_location();
v10 = optarg;
*v9 = 0;
v11 = v9;
v12 = strtoull(v10, endptr, 10);
v13 = *v11;
arg_min_delay = v12;
if ( v13 || endptr[0] == optarg || *endptr[0] )
{
LABEL_33:
fprintf(stderr, "Invalid delay specification '%s'\n", optarg);
LABEL_8:
exit(1);
}
arg_min_delay = 1000 * v12;
break;
case 'p':
v6 = _errno_location();
v7 = optarg;
*v6 = 0;
v8 = v6;
arg_pid_filter = strtoul(v7, endptr, 10);
if ( !*v8 && endptr[0] != optarg && !*endptr[0] )
continue;
fprintf(stderr, "Invalid PID specification '%s'\n", optarg);
goto LABEL_8;
case 'r':
arg_reverse = 1;
continue;
case 's':
v4 = optarg;
v5 = strcasecmp(optarg, "max");
if ( !v5 )
goto LABEL_27;
if ( !strcasecmp(v4, "total") )
{
v5 = 1;
}
else
{
if ( strcasecmp(v4, "pid") )
{
fprintf(stderr, "Unknown sort type '%s'. Must be one of: max, total, pid\n", v4);
goto LABEL_8;
}
v5 = 2;
}
LABEL_27:
arg_sort = v5;
break;
default:
goto LABEL_31;
}
}
if ( optind < argc )
LABEL_31:
func1(1);
return result;
}

original_code:
static void parse_argv(int argc, char *argv[])
{
 char *endptr;
 int c, i, option_index = 0;
 static const struct option long_options[] = {
  { "interval", 1, 0, 'i' },
  { "count", 1, 0, 'c' },
  { "sort", 1, 0, 's' },
  { "reverse", 0, 0, 'r' },
  { "min-latency", 1, 0, 'm' },
  { "max-interruptible", 1, 0, 'M' },
  { "pid-filter", 1, 0, 'p' },
  { "help", 0, 0, 'h' },
  { 0, 0, 0, 0 }
 };
 static const char *sort_types[_NR_SORT_BY] = {
  [SORT_BY_MAX_LATENCY] = "max",
  [SORT_BY_TOTAL_LATENCY] = "total",
  [SORT_BY_PID] = "pid",
 };
 for (;;) {
  c = getopt_long(argc, argv, "i:c:s:rm:M:p:h", long_options, &option_index);
  if (c == -1)
   break;
  switch (c) {
  case 'i':
   arg_interval = atoi(optarg);
   if (arg_interval <= 0) {
    fprintf(stderr, "Interval must be a positive number.\n");
    exit(1);
   }
   break;
  case 'c':
   arg_count = atoi(optarg);
   if (arg_interval < 0) {
    fprintf(stderr, "Count must be positive (or zero for infinite).\n");
    exit(1);
   }
   break;
  case 'r':
   arg_reverse = 1;
   break;
  case 's':
   for (i = 0; i < _NR_SORT_BY; i++) {
    if (!strcasecmp(optarg, sort_types[i]))
     break;
   }
   if (i == _NR_SORT_BY) {
    fprintf(stderr, "Unknown sort type '%s'. Must be one of: max, total, pid\n", optarg);
    exit(1);
   }
   arg_sort = i;
   break;
  case 'm':
   (*__errno_location ()) = 0;
   arg_min_delay = strtoull(optarg, &endptr, 10);
   if ((*__errno_location ()) || endptr == optarg || *endptr != '\0') {
    fprintf(stderr, "Invalid delay specification '%s'\n", optarg);
    exit(1);
   }
   arg_min_delay *= 1000ULL;
   break;
  case 'M':
   (*__errno_location ()) = 0;
   arg_max_interruptible_delay = strtoull(optarg, &endptr, 10);
   if ((*__errno_location ()) || endptr == optarg || *endptr != '\0') {
    fprintf(stderr, "Invalid delay specification '%s'\n", optarg);
    exit(1);
   }
   arg_max_interruptible_delay *= 1000ULL;
   break;
  case 'p':
   (*__errno_location ()) = 0;
   arg_pid_filter = strtoul(optarg, &endptr, 10);
   if ((*__errno_location ()) || endptr == optarg || *endptr != '\0') {
    fprintf(stderr, "Invalid PID specification '%s'\n", optarg);
    exit(1);
   }
   break;
  case 'h':
   usage_and_exit(0);
  case '?':
  default:
   usage_and_exit(1);
  }
 }
 if (optind < argc)
  usage_and_exit(1);
}

canonical_original_code:
static void parse_argv(int argc, char *argv[])
{
 char *endptr;
 int c; int i; int option_index = 0;
 static struct option long_options[] = {
  { "interval", 1, 0, 'i' },
  { "count", 1, 0, 'c' },
  { "sort", 1, 0, 's' },
  { "reverse", 0, 0, 'r' },
  { "min-latency", 1, 0, 'm' },
  { "max-interruptible", 1, 0, 'M' },
  { "pid-filter", 1, 0, 'p' },
  { "help", 0, 0, 'h' },
  { 0, 0, 0, 0 }
 };
 static char *sort_types[-1] = {
  [SORT_BY_MAX_LATENCY] = "max",
  [SORT_BY_TOTAL_LATENCY] = "total",
  [SORT_BY_PID] = "pid",
 };
 for (;;) {
  c = getopt_long(argc, argv, "i:c:s:rm:M:p:h", long_options, &option_index);
  if (c == -1)
   break;
  switch (c) {
  case 'i':
   arg_interval = atoi(optarg);
   if (arg_interval <= 0) {
    fprintf(stderr, "Interval must be a positive number.\n");
    exit(1);
   }
   break;
  case 'c':
   arg_count = atoi(optarg);
   if (arg_interval < 0) {
    fprintf(stderr, "Count must be positive (or zero for infinite).\n");
    exit(1);
   }
   break;
  case 'r':
   arg_reverse = 1;
   break;
  case 's':
   for (i = 0; i < _NR_SORT_BY; i++) {
    if (!strcasecmp(optarg, sort_types[i]))
     break;
   }
   if (i == _NR_SORT_BY) {
    fprintf(stderr, "Unknown sort type '%s'. Must be one of: max, total, pid\n", optarg);
    exit(1);
   }
   arg_sort = i;
   break;
  case 'm':
   (*__errno_location ()) = 0;
   arg_min_delay = strtoull(optarg, &endptr, 10);
   if ((*__errno_location ()) || endptr == optarg || *endptr != '\0') {
    fprintf(stderr, "Invalid delay specification '%s'\n", optarg);
    exit(1);
   }
   arg_min_delay *= 1000ULL;
   break;
  case 'M':
   (*__errno_location ()) = 0;
   arg_max_interruptible_delay = strtoull(optarg, &endptr, 10);
   if ((*__errno_location ()) || endptr == optarg || *endptr != '\0') {
    fprintf(stderr, "Invalid delay specification '%s'\n", optarg);
    exit(1);
   }
   arg_max_interruptible_delay *= 1000ULL;
   break;
  case 'p':
   (*__errno_location ()) = 0;
   arg_pid_filter = strtoul(optarg, &endptr, 10);
   if ((*__errno_location ()) || endptr == optarg || *endptr != '\0') {
    fprintf(stderr, "Invalid PID specification '%s'\n", optarg);
    exit(1);
   }
   break;
  case 'h':
   usage_and_exit(0);
  case '?':
  default:
   usage_and_exit(1);
  }
 }
 if (optind < argc)
  usage_and_exit(1);
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
endptr
char *

variable_types: c int

variable_types: i int

variable_types: struct option { char *name; int has_arg; int *flag; int val; } []


decompiled_code:
__int64 main_loop()
{
unsigned int v0; // er12
__int64 v1; // rbx
int v2; // eax
__int64 result; // rax
unsigned int v4; // er12

v0 = should_quit;
if ( should_quit )
{
v0 = 0;
LABEL_8:
result = v0;
}
else
{
while ( 1 )
{
if ( poll(&poll_fds, (unsigned int)num_readers, -1) < 0 )
{
v0 = 1;
perror("poll");
goto LABEL_8;
}
v1 = 0LL;
if ( (_DWORD)num_readers )
break;
LABEL_7:
if ( should_quit )
goto LABEL_8;
}
while ( 1 )
{
if ( *(&poll_fds.revents + 4 * v1) )
{
v2 = (*(__int64 (__fastcall **)(__int64))(*(_QWORD *)readers[v1] + 24LL))(readers[v1]);
if ( v2 )
break;
}
if ( (unsigned int)num_readers <= (unsigned int)++v1 )
goto LABEL_7;
}
should_quit = 1;
v4 = 0;
if ( v2 <= 0 )
v4 = v2;
result = v4;
}
return result;
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int v0; // er12
__int64 v1; // rbx
int v2; // eax
__int64 result; // rax
unsigned int v4; // er12

v0 = should_quit;
if ( should_quit )
{
v0 = 0;
LABEL_8:
result = v0;
}
else
{
while ( 1 )
{
if ( poll(&poll_fds, (unsigned int)num_readers, -1) < 0 )
{
v0 = 1;
perror("poll");
goto LABEL_8;
}
v1 = 0LL;
if ( (_DWORD)num_readers )
break;
LABEL_7:
if ( should_quit )
goto LABEL_8;
}
while ( 1 )
{
if ( *(&poll_fds.revents + 4 * v1) )
{
v2 = (*(__int64 (__fastcall **)(__int64))(*(_QWORD *)readers[v1] + 24LL))(readers[v1]);
if ( v2 )
break;
}
if ( (unsigned int)num_readers <= (unsigned int)++v1 )
goto LABEL_7;
}
should_quit = 1;
v4 = 0;
if ( v2 <= 0 )
v4 = v2;
result = v4;
}
return result;
}

original_code:
static int main_loop(void)
{
 int nready, i;
 int r = 0;
 while (!should_quit) {
  nready = poll(poll_fds, num_readers, -1);
  if (nready < 0) {
   perror("poll");
   return 1;
  }
  for (i = 0; i < num_readers; i++) {
   if (!poll_fds[i].revents)
    continue;
   r = readers[i]->ops->handle_ready_fd(readers[i]);
   if (r) {
    should_quit = 1;
    if (r > 0)
     r = 0;
    break;
   }
  }
 }
 return r;
}

canonical_original_code:
static int main_loop()
{
 int nready; int i;
 int r = 0;
 while (!should_quit) {
  nready = poll(poll_fds, num_readers, -1);
  if (nready < 0) {
   perror("poll");
   return 1;
  }
  for (i = 0; i < num_readers; i++) {
   if (!poll_fds[i].revents)
    continue;
   r = readers[i]->ops->handle_ready_fd(readers[i]);
   if (r) {
    should_quit = 1;
    if (r > 0)
     r = 0;
    break;
   }
  }
 }
 return r;
}

variable_types: nready int


fini

decompiled_code:
__int64 fini()
{
__int64 i; // rbx
void (***v1)(void); // rdi
void (*v2)(void); // rax

for ( i = 0LL; (unsigned int)num_readers > (unsigned int)i; ++i )
{
v1 = (void (***)(void))readers[i];
v2 = **v1;
if ( v2 )
{
v2();
v1 = (void (***)(void))readers[i];
}
free(v1);
}
pa_fini();
sym_translator_fini();
return lat_translator_fini();
}

canonical_decompiled_code:
__int64 func4()
{
__int64 i; // rbx
void (***v1)(void); // rdi
void (*v2)(void); // rax

for ( i = 0LL; (unsigned int)num_readers > (unsigned int)i; ++i )
{
v1 = (void (***)(void))readers[i];
v2 = **v1;
if ( v2 )
{
v2();
v1 = (void (***)(void))readers[i];
}
free(v1);
}
pa_fini();
sym_translator_fini();
return lat_translator_fini();
}

original_code:
static void fini(void)
{
 int i;
 for (i = 0; i < num_readers; i++) {
  if (readers[i]->ops->fini)
   readers[i]->ops->fini(readers[i]);
  free(readers[i]);
 }
 pa_fini();
 sym_translator_fini();
 lat_translator_fini();
}

canonical_original_code:
static void fini()
{
 int i;
 for (i = 0; i < num_readers; i++) {
  if (readers[i]->ops->fini)
   readers[i]->ops->fini(readers[i]);
  free(readers[i]);
 }
 pa_fini();
 sym_translator_fini();
 lat_translator_fini();
}


init

decompiled_code:
__int64 init()
{
unsigned int v0; // er12
__int64 v1; // rbx
__int64 v2; // rbx
__int64 v3; // rax
bool v4; // cc
unsigned int v5; // ebp
int v6; // eax
int *v8; // rax
char *v9; // rax
unsigned int v10; // [rsp+Ch] [rbp-2Ch]
struct sched_param param; // [rsp+1Ch] [rbp-1Ch] BYREF

if ( (unsigned int)lat_translator_init() )
fwrite("Warning: Failed to load latencytop translations.\n", 1uLL, 0x31uLL, stderr);
v0 = sym_translator_init();
if ( v0 )
{
fwrite("Failed to init the symbol map.\n", 1uLL, 0x1FuLL, stderr);
v6 = v0;
LABEL_9:
v10 = v6;
fini();
return v10;
}
pa_init();
v1 = (unsigned int)num_readers;
LODWORD(num_readers) = num_readers + 1;
readers[v1] = stap_reader_new();
v2 = (unsigned int)num_readers;
LODWORD(num_readers) = num_readers + 1;
v3 = signal_reader_new();
v4 = (unsigned int)num_readers <= 3;
readers[v2] = v3;
if ( !v4 )
_assert_fail("num_readers <= MAX_READERS", "lattop.c", 0x8Du, "init");
fwrite("Initializing Systemtap probe...\n", 1uLL, 0x20uLL, stderr);
if ( (_DWORD)num_readers )
{
v5 = 0;
do
{
v6 = start_reader(v5);
if ( v6 < 0 )
goto LABEL_9;
}
while ( (unsigned int)num_readers > ++v5 );
}
param.__sched_priority = 10;
if ( sched_setscheduler(0, 1, &param) < 0 )
{
v8 = _errno_location();
v9 = strerror(*v8);
fprintf(stderr, "Warning: Failed to set real-time scheduling policy: %s\n", v9);
}
return v0;
}

canonical_decompiled_code:
__int64 func5()
{
unsigned int v0; // er12
__int64 v1; // rbx
__int64 v2; // rbx
__int64 v3; // rax
bool v4; // cc
unsigned int v5; // ebp
int v6; // eax
int *v8; // rax
char *v9; // rax
unsigned int v10; // [rsp+Ch] [rbp-2Ch]
struct sched_param param; // [rsp+1Ch] [rbp-1Ch] BYREF

if ( (unsigned int)lat_translator_init() )
fwrite("Warning: Failed to load latencytop translations.\n", 1uLL, 0x31uLL, stderr);
v0 = sym_translator_init();
if ( v0 )
{
fwrite("Failed to init the symbol map.\n", 1uLL, 0x1FuLL, stderr);
v6 = v0;
LABEL_9:
v10 = v6;
func4();
return v10;
}
pa_init();
v1 = (unsigned int)num_readers;
LODWORD(num_readers) = num_readers + 1;
readers[v1] = stap_reader_new();
v2 = (unsigned int)num_readers;
LODWORD(num_readers) = num_readers + 1;
v3 = signal_reader_new();
v4 = (unsigned int)num_readers <= 3;
readers[v2] = v3;
if ( !v4 )
_assert_fail("num_readers <= MAX_READERS", "lattop.c", 0x8Du, "init");
fwrite("Initializing Systemtap probe...\n", 1uLL, 0x20uLL, stderr);
if ( (_DWORD)num_readers )
{
v5 = 0;
do
{
v6 = func0(v5);
if ( v6 < 0 )
goto LABEL_9;
}
while ( (unsigned int)num_readers > ++v5 );
}
param.__sched_priority = 10;
if ( sched_setscheduler(0, 1, &param) < 0 )
{
v8 = _errno_location();
v9 = strerror(*v8);
fprintf(stderr, "Warning: Failed to set real-time scheduling policy: %s\n", v9);
}
return v0;
}

original_code:
static int init(void)
{
 int r, i;
 struct sched_param schedp;
 r = lat_translator_init();
 if (r)
  fprintf(stderr, "Warning: Failed to load latencytop translations.\n");
 r = sym_translator_init();
 if (r) {
  fprintf(stderr, "Failed to init the symbol map.\n");
  goto err;
 }
 pa_init();
 readers[num_readers++] = stap_reader_new();
 readers[num_readers++] = signal_reader_new();
 ((void) sizeof ((num_readers <= 3) ? 1 : 0), __extension__ ({ if (num_readers <= 3) ; else __assert_fail ("num_readers <= MAX_READERS", "lattop.c", 141, __extension__ __PRETTY_FUNCTION__); }));
 fprintf(stderr, "Initializing Systemtap probe...\n");
 for (i = 0; i < num_readers; i++) {
  r = start_reader(i);
  if (r < 0)
   goto err;
 }
 memset(&schedp, 0, sizeof(schedp));
 schedp.sched_priority = 10;
 r = sched_setscheduler(0, 1, &schedp);
 if (r < 0)
  fprintf(stderr, "Warning: Failed to set real-time scheduling policy: %s\n",
                  strerror((*__errno_location ())));
 return 0;
err:
 fini();
 return r;
}

canonical_original_code:
static int init()
{
 int r; int i;
 struct sched_param schedp;
 r = lat_translator_init();
 if (r)
  fprintf(stderr, "Warning: Failed to load latencytop translations.\n");
 r = sym_translator_init();
 if (r) {
  fprintf(stderr, "Failed to init the symbol map.\n");
  goto err;
 }
 pa_init();
 readers[num_readers++] = stap_reader_new();
 readers[num_readers++] = signal_reader_new();
 ((void) sizeof ((num_readers <= 3) ? 1 : 0), __extension__ ({ if (num_readers <= 3) ; else __assert_fail ("num_readers <= MAX_READERS", "lattop.c", 141, __extension__ __PRETTY_FUNCTION__); }));
 fprintf(stderr, "Initializing Systemtap probe...\n");
 for (i = 0; i < num_readers; i++) {
  r = start_reader(i);
  if (r < 0)
   goto err;
 }
 memset(&schedp, 0, sizeof(schedp));
 schedp.sched_priority = 10;
 r = sched_setscheduler(0, 1, &schedp);
 if (r < 0)
  fprintf(stderr, "Warning: Failed to set real-time scheduling policy: %s\n",
                  strerror((*__errno_location ())));
 return 0;
err:
 fini();
 return r;
}

variable_types: struct sched_param { int sched_priority; }


decompiled_code:
size_t __fastcall lattop_reader_started(__int64 a1)
{
__int64 v1; // rbx
__int64 v2; // rax
unsigned int v3; // edi

if ( readers[0] != a1 )
_assert_fail("readers[0] == r", "lattop.c", 0x46u, "lattop_reader_started");
v1 = (unsigned int)num_readers;
if ( (unsigned int)num_readers > 2 )
_assert_fail("num_readers < MAX_READERS", "lattop.c", 0x47u, "lattop_reader_started");
v2 = timer_reader_new();
v3 = num_readers;
readers[v1] = v2;
start_reader(v3);
LODWORD(num_readers) = num_readers + 1;
return fwrite("Systemtap probe activated. Reading data...\n", 1uLL, 0x2BuLL, stderr);
}

canonical_decompiled_code:
size_t __fastcall func6(__int64 a1)
{
__int64 v1; // rbx
__int64 v2; // rax
unsigned int v3; // edi

if ( readers[0] != a1 )
_assert_fail("readers[0] == r", "lattop.c", 0x46u, "lattop_reader_started");
v1 = (unsigned int)num_readers;
if ( (unsigned int)num_readers > 2 )
_assert_fail("num_readers < MAX_READERS", "lattop.c", 0x47u, "lattop_reader_started");
v2 = timer_reader_new();
v3 = num_readers;
readers[v1] = v2;
func0(v3);
LODWORD(num_readers) = num_readers + 1;
return fwrite("Systemtap probe activated. Reading data...\n", 1uLL, 0x2BuLL, stderr);
}

original_code:
void lattop_reader_started(struct polled_reader *r)
{
 ((void) sizeof ((readers[0] == r) ? 1 : 0), __extension__ ({ if (readers[0] == r) ; else __assert_fail ("readers[0] == r", "lattop.c", 70, __extension__ __PRETTY_FUNCTION__); }));
 ((void) sizeof ((num_readers < 3) ? 1 : 0), __extension__ ({ if (num_readers < 3) ; else __assert_fail ("num_readers < MAX_READERS", "lattop.c", 71, __extension__ __PRETTY_FUNCTION__); }));
 readers[num_readers] = timer_reader_new();
 start_reader(num_readers);
 num_readers++;
 fprintf(stderr, "Systemtap probe activated. Reading data...\n");
}

variable_types: struct polled_reader { struct polled_reader_ops { void (*fini)(struct polled_reader *pr); int (*start)(struct polled_reader *pr); int (*get_fd)(struct polled_reader *pr); int (*handle_ready_fd)(struct polled_reader *pr); } *ops; } *

user_defined_types: struct polled_reader { struct polled_reader_ops *ops; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er12

v3 = 1;
parse_argv(argc, (char **)argv);
if ( !(unsigned int)init() )
{
v3 = main_loop();
fini();
}
return v3;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er12

v3 = 1;
func2(argc, (char **)argv);
if ( !(unsigned int)func5() )
{
v3 = func3();
func4();
}
return v3;
}

original_code:
int main(int argc, char *argv[])
{
 int ret;
 parse_argv(argc, argv);
 if (init())
  return 1;
 ret = main_loop();
 fini();
 return ret;
}

variable_types: ret int


decompiled_code:
__int64 __fastcall signal_reader_get_fd(__int64 a1)
{
return *(unsigned int *)(a1 + 8);
}

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

original_code:
static int signal_reader_get_fd(struct polled_reader *pr)
{
 struct signal_reader *sr = (struct signal_reader*) pr;
 return sr->signalfd;
}

variable_types: struct signal_reader { struct polled_reader { struct polled_reader_ops { void (*fini)(struct polled_reader *pr); int (*start)(struct polled_reader *pr); int (*get_fd)(struct polled_reader *pr); int (*handle_ready_fd)(struct polled_reader *pr); } *ops; } pr; int signalfd; struct __sigset_t { unsigned long __val[-1]; } orig_sigmask; } *

user_defined_types: struct signal_reader { struct polled_reader pr; int signalfd; struct __sigset_t orig_sigmask; }


decompiled_code:
__int64 __fastcall signal_reader_handle_ready_fd(__int64 a1)
{
__int64 result; // rax
unsigned int v2[34]; // [rsp+0h] [rbp-88h] BYREF

if ( read(*(_DWORD *)(a1 + 8), v2, 0x80uLL) == 128 )
{
if ( v2[0] > 3 )
{
if ( v2[0] != 15 )
goto LABEL_4;
}
else if ( v2[0] <= 1 )
{
LABEL_4:
fprintf(stderr, "Unexpected signal %d received via signalfd.\n", v2[0]);
return 0xFFFFFFFFLL;
}
fwrite("Exiting.\n", 1uLL, 9uLL, stderr);
result = 1LL;
}
else
{
fwrite("Invalid read from signalfd\n", 1uLL, 0x1BuLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 result; // rax
unsigned int v2[34]; // [rsp+0h] [rbp-88h] BYREF

if ( read(*(_DWORD *)(a1 + 8), v2, 0x80uLL) == 128 )
{
if ( v2[0] > 3 )
{
if ( v2[0] != 15 )
goto LABEL_4;
}
else if ( v2[0] <= 1 )
{
LABEL_4:
fprintf(stderr, "Unexpected signal %d received via signalfd.\n", v2[0]);
return 0xFFFFFFFFLL;
}
fwrite("Exiting.\n", 1uLL, 9uLL, stderr);
result = 1LL;
}
else
{
fwrite("Invalid read from signalfd\n", 1uLL, 0x1BuLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
static int signal_reader_handle_ready_fd(struct polled_reader *pr)
{
 struct signal_reader *sr = (struct signal_reader*) pr;
 struct signalfd_siginfo si;
 ssize_t r;
 r = read(sr->signalfd, &si, sizeof(si));
 if (r != sizeof(si)) {
  fprintf(stderr, "Invalid read from signalfd\n");
  return -1;
 }
 switch (si.ssi_signo) {
 case 2:
 case 15:
 case 3:
  fprintf(stderr, "Exiting.\n");
  return 1;
 default:
  fprintf(stderr, "Unexpected signal %d received via signalfd.\n", si.ssi_signo);
  return -1;
 }
 return 0;
}

canonical_original_code:
static int signal_reader_handle_ready_fd(struct polled_reader *pr)
{
 struct signal_reader *sr = (struct signal_reader*) pr;
 struct signalfd_siginfo si;
 long r;
 r = read(sr->signalfd, &si, sizeof(si));
 if (r != sizeof(si)) {
  fprintf(stderr, "Invalid read from signalfd\n");
  return -1;
 }
 switch (si.ssi_signo) {
 case 2:
 case 15:
 case 3:
  fprintf(stderr, "Exiting.\n");
  return 1;
 default:
  fprintf(stderr, "Unexpected signal %d received via signalfd.\n", si.ssi_signo);
  return -1;
 }
 return 0;
}

variable_types: struct signalfd_siginfo { unsigned int ssi_signo; int ssi_errno; int ssi_code; unsigned int ssi_pid; unsigned int ssi_uid; int ssi_fd; unsigned int ssi_tid; unsigned int ssi_band; unsigned int ssi_overrun; unsigned int ssi_trapno; int ssi_status; int ssi_int; unsigned long ssi_ptr; unsigned long ssi_utime; unsigned long ssi_stime; unsigned long ssi_addr; unsigned char __pad[48]; }

variable_types: r long

user_defined_types: struct __sigset_t { unsigned long __val[-1]; }

user_defined_types: struct polled_reader_ops { void (*fini)(struct polled_reader *pr); int (*start)(struct polled_reader *pr); int (*get_fd)(struct polled_reader *pr); int (*handle_ready_fd)(struct polled_reader *pr); }


decompiled_code:
__int64 __fastcall signal_reader_start(__int64 a1)
{
int v1; // eax
__int64 result; // rax
int v3; // er12
int v4; // er12
sigset_t v5; // [rsp+0h] [rbp-98h] BYREF

sigemptyset(&v5);
sigaddset(&v5, 2);
sigaddset(&v5, 15);
sigaddset(&v5, 3);
if ( sigprocmask(0, &v5, (sigset_t *)(a1 + 16)) < 0 )
{
v3 = *_errno_location();
perror("sigprocmask");
result = (unsigned int)-v3;
}
else
{
v1 = signalfd(-1, &v5, 0x80000);
*(_DWORD *)(a1 + 8) = v1;
if ( v1 < 0 )
{
v4 = *_errno_location();
perror("signalfd");
result = (unsigned int)-v4;
}
else
{
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
int v1; // eax
__int64 result; // rax
int v3; // er12
int v4; // er12
sigset_t v5; // [rsp+0h] [rbp-98h] BYREF

sigemptyset(&v5);
sigaddset(&v5, 2);
sigaddset(&v5, 15);
sigaddset(&v5, 3);
if ( sigprocmask(0, &v5, (sigset_t *)(a1 + 16)) < 0 )
{
v3 = *_errno_location();
perror("sigprocmask");
result = (unsigned int)-v3;
}
else
{
v1 = signalfd(-1, &v5, 0x80000);
*(_DWORD *)(a1 + 8) = v1;
if ( v1 < 0 )
{
v4 = *_errno_location();
perror("signalfd");
result = (unsigned int)-v4;
}
else
{
result = 0LL;
}
}
return result;
}

original_code:
static int signal_reader_start(struct polled_reader *pr)
{
 struct signal_reader *sr = (struct signal_reader*) pr;
 sigset_t accept_sigs;
 int r;
 sigemptyset(&accept_sigs);
 sigaddset(&accept_sigs, 2);
 sigaddset(&accept_sigs, 15);
 sigaddset(&accept_sigs, 3);
 r = sigprocmask(0, &accept_sigs, &sr->orig_sigmask);
 if (r < 0) {
  r = -(*__errno_location ());
  perror("sigprocmask");
  return r;
 }
 sr->signalfd = signalfd(-1, &accept_sigs, SFD_CLOEXEC);
 if (sr->signalfd < 0) {
  r = -(*__errno_location ());
  perror("signalfd");
  return r;
 }
 return 0;
}

canonical_original_code:
static int signal_reader_start(struct polled_reader *pr)
{
 struct signal_reader *sr = (struct signal_reader*) pr;
 struct __sigset_t accept_sigs;
 int r;
 sigemptyset(&accept_sigs);
 sigaddset(&accept_sigs, 2);
 sigaddset(&accept_sigs, 15);
 sigaddset(&accept_sigs, 3);
 r = sigprocmask(0, &accept_sigs, &sr->orig_sigmask);
 if (r < 0) {
  r = -(*__errno_location ());
  perror("sigprocmask");
  return r;
 }
 sr->signalfd = signalfd(-1, &accept_sigs, SFD_CLOEXEC);
 if (sr->signalfd < 0) {
  r = -(*__errno_location ());
  perror("signalfd");
  return r;
 }
 return 0;
}

variable_types: struct __sigset_t { unsigned long __val[-1]; }


decompiled_code:
int __fastcall signal_reader_fini(__int64 a1)
{
close(*(_DWORD *)(a1 + 8));
return sigprocmask(2, (const sigset_t *)(a1 + 16), 0LL);
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
close(*(_DWORD *)(a1 + 8));
return sigprocmask(2, (const sigset_t *)(a1 + 16), 0LL);
}

original_code:
static void signal_reader_fini(struct polled_reader *pr)
{
 struct signal_reader *sr = (struct signal_reader*) pr;
 close(sr->signalfd);
 sigprocmask(2, &sr->orig_sigmask, ((void *)0));
}


decompiled_code:
_QWORD *signal_reader_new()
{
_QWORD *result; // rax

result = calloc(1uLL, 0x90uLL);
if ( result )
*result = signal_reader_ops;
return result;
}

canonical_decompiled_code:
_QWORD *func4()
{
_QWORD *result; // rax

result = calloc(1uLL, 0x90uLL);
if ( result )
*result = signal_reader_ops;
return result;
}

original_code:
struct polled_reader *signal_reader_new()
{
 struct signal_reader *r;
 r = calloc(1, sizeof(struct signal_reader));
 if (r == ((void *)0))
  return ((void *)0);
 r->pr.ops = &signal_reader_ops;
 return &r->pr;
}

return_type: struct polled_reader { struct polled_reader_ops { void (*fini)(struct polled_reader *pr); int (*start)(struct polled_reader *pr); int (*get_fd)(struct polled_reader *pr); int (*handle_ready_fd)(struct polled_reader *pr); } *ops; } *


decompiled_code:
__int64 __fastcall compare_by_pid(__int64 *a1, __int64 *a2)
{
__int64 v2; // rdx
__int64 v3; // rcx
__int64 result; // rax
int v5; // esi
int v6; // eax
bool v7; // cc

v2 = *a2;
v3 = *a1;
result = 0xFFFFFFFFLL;
v5 = *(_DWORD *)(*a2 + 32);
if ( *(_DWORD *)(*a1 + 32) >= v5 )
{
result = 1LL;
if ( *(_DWORD *)(*a1 + 32) <= v5 )
{
v6 = *(_DWORD *)(v2 + 36);
v7 = *(_DWORD *)(v3 + 36) < v6;
result = *(_DWORD *)(v3 + 36) > v6;
if ( v7 )
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 *a1, __int64 *a2)
{
__int64 v2; // rdx
__int64 v3; // rcx
__int64 result; // rax
int v5; // esi
int v6; // eax
bool v7; // cc

v2 = *a2;
v3 = *a1;
result = 0xFFFFFFFFLL;
v5 = *(_DWORD *)(*a2 + 32);
if ( *(_DWORD *)(*a1 + 32) >= v5 )
{
result = 1LL;
if ( *(_DWORD *)(*a1 + 32) <= v5 )
{
v6 = *(_DWORD *)(v2 + 36);
v7 = *(_DWORD *)(v3 + 36) < v6;
result = *(_DWORD *)(v3 + 36) > v6;
if ( v7 )
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
static int compare_by_pid(const void *p1, const void *p2)
{
 struct process *pr1 = *(struct process**)p1;
 struct process *pr2 = *(struct process**)p2;
 if (pr1->pid < pr2->pid)
  return -1;
 else if (pr1->pid > pr2->pid)
  return 1;
 else if (pr1->tid < pr2->tid)
  return -1;
 else if (pr1->tid > pr2->tid)
  return 1;
 else
  return 0;
}

canonical_original_code:
static int compare_by_pid(void *p1, void *p2)
{
 struct process *pr1 = *(struct process**)p1;
 struct process *pr2 = *(struct process**)p2;
 if (pr1->pid < pr2->pid)
  return -1;
 else if (pr1->pid > pr2->pid)
  return 1;
 else if (pr1->tid < pr2->tid)
  return -1;
 else if (pr1->tid > pr2->tid)
  return 1;
 else
  return 0;
}

variable_types: struct process { struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } rb_node; struct rb_root { struct rb_node *rb_node; } bt2la_map; int pid; int tid; char comm[16]; struct latency_account { unsigned long total; unsigned long max; int count; } summarized; unsigned int bt2la_count; } *

user_defined_types: struct process { struct rb_node rb_node; struct rb_root bt2la_map; int pid; int tid; char comm[16]; struct latency_account summarized; unsigned int bt2la_count; }


decompiled_code:
char *__fastcall search_process(int a1, _QWORD *a2, void ***a3)
{
char *result; // rax
void **v4; // rcx

result = (char *)processes;
if ( processes )
{
while ( 1 )
{
v4 = (void **)(result + 16);
if ( *((_DWORD *)result + 9) <= a1 )
{
if ( *((_DWORD *)result + 9) >= a1 )
return result;
v4 = (void **)(result + 8);
}
if ( !*v4 )
break;
result = (char *)*v4;
}
}
else
{
v4 = &processes;
}
*a2 = result;
result = 0LL;
*a3 = v4;
return result;
}

canonical_decompiled_code:
char *__fastcall func4(int a1, _QWORD *a2, void ***a3)
{
char *result; // rax
void **v4; // rcx

result = (char *)processes;
if ( processes )
{
while ( 1 )
{
v4 = (void **)(result + 16);
if ( *((_DWORD *)result + 9) <= a1 )
{
if ( *((_DWORD *)result + 9) >= a1 )
return result;
v4 = (void **)(result + 8);
}
if ( !*v4 )
break;
result = (char *)*v4;
}
}
else
{
v4 = &processes;
}
*a2 = result;
result = 0LL;
*a3 = v4;
return result;
}

original_code:
static struct process *search_process(pid_t tid, struct rb_node **pparent,
          struct rb_node ***plink)
{
 struct rb_node **p = &processes.rb_node;
 struct rb_node *parent = ((void *)0);
 struct process *process;
 while (*p) {
  parent = *p;
  process = (struct process *)((char *)(parent) - (char *) &((struct process *)0)->rb_node);
  if (tid < process->tid)
   p = &(*p)->rb_left;
  else if (tid > process->tid)
   p = &(*p)->rb_right;
  else
   return process;
 }
 *pparent = parent;
 *plink = p;
 return ((void *)0);
}

canonical_original_code:
static struct process *search_process(int tid, struct rb_node **pparent, struct rb_node ***plink)
{
 struct rb_node **p = &processes.rb_node;
 struct rb_node *parent = ((void *)0);
 struct process *process;
 while (*p) {
  parent = *p;
  process = (struct process *)((char *)(parent) - (char *) &((struct process *)0)->rb_node);
  if (tid < process->tid)
   p = &(*p)->rb_left;
  else if (tid > process->tid)
   p = &(*p)->rb_right;
  else
   return process;
 }
 *pparent = parent;
 *plink = p;
 return ((void *)0);
}

variable_types: tid int

variable_types:
pparent
struct rb_node **

variable_types:
plink
struct rb_node ***

variable_types: struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } **

return_type: struct process { struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } rb_node; struct rb_root { struct rb_node *rb_node; } bt2la_map; int pid; int tid; char comm[16]; struct latency_account { unsigned long total; unsigned long max; int count; } summarized; unsigned int bt2la_count; } *


decompiled_code:
void __fastcall pa_delete_rbtree(void *ptr)
{
if ( ptr )
{
pa_delete_rbtree(*((void **)ptr + 2));
pa_delete_rbtree(*((void **)ptr + 1));
process_fini(ptr);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func5(void *ptr)
{
if ( ptr )
{
func5(*((void **)ptr + 2));
func5(*((void **)ptr + 1));
process_fini(ptr);
free(ptr);
}
}

original_code:
static void pa_delete_rbtree(struct rb_node *n)
{
 struct process *p;
 if (!n)
  return;
 pa_delete_rbtree(n->rb_left);
 pa_delete_rbtree(n->rb_right);
 p = (struct process *)((char *)(n) - (char *) &((struct process *)0)->rb_node);
 process_fini(p);
 free(p);
}

variable_types: struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } *

user_defined_types: struct rb_root { struct rb_node *rb_node; }

user_defined_types: struct latency_account { unsigned long total; unsigned long max; int count; }


decompiled_code:
void pa_clear()
{
pa_delete_rbtree(processes);
processes = 0LL;
count = 0;
}

canonical_decompiled_code:
void func6()
{
func5(processes);
processes = 0LL;
count = 0;
}

original_code:
void pa_clear(void)
{
 pa_delete_rbtree(processes.rb_node);
 processes = (struct rb_root) { ((void *)0), };
 count = 0;
}

canonical_original_code:
void pa_clear()
{
 pa_delete_rbtree(processes.rb_node);
 processes = (struct rb_root) { ((void *)0), };
 count = 0;
}

user_defined_types: struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; }


decompiled_code:
void pa_dump_and_clear()
{
void *v0; // rsp
__int64 v1; // rax
__int64 v2; // r12
unsigned int v3; // er13
__int64 v4; // rax
unsigned int v5; // er12
__int64 v6; // rax
char *v7; // rax
__int64 *v8; // r12
__int64 *v9; // rax
__int64 v10; // [rsp+0h] [rbp-30h] BYREF
time_t timer; // [rsp+8h] [rbp-28h] BYREF

time(&timer);
v0 = alloca(16 * ((8 * (unsigned __int64)(unsigned int)count + 23) >> 4));
v1 = rb_first(&processes);
if ( v1 )
{
v2 = v1;
v3 = 0;
do
{
process_summarize(v2);
v4 = v3++;
*(&v10 + v4) = v2;
v2 = rb_next(v2);
}
while ( v2 );
}
else
{
v3 = 0;
}
if ( count != v3 )
_assert_fail("n == count", "process_accountant.c", 0x6Au, "pa_dump_and_clear");
qsort(&v10, v3, 8uLL, (__compar_fn_t)sort_func_0[arg_sort]);
putchar(10);
if ( arg_reverse )
{
if ( count )
{
v8 = &v10 + (unsigned int)(count - 1);
do
{
process_dump(*v8);
v9 = v8--;
}
while ( &v10 != v9 );
}
}
else if ( count )
{
v5 = 0;
do
{
v6 = v5++;
process_dump(*(&v10 + v6));
}
while ( count > v5 );
}
v7 = ctime(&timer);
printf("=== %s", v7);
pa_clear();
}

canonical_decompiled_code:
void func7()
{
void *v0; // rsp
__int64 v1; // rax
__int64 v2; // r12
unsigned int v3; // er13
__int64 v4; // rax
unsigned int v5; // er12
__int64 v6; // rax
char *v7; // rax
__int64 *v8; // r12
__int64 *v9; // rax
__int64 v10; // [rsp+0h] [rbp-30h] BYREF
time_t timer; // [rsp+8h] [rbp-28h] BYREF

time(&timer);
v0 = alloca(16 * ((8 * (unsigned __int64)(unsigned int)count + 23) >> 4));
v1 = rb_first(&processes);
if ( v1 )
{
v2 = v1;
v3 = 0;
do
{
process_summarize(v2);
v4 = v3++;
*(&v10 + v4) = v2;
v2 = rb_next(v2);
}
while ( v2 );
}
else
{
v3 = 0;
}
if ( count != v3 )
_assert_fail("n == count", "process_accountant.c", 0x6Au, "pa_dump_and_clear");
qsort(&v10, v3, 8uLL, (__compar_fn_t)sort_func_0[arg_sort]);
putchar(10);
if ( arg_reverse )
{
if ( count )
{
v8 = &v10 + (unsigned int)(count - 1);
do
{
process_dump(*v8);
v9 = v8--;
}
while ( &v10 != v9 );
}
}
else if ( count )
{
v5 = 0;
do
{
v6 = v5++;
process_dump(*(&v10 + v6));
}
while ( count > v5 );
}
v7 = ctime(&timer);
printf("=== %s", v7);
func6();
}

original_code:
void pa_dump_and_clear(void)
{
 struct rb_node *node;
 struct process *process, **array;
 time_t cur_time;
 unsigned n = 0;
 static int (*const sort_func[_NR_SORT_BY])(const void *, const void *) = {
  [SORT_BY_MAX_LATENCY] = compare_by_max_latency,
  [SORT_BY_TOTAL_LATENCY] = compare_by_total_latency,
  [SORT_BY_PID] = compare_by_pid,
 };
 time(&cur_time);
 array = __builtin_alloca (sizeof(struct process*) * count);
 for (node = rb_first(&processes); node; node = rb_next(node)) {
  process = (struct process *)((char *)(node) - (char *) &((struct process *)0)->rb_node);
  process_summarize(process);
  array[n++] = process;
 }
 ((void) sizeof ((n == count) ? 1 : 0), __extension__ ({ if (n == count) ; else __assert_fail ("n == count", "process_accountant.c", 106, __extension__ __PRETTY_FUNCTION__); }));
 qsort(array, count, sizeof(struct process*), sort_func[arg_sort]);
 putchar('\n');
 if (!arg_reverse)
  for (n = 0; n < count; n++)
   process_dump(array[n]);
 else
  for (n = count; n > 0; n--)
   process_dump(array[n-1]);
 printf("=== %s", ctime(&cur_time));
 pa_clear();
}

canonical_original_code:
void pa_dump_and_clear()
{
 struct rb_node *node;
 struct process *process; struct process **array;
 long cur_time;
 unsigned int n = 0;
 static int (*sort_func[-1])(void *, void *) = {
  [SORT_BY_MAX_LATENCY] = compare_by_max_latency,
  [SORT_BY_TOTAL_LATENCY] = compare_by_total_latency,
  [SORT_BY_PID] = compare_by_pid,
 };
 time(&cur_time);
 array = __builtin_alloca (sizeof(struct process *) * count);
 for (node = rb_first(&processes); node; node = rb_next(node)) {
  process = (struct process *)((char *)(node) - (char *) &((struct process *)0)->rb_node);
  process_summarize(process);
  array[n++] = process;
 }
 ((void) sizeof ((n == count) ? 1 : 0), __extension__ ({ if (n == count) ; else __assert_fail ("n == count", "process_accountant.c", 106, __extension__ __PRETTY_FUNCTION__); }));
 qsort(array, count, sizeof(struct process *), sort_func[arg_sort]);
 putchar('\n');
 if (!arg_reverse)
  for (n = 0; n < count; n++)
   process_dump(array[n]);
 else
  for (n = count; n > 0; n--)
   process_dump(array[n-1]);
 printf("=== %s", ctime(&cur_time));
 pa_clear();
}

variable_types: struct process { struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } rb_node; struct rb_root { struct rb_node *rb_node; } bt2la_map; int pid; int tid; char comm[16]; struct latency_account { unsigned long total; unsigned long max; int count; } summarized; unsigned int bt2la_count; } **

variable_types:
n
unsigned int


decompiled_code:
__int64 __fastcall pa_account_latency(__int64 a1, int a2, __int64 a3, __int64 a4, __int64 a5)
{
char *v7; // rbp
unsigned int v8; // er9
unsigned int v9; // er10
__int64 v10; // r11
__int64 v12; // [rsp+0h] [rbp-28h] BYREF
void **v13; // [rsp+8h] [rbp-20h] BYREF

v7 = search_process(a2, &v12, &v13);
if ( !v7 )
{
v7 = (char *)process_new(v9, v8, v10);
rb_link_node(v7, v12, v13);
rb_insert_color(v7, &processes);
++count;
}
return process_suffer_latency(v7, a4, a5);
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, int a2, __int64 a3, __int64 a4, __int64 a5)
{
char *v7; // rbp
unsigned int v8; // er9
unsigned int v9; // er10
__int64 v10; // r11
__int64 v12; // [rsp+0h] [rbp-28h] BYREF
void **v13; // [rsp+8h] [rbp-20h] BYREF

v7 = func4(a2, &v12, &v13);
if ( !v7 )
{
v7 = (char *)process_new(v9, v8, v10);
func0(v7, v12, v13);
rb_insert_color(v7, &processes);
++count;
}
return process_suffer_latency(v7, a4, a5);
}

original_code:
void pa_account_latency(pid_t pid, pid_t tid, const char comm[16], uint64_t delay,
                        struct back_trace *bt)
{
 struct process *process;
 struct rb_node *parent;
 struct rb_node **link;
 process = search_process(tid, &parent, &link);
 if (!process) {
  process = process_new(pid, tid, comm);
  rb_link_node(&process->rb_node, parent, link);
  rb_insert_color(&process->rb_node, &processes);
  count++;
 }
 process_suffer_latency(process, delay, bt);
}

canonical_original_code:
void pa_account_latency(int pid, int tid, char comm[16], unsigned long delay, struct back_trace *bt)
{
 struct process *process;
 struct rb_node *parent;
 struct rb_node **link;
 process = search_process(tid, &parent, &link);
 if (!process) {
  process = process_new(pid, tid, comm);
  rb_link_node(&process->rb_node, parent, link);
  rb_insert_color(&process->rb_node, &processes);
  count++;
 }
 process_suffer_latency(process, delay, bt);
}

variable_types: pid int

variable_types:
comm
char [16]

variable_types:
delay
unsigned long

variable_types: struct back_trace { unsigned long trace[12]; } *


decompiled_code:
void pa_init()
{
processes = 0LL;
}

canonical_decompiled_code:
void func9()
{
processes = 0LL;
}

original_code:
void pa_init(void)
{
 processes = (struct rb_root) { ((void *)0), };
}

canonical_original_code:
void pa_init()
{
 processes = (struct rb_root) { ((void *)0), };
}


decompiled_code:
// attributes: thunk
void pa_fini()
{
pa_clear();
}

canonical_decompiled_code:
void func10()
{
func6();
}

original_code:
void pa_fini(void)
{
 pa_clear();
}

canonical_original_code:
void pa_fini()
{
 pa_clear();
}


original_code:
static void la_clear(struct latency_account *la)
{
 la->total = la->max = la->count = 0;
}

variable_types: struct latency_account { unsigned long total; unsigned long max; int count; } *


original_code:
static void la_init(struct latency_account *la, uint64_t delay)
{
 la->total = delay;
 la->max = delay;
 la->count = 1;
}

canonical_original_code:
static void la_init(struct latency_account *la, unsigned long delay)
{
 la->total = delay;
 la->max = delay;
 la->count = 1;
}


original_code:
static void la_add_delay(struct latency_account *la, uint64_t delay)
{
 la->total += delay;
 if (la->max < delay)
  la->max = delay;
 la->count++;
}

canonical_original_code:
static void la_add_delay(struct latency_account *la, unsigned long delay)
{
 la->total += delay;
 if (la->max < delay)
  la->max = delay;
 la->count++;
}


decompiled_code:
__int64 __fastcall la_sum_delay(__int64 a1, __int64 a2)
{
unsigned __int64 v2; // rax
__int64 result; // rax

*(_QWORD *)a1 += *(_QWORD *)a2;
v2 = *(_QWORD *)(a2 + 8);
if ( *(_QWORD *)(a1 + 8) < v2 )
*(_QWORD *)(a1 + 8) = v2;
result = *(unsigned int *)(a2 + 16);
*(_DWORD *)(a1 + 16) += result;
return result;
}

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

*(_QWORD *)a1 += *(_QWORD *)a2;
v2 = *(_QWORD *)(a2 + 8);
if ( *(_QWORD *)(a1 + 8) < v2 )
*(_QWORD *)(a1 + 8) = v2;
result = *(unsigned int *)(a2 + 16);
*(_DWORD *)(a1 + 16) += result;
return result;
}

original_code:
static void la_sum_delay(struct latency_account *la,
                                const struct latency_account *other)
{
 la->total += other->total;
 if (la->max < other->max)
  la->max = other->max;
 la->count += other->count;
}

canonical_original_code:
static void la_sum_delay(struct latency_account *la, struct latency_account *other)
{
 la->total += other->total;
 if (la->max < other->max)
  la->max = other->max;
 la->count += other->count;
}

variable_types:
other
struct latency_account *


original_code:
static struct bt2la *rb_search_bt2la(struct process *process,
                                     struct back_trace *bt,
                                     struct rb_node **pparent,
                                     struct rb_node ***plink)
{
 struct rb_node **p = &process->bt2la_map.rb_node;
 struct rb_node *parent = ((void *)0);
 struct bt2la *bt2la;
 int cmp;
 while (*p) {
  parent = *p;
  bt2la = (struct bt2la *)((char *)(parent) - (char *) &((struct bt2la *)0)->rb_node);
  cmp = bt_compare(bt, &bt2la->bt);
  if (cmp < 0)
   p = &(*p)->rb_left;
  else if (cmp > 0)
   p = &(*p)->rb_right;
  else
   return bt2la;
 }
 *pparent = parent;
 *plink = p;
 return ((void *)0);
}

variable_types: struct process { struct rb_node rb_node; struct rb_root { struct rb_node *rb_node; } bt2la_map; int pid; int tid; char comm[16]; struct latency_account summarized; unsigned int bt2la_count; } *

variable_types:
bt
struct back_trace *

variable_types: struct bt2la { struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } rb_node; struct back_trace { unsigned long trace[12]; } bt; struct latency_account { unsigned long total; unsigned long max; int count; } la; } *

variable_types: cmp int

user_defined_types: struct bt2la { struct rb_node rb_node; struct back_trace bt; struct latency_account la; }


decompiled_code:
void __fastcall process_delete_rbtree(void *ptr)
{
if ( ptr )
{
process_delete_rbtree(*((void **)ptr + 2));
process_delete_rbtree(*((void **)ptr + 1));
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func8(void *ptr)
{
if ( ptr )
{
func8(*((void **)ptr + 2));
func8(*((void **)ptr + 1));
free(ptr);
}
}

original_code:
static void process_delete_rbtree(struct rb_node *n)
{
 struct bt2la *item;
 if (!n)
  return;
 process_delete_rbtree(n->rb_left);
 process_delete_rbtree(n->rb_right);
 item = (struct bt2la *)((char *)(n) - (char *) &((struct bt2la *)0)->rb_node);
 free(item);
}

user_defined_types: struct back_trace { unsigned long trace[12]; }


decompiled_code:
__int64 __fastcall process_dump(__int64 a1)
{
__int64 v2; // r8
__int64 v3; // r9
const char *v4; // rcx
unsigned int v5; // er13
void *v6; // rsp
__int64 i; // rdi
__int64 v8; // rax
__int64 result; // rax
unsigned int v10; // er13
__int64 v11; // r14
__int64 v12; // rax
double v13; // xmm0_8
__int64 v14; // rax
double v15; // xmm0_8
double v16; // xmm1_8
const char *v17; // r15
size_t v18; // rax
unsigned __int64 v19; // rdx
__int64 v20; // [rsp+0h] [rbp-4B0h] BYREF
double v21; // [rsp+8h] [rbp-4A8h]
char v22[32]; // [rsp+10h] [rbp-4A0h] BYREF
char v23[32]; // [rsp+30h] [rbp-480h] BYREF
char s[64]; // [rsp+50h] [rbp-460h] BYREF
char v25; // [rsp+90h] [rbp-420h] BYREF
char string[1055]; // [rsp+91h] [rbp-41Fh] BYREF

format_timespan(v22, 32LL, *(_QWORD *)(a1 + 56) / 0x3E8uLL, 3LL);
format_timespan(v23, 32LL, *(_QWORD *)(a1 + 64) / 0x3E8uLL, 3LL);
v2 = *(unsigned int *)(a1 + 32);
v3 = *(unsigned int *)(a1 + 36);
v4 = (const char *)(a1 + 40);
if ( (_DWORD)v2 == (_DWORD)v3 )
snprintf(s, 0x34uLL, "%s (%d)", v4, v2);
else
snprintf(s, 0x34uLL, "%s (%d, thread %d)", v4, v2, v3);
v5 = 0;
printf("%-51s Max:%8s Total:%8s\n", s, v23, v22);
v6 = alloca(16 * ((8 * (unsigned __int64)*(unsigned int *)(a1 + 80) + 23) >> 4));
for ( i = rb_first(a1 + 24); i; i = rb_next() )
{
v8 = v5++;
*(&v20 + v8) = i;
}
if ( *(_DWORD *)(a1 + 80) != v5 )
_assert_fail("n == p->bt2la_count", "process.c", 0x66u, "process_dump");
qsort(&v20, v5, 8uLL, (__compar_fn_t)sort_func_0[arg_sort]);
result = *(unsigned int *)(a1 + 80);
if ( (_DWORD)result )
{
v10 = 0;
do
{
if ( arg_reverse )
{
v11 = *(&v20 + ~v10 + (unsigned int)result);
v12 = *(_QWORD *)(v11 + 120);
if ( v12 < 0 )
{
LABEL_17:
v13 = (double)(int)(v12 & 1 | ((unsigned __int64)v12 >> 1))
+ (double)(int)(v12 & 1 | ((unsigned __int64)v12 >> 1));
goto LABEL_10;
}
}
else
{
v11 = *(&v20 + v10);
v12 = *(_QWORD *)(v11 + 120);
if ( v12 < 0 )
goto LABEL_17;
}
v13 = (double)(int)v12;
LABEL_10:
v14 = *(_QWORD *)(a1 + 56);
v15 = v13 * 100.0;
if ( v14 < 0 )
v16 = (double)(int)(*(_DWORD *)(a1 + 56) & 1 | (*(_QWORD *)(a1 + 56) >> 1))
+ (double)(int)(*(_DWORD *)(a1 + 56) & 1 | (*(_QWORD *)(a1 + 56) >> 1));
else
v16 = (double)(int)v14;
v21 = v15 / v16;
bt_save_symbolic(v11 + 24, string, 999LL);
v17 = (const char *)lat_translator_translate_stack(string);
if ( v17 )
{
format_timespan(v22, 32LL, *(_QWORD *)(v11 + 120) / 0x3E8uLL, 3LL);
}
else
{
v17 = &v25;
v18 = strnlen(string, 0x31uLL);
v19 = *(_QWORD *)(v11 + 120);
string[v18] = 93;
string[v18 + 1] = 0;
v25 = 91;
format_timespan(v22, 32LL, v19 / 0x3E8, 3LL);
}
format_timespan(v23, 32LL, *(_QWORD *)(v11 + 128) / 0x3E8uLL, 3LL);
++v10;
printf(" %-51s Max:%8s %5.1f%%\n", v17, v23, v21);
result = *(unsigned int *)(a1 + 80);
}
while ( (unsigned int)result > v10 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
__int64 v2; // r8
__int64 v3; // r9
const char *v4; // rcx
unsigned int v5; // er13
void *v6; // rsp
__int64 i; // rdi
__int64 v8; // rax
__int64 result; // rax
unsigned int v10; // er13
__int64 v11; // r14
__int64 v12; // rax
double v13; // xmm0_8
__int64 v14; // rax
double v15; // xmm0_8
double v16; // xmm1_8
const char *v17; // r15
size_t v18; // rax
unsigned __int64 v19; // rdx
__int64 v20; // [rsp+0h] [rbp-4B0h] BYREF
double v21; // [rsp+8h] [rbp-4A8h]
char v22[32]; // [rsp+10h] [rbp-4A0h] BYREF
char v23[32]; // [rsp+30h] [rbp-480h] BYREF
char s[64]; // [rsp+50h] [rbp-460h] BYREF
char v25; // [rsp+90h] [rbp-420h] BYREF
char string[1055]; // [rsp+91h] [rbp-41Fh] BYREF

format_timespan(v22, 32LL, *(_QWORD *)(a1 + 56) / 0x3E8uLL, 3LL);
format_timespan(v23, 32LL, *(_QWORD *)(a1 + 64) / 0x3E8uLL, 3LL);
v2 = *(unsigned int *)(a1 + 32);
v3 = *(unsigned int *)(a1 + 36);
v4 = (const char *)(a1 + 40);
if ( (_DWORD)v2 == (_DWORD)v3 )
snprintf(s, 0x34uLL, "%s (%d)", v4, v2);
else
snprintf(s, 0x34uLL, "%s (%d, thread %d)", v4, v2, v3);
v5 = 0;
printf("%-51s Max:%8s Total:%8s\n", s, v23, v22);
v6 = alloca(16 * ((8 * (unsigned __int64)*(unsigned int *)(a1 + 80) + 23) >> 4));
for ( i = rb_first(a1 + 24); i; i = rb_next() )
{
v8 = v5++;
*(&v20 + v8) = i;
}
if ( *(_DWORD *)(a1 + 80) != v5 )
_assert_fail("n == p->bt2la_count", "process.c", 0x66u, "process_dump");
qsort(&v20, v5, 8uLL, (__compar_fn_t)sort_func_0[arg_sort]);
result = *(unsigned int *)(a1 + 80);
if ( (_DWORD)result )
{
v10 = 0;
do
{
if ( arg_reverse )
{
v11 = *(&v20 + ~v10 + (unsigned int)result);
v12 = *(_QWORD *)(v11 + 120);
if ( v12 < 0 )
{
LABEL_17:
v13 = (double)(int)(v12 & 1 | ((unsigned __int64)v12 >> 1))
+ (double)(int)(v12 & 1 | ((unsigned __int64)v12 >> 1));
goto LABEL_10;
}
}
else
{
v11 = *(&v20 + v10);
v12 = *(_QWORD *)(v11 + 120);
if ( v12 < 0 )
goto LABEL_17;
}
v13 = (double)(int)v12;
LABEL_10:
v14 = *(_QWORD *)(a1 + 56);
v15 = v13 * 100.0;
if ( v14 < 0 )
v16 = (double)(int)(*(_DWORD *)(a1 + 56) & 1 | (*(_QWORD *)(a1 + 56) >> 1))
+ (double)(int)(*(_DWORD *)(a1 + 56) & 1 | (*(_QWORD *)(a1 + 56) >> 1));
else
v16 = (double)(int)v14;
v21 = v15 / v16;
bt_save_symbolic(v11 + 24, string, 999LL);
v17 = (const char *)lat_translator_translate_stack(string);
if ( v17 )
{
format_timespan(v22, 32LL, *(_QWORD *)(v11 + 120) / 0x3E8uLL, 3LL);
}
else
{
v17 = &v25;
v18 = strnlen(string, 0x31uLL);
v19 = *(_QWORD *)(v11 + 120);
string[v18] = 93;
string[v18 + 1] = 0;
v25 = 91;
format_timespan(v22, 32LL, v19 / 0x3E8, 3LL);
}
format_timespan(v23, 32LL, *(_QWORD *)(v11 + 128) / 0x3E8uLL, 3LL);
++v10;
printf(" %-51s Max:%8s %5.1f%%\n", v17, v23, v21);
result = *(unsigned int *)(a1 + 80);
}
while ( (unsigned int)result > v10 );
}
return result;
}

original_code:
void process_dump(struct process *p)
{
 struct rb_node *node;
 struct bt2la **array;
 char sym_bt[1000], commpidtid[52], total[32], max[32];
 unsigned n = 0;
 static int (*const sort_func[_NR_SORT_BY])(const void *, const void *) = {
  [SORT_BY_MAX_LATENCY] = compare_by_max_latency,
  [SORT_BY_TOTAL_LATENCY] = compare_by_total_latency,
  [SORT_BY_PID] = compare_by_max_latency,
 };
 format_timespan(total, 32, p->summarized.total/1000, 3);
 format_timespan(max, 32, p->summarized.max/1000, 3);
 if (p->pid != p->tid)
  snprintf(commpidtid, sizeof(commpidtid), "%s (%d, thread %d)", p->comm, p->pid, p->tid);
 else
  snprintf(commpidtid, sizeof(commpidtid), "%s (%d)", p->comm, p->pid);
 printf("%-51s Max:%8s Total:%8s\n", commpidtid, max, total);
 array = __builtin_alloca (sizeof(struct bt2la*) * p->bt2la_count);
 for (node = rb_first(&p->bt2la_map); node; node = rb_next(node)) {
  struct bt2la *bt2la = (struct bt2la *)((char *)(node) - (char *) &((struct bt2la *)0)->rb_node);
  array[n++] = bt2la;
 }
 ((void) sizeof ((n == p->bt2la_count) ? 1 : 0), __extension__ ({ if (n == p->bt2la_count) ; else __assert_fail ("n == p->bt2la_count", "process.c", 102, __extension__ __PRETTY_FUNCTION__); }));
 qsort(array, n, sizeof(struct bt2la*), sort_func[arg_sort]);
 for (n = 0; n < p->bt2la_count; n++) {
  struct bt2la *bt2la = array[!arg_reverse ? n : p->bt2la_count - n - 1];
  double percentage = (bt2la->la.total*100.0)/p->summarized.total;
  const char *translation;
  bt_save_symbolic(&bt2la->bt, sym_bt+1, sizeof(sym_bt)-1);
  translation = lat_translator_translate_stack(sym_bt+1);
  if (!translation) {
   size_t end = strnlen(sym_bt+1, 49);
   sym_bt[0] = '[';
   sym_bt[end+1] = ']';
   sym_bt[end+2] = '\0';
  }
  format_timespan(total, 32, bt2la->la.total/1000, 3);
  format_timespan(max, 32, bt2la->la.max/1000, 3);
  printf(" %-51s Max:%8s %5.1f%%\n", translation ?: sym_bt, max, percentage);
 }
}

canonical_original_code:
void process_dump(struct process *p)
{
 struct rb_node *node;
 struct bt2la **array;
 char sym_bt[1000]; char commpidtid[52]; char total[32]; char max[32];
 unsigned int n = 0;
 static int (*sort_func[-1])(void *, void *) = {
  [SORT_BY_MAX_LATENCY] = compare_by_max_latency,
  [SORT_BY_TOTAL_LATENCY] = compare_by_total_latency,
  [SORT_BY_PID] = compare_by_max_latency,
 };
 format_timespan(total, 32, p->summarized.total/1000, 3);
 format_timespan(max, 32, p->summarized.max/1000, 3);
 if (p->pid != p->tid)
  snprintf(commpidtid, sizeof(commpidtid), "%s (%d, thread %d)", p->comm, p->pid, p->tid);
 else
  snprintf(commpidtid, sizeof(commpidtid), "%s (%d)", p->comm, p->pid);
 printf("%-51s Max:%8s Total:%8s\n", commpidtid, max, total);
 array = __builtin_alloca (sizeof(struct bt2la *) * p->bt2la_count);
 for (node = rb_first(&p->bt2la_map); node; node = rb_next(node)) {
  struct bt2la *bt2la = (struct bt2la *)((char *)(node) - (char *) &((struct bt2la *)0)->rb_node);
  array[n++] = bt2la;
 }
 ((void) sizeof ((n == p->bt2la_count) ? 1 : 0), __extension__ ({ if (n == p->bt2la_count) ; else __assert_fail ("n == p->bt2la_count", "process.c", 102, __extension__ __PRETTY_FUNCTION__); }));
 qsort(array, n, sizeof(struct bt2la *), sort_func[arg_sort]);
 for (n = 0; n < p->bt2la_count; n++) {
  struct bt2la *bt2la = array[!arg_reverse ? n : p->bt2la_count - n - 1];
  double percentage = (bt2la->la.total*100.0)/p->summarized.total;
  char *translation;
  bt_save_symbolic(&bt2la->bt, sym_bt+1, sizeof(sym_bt)-1);
  translation = lat_translator_translate_stack(sym_bt+1);
  if (!translation) {
   unsigned long end = strnlen(sym_bt+1, 49);
   sym_bt[0] = '[';
   sym_bt[end+1] = ']';
   sym_bt[end+2] = '\0';
  }
  format_timespan(total, 32, bt2la->la.total/1000, 3);
  format_timespan(max, 32, bt2la->la.max/1000, 3);
  printf(" %-51s Max:%8s %5.1f%%\n", translation ?: sym_bt, max, percentage);
 }
}

variable_types: struct process { struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } rb_node; struct rb_root { struct rb_node *rb_node; } bt2la_map; int pid; int tid; char comm[16]; struct latency_account { unsigned long total; unsigned long max; int count; } summarized; unsigned int bt2la_count; } *

variable_types: struct bt2la { struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } rb_node; struct back_trace { unsigned long trace[12]; } bt; struct latency_account { unsigned long total; unsigned long max; int count; } la; } **

variable_types:
commpidtid
char [52]

variable_types:
total
char [32]

variable_types:
max
char [32]

variable_types: percentage double

variable_types:
translation
char *

variable_types:
end
unsigned long


decompiled_code:
__int64 __fastcall process_summarize(__int64 a1)
{
__int64 v1; // rax
__int64 result; // rax
__int64 v3; // r8
__int64 v4; // r8

la_clear(a1 + 56);
result = rb_first(v1 + 24);
if ( result )
{
v3 = result;
do
{
la_sum_delay(a1 + 56, v3 + 120);
result = rb_next(v4);
v3 = result;
}
while ( result );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
__int64 v1; // rax
__int64 result; // rax
__int64 v3; // r8
__int64 v4; // r8

func1(a1 + 56);
result = rb_first(v1 + 24);
if ( result )
{
v3 = result;
do
{
func4(a1 + 56, v3 + 120);
result = rb_next(v4);
v3 = result;
}
while ( result );
}
return result;
}

original_code:
void process_summarize(struct process *p)
{
 struct rb_node *node;
 la_clear(&p->summarized);
 for (node = rb_first(&p->bt2la_map); node; node = rb_next(node)) {
  struct bt2la *bt2la = (struct bt2la *)((char *)(node) - (char *) &((struct bt2la *)0)->rb_node);
  la_sum_delay(&p->summarized, &bt2la->la);
 }
}

variable_types: struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } *


original_code:
void process_suffer_latency(struct process *p, uint64_t delay,
                            struct back_trace *bt)
{
 struct bt2la *item;
 struct rb_node *parent;
 struct rb_node **link;
 item = rb_search_bt2la(p, bt, &parent, &link);
 if (item) {
  la_add_delay(&item->la, delay);
  return;
 }
 item = malloc(sizeof(struct bt2la));
 item->bt = *bt;
 la_init(&item->la, delay);
 rb_link_node(&item->rb_node, parent, link);
 rb_insert_color(&item->rb_node, &p->bt2la_map);
 p->bt2la_count++;
}

canonical_original_code:
void process_suffer_latency(struct process *p, unsigned long delay, struct back_trace *bt)
{
 struct bt2la *item;
 struct rb_node *parent;
 struct rb_node **link;
 item = rb_search_bt2la(p, bt, &parent, &link);
 if (item) {
  la_add_delay(&item->la, delay);
  return;
 }
 item = malloc(sizeof(struct bt2la));
 item->bt = *bt;
 la_init(&item->la, delay);
 rb_link_node(&item->rb_node, parent, link);
 rb_insert_color(&item->rb_node, &p->bt2la_map);
 p->bt2la_count++;
}

variable_types:
delay
unsigned long

variable_types: struct rb_node { unsigned long rb_parent_color; struct rb_node *rb_right; struct rb_node *rb_left; } **


decompiled_code:
char *__fastcall process_new(int a1, int a2, const char *a3)
{
char *v4; // rax
char *v5; // r12

v4 = (char *)malloc(0x58uLL);
v5 = v4;
if ( v4 )
{
*((_QWORD *)v4 + 3) = 0LL;
*((_DWORD *)v4 + 8) = a1;
*((_DWORD *)v4 + 9) = a2;
strcpy(v4 + 40, a3);
la_clear((__int64)(v5 + 56));
*((_DWORD *)v5 + 20) = 0;
}
return v5;
}

original_code:
struct process *process_new(pid_t pid, pid_t tid, const char comm[16])
{
 struct process *p;
 p = malloc(sizeof(struct process));
 if (!p)
  return ((void *)0);
 p->bt2la_map = (struct rb_root) { ((void *)0), };
 p->pid = pid;
 p->tid = tid;
 strcpy(p->comm, comm);
 la_clear(&p->summarized);
 p->bt2la_count = 0;
 return p;
}

canonical_original_code:
struct process *process_new(int pid, int tid, char comm[16])
{
 struct process *p;
 p = malloc(sizeof(struct process));
 if (!p)
  return ((void *)0);
 p->bt2la_map = (struct rb_root) { ((void *)0), };
 p->pid = pid;
 p->tid = tid;
 strcpy(p->comm, comm);
 la_clear(&p->summarized);
 p->bt2la_count = 0;
 return p;
}

variable_types: pid int

variable_types: tid int

variable_types:
comm
char [16]


decompiled_code:
void __fastcall process_fini(__int64 a1)
{
process_delete_rbtree(*(void **)(a1 + 24));
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1)
{
func8(*(void **)(a1 + 24));
}

original_code:
void process_fini(struct process *p)
{
 process_delete_rbtree(p->bt2la_map.rb_node);
}


decompiled_code:
__int64 __fastcall timer_reader_get_fd(__int64 a1)
{
return *(unsigned int *)(a1 + 8);
}

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

original_code:
static int timer_reader_get_fd(struct polled_reader *pr)
{
 struct timer_reader *r = (struct timer_reader*) pr;
 return r->timerfd;
}

variable_types: struct polled_reader { struct polled_reader_ops { void (*fini)(struct polled_reader *pr); int (*start)(struct polled_reader *pr); int (*get_fd)(struct polled_reader *pr); int (*handle_ready_fd)(struct polled_reader *pr); } *ops; } *

variable_types: struct timer_reader { struct polled_reader { struct polled_reader_ops { void (*fini)(struct polled_reader *pr); int (*start)(struct polled_reader *pr); int (*get_fd)(struct polled_reader *pr); int (*handle_ready_fd)(struct polled_reader *pr); } *ops; } pr; int timerfd; int interval; int count; } *

user_defined_types: struct timer_reader { struct polled_reader pr; int timerfd; int interval; int count; }


decompiled_code:
__int64 __fastcall timer_reader_handle_ready_fd(__int64 a1)
{
unsigned int v1; // er8
int v3; // eax
int v4; // eax
char buf[16]; // [rsp+8h] [rbp-10h] BYREF

if ( read(*(_DWORD *)(a1 + 8), buf, 8uLL) != 8 )
{
fwrite("Invalid read from timerfd\n", 1uLL, 0x1AuLL, stderr);
return (unsigned int)-1;
}
pa_dump_and_clear();
v3 = *(_DWORD *)(a1 + 16);
v1 = 0;
if ( v3 <= 0 )
return v1;
v4 = v3 - 1;
*(_DWORD *)(a1 + 16) = v4;
return v4 == 0;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
unsigned int v1; // er8
int v3; // eax
int v4; // eax
char buf[16]; // [rsp+8h] [rbp-10h] BYREF

if ( read(*(_DWORD *)(a1 + 8), buf, 8uLL) != 8 )
{
fwrite("Invalid read from timerfd\n", 1uLL, 0x1AuLL, stderr);
return (unsigned int)-1;
}
pa_dump_and_clear();
v3 = *(_DWORD *)(a1 + 16);
v1 = 0;
if ( v3 <= 0 )
return v1;
v4 = v3 - 1;
*(_DWORD *)(a1 + 16) = v4;
return v4 == 0;
}

original_code:
static int timer_reader_handle_ready_fd(struct polled_reader *pr)
{
 struct timer_reader *tr = (struct timer_reader*) pr;
 uint64_t expired;
 ssize_t r;
 r = read(tr->timerfd, &expired, sizeof(uint64_t));
 if (r != sizeof(uint64_t)) {
  fprintf(stderr, "Invalid read from timerfd\n");
  return -1;
 }
 pa_dump_and_clear();
 if (tr->count <= 0)
  return 0;
 if (--tr->count == 0)
  return 1;
 return 0;
}

canonical_original_code:
static int timer_reader_handle_ready_fd(struct polled_reader *pr)
{
 struct timer_reader *tr = (struct timer_reader*) pr;
 unsigned long expired;
 long r;
 r = read(tr->timerfd, &expired, sizeof(unsigned long));
 if (r != sizeof(unsigned long)) {
  fprintf(stderr, "Invalid read from timerfd\n");
  return -1;
 }
 pa_dump_and_clear();
 if (tr->count <= 0)
  return 0;
 if (--tr->count == 0)
  return 1;
 return 0;
}

variable_types:
expired
unsigned long

variable_types: r long


decompiled_code:
__int64 __fastcall timer_reader_start(__int64 a1)
{
int v1; // eax
unsigned int v2; // er12
struct itimerspec v4; // [rsp+0h] [rbp-38h] BYREF

v4.it_interval.tv_nsec = 0LL;
v4.it_interval.tv_sec = arg_interval;
v4.it_value.tv_sec = arg_interval;
v4.it_value.tv_nsec = 0LL;
v1 = timerfd_create(1, 0x80000);
*(_DWORD *)(a1 + 8) = v1;
if ( v1 < 0 )
return (unsigned int)-*_errno_location();
v2 = 0;
if ( timerfd_settime(v1, 0, &v4, 0LL) < 0 )
{
v2 = -*_errno_location();
close(*(_DWORD *)(a1 + 8));
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
int v1; // eax
unsigned int v2; // er12
struct itimerspec v4; // [rsp+0h] [rbp-38h] BYREF

v4.it_interval.tv_nsec = 0LL;
v4.it_interval.tv_sec = arg_interval;
v4.it_value.tv_sec = arg_interval;
v4.it_value.tv_nsec = 0LL;
v1 = timerfd_create(1, 0x80000);
*(_DWORD *)(a1 + 8) = v1;
if ( v1 < 0 )
return (unsigned int)-*_errno_location();
v2 = 0;
if ( timerfd_settime(v1, 0, &v4, 0LL) < 0 )
{
v2 = -*_errno_location();
close(*(_DWORD *)(a1 + 8));
}
return v2;
}

original_code:
static int timer_reader_start(struct polled_reader *pr)
{
 struct timer_reader *tr = (struct timer_reader*) pr;
 const struct itimerspec its = {
  .it_interval = { arg_interval, 0 },
  .it_value = { arg_interval, 0 },
 };
 int r;
 tr->timerfd = timerfd_create(1, TFD_CLOEXEC);
 if (tr->timerfd < 0)
  return -(*__errno_location ());
 r = timerfd_settime(tr->timerfd, 0, &its, ((void *)0));
 if (r < 0) {
  r = -(*__errno_location ());
  close(tr->timerfd);
  return r;
 }
 return 0;
}

canonical_original_code:
static int timer_reader_start(struct polled_reader *pr)
{
 struct timer_reader *tr = (struct timer_reader*) pr;
 struct itimerspec its = {
  .it_interval = { arg_interval, 0 },
  .it_value = { arg_interval, 0 },
 };
 int r;
 tr->timerfd = timerfd_create(1, TFD_CLOEXEC);
 if (tr->timerfd < 0)
  return -(*__errno_location ());
 r = timerfd_settime(tr->timerfd, 0, &its, ((void *)0));
 if (r < 0) {
  r = -(*__errno_location ());
  close(tr->timerfd);
  return r;
 }
 return 0;
}

variable_types: struct itimerspec { struct timespec { long tv_sec; long tv_nsec; } it_interval; struct timespec it_value; }

variable_types: r int

user_defined_types: struct itimerspec { struct timespec it_interval; struct timespec it_value; }


decompiled_code:
int __fastcall timer_reader_fini(__int64 a1)
{
return close(*(_DWORD *)(a1 + 8));
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
return close(*(_DWORD *)(a1 + 8));
}

original_code:
static void timer_reader_fini(struct polled_reader *pr)
{
 struct timer_reader *tr = (struct timer_reader*) pr;
 close(tr->timerfd);
}


decompiled_code:
_DWORD *timer_reader_new()
{
_DWORD *result; // rax
int v1; // edx

result = calloc(1uLL, 0x18uLL);
if ( result )
{
v1 = arg_count;
*(_QWORD *)result = timer_reader_ops;
result[4] = v1;
}
return result;
}

canonical_decompiled_code:
_DWORD *func4()
{
_DWORD *result; // rax
int v1; // edx

result = calloc(1uLL, 0x18uLL);
if ( result )
{
v1 = arg_count;
*(_QWORD *)result = timer_reader_ops;
result[4] = v1;
}
return result;
}

original_code:
struct polled_reader *timer_reader_new()
{
 struct timer_reader *r;
 r = calloc(1, sizeof(struct timer_reader));
 if (r == ((void *)0))
  return ((void *)0);
 r->pr.ops = &timer_reader_ops;
 r->count = arg_count;
 return &r->pr;
}


decompiled_code:
int __fastcall bt_compare(const void *a1, const void *a2)
{
return memcmp(a1, a2, 0x60uLL);
}

canonical_decompiled_code:
int __fastcall func0(const void *a1, const void *a2)
{
return memcmp(a1, a2, 0x60uLL);
}

original_code:
int bt_compare(const struct back_trace *b1, const struct back_trace *b2)
{
 return memcmp(b1->trace, b2->trace, sizeof(b1->trace));
}

canonical_original_code:
int bt_compare(struct back_trace *b1, struct back_trace *b2)
{
 return memcmp(b1->trace, b2->trace, sizeof(b1->trace));
}

variable_types: struct back_trace { unsigned long trace[12]; } *


original_code:
void bt_init(struct back_trace *b, const long tr[], int len)
{
 int i;
 for (i = 0; i < len && i < 12; i++)
  b->trace[i] = tr[i];
}

canonical_original_code:
void bt_init(struct back_trace *b, long tr[], int len)
{
 int i;
 for (i = 0; i < len && i < 12; i++)
  b->trace[i] = tr[i];
}

variable_types:
tr
long []

variable_types: len int

variable_types: i int


sighandler

repo: michielboland/mathopd

decompiled_code:
void __fastcall sighandler(int a1)
{
switch ( a1 )
{
case 1:
gotsighup = 1;
break;
case 2:
case 15:
gotsigterm = 1;
break;
case 3:
gotsigquit = 1;
break;
case 10:
gotsigusr1 = 1;
break;
case 12:
gotsigusr2 = 1;
break;
case 17:
gotsigchld = 1;
break;
case 28:
gotsigwinch = 1;
break;
default:
return;
}
}

canonical_decompiled_code:
void __fastcall func0(int a1)
{
switch ( a1 )
{
case 1:
gotsighup = 1;
break;
case 2:
case 15:
gotsigterm = 1;
break;
case 3:
gotsigquit = 1;
break;
case 10:
gotsigusr1 = 1;
break;
case 12:
gotsigusr2 = 1;
break;
case 17:
gotsigchld = 1;
break;
case 28:
gotsigwinch = 1;
break;
default:
return;
}
}

original_code:
static void sighandler(int sig)
{
 switch (sig) {
 case 15:
 case 2:
  gotsigterm = 1;
  break;
 case 1:
  gotsighup = 1;
  break;
 case 10:
  gotsigusr1 = 1;
  break;
 case 12:
  gotsigusr2 = 1;
  break;
 case 17:
  gotsigchld = 1;
  break;
 case 3:
  gotsigquit = 1;
  break;
 case 28:
  gotsigwinch = 1;
  break;
 }
}

variable_types: sig int


die

decompiled_code:
void __noreturn die(char *s, char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-E0h] BYREF

if ( format )
{
fprintf(stderr, "%s: ", (const char *)progname);
va_start(arg, format);
vfprintf(stderr, format, arg);
fputc(10, stderr);
}
if ( s )
perror(s);
exit(1);
}

canonical_decompiled_code:
void __noreturn func1(char *s, char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-E0h] BYREF

if ( format )
{
fprintf(stderr, "%s: ", (const char *)progname);
va_start(arg, format);
vfprintf(stderr, format, arg);
fputc(10, stderr);
}
if ( s )
perror(s);
exit(1);
}

original_code:
static void die(const char *t, const char *fmt, ...)
{
 va_list ap;
 if (fmt) {
  fprintf(stderr, "%s: ", progname);
  __builtin_va_start(ap,fmt);
  vfprintf(stderr, fmt, ap);
  fprintf(stderr, "\n");
  __builtin_va_end(ap);
 }
 if (t)
  perror(t);
 exit(1);
}

canonical_original_code:
static void die(char *t, char *fmt, ...)
{
 __builtin_va_list ap;
 if (fmt) {
  fprintf(stderr, "%s: ", progname);
  __builtin_va_start(ap,fmt);
  vfprintf(stderr, fmt, ap);
  fprintf(stderr, "\n");
  __builtin_va_end(ap);
 }
 if (t)
  perror(t);
 exit(1);
}

variable_types:
t
char *

variable_types:
fmt
char *


decompiled_code:
int __fastcall startup_server(__int64 a1)
{
int v1; // eax
__int64 i; // rbx
int result; // eax
const char *v4; // rdx
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = socket(*(_DWORD *)(a1 + 88), *(_DWORD *)(a1 + 92), *(_DWORD *)(a1 + 96));
*(_DWORD *)a1 = v1;
if ( v1 == -1 )
die("socket", 0LL);
optval[0] = 1;
if ( setsockopt(v1, 1, 2, optval, 4u) == -1 )
die("setsockopt", "cannot set re-use flag");
for ( i = *(_QWORD *)(a1 + 104); i; i = *(_QWORD *)(i + 24) )
{
if ( setsockopt(*(_DWORD *)a1, *(_DWORD *)i, *(_DWORD *)(i + 4), *(const void **)(i + 8), *(_DWORD *)(i + 16)) == -1 )
die("setsockopt", 0LL);
}
fcntl(*(_DWORD *)a1, 2, 1LL);
fcntl(*(_DWORD *)a1, 4, 2048LL);
if ( bind(*(_DWORD *)a1, *(const struct sockaddr **)(a1 + 16), *(_DWORD *)(a1 + 8)) == -1 )
{
v4 = *(const char **)(a1 + 72);
if ( !v4 )
v4 = "[any]";
die("bind", "cannot start up server at %s port %s", v4, *(const char **)(a1 + 80));
}
result = listen(*(_DWORD *)a1, *(_DWORD *)(a1 + 64));
if ( result == -1 )
die("listen", 0LL);
return result;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1)
{
int v1; // eax
__int64 i; // rbx
int result; // eax
const char *v4; // rdx
int optval[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = socket(*(_DWORD *)(a1 + 88), *(_DWORD *)(a1 + 92), *(_DWORD *)(a1 + 96));
*(_DWORD *)a1 = v1;
if ( v1 == -1 )
func1("socket", 0LL);
optval[0] = 1;
if ( setsockopt(v1, 1, 2, optval, 4u) == -1 )
func1("setsockopt", "cannot set re-use flag");
for ( i = *(_QWORD *)(a1 + 104); i; i = *(_QWORD *)(i + 24) )
{
if ( setsockopt(*(_DWORD *)a1, *(_DWORD *)i, *(_DWORD *)(i + 4), *(const void **)(i + 8), *(_DWORD *)(i + 16)) == -1 )
func1("setsockopt", 0LL);
}
fcntl(*(_DWORD *)a1, 2, 1LL);
fcntl(*(_DWORD *)a1, 4, 2048LL);
if ( bind(*(_DWORD *)a1, *(const struct sockaddr **)(a1 + 16), *(_DWORD *)(a1 + 8)) == -1 )
{
v4 = *(const char **)(a1 + 72);
if ( !v4 )
v4 = "[any]";
func1("bind", "cannot start up server at %s port %s", v4, *(const char **)(a1 + 80));
}
result = listen(*(_DWORD *)a1, *(_DWORD *)(a1 + 64));
if ( result == -1 )
func1("listen", 0LL);
return result;
}

original_code:
static void startup_server(struct server *s)
{
 int onoff;
 struct server_sockopts *o;
 s->fd = socket(s->family, s->socktype, s->protocol);
 if (s->fd == -1)
  die("socket", 0);
 onoff = 1;
 if (setsockopt(s->fd, 1, 2, &onoff, sizeof onoff) == -1)
  die("setsockopt", "cannot set re-use flag");
 o = s->options;
 while (o) {
  if (setsockopt(s->fd, o->ss_level, o->ss_optname, o->ss_optval, o->ss_optlen) == -1)
   die("setsockopt", 0);
  o = o->next;
 }
 fcntl(s->fd, 2, 1);
 fcntl(s->fd, 4, 04000);
 if (bind(s->fd, s->server_addr, s->server_addrlen) == -1)
  die("bind", "cannot start up server at %s port %s", s->addr ? s->addr : "[any]", s->port);
 if (listen(s->fd, s->backlog) == -1)
  die("listen", 0);
}

variable_types: struct server { int fd; unsigned long server_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *server_addr; struct virtual { char *host; struct virtual *next; struct vserver { struct control { char *alias; int path_args_ok; int exact_match; struct simple_list { char *name; struct simple_list *next; } *index_names; struct access { int type; struct sockaddr_storage { unsigned short ss_family; char __ss_padding[-1]; unsigned long __ss_align; } addr; unsigned int prefixlen; struct access *next; } *accesses; struct mime { int class; char *ext; char *name; struct mime *next; } *mimes; struct control *next; struct simple_list *locations; struct access *clients; char *admin; char *realm; char *userfile; char *error_401_file; char *error_403_file; char *error_404_file; int do_crypt; char *child_filename; struct simple_list *exports; int script_identity; unsigned int script_uid; unsigned int script_gid; int allow_dotfiles; int user_directory; struct simple_list *putenvs; struct simple_list *extra_headers; int path_info_ok; char *auto_index_command; unsigned long expire_interval; int sanitize_path; } *controls; struct vserver *next; } *vserver; int anyhost; } *children; struct control *controls; struct server *next; int pollno; struct vserver *vservers; unsigned long backlog; char *addr; char *port; int family; int socktype; int protocol; struct server_sockopts { int ss_level; int ss_optname; void *ss_optval; unsigned int ss_optlen; struct server_sockopts *next; } *options; } *

variable_types: onoff int

user_defined_types: struct server { int fd; unsigned long server_addrlen; struct sockaddr *server_addr; struct virtual *children; struct control *controls; struct server *next; int pollno; struct vserver *vservers; unsigned long backlog; char *addr; char *port; int family; int socktype; int protocol; struct server_sockopts *options; }

user_defined_types: struct virtual { char *host; struct virtual *next; struct vserver *vserver; int anyhost; }

user_defined_types: struct vserver { struct control *controls; struct vserver *next; }

user_defined_types: struct control { char *alias; int path_args_ok; int exact_match; struct simple_list *index_names; struct access *accesses; struct mime *mimes; struct control *next; struct simple_list *locations; struct access *clients; char *admin; char *realm; char *userfile; char *error_401_file; char *error_403_file; char *error_404_file; int do_crypt; char *child_filename; struct simple_list *exports; int script_identity; unsigned int script_uid; unsigned int script_gid; int allow_dotfiles; int user_directory; struct simple_list *putenvs; struct simple_list *extra_headers; int path_info_ok; char *auto_index_command; unsigned long expire_interval; int sanitize_path; }

user_defined_types: struct access { int type; struct sockaddr_storage addr; unsigned int prefixlen; struct access *next; }


spawn

decompiled_code:
__int64 __fastcall spawn(char *path, char **argv, char **envp, int fd, int a5, __uid_t uid, __gid_t gid, char *patha)
{
__pid_t v12; // eax
__int64 v13; // rdx
__int64 v14; // rcx
unsigned int v15; // er8
int v16; // eax
unsigned int v18; // [rsp+Ch] [rbp-4Ch]
struct rlimit rlimits; // [rsp+10h] [rbp-48h] BYREF

v12 = fork();
v15 = v12;
if ( v12 == -1 )
{
lerror("spawn: failed to create child process", argv, v13, v14, 0xFFFFFFFFLL);
return (unsigned int)-1;
}
if ( !v12 )
{
setpgid(0, 0);
mysignal_isra_0(13, 0LL);
if ( coredir )
{
rlimits.rlim_max = 0LL;
rlimits.rlim_cur = 0LL;
setrlimit(RLIMIT_CORE, &rlimits);
}
dup2(fd, 0);
dup2(fd, 1);
if ( a5 == -1 )
{
if ( !uid )
goto LABEL_11;
}
else
{
dup2(a5, 2);
if ( !uid )
goto LABEL_11;
}
if ( setuid(0) == -1 )
exit(1);
if ( setgid(gid) == -1 )
exit(2);
if ( setuid(uid) == -1 )
exit(3);
LABEL_11:
if ( getuid() && geteuid() )
{
if ( chdir(patha) != -1 )
{
execve(path, argv, envp);
exit(6);
}
exit(5);
}
exit(4);
}
v16 = debug;
++stats[2];
if ( v16 )
{
v18 = v15;
log_d("child process %d created", v15);
v15 = v18;
}
return v15;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *path, char **argv, char **envp, int fd, int a5, __uid_t uid, __gid_t gid, char *patha)
{
__pid_t v12; // eax
__int64 v13; // rdx
__int64 v14; // rcx
unsigned int v15; // er8
int v16; // eax
unsigned int v18; // [rsp+Ch] [rbp-4Ch]
struct rlimit rlimits; // [rsp+10h] [rbp-48h] BYREF

v12 = fork();
v15 = v12;
if ( v12 == -1 )
{
lerror("spawn: failed to create child process", argv, v13, v14, 0xFFFFFFFFLL);
return (unsigned int)-1;
}
if ( !v12 )
{
setpgid(0, 0);
func3(13, 0LL);
if ( coredir )
{
rlimits.rlim_max = 0LL;
rlimits.rlim_cur = 0LL;
setrlimit(RLIMIT_CORE, &rlimits);
}
dup2(fd, 0);
dup2(fd, 1);
if ( a5 == -1 )
{
if ( !uid )
goto LABEL_11;
}
else
{
dup2(a5, 2);
if ( !uid )
goto LABEL_11;
}
if ( setuid(0) == -1 )
exit(1);
if ( setgid(gid) == -1 )
exit(2);
if ( setuid(uid) == -1 )
exit(3);
LABEL_11:
if ( getuid() && geteuid() )
{
if ( chdir(patha) != -1 )
{
execve(path, argv, envp);
exit(6);
}
exit(5);
}
exit(4);
}
v16 = debug;
++stats[2];
if ( v16 )
{
v18 = v15;
log_d("child process %d created", v15);
v15 = v18;
}
return v15;
}

original_code:
pid_t spawn(const char *program, char *const argv[], char *const envp[], int fd, int efd, uid_t u, gid_t g, const char *curdir)
{
 pid_t pid;
 struct rlimit rl;
 pid = fork();
 switch (pid) {
 default:
  ++stats.forked_children;
  if (debug)
   log_d("child process %d created", (int) pid);
  break;
 case -1:
  lerror("spawn: failed to create child process");
  break;
 case 0:
  setpgid(0, 0);
  mysignal(13, ((__sighandler_t) 0));
  if (coredir) {
   rl.rlim_cur = rl.rlim_max = 0;
   setrlimit(RLIMIT_CORE, &rl);
  }
  dup2(fd, 0);
  dup2(fd, 1);
  if (efd != -1)
   dup2(efd, 2);
  if (u) {
   if (setuid(0) == -1)
    _exit(1);
   if (setgid(g) == -1)
    _exit(2);
   if (setuid(u) == -1)
    _exit(3);
  }
  if (getuid() == 0 || geteuid() == 0)
   _exit(4);
  if (chdir(curdir) == -1)
   _exit(5);
  execve(program, argv, envp);
  _exit(6);
 }
 return pid;
}

canonical_original_code:
int spawn(char *program, char *argv[], char *envp[], int fd, int efd, unsigned int u, unsigned int g, char *curdir)
{
 int pid;
 struct rlimit rl;
 pid = fork();
 switch (pid) {
 default:
  ++stats.forked_children;
  if (debug)
   log_d("child process %d created", (int) pid);
  break;
 case -1:
  lerror("spawn: failed to create child process");
  break;
 case 0:
  setpgid(0, 0);
  mysignal(13, ((void (*)(int)) 0));
  if (coredir) {
   rl.rlim_cur = rl.rlim_max = 0;
   setrlimit(RLIMIT_CORE, &rl);
  }
  dup2(fd, 0);
  dup2(fd, 1);
  if (efd != -1)
   dup2(efd, 2);
  if (u) {
   if (setuid(0) == -1)
    _exit(1);
   if (setgid(g) == -1)
    _exit(2);
   if (setuid(u) == -1)
    _exit(3);
  }
  if (getuid() == 0 || geteuid() == 0)
   _exit(4);
  if (chdir(curdir) == -1)
   _exit(5);
  execve(program, argv, envp);
  _exit(6);
 }
 return pid;
}

variable_types:
program
char *

variable_types:
argv
char *[]

variable_types:
envp
char *[]

variable_types: fd int

variable_types: efd int

variable_types:
u
unsigned int

variable_types:
g
unsigned int

variable_types:
curdir
char *

variable_types: pid int

variable_types: struct rlimit { unsigned long rlim_cur; unsigned long rlim_max; }