diff options
-rw-r--r-- | src/base/remote_gdb.cc | 90 | ||||
-rw-r--r-- | src/base/remote_gdb.hh | 29 |
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> |