summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/base/remote_gdb.cc90
-rw-r--r--src/base/remote_gdb.hh29
2 files changed, 117 insertions, 2 deletions
diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc
index 2c54f5b5f..d620665b6 100644
--- a/src/base/remote_gdb.cc
+++ b/src/base/remote_gdb.cc
@@ -1,4 +1,15 @@
/*
+ * Copyright (c) 2018 ARM Limited
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright 2015 LabWare
* Copyright 2014 Google, Inc.
* Copyright (c) 2002-2005 The Regents of The University of Michigan
@@ -127,6 +138,7 @@
#include <csignal>
#include <cstdint>
#include <cstdio>
+#include <sstream>
#include <string>
#include "arch/vtophys.hh"
@@ -966,12 +978,86 @@ BaseRemoteGDB::cmd_mem_w(GdbCommand::Context &ctx)
bool
BaseRemoteGDB::cmd_query_var(GdbCommand::Context &ctx)
{
- if (string(ctx.data, ctx.len - 1) != "C")
+ string s(ctx.data, ctx.len - 1);
+ string xfer_read_prefix = "Xfer:features:read:";
+ if (s.rfind("Supported:", 0) == 0) {
+ std::ostringstream oss;
+ // This reply field mandatory. We can receive arbitrarily
+ // long packets, so we could choose it to be arbitrarily large.
+ // This is just an arbitrary filler value that seems to work.
+ oss << "PacketSize=1024";
+ for (const auto& feature : availableFeatures())
+ oss << ';' << feature;
+ send(oss.str().c_str());
+ } else if (s.rfind(xfer_read_prefix, 0) == 0) {
+ size_t offset, length;
+ auto value_string = s.substr(xfer_read_prefix.length());
+ auto colon_pos = value_string.find(':');
+ auto comma_pos = value_string.find(',');
+ if (colon_pos == std::string::npos || comma_pos == std::string::npos)
+ throw CmdError("E00");
+ std::string annex;
+ if (!getXferFeaturesRead(value_string.substr(0, colon_pos), annex))
+ throw CmdError("E00");
+ try {
+ offset = std::stoull(
+ value_string.substr(colon_pos + 1, comma_pos), NULL, 16);
+ length = std::stoull(
+ value_string.substr(comma_pos + 1), NULL, 16);
+ } catch (std::invalid_argument& e) {
+ throw CmdError("E00");
+ } catch (std::out_of_range& e) {
+ throw CmdError("E00");
+ }
+ std::string encoded;
+ encodeXferResponse(annex, encoded, offset, length);
+ send(encoded.c_str());
+ } else if (s == "C") {
+ send("QC0");
+ } else {
throw Unsupported();
- send("QC0");
+ }
return true;
}
+std::vector<std::string>
+BaseRemoteGDB::availableFeatures() const
+{
+ return {};
+};
+
+bool
+BaseRemoteGDB::getXferFeaturesRead(
+ const std::string &annex, std::string &output)
+{
+ return false;
+}
+
+void
+BaseRemoteGDB::encodeBinaryData(
+ const std::string &unencoded, std::string &encoded) const
+{
+ for (const char& c : unencoded) {
+ if (c == '$' || c == '#' || c == '}' || c == '*') {
+ encoded += '}';
+ encoded += c ^ 0x20;
+ } else {
+ encoded += c;
+ }
+ }
+}
+
+void
+BaseRemoteGDB::encodeXferResponse(const std::string &unencoded,
+ std::string &encoded, size_t offset, size_t unencoded_length) const
+{
+ if (offset + unencoded_length < unencoded.length())
+ encoded += 'm';
+ else
+ encoded += 'l';
+ encodeBinaryData(unencoded.substr(offset, unencoded_length), encoded);
+}
+
bool
BaseRemoteGDB::cmd_async_step(GdbCommand::Context &ctx)
{
diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh
index 82a1e15bc..123376cd0 100644
--- a/src/base/remote_gdb.hh
+++ b/src/base/remote_gdb.hh
@@ -1,4 +1,15 @@
/*
+ * Copyright (c) 2018 ARM Limited
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright 2015 LabWare
* Copyright 2014 Google, Inc.
* Copyright (c) 2002-2005 The Regents of The University of Michigan
@@ -276,12 +287,30 @@ class BaseRemoteGDB
ThreadContext *context() { return tc; }
System *system() { return sys; }
+ void encodeBinaryData(const std::string &unencoded,
+ std::string &encoded) const;
+
+ void encodeXferResponse(const std::string &unencoded,
+ std::string &encoded, size_t offset, size_t unencoded_length) const;
+
// To be implemented by subclasses.
virtual bool checkBpLen(size_t len);
virtual BaseGdbRegCache *gdbRegs() = 0;
virtual bool acc(Addr addr, size_t len) = 0;
+
+ virtual std::vector<std::string> availableFeatures() const;
+
+ /**
+ * Get an XML target description.
+ *
+ * @param[in] annex the XML filename
+ * @param[out] output set to the decoded XML
+ * @return true if the given annex was found
+ */
+ virtual bool getXferFeaturesRead(const std::string &annex,
+ std::string &output);
};
template <class T>