aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2013-12-03 18:51:59 +0000
committerEd Maste <emaste@FreeBSD.org>2013-12-03 18:51:59 +0000
commit86758c718870f701bc69c1ca05495305ed1c5b85 (patch)
treeb2051e4e4856cc58ac7e2d20242b870b4f355ca1 /tools
parentf21a844f60ae6c74fcf1fddca32461acce3c1ee0 (diff)
downloadsrc-86758c718870f701bc69c1ca05495305ed1c5b85.tar.gz
src-86758c718870f701bc69c1ca05495305ed1c5b85.zip
Import lldb as of SVN r196259 (git 3be86e5)vendor/lldb/lldb-r196259
(A number of files not required for the FreeBSD build have been removed.) Sponsored by: DARPA, AFRL
Notes
Notes: svn path=/vendor/lldb/dist/; revision=258882 svn path=/vendor/lldb/lldb-r196259/; revision=258883; tag=vendor/lldb/lldb-r196259
Diffstat (limited to 'tools')
-rw-r--r--tools/lldb-platform/lldb-platform.cpp215
1 files changed, 131 insertions, 84 deletions
diff --git a/tools/lldb-platform/lldb-platform.cpp b/tools/lldb-platform/lldb-platform.cpp
index 007e69c92814..bc9d62974771 100644
--- a/tools/lldb-platform/lldb-platform.cpp
+++ b/tools/lldb-platform/lldb-platform.cpp
@@ -21,11 +21,15 @@
// C++ Includes
// Other libraries and framework includes
+#include "lldb/lldb-private-log.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/ConnectionMachPort.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
using namespace lldb;
@@ -44,24 +48,32 @@ static struct option g_long_options[] =
{ "debug", no_argument, &g_debug, 1 },
{ "verbose", no_argument, &g_verbose, 1 },
{ "stay-alive", no_argument, &g_stay_alive, 1 },
- { "log-file", required_argument, NULL, 'l' },
- { "log-flags", required_argument, NULL, 'f' },
{ "listen", required_argument, NULL, 'L' },
+ { "port-offset", required_argument, NULL, 'p' },
+ { "gdbserver-port", required_argument, NULL, 'P' },
+ { "min-gdbserver-port", required_argument, NULL, 'm' },
+ { "max-gdbserver-port", required_argument, NULL, 'M' },
+ { "lldb-command", required_argument, NULL, 'c' },
{ NULL, 0, NULL, 0 }
};
+#if defined (__APPLE__)
+#define LOW_PORT (IPPORT_RESERVED)
+#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
+#else
+#define LOW_PORT (1024u)
+#define HIGH_PORT (49151u)
+#endif
+
+
//----------------------------------------------------------------------
// Watch for signals
//----------------------------------------------------------------------
-int g_sigpipe_received = 0;
void
signal_handler(int signo)
{
switch (signo)
{
- case SIGPIPE:
- g_sigpipe_received = 1;
- break;
case SIGHUP:
// Use SIGINT first, if that does not work, use SIGHUP as a last resort.
// And we should not call exit() here because it results in the global destructors
@@ -86,130 +98,165 @@ int
main (int argc, char *argv[])
{
const char *progname = argv[0];
- signal (SIGPIPE, signal_handler);
+ signal (SIGPIPE, SIG_IGN);
signal (SIGHUP, signal_handler);
int long_option_index = 0;
- StreamSP log_stream_sp;
- Args log_args;
Error error;
std::string listen_host_port;
int ch;
- Debugger::Initialize();
+ Debugger::Initialize(NULL);
+
+ lldb::DebuggerSP debugger_sp = Debugger::CreateInstance ();
+
+ debugger_sp->SetInputFileHandle(stdin, false);
+ debugger_sp->SetOutputFileHandle(stdout, false);
+ debugger_sp->SetErrorFileHandle(stderr, false);
-// ConnectionMachPort a;
-// ConnectionMachPort b;
-//
-// lldb::ConnectionStatus status;
-// const char *bootstrap_service_name = "HelloWorld";
-// status = a.BootstrapCheckIn(bootstrap_service_name, &error);
-//
-// if (status != eConnectionStatusSuccess)
-// {
-// fprintf(stderr, "%s", error.AsCString());
-// return 1;
-// }
-// status = b.BootstrapLookup (bootstrap_service_name, &error);
-// if (status != eConnectionStatusSuccess)
-// {
-// fprintf(stderr, "%s", error.AsCString());
-// return 2;
-// }
-//
-// if (a.Write ("hello", 5, status, &error) == 5)
-// {
-// char buf[32];
-// memset(buf, 0, sizeof(buf));
-// if (b.Read (buf, 5, status, &error))
-// {
-// printf("read returned bytes: %s", buf);
-// }
-// else
-// {
-// fprintf(stderr, "%s", error.AsCString());
-// return 4;
-// }
-// }
-// else
-// {
-// fprintf(stderr, "%s", error.AsCString());
-// return 3;
-// }
+ GDBRemoteCommunicationServer::PortMap gdbserver_portmap;
+ int min_gdbserver_port = 0;
+ int max_gdbserver_port = 0;
+ uint16_t port_offset = 0;
+
+ std::vector<std::string> lldb_commands;
+ bool show_usage = false;
+ int option_error = 0;
- while ((ch = getopt_long_only(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1)
+ std::string short_options(OptionParser::GetShortOptionString(g_long_options));
+
+#if __GLIBC__
+ optind = 0;
+#else
+ optreset = 1;
+ optind = 1;
+#endif
+
+ while ((ch = getopt_long_only(argc, argv, short_options.c_str(), g_long_options, &long_option_index)) != -1)
{
-// DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
-// ch, (uint8_t)ch,
-// g_long_options[long_option_index].name,
-// g_long_options[long_option_index].has_arg ? '=' : ' ',
-// optarg ? optarg : "");
switch (ch)
{
case 0: // Any optional that auto set themselves will return 0
break;
- case 'l': // Set Log File
- if (optarg && optarg[0])
+ case 'L':
+ listen_host_port.append (optarg);
+ break;
+
+ case 'p':
{
- if ((strcasecmp(optarg, "stdout") == 0) || (strcmp(optarg, "/dev/stdout") == 0))
+ char *end = NULL;
+ long tmp_port_offset = strtoul(optarg, &end, 0);
+ if (end && *end == '\0')
{
- log_stream_sp.reset (new StreamFile (stdout, false));
+ if (LOW_PORT <= tmp_port_offset && tmp_port_offset <= HIGH_PORT)
+ {
+ port_offset = (uint16_t)tmp_port_offset;
+ }
+ else
+ {
+ fprintf (stderr, "error: port offset %li is not in the valid user port range of %u - %u\n", tmp_port_offset, LOW_PORT, HIGH_PORT);
+ option_error = 5;
+ }
}
- else if ((strcasecmp(optarg, "stderr") == 0) || (strcmp(optarg, "/dev/stderr") == 0))
+ else
{
- log_stream_sp.reset (new StreamFile (stderr, false));
+ fprintf (stderr, "error: invalid port offset string %s\n", optarg);
+ option_error = 4;
}
- else
+ }
+ break;
+
+ case 'P':
+ case 'm':
+ case 'M':
+ {
+ char *end = NULL;
+ long portnum = strtoul(optarg, &end, 0);
+ if (end && *end == '\0')
{
- FILE *log_file = fopen(optarg, "w");
- if (log_file)
+ if (LOW_PORT <= portnum && portnum <= HIGH_PORT)
{
- setlinebuf(log_file);
- log_stream_sp.reset (new StreamFile (log_file, true));
+ if (ch == 'P')
+ gdbserver_portmap[(uint16_t)portnum] = LLDB_INVALID_PROCESS_ID;
+ else if (ch == 'm')
+ min_gdbserver_port = portnum;
+ else
+ max_gdbserver_port = portnum;
}
else
{
- const char *errno_str = strerror(errno);
- fprintf (stderr, "Failed to open log file '%s' for writing: errno = %i (%s)", optarg, errno, errno_str ? errno_str : "unknown error");
+ fprintf (stderr, "error: port number %li is not in the valid user port range of %u - %u\n", portnum, LOW_PORT, HIGH_PORT);
+ option_error = 1;
}
-
}
-
+ else
+ {
+ fprintf (stderr, "error: invalid port number string %s\n", optarg);
+ option_error = 2;
+ }
}
break;
-
- case 'f': // Log Flags
- if (optarg && optarg[0])
- log_args.AppendArgument(optarg);
- break;
-
- case 'L':
- listen_host_port.append (optarg);
+
+ case 'c':
+ lldb_commands.push_back(optarg);
break;
case 'h': /* fall-through is intentional */
case '?':
- display_usage(progname);
+ show_usage = true;
break;
}
}
+
+ // Make a port map for a port range that was specified.
+ if (min_gdbserver_port < max_gdbserver_port)
+ {
+ for (uint16_t port = min_gdbserver_port; port < max_gdbserver_port; ++port)
+ gdbserver_portmap[port] = LLDB_INVALID_PROCESS_ID;
+ }
+ else if (min_gdbserver_port != max_gdbserver_port)
+ {
+ fprintf (stderr, "error: --min-gdbserver-port (%u) is greater than --max-gdbserver-port (%u)\n", min_gdbserver_port, max_gdbserver_port);
+ option_error = 3;
+
+ }
+
// Print usage and exit if no listening port is specified.
if (listen_host_port.empty())
- display_usage(progname);
+ show_usage = true;
- if (log_stream_sp)
+ if (show_usage || option_error)
{
- if (log_args.GetArgumentCount() == 0)
- log_args.AppendArgument("default");
- ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args.GetConstArgumentVector(), log_stream_sp.get());
+ display_usage(progname);
+ exit(option_error);
}
-
+
// Skip any options we consumed with getopt_long_only
argc -= optind;
argv += optind;
+ // Execute any LLDB commands that we were asked to evaluate.
+ for (const auto &lldb_command : lldb_commands)
+ {
+ lldb_private::CommandReturnObject result;
+ printf("(lldb) %s\n", lldb_command.c_str());
+ debugger_sp->GetCommandInterpreter().HandleCommand(lldb_command.c_str(), eLazyBoolNo, result);
+ const char *output = result.GetOutputData();
+ if (output && output[0])
+ puts(output);
+ }
+
do {
GDBRemoteCommunicationServer gdb_server (true);
+
+ if (port_offset > 0)
+ gdb_server.SetPortOffset(port_offset);
+
+ if (!gdbserver_portmap.empty())
+ {
+ gdb_server.SetPortMap(std::move(gdbserver_portmap));
+ }
+
if (!listen_host_port.empty())
{
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());