mono_attach_parse_options (char * options)
{
  int D.20219;
  int iftmp.0;
  int D.20218;
  const char[8] * D.20311;
  unsigned char D.20312;
  int D.20313;
  unsigned char D.20314;
  int D.20315;
  _Bool D.20316;
  _Bool D.20317;
  _Bool D.20318;
  const unsigned char * D.20321;
  unsigned char D.20322;
  int D.20323;
  const unsigned char * D.20324;
  unsigned char D.20325;
  int D.20326;
  _Bool D.20327;
  _Bool D.20328;
  const unsigned char * D.20331;
  unsigned char D.20332;
  int D.20333;
  const unsigned char * D.20334;
  unsigned char D.20335;
  int D.20336;
  _Bool D.20337;
  _Bool D.20338;
  const unsigned char * D.20341;
  unsigned char D.20342;
  int D.20343;
  const unsigned char * D.20344;
  unsigned char D.20345;
  int D.20346;

  if (options == 0B) goto <D.20306>; else goto <D.20307>;
  <D.20306>:
  return;
  <D.20307>:
  {
    size_t __s1_len;
    size_t __s2_len;

    __s2_len = 7;
    if (__s2_len <= 3) goto <D.20309>; else goto <D.20310>;
    <D.20309>:
    {
      const unsigned char * __s2;
      int __result;

      __s2 = options;
      D.20311 = "disable";
      D.20312 = MEM[(const unsigned char *)D.20311];
      D.20313 = (int) D.20312;
      D.20314 = *__s2;
      D.20315 = (int) D.20314;
      __result = D.20313 - D.20315;
      {
        D.20316 = __s2_len != 0;
        D.20317 = __result == 0;
        D.20318 = D.20316 & D.20317;
        if (D.20318 != 0) goto <D.20319>; else goto <D.20320>;
        <D.20319>:
        D.20321 = &MEM[(void *)"disable" + 1B];
        D.20322 = *D.20321;
        D.20323 = (int) D.20322;
        D.20324 = __s2 + 1;
        D.20325 = *D.20324;
        D.20326 = (int) D.20325;
        __result = D.20323 - D.20326;
        D.20327 = __s2_len > 1;
        D.20317 = __result == 0;
        D.20328 = D.20327 & D.20317;
        if (D.20328 != 0) goto <D.20329>; else goto <D.20330>;
        <D.20329>:
        D.20331 = &MEM[(void *)"disable" + 2B];
        D.20332 = *D.20331;
        D.20333 = (int) D.20332;
        D.20334 = __s2 + 2;
        D.20335 = *D.20334;
        D.20336 = (int) D.20335;
        __result = D.20333 - D.20336;
        D.20337 = __s2_len > 2;
        D.20317 = __result == 0;
        D.20338 = D.20337 & D.20317;
        if (D.20338 != 0) goto <D.20339>; else goto <D.20340>;
        <D.20339>:
        D.20341 = &MEM[(void *)"disable" + 3B];
        D.20342 = *D.20341;
        D.20343 = (int) D.20342;
        D.20344 = __s2 + 3;
        D.20345 = *D.20344;
        D.20346 = (int) D.20345;
        __result = D.20343 - D.20346;
        <D.20340>:
        <D.20330>:
        <D.20320>:
      }
      D.20218 = __result;
    }
    iftmp.0 = -D.20218;
    goto <D.20347>;
    <D.20310>:
    iftmp.0 = __builtin_strcmp (options, "disable");
    <D.20347>:
    D.20219 = iftmp.0;
  }
  if (D.20219 == 0) goto <D.20348>; else goto <D.20349>;
  <D.20348>:
  config.enabled = 0;
  <D.20349>:
}


mono_attach_init ()
{
  InitializeCriticalSection (&agent_mutex);
  config.enabled = 1;
}


mono_attach_start ()
{
  int started.1;
  gboolean D.20354;
  int D.20355;
  int D.20358;
  char path[256];
  int fd;

  try
    {
      started.1 = started;
      if (started.1 != 0) goto <D.20352>; else goto <D.20353>;
      <D.20352>:
      D.20354 = 0;
      return D.20354;
      <D.20353>:
      D.20355 = getpid ();
      snprintf (&path, 256, "/tmp/.mono_attach_pid%d", D.20355);
      fd = open (&path, 0);
      if (fd == -1) goto <D.20356>; else goto <D.20357>;
      <D.20356>:
      D.20354 = 0;
      return D.20354;
      <D.20357>:
      close (fd);
      D.20358 = config.enabled;
      if (D.20358 == 0) goto <D.20359>; else goto <D.20360>;
      <D.20359>:
      D.20354 = 1;
      return D.20354;
      <D.20360>:
      started.1 = started;
      if (started.1 != 0) goto <D.20361>; else goto <D.20362>;
      <D.20361>:
      D.20354 = 0;
      return D.20354;
      <D.20362>:
      needs_to_start = 1;
      mono_gc_finalize_notify ();
      D.20354 = 1;
      return D.20354;
    }
  finally
    {
      path = {CLOBBER};
    }
}


snprintf (char * restrict __s, size_t __n, const char * restrict __fmt)
{
  int D.20365;
  unsigned int D.20366;

  D.20366 = __builtin_object_size (__s, 1);
  D.20365 = __builtin___snprintf_chk (__s, __n, 1, D.20366, __fmt, __builtin_va_arg_pack ());
  return D.20365;
}


open (const char * __path, int __oflag)
{
  int D.20368;
  int D.20371;
  int D.20376;
  int D.20378;
  int D.20379;
  int D.20382;
  int D.20383;

  D.20368 = __builtin_va_arg_pack_len ();
  if (D.20368 > 1) goto <D.20369>; else goto <D.20370>;
  <D.20369>:
  __open_too_many_args ();
  <D.20370>:
  D.20371 = __builtin_constant_p (__oflag);
  if (D.20371 != 0) goto <D.20372>; else goto <D.20373>;
  <D.20372>:
  D.20376 = __oflag & 64;
  if (D.20376 != 0) goto <D.20374>; else goto <D.20377>;
  <D.20377>:
  D.20378 = __oflag & 4210688;
  if (D.20378 == 4210688) goto <D.20374>; else goto <D.20375>;
  <D.20374>:
  D.20379 = __builtin_va_arg_pack_len ();
  if (D.20379 <= 0) goto <D.20380>; else goto <D.20381>;
  <D.20380>:
  __open_missing_mode ();
  D.20382 = __open_2 (__path, __oflag);
  return D.20382;
  <D.20381>:
  <D.20375>:
  D.20382 = __open_alias (__path, __oflag, __builtin_va_arg_pack ());
  return D.20382;
  <D.20373>:
  D.20383 = __builtin_va_arg_pack_len ();
  if (D.20383 <= 0) goto <D.20384>; else goto <D.20385>;
  <D.20384>:
  D.20382 = __open_2 (__path, __oflag);
  return D.20382;
  <D.20385>:
  D.20382 = __open_alias (__path, __oflag, __builtin_va_arg_pack ());
  return D.20382;
}


mono_attach_maybe_start ()
{
  int needs_to_start.2;
  int started.3;

  needs_to_start.2 = needs_to_start;
  if (needs_to_start.2 == 0) goto <D.20388>; else goto <D.20389>;
  <D.20388>:
  return;
  <D.20389>:
  needs_to_start = 0;
  started.3 = started;
  if (started.3 == 0) goto <D.20391>; else goto <D.20392>;
  <D.20391>:
  transport_start_receive ();
  started = 1;
  <D.20392>:
}


transport_start_receive ()
{
  int listen_fd.4;
  void * receiver_thread_handle.5;
  void * receiver_thread_handle.6;
  _Bool D.20399;
  long int D.20400;
  long int D.20401;

  transport_connect ();
  listen_fd.4 = listen_fd;
  if (listen_fd.4 == 0) goto <D.20395>; else goto <D.20396>;
  <D.20395>:
  return;
  <D.20396>:
  receiver_thread_handle.5 = mono_threads_create_thread (receiver_thread, 0B, 0, 0, 0B);
  receiver_thread_handle = receiver_thread_handle.5;
  receiver_thread_handle.6 = receiver_thread_handle;
  D.20399 = receiver_thread_handle.6 == 0B;
  D.20400 = (long int) D.20399;
  D.20401 = __builtin_expect (D.20400, 0);
  if (D.20401 != 0) goto <D.20402>; else goto <D.20403>;
  <D.20402>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 482, "receiver_thread_handle");
  <D.20403>:
}


receiver_thread (void * arg)
{
  char * server_uri.7;
  int listen_fd.8;
  union 
{
  struct sockaddr * restrict __sockaddr__;
  struct sockaddr_at * restrict __sockaddr_at__;
  struct sockaddr_ax25 * restrict __sockaddr_ax25__;
  struct sockaddr_dl * restrict __sockaddr_dl__;
  struct sockaddr_eon * restrict __sockaddr_eon__;
  struct sockaddr_in * restrict __sockaddr_in__;
  struct sockaddr_in6 * restrict __sockaddr_in6__;
  struct sockaddr_inarp * restrict __sockaddr_inarp__;
  struct sockaddr_ipx * restrict __sockaddr_ipx__;
  struct sockaddr_iso * restrict __sockaddr_iso__;
  struct sockaddr_ns * restrict __sockaddr_ns__;
  struct sockaddr_un * restrict __sockaddr_un__;
  struct sockaddr_x25 * restrict __sockaddr_x25__;
} D.20407;
  int conn_fd.9;
  int conn_fd.10;
  guint32 D.20412;
  struct MonoDomain * D.20413;
  struct MonoInternalThread * D.20414;
  unsigned int D.20415;
  unsigned int D.20416;
  int * D.20419;
  int D.20420;
  int stop_receiver_thread.11;
  int D.20429;
  unsigned char D.20431;
  unsigned char D.20433;
  struct _IO_FILE * stderr.12;
  guint8 * p.13;
  unsigned int content_len.14;
  unsigned int content_len.15;
  sizetype content_len.16;
  int D.20299;
  int iftmp.17;
  int D.20298;
  const char[7] * D.20444;
  unsigned char D.20445;
  int D.20446;
  unsigned char D.20447;
  int D.20448;
  _Bool D.20449;
  _Bool D.20450;
  _Bool D.20451;
  const unsigned char * D.20454;
  unsigned char D.20455;
  int D.20456;
  const unsigned char * D.20457;
  unsigned char D.20458;
  int D.20459;
  _Bool D.20460;
  _Bool D.20461;
  const unsigned char * D.20464;
  unsigned char D.20465;
  int D.20466;
  const unsigned char * D.20467;
  unsigned char D.20468;
  int D.20469;
  _Bool D.20470;
  _Bool D.20471;
  const unsigned char * D.20474;
  unsigned char D.20475;
  int D.20476;
  const unsigned char * D.20477;
  unsigned char D.20478;
  int D.20479;
  _Bool D.20481;
  long int D.20482;
  long int D.20483;
  struct MonoDomain * D.20486;
  int res;
  int content_len;
  guint8 buffer[256];
  guint8 * p;
  guint8 * p_end;
  struct MonoObject * exc;

  try
    {
      server_uri.7 = server_uri;
      printf ("attach: Listening on \'%s\'...\n", server_uri.7);
      <D.20302>:
      listen_fd.8 = listen_fd;
      D.20407.__sockaddr__ = 0B;
      conn_fd.9 = accept (listen_fd.8, D.20407, 0B);
      conn_fd = conn_fd.9;
      conn_fd.10 = conn_fd;
      if (conn_fd.10 == -1) goto <D.20410>; else goto <D.20411>;
      <D.20410>:
      D.20412 = 0;
      return D.20412;
      <D.20411>:
      printf ("attach: Connected.\n");
      D.20413 = mono_get_root_domain ();
      mono_thread_attach (D.20413);
      D.20414 = mono_thread_internal_current ();
      D.20415 = D.20414->state;
      D.20416 = D.20415 | 4;
      D.20414->state = D.20416;
      <D.20300>:
      {
        char * cmd;
        char * agent_name;
        char * agent_args;
        guint8 * body;

        conn_fd.10 = conn_fd;
        res = read (conn_fd.10, &buffer, 6);
        if (res == -1) goto <D.20417>; else goto <D.20418>;
        <D.20417>:
        D.20419 = __errno_location ();
        D.20420 = *D.20419;
        if (D.20420 == 4) goto <D.20421>; else goto <D.20422>;
        <D.20421>:
        // predicted unlikely by continue predictor.
        goto <D.20280>;
        <D.20422>:
        <D.20418>:
        if (res == -1) goto <D.20281>; else goto <D.20423>;
        <D.20423>:
        stop_receiver_thread.11 = stop_receiver_thread;
        if (stop_receiver_thread.11 != 0) goto <D.20281>; else goto <D.20425>;
        <D.20425>:
        if (res != 6) goto <D.20281>; else goto <D.20426>;
        <D.20426>:
        D.20429 = strncmp (&buffer, "MONO", 4);
        if (D.20429 != 0) goto <D.20427>; else goto <D.20430>;
        <D.20430>:
        D.20431 = buffer[4];
        if (D.20431 != 1) goto <D.20427>; else goto <D.20432>;
        <D.20432>:
        D.20433 = buffer[5];
        if (D.20433 != 0) goto <D.20427>; else goto <D.20428>;
        <D.20427>:
        stderr.12 = stderr;
        fprintf (stderr.12, "attach: message from server has unknown header.\n");
        goto <D.20281>;
        <D.20428>:
        conn_fd.10 = conn_fd;
        res = read (conn_fd.10, &buffer, 4);
        if (res != 4) goto <D.20281>; else goto <D.20435>;
        <D.20435>:
        p = &buffer;
        p.13 = p;
        p_end = p.13 + 8;
        p.13 = p;
        content_len = decode_int (p.13, &p, p_end);
        content_len.14 = (unsigned int) content_len;
        body = monoeg_malloc (content_len.14);
        conn_fd.10 = conn_fd;
        content_len.15 = (unsigned int) content_len;
        res = read (conn_fd.10, body, content_len.15);
        p = body;
        content_len.16 = (sizetype) content_len;
        p_end = body + content_len.16;
        p.13 = p;
        cmd = decode_string_value (p.13, &p, p_end);
        if (cmd == 0B) goto <D.20281>; else goto <D.20440>;
        <D.20440>:
        {
          size_t __s1_len;
          size_t __s2_len;

          __s2_len = 6;
          if (__s2_len <= 3) goto <D.20442>; else goto <D.20443>;
          <D.20442>:
          {
            const unsigned char * __s2;
            int __result;

            __s2 = cmd;
            D.20444 = "attach";
            D.20445 = MEM[(const unsigned char *)D.20444];
            D.20446 = (int) D.20445;
            D.20447 = *__s2;
            D.20448 = (int) D.20447;
            __result = D.20446 - D.20448;
            {
              D.20449 = __s2_len != 0;
              D.20450 = __result == 0;
              D.20451 = D.20449 & D.20450;
              if (D.20451 != 0) goto <D.20452>; else goto <D.20453>;
              <D.20452>:
              D.20454 = &MEM[(void *)"attach" + 1B];
              D.20455 = *D.20454;
              D.20456 = (int) D.20455;
              D.20457 = __s2 + 1;
              D.20458 = *D.20457;
              D.20459 = (int) D.20458;
              __result = D.20456 - D.20459;
              D.20460 = __s2_len > 1;
              D.20450 = __result == 0;
              D.20461 = D.20460 & D.20450;
              if (D.20461 != 0) goto <D.20462>; else goto <D.20463>;
              <D.20462>:
              D.20464 = &MEM[(void *)"attach" + 2B];
              D.20465 = *D.20464;
              D.20466 = (int) D.20465;
              D.20467 = __s2 + 2;
              D.20468 = *D.20467;
              D.20469 = (int) D.20468;
              __result = D.20466 - D.20469;
              D.20470 = __s2_len > 2;
              D.20450 = __result == 0;
              D.20471 = D.20470 & D.20450;
              if (D.20471 != 0) goto <D.20472>; else goto <D.20473>;
              <D.20472>:
              D.20474 = &MEM[(void *)"attach" + 3B];
              D.20475 = *D.20474;
              D.20476 = (int) D.20475;
              D.20477 = __s2 + 3;
              D.20478 = *D.20477;
              D.20479 = (int) D.20478;
              __result = D.20476 - D.20479;
              <D.20473>:
              <D.20463>:
              <D.20453>:
            }
            D.20298 = __result;
          }
          iftmp.17 = -D.20298;
          goto <D.20480>;
          <D.20443>:
          iftmp.17 = __builtin_strcmp (cmd, "attach");
          <D.20480>:
          D.20299 = iftmp.17;
        }
        D.20481 = D.20299 != 0;
        D.20482 = (long int) D.20481;
        D.20483 = __builtin_expect (D.20482, 0);
        if (D.20483 != 0) goto <D.20484>; else goto <D.20485>;
        <D.20484>:
        monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 550, "!strcmp (cmd, \"attach\")");
        <D.20485>:
        p.13 = p;
        agent_name = decode_string_value (p.13, &p, p_end);
        p.13 = p;
        agent_args = decode_string_value (p.13, &p, p_end);
        printf ("attach: Loading agent \'%s\'.\n", agent_name);
        D.20486 = mono_domain_get ();
        mono_attach_load_agent (D.20486, agent_name, agent_args, &exc);
        monoeg_g_free (body);
      }
      <D.20280>:
      goto <D.20300>;
      <D.20281>:
      conn_fd.10 = conn_fd;
      close (conn_fd.10);
      conn_fd = 0;
      printf ("attach: Disconnected.\n");
      stop_receiver_thread.11 = stop_receiver_thread;
      if (stop_receiver_thread.11 != 0) goto <D.20301>; else goto <D.20487>;
      <D.20487>:
      goto <D.20302>;
      <D.20301>:
      D.20412 = 0;
      return D.20412;
    }
  finally
    {
      buffer = {CLOBBER};
      p = {CLOBBER};
      exc = {CLOBBER};
    }
}


fprintf (struct FILE * restrict __stream, const char * restrict __fmt)
{
  int D.20490;

  D.20490 = __fprintf_chk (__stream, 1, __fmt, __builtin_va_arg_pack ());
  return D.20490;
}


decode_int (guint8 * buf, guint8 * * endbuf, guint8 * limit)
{
  guint8 * D.20492;
  guint8 * D.20493;
  _Bool D.20494;
  long int D.20495;
  long int D.20496;
  int D.20499;
  unsigned char D.20500;
  int D.20501;
  guint8 * D.20502;
  unsigned char D.20503;
  int D.20504;
  int D.20505;
  int D.20506;
  guint8 * D.20507;
  unsigned char D.20508;
  int D.20509;
  int D.20510;
  int D.20511;
  guint8 * D.20512;
  unsigned char D.20513;
  int D.20514;
  int D.20515;

  D.20492 = buf + 4;
  *endbuf = D.20492;
  D.20493 = *endbuf;
  D.20494 = D.20493 > limit;
  D.20495 = (long int) D.20494;
  D.20496 = __builtin_expect (D.20495, 0);
  if (D.20496 != 0) goto <D.20497>; else goto <D.20498>;
  <D.20497>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 126, "*endbuf <= limit");
  <D.20498>:
  D.20500 = *buf;
  D.20501 = (int) D.20500;
  D.20502 = buf + 1;
  D.20503 = *D.20502;
  D.20504 = (int) D.20503;
  D.20505 = D.20504 << 8;
  D.20506 = D.20501 | D.20505;
  D.20507 = buf + 2;
  D.20508 = *D.20507;
  D.20509 = (int) D.20508;
  D.20510 = D.20509 << 16;
  D.20511 = D.20506 | D.20510;
  D.20512 = buf + 3;
  D.20513 = *D.20512;
  D.20514 = (int) D.20513;
  D.20515 = D.20514 << 24;
  D.20499 = D.20511 | D.20515;
  return D.20499;
}


read (int __fd, void * __buf, size_t __nbytes)
{
  unsigned int D.20517;
  int D.20520;
  ssize_t D.20523;
  unsigned int D.20524;
  unsigned int D.20525;
  unsigned int D.20528;

  D.20517 = __builtin_object_size (__buf, 0);
  if (D.20517 != 4294967295) goto <D.20518>; else goto <D.20519>;
  <D.20518>:
  D.20520 = __builtin_constant_p (__nbytes);
  if (D.20520 == 0) goto <D.20521>; else goto <D.20522>;
  <D.20521>:
  D.20524 = __builtin_object_size (__buf, 0);
  D.20523 = __read_chk (__fd, __buf, __nbytes, D.20524);
  return D.20523;
  <D.20522>:
  D.20525 = __builtin_object_size (__buf, 0);
  if (D.20525 < __nbytes) goto <D.20526>; else goto <D.20527>;
  <D.20526>:
  D.20528 = __builtin_object_size (__buf, 0);
  D.20523 = __read_chk_warn (__fd, __buf, __nbytes, D.20528);
  return D.20523;
  <D.20527>:
  <D.20519>:
  D.20523 = __read_alias (__fd, __buf, __nbytes);
  return D.20523;
}


decode_string_value (guint8 * buf, guint8 * * endbuf, guint8 * limit)
{
  guint8 * p.18;
  char * D.20533;
  _Bool D.20534;
  long int D.20535;
  long int D.20536;
  int D.20539;
  int D.20540;
  signed char b.19;
  _Bool D.20543;
  long int D.20544;
  long int D.20545;
  int D.20548;
  unsigned int D.20549;
  sizetype length.20;
  guint8 * p.22;
  _Bool D.20552;
  long int D.20553;
  long int D.20554;
  unsigned int length.21;
  char * D.20558;
  int type;
  gint32 length;
  guint8 * p;
  char * s;

  try
    {
      p = buf;
      p.18 = p;
      type = decode_byte (p.18, &p, limit);
      if (type == 17) goto <D.20531>; else goto <D.20532>;
      <D.20531>:
      p.18 = p;
      *endbuf = p.18;
      D.20533 = 0B;
      return D.20533;
      <D.20532>:
      D.20534 = type != 18;
      D.20535 = (long int) D.20534;
      D.20536 = __builtin_expect (D.20535, 0);
      if (D.20536 != 0) goto <D.20537>; else goto <D.20538>;
      <D.20537>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 153, "type == PRIM_TYPE_STRING");
      <D.20538>:
      length = 0;
      <D.20207>:
      {
        guint8 b;

        p.18 = p;
        D.20539 = decode_byte (p.18, &p, limit);
        b = (guint8) D.20539;
        length = length << 8;
        D.20540 = (int) b;
        length = D.20540 + length;
        b.19 = (signed char) b;
        if (b.19 >= 0) goto <D.20206>; else goto <D.20542>;
        <D.20542>:
      }
      goto <D.20207>;
      <D.20206>:
      D.20543 = length > 65535;
      D.20544 = (long int) D.20543;
      D.20545 = __builtin_expect (D.20544, 0);
      if (D.20545 != 0) goto <D.20546>; else goto <D.20547>;
      <D.20546>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 165, "length < (1 << 16)");
      <D.20547>:
      D.20548 = length + 1;
      D.20549 = (unsigned int) D.20548;
      s = monoeg_malloc (D.20549);
      p.18 = p;
      length.20 = (sizetype) length;
      p.22 = p.18 + length.20;
      D.20552 = p.22 > limit;
      D.20553 = (long int) D.20552;
      D.20554 = __builtin_expect (D.20553, 0);
      if (D.20554 != 0) goto <D.20555>; else goto <D.20556>;
      <D.20555>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 169, "p + length <= limit");
      <D.20556>:
      p.18 = p;
      length.21 = (unsigned int) length;
      memcpy (s, p.18, length.21);
      length.20 = (sizetype) length;
      D.20558 = s + length.20;
      *D.20558 = 0;
      p.18 = p;
      length.20 = (sizetype) length;
      p.22 = p.18 + length.20;
      p = p.22;
      p.18 = p;
      *endbuf = p.18;
      D.20533 = s;
      return D.20533;
    }
  finally
    {
      p = {CLOBBER};
    }
}


decode_byte (guint8 * buf, guint8 * * endbuf, guint8 * limit)
{
  guint8 * D.20561;
  guint8 * D.20562;
  _Bool D.20563;
  long int D.20564;
  long int D.20565;
  int D.20568;
  unsigned char D.20569;

  D.20561 = buf + 1;
  *endbuf = D.20561;
  D.20562 = *endbuf;
  D.20563 = D.20562 > limit;
  D.20564 = (long int) D.20563;
  D.20565 = __builtin_expect (D.20564, 0);
  if (D.20565 != 0) goto <D.20566>; else goto <D.20567>;
  <D.20566>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 118, "*endbuf <= limit");
  <D.20567>:
  D.20569 = *buf;
  D.20568 = (int) D.20569;
  return D.20568;
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.20571;
  unsigned int D.20572;

  D.20572 = __builtin_object_size (__dest, 0);
  D.20571 = __builtin___memcpy_chk (__dest, __src, __len, D.20572);
  return D.20571;
}


mono_attach_load_agent (struct MonoDomain * domain, char * agent, char * args, struct MonoObject * * exc)
{
  struct _IO_FILE * stderr.23;
  <unnamed type> open_status.24;
  const char * D.20578;
  int D.20579;
  const char * D.20582;
  struct MonoClass * D.20587;
  struct MonoString * D.20588;
  struct MonoAssembly * agent_assembly;
  struct MonoImage * image;
  struct MonoMethod * method;
  guint32 entry;
  struct MonoArray * main_args;
  void * pa[1];
  MonoImageOpenStatus open_status;

  try
    {
      agent_assembly = mono_assembly_open (agent, &open_status);
      if (agent_assembly == 0B) goto <D.20574>; else goto <D.20575>;
      <D.20574>:
      stderr.23 = stderr;
      open_status.24 = open_status;
      D.20578 = mono_image_strerror (open_status.24);
      fprintf (stderr.23, "Cannot open agent assembly \'%s\': %s.\n", agent, D.20578);
      monoeg_g_free (agent);
      D.20579 = 2;
      return D.20579;
      <D.20575>:
      image = mono_assembly_get_image (agent_assembly);
      entry = mono_image_get_entry_point (image);
      if (entry == 0) goto <D.20580>; else goto <D.20581>;
      <D.20580>:
      D.20582 = mono_image_get_filename (image);
      monoeg_g_print ("Assembly \'%s\' doesn\'t have an entry point.\n", D.20582);
      monoeg_g_free (agent);
      D.20579 = 1;
      return D.20579;
      <D.20581>:
      method = mono_get_method (image, entry, 0B);
      if (method == 0B) goto <D.20583>; else goto <D.20584>;
      <D.20583>:
      monoeg_g_print ("The entry point method of assembly \'%s\' could not be loaded\n", agent);
      monoeg_g_free (agent);
      D.20579 = 1;
      return D.20579;
      <D.20584>:
      if (args != 0B) goto <D.20585>; else goto <D.20586>;
      <D.20585>:
      D.20587 = mono_defaults.string_class;
      main_args = mono_array_new (domain, D.20587, 1);
      {
        struct MonoString * * __p;

        __p = mono_array_addr_with_size (main_args, 4, 0);
        D.20588 = mono_string_new (domain, args);
        *__p = D.20588;
      }
      goto <D.20589>;
      <D.20586>:
      D.20587 = mono_defaults.string_class;
      main_args = mono_array_new (domain, D.20587, 0);
      <D.20589>:
      monoeg_g_free (agent);
      pa[0] = main_args;
      mono_runtime_invoke (method, 0B, &pa, exc);
      D.20579 = 0;
      return D.20579;
    }
  finally
    {
      pa = {CLOBBER};
      open_status = {CLOBBER};
    }
}


printf (const char * restrict __fmt)
{
  int D.20592;

  D.20592 = __printf_chk (1, __fmt, __builtin_va_arg_pack ());
  return D.20592;
}


transport_connect ()
{
  ipc_connect ();
}


ipc_connect ()
{
  unsigned int D.20594;
  unsigned int D.20595;
  struct _IO_FILE * stderr.25;
  unsigned int D.20601;
  struct passwd * pw.26;
  _Bool D.20605;
  long int D.20606;
  long int D.20607;
  char * D.20610;
  int * D.20613;
  int D.20614;
  unsigned int D.20619;
  unsigned int D.20620;
  unsigned int D.20623;
  unsigned int D.20624;
  unsigned int D.20627;
  unsigned int D.20628;
  int D.20632;
  unsigned int D.20633;
  union 
{
  const struct sockaddr * restrict __sockaddr__;
  const struct sockaddr_at * restrict __sockaddr_at__;
  const struct sockaddr_ax25 * restrict __sockaddr_ax25__;
  const struct sockaddr_dl * restrict __sockaddr_dl__;
  const struct sockaddr_eon * restrict __sockaddr_eon__;
  const struct sockaddr_in * restrict __sockaddr_in__;
  const struct sockaddr_in6 * restrict __sockaddr_in6__;
  const struct sockaddr_inarp * restrict __sockaddr_inarp__;
  const struct sockaddr_ipx * restrict __sockaddr_ipx__;
  const struct sockaddr_iso * restrict __sockaddr_iso__;
  const struct sockaddr_ns * restrict __sockaddr_ns__;
  const struct sockaddr_un * restrict __sockaddr_un__;
  const struct sockaddr_x25 * restrict __sockaddr_x25__;
} D.20634;
  int D.20635;
  char * D.20638;
  char * D.20643;
  gchar * ipc_filename.27;
  int D.20645;
  gchar * server_uri.28;
  struct sockaddr_un name;
  int sock;
  int res;
  size_t size;
  char * filename;
  char * directory;
  struct stat stat;
  struct passwd pwbuf;
  char buf[1024];
  struct passwd * pw;

  try
    {
      D.20594 = getuid ();
      D.20595 = geteuid ();
      if (D.20594 != D.20595) goto <D.20596>; else goto <D.20597>;
      <D.20596>:
      stderr.25 = stderr;
      fprintf (stderr.25, "attach: disabled listening on an IPC socket when running in setuid mode.\n");
      return;
      <D.20597>:
      sock = socket (1, 1, 0);
      if (sock < 0) goto <D.20599>; else goto <D.20600>;
      <D.20599>:
      perror ("attach: failed to create IPC socket");
      return;
      <D.20600>:
      pw = 0B;
      D.20601 = getuid ();
      res = getpwuid_r (D.20601, &pwbuf, &buf, 1024, &pw);
      if (res != 0) goto <D.20602>; else goto <D.20603>;
      <D.20602>:
      stderr.25 = stderr;
      fprintf (stderr.25, "attach: getpwuid_r () failed.\n");
      return;
      <D.20603>:
      pw.26 = pw;
      D.20605 = pw.26 == 0B;
      D.20606 = (long int) D.20605;
      D.20607 = __builtin_expect (D.20606, 0);
      if (D.20607 != 0) goto <D.20608>; else goto <D.20609>;
      <D.20608>:
      monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "attach.c", 379, "pw");
      <D.20609>:
      pw.26 = pw;
      D.20610 = pw.26->pw_name;
      directory = monoeg_g_strdup_printf ("/tmp/mono-%s", D.20610);
      res = mkdir (directory, 448);
      if (res != 0) goto <D.20611>; else goto <D.20612>;
      <D.20611>:
      D.20613 = __errno_location ();
      D.20614 = *D.20613;
      if (D.20614 == 17) goto <D.20615>; else goto <D.20616>;
      <D.20615>:
      res = lstat (directory, &stat);
      if (res != 0) goto <D.20617>; else goto <D.20618>;
      <D.20617>:
      perror ("attach: lstat () failed");
      return;
      <D.20618>:
      D.20619 = stat.st_mode;
      D.20620 = D.20619 & 61440;
      if (D.20620 != 16384) goto <D.20621>; else goto <D.20622>;
      <D.20621>:
      stderr.25 = stderr;
      fprintf (stderr.25, "attach: path \'%s\' is not a directory.\n", directory);
      return;
      <D.20622>:
      D.20623 = stat.st_uid;
      D.20624 = getuid ();
      if (D.20623 != D.20624) goto <D.20625>; else goto <D.20626>;
      <D.20625>:
      stderr.25 = stderr;
      fprintf (stderr.25, "attach: directory \'%s\' is not owned by the current user.\n", directory);
      return;
      <D.20626>:
      D.20627 = BIT_FIELD_REF <stat, 32, 128>;
      D.20628 = D.20627 & 511;
      if (D.20628 != 448) goto <D.20629>; else goto <D.20630>;
      <D.20629>:
      stderr.25 = stderr;
      fprintf (stderr.25, "attach: directory \'%s\' should have protection 0700.\n", directory);
      return;
      <D.20630>:
      goto <D.20631>;
      <D.20616>:
      perror ("attach: mkdir () failed");
      return;
      <D.20631>:
      <D.20612>:
      D.20632 = getpid ();
      filename = monoeg_g_strdup_printf ("%s/.mono-%d", directory, D.20632);
      unlink (filename);
      name.sun_family = 1;
      strcpy (&name.sun_path, filename);
      D.20633 = strlen (&name.sun_path);
      size = D.20633 + 3;
      D.20634.__sockaddr__ = &name;
      D.20635 = bind (sock, D.20634, size);
      if (D.20635 < 0) goto <D.20636>; else goto <D.20637>;
      <D.20636>:
      stderr.25 = stderr;
      D.20613 = __errno_location ();
      D.20614 = *D.20613;
      D.20638 = strerror (D.20614);
      fprintf (stderr.25, "attach: failed to bind IPC socket \'%s\': %s\n", filename, D.20638);
      close (sock);
      return;
      <D.20637>:
      res = chmod (filename, 384);
      if (res != 0) goto <D.20639>; else goto <D.20640>;
      <D.20639>:
      perror ("attach: failed to set permissions on IPC socket");
      close (sock);
      unlink (filename);
      return;
      <D.20640>:
      res = listen (sock, 16);
      if (res != 0) goto <D.20641>; else goto <D.20642>;
      <D.20641>:
      stderr.25 = stderr;
      D.20613 = __errno_location ();
      D.20614 = *D.20613;
      D.20643 = strerror (D.20614);
      fprintf (stderr.25, "attach: listen () failed: %s\n", D.20643);
      exit (1);
      <D.20642>:
      listen_fd = sock;
      ipc_filename.27 = monoeg_strdup (filename);
      ipc_filename = ipc_filename.27;
      D.20645 = getpid ();
      server_uri.28 = monoeg_g_strdup_printf ("unix://%s/.mono-%d?/vm", directory, D.20645);
      server_uri = server_uri.28;
      monoeg_g_free (filename);
      monoeg_g_free (directory);
    }
  finally
    {
      name = {CLOBBER};
      stat = {CLOBBER};
      pwbuf = {CLOBBER};
      buf = {CLOBBER};
      pw = {CLOBBER};
    }
}


lstat (const char * __path, struct stat * __statbuf)
{
  int D.20650;

  D.20650 = __lxstat (3, __path, __statbuf);
  return D.20650;
}


strcpy (char * restrict __dest, const char * restrict __src)
{
  char * D.20652;
  unsigned int D.20653;

  D.20653 = __builtin_object_size (__dest, 1);
  D.20652 = __builtin___strcpy_chk (__dest, __src, D.20653);
  return D.20652;
}


monoeg_strdup (const gchar * str)
{
  gchar * D.20657;

  if (str != 0B) goto <D.20655>; else goto <D.20656>;
  <D.20655>:
  D.20657 = __strdup (str);
  return D.20657;
  <D.20656>:
  D.20657 = 0B;
  return D.20657;
}


mono_attach_cleanup ()
{
  int listen_fd.29;
  char * ipc_filename.30;
  int conn_fd.31;
  void * receiver_thread_handle.32;

  listen_fd.29 = listen_fd;
  if (listen_fd.29 != 0) goto <D.20660>; else goto <D.20661>;
  <D.20660>:
  listen_fd.29 = listen_fd;
  close (listen_fd.29);
  <D.20661>:
  ipc_filename.30 = ipc_filename;
  if (ipc_filename.30 != 0B) goto <D.20663>; else goto <D.20664>;
  <D.20663>:
  ipc_filename.30 = ipc_filename;
  unlink (ipc_filename.30);
  <D.20664>:
  stop_receiver_thread = 1;
  conn_fd.31 = conn_fd;
  if (conn_fd.31 != 0) goto <D.20666>; else goto <D.20667>;
  <D.20666>:
  conn_fd.31 = conn_fd;
  close (conn_fd.31);
  <D.20667>:
  receiver_thread_handle.32 = receiver_thread_handle;
  if (receiver_thread_handle.32 != 0B) goto <D.20669>; else goto <D.20670>;
  <D.20669>:
  receiver_thread_handle.32 = receiver_thread_handle;
  WaitForSingleObjectEx (receiver_thread_handle.32, 0, 0);
  <D.20670>:
}


