Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/44611 )

Change subject: base: Make the BaseRemoteGDB class able to handle multiple TCs.
......................................................................

base: Make the BaseRemoteGDB class able to handle multiple TCs.

Only one is set up corrent, the one passed in from the constructor.
Others can be added with addThreadContext.

The inconsistency of adding one ThreadContext through the constructor
and others through addThreadContext isn't great, but this way we can
ensure that there is always at least one ThreadContext. I'm not sure
what the GDB stub should do if there aren't any threads. I don't think
that the protocol can actually handle that, judging from the
documentation I can find.

Change-Id: I9160c3701ce78dcbbe99de1a6fe2a13e7e69404e
---
M src/base/remote_gdb.cc
M src/base/remote_gdb.hh
2 files changed, 53 insertions(+), 13 deletions(-)



diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc
index 6f5841b..20b26b9 100644
--- a/src/base/remote_gdb.cc
+++ b/src/base/remote_gdb.cc
@@ -132,6 +132,7 @@
 #include <sys/signal.h>
 #include <unistd.h>

+#include <cassert>
 #include <csignal>
 #include <cstdint>
 #include <cstdio>
@@ -350,9 +351,10 @@

BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, int _port) :
         connectEvent(nullptr), dataEvent(nullptr), _port(_port), fd(-1),
-        active(false), attached(false), sys(_system), tc(c),
+        active(false), attached(false), sys(_system),
         trapEvent(this), singleStepEvent(*this)
 {
+    addThreadContext(c);
 }

 BaseRemoteGDB::~BaseRemoteGDB()
@@ -437,11 +439,35 @@
 }

 void
+BaseRemoteGDB::addThreadContext(ThreadContext *_tc)
+{
+    threads[_tc->contextId()] = _tc;
+    // If no ThreadContext is current selected, select this one.
+    if (!tc)
+        assert(selectThreadContext(_tc->contextId()));
+}
+
+void
 BaseRemoteGDB::replaceThreadContext(ThreadContext *_tc)
 {
-    ContextID id = _tc->contextId();
-    panic_if(id != tc->contextId(), "No context with ID %d found.", id);
-    tc = _tc;
+    auto it = threads.find(_tc->contextId());
+    panic_if(it == threads.end(), "No context with ID %d found.",
+            _tc->contextId());
+    it->second = _tc;
+}
+
+bool
+BaseRemoteGDB::selectThreadContext(ContextID id)
+{
+    auto it = threads.find(id);
+    if (it == threads.end())
+        return false;
+
+    tc = it->second;
+ // Update the register cache for the new thread context, if there is one.
+    if (regCachePtr)
+        regCachePtr->getRegs(tc);
+    return true;
 }

 // This function does all command processing for interfacing to a
@@ -926,11 +952,13 @@
         // should complain.
         if (all)
             throw CmdError("E03");
- // If GDB cares which thread we're using and wants a different one, we
-        // don't support that right now.
-        if (!any && tid != tc->contextId())
-            throw CmdError("E04");
-        // Since we weren't asked to do anything, we succeeded.
+
+        // If GDB doesn't care which thread we're using, keep using the
+        // current one, otherwise switch.
+        if (!any && tid != tc->contextId()) {
+            if (!selectThreadContext(tid))
+                throw CmdError("E04");
+        }
     } else {
         throw CmdError("E05");
     }
@@ -1074,13 +1102,19 @@
 void
 BaseRemoteGDB::queryFThreadInfo(QuerySetCommand::Context &ctx)
 {
-    send("m%x", encodeThreadId(tc->contextId()));
+    threadInfoIdx = 0;
+    querySThreadInfo(ctx);
 }

 void
 BaseRemoteGDB::querySThreadInfo(QuerySetCommand::Context &ctx)
 {
-    send("l");
+    if (threadInfoIdx >= threads.size()) {
+        threadInfoIdx = 0;
+        send("l");
+    } else {
+        send("m%x", encodeThreadId(threads[threadInfoIdx++]->contextId()));
+    }
 }

 bool
diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh
index ba274e6..93a6026 100644
--- a/src/base/remote_gdb.hh
+++ b/src/base/remote_gdb.hh
@@ -163,7 +163,9 @@
     void detach();
     bool isAttached() { return attached; }

+    void addThreadContext(ThreadContext *_tc);
     void replaceThreadContext(ThreadContext *_tc);
+    bool selectThreadContext(ContextID id);

     bool trap(int type);

@@ -227,9 +229,11 @@
     bool attached;

     System *sys;
-    ThreadContext *tc;

-    BaseGdbRegCache *regCachePtr;
+    std::map<ContextID, ThreadContext *> threads;
+    ThreadContext *tc = nullptr;
+
+    BaseGdbRegCache *regCachePtr = nullptr;

     class TrapEvent : public Event
     {
@@ -340,6 +344,8 @@
     void queryC(QuerySetCommand::Context &ctx);
     void querySupported(QuerySetCommand::Context &ctx);
     void queryXfer(QuerySetCommand::Context &ctx);
+
+    size_t threadInfoIdx = 0;
     void queryFThreadInfo(QuerySetCommand::Context &ctx);
     void querySThreadInfo(QuerySetCommand::Context &ctx);


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/44611
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I9160c3701ce78dcbbe99de1a6fe2a13e7e69404e
Gerrit-Change-Number: 44611
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to