debuggeragents.cpp 7.64 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
27
28
29
30
**
**************************************************************************/

#include "debuggeragents.h"
31
#include "debuggerstringutils.h"
32
33
#include "idebuggerengine.h"

34
#include <coreplugin/coreconstants.h>
35
#include <coreplugin/editormanager/editormanager.h>
36
37
38
39
40
41
42
43
44
45
46
47
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h>

#include <texteditor/basetexteditor.h>
#include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>

#include <utils/qtcassert.h>

#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextCursor>
48
#include <QtGui/QSyntaxHighlighter>
49

Bradley T. Hughes's avatar
Compile    
Bradley T. Hughes committed
50
51
#include <limits.h>

52
53
54
namespace Debugger {
namespace Internal {

55
56
57
58
59
60
///////////////////////////////////////////////////////////////////////
//
// MemoryViewAgent
//
///////////////////////////////////////////////////////////////////////

ck's avatar
ck committed
61
/*!
62
63
64
65
66
67
68
    \class MemoryViewAgent

    Objects form this class are created in response to user actions in
    the Gui for showing raw memory from the inferior. After creation
    it handles communication between the engine and the bineditor.
*/

69
70
MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
    : QObject(manager), m_engine(manager->currentEngine())
71
72
73
74
75
76
77
78
{
    init(addr);
}

MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, const QString &addr)
    : QObject(manager), m_engine(manager->currentEngine())
{
    bool ok = true;
79
    init(addr.toULongLong(&ok, 0));
80
    //qDebug() <<  " ADDRESS: " << addr <<  addr.toUInt(&ok, 0);
81
82
83
84
}

MemoryViewAgent::~MemoryViewAgent()
{
85
86
    if (m_editor)
        m_editor->deleteLater();
87
88
}

ck's avatar
ck committed
89
void MemoryViewAgent::init(quint64 addr)
90
91
{
    Core::EditorManager *editorManager = Core::EditorManager::instance();
92
    QString titlePattern = tr("Memory $");
93
94
95
    m_editor = editorManager->openEditorWithContents(
        Core::Constants::K_DEFAULT_BINARY_EDITOR,
        &titlePattern);
ck's avatar
ck committed
96
97
    connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)),
        this, SLOT(fetchLazyData(quint64,bool)));
98
99
    editorManager->activateEditor(m_editor);
    QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
ck's avatar
ck committed
100
        Q_ARG(quint64, addr), Q_ARG(int, 1024 * 1024), Q_ARG(int, BinBlockSize));
101
102
}

ck's avatar
ck committed
103
void MemoryViewAgent::fetchLazyData(quint64 block, bool sync)
104
105
{
    Q_UNUSED(sync); // FIXME: needed support for incremental searching
106
107
    if (m_engine)
        m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
108
109
110
111
}

void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
{
112
113
114
    if (m_editor && m_editor->widget())
        QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
            Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
115
116
117
}


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
///////////////////////////////////////////////////////////////////////
//
// DisassemblerViewAgent
//
///////////////////////////////////////////////////////////////////////

static QIcon locationMarkIcon()
{
    static const QIcon icon(":/debugger/images/location.svg");
    return icon;
}

// Used for the disassembler view
class LocationMark2 : public TextEditor::ITextMark
{
public:
    LocationMark2() {}

    QIcon icon() const { return locationMarkIcon(); }
    void updateLineNumber(int /*lineNumber*/) {}
    void updateBlock(const QTextBlock & /*block*/) {}
    void removedFromEditor() {}
    void documentClosing() {}
};

struct DisassemblerViewAgentPrivate
{
    QPointer<TextEditor::ITextEditor> editor;
    QString address;
147
148
    QString function;
    QPointer<DebuggerManager> manager;
149
150
151
    LocationMark2 *locationMark;
};

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*!
    \class DisassemblerSyntaxHighlighter

     Simple syntax highlighter to make the disassembler text less prominent.
*/

class DisassemblerHighlighter : public QSyntaxHighlighter
{
public:
    DisassemblerHighlighter(QPlainTextEdit *parent)
        : QSyntaxHighlighter(parent->document())
    {}

private:
    void highlightBlock(const QString &text)
    {
        if (!text.isEmpty() && text.at(0) != ' ') {
            QTextCharFormat format;
            format.setForeground(QColor(128, 128, 128));
            setFormat(0, text.size(), format);
        }
    }
};

176
177
178
179
180
181
182
183
184
185
186
187
188
/*!
    \class DisassemblerViewAgent

     Objects from this class are created in response to user actions in
     the Gui for showing disassembled memory from the inferior. After creation
     it handles communication between the engine and the editor.
*/

DisassemblerViewAgent::DisassemblerViewAgent(DebuggerManager *manager)
    : QObject(manager), d(new DisassemblerViewAgentPrivate)
{
    d->editor = 0;
    d->locationMark = new LocationMark2();
189
    d->manager = manager;
190
191
192
193
194
195
196
197
198
199
200
}

DisassemblerViewAgent::~DisassemblerViewAgent()
{
    if (d->editor)
        d->editor->deleteLater();
    delete d;
}

void DisassemblerViewAgent::setFrame(const StackFrame &frame)
{
201
202
203
    IDebuggerEngine *engine = d->manager->currentEngine();
    QTC_ASSERT(engine, return);
    engine->fetchDisassembler(this, frame);
204
    d->address = frame.address;
205
    d->function = frame.function;
206
207
208
209
210
211
212
}

void DisassemblerViewAgent::setContents(const QString &contents)
{
    using namespace Core;
    using namespace TextEditor;

213
214
215
    if (!d->editor)
        return;

216
    QPlainTextEdit *plainTextEdit = 0;
217
218
219
220
221
    EditorManager *editorManager = EditorManager::instance();
    if (!d->editor) {
        QString titlePattern = "Disassembler";
        d->editor = qobject_cast<ITextEditor *>(
            editorManager->openEditorWithContents(
222
223
224
                Core::Constants::K_DEFAULT_TEXT_EDITOR,
                &titlePattern));
        QTC_ASSERT(d->editor, return);
225
226
        if ((plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget())))
            (void) new DisassemblerHighlighter(plainTextEdit);
227
228
229
230
    }

    editorManager->activateEditor(d->editor);

231
    plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget());
232
233
234
235
    if (plainTextEdit)
        plainTextEdit->setPlainText(contents);

    d->editor->markableInterface()->removeMark(d->locationMark);
236
    d->editor->setDisplayName(_("Disassembler (%1)").arg(d->function));
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

    for (int pos = 0, line = 0; ; ++line, ++pos) {
        if (contents.midRef(pos, d->address.size()) == d->address) {
            d->editor->markableInterface()->addMark(d->locationMark, line + 1);
            if (plainTextEdit) {
                QTextCursor tc = plainTextEdit->textCursor();
                tc.setPosition(pos);
                plainTextEdit->setTextCursor(tc);
            }
            break;
        }
        pos = contents.indexOf('\n', pos + 1);
        if (pos == -1)
            break;
    }
}

QString DisassemblerViewAgent::address() const
{
    return d->address;
}

259
260
} // namespace Internal
} // namespace Debugger