1b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//===-- lldb-platform.cpp ---------------------------------------*- C++ -*-===//
2b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//
3b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//                     The LLVM Compiler Infrastructure
4b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//
5b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// This file is distributed under the University of Illinois Open Source
6b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// License. See LICENSE.TXT for details.
7b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//
8b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//===----------------------------------------------------------------------===//
9b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h"
11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea
12cb8977d726be451df9978a74088435667fa37da2Greg Clayton// C Includes
13b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <errno.h>
14b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <getopt.h>
15b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <signal.h>
16b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <stdint.h>
17b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <stdio.h>
18b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <stdlib.h>
19b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <string.h>
20b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
21cb8977d726be451df9978a74088435667fa37da2Greg Clayton// C++ Includes
22cb8977d726be451df9978a74088435667fa37da2Greg Clayton
23cb8977d726be451df9978a74088435667fa37da2Greg Clayton// Other libraries and framework includes
24cb8977d726be451df9978a74088435667fa37da2Greg Clayton#include "lldb/Core/Error.h"
25cb8977d726be451df9978a74088435667fa37da2Greg Clayton#include "lldb/Core/ConnectionFileDescriptor.h"
2606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton#include "lldb/Core/ConnectionMachPort.h"
2758e26e0935138225477fd61283215ceff2068899Greg Clayton#include "lldb/Core/Debugger.h"
2858e26e0935138225477fd61283215ceff2068899Greg Clayton#include "lldb/Core/StreamFile.h"
2927cf23214479177c83f115b4dbac92b2dba2b3b2Greg Clayton#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
3058e26e0935138225477fd61283215ceff2068899Greg Clayton#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
31cb8977d726be451df9978a74088435667fa37da2Greg Claytonusing namespace lldb;
32cb8977d726be451df9978a74088435667fa37da2Greg Claytonusing namespace lldb_private;
33cb8977d726be451df9978a74088435667fa37da2Greg Clayton
34b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//----------------------------------------------------------------------
353f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton// option descriptors for getopt_long_only()
36b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//----------------------------------------------------------------------
37b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
38b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint g_debug = 0;
39b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint g_verbose = 0;
40b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
41b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonstatic struct option g_long_options[] =
42b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton{
43b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    { "debug",              no_argument,        &g_debug,           1   },
44b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    { "verbose",            no_argument,        &g_verbose,         1   },
45b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    { "log-file",           required_argument,  NULL,               'l' },
46b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    { "log-flags",          required_argument,  NULL,               'f' },
47cb8977d726be451df9978a74088435667fa37da2Greg Clayton    { "listen",             required_argument,  NULL,               'L' },
48b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    { NULL,                 0,                  NULL,               0   }
49b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton};
50b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
51b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//----------------------------------------------------------------------
52b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// Watch for signals
53b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//----------------------------------------------------------------------
54b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint g_sigpipe_received = 0;
55b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonvoid
56b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonsignal_handler(int signo)
57b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton{
58b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    switch (signo)
59b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    {
60b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    case SIGPIPE:
61b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        g_sigpipe_received = 1;
62b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        break;
63b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    }
64b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton}
65b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
66b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//----------------------------------------------------------------------
67b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// main
68b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//----------------------------------------------------------------------
69b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint
70b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonmain (int argc, char *argv[])
71b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton{
72b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    signal (SIGPIPE, signal_handler);
73b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    int long_option_index = 0;
7458e26e0935138225477fd61283215ceff2068899Greg Clayton    StreamSP log_stream_sp;
7558e26e0935138225477fd61283215ceff2068899Greg Clayton    Args log_args;
7606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton    Error error;
7763afdb07641f04aa7b60d895120b056124d3469bGreg Clayton    std::string listen_host_port;
78b51693999473f5dc7cb9681bbbc4a65028eea35bGreg Clayton    int ch;
7958e26e0935138225477fd61283215ceff2068899Greg Clayton    Debugger::Initialize();
8058e26e0935138225477fd61283215ceff2068899Greg Clayton
8106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    ConnectionMachPort a;
8206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    ConnectionMachPort b;
8306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//
8406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    lldb::ConnectionStatus status;
8506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    const char *bootstrap_service_name = "HelloWorld";
8606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    status = a.BootstrapCheckIn(bootstrap_service_name, &error);
8706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//
8806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    if (status != eConnectionStatusSuccess)
8906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    {
9006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        fprintf(stderr, "%s", error.AsCString());
9106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        return 1;
9206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    }
9306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    status = b.BootstrapLookup (bootstrap_service_name, &error);
9406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    if (status != eConnectionStatusSuccess)
9506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    {
9606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        fprintf(stderr, "%s", error.AsCString());
9706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        return 2;
9806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    }
9906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//
10006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    if (a.Write ("hello", 5, status, &error) == 5)
10106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    {
10206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        char buf[32];
10306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        memset(buf, 0, sizeof(buf));
10406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        if (b.Read (buf, 5, status, &error))
10506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        {
10606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//            printf("read returned bytes: %s", buf);
10706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        }
10806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        else
10906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        {
11006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//            fprintf(stderr, "%s", error.AsCString());
11106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//            return 4;
11206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        }
11306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    }
11406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    else
11506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    {
11606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        fprintf(stderr, "%s", error.AsCString());
11706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//        return 3;
11806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton//    }
11906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton
1203f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton    while ((ch = getopt_long_only(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1)
121b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    {
122b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//        DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
123b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//                    ch, (uint8_t)ch,
124b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//                    g_long_options[long_option_index].name,
125b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//                    g_long_options[long_option_index].has_arg ? '=' : ' ',
126b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//                    optarg ? optarg : "");
127b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        switch (ch)
128b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        {
129b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        case 0:   // Any optional that auto set themselves will return 0
130b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton            break;
131b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
132b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        case 'l': // Set Log File
133b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton            if (optarg && optarg[0])
134b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton            {
13558e26e0935138225477fd61283215ceff2068899Greg Clayton                if ((strcasecmp(optarg, "stdout") == 0) || (strcmp(optarg, "/dev/stdout") == 0))
13658e26e0935138225477fd61283215ceff2068899Greg Clayton                {
13758e26e0935138225477fd61283215ceff2068899Greg Clayton                    log_stream_sp.reset (new StreamFile (stdout, false));
13858e26e0935138225477fd61283215ceff2068899Greg Clayton                }
13958e26e0935138225477fd61283215ceff2068899Greg Clayton                else if ((strcasecmp(optarg, "stderr") == 0) || (strcmp(optarg, "/dev/stderr") == 0))
14058e26e0935138225477fd61283215ceff2068899Greg Clayton                {
14158e26e0935138225477fd61283215ceff2068899Greg Clayton                    log_stream_sp.reset (new StreamFile (stderr, false));
14258e26e0935138225477fd61283215ceff2068899Greg Clayton                }
143b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton                else
144b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton                {
14558e26e0935138225477fd61283215ceff2068899Greg Clayton                    FILE *log_file = fopen(optarg, "w");
14658e26e0935138225477fd61283215ceff2068899Greg Clayton                    if (log_file)
14758e26e0935138225477fd61283215ceff2068899Greg Clayton                    {
148b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton                        setlinebuf(log_file);
14958e26e0935138225477fd61283215ceff2068899Greg Clayton                        log_stream_sp.reset (new StreamFile (log_file, true));
15058e26e0935138225477fd61283215ceff2068899Greg Clayton                    }
15158e26e0935138225477fd61283215ceff2068899Greg Clayton                    else
15258e26e0935138225477fd61283215ceff2068899Greg Clayton                    {
15358e26e0935138225477fd61283215ceff2068899Greg Clayton                        const char *errno_str = strerror(errno);
15458e26e0935138225477fd61283215ceff2068899Greg Clayton                        fprintf (stderr, "Failed to open log file '%s' for writing: errno = %i (%s)", optarg, errno, errno_str ? errno_str : "unknown error");
15558e26e0935138225477fd61283215ceff2068899Greg Clayton                    }
15658e26e0935138225477fd61283215ceff2068899Greg Clayton
157b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton                }
158b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
159b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton            }
160b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton            break;
161b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
162b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        case 'f': // Log Flags
163b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton            if (optarg && optarg[0])
16458e26e0935138225477fd61283215ceff2068899Greg Clayton                log_args.AppendArgument(optarg);
165b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton            break;
166cb8977d726be451df9978a74088435667fa37da2Greg Clayton
167cb8977d726be451df9978a74088435667fa37da2Greg Clayton        case 'L':
16863afdb07641f04aa7b60d895120b056124d3469bGreg Clayton            listen_host_port.append (optarg);
169cb8977d726be451df9978a74088435667fa37da2Greg Clayton            break;
170b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton        }
171b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    }
172b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
17358e26e0935138225477fd61283215ceff2068899Greg Clayton    if (log_stream_sp)
17458e26e0935138225477fd61283215ceff2068899Greg Clayton    {
17558e26e0935138225477fd61283215ceff2068899Greg Clayton        if (log_args.GetArgumentCount() == 0)
17658e26e0935138225477fd61283215ceff2068899Greg Clayton            log_args.AppendArgument("default");
1776c530f2201be4788dedf3d5970399220fbd50b11Jim Ingham        ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args.GetConstArgumentVector(), log_stream_sp.get());
17858e26e0935138225477fd61283215ceff2068899Greg Clayton    }
17958e26e0935138225477fd61283215ceff2068899Greg Clayton
1803f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton    // Skip any options we consumed with getopt_long_only
181b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    argc -= optind;
182b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    argv += optind;
183b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
184b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
185b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton    GDBRemoteCommunicationServer gdb_server (true);
18663afdb07641f04aa7b60d895120b056124d3469bGreg Clayton    if (!listen_host_port.empty())
187cb8977d726be451df9978a74088435667fa37da2Greg Clayton    {
188102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
189cb8977d726be451df9978a74088435667fa37da2Greg Clayton        if (conn_ap.get())
190cb8977d726be451df9978a74088435667fa37da2Greg Clayton        {
19158e26e0935138225477fd61283215ceff2068899Greg Clayton            std::string connect_url ("listen://");
19263afdb07641f04aa7b60d895120b056124d3469bGreg Clayton            connect_url.append(listen_host_port.c_str());
193cb8977d726be451df9978a74088435667fa37da2Greg Clayton
19463afdb07641f04aa7b60d895120b056124d3469bGreg Clayton            printf ("Listening for a connection on %s...\n", listen_host_port.c_str());
19558e26e0935138225477fd61283215ceff2068899Greg Clayton            if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
19658e26e0935138225477fd61283215ceff2068899Greg Clayton            {
19758e26e0935138225477fd61283215ceff2068899Greg Clayton                printf ("Connection established.\n");
19858e26e0935138225477fd61283215ceff2068899Greg Clayton                gdb_server.SetConnection (conn_ap.release());
199cb8977d726be451df9978a74088435667fa37da2Greg Clayton            }
200cb8977d726be451df9978a74088435667fa37da2Greg Clayton        }
201cb8977d726be451df9978a74088435667fa37da2Greg Clayton    }
202cb8977d726be451df9978a74088435667fa37da2Greg Clayton
203cb8977d726be451df9978a74088435667fa37da2Greg Clayton
204cb8977d726be451df9978a74088435667fa37da2Greg Clayton    if (gdb_server.IsConnected())
205cb8977d726be451df9978a74088435667fa37da2Greg Clayton    {
20658e26e0935138225477fd61283215ceff2068899Greg Clayton        // After we connected, we need to get an initial ack from...
20758e26e0935138225477fd61283215ceff2068899Greg Clayton        if (gdb_server.HandshakeWithClient(&error))
208cb8977d726be451df9978a74088435667fa37da2Greg Clayton        {
209cb8977d726be451df9978a74088435667fa37da2Greg Clayton            bool interrupt = false;
210cb8977d726be451df9978a74088435667fa37da2Greg Clayton            bool done = false;
211cb8977d726be451df9978a74088435667fa37da2Greg Clayton            while (!interrupt && !done)
212cb8977d726be451df9978a74088435667fa37da2Greg Clayton            {
21363afdb07641f04aa7b60d895120b056124d3469bGreg Clayton                if (!gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done))
21458e26e0935138225477fd61283215ceff2068899Greg Clayton                    break;
215cb8977d726be451df9978a74088435667fa37da2Greg Clayton            }
216801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton
217801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton            if (error.Fail())
218801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton            {
219801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton                fprintf(stderr, "error: %s\n", error.AsCString());
220801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton            }
221cb8977d726be451df9978a74088435667fa37da2Greg Clayton        }
222cb8977d726be451df9978a74088435667fa37da2Greg Clayton        else
223cb8977d726be451df9978a74088435667fa37da2Greg Clayton        {
22458e26e0935138225477fd61283215ceff2068899Greg Clayton            fprintf(stderr, "error: handshake with client failed\n");
225cb8977d726be451df9978a74088435667fa37da2Greg Clayton        }
226cb8977d726be451df9978a74088435667fa37da2Greg Clayton    }
227b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton
22858e26e0935138225477fd61283215ceff2068899Greg Clayton    Debugger::Terminate();
22958e26e0935138225477fd61283215ceff2068899Greg Clayton
230b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton    return 0;
231b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton}
232