Merge remote-tracking branch 'origin/GP-3264_ghidragon_debugger_slow_down_caused_by_byteviewer_selection_bug'

This commit is contained in:
ghidragon
2023-03-28 14:09:27 -04:00
3 changed files with 67 additions and 12 deletions
@@ -606,6 +606,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
/** /**
* Convert the cursor location to a byte block and an offset. * Convert the cursor location to a byte block and an offset.
* @return the cursor location to a byte block and an offset.
*/ */
ByteBlockInfo getViewerCursorLocation() { ByteBlockInfo getViewerCursorLocation() {
FieldLocation loc = getCursorLocation(); FieldLocation loc = getCursorLocation();
@@ -634,11 +635,10 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
if (info == null) { if (info == null) {
return null; return null;
} }
ByteBlock block = info.getBlock();
BigInteger offset = info.getOffset(); BigInteger offset = info.getOffset();
int byteOffset = model.getByteOffset(info.getBlock(), pos); int byteOffset = model.getByteOffset(info.getBlock(), pos);
offset = offset.add(BigInteger.valueOf(byteOffset)); offset = offset.add(BigInteger.valueOf(byteOffset));
return new ByteBlockInfo(block, offset, loc.getCol()); return new ByteBlockInfo(info.getBlock(), offset, loc.getCol());
} }
DataFormatModel getDataModel() { DataFormatModel getDataModel() {
@@ -764,7 +764,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
layoutModel.setFactorys(fieldFactories, model, charWidth); layoutModel.setFactorys(fieldFactories, model, charWidth);
} }
private ByteBlockInfo getBlockInfoForSelectionStart(FieldLocation loc) { private IndexedByteBlockInfo getBlockInfoForSelectionStart(FieldLocation loc) {
BigInteger index = loc.getIndex(); BigInteger index = loc.getIndex();
int fieldNum = loc.getFieldNum(); int fieldNum = loc.getFieldNum();
@@ -778,7 +778,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
return indexMap.getBlockInfo(index, offset); return indexMap.getBlockInfo(index, offset);
} }
private ByteBlockInfo getBlockInfoForSelectionEnd(FieldLocation loc) { private IndexedByteBlockInfo getBlockInfoForSelectionEnd(FieldLocation loc) {
BigInteger lineIndex = loc.getIndex(); BigInteger lineIndex = loc.getIndex();
int fieldNum = loc.getFieldNum(); int fieldNum = loc.getFieldNum();
@@ -812,10 +812,17 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
return indexMap.getBlockInfo(lineIndex, lastByteInSelectionOnLine); return indexMap.getBlockInfo(lineIndex, lastByteInSelectionOnLine);
} }
private void addByteBlockRange(ByteBlockSelection sel, ByteBlockInfo start, ByteBlockInfo end) { private void addByteBlockRange(ByteBlockSelection sel, IndexedByteBlockInfo start,
IndexedByteBlockInfo end) {
if (start == null || end == null) { if (start == null || end == null) {
return; return;
} }
// this should only happen when both the start and end are on the same separator line
if (start.compareTo(end) > 0) {
return;
}
ByteBlock startBlock = start.getBlock(); ByteBlock startBlock = start.getBlock();
ByteBlock endBlock = end.getBlock(); ByteBlock endBlock = end.getBlock();
@@ -849,8 +856,8 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
FieldRange range = fieldSelection.getFieldRange(i); FieldRange range = fieldSelection.getFieldRange(i);
ByteBlockInfo start = getBlockInfoForSelectionStart(range.getStart()); IndexedByteBlockInfo start = getBlockInfoForSelectionStart(range.getStart());
ByteBlockInfo end = getBlockInfoForSelectionEnd(range.getEnd()); IndexedByteBlockInfo end = getBlockInfoForSelectionEnd(range.getEnd());
addByteBlockRange(blockSelection, start, end); addByteBlockRange(blockSelection, start, end);
} }
@@ -100,7 +100,7 @@ public class IndexMap {
* @return The ByteBlockInfo object that contains the block and offset into that block * @return The ByteBlockInfo object that contains the block and offset into that block
* that is the resulting byte value. * that is the resulting byte value.
*/ */
ByteBlockInfo getBlockInfo(BigInteger index, int fieldOffset) { IndexedByteBlockInfo getBlockInfo(BigInteger index, int fieldOffset) {
SortedMap<BigInteger, BlockInfo> tailMap = blockInfoMap.tailMap(index); SortedMap<BigInteger, BlockInfo> tailMap = blockInfoMap.tailMap(index);
if (tailMap.isEmpty()) { if (tailMap.isEmpty()) {
return null; return null;
@@ -109,7 +109,8 @@ public class IndexMap {
BigInteger byteIndex = index.multiply(bytesInLine).add(BigInteger.valueOf(fieldOffset)); BigInteger byteIndex = index.multiply(bytesInLine).add(BigInteger.valueOf(fieldOffset));
if ((byteIndex.compareTo(blockInfo.blockStart) >= 0) && if ((byteIndex.compareTo(blockInfo.blockStart) >= 0) &&
(byteIndex.compareTo(blockInfo.blockEnd) < 0)) { (byteIndex.compareTo(blockInfo.blockEnd) < 0)) {
return new ByteBlockInfo(blockInfo.block, byteIndex.subtract(blockInfo.blockStart)); return new IndexedByteBlockInfo(index, blockInfo.block,
byteIndex.subtract(blockInfo.blockStart), 0);
} }
return null; return null;
} }
@@ -257,12 +258,12 @@ public class IndexMap {
while (iterator.hasNext()) { while (iterator.hasNext()) {
BlockInfo next = iterator.next(); BlockInfo next = iterator.next();
if (next.block == endBlock) { if (next.block == endBlock) {
break; return byteBlocks;
} }
byteBlocks.add(next.block); byteBlocks.add(next.block);
} }
return byteBlocks; // didn't find the end, so the end must have been before the start, so return empty list
return List.of();
} }
} }
@@ -0,0 +1,47 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.format;
import java.math.BigInteger;
/**
* This is a ByteBlockInfo that also includes line index information. With the extra line index
* information, this object can be ordered and therefore, can implement {@link Comparable}
*/
public class IndexedByteBlockInfo extends ByteBlockInfo
implements Comparable<IndexedByteBlockInfo> {
private BigInteger lineIndex;
public IndexedByteBlockInfo(BigInteger lineIndex, ByteBlock block, BigInteger offset,
int column) {
super(block, offset, column);
this.lineIndex = lineIndex;
}
@Override
public int compareTo(IndexedByteBlockInfo o) {
int result = lineIndex.compareTo(o.lineIndex);
if (result == 0) {
result = getOffset().compareTo(o.getOffset());
}
if (result == 0) {
return Integer.compare(getColumn(), o.getColumn());
}
return result;
}
}