Updated the Bytes table column to not read too many bytes

This commit is contained in:
dragonmacher
2026-04-15 15:33:16 -04:00
parent 7ff28d30bc
commit 60431824b5
4 changed files with 57 additions and 45 deletions

View File

@@ -4,9 +4,9 @@
* 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.
@@ -40,6 +40,9 @@ public class BytesTableColumn extends ProgramLocationTableColumnExtensionPoint<A
private static SettingsDefinition[] SETTINGS_DEFS =
{ BYTE_COUNT, MEMORY_OFFSET, ENDIANNESS, FORMAT };
// arbitrary limit to keep the table from reading too many bytes and becoming sluggish
private static final int BYTE_LIMIT = 20;
private final GColumnRenderer<Byte[]> monospacedRenderer = new MonospacedByteRenderer();
/**
@@ -68,50 +71,32 @@ public class BytesTableColumn extends ProgramLocationTableColumnExtensionPoint<A
}
@Override
public Byte[] getValue(Address rowObject, Settings settings, Program pgm,
public Byte[] getValue(Address rowObject, Settings settings, Program program,
ServiceProvider serviceProvider) throws IllegalArgumentException {
Address addr = rowObject;
try {
int offset = MEMORY_OFFSET.getOffset(settings);
int byteCnt = BYTE_COUNT.getChoice(settings);
byte[] bytes = null;
int byteCount = BYTE_COUNT.getChoice(settings);
Address addr = rowObject;
if (offset != 0) {
addr = addr.add(offset);
}
if (byteCnt == 0) {
if (offset != 0) {
byteCnt = 1;
}
else {
CodeUnit cu = pgm.getListing().getCodeUnitContaining(addr);
if (cu == null) { // can happen for 'SpecialAddress'es
return new Byte[0];
}
if (cu instanceof Instruction instr) {
bytes = instr.getParsedBytes();
}
else {
bytes = cu.getBytes();
}
if (byteCount == 0) {
// note: would be nice to know why we only read one byte when there is an offset
byteCount = 1;
}
}
if (bytes == null) {
bytes = new byte[byteCnt];
pgm.getMemory().getBytes(addr, bytes);
if (byteCount == 0) {
return getBytesFromCodeUnit(program, addr);
}
Byte[] bytesObj = new Byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
bytesObj[i] = Byte.valueOf(bytes[i]);
}
return bytesObj;
// read bytes; one of: 1, 2, 3, 4, 5, 6, 7, 8
byte[] bytes = new byte[byteCount];
program.getMemory().getBytes(addr, bytes);
return toBigBytes(bytes);
}
catch (MemoryAccessException e) {
// handled below
@@ -123,6 +108,36 @@ public class BytesTableColumn extends ProgramLocationTableColumnExtensionPoint<A
return new Byte[0];
}
private Byte[] getBytesFromCodeUnit(Program p, Address addr) throws MemoryAccessException {
Listing listing = p.getListing();
CodeUnit cu = listing.getCodeUnitContaining(addr);
if (cu == null) { // can happen for 'SpecialAddress'es
return new Byte[0];
}
byte[] bytes;
int n = Math.min(cu.getLength(), BYTE_LIMIT);
if (cu instanceof Instruction instr) {
bytes = instr.getParsedBytes();
}
else {
bytes = new byte[n];
cu.getBytes(bytes, 0);
}
return toBigBytes(bytes);
}
private Byte[] toBigBytes(byte[] b) {
Byte[] bigBytes = new Byte[b.length];
for (int i = 0; i < b.length; i++) {
bigBytes[i] = Byte.valueOf(b[i]);
}
return bigBytes;
}
@Override
public GColumnRenderer<Byte[]> getColumnRenderer() {
return monospacedRenderer;

View File

@@ -59,7 +59,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
private MemoryBlock lastBlock;// the last accessed block
// lazy hashmap of block names to blocks, must be reloaded if blocks are removed or added
// lazy map of block names to blocks, must be reloaded if blocks are removed or added
private HashMap<String, MemoryBlock> nameBlockMap = new HashMap<>();
private final static MemoryBlock NoBlock = new MemoryBlockStub(); // placeholder for no block, not given out
@@ -135,9 +135,8 @@ public class MemoryMapDB implements Memory, ManagerDB {
* <br>
* NOTE: The {@link #initializeBlocks()} method is used to invalidate the {code addrSetViews}
* without affecting {@code allAddrSet}, while {@link #reloadAll()} will force a complete
* rebuild of all addresss sets.
* rebuild of all address sets.
*
* @param rebuildAllAddrSets if true all address sets will be rebuilt before returning the
* address set view object.
* @return the address set view object
*/
@@ -2126,8 +2125,6 @@ public class MemoryMapDB implements Memory, ManagerDB {
* In addition, allAddrSet will be updated if addToAll parameter is true.
*
* @param block memory block to be added
* @param newAddrSetViews address set views which should be built-up
* @param newAllAddrs if not null this set will be updated with the specified block's address range,
* otherwise only the {@code addrSetView} sets will be updated.
*/
private void addBlockAddresses(MemoryBlockDB block) {

View File

@@ -4,9 +4,9 @@
* 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.
@@ -97,7 +97,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
throws IndexOutOfBoundsException, MemoryAccessException, IOException;
/**
* Tries to get len bytes from this block at the given offset (relative to the containing
* Tries to get {@code len} bytes from this block at the given offset (relative to the containing
* {@link MemoryBlockDB} and put them into the given byte array at the specified offset.
* May return fewer bytes if the requested length is beyond the end of the block.
* @param memBlockOffset the offset relative to the containing {@link MemoryBlockDB}
@@ -130,7 +130,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
throws IndexOutOfBoundsException, MemoryAccessException, IOException;
/**
* Tries to write len bytes to this block at the given offset (relative to the containing
* Tries to write {@code len} bytes to this block at the given offset (relative to the containing
* {@link MemoryBlockDB} using the bytes contained in the given byte array at the specified byte
* array offset.
* May write fewer bytes if the requested length is beyond the end of the block.
@@ -157,7 +157,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
}
/**
* Sets the length of a subblock (Used by the split command)
* Sets the length of a sub-block (Used by the split command)
* @param length the new length of the block
* @throws IOException if a database error occurs
*/

View File

@@ -266,9 +266,9 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
public int getBytes(Address addr, byte[] b) throws MemoryAccessException;
/**
* Tries to get len bytes from this block at the given address and put them into the given byte
* array at the specified offet. May return fewer bytes if the requested length is beyond the
* end of the block.
* Tries to get {@code len} bytes from this block at the given address and put them into the
* given byte array at the specified offset. May return fewer bytes if the requested length is
* beyond the end of the block.
*
* @param addr the address from which to get the bytes.
* @param b the byte array to populate.