forked from qt-creator/qt-creator
debugger: re-work DisassemblerLine structure
This commit is contained in:
@@ -1509,7 +1509,7 @@ void CdbEngine::handleDisassembler(const CdbBuiltinCommandPtr &command)
|
|||||||
DisassemblerAgent *agent = qvariant_cast<DisassemblerAgent*>(command->cookie);
|
DisassemblerAgent *agent = qvariant_cast<DisassemblerAgent*>(command->cookie);
|
||||||
DisassemblerLines disassemblerLines;
|
DisassemblerLines disassemblerLines;
|
||||||
foreach(const QByteArray &line, command->reply)
|
foreach(const QByteArray &line, command->reply)
|
||||||
disassemblerLines.appendLine(DisassemblerLine(QString::fromLatin1(line)));
|
disassemblerLines.appendUnparsed(QString::fromLatin1(line));
|
||||||
agent->setContents(disassemblerLines);
|
agent->setContents(disassemblerLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
#include "breakhandler.h"
|
#include "breakhandler.h"
|
||||||
#include "breakwindow.h"
|
#include "breakwindow.h"
|
||||||
#include "consolewindow.h"
|
#include "consolewindow.h"
|
||||||
#include "disassembleragent.h"
|
#include "disassemblerlines.h"
|
||||||
#include "logwindow.h"
|
#include "logwindow.h"
|
||||||
#include "moduleswindow.h"
|
#include "moduleswindow.h"
|
||||||
#include "moduleshandler.h"
|
#include "moduleshandler.h"
|
||||||
@@ -1621,7 +1621,7 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
|
|||||||
.section('\n', lineNumber - 1, lineNumber - 1);
|
.section('\n', lineNumber - 1, lineNumber - 1);
|
||||||
BreakpointResponse needle;
|
BreakpointResponse needle;
|
||||||
needle.type = BreakpointByAddress;
|
needle.type = BreakpointByAddress;
|
||||||
needle.address = DisassemblerAgent::addressFromDisassemblyLine(line);
|
needle.address = DisassemblerLine::addressFromDisassemblyLine(line);
|
||||||
args.address = needle.address;
|
args.address = needle.address;
|
||||||
needle.lineNumber = -1;
|
needle.lineNumber = -1;
|
||||||
id = breakHandler()->findSimilarBreakpoint(needle);
|
id = breakHandler()->findSimilarBreakpoint(needle);
|
||||||
@@ -1704,7 +1704,7 @@ void DebuggerPluginPrivate::toggleBreakpoint()
|
|||||||
if (textEditor->property("DisassemblerView").toBool()) {
|
if (textEditor->property("DisassemblerView").toBool()) {
|
||||||
QString line = textEditor->contents()
|
QString line = textEditor->contents()
|
||||||
.section('\n', lineNumber - 1, lineNumber - 1);
|
.section('\n', lineNumber - 1, lineNumber - 1);
|
||||||
quint64 address = DisassemblerAgent::addressFromDisassemblyLine(line);
|
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
|
||||||
toggleBreakpointByAddress(address);
|
toggleBreakpointByAddress(address);
|
||||||
} else if (lineNumber >= 0) {
|
} else if (lineNumber >= 0) {
|
||||||
toggleBreakpointByFileAndLine(textEditor->file()->fileName(), lineNumber);
|
toggleBreakpointByFileAndLine(textEditor->file()->fileName(), lineNumber);
|
||||||
@@ -1751,7 +1751,7 @@ void DebuggerPluginPrivate::requestMark(ITextEditor *editor, int lineNumber)
|
|||||||
if (editor->property("DisassemblerView").toBool()) {
|
if (editor->property("DisassemblerView").toBool()) {
|
||||||
QString line = editor->contents()
|
QString line = editor->contents()
|
||||||
.section('\n', lineNumber - 1, lineNumber - 1);
|
.section('\n', lineNumber - 1, lineNumber - 1);
|
||||||
quint64 address = DisassemblerAgent::addressFromDisassemblyLine(line);
|
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
|
||||||
toggleBreakpointByAddress(address);
|
toggleBreakpointByAddress(address);
|
||||||
} else if (editor->file()) {
|
} else if (editor->file()) {
|
||||||
toggleBreakpointByFileAndLine(editor->file()->fileName(), lineNumber);
|
toggleBreakpointByFileAndLine(editor->file()->fileName(), lineNumber);
|
||||||
|
@@ -265,6 +265,9 @@ QDataStream &operator>>(QDataStream &stream, WatchData &wd)
|
|||||||
QDataStream &operator<<(QDataStream& stream, const DisassemblerLine &o)
|
QDataStream &operator<<(QDataStream& stream, const DisassemblerLine &o)
|
||||||
{
|
{
|
||||||
stream << o.address;
|
stream << o.address;
|
||||||
|
stream << o.function;
|
||||||
|
stream << o.offset;
|
||||||
|
stream << o.lineNumber;
|
||||||
stream << o.data;
|
stream << o.data;
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
@@ -272,6 +275,9 @@ QDataStream &operator<<(QDataStream& stream, const DisassemblerLine &o)
|
|||||||
QDataStream &operator>>(QDataStream& stream, DisassemblerLine &o)
|
QDataStream &operator>>(QDataStream& stream, DisassemblerLine &o)
|
||||||
{
|
{
|
||||||
stream >> o.address;
|
stream >> o.address;
|
||||||
|
stream >> o.function;
|
||||||
|
stream >> o.offset;
|
||||||
|
stream >> o.lineNumber;
|
||||||
stream >> o.data;
|
stream >> o.data;
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
@@ -254,13 +254,7 @@ void DisassemblerAgent::setContents(const DisassemblerLines &contents)
|
|||||||
|
|
||||||
QString str;
|
QString str;
|
||||||
for (int i = 0, n = contents.size(); i != n; ++i) {
|
for (int i = 0, n = contents.size(); i != n; ++i) {
|
||||||
const DisassemblerLine &dl = contents.at(i);
|
str += contents.at(i).toString();
|
||||||
if (dl.address) {
|
|
||||||
str += QLatin1String("0x");
|
|
||||||
str += QString::number(dl.address, 16);
|
|
||||||
str += QLatin1String(" ");
|
|
||||||
}
|
|
||||||
str += dl.data;
|
|
||||||
str += QLatin1Char('\n');
|
str += QLatin1Char('\n');
|
||||||
}
|
}
|
||||||
plainTextEdit->setPlainText(str);
|
plainTextEdit->setPlainText(str);
|
||||||
@@ -331,12 +325,6 @@ quint64 DisassemblerAgent::address() const
|
|||||||
return d->location.address();
|
return d->location.address();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return address of an assembly line "0x0dfd bla"
|
|
||||||
quint64 DisassemblerAgent::addressFromDisassemblyLine(const QString &line)
|
|
||||||
{
|
|
||||||
return DisassemblerLine(line).address;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisassemblerAgent::setTryMixed(bool on)
|
void DisassemblerAgent::setTryMixed(bool on)
|
||||||
{
|
{
|
||||||
d->tryMixed = on;
|
d->tryMixed = on;
|
||||||
|
@@ -72,9 +72,6 @@ public:
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
bool isMixed() const;
|
bool isMixed() const;
|
||||||
|
|
||||||
// Return address of an assembly line "0x0dfd bla"
|
|
||||||
static quint64 addressFromDisassemblyLine(const QString &data);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DisassemblerAgentPrivate *d;
|
DisassemblerAgentPrivate *d;
|
||||||
};
|
};
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "disassemblerlines.h"
|
#include "disassemblerlines.h"
|
||||||
|
#include "debuggerstringutils.h"
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QRegExp>
|
#include <QtCore/QRegExp>
|
||||||
@@ -39,7 +40,7 @@
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
DisassemblerLine::DisassemblerLine(const QString &unparsed)
|
void DisassemblerLine::fromString(const QString &unparsed)
|
||||||
{
|
{
|
||||||
int pos = -1;
|
int pos = -1;
|
||||||
for (int i = 0; i != unparsed.size(); ++i) {
|
for (int i = 0; i != unparsed.size(); ++i) {
|
||||||
@@ -71,6 +72,13 @@ DisassemblerLine::DisassemblerLine(const QString &unparsed)
|
|||||||
data = unparsed;
|
data = unparsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quint64 DisassemblerLine::addressFromDisassemblyLine(const QString &line)
|
||||||
|
{
|
||||||
|
DisassemblerLine l;
|
||||||
|
l.fromString(line);
|
||||||
|
return l.address;
|
||||||
|
}
|
||||||
|
|
||||||
int DisassemblerLines::lineForAddress(quint64 address) const
|
int DisassemblerLines::lineForAddress(quint64 address) const
|
||||||
{
|
{
|
||||||
return m_rowCache.value(address);
|
return m_rowCache.value(address);
|
||||||
@@ -81,18 +89,81 @@ bool DisassemblerLines::coversAddress(quint64 address) const
|
|||||||
return m_rowCache.value(address) != 0;
|
return m_rowCache.value(address) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblerLines::appendComment(const QString &comment)
|
|
||||||
{
|
|
||||||
DisassemblerLine dl;
|
|
||||||
dl.data = comment;
|
|
||||||
m_data.append(dl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisassemblerLines::appendLine(const DisassemblerLine &dl)
|
void DisassemblerLines::appendLine(const DisassemblerLine &dl)
|
||||||
{
|
{
|
||||||
m_data.append(dl);
|
m_data.append(dl);
|
||||||
m_rowCache[dl.address] = m_data.size();
|
m_rowCache[dl.address] = m_data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblerLines::appendUnparsed(const QString &unparsed)
|
||||||
|
{
|
||||||
|
QString line = unparsed.trimmed();
|
||||||
|
if (line.isEmpty())
|
||||||
|
return;
|
||||||
|
if (line.startsWith("Current language:"))
|
||||||
|
return;
|
||||||
|
if (line.startsWith("Dump of assembler")) {
|
||||||
|
m_lastFunction.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (line.startsWith("The current source"))
|
||||||
|
return;
|
||||||
|
if (line.startsWith("End of assembler")) {
|
||||||
|
m_lastFunction.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (line.startsWith("=> "))
|
||||||
|
line = line.mid(3);
|
||||||
|
if (line.startsWith("0x")) {
|
||||||
|
// Address line.
|
||||||
|
int pos1 = line.indexOf('<') + 1;
|
||||||
|
int pos2 = line.indexOf('+', pos1);
|
||||||
|
int pos3 = line.indexOf('>', pos1);
|
||||||
|
if (pos1 < pos2 && pos2 < pos3) {
|
||||||
|
QString function = line.mid(pos1, pos2 - pos1);
|
||||||
|
if (function != m_lastFunction) {
|
||||||
|
DisassemblerLine dl;
|
||||||
|
dl.data = _("Function: ") + function;
|
||||||
|
m_data.append(dl);
|
||||||
|
m_lastFunction = function;
|
||||||
|
}
|
||||||
|
//line.replace(pos1, pos2 - pos1, "");
|
||||||
|
}
|
||||||
|
DisassemblerLine dl;
|
||||||
|
dl.address = line.left(pos1 - 1).toULongLong(0, 0);
|
||||||
|
dl.function = m_lastFunction;
|
||||||
|
dl.offset = line.mid(pos2, pos3 - pos2).toUInt();
|
||||||
|
dl.data = line.mid(pos3 + 3).trimmed();
|
||||||
|
m_rowCache[dl.address] = m_data.size() + 1;
|
||||||
|
m_data.append(dl);
|
||||||
|
} else {
|
||||||
|
// Comment line.
|
||||||
|
DisassemblerLine dl;
|
||||||
|
dl.data = line;
|
||||||
|
m_data.append(dl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DisassemblerLine::toString() const
|
||||||
|
{
|
||||||
|
const QString someSpace = _(" ");
|
||||||
|
QString str;
|
||||||
|
if (isAssembler()) {
|
||||||
|
if (address)
|
||||||
|
str += _("0x%1 ").arg(address, 0, 16);
|
||||||
|
if (offset)
|
||||||
|
str += _("<+0x%1> ").arg(offset, 4, 10, QLatin1Char('0'));
|
||||||
|
str += _(" ");
|
||||||
|
str += data;
|
||||||
|
} else if (isCode()) {
|
||||||
|
str += someSpace;
|
||||||
|
str += data;
|
||||||
|
} else {
|
||||||
|
str += someSpace;
|
||||||
|
str += data;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -41,15 +41,31 @@
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
// A DisassemblerLine represents either
|
||||||
|
// - an assembler instruction (address, offset, function, data fields), or
|
||||||
|
// - a code line (lineNumber, data fields), or
|
||||||
|
// - a comment line.
|
||||||
|
|
||||||
class DisassemblerLine
|
class DisassemblerLine
|
||||||
{
|
{
|
||||||
|
//DisassemblerLine(const QString &unparsed);
|
||||||
public:
|
public:
|
||||||
DisassemblerLine() : address(0) {}
|
DisassemblerLine() : address(0), offset(0), lineNumber(0) {}
|
||||||
DisassemblerLine(const QString &unparsed);
|
bool isAssembler() const { return address != 0; }
|
||||||
|
bool isCode() const { return lineNumber != 0; }
|
||||||
|
bool isComment() const { return lineNumber == 0 && address == 0; }
|
||||||
|
QString toString() const;
|
||||||
|
void fromString(const QString &unparsed);
|
||||||
|
|
||||||
|
// Return address of an assembly line "0x0dfd bla".
|
||||||
|
static quint64 addressFromDisassemblyLine(const QString &line);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
quint64 address;
|
quint64 address; // (ass) Address of instruction in memory/in binary.
|
||||||
QString data;
|
QString function; // (ass) Function to which current instruction belongs.
|
||||||
|
uint offset; // (ass) Offset of instruction in relation to current function.
|
||||||
|
uint lineNumber; // (src) Line number in source.
|
||||||
|
QString data; // (ass) Instruction text, (src) source text, (cmt) arbitrary.
|
||||||
};
|
};
|
||||||
|
|
||||||
class DisassemblerLines
|
class DisassemblerLines
|
||||||
@@ -58,13 +74,14 @@ public:
|
|||||||
DisassemblerLines() {}
|
DisassemblerLines() {}
|
||||||
|
|
||||||
bool coversAddress(quint64 address) const;
|
bool coversAddress(quint64 address) const;
|
||||||
|
void appendUnparsed(const QString &line);
|
||||||
void appendLine(const DisassemblerLine &dl);
|
void appendLine(const DisassemblerLine &dl);
|
||||||
void appendComment(const QString &comment);
|
|
||||||
int size() const { return m_data.size(); }
|
int size() const { return m_data.size(); }
|
||||||
const DisassemblerLine &at(int i) const { return m_data.at(i); }
|
const DisassemblerLine &at(int i) const { return m_data.at(i); }
|
||||||
int lineForAddress(quint64 address) const;
|
int lineForAddress(quint64 address) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString m_lastFunction;
|
||||||
QVector<DisassemblerLine> m_data;
|
QVector<DisassemblerLine> m_data;
|
||||||
QHash<quint64, int> m_rowCache;
|
QHash<quint64, int> m_rowCache;
|
||||||
};
|
};
|
||||||
|
@@ -4119,6 +4119,8 @@ static DisassemblerLine parseLine(const GdbMi &line)
|
|||||||
QByteArray address = line.findChild("address").data();
|
QByteArray address = line.findChild("address").data();
|
||||||
dl.address = address.toULongLong();
|
dl.address = address.toULongLong();
|
||||||
dl.data = _(line.findChild("inst").data());
|
dl.data = _(line.findChild("inst").data());
|
||||||
|
dl.function = _(line.findChild("func-name").data());
|
||||||
|
dl.offset = line.findChild("offset").data().toUInt();
|
||||||
return dl;
|
return dl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4153,8 +4155,12 @@ DisassemblerLines GdbEngine::parseMiDisassembler(const GdbMi &lines)
|
|||||||
fileLoaded = true;
|
fileLoaded = true;
|
||||||
}
|
}
|
||||||
int line = child.findChild("line").data().toInt();
|
int line = child.findChild("line").data().toInt();
|
||||||
if (line >= 1 && line <= fileContents.size())
|
if (line >= 1 && line <= fileContents.size()) {
|
||||||
result.appendComment(fileContents.at(line - 1));
|
DisassemblerLine dl;
|
||||||
|
dl.lineNumber = line;
|
||||||
|
dl.data = fileContents.at(line - 1);
|
||||||
|
result.appendLine(dl);
|
||||||
|
}
|
||||||
GdbMi insn = child.findChild("line_asm_insn");
|
GdbMi insn = child.findChild("line_asm_insn");
|
||||||
foreach (const GdbMi &item, insn.children())
|
foreach (const GdbMi &item, insn.children())
|
||||||
result.appendLine(parseLine(item));
|
result.appendLine(parseLine(item));
|
||||||
@@ -4172,45 +4178,8 @@ DisassemblerLines GdbEngine::parseCliDisassembler(const GdbMi &output)
|
|||||||
// First line is something like
|
// First line is something like
|
||||||
// "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:"
|
// "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:"
|
||||||
DisassemblerLines dlines;
|
DisassemblerLines dlines;
|
||||||
QByteArray lastFunction;
|
foreach (const QByteArray &line, output.data().split('\n'))
|
||||||
foreach (const QByteArray &line0, output.data().split('\n')) {
|
dlines.appendUnparsed(_(line));
|
||||||
QByteArray line = line0.trimmed();
|
|
||||||
if (line.startsWith("=> "))
|
|
||||||
line = line.mid(3);
|
|
||||||
if (line.isEmpty())
|
|
||||||
continue;
|
|
||||||
if (line.startsWith("Current language:"))
|
|
||||||
continue;
|
|
||||||
if (line.startsWith("Dump of assembler"))
|
|
||||||
continue;
|
|
||||||
if (line.startsWith("The current source"))
|
|
||||||
continue;
|
|
||||||
if (line.startsWith("End of assembler"))
|
|
||||||
continue;
|
|
||||||
if (line.startsWith("0x")) {
|
|
||||||
int pos1 = line.indexOf('<') + 1;
|
|
||||||
int pos2 = line.indexOf('+', pos1);
|
|
||||||
int pos3 = line.indexOf('>', pos1);
|
|
||||||
if (pos1 < pos2 && pos2 < pos3) {
|
|
||||||
QByteArray function = line.mid(pos1, pos2 - pos1);
|
|
||||||
if (function != lastFunction) {
|
|
||||||
dlines.appendComment(QString());
|
|
||||||
dlines.appendComment(_("Function: ") + _(function));
|
|
||||||
lastFunction = function;
|
|
||||||
}
|
|
||||||
line.replace(pos1, pos2 - pos1, "");
|
|
||||||
}
|
|
||||||
if (pos3 - pos2 == 1)
|
|
||||||
line.insert(pos2 + 1, "000");
|
|
||||||
if (pos3 - pos2 == 2)
|
|
||||||
line.insert(pos2 + 1, "00");
|
|
||||||
if (pos3 - pos2 == 3)
|
|
||||||
line.insert(pos2 + 1, "0");
|
|
||||||
dlines.appendLine(DisassemblerLine(_(line)));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dlines.appendComment(someSpace + _(line));
|
|
||||||
}
|
|
||||||
return dlines;
|
return dlines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user