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
commit 11ac896fb3
3 changed files with 67 additions and 12 deletions

View File

@ -606,6 +606,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
/**
* Convert the cursor location to a byte block and an offset.
* @return the cursor location to a byte block and an offset.
*/
ByteBlockInfo getViewerCursorLocation() {
FieldLocation loc = getCursorLocation();
@ -634,11 +635,10 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
if (info == null) {
return null;
}
ByteBlock block = info.getBlock();
BigInteger offset = info.getOffset();
int byteOffset = model.getByteOffset(info.getBlock(), pos);
offset = offset.add(BigInteger.valueOf(byteOffset));
return new ByteBlockInfo(block, offset, loc.getCol());
return new ByteBlockInfo(info.getBlock(), offset, loc.getCol());
}
DataFormatModel getDataModel() {
@ -764,7 +764,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
layoutModel.setFactorys(fieldFactories, model, charWidth);
}
private ByteBlockInfo getBlockInfoForSelectionStart(FieldLocation loc) {
private IndexedByteBlockInfo getBlockInfoForSelectionStart(FieldLocation loc) {
BigInteger index = loc.getIndex();
int fieldNum = loc.getFieldNum();
@ -778,7 +778,7 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
return indexMap.getBlockInfo(index, offset);
}
private ByteBlockInfo getBlockInfoForSelectionEnd(FieldLocation loc) {
private IndexedByteBlockInfo getBlockInfoForSelectionEnd(FieldLocation loc) {
BigInteger lineIndex = loc.getIndex();
int fieldNum = loc.getFieldNum();
@ -812,10 +812,17 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
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) {
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 endBlock = end.getBlock();
@ -849,8 +856,8 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
for (int i = 0; i < count; i++) {
FieldRange range = fieldSelection.getFieldRange(i);
ByteBlockInfo start = getBlockInfoForSelectionStart(range.getStart());
ByteBlockInfo end = getBlockInfoForSelectionEnd(range.getEnd());
IndexedByteBlockInfo start = getBlockInfoForSelectionStart(range.getStart());
IndexedByteBlockInfo end = getBlockInfoForSelectionEnd(range.getEnd());
addByteBlockRange(blockSelection, start, end);
}

View File

@ -100,7 +100,7 @@ public class IndexMap {
* @return The ByteBlockInfo object that contains the block and offset into that block
* 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);
if (tailMap.isEmpty()) {
return null;
@ -109,7 +109,8 @@ public class IndexMap {
BigInteger byteIndex = index.multiply(bytesInLine).add(BigInteger.valueOf(fieldOffset));
if ((byteIndex.compareTo(blockInfo.blockStart) >= 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;
}
@ -257,12 +258,12 @@ public class IndexMap {
while (iterator.hasNext()) {
BlockInfo next = iterator.next();
if (next.block == endBlock) {
break;
return byteBlocks;
}
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();
}
}

View File

@ -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;
}
}