diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp index 306de5d80adcdddc47c68a5ff6adeafa89c92640..27629a130ea4e390176b7c4841ecc22beef83da2 100644 --- a/src/plugins/bineditor/bineditor.cpp +++ b/src/plugins/bineditor/bineditor.cpp @@ -77,6 +77,7 @@ BinEditor::BinEditor(QWidget *parent) { m_ieditor = 0; m_inLazyMode = false; + m_baseAddr = 0; m_blockSize = 4096; init(); m_unmodifiedState = 0; @@ -88,7 +89,7 @@ BinEditor::BinEditor(QWidget *parent) m_cursorVisible = false; m_caseSensitiveSearch = false; setFocusPolicy(Qt::WheelFocus); - m_addressString = QString(9, QLatin1Char(':')); + m_addressString = QString(16 + 3, QLatin1Char(':')); } BinEditor::~BinEditor() @@ -108,7 +109,7 @@ void BinEditor::init() m_numVisibleLines = viewport()->height() / m_lineHeight; m_textWidth = 16 * m_charWidth + m_charWidth; int m_numberWidth = fm.width(QChar(QLatin1Char('9'))); - m_labelWidth = 8 * m_numberWidth + 2 * m_charWidth; + m_labelWidth = 16 * m_numberWidth + 4 * m_charWidth; int expectedCharWidth = m_columnWidth / 3; const char *hex = "0123456789abcdef"; @@ -129,13 +130,17 @@ void BinEditor::init() } -void BinEditor::addLazyData(int block, const QByteArray &data) +void BinEditor::addLazyData(quint64 block, const QByteArray &data) { Q_ASSERT(m_inLazyMode); Q_ASSERT(data.size() == m_blockSize); - m_lazyData.insert(block, data); - m_lazyRequests.remove(block); - viewport()->update(); + const quint64 addr = block * m_blockSize; + if (addr >= m_baseAddr && addr <= m_baseAddr + m_size - 1) { + const int translatedBlock = (addr - m_baseAddr) / m_blockSize; + m_lazyData.insert(translatedBlock, data); + m_lazyRequests.remove(translatedBlock); + viewport()->update(); + } } bool BinEditor::requestDataAt(int pos, bool synchronous) const @@ -148,7 +153,8 @@ bool BinEditor::requestDataAt(int pos, bool synchronous) const if (it == m_lazyData.end()) { if (!m_lazyRequests.contains(block)) { m_lazyRequests.insert(block); - emit const_cast<BinEditor*>(this)->lazyDataRequested(block, synchronous); + emit const_cast<BinEditor*>(this)-> + lazyDataRequested(m_baseAddr / m_blockSize + block, synchronous); if (!m_lazyRequests.contains(block)) return true; // synchronous data source } @@ -294,6 +300,7 @@ bool BinEditor::isReadOnly() const void BinEditor::setData(const QByteArray &data) { m_inLazyMode = false; + m_baseAddr = 0; m_lazyData.clear(); m_lazyRequests.clear(); m_data = data; @@ -325,12 +332,12 @@ bool BinEditor::applyModifications(QByteArray &data) const if (data.size() != m_size) return false; for (QMap<int,QByteArray>::const_iterator it = m_lazyData.begin(); it != m_lazyData.end(); ++it) { - ::memcpy(data.data() + it.key() * m_blockSize, it->constData(), m_blockSize); + ::memcpy(data.data() + m_baseAddr + it.key() * m_blockSize, it->constData(), m_blockSize); } return true; } -void BinEditor::setLazyData(int cursorPosition, int size, int blockSize) +void BinEditor::setLazyData(quint64 startAddr, int range, int blockSize) { m_inLazyMode = true; m_blockSize = blockSize; @@ -339,7 +346,14 @@ void BinEditor::setLazyData(int cursorPosition, int size, int blockSize) m_data.clear(); m_lazyData.clear(); m_lazyRequests.clear(); - m_size = size; + + // In lazy mode, users can edit data in the range + // [startAddr - range/2, startAddr + range/2]. + m_baseAddr = static_cast<quint64>(range/2) > startAddr + ? 0 : startAddr - range/2; + m_baseAddr = (m_baseAddr / blockSize) * blockSize; + m_size = m_baseAddr != 0 && static_cast<quint64>(range) >= -m_baseAddr + ? -m_baseAddr : range; m_unmodifiedState = 0; m_undoStack.clear(); @@ -347,7 +361,7 @@ void BinEditor::setLazyData(int cursorPosition, int size, int blockSize) init(); - m_cursorPosition = cursorPosition; + m_cursorPosition = startAddr - m_baseAddr; verticalScrollBar()->setValue(m_cursorPosition / 16); emit cursorPositionChanged(m_cursorPosition); @@ -526,7 +540,8 @@ int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSen } -int BinEditor::find(const QByteArray &pattern_arg, int from, QTextDocument::FindFlags findFlags) +int BinEditor::find(const QByteArray &pattern_arg, int from, + QTextDocument::FindFlags findFlags) { if (pattern_arg.isEmpty()) return 0; @@ -541,7 +556,7 @@ int BinEditor::find(const QByteArray &pattern_arg, int from, QTextDocument::Find bool backwards = (findFlags & QTextDocument::FindBackward); int found = backwards ? dataLastIndexOf(pattern, from, caseSensitiveSearch) : dataIndexOf(pattern, from, caseSensitiveSearch); - + int foundHex = -1; QByteArray hexPattern = calculateHexPattern(pattern_arg); if (!hexPattern.isEmpty()) { @@ -593,20 +608,21 @@ void BinEditor::drawItems(QPainter *painter, int x, int y, const QString &itemSt } } -QString BinEditor::addressString(uint address) +QString BinEditor::addressString(quint64 address) { QChar *addressStringData = m_addressString.data(); const char *hex = "0123456789abcdef"; - for (int h = 0; h < 4; ++h) { - int shift = 4*(7-h); - addressStringData[h] = hex[(address & (0xf<<shift))>>shift]; - } - for (int h = 4; h < 8; ++h) { - int shift = 4*(7-h); - addressStringData[h+1] = hex[(address & (0xf<<shift))>>shift]; + + // Take colons into account. + const int indices[16] = { + 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18 + }; + + for (int b = 0; b < 8; ++b) { + addressStringData[indices[15 - b*2]] = hex[(address >> (8*b)) & 0xf]; + addressStringData[indices[14 - b*2]] = hex[(address >> (8*b + 4)) & 0xf]; } return m_addressString; - } void BinEditor::paintEvent(QPaintEvent *e) @@ -663,7 +679,8 @@ void BinEditor::paintEvent(QPaintEvent *e) continue; - painter.drawText(-xoffset, i * m_lineHeight + m_ascent, addressString(((uint) line) * 16)); + painter.drawText(-xoffset, i * m_lineHeight + m_ascent, + addressString(m_baseAddr + ((uint) line) * 16)); int cursor = -1; if (line * 16 <= m_cursorPosition && m_cursorPosition < line * 16 + 16) diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditor.h index 0b9184b7c4c4618273f09e55f414fbec33b90cdf..dc14fd7e608365fcb5a7e170719d4a8c0a92beda 100644 --- a/src/plugins/bineditor/bineditor.h +++ b/src/plugins/bineditor/bineditor.h @@ -64,9 +64,9 @@ public: inline int dataSize() const { return m_size; } inline bool inLazyMode() const { return m_inLazyMode; } - Q_INVOKABLE void setLazyData(int cursorPosition, int size, int blockSize = 4096); + Q_INVOKABLE void setLazyData(quint64 startAddr, int range, int blockSize = 4096); inline int lazyDataBlockSize() const { return m_blockSize; } - Q_INVOKABLE void addLazyData(int block, const QByteArray &data); + Q_INVOKABLE void addLazyData(quint64 block, const QByteArray &data); bool applyModifications(QByteArray &data) const; void zoomIn(int range = 1); @@ -86,7 +86,8 @@ public: void setReadOnly(bool); bool isReadOnly() const; - int find(const QByteArray &pattern, int from = 0, QTextDocument::FindFlags findFlags = 0); + int find(const QByteArray &pattern, int from = 0, + QTextDocument::FindFlags findFlags = 0); void selectAll(); void clear(); @@ -106,7 +107,7 @@ public: bool isUndoAvailable() const { return m_undoStack.size(); } bool isRedoAvailable() const { return m_redoStack.size(); } - QString addressString(uint address); + QString addressString(quint64 address); public Q_SLOTS: @@ -121,7 +122,7 @@ Q_SIGNALS: void copyAvailable(bool); void cursorPositionChanged(int position); - void lazyDataRequested(int block, bool syncronous); + void lazyDataRequested(quint64 block, bool synchronous); protected: void scrollContentsBy(int dx, int dy); @@ -169,6 +170,7 @@ private: int m_numLines; int m_numVisibleLines; + quint64 m_baseAddr; bool m_cursorVisible; int m_cursorPosition; diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index ddbb6250a25d84f1627f89a69eabf37e6887a83a..2d0f2054de41c6868a5aa3f02097980f87c22b5d 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -137,7 +137,7 @@ public: m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE)) { m_editor = parent; - connect(m_editor, SIGNAL(lazyDataRequested(int, bool)), this, SLOT(provideData(int))); + connect(m_editor, SIGNAL(lazyDataRequested(quint64, bool)), this, SLOT(provideData(quint64))); } ~BinEditorFile() {} @@ -162,7 +162,8 @@ public: file.write(data); file.close(); m_editor->setModified(false); - m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName()); + m_editor->editorInterface()-> + setDisplayName(QFileInfo(fileName).fileName()); m_fileName = fileName; emit changed(); return true; @@ -174,11 +175,13 @@ public: QFile file(fileName); if (file.open(QIODevice::ReadOnly)) { m_fileName = fileName; - if (file.isSequential()) { + if (file.isSequential() && file.size() <= INT_MAX) { m_editor->setData(file.readAll()); } else { - m_editor->setLazyData(0, file.size()); - m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName()); + m_editor->setLazyData(0, qMin(file.size(), + static_cast<qint64>(INT_MAX))); + m_editor->editorInterface()-> + setDisplayName(QFileInfo(fileName).fileName()); } file.close(); return true; @@ -187,7 +190,7 @@ public: } private slots: - void provideData(int block) { + void provideData(quint64 block) { QFile file(m_fileName); if (file.open(QIODevice::ReadOnly)) { int blockSize = m_editor->lazyDataBlockSize(); diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp index ad1b6d677105d6055f812e2aec33425ff30526e0..2b41b39394c0d82604ce869b674a683dcf1698d1 100644 --- a/src/plugins/debugger/debuggeragents.cpp +++ b/src/plugins/debugger/debuggeragents.cpp @@ -57,7 +57,7 @@ namespace Internal { // /////////////////////////////////////////////////////////////////////// -/*! +/*! \class MemoryViewAgent Objects form this class are created in response to user actions in @@ -84,30 +84,30 @@ MemoryViewAgent::~MemoryViewAgent() m_editor->deleteLater(); } -void MemoryViewAgent::init(quint64 addr) +void MemoryViewAgent::init(quint64 addr) { Core::EditorManager *editorManager = Core::EditorManager::instance(); QString titlePattern = tr("Memory $"); m_editor = editorManager->openEditorWithContents( Core::Constants::K_DEFAULT_BINARY_EDITOR, &titlePattern); - connect(m_editor->widget(), SIGNAL(lazyDataRequested(int,bool)), - this, SLOT(fetchLazyData(int,bool))); + connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)), + this, SLOT(fetchLazyData(quint64,bool))); editorManager->activateEditor(m_editor); QMetaObject::invokeMethod(m_editor->widget(), "setLazyData", - Q_ARG(int, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize)); + Q_ARG(quint64, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize)); } -void MemoryViewAgent::fetchLazyData(int block, bool sync) +void MemoryViewAgent::fetchLazyData(quint64 block, bool sync) { Q_UNUSED(sync); // FIXME: needed support for incremental searching - m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize); + m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize); } void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba) { QMetaObject::invokeMethod(m_editor->widget(), "addLazyData", - Q_ARG(int, addr / BinBlockSize), Q_ARG(QByteArray, ba)); + Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba)); } diff --git a/src/plugins/debugger/debuggeragents.h b/src/plugins/debugger/debuggeragents.h index 2ee788ccedc9c1770ee6b23e56ce03452ec02979..7e52f96fae9e2d98d54b00cd1fe48ebb7eee2301 100644 --- a/src/plugins/debugger/debuggeragents.h +++ b/src/plugins/debugger/debuggeragents.h @@ -63,7 +63,7 @@ public slots: // Called from Engine void addLazyData(quint64 addr, const QByteArray &data); // Called from Editor - void fetchLazyData(int block, bool sync); + void fetchLazyData(quint64 block, bool sync); private: void init(quint64 startaddr);