repo: travisb-ca/tachyon

decompiled_code:
__int64 __fastcall tty_new(__int64 a1, unsigned int a2)
{
int v2; // eax
unsigned int v3; // ebp
unsigned int v4; // er13
unsigned int v5; // er12
unsigned int v7; // er13
int *v8; // rax
int *v9; // rax
char *v10; // rax
int v11; // er13
int v12; // ebx
char *v13; // r14
const unsigned __int16 *v14; // rax
char v15; // r15
int v16; // er15
char **v17; // r14
char *v18; // rax
const char *v19; // rdx
bool v20; // zf
const char *v21; // rax
const unsigned __int16 **v22; // rax
int v23; // er8
const unsigned __int16 *v24; // rdi
char *v25; // rax
__int64 v26; // rcx
__int64 v27; // rdx
int *v28; // rax
__int64 v29; // r8
const char *v30; // rcx
unsigned int v31; // er13
int *v32; // rax
int *v33; // rax
unsigned int v34; // er13
int *v35; // rax
__int64 v36; // [rsp+8h] [rbp-450h]
__int64 v37; // [rsp+8h] [rbp-450h]
char value[16]; // [rsp+10h] [rbp-448h] BYREF
char s[1024]; // [rsp+20h] [rbp-438h] BYREF
char v40; // [rsp+420h] [rbp-38h] BYREF

v2 = posix_openpt(258);
v3 = v2;
if ( v2 < 0 )
{
v5 = -1;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v9 = _errno_location();
fprintf(stderr, "openpt failed %d %d\n", v3, (unsigned int)*v9);
}
goto LABEL_5;
}
close_on_exec((unsigned int)v2);
v4 = grantpt(v3);
if ( v4 )
{
v5 = -2;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v28 = _errno_location();
fprintf(stderr, "granpt failed %d %d\n", v4, (unsigned int)*v28);
}
LABEL_5:
close(v3);
return v5;
}
v7 = unlockpt(v3);
if ( v7 )
{
v5 = -3;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v8 = _errno_location();
fprintf(stderr, "unlockpt failed %d %d\n", v7, (unsigned int)*v8);
}
goto LABEL_5;
}
v10 = ptsname(v3);
v11 = open(v10, 2);
if ( v11 < 0 )
{
if ( *((int *)&cmd_options + 1) >= 0 )
{
v33 = _errno_location();
fprintf(stderr, "failed to open slave %d %d\n", (unsigned int)v11, (unsigned int)*v33);
}
v5 = -4;
close(v11);
goto LABEL_5;
}
if ( fork() )
{
v5 = v3;
close(v11);
}
else
{
v12 = 1;
qmemcpy(s, (const void *)(unsigned int)((_DWORD)&cmd_options + 8), sizeof(s));
v13 = s;
do
{
v15 = v13[1];
if ( !v15 )
break;
v14 = *_ctype_b_loc();
if ( (v14[*v13] & 0x2000) != 0 )
v12 += (v14[v15] & 0x2000) == 0;
++v13;
}
while ( &s[1023] != v13 );
v16 = *((_DWORD *)&cmd_options + 1);
if ( v16 > 1 )
{
fprintf(stderr, "Shell command had %d args\n", (unsigned int)v12);
v16 = *((_DWORD *)&cmd_options + 1);
}
v17 = (char **)calloc(v12 + 1, 8uLL);
if ( v17 )
{
v18 = strrchr(s, 47);
v19 = v18 + 1;
v20 = v18 == 0LL;
v21 = "unknown";
if ( !v20 )
v21 = v19;
*v17 = (char *)v21;
v22 = _ctype_b_loc();
v23 = 1;
v24 = *v22;
v25 = &s[1];
do
{
v26 = *v25;
if ( (v24[v26] & 0x2000) != 0 )
{
*v25 = 0;
}
else if ( !*(v25 - 1) && (_BYTE)v26 )
{
v27 = v23++;
v17[v27] = v25;
}
++v25;
}
while ( &v40 != v25 );
if ( v16 > 1 )
{
v29 = 0LL;
while ( 1 )
{
v30 = v17[v29];
if ( v30 )
{
if ( v16 > 1 )
{
v36 = v29;
fprintf(stderr, "arg %d is '%s'\n", (unsigned int)v29, v30);
v29 = v36;
}
}
else if ( v16 > 1 )
{
v37 = v29;
fprintf(stderr, "arg %d is NULL\n", (unsigned int)v29);
v29 = v37;
}
if ( v12 < (int)++v29 )
break;
v16 = *((_DWORD *)&cmd_options + 1);
}
}
snprintf(value, 0x10uLL, "%d", a2);
setenv("WINDOW", value, 1);
setenv("TACHYON_SESSION", (const char *)(unsigned int)((_DWORD)&cmd_options + 1032), 1);
close(v3);
close(0);
close(1);
close(2);
dup(v11);
dup(v11);
dup(v11);
close(v11);
setsid();
v31 = ioctl(0, 0x540EuLL, 1LL);
if ( v31 )
{
v5 = 7;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v32 = _errno_location();
fprintf(stderr, "slave failed to set controlling tty %d %d\n", v31, (unsigned int)*v32);
}
}
else
{
v5 = 8;
v34 = execv(s, v17);
if ( *((int *)&cmd_options + 1) >= 0 )
{
v35 = _errno_location();
fprintf(stderr, "slave failed to exec %d %d\n", v34, (unsigned int)*v35);
}
}
}
else
{
v5 = 9;
if ( v16 >= 0 )
fwrite("Unable to allocate arg buffer\n", 1uLL, 0x1EuLL, stderr);
}
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned int a2)
{
int v2; // eax
unsigned int v3; // ebp
unsigned int v4; // er13
unsigned int v5; // er12
unsigned int v7; // er13
int *v8; // rax
int *v9; // rax
char *v10; // rax
int v11; // er13
int v12; // ebx
char *v13; // r14
const unsigned __int16 *v14; // rax
char v15; // r15
int v16; // er15
char **v17; // r14
char *v18; // rax
const char *v19; // rdx
bool v20; // zf
const char *v21; // rax
const unsigned __int16 **v22; // rax
int v23; // er8
const unsigned __int16 *v24; // rdi
char *v25; // rax
__int64 v26; // rcx
__int64 v27; // rdx
int *v28; // rax
__int64 v29; // r8
const char *v30; // rcx
unsigned int v31; // er13
int *v32; // rax
int *v33; // rax
unsigned int v34; // er13
int *v35; // rax
__int64 v36; // [rsp+8h] [rbp-450h]
__int64 v37; // [rsp+8h] [rbp-450h]
char value[16]; // [rsp+10h] [rbp-448h] BYREF
char s[1024]; // [rsp+20h] [rbp-438h] BYREF
char v40; // [rsp+420h] [rbp-38h] BYREF

v2 = posix_openpt(258);
v3 = v2;
if ( v2 < 0 )
{
v5 = -1;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v9 = _errno_location();
fprintf(stderr, "openpt failed %d %d\n", v3, (unsigned int)*v9);
}
goto LABEL_5;
}
close_on_exec((unsigned int)v2);
v4 = grantpt(v3);
if ( v4 )
{
v5 = -2;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v28 = _errno_location();
fprintf(stderr, "granpt failed %d %d\n", v4, (unsigned int)*v28);
}
LABEL_5:
close(v3);
return v5;
}
v7 = unlockpt(v3);
if ( v7 )
{
v5 = -3;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v8 = _errno_location();
fprintf(stderr, "unlockpt failed %d %d\n", v7, (unsigned int)*v8);
}
goto LABEL_5;
}
v10 = ptsname(v3);
v11 = open(v10, 2);
if ( v11 < 0 )
{
if ( *((int *)&cmd_options + 1) >= 0 )
{
v33 = _errno_location();
fprintf(stderr, "failed to open slave %d %d\n", (unsigned int)v11, (unsigned int)*v33);
}
v5 = -4;
close(v11);
goto LABEL_5;
}
if ( fork() )
{
v5 = v3;
close(v11);
}
else
{
v12 = 1;
qmemcpy(s, (const void *)(unsigned int)((_DWORD)&cmd_options + 8), sizeof(s));
v13 = s;
do
{
v15 = v13[1];
if ( !v15 )
break;
v14 = *_ctype_b_loc();
if ( (v14[*v13] & 0x2000) != 0 )
v12 += (v14[v15] & 0x2000) == 0;
++v13;
}
while ( &s[1023] != v13 );
v16 = *((_DWORD *)&cmd_options + 1);
if ( v16 > 1 )
{
fprintf(stderr, "Shell command had %d args\n", (unsigned int)v12);
v16 = *((_DWORD *)&cmd_options + 1);
}
v17 = (char **)calloc(v12 + 1, 8uLL);
if ( v17 )
{
v18 = strrchr(s, 47);
v19 = v18 + 1;
v20 = v18 == 0LL;
v21 = "unknown";
if ( !v20 )
v21 = v19;
*v17 = (char *)v21;
v22 = _ctype_b_loc();
v23 = 1;
v24 = *v22;
v25 = &s[1];
do
{
v26 = *v25;
if ( (v24[v26] & 0x2000) != 0 )
{
*v25 = 0;
}
else if ( !*(v25 - 1) && (_BYTE)v26 )
{
v27 = v23++;
v17[v27] = v25;
}
++v25;
}
while ( &v40 != v25 );
if ( v16 > 1 )
{
v29 = 0LL;
while ( 1 )
{
v30 = v17[v29];
if ( v30 )
{
if ( v16 > 1 )
{
v36 = v29;
fprintf(stderr, "arg %d is '%s'\n", (unsigned int)v29, v30);
v29 = v36;
}
}
else if ( v16 > 1 )
{
v37 = v29;
fprintf(stderr, "arg %d is NULL\n", (unsigned int)v29);
v29 = v37;
}
if ( v12 < (int)++v29 )
break;
v16 = *((_DWORD *)&cmd_options + 1);
}
}
snprintf(value, 0x10uLL, "%d", a2);
setenv("WINDOW", value, 1);
setenv("TACHYON_SESSION", (const char *)(unsigned int)((_DWORD)&cmd_options + 1032), 1);
close(v3);
close(0);
close(1);
close(2);
dup(v11);
dup(v11);
dup(v11);
close(v11);
setsid();
v31 = ioctl(0, 0x540EuLL, 1LL);
if ( v31 )
{
v5 = 7;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v32 = _errno_location();
fprintf(stderr, "slave failed to set controlling tty %d %d\n", v31, (unsigned int)*v32);
}
}
else
{
v5 = 8;
v34 = execv(s, v17);
if ( *((int *)&cmd_options + 1) >= 0 )
{
v35 = _errno_location();
fprintf(stderr, "slave failed to exec %d %d\n", v34, (unsigned int)*v35);
}
}
}
else
{
v5 = 9;
if ( v16 >= 0 )
fwrite("Unable to allocate arg buffer\n", 1uLL, 0x1EuLL, stderr);
}
}
return v5;
}

original_code:
int tty_new(char *command, int bufnum) {
 int result;
 int pty_master;
 int pty_slave;
 pty_master = posix_openpt(02 | 0400);
 if (pty_master < 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "openpt failed %d %d" "\n", pty_master, (*__errno_location ())); } while (0);
  result = -1;
  goto err_master;
 }
 close_on_exec(pty_master);
 result = grantpt(pty_master);
 if (result != 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "granpt failed %d %d" "\n", result, (*__errno_location ())); } while (0);
  result = -2;
  goto err_master;
 }
 result = unlockpt(pty_master);
 if (result != 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "unlockpt failed %d %d" "\n", result, (*__errno_location ())); } while (0);
  result = -3;
  goto err_master;
 }
 pty_slave = open(ptsname(pty_master), 02);
 if (pty_slave < 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "failed to open slave %d %d" "\n", pty_slave, (*__errno_location ())); } while (0);
  result = -4;
  goto err_slave;
 }
 if (fork()) {
  close(pty_slave);
  return pty_master;
 } else {
  char *cmd_name;
  int num_args = 1;
  char buf[1024];
  char **args;
  memcpy(buf, cmd_options.new_buf_command, sizeof(buf));
  for (int i = 1; i < sizeof(buf); i++) {
   if (buf[i] == '\0')
    break;
   if (((*__ctype_b_loc ())[(int) ((buf[i-1]))] & (unsigned short int) _ISspace) && !((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int) _ISspace))
    num_args++;
  }
  do { if (cmd_options.verbose >= 2) fprintf(stderr, "Shell command had %d args" "\n", num_args); } while (0);
  args = calloc(num_args + 1, sizeof(char *));
  if (!args) {
   do { if (cmd_options.verbose >= 0) fprintf(stderr, "Unable to allocate arg buffer" "\n"); } while (0);
   return 9;
  }
  cmd_name = strrchr(buf, '/');
  if (!cmd_name)
   cmd_name = "unknown";
  else
   cmd_name++;
  args[0] = cmd_name;
  for (int i = 1, n = 1; i < sizeof(buf); i++) {
   if (((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int) _ISspace))
    buf[i] = '\0';
   if (buf[i - 1] == '\0' && buf[i] != '\0')
    args[n++] = &buf[i];
  }
  if (cmd_options.verbose >= 2)
   for (int i = 0; i < num_args + 1; i++)
    if (args[i])
     do { if (cmd_options.verbose >= 2) fprintf(stderr, "arg %d is '%s'" "\n", i, args[i]); } while (0);
    else
     do { if (cmd_options.verbose >= 2) fprintf(stderr, "arg %d is NULL" "\n", i); } while (0);
  {
   char bufnum_str[16];
   snprintf(bufnum_str, sizeof(bufnum_str), "%d", bufnum);
   setenv("WINDOW", bufnum_str, 1);
   setenv("TACHYON_SESSION", cmd_options.session_name, 1);
  }
  close(pty_master);
  close(0);
  close(1);
  close(2);
  dup(pty_slave);
  dup(pty_slave);
  dup(pty_slave);
  close(pty_slave);
  setsid();
  result = ioctl(0, 0x540E, 1);
  if (result != 0) {
   do { if (cmd_options.verbose >= 0) fprintf(stderr, "slave failed to set controlling tty %d %d" "\n", result, (*__errno_location ())); } while (0);
   return 7;
  }
  result = execv(buf, args);
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "slave failed to exec %d %d" "\n", result, (*__errno_location ())); } while (0);
  return 8;
 }
err_slave:
 close(pty_slave);
err_master:
 close(pty_master);
 return result;
}

canonical_original_code:
int tty_new(char *command, int bufnum) {
 int result;
 int pty_master;
 int pty_slave;
 pty_master = posix_openpt(02 | 0400);
 if (pty_master < 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "openpt failed %d %d" "\n", pty_master, (*__errno_location ())); } while (0);
  result = -1;
  goto err_master;
 }
 close_on_exec(pty_master);
 result = grantpt(pty_master);
 if (result != 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "granpt failed %d %d" "\n", result, (*__errno_location ())); } while (0);
  result = -2;
  goto err_master;
 }
 result = unlockpt(pty_master);
 if (result != 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "unlockpt failed %d %d" "\n", result, (*__errno_location ())); } while (0);
  result = -3;
  goto err_master;
 }
 pty_slave = open(ptsname(pty_master), 02);
 if (pty_slave < 0) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "failed to open slave %d %d" "\n", pty_slave, (*__errno_location ())); } while (0);
  result = -4;
  goto err_slave;
 }
 if (fork()) {
  close(pty_slave);
  return pty_master;
 } else {
  char *cmd_name;
  int num_args = 1;
  char buf[1024];
  char **args;
  memcpy(buf, cmd_options.new_buf_command, sizeof(buf));
  for (int i = 1; i < sizeof(buf); i++) {
   if (buf[i] == '\0')
    break;
   if (((*__ctype_b_loc ())[(int) ((buf[i-1]))] & (unsigned short) _ISspace) && !((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short) _ISspace))
    num_args++;
  }
  do { if (cmd_options.verbose >= 2) fprintf(stderr, "Shell command had %d args" "\n", num_args); } while (0);
  args = calloc(num_args + 1, sizeof(char *));
  if (!args) {
   do { if (cmd_options.verbose >= 0) fprintf(stderr, "Unable to allocate arg buffer" "\n"); } while (0);
   return 9;
  }
  cmd_name = strrchr(buf, '/');
  if (!cmd_name)
   cmd_name = "unknown";
  else
   cmd_name++;
  args[0] = cmd_name;
  for (int i = 1; int n = 1; i < sizeof(buf); i++) {
   if (((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short) _ISspace))
    buf[i] = '\0';
   if (buf[i - 1] == '\0' && buf[i] != '\0')
    args[n++] = &buf[i];
  }
  if (cmd_options.verbose >= 2)
   for (int i = 0; i < num_args + 1; i++)
    if (args[i])
     do { if (cmd_options.verbose >= 2) fprintf(stderr, "arg %d is '%s'" "\n", i, args[i]); } while (0);
    else
     do { if (cmd_options.verbose >= 2) fprintf(stderr, "arg %d is NULL" "\n", i); } while (0);
  {
   char bufnum_str[16];
   snprintf(bufnum_str, sizeof(bufnum_str), "%d", bufnum);
   setenv("WINDOW", bufnum_str, 1);
   setenv("TACHYON_SESSION", cmd_options.session_name, 1);
  }
  close(pty_master);
  close(0);
  close(1);
  close(2);
  dup(pty_slave);
  dup(pty_slave);
  dup(pty_slave);
  close(pty_slave);
  setsid();
  result = ioctl(0, 0x540E, 1);
  if (result != 0) {
   do { if (cmd_options.verbose >= 0) fprintf(stderr, "slave failed to set controlling tty %d %d" "\n", result, (*__errno_location ())); } while (0);
   return 7;
  }
  result = execv(buf, args);
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "slave failed to exec %d %d" "\n", result, (*__errno_location ())); } while (0);
  return 8;
 }
err_slave:
 close(pty_slave);
err_master:
 close(pty_master);
 return result;
}

variable_types:
command
char *

variable_types: bufnum int

variable_types: result int

variable_types:
buf
char [1024]

variable_types: i int

variable_types: n int


decompiled_code:
int tty_save_termstate()
{
return tcgetattr(0, &original_term_state);
}

canonical_decompiled_code:
int func1()
{
return tcgetattr(0, &original_term_state);
}

original_code:
void tty_save_termstate(void) {
 tcgetattr(0, &original_term_state);
}

canonical_original_code:
void tty_save_termstate() {
 tcgetattr(0, &original_term_state);
}

return_type: void


decompiled_code:
int tty_restore_termstate()
{
return tcsetattr(0, 0, &original_term_state);
}

canonical_decompiled_code:
int func2()
{
return tcsetattr(0, 0, &original_term_state);
}

original_code:
void tty_restore_termstate(void) {
 tcsetattr(0, 0, &original_term_state);
}

canonical_original_code:
void tty_restore_termstate() {
 tcsetattr(0, 0, &original_term_state);
}


decompiled_code:
__int64 tty_configure_control_tty()
{
unsigned int v0; // er12
struct termios v2; // [rsp+0h] [rbp-48h] BYREF

if ( tcgetattr(0, &v2) )
return (unsigned int)-1;
v2.c_lflag &= 0xFFFFFFB5;
v2.c_cc[6] = 1;
if ( (v0 = tcsetattr(0, 0, &v2)) != 0 )
return (unsigned int)-1;
setvbuf(stdout, 0LL, 2, 0LL);
return v0;
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int v0; // er12
struct termios v2; // [rsp+0h] [rbp-48h] BYREF

if ( tcgetattr(0, &v2) )
return (unsigned int)-1;
v2.c_lflag &= 0xFFFFFFB5;
v2.c_cc[6] = 1;
if ( (v0 = tcsetattr(0, 0, &v2)) != 0 )
return (unsigned int)-1;
setvbuf(stdout, 0LL, 2, 0LL);
return v0;
}

original_code:
int tty_configure_control_tty(void) {
 struct termios termstate;
 if (tcgetattr(0, &termstate))
  return -1;
 termstate.c_lflag &= ~(0000002 | 0000010 | 0000100);
 termstate.c_cc[6] = 1;
 if (tcsetattr(0, 0, &termstate))
     return -1;
 setvbuf(stdout, ((void *)0), 2, 0);
 return 0;
}

canonical_original_code:
int tty_configure_control_tty() {
 struct termios termstate;
 if (tcgetattr(0, &termstate))
  return -1;
 termstate.c_lflag &= ~(0000002 | 0000010 | 0000100);
 termstate.c_cc[6] = 1;
 if (tcsetattr(0, 0, &termstate))
     return -1;
 setvbuf(stdout, ((void *)0), 2, 0);
 return 0;
}

variable_types: struct termios { unsigned int c_iflag; unsigned int c_oflag; unsigned int c_cflag; unsigned int c_lflag; unsigned char c_line; unsigned char c_cc[32]; unsigned int c_ispeed; unsigned int c_ospeed; }

return_type: int


decompiled_code:
__int64 __fastcall tty_set_winsize(int a1, unsigned int a2, unsigned int a3)
{
unsigned int v4; // eax
unsigned int v5; // er12
__int16 v7[2]; // [rsp+8h] [rbp-20h] BYREF
int v8; // [rsp+Ch] [rbp-1Ch]

v7[0] = a2;
v7[1] = a3;
v8 = 0;
v4 = ioctl(a1, 0x5414uLL, v7);
v5 = v4;
if ( *((int *)&cmd_options + 1) > 1 )
fprintf(stderr, "Setting winsize to %d x %d: %d\n", a2, a3, v4);
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1, unsigned int a2, unsigned int a3)
{
unsigned int v4; // eax
unsigned int v5; // er12
__int16 v7[2]; // [rsp+8h] [rbp-20h] BYREF
int v8; // [rsp+Ch] [rbp-1Ch]

v7[0] = a2;
v7[1] = a3;
v8 = 0;
v4 = ioctl(a1, 0x5414uLL, v7);
v5 = v4;
if ( *((int *)&cmd_options + 1) > 1 )
fprintf(stderr, "Setting winsize to %d x %d: %d\n", a2, a3, v4);
return v5;
}

original_code:
int tty_set_winsize(int fd, int rows, int cols) {
 int result;
 struct winsize size = {rows, cols, 0, 0};
 result = ioctl(fd, 0x5414, &size);
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "Setting winsize to %d x %d: %d" "\n", rows, cols, result); } while (0);
 return result;
}

variable_types: fd int

variable_types: rows int

variable_types: cols int

variable_types: struct winsize { unsigned short ws_row; unsigned short ws_col; unsigned short ws_xpixel; unsigned short ws_ypixel; }


decompiled_code:
__int64 __fastcall tty_get_winsize(int a1)
{
int *v2; // rax
__int64 v3; // [rsp+8h] [rbp-10h] BYREF

if ( !ioctl(a1, 0x5413uLL, &v3) || *((int *)&cmd_options + 1) <= 0 )
return v3;
v2 = _errno_location();
fprintf(stderr, "Unable to get window size %d\n", (unsigned int)*v2);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1)
{
int *v2; // rax
__int64 v3; // [rsp+8h] [rbp-10h] BYREF

if ( !ioctl(a1, 0x5413uLL, &v3) || *((int *)&cmd_options + 1) <= 0 )
return v3;
v2 = _errno_location();
fprintf(stderr, "Unable to get window size %d\n", (unsigned int)*v2);
return v3;
}

original_code:
struct winsize tty_get_winsize(int fd) {
 int result;
 struct winsize size;
 result = ioctl(fd, 0x5413, &size);
 if (result != 0)
  do { if (cmd_options.verbose >= 1) fprintf(stderr, "Unable to get window size %d" "\n", (*__errno_location ())); } while (0);
 return size;
}

return_type: struct winsize { unsigned short ws_row; unsigned short ws_col; unsigned short ws_xpixel; unsigned short ws_ypixel; }


usage

decompiled_code:
int usage()
{
puts("tachyon [-hHpqv] [-s shell] [-n name]");
puts("\t-h --help - Display this message");
puts("\t-p --predictor - Turn on character prediction");
puts("\t-v --verbose - increase log level (multiple allowed)");
puts("\t-s shell --shell=shell - command to run as shell for new buffer");
puts("\t-q --quiet - decrease log level (multiple allowed)");
return puts(" -n --name - Name to use for this session");
}

canonical_decompiled_code:
int func0()
{
puts("tachyon [-hHpqv] [-s shell] [-n name]");
puts("\t-h --help - Display this message");
puts("\t-p --predictor - Turn on character prediction");
puts("\t-v --verbose - increase log level (multiple allowed)");
puts("\t-s shell --shell=shell - command to run as shell for new buffer");
puts("\t-q --quiet - decrease log level (multiple allowed)");
return puts(" -n --name - Name to use for this session");
}

original_code:
static void usage(void) {
 printf("tachyon [-hHpqv] [-s shell] [-n name]\n");
 printf("	-h --help              - Display this message\n");
 printf("	-p --predictor         - Turn on character prediction\n");
 printf("	-v --verbose           - increase log level (multiple allowed)\n");
 printf("	-s shell --shell=shell - command to run as shell for new buffer\n");
 printf("	-q --quiet             - decrease log level (multiple allowed)\n");
 printf("        -n --name              - Name to use for this session\n");
}

canonical_original_code:
static void usage() {
 printf("tachyon [-hHpqv] [-s shell] [-n name]\n");
 printf("	-h --help              - Display this message\n");
 printf("	-p --predictor         - Turn on character prediction\n");
 printf("	-v --verbose           - increase log level (multiple allowed)\n");
 printf("	-s shell --shell=shell - command to run as shell for new buffer\n");
 printf("	-q --quiet             - decrease log level (multiple allowed)\n");
 printf("        -n --name              - Name to use for this session\n");
}


decompiled_code:
__int64 __fastcall process_args(int argc, char **argv)
{
int v2; // eax
__int64 result; // rax

while ( 2 )
{
v2 = getopt_long(argc, argv, "hpqs:vn:", &parameters, 0LL);
if ( v2 == -1 )
return 0LL;
switch ( v2 )
{
case 'h':
usage();
result = 1LL;
break;
case 'n':
strncpy((char *)(unsigned int)((_DWORD)cmd_options + 1032), optarg, 0x80uLL);
continue;
case 'p':
*(_DWORD *)cmd_options = 1;
continue;
case 'q':
--*(_DWORD *)&cmd_options[4];
continue;
case 's':
strncpy((char *)(unsigned int)((_DWORD)cmd_options + 8), optarg, 0x400uLL);
continue;
case 'v':
++*(_DWORD *)&cmd_options[4];
continue;
default:
usage();
result = 2LL;
break;
}
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int argc, char **argv)
{
int v2; // eax
__int64 result; // rax

while ( 2 )
{
v2 = getopt_long(argc, argv, "hpqs:vn:", &parameters, 0LL);
if ( v2 == -1 )
return 0LL;
switch ( v2 )
{
case 'h':
func0();
result = 1LL;
break;
case 'n':
strncpy((char *)(unsigned int)((_DWORD)cmd_options + 1032), optarg, 0x80uLL);
continue;
case 'p':
*(_DWORD *)cmd_options = 1;
continue;
case 'q':
--*(_DWORD *)&cmd_options[4];
continue;
case 's':
strncpy((char *)(unsigned int)((_DWORD)cmd_options + 8), optarg, 0x400uLL);
continue;
case 'v':
++*(_DWORD *)&cmd_options[4];
continue;
default:
func0();
result = 2LL;
break;
}
break;
}
return result;
}

original_code:
static int process_args(int argn, char **args) {
 int flag;
 while ((flag = getopt_long(argn, args, "hpqs:vn:", parameters, ((void *)0))) != -1) {
  switch(flag) {
   case 'p':
    cmd_options.predict = 1;
    break;
   case 'v':
    cmd_options.verbose++;
    break;
   case 'q':
    cmd_options.verbose--;
    break;
   case 's':
    strncpy(cmd_options.new_buf_command, optarg,
     sizeof(cmd_options.new_buf_command));
    break;
   case 'n':
    strncpy(cmd_options.session_name, optarg,
     sizeof(cmd_options.session_name));
    break;
   case 'h':
    usage();
    return 1;
   default:
    usage();
    return 2;
  }
 }
 return 0;
}

variable_types: argn int

variable_types:
args
char **

variable_types: flag int


decompiled_code:
__int64 set_defaults()
{
unsigned int v1; // eax

if ( LOBYTE(cmd_options[2]) || !(unsigned int)get_login_shell_constprop_0() )
{
if ( cmd_options[1] > 1 )
{
fprintf(stderr, "Shell is '%s'\n", (const char *)(unsigned int)((_DWORD)cmd_options + 8));
if ( LOBYTE(cmd_options[258]) )
goto LABEL_7;
}
else if ( LOBYTE(cmd_options[258]) )
{
return 0LL;
}
v1 = getpid();
snprintf((char *)(unsigned int)((_DWORD)cmd_options + 1032), 0x7FuLL, "tachyon-%d", v1);
LABEL_7:
if ( cmd_options[1] > 1 )
fprintf(stderr, "Session name is '%s'\n", (const char *)(unsigned int)((_DWORD)cmd_options + 1032));
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int v1; // eax

if ( LOBYTE(cmd_options[2]) || !(unsigned int)func2() )
{
if ( cmd_options[1] > 1 )
{
fprintf(stderr, "Shell is '%s'\n", (const char *)(unsigned int)((_DWORD)cmd_options + 8));
if ( LOBYTE(cmd_options[258]) )
goto LABEL_7;
}
else if ( LOBYTE(cmd_options[258]) )
{
return 0LL;
}
v1 = getpid();
snprintf((char *)(unsigned int)((_DWORD)cmd_options + 1032), 0x7FuLL, "tachyon-%d", v1);
LABEL_7:
if ( cmd_options[1] > 1 )
fprintf(stderr, "Session name is '%s'\n", (const char *)(unsigned int)((_DWORD)cmd_options + 1032));
return 0LL;
}
return 1LL;
}

original_code:
static int set_defaults(void) {
 int result;
 if (cmd_options.new_buf_command[0] == '\0') {
  result = get_login_shell(cmd_options.new_buf_command, sizeof(cmd_options.new_buf_command));
  if (result)
   return 1;
 }
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "Shell is '%s'" "\n", cmd_options.new_buf_command); } while (0);
 if (cmd_options.session_name[0] == '\0') {
  snprintf(cmd_options.session_name, sizeof(cmd_options.session_name) - 1, "tachyon-%d",
    getpid());
 }
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "Session name is '%s'" "\n", cmd_options.session_name); } while (0);
 return 0;
}

canonical_original_code:
static int set_defaults() {
 int result;
 if (cmd_options.new_buf_command[0] == '\0') {
  result = get_login_shell(cmd_options.new_buf_command, sizeof(cmd_options.new_buf_command));
  if (result)
   return 1;
 }
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "Shell is '%s'" "\n", cmd_options.new_buf_command); } while (0);
 if (cmd_options.session_name[0] == '\0') {
  snprintf(cmd_options.session_name, sizeof(cmd_options.session_name) - 1, "tachyon-%d",
    getpid());
 }
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "Session name is '%s'" "\n", cmd_options.session_name); } while (0);
 return 0;
}


main

canonical_name: main

decompiled_code:
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // er12
unsigned int v6; // er13
__int64 v7; // rdx
__int64 v8; // rdx
int *v9; // rax

v3 = process_args(argc, (char **)argv);
v4 = v3 - 1;
if ( !v3 )
{
v4 = set_defaults();
if ( v4 )
{
v4 = 1;
}
else
{
tty_save_termstate();
v6 = tty_configure_control_tty();
if ( cmd_options[1] > 1 )
{
v9 = _errno_location();
*(_QWORD *)&argc = stderr;
argv = (const char **)"tty_configure_control_tty %d %d\n";
fprintf(stderr, "tty_configure_control_tty %d %d\n", v6, (unsigned int)*v9);
}
v7 = (unsigned int)loop_init();
if ( cmd_options[1] > 1 )
{
*(_QWORD *)&argc = stderr;
argv = (const char **)"loop_init %d\n";
fprintf(stderr, "loop_init %d\n", v7);
}
v8 = (unsigned int)controller_init(*(_QWORD *)&argc, argv, v7);
if ( cmd_options[1] > 1 )
{
*(_QWORD *)&argc = stderr;
argv = (const char **)"register out %d\n";
fprintf(stderr, "register out %d\n", v8);
}
while ( run )
{
if ( !(unsigned __int8)loop_run(*(_QWORD *)&argc, argv, v8) && cmd_options[1] >= 0 )
{
argv = (const char **)(usage + 1);
*(_QWORD *)&argc = "Running the loop failed\n";
fwrite("Running the loop failed\n", 1uLL, 0x18uLL, stderr);
}
}
tty_restore_termstate(*(_QWORD *)&argc, argv, v8);
}
}
return v4;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // er12
unsigned int v6; // er13
__int64 v7; // rdx
__int64 v8; // rdx
int *v9; // rax

v3 = func1(argc, (char **)argv);
v4 = v3 - 1;
if ( !v3 )
{
v4 = func3();
if ( v4 )
{
v4 = 1;
}
else
{
tty_save_termstate();
v6 = tty_configure_control_tty();
if ( cmd_options[1] > 1 )
{
v9 = _errno_location();
*(_QWORD *)&argc = stderr;
argv = (const char **)"tty_configure_control_tty %d %d\n";
fprintf(stderr, "tty_configure_control_tty %d %d\n", v6, (unsigned int)*v9);
}
v7 = (unsigned int)loop_init();
if ( cmd_options[1] > 1 )
{
*(_QWORD *)&argc = stderr;
argv = (const char **)"loop_init %d\n";
fprintf(stderr, "loop_init %d\n", v7);
}
v8 = (unsigned int)controller_init(*(_QWORD *)&argc, argv, v7);
if ( cmd_options[1] > 1 )
{
*(_QWORD *)&argc = stderr;
argv = (const char **)"register out %d\n";
fprintf(stderr, "register out %d\n", v8);
}
while ( run )
{
if ( !(unsigned __int8)loop_run(*(_QWORD *)&argc, argv, v8) && cmd_options[1] >= 0 )
{
argv = (const char **)(usage + 1);
*(_QWORD *)&argc = "Running the loop failed\n";
fwrite("Running the loop failed\n", 1uLL, 0x18uLL, stderr);
}
}
tty_restore_termstate(*(_QWORD *)&argc, argv, v8);
}
}
return v4;
}

original_code:
int main(int argn, char **args) {
 int result;
 result = process_args(argn, args);
 if (result)
  return result - 1;
 if (set_defaults())
  return 1;
 tty_save_termstate();
 result = tty_configure_control_tty();
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "tty_configure_control_tty %d %d" "\n", result, (*__errno_location ())); } while (0);
 result = loop_init();
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "loop_init %d" "\n", result); } while (0);
 result = controller_init();
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "register out %d" "\n", result); } while (0);
 while (run) {
  if (!loop_run())
   do { if (cmd_options.verbose >= 0) fprintf(stderr, "Running the loop failed" "\n"); } while (0);
 }
 tty_restore_termstate();
 return 0;
}


original_code:
static void signal_handler(int signal, siginfo_t *siginfo, void *context) {
 int save_errno;
 if (signal < 0 || signal > (64 + 1))
  return;
 if (signal_callbacks[signal].handler) {
  signal_callbacks[signal].num_calls++;
  signal_callbacks[signal].siginfo = *siginfo;
 }
 save_errno = (*__errno_location ());
 write(signal_fd.write_fd, "1", 1);
 (*__errno_location ()) = save_errno;
}

canonical_original_code:
static void signal_handler(int signal, struct siginfo_t *siginfo, void *context) {
 int save_errno;
 if (signal < 0 || signal > (64 + 1))
  return;
 if (signal_callbacks[signal].handler) {
  signal_callbacks[signal].num_calls++;
  signal_callbacks[signal].siginfo = *siginfo;
 }
 save_errno = (*__errno_location ());
 write(signal_fd.write_fd, "1", 1);
 (*__errno_location ()) = save_errno;
}

variable_types: signal int

variable_types: struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval { int sival_int; void *sival_ptr; } si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; } *

variable_types:
context
void *

user_defined_types: struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; }


decompiled_code:
int __fastcall process_signals(int *a1)
{
unsigned int v1; // ebp
__int128 *v2; // rbx
__int64 (__fastcall *v3)(__int128 *, __int64); // rax
__int64 v4; // rsi
int v5; // edx
__int64 v6; // rdx
char buf[28]; // [rsp+Ch] [rbp-1Ch] BYREF

if ( *((int *)&cmd_options + 1) > 1 )
fwrite("Received signal\n", 1uLL, 0x10uLL, stderr);
v1 = 0;
v2 = xmmword_5C8;
LODWORD(v3) = read(*a1, buf, 4uLL);
do
{
while ( 1 )
{
v4 = *((unsigned int *)v2 + 32);
if ( (int)v4 > 0 )
{
v3 = (__int64 (__fastcall *)(__int128 *, __int64))*((_QWORD *)v2 - 1);
v5 = *((_DWORD *)&cmd_options + 1);
if ( v3 )
{
if ( v5 > 1 )
{
fprintf(stderr, "Received signal %d %d times: Handling\n", v1, (unsigned int)v4);
v3 = (__int64 (__fastcall *)(__int128 *, __int64))*((_QWORD *)v2 - 1);
v4 = *((unsigned int *)v2 + 32);
}
LODWORD(v3) = v3(v2, v4);
*((_DWORD *)v2 + 32) = 0;
goto LABEL_7;
}
if ( v5 > 1 )
break;
}
LABEL_7:
++v1;
v2 += 9;
if ( v1 == 66 )
return (int)v3;
}
v6 = v1++;
v2 += 9;
LODWORD(v3) = fprintf(stderr, "Received signal %d %d times: Ignoring\n", v6, (unsigned int)v4);
}
while ( v1 != 66 );
return (int)v3;
}

canonical_decompiled_code:
int __fastcall func1(int *a1)
{
unsigned int v1; // ebp
__int128 *v2; // rbx
__int64 (__fastcall *v3)(__int128 *, __int64); // rax
__int64 v4; // rsi
int v5; // edx
__int64 v6; // rdx
char buf[28]; // [rsp+Ch] [rbp-1Ch] BYREF

if ( *((int *)&cmd_options + 1) > 1 )
fwrite("Received signal\n", 1uLL, 0x10uLL, stderr);
v1 = 0;
v2 = xmmword_5C8;
LODWORD(v3) = read(*a1, buf, 4uLL);
do
{
while ( 1 )
{
v4 = *((unsigned int *)v2 + 32);
if ( (int)v4 > 0 )
{
v3 = (__int64 (__fastcall *)(__int128 *, __int64))*((_QWORD *)v2 - 1);
v5 = *((_DWORD *)&cmd_options + 1);
if ( v3 )
{
if ( v5 > 1 )
{
fprintf(stderr, "Received signal %d %d times: Handling\n", v1, (unsigned int)v4);
v3 = (__int64 (__fastcall *)(__int128 *, __int64))*((_QWORD *)v2 - 1);
v4 = *((unsigned int *)v2 + 32);
}
LODWORD(v3) = v3(v2, v4);
*((_DWORD *)v2 + 32) = 0;
goto LABEL_7;
}
if ( v5 > 1 )
break;
}
LABEL_7:
++v1;
v2 += 9;
if ( v1 == 66 )
return (int)v3;
}
v6 = v1++;
v2 += 9;
LODWORD(v3) = fprintf(stderr, "Received signal %d %d times: Ignoring\n", v6, (unsigned int)v4);
}
while ( v1 != 66 );
return (int)v3;
}

original_code:
static void process_signals(struct loop_fd *fd, int revents) {
 struct signal_fd *signal = (struct signal_fd *)fd;
 char buf[4];
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "Received signal" "\n"); } while (0);
 read(signal->fd.fd, buf, sizeof(buf));
 for (int i = 0; i <= (64 + 1); i++) {
  if (signal_callbacks[i].num_calls > 0) {
   if (signal_callbacks[i].handler) {
    do { if (cmd_options.verbose >= 2) fprintf(stderr, "Received signal %d %d times: Handling" "\n", i, signal_callbacks[i].num_calls); } while (0);
    signal_callbacks[i].handler(&signal_callbacks[i].siginfo,
           signal_callbacks[i].num_calls);
    signal_callbacks[i].num_calls = 0;
   } else {
    do { if (cmd_options.verbose >= 2) fprintf(stderr, "Received signal %d %d times: Ignoring" "\n", i, signal_callbacks[i].num_calls); } while (0);
   }
  }
 }
}

variable_types: struct loop_fd { int fd; int poll_flags; void (*poll_callback)(struct loop_fd *fd, int revents); } *

variable_types: revents int

variable_types: struct signal_fd { struct loop_fd { int fd; int poll_flags; void (*poll_callback)(struct loop_fd *fd, int revents); } fd; int write_fd; _Bool received_sigwinch; } *

variable_types:
buf
char [4]

user_defined_types: struct signal_fd { struct loop_fd fd; int write_fd; _Bool received_sigwinch; }


decompiled_code:
__int64 __fastcall loop_register(int *a1)
{
__int64 v1; // rbx
__int64 v2; // r12
_QWORD *v3; // r14
char *v4; // r15
int v5; // edx
char *v6; // rax
int v8; // er13
size_t v9; // r15
char *v10; // rax
size_t v11; // r12
void *v12; // [rsp+0h] [rbp-48h]
void *ptr; // [rsp+8h] [rbp-40h]

v1 = num_loop_items;
v2 = max_loop_items;
if ( num_loop_items < max_loop_items )
{
v3 = loop_items;
v4 = (char *)fds;
LABEL_3:
v5 = *a1;
v3[v1] = a1;
num_loop_items = v1 + 1;
v6 = &v4[8 * v1];
*(_DWORD *)v6 = v5;
*((_WORD *)v6 + 2) = a1[1];
return 0LL;
}
if ( max_loop_items )
{
v8 = 2 * max_loop_items;
v9 = 2 * max_loop_items;
}
else
{
v9 = 16LL;
v8 = 16;
}
v3 = calloc(v9, 8uLL);
v10 = (char *)calloc(v9, 8uLL);
v4 = v10;
if ( v3 )
{
if ( v10 )
{
v11 = 8 * v2;
ptr = loop_items;
memmove(v3, loop_items, v11);
v12 = fds;
memmove(v4, fds, v11);
free(ptr);
loop_items = v3;
free(v12);
fds = v4;
max_loop_items = v8;
goto LABEL_3;
}
free(v3);
}
if ( v4 )
free(v4);
return 12LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(int *a1)
{
__int64 v1; // rbx
__int64 v2; // r12
_QWORD *v3; // r14
char *v4; // r15
int v5; // edx
char *v6; // rax
int v8; // er13
size_t v9; // r15
char *v10; // rax
size_t v11; // r12
void *v12; // [rsp+0h] [rbp-48h]
void *ptr; // [rsp+8h] [rbp-40h]

v1 = num_loop_items;
v2 = max_loop_items;
if ( num_loop_items < max_loop_items )
{
v3 = loop_items;
v4 = (char *)fds;
LABEL_3:
v5 = *a1;
v3[v1] = a1;
num_loop_items = v1 + 1;
v6 = &v4[8 * v1];
*(_DWORD *)v6 = v5;
*((_WORD *)v6 + 2) = a1[1];
return 0LL;
}
if ( max_loop_items )
{
v8 = 2 * max_loop_items;
v9 = 2 * max_loop_items;
}
else
{
v9 = 16LL;
v8 = 16;
}
v3 = calloc(v9, 8uLL);
v10 = (char *)calloc(v9, 8uLL);
v4 = v10;
if ( v3 )
{
if ( v10 )
{
v11 = 8 * v2;
ptr = loop_items;
memmove(v3, loop_items, v11);
v12 = fds;
memmove(v4, fds, v11);
free(ptr);
loop_items = v3;
free(v12);
fds = v4;
max_loop_items = v8;
goto LABEL_3;
}
free(v3);
}
if ( v4 )
free(v4);
return 12LL;
}

original_code:
int loop_register(struct loop_fd *fd) {
 int i;
 if (num_loop_items >= max_loop_items) {
  struct loop_item *new_items = ((void *)0);
  struct pollfd *new_fds = ((void *)0);
  int new_size;
  if (max_loop_items == 0)
   new_size = 16;
  else
   new_size = 2 * max_loop_items;
  new_items = calloc(new_size, sizeof(*loop_items));
  new_fds = calloc(new_size, sizeof(*loop_items));
  if (!new_items || !new_fds) {
   if (new_items)
    free(new_items);
   if (new_fds)
    free(new_fds);
   return 12;
  }
  memmove(new_items, loop_items, max_loop_items * sizeof(*loop_items));
  memmove(new_fds, fds, max_loop_items * sizeof(*fds));
  free(loop_items);
  loop_items = new_items;
  free(fds);
  fds = new_fds;
  max_loop_items = new_size;
 }
 i = num_loop_items++;
 loop_items[i].fd = fd;
 fds[i].fd = fd->fd;
 fds[i].events = fd->poll_flags;
 return 0;
}

variable_types: i int

variable_types: struct loop_item { struct loop_fd { int fd; int poll_flags; void (*poll_callback)(struct loop_fd *fd, int revents); } *fd; } *

variable_types: struct pollfd { int fd; short events; short revents; } *

user_defined_types: struct loop_item { struct loop_fd *fd; }


decompiled_code:
__int64 init_signals()
{
unsigned int v0; // er12
unsigned int v1; // er12
int *v3; // rax
int *v4; // rax
int pipedes[2]; // [rsp+8h] [rbp-B0h] BYREF
struct sigaction v6; // [rsp+10h] [rbp-A8h] BYREF

if ( pipe(pipedes) == -1 )
{
v1 = 32;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v4 = _errno_location();
fprintf(stderr, "Unable to create signal pipe %d\n", (unsigned int)*v4);
}
}
else
{
close_on_exec((unsigned int)pipedes[0]);
close_on_exec((unsigned int)pipedes[1]);
dword_2AE4 = 1;
signal_fd = pipedes[0];
qword_2AE8 = (__int64)process_signals;
fd = pipedes[1];
memset(&v6.sa_mask, 0, 0x90uLL);
v6.sa_handler = (__sighandler_t)signal_handler;
v6.sa_flags = 268435460;
v0 = sigaction(28, &v6, 0LL);
if ( *((int *)&cmd_options + 1) > 1 )
{
v3 = _errno_location();
fprintf(stderr, "sigaction returned %d %d\n", v0, (unsigned int)*v3);
}
v1 = loop_register(&signal_fd);
if ( v1 )
v1 = 12;
}
return v1;
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int v0; // er12
unsigned int v1; // er12
int *v3; // rax
int *v4; // rax
int pipedes[2]; // [rsp+8h] [rbp-B0h] BYREF
struct sigaction v6; // [rsp+10h] [rbp-A8h] BYREF

if ( pipe(pipedes) == -1 )
{
v1 = 32;
if ( *((int *)&cmd_options + 1) >= 0 )
{
v4 = _errno_location();
fprintf(stderr, "Unable to create signal pipe %d\n", (unsigned int)*v4);
}
}
else
{
close_on_exec((unsigned int)pipedes[0]);
close_on_exec((unsigned int)pipedes[1]);
dword_2AE4 = 1;
signal_fd = pipedes[0];
qword_2AE8 = (__int64)process_signals;
fd = pipedes[1];
memset(&v6.sa_mask, 0, 0x90uLL);
v6.sa_handler = (__sighandler_t)signal_handler;
v6.sa_flags = 268435460;
v0 = sigaction(28, &v6, 0LL);
if ( *((int *)&cmd_options + 1) > 1 )
{
v3 = _errno_location();
fprintf(stderr, "sigaction returned %d %d\n", v0, (unsigned int)*v3);
}
v1 = func2(&signal_fd);
if ( v1 )
v1 = 12;
}
return v1;
}

original_code:
static int init_signals(void) {
 int pipes[2];
 int result;
 struct sigaction sig;
 result = pipe(pipes);
 if (result == -1) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "Unable to create signal pipe %d" "\n", (*__errno_location ())); } while (0);
  return 32;
 }
 close_on_exec(pipes[0]);
 close_on_exec(pipes[1]);
 signal_fd.fd.fd = pipes[0];
 signal_fd.write_fd = pipes[1];
 signal_fd.fd.poll_flags = 0x001;
 signal_fd.fd.poll_callback = process_signals;
 memset(&sig, 0, sizeof(sig));
 sig.__sigaction_handler.sa_sigaction = signal_handler;
 sig.sa_flags = 4 | 0x10000000;
 result = sigaction(28, &sig, ((void *)0));
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "sigaction returned %d %d" "\n", result, (*__errno_location ())); } while (0);
 result = loop_register((struct loop_fd *)&signal_fd);
 if (result)
  return 12;
 return 0;
}

canonical_original_code:
static int init_signals() {
 int pipes[2];
 int result;
 struct sigaction sig;
 result = pipe(pipes);
 if (result == -1) {
  do { if (cmd_options.verbose >= 0) fprintf(stderr, "Unable to create signal pipe %d" "\n", (*__errno_location ())); } while (0);
  return 32;
 }
 close_on_exec(pipes[0]);
 close_on_exec(pipes[1]);
 signal_fd.fd.fd = pipes[0];
 signal_fd.write_fd = pipes[1];
 signal_fd.fd.poll_flags = 0x001;
 signal_fd.fd.poll_callback = process_signals;
 memset(&sig, 0, sizeof(sig));
 sig.__sigaction_handler.sa_sigaction = signal_handler;
 sig.sa_flags = 4 | 0x10000000;
 result = sigaction(28, &sig, ((void *)0));
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "sigaction returned %d %d" "\n", result, (*__errno_location ())); } while (0);
 result = loop_register((struct loop_fd *)&signal_fd);
 if (result)
  return 12;
 return 0;
}

variable_types:
pipes
int [2]

variable_types: result int

variable_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval { int sival_int; void *sival_ptr; } si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; } *, void *); } __sigaction_handler; struct __sigset_t { unsigned long __val[-1]; } sa_mask; int sa_flags; void (*sa_restorer)(); }

user_defined_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t *, void *); } __sigaction_handler; struct __sigset_t sa_mask; int sa_flags; void (*sa_restorer)(); }

user_defined_types: struct loop_fd { int fd; int poll_flags; void (*poll_callback)(struct loop_fd *fd, int revents); }


decompiled_code:
__int64 __fastcall loop_deregister(__int64 a1)
{
__int64 v1; // rax
int v2; // edx
_QWORD *v3; // r8
__int64 v4; // rdx
__int64 v5; // rdx
__int64 v6; // rcx

if ( num_loop_items <= 0 )
{
v3 = loop_items;
v1 = 0LL;
}
else
{
v1 = 0LL;
v2 = 0;
while ( 1 )
{
v3 = (char *)loop_items + v1;
if ( *(_QWORD *)((char *)loop_items + v1) == a1 )
break;
++v2;
v1 += 8LL;
if ( num_loop_items == v2 )
{
v4 = num_loop_items;
v1 = 8LL * num_loop_items;
v3 = (char *)loop_items + v1;
goto LABEL_6;
}
}
}
v4 = num_loop_items;
LABEL_6:
v5 = 8 * v4;
v6 = *(_QWORD *)((char *)loop_items + v5 - 8);
--num_loop_items;
*v3 = v6;
*(_QWORD *)((char *)fds + v1) = *(_QWORD *)((char *)fds + v5 - 8);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
__int64 v1; // rax
int v2; // edx
_QWORD *v3; // r8
__int64 v4; // rdx
__int64 v5; // rdx
__int64 v6; // rcx

if ( num_loop_items <= 0 )
{
v3 = loop_items;
v1 = 0LL;
}
else
{
v1 = 0LL;
v2 = 0;
while ( 1 )
{
v3 = (char *)loop_items + v1;
if ( *(_QWORD *)((char *)loop_items + v1) == a1 )
break;
++v2;
v1 += 8LL;
if ( num_loop_items == v2 )
{
v4 = num_loop_items;
v1 = 8LL * num_loop_items;
v3 = (char *)loop_items + v1;
goto LABEL_6;
}
}
}
v4 = num_loop_items;
LABEL_6:
v5 = 8 * v4;
v6 = *(_QWORD *)((char *)loop_items + v5 - 8);
--num_loop_items;
*v3 = v6;
*(_QWORD *)((char *)fds + v1) = *(_QWORD *)((char *)fds + v5 - 8);
return 0LL;
}

original_code:
int loop_deregister(struct loop_fd *fd) {
 int i;
 for (i = 0; i < num_loop_items; i++)
  if (loop_items[i].fd == fd)
   break;
 memmove(&loop_items[i], &loop_items[num_loop_items - 1], sizeof(*loop_items));
 memmove(&fds[i], &fds[num_loop_items - 1], sizeof(*fds));
 num_loop_items--;
 return 0;
}


decompiled_code:
// attributes: thunk
__int64 loop_init()
{
return init_signals();
}

canonical_decompiled_code:
__int64 func6()
{
return func3();
}

original_code:
int loop_init(void) {
 int result;
 result = init_signals();
 return result;
}

canonical_original_code:
int loop_init() {
 int result;
 result = init_signals();
 return result;
}


decompiled_code:
__int64 loop_run()
{
__int64 v0; // rsi
_WORD *v1; // rdi
unsigned __int64 v2; // rcx
__int64 v3; // rax
int v4; // er12
__int64 i; // r12
void (*v6)(void); // rax
unsigned int v7; // er13

v0 = num_loop_items;
v1 = fds;
v2 = (unsigned __int64)loop_items;
if ( num_loop_items > 0 )
{
v3 = 0LL;
do
{
v1[4 * v3 + 2] = *(_DWORD *)(*(_QWORD *)(v2 + 8 * v3) + 4LL);
++v3;
}
while ( v0 != v3 );
}
while ( 1 )
{
v4 = pal_poll(v1, v0, 0xFFFFFFFFLL, v2);
if ( v4 > 0 )
{
for ( i = 0LL; num_loop_items > (int)i; ++i )
{
if ( *((_WORD *)fds + 4 * i + 3) )
{
v6 = *(void (**)(void))(*((_QWORD *)loop_items + i) + 8LL);
if ( v6 )
v6();
}
}
return 1;
}
v2 = (unsigned int)*_errno_location();
if ( (_DWORD)v2 != 4 )
break;
v1 = fds;
v0 = num_loop_items;
}
v7 = 0;
if ( *((int *)&cmd_options + 1) <= 0 )
return v7;
fprintf(stderr, "poll failed %d %d\n", (unsigned int)v4, v2);
return 0LL;
}

canonical_decompiled_code:
__int64 func7()
{
__int64 v0; // rsi
_WORD *v1; // rdi
unsigned __int64 v2; // rcx
__int64 v3; // rax
int v4; // er12
__int64 i; // r12
void (*v6)(void); // rax
unsigned int v7; // er13

v0 = num_loop_items;
v1 = fds;
v2 = (unsigned __int64)loop_items;
if ( num_loop_items > 0 )
{
v3 = 0LL;
do
{
v1[4 * v3 + 2] = *(_DWORD *)(*(_QWORD *)(v2 + 8 * v3) + 4LL);
++v3;
}
while ( v0 != v3 );
}
while ( 1 )
{
v4 = pal_poll(v1, v0, 0xFFFFFFFFLL, v2);
if ( v4 > 0 )
{
for ( i = 0LL; num_loop_items > (int)i; ++i )
{
if ( *((_WORD *)fds + 4 * i + 3) )
{
v6 = *(void (**)(void))(*((_QWORD *)loop_items + i) + 8LL);
if ( v6 )
v6();
}
}
return 1;
}
v2 = (unsigned int)*_errno_location();
if ( (_DWORD)v2 != 4 )
break;
v1 = fds;
v0 = num_loop_items;
}
v7 = 0;
if ( *((int *)&cmd_options + 1) <= 0 )
return v7;
fprintf(stderr, "poll failed %d %d\n", (unsigned int)v4, v2);
return 0LL;
}

original_code:
_Bool loop_run(void) {
 int result;
 int i;
 for (i = 0; i < num_loop_items; i++)
  fds[i].events = loop_items[i].fd->poll_flags;
poll:
 result = pal_poll(fds, num_loop_items, -1);
 if (result <= 0) {
  if ((*__errno_location ()) == 4) {
   goto poll;
  }
  do { if (cmd_options.verbose >= 1) fprintf(stderr, "poll failed %d %d" "\n", result, (*__errno_location ())); } while (0);
  return 0;
 }
 for (i = 0; i < num_loop_items; i++) {
  if (fds[i].revents && loop_items[i].fd->poll_callback) {
   loop_items[i].fd->poll_callback(loop_items[i].fd, fds[i].revents);
  }
 }
 return 1;
}

canonical_original_code:
_Bool loop_run() {
 int result;
 int i;
 for (i = 0; i < num_loop_items; i++)
  fds[i].events = loop_items[i].fd->poll_flags;
poll:
 result = pal_poll(fds, num_loop_items, -1);
 if (result <= 0) {
  if ((*__errno_location ()) == 4) {
   goto poll;
  }
  do { if (cmd_options.verbose >= 1) fprintf(stderr, "poll failed %d %d" "\n", result, (*__errno_location ())); } while (0);
  return 0;
 }
 for (i = 0; i < num_loop_items; i++) {
  if (fds[i].revents && loop_items[i].fd->poll_callback) {
   loop_items[i].fd->poll_callback(loop_items[i].fd, fds[i].revents);
  }
 }
 return 1;
}


decompiled_code:
unsigned __int64 __fastcall predictor_output_guess(int *a1, __int64 a2, unsigned int a3, const void *a4)
{
int v6; // ecx
int v7; // er14
int v8; // edx
int v9; // eax
unsigned __int64 result; // rax

v6 = *a1;
v7 = a1[2];
if ( *a1 > 1000000 )
{
v8 = a1[1];
v6 >>= 1;
*a1 = v6;
v9 = v8 / 2;
a1[1] = v8 / 2;
goto LABEL_3;
}
if ( v6 )
{
v9 = a1[1];
LABEL_3:
result = (unsigned int)(100 * v9 / v6);
if ( (int)result <= 69 )
return result;
}
result = 128LL - v7;
if ( result >= (int)a3 )
{
memcpy((char *)a1 + v7 + 12, a4, (int)a3);
a1[2] += a3;
result = buffer_input(a2, a3, a4);
if ( (_DWORD)result )
a1[2] = v7;
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func0(int *a1, __int64 a2, unsigned int a3, const void *a4)
{
int v6; // ecx
int v7; // er14
int v8; // edx
int v9; // eax
unsigned __int64 result; // rax

v6 = *a1;
v7 = a1[2];
if ( *a1 > 1000000 )
{
v8 = a1[1];
v6 >>= 1;
*a1 = v6;
v9 = v8 / 2;
a1[1] = v8 / 2;
goto LABEL_3;
}
if ( v6 )
{
v9 = a1[1];
LABEL_3:
result = (unsigned int)(100 * v9 / v6);
if ( (int)result <= 69 )
return result;
}
result = 128LL - v7;
if ( result >= (int)a3 )
{
memcpy((char *)a1 + v7 + 12, a4, (int)a3);
a1[2] += a3;
result = buffer_input(a2, a3, a4);
if ( (_DWORD)result )
a1[2] = v7;
}
return result;
}

original_code:
static void predictor_output_guess(struct predictor *predictor, struct buffer *buffer, int size, char *input) {
 int old_history_used;
 _Bool predict;
 int result;
 old_history_used = predictor->history_used;
 if (predictor->num_chars > 1000000) {
  predictor->num_chars /= 2;
  predictor->num_echoed /= 2;
 }
 if (predictor->num_chars == 0)
  predict = 1;
 else
  predict = (predictor->num_echoed * 100) / predictor->num_chars
   >= 70;
 if (predict && sizeof(predictor->history) - predictor->history_used >= size) {
  memcpy(predictor->history + predictor->history_used,
         input, size);
  predictor->history_used += size;
  result = buffer_input(buffer, size, input);
  if (result != 0) {
   predictor->history_used = old_history_used;
  }
 }
}

variable_types: struct predictor { int num_chars; int num_echoed; int history_used; char history[128]; } *

variable_types: struct buffer { struct loop_fd { int fd; int poll_flags; void (*poll_callback)(struct loop_fd *fd, int revents); } fd; struct predictor predictor; int bufid; int buf_out_used; char buf_out[1024]; struct vt { int vt_mode; unsigned short rows; unsigned short cols; struct vt_cursor_mode { unsigned short row; unsigned short col; unsigned long flags; struct { unsigned int data[-1]; } tabstops; } current; struct vt_cursor_mode saved; char window_title[128]; char icon_name[128]; unsigned int flags; struct vt_line { struct vt_line *next; unsigned short len; struct vt_cell { char c; unsigned long flags; } cells[]; } *topmost; struct vt_line *bottommost; struct vt_line **lines; struct { char chars[128]; unsigned short len; } params; } vt; } *

variable_types: size int

variable_types:
input
char *

user_defined_types: struct buffer { struct loop_fd fd; struct predictor predictor; int bufid; int buf_out_used; char buf_out[1024]; struct vt vt; }

user_defined_types: struct vt { int vt_mode; unsigned short rows; unsigned short cols; struct vt_cursor_mode current; struct vt_cursor_mode saved; char window_title[128]; char icon_name[128]; unsigned int flags; struct vt_line *topmost; struct vt_line *bottommost; struct vt_line **lines; struct { char chars[128]; unsigned short len; } params; }

user_defined_types: struct vt_line { struct vt_line *next; unsigned short len; struct vt_cell cells[]; }


decompiled_code:
__int64 __fastcall predictor_init(_QWORD *a1)
{
int v1; // eax
unsigned __int64 v2; // rdi

*a1 = 0LL;
v1 = (int)a1;
v2 = (unsigned __int64)a1 + 20;
*(_QWORD *)(v2 - 8) = 0LL;
*(_QWORD *)(v2 + 112) = 0LL;
*(_DWORD *)(v2 - 12) = 0;
memset((void *)(v2 & 0xFFFFFFFFFFFFFFF8LL), 0, 8 * ((v1 - (v2 & 0xFFFFFFF8) + 140) >> 3));
if ( (_BYTE)backspaces != 8 )
{
backspaces = (__int128)_mm_load_si128((const __m128i *)&LC0);
xmmword_310 = backspaces;
xmmword_320 = backspaces;
xmmword_330 = backspaces;
xmmword_340 = backspaces;
xmmword_350 = backspaces;
xmmword_360 = backspaces;
xmmword_370 = backspaces;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1)
{
int v1; // eax
unsigned __int64 v2; // rdi

*a1 = 0LL;
v1 = (int)a1;
v2 = (unsigned __int64)a1 + 20;
*(_QWORD *)(v2 - 8) = 0LL;
*(_QWORD *)(v2 + 112) = 0LL;
*(_DWORD *)(v2 - 12) = 0;
memset((void *)(v2 & 0xFFFFFFFFFFFFFFF8LL), 0, 8 * ((v1 - (v2 & 0xFFFFFFF8) + 140) >> 3));
if ( (_BYTE)backspaces != 8 )
{
backspaces = (__int128)_mm_load_si128((const __m128i *)&LC0);
xmmword_310 = backspaces;
xmmword_320 = backspaces;
xmmword_330 = backspaces;
xmmword_340 = backspaces;
xmmword_350 = backspaces;
xmmword_360 = backspaces;
xmmword_370 = backspaces;
}
return 0LL;
}

original_code:
int predictor_init(struct predictor *predictor) {
 predictor->num_chars = 0;
 predictor->num_echoed = 0;
 predictor->history_used = 0;
 memset(&predictor->history, 0, sizeof(predictor->history));
 if (backspaces[0] != '\b')
  for (int i = 0; i < sizeof(backspaces); i++)
   backspaces[i] = '\b';
 return 0;
}

user_defined_types: struct predictor { int num_chars; int num_echoed; int history_used; char history[128]; }


decompiled_code:
void predictor_free()
{
;
}

canonical_decompiled_code:
void func2()
{
;
}

original_code:
void predictor_free(struct predictor *predictor) {
 return;
}


decompiled_code:
__int64 __fastcall predictor_output(int *a1, __int64 a2, unsigned int a3, const void *a4, __int64 (__fastcall *a5)(__int64, _QWORD, const void *))
{
if ( !cmd_options )
return a5(a2, a3, a4);
predictor_output_guess(a1, a2, a3, a4);
return a5(a2, a3, a4);
}

canonical_decompiled_code:
__int64 __fastcall func3(int *a1, __int64 a2, unsigned int a3, const void *a4, __int64 (__fastcall *a5)(__int64, _QWORD, const void *))
{
if ( !cmd_options )
return a5(a2, a3, a4);
func0(a1, a2, a3, a4);
return a5(a2, a3, a4);
}

original_code:
int predictor_output(struct predictor *predictor, struct buffer *buffer, int size, char *input,
       int (*outfunc)(struct buffer *buffer, int size, char *buf)) {
 if (cmd_options.predict)
  predictor_output_guess(predictor, buffer, size, input);
 return outfunc(buffer, size, input);
}

variable_types: int (*)(struct buffer *buffer, int size, char *buf)

user_defined_types: struct vt_cursor_mode { unsigned short row; unsigned short col; unsigned long flags; struct { unsigned int data[-1]; } tabstops; }

user_defined_types: struct vt_cell { char c; unsigned long flags; }


original_code:
int predictor_learn(struct predictor *predictor, struct buffer *buffer, int size, char *output) {
 int n;
 int result;
 if (cmd_options.predict) {
  for (n = 0; n < predictor->history_used && n < size; n++) {
   predictor->num_chars++;
   if (output[n] != predictor->history[n])
    break;
   predictor->num_echoed++;
  }
  if (output[n] != predictor->history[n]) {
   predictor->num_chars += ((predictor->history_used - n) < (size - n) ? (predictor->history_used - n) : (size - n));
  }
  buffer_input(buffer, predictor->history_used, backspaces);
 }
 result = buffer_input(buffer, size, output);
 if (cmd_options.predict) {
  predictor->history_used = ((0) > (predictor->history_used - size) ? (0) : (predictor->history_used - size));
  memmove(predictor->history, predictor->history + size, predictor->history_used);
  if (result == 0 && predictor->history_used > 0) {
   buffer_input(buffer, predictor->history_used, predictor->history);
  }
 }
 return result;
}

variable_types:
output
char *

variable_types: n int


decompiled_code:
int __fastcall close_on_exec(int fd)
{
int v1; // eax

v1 = fcntl(fd, 1);
return fcntl(fd, 2, v1 | 1u);
}

canonical_decompiled_code:
int __fastcall func0(int fd)
{
int v1; // eax

v1 = fcntl(fd, 1);
return fcntl(fd, 2, v1 | 1u);
}

original_code:
void close_on_exec(int fd) {
 int flags = fcntl(fd, 1);
 fcntl(fd, 2, flags | 1);
}

variable_types: fd int

variable_types: flags int


decompiled_code:
// attributes: thunk
int pal_poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
return poll(fds, nfds, timeout);
}

canonical_decompiled_code:
int func0(struct pollfd *fds, nfds_t nfds, int timeout)
{
return poll(fds, nfds, timeout);
}

original_code:
int pal_poll(struct pollfd fds[], nfds_t nfds, int timeout) {
 return poll(fds, nfds, timeout);
}

canonical_original_code:
int pal_poll(struct pollfd fds[], unsigned long nfds, int timeout) {
 return poll(fds, nfds, timeout);
}

variable_types: struct pollfd { int fd; short events; short revents; } []

variable_types:
nfds
unsigned long

variable_types: timeout int


decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
__int128 v4; // rax
__int64 v5; // r13
__int64 v6; // rbx
__suseconds_t v7; // rax
__time_t v8; // rdx
__time_t v9; // rcx
__int64 v10; // rdx
int i; // [rsp+Ch] [rbp-1810Ch] BYREF
struct timeval timeout; // [rsp+10h] [rbp-18108h] BYREF
struct timeval tv; // [rsp+20h] [rbp-180F8h] BYREF
struct termios termios_p; // [rsp+30h] [rbp-180E8h] BYREF
fd_set readfds; // [rsp+70h] [rbp-180A8h] BYREF
char buf[8]; // [rsp+F0h] [rbp-18028h] BYREF
struct timeval v17; // [rsp+F8h] [rbp-18020h] BYREF
char src[98320]; // [rsp+108h] [rbp-18010h] BYREF

v3 = 0;
tcgetattr(0, &termios_p);
termios_p.c_lflag &= 0xFFFFFFB5;
termios_p.c_cc[6] = 1;
tcsetattr(0, 0, &termios_p);
setvbuf(_bss_start, 0LL, 2, 0LL);
i = 1;
fcntl(0, 4, &i);
for ( i = 0; ; memmove(buf, src, 24LL * i) )
{
LABEL_2:
if ( !v3 )
{
LABEL_3:
timeout.tv_sec = 10000000LL;
timeout.tv_usec = 0LL;
goto LABEL_4;
}
while ( 1 )
{
gettimeofday(&tv, 0LL);
*((_QWORD *)&v4 + 1) = v17.tv_sec - tv.tv_sec;
*(_QWORD *)&v4 = v17.tv_usec - tv.tv_usec;
timeout.tv_sec = v17.tv_sec - tv.tv_sec;
timeout.tv_usec = v17.tv_usec - tv.tv_usec;
if ( v17.tv_usec - tv.tv_usec < 0 )
{
--*((_QWORD *)&v4 + 1);
*(_QWORD *)&v4 = v4 + 1000000;
timeout.tv_sec = *((_QWORD *)&v4 + 1);
timeout.tv_usec = v4;
}
if ( v4 == 0 )
break;
LABEL_4:
memset(&readfds, 0, sizeof(readfds));
readfds.fds_bits[0] |= 1uLL;
if ( !select(1, &readfds, 0LL, 0LL, &timeout) )
break;
if ( i != 4096 )
{
if ( (unsigned int)read(0, &buf[24 * i], 1uLL) == 1 )
{
v5 = i;
v6 = 24LL * i;
gettimeofday((struct timeval *)((char *)&v17 + v6), 0LL);
v7 = *(__suseconds_t *)((char *)&v17.tv_usec + v6) + 2000000;
*(__suseconds_t *)((char *)&v17.tv_usec + v6) = v7;
if ( v7 > 1000000 )
{
v8 = *(__time_t *)((char *)&v17.tv_sec + v6) + 1;
do
{
v7 -= 1000000LL;
v9 = v8++;
}
while ( v7 > 1000000 );
v10 = 24 * v5;
*(__suseconds_t *)((char *)&v17.tv_usec + v10) = v7;
*(__time_t *)((char *)&v17.tv_sec + v10) = v9;
}
v3 = ++i;
goto LABEL_2;
}
if ( !i )
goto LABEL_3;
}
}
putc(buf[0], _bss_start);
v3 = --i;
}
}

canonical_original_code:
int main(int argn, char **args) {
 int result;
 result = process_args(argn, args);
 if (result)
  return result - 1;
 if (set_defaults())
  return 1;
 tty_save_termstate();
 result = tty_configure_control_tty();
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "tty_configure_control_tty %d %d" "\n", result, (*__errno_location ())); } while (0);
 result = loop_init();
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "loop_init %d" "\n", result); } while (0);
 result = controller_init();
 do { if (cmd_options.verbose >= 2) fprintf(stderr, "register out %d" "\n", result); } while (0);
 while (run) {
  if (!loop_run())
   do { if (cmd_options.verbose >= 0) fprintf(stderr, "Running the loop failed" "\n"); } while (0);
 }
 tty_restore_termstate();
 return 0;
}

variable_types: argn int

variable_types:
args
char **


repo: umbrant/ionice-tester

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er13
const char *v4; // r12
int v5; // eax
char *v6; // rbx
__int64 v7; // r15
pthread_attr_t *v8; // r12
const char *v9; // rax
char *v10; // r14
char *v11; // rcx
const pthread_attr_t *v12; // rsi
pthread_t *v13; // rdi
pthread_t v14; // rdi
int result; // eax
__int64 v16; // [rsp-1C0h] [rbp-300h] BYREF
__int64 *v17; // [rsp+0h] [rbp-140h] BYREF
const char *v18; // [rsp+8h] [rbp-138h]
pthread_t newthread[8]; // [rsp+10h] [rbp-130h] BYREF
char arg[240]; // [rsp+50h] [rbp-F0h] BYREF

v3 = 60;
v4 = 0LL;
while ( 1 )
{
v5 = getopt(argc, (char *const *)argv, "d:o:p");
if ( v5 == -1 )
break;
if ( v5 == 100 )
{
v3 = strtol(optarg, 0LL, 10);
}
else if ( v5 == 111 )
{
v4 = optarg;
}
}
if ( argc - optind == 2 )
{
v18 = argv[optind];
if ( v4 )
{
log = fopen(v4, "w");
if ( log )
{
printf("Using %s for logging\n", v4);
}
else
{
perror("Cannot open log file");
log = (FILE *)stderr;
}
}
else
{
log = (FILE *)stderr;
puts("Defaulting to stderr for logging");
}
v17 = (__int64 *)&v17;
v6 = arg;
v7 = 0LL;
v8 = (pthread_attr_t *)&v16;
do
{
v9 = v18;
*((_DWORD *)v6 + 4) = v7;
v10 = (char *)newthread;
*((_DWORD *)v6 + 2) = v3;
*(_QWORD *)v6 = v9;
*((_DWORD *)v6 + 3) = 0;
pthread_attr_init(v8);
v11 = v6;
v12 = v8;
v13 = &newthread[v7++];
v6 += 24;
++v8;
pthread_create(v13, v12, reader, v11);
}
while ( v7 != 8 );
do
{
v14 = *(_QWORD *)v10;
v10 += 8;
pthread_join(v14, 0LL);
}
while ( v10 != arg );
result = 0;
}
else
{
puts("Usage: ionicer [-d duration] [-o outfile] [-p] scan_file seek_file");
result = 1;
}
return result;
}

original_code:
int main(int argc, char *argv[]) {
  int ret;
  int c;
  int duration = 60;
  int seek_priority = 0;
  char* logfile = ((void *)0);
 while ((c = getopt(argc, argv, "d:o:p")) != (-1)) {
  switch (c) {
  case 'd':
    duration = strtol(optarg, ((void *)0), 10);
    break;
  case 'o':
    logfile = optarg;
    break;
  case 'p':
   seek_priority = 1;
   break;
  }
 }
 char *f1, *f2;
 if(argc - optind == 2) {
   f1 = argv[optind];
   f2 = argv[optind+1];
 }
 else {
   printf("Usage: ionicer [-d duration] [-o outfile] [-p] scan_file seek_file\n");
   return 1;
 }
 if(logfile == ((void *)0)) {
   log = stderr;
    printf("Defaulting to stderr for logging\n");
 } else {
   log = fopen(logfile, "w");
   if(log == ((void *)0)) {
     perror("Cannot open log file");
     log = stderr;
   }
   else {
      printf("Using %s for logging\n", logfile);
   }
 }
  int num_threads = 8;
  pthread_t threads[num_threads];
  pthread_attr_t attrs[num_threads];
  param_t params[num_threads];
  int i;
  for(i=0; i<num_threads; i++) {
    params[i].duration = duration;
    params[i].filename = f1;
    params[i].type = SEEK;
    params[i].priority = i;
    pthread_attr_init(&attrs[i]);
    ret = pthread_create(&threads[i], &attrs[i], reader, (void*)&params[i]);
  }
  for(i=0; i<num_threads; i++) {
    pthread_join(threads[i], ((void *)0));
  }
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  int ret;
  int c;
  int duration = 60;
  int seek_priority = 0;
  char *logfile = ((void *)0);
 while ((c = getopt(argc, argv, "d:o:p")) != (-1)) {
  switch (c) {
  case 'd':
    duration = strtol(optarg, ((void *)0), 10);
    break;
  case 'o':
    logfile = optarg;
    break;
  case 'p':
   seek_priority = 1;
   break;
  }
 }
 char *f1; char *f2;
 if(argc - optind == 2) {
   f1 = argv[optind];
   f2 = argv[optind+1];
 }
 else {
   printf("Usage: ionicer [-d duration] [-o outfile] [-p] scan_file seek_file\n");
   return 1;
 }
 if(logfile == ((void *)0)) {
   log = stderr;
    printf("Defaulting to stderr for logging\n");
 } else {
   log = fopen(logfile, "w");
   if(log == ((void *)0)) {
     perror("Cannot open log file");
     log = stderr;
   }
   else {
      printf("Using %s for logging\n", logfile);
   }
 }
  int num_threads = 8;
  unsigned long threads[-1];
  union pthread_attr_t attrs[-1];
  struct param_t params[-1];
  int i;
  for(i=0; i<num_threads; i++) {
    params[i].duration = duration;
    params[i].filename = f1;
    params[i].type = SEEK;
    params[i].priority = i;
    pthread_attr_init(&attrs[i]);
    ret = pthread_create(&threads[i], &attrs[i], reader, (void *)&params[i]);
  }
  for(i=0; i<num_threads; i++) {
    pthread_join(threads[i], ((void *)0));
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: ret int

variable_types: c int

variable_types: duration int

variable_types:
logfile
char *

variable_types:
threads
unsigned long [-1]

variable_types: union pthread_attr_t { char __size[56]; long __align; } [-1]

variable_types: struct param_t { char *filename; int duration; int type; int priority; } [-1]

variable_types: i int


gettid

decompiled_code:
__int64 gettid()
{
return syscall(186LL);
}

canonical_decompiled_code:
__int64 func7()
{
return syscall(186LL);
}

original_code:
int gettid() {
  return syscall(186);
}

canonical_original_code:
int gettid() {
  return syscall(186);
}


decompiled_code:
void __fastcall set_priority(unsigned int a1)
{
unsigned int v1; // eax
__int64 v2; // rcx
unsigned int v3; // ebp

v1 = gettid();
v2 = a1;
v3 = v1;
BYTE1(v2) = BYTE1(a1) | 0x40;
if ( (int)syscall(251LL, 1LL, v1, v2) < 0 )
{
printf("Error trying to set priority of tid %d\n", v3);
perror("ioprio_set");
}
else
{
printf("Set priority of thread %d to %d\n", v3, a1);
}
}

canonical_decompiled_code:
void __fastcall func8(unsigned int a1)
{
unsigned int v1; // eax
__int64 v2; // rcx
unsigned int v3; // ebp

v1 = func7();
v2 = a1;
v3 = v1;
BYTE1(v2) = BYTE1(a1) | 0x40;
if ( (int)syscall(251LL, 1LL, v1, v2) < 0 )
{
printf("Error trying to set priority of tid %d\n", v3);
perror("ioprio_set");
}
else
{
printf("Set priority of thread %d to %d\n", v3, a1);
}
}

original_code:
void set_priority(int new_prio) {
  int tid = gettid();
  int new_class = IOPRIO_CLASS_BE;
  int ret = syscall(251, IOPRIO_WHO_PROCESS, tid, (new_prio | new_class << 13));
  if(ret < 0) {
    printf("Error trying to set priority of tid %d\n", tid);
    perror("ioprio_set");
  }
  else {
    printf("Set priority of thread %d to %d\n", tid, new_prio);
  }
}

variable_types: tid int


reader

decompiled_code:
void __fastcall reader(void *a1)
{
char *v1; // r12
unsigned int v2; // er14
int v3; // eax
int v4; // ebp
int v5; // eax
int *v6; // rbx
__int64 v7; // rdx
__time_t v8; // r14
__suseconds_t v9; // r15
int v10; // eax
__suseconds_t v11; // r15
int v12; // er14
__int64 v13; // rax
int v14; // eax
__suseconds_t v15; // rax
__suseconds_t v16; // rdx
double v17; // xmm1_8
double v18; // xmm3_8
double v19; // xmm2_8
unsigned int v20; // er13
unsigned int v21; // eax
size_t size; // [rsp+8h] [rbp-130h]
int v23; // [rsp+10h] [rbp-128h]
__int64 v24; // [rsp+10h] [rbp-128h]
int v25; // [rsp+1Ch] [rbp-11Ch]
__suseconds_t v26; // [rsp+20h] [rbp-118h]
__time_t v27; // [rsp+28h] [rbp-110h]
void *memptr; // [rsp+38h] [rbp-100h] BYREF
struct timeval tv; // [rsp+40h] [rbp-F8h] BYREF
struct timeval v30; // [rsp+50h] [rbp-E8h] BYREF
struct timeval v31; // [rsp+60h] [rbp-D8h] BYREF
struct stat stat_buf; // [rsp+70h] [rbp-C8h] BYREF

v2 = gettid();
v3 = open(*(const char **)a1, 0x4000);
if ( v3 == -1 )
{
perror("Reader open");
}
else
{
v4 = v3;
printf("[%d] Reader opened file %s\n", v2, *(const char **)a1);
v5 = *((_DWORD *)a1 + 3);
if ( v5 )
{
if ( v5 == 1 )
{
v6 = &dword_400000;
printf("[%d] Doing random scans\n", v2);
v7 = (__int64)&dword_400000;
}
else
{
v7 = 0LL;
LODWORD(v6) = 0;
}
}
else
{
LODWORD(v6) = 0x10000;
printf("[%d] Doing random reads\n", v2);
v7 = 0x10000LL;
}
size = v7;
set_priority(*((_DWORD *)a1 + 4));
gettimeofday(&tv, 0LL);
v8 = tv.tv_sec;
v9 = tv.tv_usec;
v23 = *((_DWORD *)a1 + 2);
v10 = posix_memalign(&memptr, 0x1000uLL, size);
if ( v10 )
{
if ( v10 < 0 )
{
printf("ERROR with posix_memalign: %d\n", (unsigned int)v10);
return;
}
}
else
{
v1 = (char *)memptr;
}
v27 = 1000000 * v8 + v9;
v26 = v27 + 1000000 * v23;
fstat(v4, &stat_buf);
if ( v27 >= v26 )
{
v19 = 0.0;
v18 = 0.0;
v17 = 0.0;
LABEL_16:
v20 = *((_DWORD *)a1 + 4);
v21 = gettid();
fprintf(
log,
"[%d] Priority: %d, Max latency: %.2f ms, Tput: %.2f KiB/s\n",
v21,
v20,
v18,
v17 * (double)(int)v6 * 0.0009765625 / v19);
free(v1);
close(v4);
}
else
{
v25 = 0;
v11 = 0LL;
v24 = (int)(stat_buf.st_size / (int)v6);
LABEL_9:
v12 = 0;
gettimeofday(&v30, 0LL);
v13 = random();
lseek(v4, v13 % v24 * (int)v6, 0);
while ( 1 )
{
v14 = read(v4, &v1[v12], (int)v6 - v12);
if ( v14 < 0 )
break;
v12 += v14;
if ( (int)v6 <= v12 )
{
gettimeofday(&v31, 0LL);
v15 = v31.tv_usec + 1000000 * v31.tv_sec;
v16 = v30.tv_usec + 1000000 * v30.tv_sec;
if ( v11 < v15 - v16 )
v11 = v31.tv_usec + 1000000 * v31.tv_sec - v16;
++v25;
if ( v26 <= v15 )
{
v17 = (double)v25;
v18 = (double)(int)v11 / 1000.0;
v19 = (double)((int)v15 - (int)v27) / 1000.0 / 1000.0;
goto LABEL_16;
}
goto LABEL_9;
}
}
perror("read");
}
}
}

canonical_decompiled_code:
void __fastcall func9(void *a1)
{
char *v1; // r12
unsigned int v2; // er14
int v3; // eax
int v4; // ebp
int v5; // eax
int *v6; // rbx
__int64 v7; // rdx
__time_t v8; // r14
__suseconds_t v9; // r15
int v10; // eax
__suseconds_t v11; // r15
int v12; // er14
__int64 v13; // rax
int v14; // eax
__suseconds_t v15; // rax
__suseconds_t v16; // rdx
double v17; // xmm1_8
double v18; // xmm3_8
double v19; // xmm2_8
unsigned int v20; // er13
unsigned int v21; // eax
size_t size; // [rsp+8h] [rbp-130h]
int v23; // [rsp+10h] [rbp-128h]
__int64 v24; // [rsp+10h] [rbp-128h]
int v25; // [rsp+1Ch] [rbp-11Ch]
__suseconds_t v26; // [rsp+20h] [rbp-118h]
__time_t v27; // [rsp+28h] [rbp-110h]
void *memptr; // [rsp+38h] [rbp-100h] BYREF
struct timeval tv; // [rsp+40h] [rbp-F8h] BYREF
struct timeval v30; // [rsp+50h] [rbp-E8h] BYREF
struct timeval v31; // [rsp+60h] [rbp-D8h] BYREF
struct stat stat_buf; // [rsp+70h] [rbp-C8h] BYREF

v2 = func7();
v3 = open(*(const char **)a1, 0x4000);
if ( v3 == -1 )
{
perror("Reader open");
}
else
{
v4 = v3;
printf("[%d] Reader opened file %s\n", v2, *(const char **)a1);
v5 = *((_DWORD *)a1 + 3);
if ( v5 )
{
if ( v5 == 1 )
{
v6 = &dword_400000;
printf("[%d] Doing random scans\n", v2);
v7 = (__int64)&dword_400000;
}
else
{
v7 = 0LL;
LODWORD(v6) = 0;
}
}
else
{
LODWORD(v6) = 0x10000;
printf("[%d] Doing random reads\n", v2);
v7 = 0x10000LL;
}
size = v7;
func8(*((_DWORD *)a1 + 4));
gettimeofday(&tv, 0LL);
v8 = tv.tv_sec;
v9 = tv.tv_usec;
v23 = *((_DWORD *)a1 + 2);
v10 = posix_memalign(&memptr, 0x1000uLL, size);
if ( v10 )
{
if ( v10 < 0 )
{
printf("ERROR with posix_memalign: %d\n", (unsigned int)v10);
return;
}
}
else
{
v1 = (char *)memptr;
}
v27 = 1000000 * v8 + v9;
v26 = v27 + 1000000 * v23;
func12(v4, &stat_buf);
if ( v27 >= v26 )
{
v19 = 0.0;
v18 = 0.0;
v17 = 0.0;
LABEL_16:
v20 = *((_DWORD *)a1 + 4);
v21 = func7();
fprintf(
log,
"[%d] Priority: %d, Max latency: %.2f ms, Tput: %.2f KiB/s\n",
v21,
v20,
v18,
v17 * (double)(int)v6 * 0.0009765625 / v19);
free(v1);
close(v4);
}
else
{
v25 = 0;
v11 = 0LL;
v24 = (int)(stat_buf.st_size / (int)v6);
LABEL_9:
v12 = 0;
gettimeofday(&v30, 0LL);
v13 = random();
lseek(v4, v13 % v24 * (int)v6, 0);
while ( 1 )
{
v14 = read(v4, &v1[v12], (int)v6 - v12);
if ( v14 < 0 )
break;
v12 += v14;
if ( (int)v6 <= v12 )
{
gettimeofday(&v31, 0LL);
v15 = v31.tv_usec + 1000000 * v31.tv_sec;
v16 = v30.tv_usec + 1000000 * v30.tv_sec;
if ( v11 < v15 - v16 )
v11 = v31.tv_usec + 1000000 * v31.tv_sec - v16;
++v25;
if ( v26 <= v15 )
{
v17 = (double)v25;
v18 = (double)(int)v11 / 1000.0;
v19 = (double)((int)v15 - (int)v27) / 1000.0 / 1000.0;
goto LABEL_16;
}
goto LABEL_9;
}
}
perror("read");
}
}
}

original_code:
void* reader(void *arg) {
  param_t* params = (param_t*) arg;
  int ret;
  int tid = gettid();
  int fd = open(params->filename, 00|040000);
  if(fd == -1) {
    perror("Reader open");
    return;
  }
  else {
    printf("[%d] Reader opened file %s\n", tid, params->filename);
  }
  int bufsize;
  switch(params->type) {
    case SEEK:
      printf("[%d] Doing random reads\n", tid);
      bufsize = 64*1024;
      break;
    case SCAN:
      printf("[%d] Doing random scans\n", tid);
      bufsize = 4*1024*1024;
      break;
  }
  set_priority(params->priority);
  long start, now, end;
  struct timeval t;
  gettimeofday(&t, ((void *)0));
  start = (1000000*t.tv_sec) + t.tv_usec;
  end = start + (1000000 * params->duration);
  now = start;
  char * buffer;
  ret = posix_memalign((void**)&buffer, 4096, bufsize);
  if(ret < 0) {
    printf("ERROR with posix_memalign: %d\n", ret);
    return;
  }
  int count = 0;
  struct stat st;
  fstat(fd, &st);
  off_t size = st.st_size;
  int blocks = size / bufsize;
  long max_latency = 0;
  while(now < end) {
    struct timeval t1, t2;
    gettimeofday(&t1, ((void *)0));
    long int seek_off = (random()%blocks)*bufsize;
    lseek(fd, seek_off, 0);
    int total = 0;
    while(total < bufsize) {
      int num_bytes = read(fd, buffer+total, bufsize-total);
      if(num_bytes < 0) {
        perror("read");
        return;
      }
      total += num_bytes;
    }
    gettimeofday(&t2, ((void *)0));
    long t1_usec = (1000000 * t1.tv_sec) + t1.tv_usec;
    long t2_usec = (1000000 * t2.tv_sec) + t2.tv_usec;
    long latency = t2_usec - t1_usec;
    if(latency > max_latency) {
        max_latency = latency;
    }
    now = t2_usec;
    count++;
  }
  long finished = now;
  double duration = (double)(finished - start) / 1000.0 / 1000.0;
  double tput = ((double)count * bufsize) / 1024.0 / duration;
  fprintf(log, "[%d] Priority: %d, Max latency: %.2f ms, Tput: %.2f KiB/s\n",
          gettid(), params->priority, (double)max_latency/1000.0, tput);
  free(buffer);
  close(fd);
}

canonical_original_code:
void *reader(void *arg) {
  struct param_t *params = (param_t*) arg;
  int ret;
  int tid = gettid();
  int fd = open(params->filename, 00|040000);
  if(fd == -1) {
    perror("Reader open");
    return;
  }
  else {
    printf("[%d] Reader opened file %s\n", tid, params->filename);
  }
  int bufsize;
  switch(params->type) {
    case SEEK:
      printf("[%d] Doing random reads\n", tid);
      bufsize = 64*1024;
      break;
    case SCAN:
      printf("[%d] Doing random scans\n", tid);
      bufsize = 4*1024*1024;
      break;
  }
  set_priority(params->priority);
  long start; long now; long end;
  struct timeval t;
  gettimeofday(&t, ((void *)0));
  start = (1000000*t.tv_sec) + t.tv_usec;
  end = start + (1000000 * params->duration);
  now = start;
  char *buffer;
  ret = posix_memalign((void **)&buffer, 4096, bufsize);
  if(ret < 0) {
    printf("ERROR with posix_memalign: %d\n", ret);
    return;
  }
  int count = 0;
  struct stat st;
  fstat(fd, &st);
  long size = st.st_size;
  int blocks = size / bufsize;
  long max_latency = 0;
  while(now < end) {
    struct timeval t1; struct timeval t2;
    gettimeofday(&t1, ((void *)0));
    long seek_off = (random()%blocks)*bufsize;
    lseek(fd, seek_off, 0);
    int total = 0;
    while(total < bufsize) {
      int num_bytes = read(fd, buffer+total, bufsize-total);
      if(num_bytes < 0) {
        perror("read");
        return;
      }
      total += num_bytes;
    }
    gettimeofday(&t2, ((void *)0));
    long t1_usec = (1000000 * t1.tv_sec) + t1.tv_usec;
    long t2_usec = (1000000 * t2.tv_sec) + t2.tv_usec;
    long latency = t2_usec - t1_usec;
    if(latency > max_latency) {
        max_latency = latency;
    }
    now = t2_usec;
    count++;
  }
  long finished = now;
  double duration = (double)(finished - start) / 1000.0 / 1000.0;
  double tput = ((double)count * bufsize) / 1024.0 / duration;
  fprintf(log, "[%d] Priority: %d, Max latency: %.2f ms, Tput: %.2f KiB/s\n",
          gettid(), params->priority, (double)max_latency/1000.0, tput);
  free(buffer);
  close(fd);
}

variable_types:
arg
void *

variable_types: struct param_t { char *filename; int duration; int type; int priority; } *

variable_types: fd int

variable_types: bufsize int

variable_types: start long

variable_types: now long

variable_types: end long

variable_types: struct timeval { long tv_sec; long tv_usec; }

variable_types:
buffer
char *

variable_types: count int

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

variable_types: size long

variable_types: blocks int

variable_types: total int

variable_types: latency long

variable_types: finished long

variable_types: duration double

variable_types: tput double

return_type: void *

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


die

repo: vlaadbrain/xkev

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

va_start(arg, format);
vfprintf(stderr, format, arg);
exit(1);
}

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

va_start(arg, format);
vfprintf(stderr, format, arg);
exit(1);
}

original_code:
void
die(const char *errstr, ...) {
 va_list ap;
 __builtin_va_start(ap,errstr);
 vfprintf(stderr, errstr, ap);
 __builtin_va_end(ap);
 exit(1);
}

canonical_original_code:
void die(char *errstr, ...) {
 __builtin_va_list ap;
 __builtin_va_start(ap,errstr);
 vfprintf(stderr, errstr, ap);
 __builtin_va_end(ap);
 exit(1);
}

variable_types:
errstr
char *


usage

decompiled_code:
void __noreturn usage()
{
char *v0; // rax

v0 = __xpg_basename(argv0);
die("usage: %s [-vsScCmMaAuUhH] [-e <key>]\n", v0);
}

canonical_decompiled_code:
void __noreturn func8()
{
char *v0; // rax

v0 = __xpg_basename(argv0);
func7("usage: %s [-vsScCmMaAuUhH] [-e <key>]\n", v0);
}

original_code:
void
usage(void) {
 die("usage: %s [-vsScCmMaAuUhH] [-e <key>]\n", __xpg_basename(argv0));
}

canonical_original_code:
void usage() {
 die("usage: %s [-vsScCmMaAuUhH] [-e <key>]\n", __xpg_basename(argv0));
}


delay

repo: wpwrak/idbg

decompiled_code:
int delay()
{
return fprintf(stderr, "SDA %d SCL %d\n", (unsigned int)I2C_SDA, (unsigned int)I2C_SCL);
}

canonical_decompiled_code:
int func7()
{
return fprintf(stderr, "SDA %d SCL %d\n", (unsigned int)I2C_SDA, (unsigned int)I2C_SCL);
}

original_code:
static void delay(void)
{
 fprintf(stderr, "SDA %d SCL %d\n", I2C_SDA, I2C_SCL);
}

canonical_original_code:
static void delay()
{
 fprintf(stderr, "SDA %d SCL %d\n", I2C_SDA, I2C_SCL);
}


decompiled_code:
void __fastcall i2c_start(char a1, __int64 a2, unsigned __int8 a3, __int64 a4, unsigned __int8 a5)
{
wpos = a2;
wbuf = a2;
rpos = a4;
rbuf = a4;
wend = a3 + a2;
rend = a5 + a4;
fetched = 0;
spos = a1;
state = 2;
}

canonical_decompiled_code:
void __fastcall func9(char a1, __int64 a2, unsigned __int8 a3, __int64 a4, unsigned __int8 a5)
{
wpos = a2;
wbuf = a2;
rpos = a4;
rbuf = a4;
wend = a3 + a2;
rend = a5 + a4;
fetched = 0;
spos = a1;
state = 2;
}

original_code:
void i2c_start(uint8_t s, const uint8_t *wdata, uint8_t wlen,
    uint8_t *rdata, uint8_t rlen)
{
 wbuf = wpos = wdata;
 wend = wbuf+wlen;
 rbuf = rpos = rdata;
 rend = rbuf+rlen;
 fetched = 0;
 spos = s;
 state = START;
}

canonical_original_code:
void i2c_start(unsigned char s, unsigned char *wdata, unsigned char wlen, unsigned char *rdata, unsigned char rlen)
{
 wbuf = wpos = wdata;
 wend = wbuf+wlen;
 rbuf = rpos = rdata;
 rend = rbuf+rlen;
 fetched = 0;
 spos = s;
 state = START;
}

variable_types:
s
unsigned char

variable_types:
wdata
unsigned char *

variable_types:
wlen
unsigned char

variable_types:
rdata
unsigned char *

variable_types:
rlen
unsigned char


decompiled_code:
int i2c_poll()
{
int result; // eax
_BYTE *v1; // rdx
int v2; // ebx
bool v3; // cf
int v4; // ebx
int v5; // ebp
__int64 v6; // rax
bool v7; // zf

result = state;
if ( state == 3 )
{
v1 = (_BYTE *)wpos;
if ( spos && wpos - wbuf == (unsigned __int8)spos )
{
I2C_SDA = 1;
delay();
I2C_SCL = 1;
delay();
result = I2C_SCL;
if ( !I2C_SCL )
return result;
I2C_SDA = 0;
spos = 0;
delay();
I2C_SCL = 0;
delay();
v1 = (_BYTE *)wpos;
}
v2 = 6;
I2C_SDA = *v1 >> 7;
delay();
I2C_SCL = 1;
delay();
I2C_SCL = 0;
do
{
I2C_SDA = ((int)*(unsigned __int8 *)wpos >> v2) & 1;
delay();
I2C_SCL = 1;
delay();
I2C_SCL = 0;
v3 = v2-- == 0;
}
while ( !v3 );
++wpos;
I2C_SDA = 1;
delay();
I2C_SCL = 1;
delay();
I2C_SCL = 0;
I2C_SDA = 0;
delay();
result = wend;
if ( wpos == wend )
{
result = rend;
if ( rpos != rend )
{
state = 4;
return result;
}
state = 0;
I2C_SCL = 1;
delay();
I2C_SDA = 1;
return delay();
}
}
else if ( state == 4 )
{
I2C_SDA = 1;
v4 = 7;
v5 = 0;
do
{
delay();
I2C_SCL = 1;
delay();
I2C_SCL = 0;
v5 |= I2C_SDA << v4;
v3 = v4-- == 0;
}
while ( !v3 );
v6 = rpos + 1;
v7 = rpos + 1 == rend;
*(_BYTE *)rpos = v5;
rpos = v6;
if ( !v7 )
I2C_SDA = 0;
delay();
I2C_SCL = 1;
delay();
result = rend;
I2C_SCL = 0;
if ( rpos == rend )
{
delay();
I2C_SDA = 0;
delay();
I2C_SCL = 1;
delay();
I2C_SDA = 1;
result = delay();
state = 0;
}
}
else if ( state == 2 && I2C_SDA && I2C_SCL )
{
I2C_SDA = 0;
delay();
I2C_SCL = 0;
state = 3;
return delay();
}
return result;
}

canonical_decompiled_code:
int func12()
{
int result; // eax
_BYTE *v1; // rdx
int v2; // ebx
bool v3; // cf
int v4; // ebx
int v5; // ebp
__int64 v6; // rax
bool v7; // zf

result = state;
if ( state == 3 )
{
v1 = (_BYTE *)wpos;
if ( spos && wpos - wbuf == (unsigned __int8)spos )
{
I2C_SDA = 1;
func7();
I2C_SCL = 1;
func7();
result = I2C_SCL;
if ( !I2C_SCL )
return result;
I2C_SDA = 0;
spos = 0;
func7();
I2C_SCL = 0;
func7();
v1 = (_BYTE *)wpos;
}
v2 = 6;
I2C_SDA = *v1 >> 7;
func7();
I2C_SCL = 1;
func7();
I2C_SCL = 0;
do
{
I2C_SDA = ((int)*(unsigned __int8 *)wpos >> v2) & 1;
func7();
I2C_SCL = 1;
func7();
I2C_SCL = 0;
v3 = v2-- == 0;
}
while ( !v3 );
++wpos;
I2C_SDA = 1;
func7();
I2C_SCL = 1;
func7();
I2C_SCL = 0;
I2C_SDA = 0;
func7();
result = wend;
if ( wpos == wend )
{
result = rend;
if ( rpos != rend )
{
state = 4;
return result;
}
state = 0;
I2C_SCL = 1;
func7();
I2C_SDA = 1;
return func7();
}
}
else if ( state == 4 )
{
I2C_SDA = 1;
v4 = 7;
v5 = 0;
do
{
func7();
I2C_SCL = 1;
func7();
I2C_SCL = 0;
v5 |= I2C_SDA << v4;
v3 = v4-- == 0;
}
while ( !v3 );
v6 = rpos + 1;
v7 = rpos + 1 == rend;
*(_BYTE *)rpos = v5;
rpos = v6;
if ( !v7 )
I2C_SDA = 0;
func7();
I2C_SCL = 1;
func7();
result = rend;
I2C_SCL = 0;
if ( rpos == rend )
{
func7();
I2C_SDA = 0;
func7();
I2C_SCL = 1;
func7();
I2C_SDA = 1;
result = func7();
state = 0;
}
}
else if ( state == 2 && I2C_SDA && I2C_SCL )
{
I2C_SDA = 0;
func7();
I2C_SCL = 0;
state = 3;
return func7();
}
return result;
}

original_code:
void i2c_poll(void)
{
 int8_t i;
 uint8_t data;
 int nak;
 switch (state) {
 case IDLE:
 case FAILED:
  break;
 case START:
  if (!I2C_SDA || !I2C_SCL)
   break;
  I2C_SDA = 0;
  delay();
  I2C_SCL = 0;
  state = SEND;
  delay();
  break;
 case SEND:
  if (spos && wpos-wbuf == spos) {
   I2C_SDA = 1;
   delay();
   I2C_SCL = 1;
   delay();
   if (!I2C_SCL)
    break;
   I2C_SDA = 0;
   spos = 0;
   delay();
   I2C_SCL = 0;
   delay();
  }
  sda = *wpos >> 7;
  I2C_SDA = sda;
  delay();
  I2C_SCL = 1;
  if (!I2C_SCL)
   break;
  delay();
  I2C_SCL = 0;
  for (i = 6; i != -1; i--) {
   sda = (*wpos >> i) & 1;
   I2C_SDA = sda;
   delay();
   I2C_SCL = 1;
   delay();
   I2C_SCL = 0;
  }
  wpos++;
  I2C_SDA = 1;
  delay();
  I2C_SCL = 1;
  delay();
  nak = I2C_SDA;
  I2C_SCL = 0;
  I2C_SDA = 0;
  delay();
  nak = 0;
  if (nak) {
   state = FAILED;
  } else {
   if (wpos != wend)
    break;
   if (rpos != rend) {
    state = RECV;
    break;
   }
   state = IDLE;
  }
  I2C_SCL = 1;
  delay();
  I2C_SDA = 1;
  delay();
  break;
 case RECV:
  I2C_SDA = 1;
  data = 0;
  for (i = 7; i != -1; i--) {
   delay();
   I2C_SCL = 1;
   delay();
   data |= I2C_SDA << i;
   I2C_SCL = 0;
  }
  *rpos++ = data;
  if (rpos != rend)
   I2C_SDA = 0;
  delay();
  I2C_SCL = 1;
  delay();
  I2C_SCL = 0;
  if (rpos != rend)
   break;
  delay();
  I2C_SDA = 0;
  delay();
  I2C_SCL = 1;
  delay();
  I2C_SDA = 1;
  delay();
  state = IDLE;
  break;
 default:
  break;
 }
}

canonical_original_code:
void i2c_poll()
{
 char i;
 unsigned char data;
 int nak;
 switch (state) {
 case IDLE:
 case FAILED:
  break;
 case START:
  if (!I2C_SDA || !I2C_SCL)
   break;
  I2C_SDA = 0;
  delay();
  I2C_SCL = 0;
  state = SEND;
  delay();
  break;
 case SEND:
  if (spos && wpos-wbuf == spos) {
   I2C_SDA = 1;
   delay();
   I2C_SCL = 1;
   delay();
   if (!I2C_SCL)
    break;
   I2C_SDA = 0;
   spos = 0;
   delay();
   I2C_SCL = 0;
   delay();
  }
  sda = *wpos >> 7;
  I2C_SDA = sda;
  delay();
  I2C_SCL = 1;
  if (!I2C_SCL)
   break;
  delay();
  I2C_SCL = 0;
  for (i = 6; i != -1; i--) {
   sda = (*wpos >> i) & 1;
   I2C_SDA = sda;
   delay();
   I2C_SCL = 1;
   delay();
   I2C_SCL = 0;
  }
  wpos++;
  I2C_SDA = 1;
  delay();
  I2C_SCL = 1;
  delay();
  nak = I2C_SDA;
  I2C_SCL = 0;
  I2C_SDA = 0;
  delay();
  nak = 0;
  if (nak) {
   state = FAILED;
  } else {
   if (wpos != wend)
    break;
   if (rpos != rend) {
    state = RECV;
    break;
   }
   state = IDLE;
  }
  I2C_SCL = 1;
  delay();
  I2C_SDA = 1;
  delay();
  break;
 case RECV:
  I2C_SDA = 1;
  data = 0;
  for (i = 7; i != -1; i--) {
   delay();
   I2C_SCL = 1;
   delay();
   data |= I2C_SDA << i;
   I2C_SCL = 0;
  }
  *rpos++ = data;
  if (rpos != rend)
   I2C_SDA = 0;
  delay();
  I2C_SCL = 1;
  delay();
  I2C_SCL = 0;
  if (rpos != rend)
   break;
  delay();
  I2C_SDA = 0;
  delay();
  I2C_SCL = 1;
  delay();
  I2C_SDA = 1;
  delay();
  state = IDLE;
  break;
 default:
  break;
 }
}

variable_types: i char

variable_types:
data
unsigned char

variable_types: nak int


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rdx
__int64 v4; // rdx
__int64 v5; // rdx
__int64 v6; // rdx

I2C_SCL = 1;
I2C_SDA = 1;
delay(argc, argv, envp);
i2c_write_constprop_0();
polln_constprop_0();
delay(argc, argv, v3);
delay(argc, argv, v4);
delay(argc, argv, v5);
delay(argc, argv, v6);
fprintf(stderr, "state %d\n", (unsigned int)state);
i2c_fetch(0LL, 10LL);
i2c_fetch(0LL, 10LL);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rdx
__int64 v4; // rdx
__int64 v5; // rdx
__int64 v6; // rdx

I2C_SCL = 1;
I2C_SDA = 1;
func7(argc, argv, envp);
func10();
func13();
func7(argc, argv, v3);
func7(argc, argv, v4);
func7(argc, argv, v5);
func7(argc, argv, v6);
fprintf(stderr, "state %d\n", (unsigned int)state);
func11(0LL, 10LL);
func11(0LL, 10LL);
return 0;
}

original_code:
int main(void)
{
 int i;
 uint8_t tmp;
 I2C_SDA = I2C_SCL = 1;
 delay();
 i2c_write(0x73, 0, "A", 1);
 polln(200);
 delay();
 delay();
 delay();
 delay();
 fprintf(stderr, "state %d\n", state);
 i2c_fetch(((void *)0), 10);
 i2c_fetch(((void *)0), 10);
 return 0;
}

canonical_original_code:
int main()
{
 int i;
 unsigned char tmp;
 I2C_SDA = I2C_SCL = 1;
 delay();
 i2c_write(0x73, 0, "A", 1);
 polln(200);
 delay();
 delay();
 delay();
 delay();
 fprintf(stderr, "state %d\n", state);
 i2c_fetch(((void *)0), 10);
 i2c_fetch(((void *)0), 10);
 return 0;
}

variable_types: i int

variable_types:
tmp
unsigned char


decompiled_code:
__int64 __fastcall set_pin(__int64 a1)
{
const char *v1; // r8
__int64 v2; // rdx
char v3; // cl
__int64 result; // rax
int v5; // [rsp+8h] [rbp-10h] BYREF
int v6[3]; // [rsp+Ch] [rbp-Ch] BYREF

translate_pin(a1, &v5, v6);
v2 = v5;
v3 = v6[0];
*((_BYTE *)&mask + v5) |= LOBYTE(v6[0]);
result = *(unsigned __int8 *)v1;
if ( !(_BYTE)result || v1[1] )
goto LABEL_6;
if ( (_BYTE)result == 49 )
{
*((_BYTE *)&mode + v2) |= v3;
LABEL_10:
*((_BYTE *)&data + v2) |= v3;
return result;
}
if ( (char)result > 49 )
{
result = (unsigned int)result & 0xFFFFFFDF;
if ( (_BYTE)result != 82 )
goto LABEL_6;
goto LABEL_10;
}
if ( (_BYTE)result != 48 )
{
LABEL_6:
fprintf(stderr, "invalid pin state \"%s\"\n", v1);
exit(1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
const char *v1; // r8
__int64 v2; // rdx
char v3; // cl
__int64 result; // rax
int v5; // [rsp+8h] [rbp-10h] BYREF
int v6[3]; // [rsp+Ch] [rbp-Ch] BYREF

func0(a1, &v5, v6);
v2 = v5;
v3 = v6[0];
*((_BYTE *)&mask + v5) |= LOBYTE(v6[0]);
result = *(unsigned __int8 *)v1;
if ( !(_BYTE)result || v1[1] )
goto LABEL_6;
if ( (_BYTE)result == 49 )
{
*((_BYTE *)&mode + v2) |= v3;
LABEL_10:
*((_BYTE *)&data + v2) |= v3;
return result;
}
if ( (char)result > 49 )
{
result = (unsigned int)result & 0xFFFFFFDF;
if ( (_BYTE)result != 82 )
goto LABEL_6;
goto LABEL_10;
}
if ( (_BYTE)result != 48 )
{
LABEL_6:
fprintf(stderr, "invalid pin state \"%s\"\n", v1);
exit(1);
}
return result;
}

original_code:
static void set_pin(const struct pin *pin, const char *value)
{
 int port, bit;
 translate_pin(pin, &port, &bit);
 mask[port] |= bit;
 if (!*value || value[1]) {
  fprintf(stderr, "invalid pin state \"%s\"\n", value);
  exit(1);
 }
 switch (*value) {
 case '1':
  mode[port] |= bit;
 case 'r':
 case 'R':
  data[port] |= bit;
  break;
 case '0':
  break;
 default:
  fprintf(stderr, "invalid pin state \"%s\"\n", value);
  exit(1);
 }
}

canonical_original_code:
static void set_pin(struct pin *pin, char *value)
{
 int port; int bit;
 translate_pin(pin, &port, &bit);
 mask[port] |= bit;
 if (!*value || value[1]) {
  fprintf(stderr, "invalid pin state \"%s\"\n", value);
  exit(1);
 }
 switch (*value) {
 case '1':
  mode[port] |= bit;
 case 'r':
 case 'R':
  data[port] |= bit;
  break;
 case '0':
  break;
 default:
  fprintf(stderr, "invalid pin state \"%s\"\n", value);
  exit(1);
 }
}

variable_types: struct pin { int pin; int port; char *host_name; char *idbg_name; } *

variable_types:
value
char *

variable_types: port int

variable_types: bit int


decompiled_code:
int __fastcall print_names(unsigned int *a1)
{
const char *v1; // rsi
const char *v2; // rsi

printf("%2d: P%d_%d (", *a1, a1[1], a1[2]);
v1 = (const char *)*((_QWORD *)a1 + 2);
if ( v1 )
{
printf("%s", v1);
if ( *((_QWORD *)a1 + 2) )
{
if ( !*((_QWORD *)a1 + 3) )
return putchar(41);
printf(", ");
}
}
v2 = (const char *)*((_QWORD *)a1 + 3);
if ( v2 )
printf("%s", v2);
return putchar(41);
}

canonical_decompiled_code:
int __fastcall func3(unsigned int *a1)
{
const char *v1; // rsi
const char *v2; // rsi

printf("%2d: P%d_%d (", *a1, a1[1], a1[2]);
v1 = (const char *)*((_QWORD *)a1 + 2);
if ( v1 )
{
printf("%s", v1);
if ( *((_QWORD *)a1 + 2) )
{
if ( !*((_QWORD *)a1 + 3) )
return putchar(41);
printf(", ");
}
}
v2 = (const char *)*((_QWORD *)a1 + 3);
if ( v2 )
printf("%s", v2);
return putchar(41);
}

original_code:
static void print_names(const struct pin *pin)
{
 printf("%2d: P%d_%d (", pin->pin, pin->port, pin->bit);
 if (pin->host_name)
  printf("%s", pin->host_name);
 if (pin->host_name && pin->idbg_name)
  printf(", ");
 if (pin->idbg_name)
  printf("%s", pin->idbg_name);
 printf(")");
}

canonical_original_code:
static void print_names(struct pin *pin)
{
 printf("%2d: P%d_%d (", pin->pin, pin->port, pin->bit);
 if (pin->host_name)
  printf("%s", pin->host_name);
 if (pin->host_name && pin->idbg_name)
  printf(", ");
 if (pin->idbg_name)
  printf("%s", pin->idbg_name);
 printf(")");
}

user_defined_types: struct pin { int pin; int port; char *host_name; char *idbg_name; }


decompiled_code:
int __fastcall dump_pin_table(const char *a1, int *a2)
{
int *v2; // rbx
int result; // eax
unsigned int *v4; // rdi

v2 = a2;
for ( result = puts(a1); *v2; result = *v2 )
{
printf(" ");
v4 = (unsigned int *)v2;
v2 += 8;
print_names(v4);
putchar(10);
}
return result;
}

canonical_decompiled_code:
int __fastcall func4(const char *a1, int *a2)
{
int *v2; // rbx
int result; // eax
unsigned int *v4; // rdi

v2 = a2;
for ( result = puts(a1); *v2; result = *v2 )
{
printf(" ");
v4 = (unsigned int *)v2;
v2 += 8;
func3(v4);
putchar(10);
}
return result;
}

original_code:
static void dump_pin_table(const char *device, const struct pin *pin_table)
{
 const struct pin *pin;
 printf("%s\n", device);
 for (pin = pin_table; pin->pin; pin++) {
  printf("  ");
  print_names(pin);
  putchar('\n');
 }
}

canonical_original_code:
static void dump_pin_table(char *device, struct pin *pin_table)
{
 struct pin *pin;
 printf("%s\n", device);
 for (pin = pin_table; pin->pin; pin++) {
  printf("  ");
  print_names(pin);
  putchar('\n');
 }
}

variable_types:
device
char *


decompiled_code:
int list_pins()
{
dump_pin_table("GTA01/GTA02", gta_pins);
dump_pin_table("Ben NanoNote, IDBG V1", ben_v1_pins);
return dump_pin_table("Ben NanoNote, IDBG V2", ben_v2_pins);
}

canonical_decompiled_code:
int func5()
{
func4("GTA01/GTA02", gta_pins);
func4("Ben NanoNote, IDBG V1", ben_v1_pins);
return func4("Ben NanoNote, IDBG V2", ben_v2_pins);
}

original_code:
static void list_pins(void)
{
 dump_pin_table("GTA01/GTA02", gta_pins);
 dump_pin_table("Ben NanoNote, IDBG V1", ben_v1_pins);
 dump_pin_table("Ben NanoNote, IDBG V2", ben_v2_pins);
}

canonical_original_code:
static void list_pins()
{
 dump_pin_table("GTA01/GTA02", gta_pins);
 dump_pin_table("Ben NanoNote, IDBG V1", ben_v1_pins);
 dump_pin_table("Ben NanoNote, IDBG V2", ben_v2_pins);
}


decompiled_code:
int __fastcall get_pin(unsigned int *a1)
{
__int64 v1; // rsi
int v3; // [rsp+8h] [rbp-10h] BYREF
int v4[3]; // [rsp+Ch] [rbp-Ch] BYREF

translate_pin((__int64)a1, &v3, v4);
print_names(a1);
v1 = 48LL;
if ( (v4[0] & *((_BYTE *)&data + v3)) != 0 )
v1 = (unsigned __int8)(*((_BYTE *)&mode + v3) & v4[0]) == 0 ? 82 : 49;
return printf(" = %c\n", v1);
}

canonical_decompiled_code:
int __fastcall func6(unsigned int *a1)
{
__int64 v1; // rsi
int v3; // [rsp+8h] [rbp-10h] BYREF
int v4[3]; // [rsp+Ch] [rbp-Ch] BYREF

func0((__int64)a1, &v3, v4);
func3(a1);
v1 = 48LL;
if ( (v4[0] & *((_BYTE *)&data + v3)) != 0 )
v1 = (unsigned __int8)(*((_BYTE *)&mode + v3) & v4[0]) == 0 ? 82 : 49;
return printf(" = %c\n", v1);
}

original_code:
static void get_pin(const struct pin *pin)
{
 int port, bit;
 translate_pin(pin, &port, &bit);
 print_names(pin);
 printf(" = %c\n",
     data[port] & bit ? mode[port] & bit ? '1' : 'R' : '0');
}

canonical_original_code:
static void get_pin(struct pin *pin)
{
 int port; int bit;
 translate_pin(pin, &port, &bit);
 print_names(pin);
 printf(" = %c\n",
     data[port] & bit ? mode[port] & bit ? '1' : 'R' : '0');
}


decompiled_code:
__int64 dump_all()
{
unsigned int *v0; // rbx
unsigned int *v1; // rdi
__int64 result; // rax

v0 = (unsigned int *)pins;
if ( *(_DWORD *)pins )
{
do
{
v1 = v0;
v0 += 8;
get_pin(v1);
result = *v0;
}
while ( (_DWORD)result );
}
return result;
}

canonical_decompiled_code:
__int64 func7()
{
unsigned int *v0; // rbx
unsigned int *v1; // rdi
__int64 result; // rax

v0 = (unsigned int *)pins;
if ( *(_DWORD *)pins )
{
do
{
v1 = v0;
v0 += 8;
func6(v1);
result = *v0;
}
while ( (_DWORD)result );
}
return result;
}

original_code:
static void dump_all(void)
{
 const struct pin *pin;
 for (pin = pins; pin->pin; pin++)
  get_pin(pin);
}

canonical_original_code:
static void dump_all()
{
 struct pin *pin;
 for (pin = pins; pin->pin; pin++)
  get_pin(pin);
}


decompiled_code:
__int64 __fastcall lookup_pin(char *s2)
{
__int64 v1; // r12
unsigned int v2; // er13
const char *v4; // rdi
const char *v5; // rdi
char s[29]; // [rsp+Bh] [rbp-1Dh] BYREF

v1 = pins;
v2 = *(_DWORD *)pins;
if ( !*(_DWORD *)pins )
return 0LL;
while ( 1 )
{
v4 = *(const char **)(v1 + 16);
if ( v4 )
{
if ( !strcasecmp(v4, s2) )
break;
}
v5 = *(const char **)(v1 + 24);
if ( v5 )
{
if ( !strcasecmp(v5, s2) )
break;
}
sprintf(s, "%d", v2);
if ( !strcmp(s, s2) )
break;
sprintf(s, "P%d_%d", *(unsigned int *)(v1 + 4), *(unsigned int *)(v1 + 8));
if ( !strcasecmp(s, s2) )
break;
v2 = *(_DWORD *)(v1 + 32);
v1 += 32LL;
if ( !v2 )
return 0LL;
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func8(char *s2)
{
__int64 v1; // r12
unsigned int v2; // er13
const char *v4; // rdi
const char *v5; // rdi
char s[29]; // [rsp+Bh] [rbp-1Dh] BYREF

v1 = pins;
v2 = *(_DWORD *)pins;
if ( !*(_DWORD *)pins )
return 0LL;
while ( 1 )
{
v4 = *(const char **)(v1 + 16);
if ( v4 )
{
if ( !strcasecmp(v4, s2) )
break;
}
v5 = *(const char **)(v1 + 24);
if ( v5 )
{
if ( !strcasecmp(v5, s2) )
break;
}
sprintf(s, "%d", v2);
if ( !strcmp(s, s2) )
break;
sprintf(s, "P%d_%d", *(unsigned int *)(v1 + 4), *(unsigned int *)(v1 + 8));
if ( !strcasecmp(s, s2) )
break;
v2 = *(_DWORD *)(v1 + 32);
v1 += 32LL;
if ( !v2 )
return 0LL;
}
return v1;
}

original_code:
static const struct pin *lookup_pin(const char *name)
{
 const struct pin *pin;
 char tmp[5];
 for (pin = pins; pin->pin; pin++) {
  if (pin->host_name && !strcasecmp(pin->host_name, name))
   return pin;
  if (pin->idbg_name && !strcasecmp(pin->idbg_name, name))
   return pin;
  sprintf(tmp, "%d", pin->pin);
  if (!strcmp(tmp, name))
   return pin;
  sprintf(tmp, "P%d_%d", pin->port, pin->bit);
  if (!strcasecmp(tmp, name))
   return pin;
 }
 return ((void *)0);
}

canonical_original_code:
static struct pin *lookup_pin(char *name)
{
 struct pin *pin;
 char tmp[5];
 for (pin = pins; pin->pin; pin++) {
  if (pin->host_name && !strcasecmp(pin->host_name, name))
   return pin;
  if (pin->idbg_name && !strcasecmp(pin->idbg_name, name))
   return pin;
  sprintf(tmp, "%d", pin->pin);
  if (!strcmp(tmp, name))
   return pin;
  sprintf(tmp, "P%d_%d", pin->port, pin->bit);
  if (!strcasecmp(tmp, name))
   return pin;
 }
 return ((void *)0);
}

variable_types:
name
char *

variable_types:
tmp
char [5]

return_type: struct pin { int pin; int port; char *host_name; char *idbg_name; } *


decompiled_code:
void __fastcall parse_set(const char **a1, int a2)
{
const char **v2; // r13
const char **v3; // rbp
signed __int64 v4; // r14
__int64 v5; // rdi
const char *v6; // r12
char *v7; // rax
char v8[152]; // [rsp+0h] [rbp-98h] BYREF

if ( a2 )
{
v2 = &a1[a2];
v3 = a1;
do
{
while ( 1 )
{
v6 = *v3;
v7 = strchr(*v3, 61);
if ( v7 )
break;
have_get = 1;
if ( ++v3 == v2 )
return;
}
v4 = v7 - v6;
memcpy(v8, v6, v7 - v6);
v8[v4] = 0;
v5 = lookup_pin(v8);
if ( !v5 )
{
fprintf(stderr, "unrecognized pin \"%s\"\n", v8);
exit(1);
}
++v3;
set_pin(v5);
}
while ( v3 != v2 );
}
}

canonical_decompiled_code:
void __fastcall func9(const char **a1, int a2)
{
const char **v2; // r13
const char **v3; // rbp
signed __int64 v4; // r14
__int64 v5; // rdi
const char *v6; // r12
char *v7; // rax
char v8[152]; // [rsp+0h] [rbp-98h] BYREF

if ( a2 )
{
v2 = &a1[a2];
v3 = a1;
do
{
while ( 1 )
{
v6 = *v3;
v7 = strchr(*v3, 61);
if ( v7 )
break;
have_get = 1;
if ( ++v3 == v2 )
return;
}
v4 = v7 - v6;
memcpy(v8, v6, v7 - v6);
v8[v4] = 0;
v5 = func8(v8);
if ( !v5 )
{
fprintf(stderr, "unrecognized pin \"%s\"\n", v8);
exit(1);
}
++v3;
func2(v5);
}
while ( v3 != v2 );
}
}

original_code:
static void parse_set(const char **args, int num_args)
{
 const struct pin *pin;
 const char *eq;
 char tmp[100];
 while (num_args--) {
  eq = strchr(*args, '=');
  if (!eq) {
   have_get = 1;
  } else {
   memcpy(tmp, *args, eq-*args);
   tmp[eq-*args] = 0;
   pin = lookup_pin(tmp);
   if (!pin) {
    fprintf(stderr, "unrecognized pin \"%s\"\n",
        tmp);
    exit(1);
   }
   set_pin(pin, eq+1);
  }
  args++;
 }
}

canonical_original_code:
static void parse_set(char **args, int num_args)
{
 struct pin *pin;
 char *eq;
 char tmp[100];
 while (num_args--) {
  eq = strchr(*args, '=');
  if (!eq) {
   have_get = 1;
  } else {
   memcpy(tmp, *args, eq-*args);
   tmp[eq-*args] = 0;
   pin = lookup_pin(tmp);
   if (!pin) {
    fprintf(stderr, "unrecognized pin \"%s\"\n",
        tmp);
    exit(1);
   }
   set_pin(pin, eq+1);
  }
  args++;
 }
}

variable_types:
args
char **

variable_types:
eq
char *

variable_types:
tmp
char [100]