From b35a4096c621670bfd6ce3555d1b00b854e8f525 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Thu, 4 Feb 2010 09:55:07 +0100
Subject: [PATCH] debugger: start using TRK's 'multi instruction step' facility

---
 share/qtcreator/gdbmacros/dumper.py        | 77 +++++++++++++++-------
 src/plugins/debugger/gdb/gdbengine.cpp     |  6 ++
 src/plugins/debugger/gdb/trkgdbadapter.cpp | 32 ++++++++-
 src/plugins/debugger/gdb/trkgdbadapter.h   |  3 +-
 src/plugins/debugger/stackhandler.h        |  1 +
 5 files changed, 93 insertions(+), 26 deletions(-)

diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index c7836431a27..cf8d822cd4e 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -63,6 +63,30 @@ def parseAndEvaluate(exp):
     return gdb.history(0)
 
 
+def catchCliOutput(command):
+    file = tempfile.mkstemp(prefix="gdbpy_")
+    filename = file[1]
+    gdb.execute("set logging off")
+    gdb.execute("set logging redirect off")
+    gdb.execute("set logging file %s" % filename)
+    gdb.execute("set logging redirect on")
+    gdb.execute("set logging on")
+    gdb.execute(command)
+    gdb.execute("set logging off")
+    gdb.execute("set logging redirect off")
+    gdb.execute("set logging file \"\"")
+    file = open(filename, "r")
+    lines = []
+    for line in file:
+        lines.append(line)
+    file.close()
+    try:  # files may still be locked by gdb on Windows
+        os.remove(filename)
+    except:
+        pass
+    return lines
+
+
 class Breakpoint:
     def __init__(self):
         self.number = None
@@ -75,17 +99,6 @@ class Breakpoint:
         self.times = None
 
 def listOfBreakpoints(d):
-    file = tempfile.mkstemp(prefix="gdbpy_")
-    filename = file[1]
-    gdb.execute("set logging off")
-    gdb.execute("set logging redirect off")
-    gdb.execute("set logging file %s" % filename)
-    gdb.execute("set logging redirect on")
-    gdb.execute("set logging on")
-    gdb.execute("info break")
-    gdb.execute("set logging off")
-    gdb.execute("set logging redirect off")
-
     # [bkpt={number="1",type="breakpoint",disp="keep",enabled="y",
     #addr="0x0804da6d",func="testHidden()",file="../app.cpp",
     #fullname="...",line="1292",times="1",original-location="\"app.cpp\":1292"},
@@ -98,21 +111,13 @@ def listOfBreakpoints(d):
     #4.1                         y     0x08056673 in Foo at ../app.cpp:126\n"
     #4.2                         y     0x0805678b in Foo at ../app.cpp:126\n"
     #5       hw watchpoint  keep y              &main\n"
+    lines = catchCliOutput("info break")
 
-    file = open(filename, "r")
-    lines = []
-    for line in file:
-        if len(line) == 0 or line.startswith(" "):
-            continue
-        lines.append(line)
-    file.close()
-    try:  # files may still be locked by gdb on Windows
-        os.remove(filename)
-    except:
-        pass
     lines.reverse()
     bp = Breakpoint()
     for line in lines:
+        if len(line) == 0 or line.startswith(" "):
+            continue
         if line[0] < '0' or line[0] > '9':
             continue
         if line.startswith("\tstop only if "):
@@ -681,6 +686,34 @@ class FrameCommand(gdb.Command):
 FrameCommand()
 
 
+#######################################################################
+#
+# Step Command
+#
+#######################################################################
+
+
+class SalCommand(gdb.Command):
+    """Do fancy stuff."""
+
+    def __init__(self):
+        super(SalCommand, self).__init__("sal", gdb.COMMAND_OBSCURE)
+
+    def invoke(self, arg, from_tty):
+        lines = catchCliOutput("info line *" + arg)
+        fromAddr = "0x0"
+        toAddr = "0x0"
+        for line in lines:
+            pos0from = line.find(" starts at address") + 19
+            pos1from = line.find(" ", pos0from)
+            pos0to = line.find(" ends at", pos1from) + 9
+            pos1to = line.find(" ", pos0to)
+            if pos1to > 0:
+                fromAddr = line[pos0from : pos1from]
+                toAddr = line[pos0to : pos1to]
+        gdb.execute("maint packet sal%s,%s" % (fromAddr, toAddr))
+
+SalCommand()
 
 #######################################################################
 #
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index f478a898eef..8a5f61ed16b 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1762,6 +1762,9 @@ void GdbEngine::stepIExec()
     setTokenBarrier();
     setState(InferiorRunningRequested);
     showStatusMessage(tr("Step by instruction requested..."), 5000);
+    StackHandler *stackHandler = manager()->stackHandler();
+    if (m_gdbAdapter->isTrkAdapter() && stackHandler->stackSize() > 0)
+        postCommand("sal " + stackHandler->topAddress().toLatin1());
     if (manager()->isReverseDebugging())
         postCommand("-reverse-stepi", RunRequest, CB(handleExecContinue));
     else
@@ -1783,6 +1786,9 @@ void GdbEngine::nextExec()
     setTokenBarrier();
     setState(InferiorRunningRequested);
     showStatusMessage(tr("Step next requested..."), 5000);
+    StackHandler *stackHandler = manager()->stackHandler();
+    if (m_gdbAdapter->isTrkAdapter() && stackHandler->stackSize() > 0)
+        postCommand("sal " + stackHandler->topAddress().toLatin1());
     if (manager()->isReverseDebugging())
         postCommand("-reverse-next", RunRequest, CB(handleExecNext));
     else
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp
index 4ee80f93a85..a94ca2d29fe 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp
@@ -122,7 +122,7 @@ QDebug operator<<(QDebug d, MemoryRange range)
 MemoryRange::MemoryRange(uint f, uint t)
     : from(f), to(t)
 {
-    QTC_ASSERT(f <= t, /**/);
+    QTC_ASSERT(f <= t, qDebug() << "F: " << f << " T: " << t);
 }
 
 bool MemoryRange::intersects(const MemoryRange &other) const
@@ -167,6 +167,8 @@ void Snapshot::reset()
         registers[i] = 0;
     registerValid = false;
     wantedMemory = MemoryRange();
+    lineFromAddress = 0;
+    lineToAddress = 0;
 }
 
 void Snapshot::insertMemory(const MemoryRange &range, const QByteArray &ba)
@@ -374,8 +376,18 @@ QByteArray TrkGdbAdapter::trkStepRangeMessage(byte option)
     ba.reserve(17);
     appendByte(&ba, option);
     //qDebug() << "STEP ON " << hexxNumber(m_snapshot.registers[RegisterPC]);
-    appendInt(&ba, m_snapshot.registers[RegisterPC]); // Start address
-    appendInt(&ba, m_snapshot.registers[RegisterPC]); // End address
+    uint from = m_snapshot.lineFromAddress;
+    uint to = m_snapshot.lineToAddress;
+    uint pc = m_snapshot.registers[RegisterPC];
+    if (from <= pc && pc <= to) {
+        qDebug() << "STEP IN " << hexxNumber(from) << hexxNumber(to)
+             << "INSTEAD OF " << hexxNumber(pc);
+    } else {
+        from = pc;
+        to = pc;
+    }
+    appendInt(&ba, from); // Start address
+    appendInt(&ba, to); // End address
     appendInt(&ba, m_session.pid);
     appendInt(&ba, m_session.tid);
     return ba;
@@ -678,6 +690,19 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
             trkReadRegistersMessage());
     }
 
+    else if (cmd.startsWith("sal")) {
+        // Receive address range for current line for future use when stepping.
+        sendGdbServerAck();
+        int pos = cmd.indexOf(',');
+        //qDebug() << "SAL: " << cmd << cmd.mid(3, pos - 3) << cmd.mid(pos + 1);
+        bool ok = false;
+        m_snapshot.lineFromAddress = cmd.mid(3, pos - 3).toUInt(0, 16);
+        m_snapshot.lineToAddress = cmd.mid(pos + 1).toUInt(0, 16);
+        //qDebug() << "SAL: " << hexxNumber(m_snapshot.lineFromAddress)
+        //    << hexxNumber(m_snapshot.lineToAddress);
+        sendGdbServerMessage("", "Stepping range received");
+    }
+
     else if (cmd.startsWith("Hc")) {
         logMessage(msgGdbPacket(QLatin1String("Set thread & continue")));
         // Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
@@ -1823,6 +1848,7 @@ void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
         m_engine->postCommand("symbol-file \"" + symbolFile + "\"");
     }
     m_engine->postCommand("set breakpoint always-inserted on");
+    m_engine->postCommand("set breakpoint auto-hw off");
     m_engine->postCommand("set trust-readonly-sections"); // No difference?
     m_engine->postCommand("set displaced-stepping on"); // No difference?
     m_engine->postCommand("mem 0x00400000 0x00800000 cache");
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h
index 0c5a4af7206..2c88eb36b2b 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.h
+++ b/src/plugins/debugger/gdb/trkgdbadapter.h
@@ -59,7 +59,6 @@ enum CodeMode
 
 enum TargetConstants
 {
-
     RegisterCount = 17,
     RegisterSP = 13, // Stack Pointer
     RegisterLR = 14, // Return address
@@ -91,6 +90,8 @@ struct Snapshot
     void insertMemory(const MemoryRange &range, const QByteArray &ba);
 
     uint registers[RegisterCount];
+    uint lineFromAddress;
+    uint lineToAddress;
     bool registerValid;
     typedef QMap<MemoryRange, QByteArray> Memory;
     Memory memory;
diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h
index 0df1d602573..3c36485dafd 100644
--- a/src/plugins/debugger/stackhandler.h
+++ b/src/plugins/debugger/stackhandler.h
@@ -69,6 +69,7 @@ public:
     int currentIndex() const { return m_currentIndex; }
     StackFrame currentFrame() const;
     int stackSize() const { return m_stackFrames.size(); }
+    QString topAddress() const { return m_stackFrames.at(0).address; }
 
     // Called from StackHandler after a new stack list has been received
     void removeAll();
-- 
GitLab