base: Adding multi-letter command support to GDB stub
The GDB remote protocol defines multi-letter command names that start with a "v". I added vKill and vMustReplyEmpty as an example. Change-Id: I10177729c7d6a3e7d469ce66a63bfcfd21aa6f83 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/63525 Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Maintainer: Bobby Bruce <bbruce@ucdavis.edu> Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
@@ -925,6 +925,8 @@ std::map<char, BaseRemoteGDB::GdbCommand> BaseRemoteGDB::commandMap = {
|
||||
{ 'S', { "KGDB_ASYNC_STEP", &BaseRemoteGDB::cmdAsyncStep } },
|
||||
// find out if the thread is alive
|
||||
{ 'T', { "KGDB_THREAD_ALIVE", &BaseRemoteGDB::cmdUnsupported } },
|
||||
//multi letter command
|
||||
{ 'v', { "KGDB_MULTI_LETTER", &BaseRemoteGDB::cmdMultiLetter } },
|
||||
// target exited
|
||||
{ 'W', { "KGDB_TARGET_EXIT", &BaseRemoteGDB::cmdUnsupported } },
|
||||
// write memory
|
||||
@@ -1104,6 +1106,67 @@ BaseRemoteGDB::cmdMemW(GdbCommand::Context &ctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseRemoteGDB::cmdMultiLetter(GdbCommand::Context &ctx)
|
||||
{
|
||||
GdbMultiLetterCommand::Context new_ctx;
|
||||
new_ctx.type = ctx.type;
|
||||
strtok(ctx.data,";?");
|
||||
char* sep = strtok(NULL,";:?");
|
||||
|
||||
int txt_len = (sep != NULL) ? (sep - ctx.data) : strlen(ctx.data);
|
||||
DPRINTF(GDBMisc, "Multi-letter: %s , len=%i\n", ctx.data,txt_len);
|
||||
new_ctx.cmdTxt = std::string(ctx.data,txt_len);
|
||||
new_ctx.data = sep;
|
||||
new_ctx.len = ctx.len - txt_len;
|
||||
try {
|
||||
auto cmd_it = multiLetterMap.find(new_ctx.cmdTxt);
|
||||
if (cmd_it == multiLetterMap.end()) {
|
||||
DPRINTF(GDBMisc, "Unknown command: %s\n", new_ctx.cmdTxt);
|
||||
throw Unsupported();
|
||||
}
|
||||
new_ctx.cmd = &(cmd_it->second);
|
||||
|
||||
return (this->*(new_ctx.cmd->func))(new_ctx);
|
||||
//catching errors: we don't need to catch anything else
|
||||
//as it will be handled by processCommands
|
||||
} catch (CmdError &e) {
|
||||
send(e.error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, BaseRemoteGDB::GdbMultiLetterCommand>
|
||||
BaseRemoteGDB::multiLetterMap = {
|
||||
{ "MustReplyEmpty", { "KGDB_REPLY_EMPTY", &BaseRemoteGDB::cmdReplyEmpty}},
|
||||
{ "Kill", { "KGDB_VKILL", &BaseRemoteGDB::cmdVKill}},
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
BaseRemoteGDB::cmdReplyEmpty(GdbMultiLetterCommand::Context &ctx)
|
||||
{
|
||||
send("");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseRemoteGDB::cmdVKill(GdbMultiLetterCommand::Context &ctx)
|
||||
{
|
||||
warn("GDB command for kill received detaching instead");
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseRemoteGDB::cmdMultiUnsupported(GdbMultiLetterCommand::Context &ctx)
|
||||
{
|
||||
DPRINTF(GDBMisc, "Unsupported Multi name command : %s\n",
|
||||
ctx.cmd->name);
|
||||
DDUMP(GDBMisc, ctx.data, ctx.len);
|
||||
throw Unsupported();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::pair<std::string, std::string>
|
||||
|
||||
@@ -344,6 +344,30 @@ class BaseRemoteGDB
|
||||
|
||||
static std::map<char, GdbCommand> commandMap;
|
||||
|
||||
struct GdbMultiLetterCommand
|
||||
{
|
||||
public:
|
||||
struct Context
|
||||
{
|
||||
const GdbMultiLetterCommand *cmd;
|
||||
std::string cmdTxt;
|
||||
int type;
|
||||
char *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
typedef bool (BaseRemoteGDB::*Func)(Context &ctx);
|
||||
|
||||
const char * const name;
|
||||
const Func func;
|
||||
|
||||
GdbMultiLetterCommand(const char *_name, Func _func) :
|
||||
name(_name), func(_func) {}
|
||||
};
|
||||
|
||||
|
||||
static std::map<std::string, GdbMultiLetterCommand> multiLetterMap;
|
||||
|
||||
bool cmdUnsupported(GdbCommand::Context &ctx);
|
||||
|
||||
bool cmdSignal(GdbCommand::Context &ctx);
|
||||
@@ -361,6 +385,13 @@ class BaseRemoteGDB
|
||||
bool cmdClrHwBkpt(GdbCommand::Context &ctx);
|
||||
bool cmdSetHwBkpt(GdbCommand::Context &ctx);
|
||||
bool cmdDumpPageTable(GdbCommand::Context &ctx);
|
||||
bool cmdMultiLetter(GdbCommand::Context &ctx);
|
||||
|
||||
//Multi letter command
|
||||
bool cmdMultiUnsupported(GdbMultiLetterCommand::Context &ctx);
|
||||
|
||||
bool cmdReplyEmpty(GdbMultiLetterCommand::Context &ctx);
|
||||
bool cmdVKill(GdbMultiLetterCommand::Context &ctx);
|
||||
|
||||
struct QuerySetCommand
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user