mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
fixing issues in memory sub-blocks
This commit is contained in:
parent
083b5f61cc
commit
c73f0381d0
10 changed files with 137 additions and 89 deletions
|
@ -45,13 +45,14 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(long offset) throws MemoryAccessException, IOException {
|
public byte getByte(long offsetInMemBlock) throws MemoryAccessException, IOException {
|
||||||
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
throw new MemoryAccessException("Cyclic Access");
|
throw new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
return getBitOverlayByte(offset);
|
return getBitOverlayByte(offsetInSubBlock);
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
throw new MemoryAccessException("No memory at address");
|
throw new MemoryAccessException("No memory at address");
|
||||||
|
@ -62,21 +63,23 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddressRange getMappedRange() {
|
public AddressRange getMappedRange() {
|
||||||
Address endMappedAddress = mappedAddress.add((length - 1) / 8);
|
Address endMappedAddress = mappedAddress.add((subBlockLength - 1) / 8);
|
||||||
return new AddressRangeImpl(mappedAddress, endMappedAddress);
|
return new AddressRangeImpl(mappedAddress, endMappedAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
throws MemoryAccessException, IOException {
|
||||||
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
new MemoryAccessException("Cyclic Access");
|
new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
len = (int) Math.min(len, length - offset);
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
b[i + off] = getBitOverlayByte(offset++);
|
b[i + off] = getBitOverlayByte(offsetInMemBlock++);
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -89,13 +92,15 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
try {
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
new MemoryAccessException("Cyclic Access");
|
new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
doPutByte(mappedAddress.addNoWrap(offset / 8), (int) (offset % 8), b);
|
doPutByte(mappedAddress.addNoWrap(offsetInSubBlock / 8), (int) (offsetInSubBlock % 8),
|
||||||
|
b);
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
new MemoryAccessException("No memory at address");
|
new MemoryAccessException("No memory at address");
|
||||||
|
@ -107,17 +112,20 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
throws MemoryAccessException, IOException {
|
||||||
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
try {
|
try {
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
new MemoryAccessException("Cyclic Access");
|
new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
len = (int) Math.min(len, length - offset);
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
doPutByte(mappedAddress.addNoWrap(offset / 8), (int) (offset % 8), b[off + i]);
|
doPutByte(mappedAddress.addNoWrap(offsetInSubBlock / 8),
|
||||||
offset++;
|
(int) (offsetInSubBlock % 8), b[off + i]);
|
||||||
|
offsetInSubBlock++;
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,26 +41,32 @@ class BufferSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(long offset) throws IOException {
|
public byte getByte(long offsetInMemBlock) throws IOException {
|
||||||
return buf.getByte((int) (offset - startingOffset));
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
return buf.getByte((int) offsetInSubBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBytes(long offset, byte[] b, int off, int len) throws IOException {
|
public int getBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException {
|
||||||
len = Math.min(len, (int) (length - (offset - startingOffset)));
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
buf.get((int) (offset - startingOffset), b, off, len);
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
|
buf.get((int) offsetInSubBlock, b, off, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putByte(long offset, byte b) throws IOException {
|
public void putByte(long offsetInMemBlock, byte b) throws IOException {
|
||||||
buf.putByte((int) (offset - startingOffset), b);
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
buf.putByte((int) offsetInSubBlock, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int putBytes(long offset, byte[] b, int off, int len) throws IOException {
|
public int putBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException {
|
||||||
len = Math.min(len, (int) (length - offset - startingOffset));
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
buf.put((int) (offset - startingOffset), b, off, len);
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
|
buf.put((int) offsetInSubBlock, b, off, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,11 +82,11 @@ class BufferSubMemoryBlock extends SubMemoryBlock {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BufferSubMemoryBlock other = (BufferSubMemoryBlock) block;
|
BufferSubMemoryBlock other = (BufferSubMemoryBlock) block;
|
||||||
if (other.length + length > Memory.GBYTE) {
|
if (other.subBlockLength + subBlockLength > Memory.GBYTE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buf.append(other.buf);
|
buf.append(other.buf);
|
||||||
setLength(length + other.length);
|
setLength(subBlockLength + other.subBlockLength);
|
||||||
adapter.deleteSubBlock(other.record.getKey());
|
adapter.deleteSubBlock(other.record.getKey());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -97,10 +103,10 @@ class BufferSubMemoryBlock extends SubMemoryBlock {
|
||||||
@Override
|
@Override
|
||||||
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
||||||
// convert from offset in block to offset in this sub block
|
// convert from offset in block to offset in this sub block
|
||||||
int offset = (int) (memBlockOffset - startingOffset);
|
int offset = (int) (memBlockOffset - subBlockOffset);
|
||||||
long newLength = length - offset;
|
long newLength = subBlockLength - offset;
|
||||||
length = offset;
|
subBlockLength = offset;
|
||||||
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length);
|
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength);
|
||||||
adapter.updateSubBlockRecord(record);
|
adapter.updateSubBlockRecord(record);
|
||||||
|
|
||||||
DBBuffer split = buf.split(offset);
|
DBBuffer split = buf.split(offset);
|
||||||
|
@ -122,8 +128,7 @@ class BufferSubMemoryBlock extends SubMemoryBlock {
|
||||||
long size) {
|
long size) {
|
||||||
long sourceId = -buf.getId(); // buffers use negative id values; FileBytes use positive id values.
|
long sourceId = -buf.getId(); // buffers use negative id values; FileBytes use positive id values.
|
||||||
ByteSourceRange bsRange =
|
ByteSourceRange bsRange =
|
||||||
new ByteSourceRange(block, start, size, sourceId, memBlockOffset - startingOffset);
|
new ByteSourceRange(block, start, size, sourceId, memBlockOffset - subBlockOffset);
|
||||||
return new ByteSourceRangeList(bsRange);
|
return new ByteSourceRangeList(bsRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,13 +46,14 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(long offset) throws MemoryAccessException, IOException {
|
public byte getByte(long offsetInMemBlock) throws MemoryAccessException, IOException {
|
||||||
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
new MemoryAccessException("Cyclic Access");
|
new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
return memMap.getByte(mappedAddress.addNoWrap(offset - startingOffset));
|
return memMap.getByte(mappedAddress.addNoWrap(offsetInSubBlock));
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
throw new MemoryAccessException("No memory at address");
|
throw new MemoryAccessException("No memory at address");
|
||||||
|
@ -63,15 +64,17 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
throws MemoryAccessException, IOException {
|
||||||
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
new MemoryAccessException("Cyclic Access");
|
new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
len = (int) Math.min(len, length - (offset - startingOffset));
|
return memMap.getBytes(mappedAddress.addNoWrap(offsetInSubBlock), b, off, len);
|
||||||
return memMap.getBytes(mappedAddress.addNoWrap(offset), b, off, len);
|
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
throw new MemoryAccessException("No memory at address");
|
throw new MemoryAccessException("No memory at address");
|
||||||
|
@ -82,13 +85,14 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
try {
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
new MemoryAccessException("Cyclic Access");
|
new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
memMap.setByte(mappedAddress.addNoWrap(offset - startingOffset), b);
|
memMap.setByte(mappedAddress.addNoWrap(offsetInSubBlock), b);
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
throw new MemoryAccessException("No memory at address");
|
throw new MemoryAccessException("No memory at address");
|
||||||
|
@ -100,15 +104,18 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 {
|
throws MemoryAccessException, IOException {
|
||||||
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
try {
|
try {
|
||||||
if (ioPending) {
|
if (ioPending) {
|
||||||
new MemoryAccessException("Cyclic Access");
|
new MemoryAccessException("Cyclic Access");
|
||||||
}
|
}
|
||||||
ioPending = true;
|
ioPending = true;
|
||||||
len = (int) Math.min(len, length - (offset - startingOffset));
|
memMap.setBytes(mappedAddress.addNoWrap(offsetInSubBlock), b, off,
|
||||||
memMap.setBytes(mappedAddress.addNoWrap(offset - startingOffset), b, off, len);
|
len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
|
@ -120,7 +127,7 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddressRange getMappedRange() {
|
public AddressRange getMappedRange() {
|
||||||
Address endMappedAddress = mappedAddress.add(length - 1);
|
Address endMappedAddress = mappedAddress.add(subBlockLength - 1);
|
||||||
return new AddressRangeImpl(mappedAddress, endMappedAddress);
|
return new AddressRangeImpl(mappedAddress, endMappedAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,10 +149,10 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
@Override
|
@Override
|
||||||
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
||||||
// convert from offset in block to offset in this sub block
|
// convert from offset in block to offset in this sub block
|
||||||
int offset = (int) (memBlockOffset - startingOffset);
|
int offset = (int) (memBlockOffset - subBlockOffset);
|
||||||
long newLength = length - offset;
|
long newLength = subBlockLength - offset;
|
||||||
length = offset;
|
subBlockLength = offset;
|
||||||
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length);
|
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength);
|
||||||
adapter.updateSubBlockRecord(record);
|
adapter.updateSubBlockRecord(record);
|
||||||
|
|
||||||
Address newAddr = mappedAddress.add(offset);
|
Address newAddr = mappedAddress.add(offset);
|
||||||
|
@ -167,7 +174,7 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
|
||||||
protected ByteSourceRangeList getByteSourceRangeList(MemoryBlock block, Address start,
|
protected ByteSourceRangeList getByteSourceRangeList(MemoryBlock block, Address start,
|
||||||
long offset, long size) {
|
long offset, long size) {
|
||||||
ByteSourceRangeList result = new ByteSourceRangeList();
|
ByteSourceRangeList result = new ByteSourceRangeList();
|
||||||
long relativeOffset = offset - startingOffset;
|
long relativeOffset = offset - subBlockOffset;
|
||||||
Address startAddress = mappedAddress.add(relativeOffset);
|
Address startAddress = mappedAddress.add(relativeOffset);
|
||||||
Address endAddress = startAddress.add(size - 1);
|
Address endAddress = startAddress.add(size - 1);
|
||||||
List<MemoryBlockDB> blocks = memMap.getBlocks(startAddress, endAddress);
|
List<MemoryBlockDB> blocks = memMap.getBlocks(startAddress, endAddress);
|
||||||
|
|
|
@ -41,24 +41,31 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(long memBlockOffset) throws IOException {
|
public byte getByte(long offsetInMemBlock) throws IOException {
|
||||||
return fileBytes.getModifiedByte(fileBytesOffset + memBlockOffset - startingOffset);
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
return fileBytes.getModifiedByte(fileBytesOffset + offsetInSubBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBytes(long memBlockOffset, byte[] b, int off, int len) throws IOException {
|
public int getBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException {
|
||||||
return fileBytes.getModifiedBytes(fileBytesOffset + memBlockOffset - startingOffset, b, off,
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
len);
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
|
return fileBytes.getModifiedBytes(fileBytesOffset + offsetInSubBlock, b, off, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putByte(long memBlockOffset, byte b) throws MemoryAccessException, IOException {
|
public void putByte(long offsetInMemBlock, byte b) throws MemoryAccessException, IOException {
|
||||||
fileBytes.putByte(fileBytesOffset + memBlockOffset - startingOffset, b);
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
fileBytes.putByte(fileBytesOffset + offsetInSubBlock, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int putBytes(long memBlockOffset, byte[] b, int off, int len) throws IOException {
|
public int putBytes(long offsetInMemBlock, byte[] b, int off, int len) throws IOException {
|
||||||
return fileBytes.putBytes(fileBytesOffset + memBlockOffset - startingOffset, b, off, len);
|
long offsetInSubBlock = offsetInMemBlock - subBlockOffset;
|
||||||
|
long available = subBlockLength - offsetInSubBlock;
|
||||||
|
len = (int) Math.min(len, available);
|
||||||
|
return fileBytes.putBytes(fileBytesOffset + offsetInSubBlock, b, off, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,11 +78,11 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// are the two block consecutive in the fileBytes space?
|
// are the two block consecutive in the fileBytes space?
|
||||||
if (other.fileBytesOffset != fileBytesOffset + length) {
|
if (other.fileBytesOffset != fileBytesOffset + subBlockLength) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// ok we can join them
|
// ok we can join them
|
||||||
setLength(length + other.length);
|
setLength(subBlockLength + other.subBlockLength);
|
||||||
adapter.deleteSubBlock(other.record.getKey());
|
adapter.deleteSubBlock(other.record.getKey());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -96,10 +103,10 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock {
|
||||||
@Override
|
@Override
|
||||||
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
||||||
// convert from offset in block to offset in this sub block
|
// convert from offset in block to offset in this sub block
|
||||||
int offset = (int) (memBlockOffset - startingOffset);
|
int offset = (int) (memBlockOffset - subBlockOffset);
|
||||||
long newLength = length - offset;
|
long newLength = subBlockLength - offset;
|
||||||
length = offset;
|
subBlockLength = offset;
|
||||||
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length);
|
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength);
|
||||||
adapter.updateSubBlockRecord(record);
|
adapter.updateSubBlockRecord(record);
|
||||||
|
|
||||||
int fileBytesID = record.getIntValue(MemoryMapDBAdapter.SUB_SOURCE_ID_COL);
|
int fileBytesID = record.getIntValue(MemoryMapDBAdapter.SUB_SOURCE_ID_COL);
|
||||||
|
@ -128,9 +135,8 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock {
|
||||||
long size) {
|
long size) {
|
||||||
long sourceId = fileBytes.getId();
|
long sourceId = fileBytes.getId();
|
||||||
ByteSourceRange bsRange = new ByteSourceRange(block, start, size, sourceId,
|
ByteSourceRange bsRange = new ByteSourceRange(block, start, size, sourceId,
|
||||||
fileBytesOffset + memBlockOffset - startingOffset);
|
fileBytesOffset + memBlockOffset - subBlockOffset);
|
||||||
return new ByteSourceRangeList(bsRange);
|
return new ByteSourceRangeList(bsRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -631,7 +631,7 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
long startingOffset = 0;
|
long startingOffset = 0;
|
||||||
for (SubMemoryBlock subBlock : subBlocks) {
|
for (SubMemoryBlock subBlock : subBlocks) {
|
||||||
subBlock.setParentIdAndStartingOffset(id, startingOffset);
|
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);
|
size = Math.min(size, length - offset);
|
||||||
|
|
||||||
SubMemoryBlock subBlock = getSubBlock(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) {
|
if (subSize == size) {
|
||||||
return subBlock.getByteSourceRangeList(this, address, offset, size);
|
return subBlock.getByteSourceRangeList(this, address, offset, size);
|
||||||
}
|
}
|
||||||
|
@ -702,7 +702,7 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
long total = subSize;
|
long total = subSize;
|
||||||
while (total < size) {
|
while (total < size) {
|
||||||
subBlock = getSubBlock(offset + total);
|
subBlock = getSubBlock(offset + total);
|
||||||
subSize = Math.min(size - total, subBlock.length);
|
subSize = Math.min(size - total, subBlock.subBlockLength);
|
||||||
start = address.add(total);
|
start = address.add(total);
|
||||||
set.add(subBlock.getByteSourceRangeList(this, start, offset + total, subSize));
|
set.add(subBlock.getByteSourceRangeList(this, start, offset + total, subSize));
|
||||||
total += subSize;
|
total += subSize;
|
||||||
|
|
|
@ -40,7 +40,7 @@ class MemoryBlockSourceInfoDB implements MemoryBlockSourceInfo {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public long getLength() {
|
public long getLength() {
|
||||||
return subBlock.length;
|
return subBlock.subBlockLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +48,7 @@ class MemoryBlockSourceInfoDB implements MemoryBlockSourceInfo {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Address getMinAddress() {
|
public Address getMinAddress() {
|
||||||
return block.getStart().add(subBlock.startingOffset);
|
return block.getStart().add(subBlock.subBlockOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,7 +56,7 @@ class MemoryBlockSourceInfoDB implements MemoryBlockSourceInfo {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Address getMaxAddress() {
|
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) {
|
public long getFileBytesOffset(Address address) {
|
||||||
if (subBlock instanceof FileBytesSubMemoryBlock && contains(address)) {
|
if (subBlock instanceof FileBytesSubMemoryBlock && contains(address)) {
|
||||||
long blockOffset = address.subtract(getMinAddress());
|
long blockOffset = address.subtract(getMinAddress());
|
||||||
long subBlockOffset = blockOffset - subBlock.startingOffset;
|
long subBlockOffset = blockOffset - subBlock.subBlockOffset;
|
||||||
return ((FileBytesSubMemoryBlock) subBlock).getFileBytesOffset() + subBlockOffset;
|
return ((FileBytesSubMemoryBlock) subBlock).getFileBytesOffset() + subBlockOffset;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -249,7 +249,7 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
long startingOffset = 0;
|
long startingOffset = 0;
|
||||||
for (SubMemoryBlock subMemoryBlock : splitBlocks) {
|
for (SubMemoryBlock subMemoryBlock : splitBlocks) {
|
||||||
subMemoryBlock.setParentIdAndStartingOffset(key, startingOffset);
|
subMemoryBlock.setParentIdAndStartingOffset(key, startingOffset);
|
||||||
startingOffset += subMemoryBlock.length;
|
startingOffset += subMemoryBlock.subBlockLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
memBlockTable.putRecord(blockRecord);
|
memBlockTable.putRecord(blockRecord);
|
||||||
|
|
|
@ -30,14 +30,14 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||||
|
|
||||||
protected final MemoryMapDBAdapter adapter;
|
protected final MemoryMapDBAdapter adapter;
|
||||||
protected final Record record;
|
protected final Record record;
|
||||||
protected long length;
|
protected long subBlockLength;
|
||||||
protected long startingOffset;
|
protected long subBlockOffset;
|
||||||
|
|
||||||
protected SubMemoryBlock(MemoryMapDBAdapter adapter, Record record) {
|
protected SubMemoryBlock(MemoryMapDBAdapter adapter, Record record) {
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
this.record = record;
|
this.record = record;
|
||||||
this.startingOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL);
|
this.subBlockOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL);
|
||||||
this.length = record.getLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL);
|
this.subBlockLength = record.getLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +62,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||||
* @return the starting offset for this sub block.
|
* @return the starting offset for this sub block.
|
||||||
*/
|
*/
|
||||||
public final long getStartingOffset() {
|
public final long getStartingOffset() {
|
||||||
return startingOffset;
|
return subBlockOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +70,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||||
* @return the length of this sub block
|
* @return the length of this sub block
|
||||||
*/
|
*/
|
||||||
public final long getLength() {
|
public final long getLength() {
|
||||||
return length;
|
return subBlockLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +80,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||||
* @return true if the offset is valid for this block
|
* @return true if the offset is valid for this block
|
||||||
*/
|
*/
|
||||||
public final boolean contains(long memBlockOffset) {
|
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<SubMemoryBlock> {
|
||||||
* @throws IOException if a database error occurs
|
* @throws IOException if a database error occurs
|
||||||
*/
|
*/
|
||||||
protected void setLength(long length) throws IOException {
|
protected void setLength(long length) throws IOException {
|
||||||
this.length = length;
|
this.subBlockLength = length;
|
||||||
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length);
|
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length);
|
||||||
adapter.updateSubBlockRecord(record);
|
adapter.updateSubBlockRecord(record);
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||||
* @throws IOException if a database error occurs.
|
* @throws IOException if a database error occurs.
|
||||||
*/
|
*/
|
||||||
protected void setParentIdAndStartingOffset(long key, long startingOffset) throws IOException {
|
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_PARENT_ID_COL, key);
|
||||||
record.setLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL, startingOffset);
|
record.setLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL, startingOffset);
|
||||||
adapter.updateSubBlockRecord(record);
|
adapter.updateSubBlockRecord(record);
|
||||||
|
|
|
@ -28,7 +28,7 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock {
|
||||||
|
|
||||||
UninitializedSubMemoryBlock(MemoryMapDBAdapter adapter, Record record) {
|
UninitializedSubMemoryBlock(MemoryMapDBAdapter adapter, Record record) {
|
||||||
super(adapter, record);
|
super(adapter, record);
|
||||||
startingOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL);
|
subBlockOffset = record.getLongValue(MemoryMapDBAdapter.SUB_START_OFFSET_COL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,10 +38,10 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(long offset) throws MemoryAccessException {
|
public byte getByte(long offset) throws MemoryAccessException {
|
||||||
if (offset < startingOffset || offset >= startingOffset + length) {
|
if (offset < subBlockOffset || offset >= subBlockOffset + subBlockLength) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Offset " + offset + "is out of bounds. Should be in [" + startingOffset + "," +
|
"Offset " + offset + "is out of bounds. Should be in [" + subBlockOffset + "," +
|
||||||
(startingOffset + length - 1));
|
(subBlockOffset + subBlockLength - 1));
|
||||||
}
|
}
|
||||||
throw new MemoryAccessException("Attempted to read from uninitialized block");
|
throw new MemoryAccessException("Attempted to read from uninitialized block");
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock {
|
||||||
if (!(block instanceof UninitializedSubMemoryBlock)) {
|
if (!(block instanceof UninitializedSubMemoryBlock)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
setLength(length + block.length);
|
setLength(subBlockLength + block.subBlockLength);
|
||||||
adapter.deleteSubBlock(block.record.getKey());
|
adapter.deleteSubBlock(block.record.getKey());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -79,10 +79,10 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock {
|
||||||
@Override
|
@Override
|
||||||
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
protected SubMemoryBlock split(long memBlockOffset) throws IOException {
|
||||||
// convert from offset in block to offset in this sub block
|
// convert from offset in block to offset in this sub block
|
||||||
long offset = memBlockOffset - startingOffset;
|
long offset = memBlockOffset - subBlockOffset;
|
||||||
long newLength = length - offset;
|
long newLength = subBlockLength - offset;
|
||||||
length = offset;
|
subBlockLength = offset;
|
||||||
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, length);
|
record.setLongValue(MemoryMapDBAdapter.SUB_LENGTH_COL, subBlockLength);
|
||||||
adapter.updateSubBlockRecord(record);
|
adapter.updateSubBlockRecord(record);
|
||||||
|
|
||||||
Record newSubRecord = adapter.createSubBlockRecord(-1, 0, newLength,
|
Record newSubRecord = adapter.createSubBlockRecord(-1, 0, newLength,
|
||||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.program.database.mem;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.*;
|
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
|
@Test
|
||||||
public void testJoinFileBytes() throws Exception {
|
public void testJoinFileBytes() throws Exception {
|
||||||
FileBytes fileBytes = createFileBytes();
|
FileBytes fileBytes = createFileBytes();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue