1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** If you are unsure which license is appropriate for your use, please
26 ** contact the sales department at http://qt.nokia.com/contact.
28 **************************************************************************/
30 #include "debuggeragents.h"
31 #include "debuggerstringutils.h"
32 #include "idebuggerengine.h"
34 #include <coreplugin/coreconstants.h>
35 #include <coreplugin/editormanager/editormanager.h>
36 #include <coreplugin/editormanager/ieditor.h>
37 #include <coreplugin/icore.h>
39 #include <texteditor/basetexteditor.h>
40 #include <texteditor/basetextmark.h>
41 #include <texteditor/itexteditor.h>
42 #include <texteditor/texteditorconstants.h>
44 #include <utils/qtcassert.h>
46 #include <QtCore/QDebug>
47 #include <QtGui/QPlainTextEdit>
48 #include <QtGui/QTextCursor>
49 #include <QtGui/QSyntaxHighlighter>
56 ///////////////////////////////////////////////////////////////////////
60 ///////////////////////////////////////////////////////////////////////
63 \class MemoryViewAgent
65 Objects form this class are created in response to user actions in
66 the Gui for showing raw memory from the inferior. After creation
67 it handles communication between the engine and the bineditor.
70 MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
71 : QObject(manager), m_engine(manager->currentEngine())
76 MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, const QString &addr)
77 : QObject(manager), m_engine(manager->currentEngine())
80 init(addr.toULongLong(&ok, 0));
81 //qDebug() << " ADDRESS: " << addr << addr.toUInt(&ok, 0);
84 MemoryViewAgent::~MemoryViewAgent()
87 m_editor->deleteLater();
90 void MemoryViewAgent::init(quint64 addr)
92 Core::EditorManager *editorManager = Core::EditorManager::instance();
93 QString titlePattern = tr("Memory $");
94 m_editor = editorManager->openEditorWithContents(
95 Core::Constants::K_DEFAULT_BINARY_EDITOR,
97 connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)),
98 this, SLOT(fetchLazyData(quint64,bool)));
99 editorManager->activateEditor(m_editor);
100 QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
101 Q_ARG(quint64, addr), Q_ARG(int, 1024 * 1024), Q_ARG(int, BinBlockSize));
104 void MemoryViewAgent::fetchLazyData(quint64 block, bool sync)
106 Q_UNUSED(sync); // FIXME: needed support for incremental searching
108 m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
111 void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
113 if (m_editor && m_editor->widget())
114 QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
115 Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
119 ///////////////////////////////////////////////////////////////////////
121 // DisassemblerViewAgent
123 ///////////////////////////////////////////////////////////////////////
125 static QIcon locationMarkIcon()
127 static const QIcon icon(":/debugger/images/location.svg");
131 // Used for the disassembler view
132 class LocationMark2 : public TextEditor::ITextMark
137 QIcon icon() const { return locationMarkIcon(); }
138 void updateLineNumber(int /*lineNumber*/) {}
139 void updateBlock(const QTextBlock & /*block*/) {}
140 void removedFromEditor() {}
141 void documentClosing() {}
144 struct DisassemblerViewAgentPrivate
146 QPointer<TextEditor::ITextEditor> editor;
148 QPointer<DebuggerManager> manager;
149 LocationMark2 *locationMark;
150 QHash<QString, QString> cache;
154 \class DisassemblerSyntaxHighlighter
156 Simple syntax highlighter to make the disassembler text less prominent.
159 class DisassemblerHighlighter : public QSyntaxHighlighter
162 DisassemblerHighlighter(QPlainTextEdit *parent)
163 : QSyntaxHighlighter(parent->document())
167 void highlightBlock(const QString &text)
169 if (!text.isEmpty() && text.at(0) != ' ') {
170 QTextCharFormat format;
171 format.setForeground(QColor(128, 128, 128));
172 setFormat(0, text.size(), format);
178 \class DisassemblerViewAgent
180 Objects from this class are created in response to user actions in
181 the Gui for showing disassembled memory from the inferior. After creation
182 it handles communication between the engine and the editor.
185 DisassemblerViewAgent::DisassemblerViewAgent(DebuggerManager *manager)
186 : QObject(0), d(new DisassemblerViewAgentPrivate)
189 d->locationMark = new LocationMark2();
190 d->manager = manager;
193 DisassemblerViewAgent::~DisassemblerViewAgent()
196 d->editor->deleteLater();
198 delete d->locationMark;
204 void DisassemblerViewAgent::cleanup()
208 // d->editor->deleteLater();
212 void DisassemblerViewAgent::resetLocation()
215 d->editor->markableInterface()->removeMark(d->locationMark);
218 QString frameKey(const StackFrame &frame)
220 return _("%1:%2:%3").arg(frame.function).arg(frame.file).arg(frame.from);
223 void DisassemblerViewAgent::setFrame(const StackFrame &frame)
226 if (!frame.function.isEmpty() && frame.function != _("??")) {
227 QHash<QString, QString>::ConstIterator it = d->cache.find(frameKey(frame));
228 if (it != d->cache.end()) {
229 QString msg = _("Use cache dissassembler for '%1' in '%2'")
230 .arg(frame.function).arg(frame.file);
231 d->manager->showDebuggerOutput(msg);
236 IDebuggerEngine *engine = d->manager->currentEngine();
237 QTC_ASSERT(engine, return);
238 engine->fetchDisassembler(this, frame);
241 void DisassemblerViewAgent::setContents(const QString &contents)
243 QTC_ASSERT(d, return);
244 using namespace Core;
245 using namespace TextEditor;
247 d->cache.insert(frameKey(d->frame), contents);
248 QPlainTextEdit *plainTextEdit = 0;
249 EditorManager *editorManager = EditorManager::instance();
251 QString titlePattern = "Disassembler";
252 d->editor = qobject_cast<ITextEditor *>(
253 editorManager->openEditorWithContents(
254 Core::Constants::K_DEFAULT_TEXT_EDITOR,
256 QTC_ASSERT(d->editor, return);
257 if ((plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget())))
258 (void) new DisassemblerHighlighter(plainTextEdit);
261 editorManager->activateEditor(d->editor);
263 plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget());
265 plainTextEdit->setPlainText(contents);
267 d->editor->markableInterface()->removeMark(d->locationMark);
268 d->editor->setDisplayName(_("Disassembler (%1)").arg(d->frame.function));
270 for (int pos = 0, line = 0; ; ++line, ++pos) {
271 if (contents.midRef(pos, d->frame.address.size()) == d->frame.address) {
272 d->editor->markableInterface()->addMark(d->locationMark, line + 1);
274 QTextCursor tc = plainTextEdit->textCursor();
276 plainTextEdit->setTextCursor(tc);
280 pos = contents.indexOf('\n', pos + 1);
286 bool DisassemblerViewAgent::contentsCoversAddress(const QString &contents) const
288 QTC_ASSERT(d, return false);
289 for (int pos = 0, line = 0; ; ++line, ++pos) {
290 if (contents.midRef(pos, d->frame.address.size()) == d->frame.address)
292 pos = contents.indexOf('\n', pos + 1);
299 QString DisassemblerViewAgent::address() const
301 return d->frame.address;
304 } // namespace Internal
305 } // namespace Debugger