diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BitMappedSubMemoryBlock.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BitMappedSubMemoryBlock.java index de8103abae..b1b77645ad 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BitMappedSubMemoryBlock.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BitMappedSubMemoryBlock.java @@ -45,13 +45,14 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock { } @Override - public byte getByte(long offset) throws MemoryAccessException, IOException { + public byte getByte(long offsetInMemBlock) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; if (ioPending) { throw new MemoryAccessException("Cyclic Access"); } try { ioPending = true; - return getBitOverlayByte(offset); + return getBitOverlayByte(offsetInSubBlock); } catch (AddressOverflowException e) { throw new MemoryAccessException("No memory at address"); @@ -62,21 +63,23 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock { } public AddressRange getMappedRange() { - Address endMappedAddress = mappedAddress.add((length - 1) / 8); + Address endMappedAddress = mappedAddress.add((subBlockLength - 1) / 8); return new AddressRangeImpl(mappedAddress, endMappedAddress); } @Override - public int getBytes(long offset, byte[] b, int off, int len) + public int getBytes(long offsetInMemBlock, byte[] b, int off, int len) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); if (ioPending) { new MemoryAccessException("Cyclic Access"); } try { ioPending = true; - len = (int) Math.min(len, length - offset); for (int i = 0; i < len; i++) { - b[i + off] = getBitOverlayByte(offset++); + b[i + off] = getBitOverlayByte(offsetInMemBlock++); } return len; } @@ -89,13 +92,15 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock { } @Override - public void putByte(long offset, byte b) throws MemoryAccessException, IOException { + public void putByte(long offsetInMemBlock, byte b) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; try { if (ioPending) { new MemoryAccessException("Cyclic Access"); } ioPending = true; - doPutByte(mappedAddress.addNoWrap(offset / 8), (int) (offset % 8), b); + doPutByte(mappedAddress.addNoWrap(offsetInSubBlock / 8), (int) (offsetInSubBlock % 8), + b); } catch (AddressOverflowException e) { new MemoryAccessException("No memory at address"); @@ -107,17 +112,20 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock { } @Override - public int putBytes(long offset, byte[] b, int off, int len) + public int putBytes(long offsetInMemBlock, byte[] b, int off, int len) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); try { if (ioPending) { new MemoryAccessException("Cyclic Access"); } ioPending = true; - len = (int) Math.min(len, length - offset); for (int i = 0; i < len; i++) { - doPutByte(mappedAddress.addNoWrap(offset / 8), (int) (offset % 8), b[off + i]); - offset++; + doPutByte(mappedAddress.addNoWrap(offsetInSubBlock / 8), + (int) (offsetInSubBlock % 8), b[off + i]); + offsetInSubBlock++; } return len; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BufferSubMemoryBlock.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BufferSubMemoryBlock.java index 23d0dfef0e..0c9ffd6ba3 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BufferSubMemoryBlock.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/BufferSubMemoryBlock.java @@ -41,26 +41,32 @@ class BufferSubMemoryBlock extends SubMemoryBlock { } @Override - public byte getByte(long offset) throws IOException { - return buf.getByte((int) (offset - startingOffset)); + public byte getByte(long offsetInMemBlock) throws IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + return buf.getByte((int) offsetInSubBlock); } @Override - public int getBytes(long offset, byte[] b, int off, int len) throws IOException { - len = Math.min(len, (int) (length - (offset - startingOffset))); - buf.get((int) (offset - startingOffset), b, off, len); + public int getBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); + buf.get((int) offsetInSubBlock, b, off, len); return len; } @Override - public void putByte(long offset, byte b) throws IOException { - buf.putByte((int) (offset - startingOffset), b); + public void putByte(long offsetInMemBlock, byte b) throws IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + buf.putByte((int) offsetInSubBlock, b); } @Override - public int putBytes(long offset, byte[] b, int off, int len) throws IOException { - len = Math.min(len, (int) (length - offset - startingOffset)); - buf.put((int) (offset - startingOffset), b, off, len); + public int putBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); + buf.put((int) offsetInSubBlock, b, off, len); return len; } @@ -76,11 +82,11 @@ class BufferSubMemoryBlock extends SubMemoryBlock { return false; } BufferSubMemoryBlock other = (BufferSubMemoryBlock) block; - if (other.length + length > Memory.GBYTE) { + if (other.subBlockLength + subBlockLength > Memory.GBYTE) { return false; } buf.append(other.buf); - setLength(length + other.length); + setLength(subBlockLength + other.subBlockLength); adapter.deleteSubBlock(other.record.getKey()); return true; } @@ -97,10 +103,10 @@ class BufferSubMemoryBlock extends SubMemoryBlock { @Override protected SubMemoryBlock split(long memBlockOffset) throws IOException { // convert from offset in block to offset in this sub block - int offset = (int) (memBlockOffset - startingOffset); - long newLength = length - offset; - length = offset; - record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length); + int offset = (int) (memBlockOffset - subBlockOffset); + long newLength = subBlockLength - offset; + subBlockLength = offset; + record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength); adapter.updateSubBlockRecord(record); DBBuffer split = buf.split(offset); @@ -122,8 +128,7 @@ class BufferSubMemoryBlock extends SubMemoryBlock { long size) { long sourceId = -buf.getId(); // buffers use negative id values; FileBytes use positive id values. ByteSourceRange bsRange = - new ByteSourceRange(block, start, size, sourceId, memBlockOffset - startingOffset); + new ByteSourceRange(block, start, size, sourceId, memBlockOffset - subBlockOffset); return new ByteSourceRangeList(bsRange); } } - diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/ByteMappedSubMemoryBlock.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/ByteMappedSubMemoryBlock.java index 2c1538a6cd..b2e7c9936c 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/ByteMappedSubMemoryBlock.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/ByteMappedSubMemoryBlock.java @@ -46,13 +46,14 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock { } @Override - public byte getByte(long offset) throws MemoryAccessException, IOException { + public byte getByte(long offsetInMemBlock) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; if (ioPending) { new MemoryAccessException("Cyclic Access"); } try { ioPending = true; - return memMap.getByte(mappedAddress.addNoWrap(offset - startingOffset)); + return memMap.getByte(mappedAddress.addNoWrap(offsetInSubBlock)); } catch (AddressOverflowException e) { throw new MemoryAccessException("No memory at address"); @@ -63,15 +64,17 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock { } @Override - public int getBytes(long offset, byte[] b, int off, int len) + public int getBytes(long offsetInMemBlock, byte[] b, int off, int len) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); if (ioPending) { new MemoryAccessException("Cyclic Access"); } try { ioPending = true; - len = (int) Math.min(len, length - (offset - startingOffset)); - return memMap.getBytes(mappedAddress.addNoWrap(offset), b, off, len); + return memMap.getBytes(mappedAddress.addNoWrap(offsetInSubBlock), b, off, len); } catch (AddressOverflowException e) { throw new MemoryAccessException("No memory at address"); @@ -82,13 +85,14 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock { } @Override - public void putByte(long offset, byte b) throws MemoryAccessException, IOException { + public void putByte(long offsetInMemBlock, byte b) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; try { if (ioPending) { new MemoryAccessException("Cyclic Access"); } ioPending = true; - memMap.setByte(mappedAddress.addNoWrap(offset - startingOffset), b); + memMap.setByte(mappedAddress.addNoWrap(offsetInSubBlock), b); } catch (AddressOverflowException e) { throw new MemoryAccessException("No memory at address"); @@ -100,15 +104,18 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock { } @Override - public int putBytes(long offset, byte[] b, int off, int len) + public int putBytes(long offsetInMemBlock, byte[] b, int off, int len) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); try { if (ioPending) { new MemoryAccessException("Cyclic Access"); } ioPending = true; - len = (int) Math.min(len, length - (offset - startingOffset)); - memMap.setBytes(mappedAddress.addNoWrap(offset - startingOffset), b, off, len); + memMap.setBytes(mappedAddress.addNoWrap(offsetInSubBlock), b, off, + len); return len; } catch (AddressOverflowException e) { @@ -120,7 +127,7 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock { } public AddressRange getMappedRange() { - Address endMappedAddress = mappedAddress.add(length - 1); + Address endMappedAddress = mappedAddress.add(subBlockLength - 1); return new AddressRangeImpl(mappedAddress, endMappedAddress); } @@ -142,10 +149,10 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock { @Override protected SubMemoryBlock split(long memBlockOffset) throws IOException { // convert from offset in block to offset in this sub block - int offset = (int) (memBlockOffset - startingOffset); - long newLength = length - offset; - length = offset; - record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length); + int offset = (int) (memBlockOffset - subBlockOffset); + long newLength = subBlockLength - offset; + subBlockLength = offset; + record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength); adapter.updateSubBlockRecord(record); Address newAddr = mappedAddress.add(offset); @@ -167,7 +174,7 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock { protected ByteSourceRangeList getByteSourceRangeList(MemoryBlock block, Address start, long offset, long size) { ByteSourceRangeList result = new ByteSourceRangeList(); - long relativeOffset = offset - startingOffset; + long relativeOffset = offset - subBlockOffset; Address startAddress = mappedAddress.add(relativeOffset); Address endAddress = startAddress.add(size - 1); List blocks = memMap.getBlocks(startAddress, endAddress); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytesSubMemoryBlock.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytesSubMemoryBlock.java index 460a324be1..6e807e06d0 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytesSubMemoryBlock.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytesSubMemoryBlock.java @@ -41,24 +41,31 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock { } @Override - public byte getByte(long memBlockOffset) throws IOException { - return fileBytes.getModifiedByte(fileBytesOffset + memBlockOffset - startingOffset); + public byte getByte(long offsetInMemBlock) throws IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + return fileBytes.getModifiedByte(fileBytesOffset + offsetInSubBlock); } @Override - public int getBytes(long memBlockOffset, byte[] b, int off, int len) throws IOException { - return fileBytes.getModifiedBytes(fileBytesOffset + memBlockOffset - startingOffset, b, off, - len); + public int getBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); + return fileBytes.getModifiedBytes(fileBytesOffset + offsetInSubBlock, b, off, len); } @Override - public void putByte(long memBlockOffset, byte b) throws MemoryAccessException, IOException { - fileBytes.putByte(fileBytesOffset + memBlockOffset - startingOffset, b); + public void putByte(long offsetInMemBlock, byte b) throws MemoryAccessException, IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + fileBytes.putByte(fileBytesOffset + offsetInSubBlock, b); } @Override - public int putBytes(long memBlockOffset, byte[] b, int off, int len) throws IOException { - return fileBytes.putBytes(fileBytesOffset + memBlockOffset - startingOffset, b, off, len); + public int putBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException { + long offsetInSubBlock = offsetInMemBlock - subBlockOffset; + long available = subBlockLength - offsetInSubBlock; + len = (int) Math.min(len, available); + return fileBytes.putBytes(fileBytesOffset + offsetInSubBlock, b, off, len); } @Override @@ -71,11 +78,11 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock { return false; } // are the two block consecutive in the fileBytes space? - if (other.fileBytesOffset != fileBytesOffset + length) { + if (other.fileBytesOffset != fileBytesOffset + subBlockLength) { return false; } // ok we can join them - setLength(length + other.length); + setLength(subBlockLength + other.subBlockLength); adapter.deleteSubBlock(other.record.getKey()); return true; } @@ -96,10 +103,10 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock { @Override protected SubMemoryBlock split(long memBlockOffset) throws IOException { // convert from offset in block to offset in this sub block - int offset = (int) (memBlockOffset - startingOffset); - long newLength = length - offset; - length = offset; - record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length); + int offset = (int) (memBlockOffset - subBlockOffset); + long newLength = subBlockLength - offset; + subBlockLength = offset; + record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength); adapter.updateSubBlockRecord(record); int fileBytesID = record.getIntValue(MemoryMapDBAdapter.SUB_SOURCE_ID_COL); @@ -128,9 +135,8 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock { long size) { long sourceId = fileBytes.getId(); ByteSourceRange bsRange = new ByteSourceRange(block, start, size, sourceId, - fileBytesOffset + memBlockOffset - startingOffset); + fileBytesOffset + memBlockOffset - subBlockOffset); return new ByteSourceRangeList(bsRange); } } - diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockDB.java index 59ce900ee8..2cd033f826 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockDB.java @@ -631,7 +631,7 @@ public class MemoryBlockDB implements MemoryBlock { long startingOffset = 0; for (SubMemoryBlock subBlock : subBlocks) { subBlock.setParentIdAndStartingOffset(id, startingOffset); - startingOffset += subBlock.length; + startingOffset += subBlock.subBlockLength; } } @@ -692,7 +692,7 @@ public class MemoryBlockDB implements MemoryBlock { size = Math.min(size, length - offset); SubMemoryBlock subBlock = getSubBlock(offset); - long subSize = Math.min(size, subBlock.length - (offset - subBlock.getStartingOffset())); + long subSize = Math.min(size, subBlock.subBlockLength - (offset - subBlock.getStartingOffset())); if (subSize == size) { return subBlock.getByteSourceRangeList(this, address, offset, size); } @@ -702,7 +702,7 @@ public class MemoryBlockDB implements MemoryBlock { long total = subSize; while (total < size) { subBlock = getSubBlock(offset + total); - subSize = Math.min(size - total, subBlock.length); + subSize = Math.min(size - total, subBlock.subBlockLength); start = address.add(total); set.add(subBlock.getByteSourceRangeList(this, start, offset + total, subSize)); total += subSize; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockSourceInfoDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockSourceInfoDB.java index d7c7f41c7a..185157c900 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockSourceInfoDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryBlockSourceInfoDB.java @@ -40,7 +40,7 @@ class MemoryBlockSourceInfoDB implements MemoryBlockSourceInfo { */ @Override public long getLength() { - return subBlock.length; + return subBlock.subBlockLength; } /** @@ -48,7 +48,7 @@ class MemoryBlockSourceInfoDB implements MemoryBlockSourceInfo { */ @Override public Address getMinAddress() { - return block.getStart().add(subBlock.startingOffset); + return block.getStart().add(subBlock.subBlockOffset); } /** @@ -56,7 +56,7 @@ class MemoryBlockSourceInfoDB implements MemoryBlockSourceInfo { */ @Override public Address getMaxAddress() { - return block.getStart().add(subBlock.startingOffset + subBlock.length - 1); + return block.getStart().add(subBlock.subBlockOffset + subBlock.subBlockLength - 1); } /** @@ -104,7 +104,7 @@ class MemoryBlockSourceInfoDB implements MemoryBlockSourceInfo { public long getFileBytesOffset(Address address) { if (subBlock instanceof FileBytesSubMemoryBlock && contains(address)) { long blockOffset = address.subtract(getMinAddress()); - long subBlockOffset = blockOffset - subBlock.startingOffset; + long subBlockOffset = blockOffset - subBlock.subBlockOffset; return ((FileBytesSubMemoryBlock) subBlock).getFileBytesOffset() + subBlockOffset; } return -1; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryMapDBAdapterV3.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryMapDBAdapterV3.java index 4f94565c4b..bc462f073d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryMapDBAdapterV3.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/MemoryMapDBAdapterV3.java @@ -249,7 +249,7 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter { long startingOffset = 0; for (SubMemoryBlock subMemoryBlock : splitBlocks) { subMemoryBlock.setParentIdAndStartingOffset(key, startingOffset); - startingOffset += subMemoryBlock.length; + startingOffset += subMemoryBlock.subBlockLength; } memBlockTable.putRecord(blockRecord); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/SubMemoryBlock.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/SubMemoryBlock.java index 8a7e28957a..e133fe246a 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/SubMemoryBlock.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/SubMemoryBlock.java @@ -30,14 +30,14 @@ abstract class SubMemoryBlock implements Comparable { protected final MemoryMapDBAdapter adapter; protected final Record record; - protected long length; - protected long startingOffset; + protected long subBlockLength; + protected long subBlockOffset; protected SubMemoryBlock(MemoryMapDBAdapter adapter, Record record) { this.adapter = adapter; this.record = record; - this.startingOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL); - this.length = record.getLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL); + this.subBlockOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL); + this.subBlockLength = record.getLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL); } /** @@ -62,7 +62,7 @@ abstract class SubMemoryBlock implements Comparable { * @return the starting offset for this sub block. */ public final long getStartingOffset() { - return startingOffset; + return subBlockOffset; } /** @@ -70,7 +70,7 @@ abstract class SubMemoryBlock implements Comparable { * @return the length of this sub block */ public final long getLength() { - return length; + return subBlockLength; } /** @@ -80,7 +80,7 @@ abstract class SubMemoryBlock implements Comparable { * @return true if the offset is valid for this block */ public final boolean contains(long memBlockOffset) { - return memBlockOffset >= startingOffset && memBlockOffset < startingOffset + length; + return memBlockOffset >= subBlockOffset && memBlockOffset < subBlockOffset + subBlockLength; } /** @@ -158,7 +158,7 @@ abstract class SubMemoryBlock implements Comparable { * @throws IOException if a database error occurs */ protected void setLength(long length) throws IOException { - this.length = length; + this.subBlockLength = length; record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length); adapter.updateSubBlockRecord(record); } @@ -216,7 +216,7 @@ abstract class SubMemoryBlock implements Comparable { * @throws IOException if a database error occurs. */ protected void setParentIdAndStartingOffset(long key, long startingOffset) throws IOException { - this.startingOffset = startingOffset; + this.subBlockOffset = startingOffset; record.setLongValue(MemoryMapDBAdapter.SUB_PARENT_ID_COL, key); record.setLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL, startingOffset); adapter.updateSubBlockRecord(record); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/UninitializedSubMemoryBlock.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/UninitializedSubMemoryBlock.java index 03da2e644c..b3cee0938d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/UninitializedSubMemoryBlock.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/UninitializedSubMemoryBlock.java @@ -28,7 +28,7 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock { UninitializedSubMemoryBlock(MemoryMapDBAdapter adapter, Record record) { super(adapter, record); - startingOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL); + subBlockOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL); } @Override @@ -38,10 +38,10 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock { @Override public byte getByte(long offset) throws MemoryAccessException { - if (offset < startingOffset || offset >= startingOffset + length) { + if (offset < subBlockOffset || offset >= subBlockOffset + subBlockLength) { throw new IllegalArgumentException( - "Offset " + offset + "is out of bounds. Should be in [" + startingOffset + "," + - (startingOffset + length - 1)); + "Offset " + offset + "is out of bounds. Should be in [" + subBlockOffset + "," + + (subBlockOffset + subBlockLength - 1)); } throw new MemoryAccessException("Attempted to read from uninitialized block"); } @@ -66,7 +66,7 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock { if (!(block instanceof UninitializedSubMemoryBlock)) { return false; } - setLength(length + block.length); + setLength(subBlockLength + block.subBlockLength); adapter.deleteSubBlock(block.record.getKey()); return true; } @@ -79,10 +79,10 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock { @Override protected SubMemoryBlock split(long memBlockOffset) throws IOException { // convert from offset in block to offset in this sub block - long offset = memBlockOffset - startingOffset; - long newLength = length - offset; - length = offset; - record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length); + long offset = memBlockOffset - subBlockOffset; + long newLength = subBlockLength - offset; + subBlockLength = offset; + record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength); adapter.updateSubBlockRecord(record); Record newSubRecord = adapter.createSubBlockRecord(-1, 0, newLength, diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/database/mem/MemBlockDBTest.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/database/mem/MemBlockDBTest.java index c302821f28..f2225cdd91 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/database/mem/MemBlockDBTest.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/database/mem/MemBlockDBTest.java @@ -18,6 +18,7 @@ package ghidra.program.database.mem; import static org.junit.Assert.*; import java.io.ByteArrayInputStream; +import java.util.Arrays; import java.util.List; import org.junit.*; @@ -315,6 +316,27 @@ public class MemBlockDBTest extends AbstractGenericTest { } } + @Test + public void testWriteBytesAcrossSubBlocks() throws Exception { + FileBytes fileBytes = createFileBytes(); + MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(10), 25, 10); + MemoryBlock block2 = createFileBytesBlock(fileBytes, addr(20), 50, 10); + mem.join(block1, block2); + byte[] bytes = createBytes(20); + mem.setBytes(addr(10), bytes); + byte[] readBytes = new byte[20]; + mem.getBytes(addr(10), readBytes); + assertTrue(Arrays.equals(bytes, readBytes)); + } + + private byte[] createBytes(int size) { + byte[] bytes = new byte[size]; + for (int i = 0; i < size; i++) { + bytes[i] = (byte) i; + } + return bytes; + } + @Test public void testJoinFileBytes() throws Exception { FileBytes fileBytes = createFileBytes();