GT-2845: Storing original program bytes in the program database.

This commit is contained in:
ghidravore 2019-05-06 12:44:51 -04:00 committed by Ryan Kurtz
parent d95fd43762
commit 0792417979
73 changed files with 7129 additions and 2575 deletions

View file

@ -0,0 +1,194 @@
/* ###
* 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.program.database.mem;
import static org.junit.Assert.*;
import java.util.Iterator;
import java.util.Set;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.program.model.address.*;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.mem.MemoryBlockStub;
public class ByteSourceRangeListTest extends AbstractGenericTest {
private AddressSpace space = new GenericAddressSpace("test", 64, AddressSpace.TYPE_RAM, 0);
private MemoryBlock block = new MemoryBlockStub();
@Test
public void testConstructor() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x10, 1, 0x50);
ByteSourceRangeList list1 = new ByteSourceRangeList(range1);
ByteSourceRangeList list2 = new ByteSourceRangeList();
list2.add(range1);
assertTrue(list1.equals(list2));
}
@Test
public void testAdd() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x10, 1, 0x50);
ByteSourceRange range2 = new ByteSourceRange(block, addr(0x100), 0x10, 2, 0x50);
ByteSourceRangeList list1 = new ByteSourceRangeList(range1);
ByteSourceRangeList list2 = new ByteSourceRangeList(range2);
list1.add(list2);
assertEquals(2, list1.getRangeCount());
assertEquals(range1, list1.get(0));
assertEquals(range2, list1.get(1));
}
@Test
public void testIsEmpty() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x10, 1, 0x50);
ByteSourceRangeList list1 = new ByteSourceRangeList();
assertTrue(list1.isEmpty());
list1.add(range1);
assertFalse(list1.isEmpty());
}
@Test
public void testAddNullRange() {
ByteSourceRange range = null;
ByteSourceRangeList list1 = new ByteSourceRangeList();
list1.add(range);
assertTrue(list1.isEmpty());
}
@Test
public void testIterator() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x10, 1, 0x50);
ByteSourceRange range2 = new ByteSourceRange(block, addr(0x100), 0x10, 2, 0x50);
ByteSourceRangeList list1 = new ByteSourceRangeList(range1);
list1.add(range2);
Iterator<ByteSourceRange> it = list1.iterator();
assertTrue(it.hasNext());
assertEquals(range1, it.next());
assertTrue(it.hasNext());
assertEquals(range2, it.next());
assertFalse(it.hasNext());
}
@Test
public void testIntersectSimple() {
ByteSourceRangeList list1 = new ByteSourceRangeList();
list1.add(new ByteSourceRange(block, addr(0), 0x100, 1, 0));
ByteSourceRangeList list2 = new ByteSourceRangeList();
list2.add(new ByteSourceRange(block, addr(0x100), 0x100, 1, 0x10));
// note that list1.intersect(list2) is not equal to list2.intersect(list1).
// The byte sources are the same but the corresponding real addresses are calling
// objects byte sources.
ByteSourceRangeList result = list1.intersect(list2);
assertEquals(1, result.getRangeCount());
ByteSourceRange range = result.get(0);
assertEquals(0xf0, range.getSize());
assertEquals(0x10, range.getOffset());
assertEquals(block, range.getMemoryBlock());
assertEquals(1, range.getSourceId());
assertEquals(addr(0x10), range.getStart());
assertEquals(addr(0xff), range.getEnd());
// now intersect from list2 perspective
result = list2.intersect(list1);
assertEquals(1, result.getRangeCount());
range = result.get(0);
assertEquals(0xf0, range.getSize());
assertEquals(0x10, range.getOffset());
assertEquals(block, range.getMemoryBlock());
assertEquals(1, range.getSourceId());
assertEquals(addr(0x100), range.getStart());
assertEquals(addr(0x1ef), range.getEnd());
}
@Test
public void testGetOverlappingBlocks() {
ByteSourceRange range = new ByteSourceRange(block, addr(0), 0x100, 1, 0x00);
MemoryBlock block1 = new MemoryBlockStub();
ByteSourceRange range1 = new ByteSourceRange(block1, addr(0x100), 0x100, 2, 0x00);
// create a byte source overlap with the first block
MemoryBlock block2 = new MemoryBlockStub();
ByteSourceRange range2 = new ByteSourceRange(block2, addr(0x200), 0x100, 1, 0x50);
ByteSourceRangeList list = new ByteSourceRangeList();
list.add(range);
list.add(range1);
list.add(range2);
Set<MemoryBlock> overlappingBlocks = list.getOverlappingBlocks();
assertEquals(2, overlappingBlocks.size());
assertTrue(overlappingBlocks.contains(block));
assertTrue(overlappingBlocks.contains(block2));
}
@Test
public void testGetOverlappingBlocksBlocksWhereBlocksAreAdjacentButDontOverlap() {
ByteSourceRange range = new ByteSourceRange(block, addr(0), 0x100, 1, 0x00);
MemoryBlock block1 = new MemoryBlockStub();
ByteSourceRange range1 = new ByteSourceRange(block1, addr(0x100), 0x100, 2, 0x00);
// create a byte source overlap with the first block
MemoryBlock block2 = new MemoryBlockStub();
ByteSourceRange range2 = new ByteSourceRange(block2, addr(0x200), 0x100, 1, 0x100);
ByteSourceRangeList list = new ByteSourceRangeList();
list.add(range);
list.add(range1);
list.add(range2);
Set<MemoryBlock> overlappingBlocks = list.getOverlappingBlocks();
assertEquals(0, overlappingBlocks.size());
}
@Test
public void testGetOverlappingBlocksBlocksWhereBlocksOverlapByExactlyOneByte() {
ByteSourceRange range = new ByteSourceRange(block, addr(0), 0x100, 1, 0x00);
MemoryBlock block1 = new MemoryBlockStub();
ByteSourceRange range1 = new ByteSourceRange(block1, addr(0x100), 0x100, 2, 0x00);
// create a byte source overlap with the first block
MemoryBlock block2 = new MemoryBlockStub();
ByteSourceRange range2 = new ByteSourceRange(block2, addr(0x200), 0x100, 1, 0xff);
ByteSourceRangeList list = new ByteSourceRangeList();
list.add(range);
list.add(range1);
list.add(range2);
Set<MemoryBlock> overlappingBlocks = list.getOverlappingBlocks();
assertEquals(2, overlappingBlocks.size());
assertTrue(overlappingBlocks.contains(block));
assertTrue(overlappingBlocks.contains(block2));
}
private Address addr(long value) {
return space.getAddress(value);
}
}

View file

@ -0,0 +1,119 @@
/* ###
* 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.program.database.mem;
import static org.junit.Assert.*;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.program.model.address.*;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.mem.MemoryBlockStub;
public class ByteSourceRangeTest extends AbstractGenericTest {
private AddressSpace space = new GenericAddressSpace("test", 64, AddressSpace.TYPE_RAM, 0);
private MemoryBlock block = new MemoryBlockStub();
@Test
public void testIntersectNotSameSource() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x10, 1, 0x50);
ByteSourceRange range2 = new ByteSourceRange(block, addr(0x100), 0x10, 2, 0x50);
assertNull(range1.intersect(range2));
}
@Test
public void testIntersectOneRangeSimpleOverlap() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x20, 1, 0x50);
ByteSourceRange range2 = new ByteSourceRange(block, addr(0x100), 0x20, 1, 0x60);
ByteSourceRange intersect = range1.intersect(range2);
assertNotNull(intersect);
assertEquals(addr(0x10), intersect.getStart());
assertEquals(addr(0x1f), intersect.getEnd());
assertEquals(0x10, intersect.getSize());
assertEquals(1, intersect.getSourceId());
assertEquals(0x60, intersect.getOffset());
intersect = range2.intersect(range1);
assertNotNull(intersect);
assertEquals(addr(0x100), intersect.getStart());
assertEquals(addr(0x10f), intersect.getEnd());
assertEquals(0x10, intersect.getSize());
assertEquals(1, intersect.getSourceId());
assertEquals(0x60, intersect.getOffset());
}
@Test
public void testIntersectOneRangeButsAgainsAnother() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x20, 1, 0x50);
ByteSourceRange range2 = new ByteSourceRange(block, addr(0x100), 0x20, 2, 0x70);
assertNull(range1.intersect(range2));
assertNull(range2.intersect(range1));
}
@Test
public void testIntersectOneRangeCompletelyInAnother() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x10, 1, 0x50);
ByteSourceRange range2 = new ByteSourceRange(block, addr(0x100), 0x30, 1, 0x40);
ByteSourceRange intersect = range1.intersect(range2);
assertNotNull(intersect);
assertEquals(addr(0), intersect.getStart());
assertEquals(addr(0xf), intersect.getEnd());
assertEquals(0x10, intersect.getSize());
assertEquals(1, intersect.getSourceId());
assertEquals(0x50, intersect.getOffset());
intersect = range2.intersect(range1);
assertNotNull(intersect);
assertEquals(addr(0x110), intersect.getStart());
assertEquals(addr(0x11f), intersect.getEnd());
assertEquals(0x10, intersect.getSize());
assertEquals(1, intersect.getSourceId());
assertEquals(0x50, intersect.getOffset());
}
@Test
public void testBitMappedIntersect() {
ByteSourceRange range1 = new ByteSourceRange(block, addr(0), 0x10, 1, 0x50);
ByteSourceRange range2 = new BitMappedByteSourceRange(block, addr(0x100), 1, 0x55, 2);
ByteSourceRange intersect = range1.intersect(range2);
assertNotNull(intersect);
assertEquals(addr(5), intersect.getStart());
assertEquals(addr(6), intersect.getEnd());
assertEquals(2, intersect.getSize());
assertEquals(1, intersect.getSourceId());
assertEquals(0x55, intersect.getOffset());
intersect = range2.intersect(range1);
assertNotNull(intersect);
assertEquals(addr(0x100), intersect.getStart());
assertEquals(addr(0x10f), intersect.getEnd());
assertEquals(2, intersect.getSize());
assertEquals(1, intersect.getSourceId());
assertEquals(0x55, intersect.getOffset());
}
private Address addr(long value) {
return space.getAddress(value);
}
}

View file

@ -0,0 +1,249 @@
/* ###
* 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.program.database.mem;
import static org.junit.Assert.*;
import java.io.*;
import java.util.List;
import org.junit.*;
import db.*;
import db.buffers.BufferFile;
import generic.jar.ResourceFile;
import generic.test.AbstractGenericTest;
import ghidra.framework.Application;
import ghidra.framework.store.db.PrivateDatabase;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.util.DefaultLanguageService;
import ghidra.util.task.TaskMonitor;
public class FileBytesTest extends AbstractGenericTest {
private static final int MAX_BUFFER_SIZE_FOR_TESTING = 200;
private Program program;
private Memory mem;
private int transactionID;
public FileBytesTest() {
super();
}
@Test
public void testStoreAndRetrieveFileBytes() throws IOException {
int dataSize = MAX_BUFFER_SIZE_FOR_TESTING / 2;
FileBytes fileBytes = createFileBytes("testFile", dataSize);
byte[] outBytes = new byte[200];
assertEquals("testFile", fileBytes.getFilename());
assertEquals(0L, fileBytes.getFileOffset());
assertEquals(dataSize, fileBytes.getSize());
int n = fileBytes.getOriginalBytes(0L, outBytes);
assertEquals(dataSize, n);
for (int i = 0; i < dataSize; i++) {
assertEquals("Byte[" + i + "]", i, outBytes[i]);
}
}
@Test
public void testRetrieveAfterSavingAndReopeningProgram() throws Exception {
int dataSize = MAX_BUFFER_SIZE_FOR_TESTING / 2;
FileBytes fileBytes = createFileBytes("testFile", dataSize);
byte[] outBytes = new byte[200];
saveAndRestoreProgram();
List<FileBytes> list = program.getMemory().getAllFileBytes();
fileBytes = list.get(0);
assertEquals("testFile", fileBytes.getFilename());
assertEquals(0L, fileBytes.getFileOffset());
assertEquals(dataSize, fileBytes.getSize());
int n = fileBytes.getOriginalBytes(0L, outBytes);
assertEquals(100, n);
for (int i = 0; i < dataSize; i++) {
assertEquals("Byte[" + i + "]", i, outBytes[i]);
}
}
@Test
public void testRequiresMultipleBuffers() throws Exception {
int dataSize = MAX_BUFFER_SIZE_FOR_TESTING + MAX_BUFFER_SIZE_FOR_TESTING / 2;
FileBytes fileBytes = createFileBytes("testFile", dataSize);
saveAndRestoreProgram();
byte[] outBytes = new byte[400];
List<FileBytes> list = program.getMemory().getAllFileBytes();
fileBytes = list.get(0);
assertEquals("testFile", fileBytes.getFilename());
assertEquals(0L, fileBytes.getFileOffset());
assertEquals(dataSize, fileBytes.getSize());
int n = fileBytes.getOriginalBytes(0L, outBytes);
assertEquals(dataSize, n);
for (int i = 0; i < dataSize; i++) {
assertEquals("Byte[" + i + "]", (byte) i, outBytes[i]);
}
DBBuffer[] buffers = (DBBuffer[]) getInstanceField("originalBuffers", fileBytes);
assertEquals(2, buffers.length);
assertEquals(MAX_BUFFER_SIZE_FOR_TESTING, buffers[0].length());
}
@Test
public void testCreateMultipleFileBytes() throws Exception {
createFileBytes("file1", 10);
createFileBytes("file2", 20);
createFileBytes("file3", 30);
saveAndRestoreProgram();
List<FileBytes> fileBytesList = mem.getAllFileBytes();
assertEquals(3, fileBytesList.size());
assertEquals("file1", fileBytesList.get(0).getFilename());
assertEquals(10, fileBytesList.get(0).getSize());
assertEquals("file2", fileBytesList.get(1).getFilename());
assertEquals(20, fileBytesList.get(1).getSize());
assertEquals("file3", fileBytesList.get(2).getFilename());
assertEquals(30, fileBytesList.get(2).getSize());
}
@Test
public void testDeleteFileBytesDescriptors() throws Exception {
createFileBytes("file1", 10);
createFileBytes("file2", 20);
createFileBytes("file3", 30);
saveAndRestoreProgram();
List<FileBytes> fileBytes = mem.getAllFileBytes();
mem.deleteFileBytes(fileBytes.get(1));
saveAndRestoreProgram();
List<FileBytes> fileBytesList = mem.getAllFileBytes();
assertEquals(2, fileBytesList.size());
assertEquals("file1", fileBytesList.get(0).getFilename());
assertEquals(10, fileBytesList.get(0).getSize());
assertEquals("file3", fileBytesList.get(1).getFilename());
assertEquals(30, fileBytesList.get(1).getSize());
}
@Test
public void testGetByte() throws Exception {
FileBytes fileBytes = createFileBytes("file1", 10);
assertEquals(5, fileBytes.getOriginalByte(5));
}
@Test
public void testGetLayeredByte() throws Exception {
FileBytes fileBytes = createFileBytes("file1", 10);
incrementFileBytes(fileBytes, 0, 10);
// check that the layered bytes are changed, but you can still get the originals
for (int i = 0; i < 10; i++) {
assertEquals(i, fileBytes.getOriginalByte(i));
assertEquals(i + 1, fileBytes.getModifiedByte(i));
}
}
private void incrementFileBytes(FileBytes fileBytes, int offset, int n) throws IOException {
for (int i = offset; i < offset + n; i++) {
fileBytes.putByte(i, (byte) (fileBytes.getModifiedByte(i) + 1));
}
}
@Test
public void testGetLayeredBytes() throws Exception {
FileBytes fileBytes = createFileBytes("file1", 10);
incrementFileBytes(fileBytes, 0, 10);
// check that the layered bytes are changed, but you can still get the originals
byte[] original = new byte[10];
byte[] modified = new byte[10];
fileBytes.getOriginalBytes(0, original);
fileBytes.getModifiedBytes(0, modified);
for (int i = 0; i < 10; i++) {
assertEquals(i, original[i]);
assertEquals(i + 1, modified[i]);
}
}
private FileBytes createFileBytes(String name, int size) throws IOException {
byte[] bytes = new byte[size];
for (int i = 0; i < size; i++) {
bytes[i] = (byte) i;
}
try (ByteArrayInputStream is = new ByteArrayInputStream(bytes)) {
return mem.createFileBytes(name, 0, size, is);
}
}
private void saveAndRestoreProgram() throws Exception {
program.endTransaction(transactionID, true);
PrivateDatabase privateDatabase = saveProgram(program);
program = restoreProgram(privateDatabase);
mem = program.getMemory();
transactionID = program.startTransaction("test");
}
private PrivateDatabase saveProgram(Program program) throws Exception {
File dir = createTempDirectory("program");
File dbDir = new File(dir, "program.db");
DBHandle dbh = ((ProgramDB) program).getDBHandle();
BufferFile bfile = PrivateDatabase.createDatabase(dbDir, null, dbh.getBufferSize());
dbh.saveAs(bfile, true, TaskMonitor.DUMMY);
return new PrivateDatabase(dbDir);
}
private Program restoreProgram(PrivateDatabase db) throws Exception {
DBHandle dbh = db.open(TaskMonitor.DUMMY);
return new ProgramDB(dbh, DBConstants.UPDATE, null, this);
}
@Before
public void setUp() throws Exception {
FileBytesAdapter.setMaxBufferSize(MAX_BUFFER_SIZE_FOR_TESTING);
Language language = getLanguage("Toy:BE:64:default");
CompilerSpec compilerSpec = language.getDefaultCompilerSpec();
program = new ProgramDB("Test", language, compilerSpec, this);
mem = program.getMemory();
transactionID = program.startTransaction("Test");
}
@After
public void tearDown() throws Exception {
program.endTransaction(transactionID, true);
program.release(this);
}
private Language getLanguage(String languageName) throws Exception {
ResourceFile ldefFile = Application.getModuleDataFile("Toy", "languages/toy.ldefs");
if (ldefFile != null) {
LanguageService languageService = DefaultLanguageService.getLanguageService(ldefFile);
Language language = languageService.getLanguage(new LanguageID(languageName));
return language;
}
throw new LanguageNotFoundException("Unsupported test language: " + languageName);
}
}

View file

@ -0,0 +1,857 @@
/* ###
* 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.program.database.mem;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import org.junit.*;
import db.DBConstants;
import db.DBHandle;
import generic.jar.ResourceFile;
import generic.test.AbstractGenericTest;
import ghidra.framework.Application;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.map.AddressMapDB;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.*;
import ghidra.program.model.mem.*;
import ghidra.program.util.DefaultLanguageService;
import ghidra.util.Lock;
import ghidra.util.task.TaskMonitor;
public class MemBlockDBTest extends AbstractGenericTest {
private static final long MAX_SUB_BLOCK_SIZE = 16;
private MemoryMapDB mem;
private long txID;
private DBHandle handle;
private AddressFactory addressFactory;
private ProgramDB program;
private int ptxID;
@Before
public void setUp() throws Exception {
Language language = getLanguage("Toy:BE:64:default");
CompilerSpec compilerSpec = language.getDefaultCompilerSpec();
program = new ProgramDB("Test", language, compilerSpec, this);
ptxID = program.startTransaction("test");
handle = new DBHandle();
txID = handle.startTransaction();
addressFactory = language.getAddressFactory();
AddressMapDB addrMap = (AddressMapDB) program.getAddressMap();
Lock lock = new Lock("Test");
int openMode = DBConstants.CREATE;
mem = new MemoryMapDB(handle, addrMap, openMode, true, lock);
MemoryMapDBAdapter adapter =
new MemoryMapDBAdapterV3(handle, mem, MAX_SUB_BLOCK_SIZE, true);
FileBytesAdapter fileBytesAdapter = new FileBytesAdapterV0(handle, mem, true);
mem.init(adapter, fileBytesAdapter);
mem.setProgram(program);
}
@After
public void tearDown() throws Exception {
program.endTransaction(ptxID, true);
handle.endTransaction(txID, true);
handle.close();
program.release(this);
}
@Test
public void testCreateInitializedBlock() throws Exception {
MemoryBlock block =
mem.createInitializedBlock("test", addr(0), 10, (byte) 1, TaskMonitor.DUMMY, false);
assertEquals(10, block.getSize());
assertEquals("test", block.getName());
assertEquals(addr(0), block.getStart());
assertEquals(addr(9), block.getEnd());
assertEquals(MemoryBlockType.DEFAULT, block.getType());
assertEquals(true, block.isInitialized());
assertEquals(false, block.isMapped());
assertNull(block.getComment());
assertNull(block.getSourceName());
assertEquals(MemoryBlock.READ, block.getPermissions());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo info = sourceInfos.get(0);
assertEquals(10, info.getLength());
assertEquals(addr(0), info.getMinAddress());
assertEquals(addr(9), info.getMaxAddress());
for (int i = 0; i < 10; i++) {
assertEquals(1, block.getByte(addr(i)));
}
}
@Test
public void testCreateUninitializedBlock() throws Exception {
MemoryBlock block = mem.createUninitializedBlock("test", addr(0), 10, false);
assertEquals(10, block.getSize());
assertEquals("test", block.getName());
assertEquals(addr(0), block.getStart());
assertEquals(addr(9), block.getEnd());
assertEquals(MemoryBlockType.DEFAULT, block.getType());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo info = sourceInfos.get(0);
assertEquals(10, info.getLength());
assertEquals(addr(0), info.getMinAddress());
assertEquals(addr(9), info.getMaxAddress());
try {
block.getByte(addr(0));
fail("expected exception trying to read bytes on unitialized block");
}
catch (MemoryAccessException e) {
// expected
}
}
@Test
public void testCreateUnitializedOverlayBlock() throws Exception {
MemoryBlock block = mem.createUninitializedBlock("test", addr(0), 10, true);
assertEquals(10, block.getSize());
assertEquals("test", block.getName());
assertNotEquals(addr(0), block.getStart()); // block should be in overlay space
assertEquals(0, block.getStart().getOffset());
assertEquals(9, block.getEnd().getOffset());
assertTrue(block.getStart().getAddressSpace().isOverlaySpace());
assertEquals(MemoryBlockType.OVERLAY, block.getType());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo info = sourceInfos.get(0);
assertEquals(10, info.getLength());
try {
block.getByte(block.getStart());
fail("expected exception trying to read bytes on unitialized block");
}
catch (MemoryAccessException e) {
// expected
}
}
@Test
public void testCreateInitializedOverlayBlock() throws Exception {
MemoryBlock block =
mem.createInitializedBlock("test", addr(0), 10, (byte) 1, TaskMonitor.DUMMY, true);
assertEquals(10, block.getSize());
assertEquals("test", block.getName());
assertNotEquals(addr(0), block.getStart()); // block should be in overlay space
assertEquals(0, block.getStart().getOffset());
assertEquals(9, block.getEnd().getOffset());
assertTrue(block.getStart().getAddressSpace().isOverlaySpace());
assertEquals(MemoryBlockType.OVERLAY, block.getType());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo info = sourceInfos.get(0);
assertEquals(10, info.getLength());
for (int i = 0; i < 10; i++) {
assertEquals(1, block.getByte(block.getStart().add(i)));
}
}
@Test
public void testCreateByteMappedBlock() throws Exception {
mem.createInitializedBlock("test1", addr(0), 50, (byte) 1, TaskMonitor.DUMMY, false);
mem.createUninitializedBlock("test2", addr(50), 50, false);
MemoryBlock block = mem.createByteMappedBlock("mapped", addr(1000), addr(40), 20);
assertEquals(20, block.getSize());
assertEquals("mapped", block.getName());
assertEquals(addr(1000), block.getStart());
assertEquals(addr(1019), block.getEnd());
assertEquals(MemoryBlockType.BYTE_MAPPED, block.getType());
assertEquals(false, block.isInitialized());
assertEquals(true, block.isMapped());
assertNull(block.getComment());
assertNull(block.getSourceName());
assertEquals(MemoryBlock.READ, block.getPermissions());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo info = sourceInfos.get(0);
assertEquals(20, info.getLength());
assertEquals(new AddressRangeImpl(addr(40), addr(59)), info.getMappedRange().get());
for (int i = 0; i < 10; i++) {
assertEquals(1, mem.getByte(block.getStart().add(i)));
}
try {
mem.getByte(block.getStart().add(10));
fail("expected exception trying to read bytes on mapped unitialized block");
}
catch (MemoryAccessException e) {
// expected
}
}
@Test
public void testCreateBitMappedBlock() throws Exception {
mem.createInitializedBlock("test1", addr(0), 50, (byte) 1, TaskMonitor.DUMMY, false);
mem.createUninitializedBlock("test2", addr(50), 50, false);
MemoryBlock block = mem.createBitMappedBlock("mapped", addr(1000), addr(49), 16);
assertEquals(16, block.getSize());
assertEquals("mapped", block.getName());
assertEquals(addr(1000), block.getStart());
assertEquals(addr(1015), block.getEnd());
assertEquals(MemoryBlockType.BIT_MAPPED, block.getType());
assertEquals(false, block.isInitialized());
assertEquals(true, block.isMapped());
assertNull(block.getComment());
assertNull(block.getSourceName());
assertEquals(MemoryBlock.READ, block.getPermissions());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo info = sourceInfos.get(0);
assertEquals(16, info.getLength());
assertEquals(new AddressRangeImpl(addr(49), addr(50)), info.getMappedRange().get());
assertEquals(1, mem.getByte(block.getStart()));
for (int i = 1; i < 8; i++) {
assertEquals(0, mem.getByte(block.getStart().add(i)));
}
try {
mem.getByte(block.getStart().add(8));
fail("expected exception trying to read bytes on mapped unitialized block");
}
catch (MemoryAccessException e) {
// expected
}
}
@Test
public void testCreateFileBytesBlock() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block = mem.createInitializedBlock("test", addr(100), fileBytes, 10, 50, false);
assertEquals(50, block.getSize());
assertEquals("test", block.getName());
assertEquals(addr(100), block.getStart());
assertEquals(addr(149), block.getEnd());
assertEquals(MemoryBlockType.DEFAULT, block.getType());
assertEquals(true, block.isInitialized());
assertEquals(false, block.isMapped());
assertNull(block.getComment());
assertNull(block.getSourceName());
assertEquals(MemoryBlock.READ, block.getPermissions());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo info = sourceInfos.get(0);
assertEquals(50, info.getLength());
assertEquals(addr(100), info.getMinAddress());
assertEquals(addr(149), info.getMaxAddress());
for (int i = 0; i < block.getSize(); i++) {
assertEquals(i + 10, block.getByte(addr(100 + i)));
}
}
@Test
public void testCreateFileBytesBlockOutSideRange() throws Exception {
byte[] bytes = new byte[256];
FileBytes fileBytes = mem.createFileBytes("test", 0, 100, new ByteArrayInputStream(bytes));
try {
mem.createInitializedBlock("test", addr(100), fileBytes, 10, 100, false);
fail(
"Expected create filebytes block to fail because the offset+blockLength > fileBytesLength");
}
catch (IndexOutOfBoundsException e) {
// expected
}
}
@Test
public void testInitializedBlockAcrossSubBlocks() throws Exception {
mem.createInitializedBlock("test", addr(0), 100, (byte) 1, TaskMonitor.DUMMY, false);
assertEquals(0x0101010101010101L, mem.getLong(addr(MAX_SUB_BLOCK_SIZE - 1)));
}
@Test
public void testInitializedBlockAcrossMutlitipleSubBlocks() throws Exception {
byte[] bytes = new byte[256];
for (int i = 0; i < 256; i++) {
bytes[i] = (byte) i;
}
mem.createInitializedBlock("test", addr(0), new ByteArrayInputStream(bytes), 256,
TaskMonitor.DUMMY, false);
byte[] b = new byte[100];
assertEquals(100, mem.getBytes(addr(10), b));
for (int i = 0; i < 100; i++) {
assertEquals(i + 10, b[i]);
}
}
@Test
public void testJoinFileBytes() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(10), 25, 10);
MemoryBlock block2 = createFileBytesBlock(fileBytes, addr(20), 35, 10);
MemoryBlock block = mem.join(block1, block2);
assertEquals(1, mem.getBlocks().length);
assertEquals(20, block.getSize());
assertEquals(addr(10), block.getStart());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo sourceInfo = sourceInfos.get(0);
assertEquals(fileBytes, sourceInfo.getFileBytes().get());
assertEquals(25, sourceInfo.getFileBytesOffset());
byte[] bytes = new byte[30];
assertEquals(20, block.getBytes(addr(10), bytes));
for (int i = 0; i < 20; i++) {
assertEquals(i + 25, bytes[i]);
}
}
@Test
public void testJoinNonConsecutiveFileBytes() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(10), 25, 10);
MemoryBlock block2 = createFileBytesBlock(fileBytes, addr(20), 70, 10);
MemoryBlock block = mem.join(block1, block2);
assertEquals(1, mem.getBlocks().length);
assertEquals(20, block.getSize());
assertEquals(addr(10), block.getStart());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(2, sourceInfos.size());
SourceInfo sourceInfo = sourceInfos.get(0);
assertEquals(fileBytes, sourceInfo.getFileBytes().get());
assertEquals(25, sourceInfo.getFileBytesOffset());
assertEquals(10, sourceInfo.getLength());
sourceInfo = sourceInfos.get(1);
assertEquals(fileBytes, sourceInfo.getFileBytes().get());
assertEquals(70, sourceInfo.getFileBytesOffset());
assertEquals(10, sourceInfo.getLength());
}
@Test
public void testJoinFileBytesBlockAndBufferBlock() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(10), 25, 10);
MemoryBlock block2 =
mem.createInitializedBlock("test", addr(20), 10, (byte) 1, TaskMonitor.DUMMY, false);
MemoryBlock block = mem.join(block1, block2);
assertEquals(1, mem.getBlocks().length);
assertEquals(20, block.getSize());
assertEquals(addr(10), block.getStart());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(2, sourceInfos.size());
SourceInfo sourceInfo = sourceInfos.get(0);
assertEquals(fileBytes, sourceInfo.getFileBytes().get());
assertEquals(25, sourceInfo.getFileBytesOffset());
assertEquals(10, sourceInfo.getLength());
SourceInfo sourceInfo2 = sourceInfos.get(1);
assertEquals(10, sourceInfo2.getLength());
}
@Test
public void testJoinBlocksFromDifferentFileBytes() throws Exception {
FileBytes fileBytes1 = createFileBytes();
FileBytes fileBytes2 = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes1, addr(10), 25, 10);
MemoryBlock block2 = createFileBytesBlock(fileBytes2, addr(20), 35, 10);
MemoryBlock block = mem.join(block1, block2);
assertEquals(1, mem.getBlocks().length);
assertEquals(20, block.getSize());
assertEquals(addr(10), block.getStart());
List<SourceInfo> sourceInfos = block.getSourceInfos();
assertEquals(2, sourceInfos.size());
SourceInfo sourceInfo = sourceInfos.get(0);
assertEquals(fileBytes1, sourceInfo.getFileBytes().get());
assertEquals(25, sourceInfo.getFileBytesOffset());
assertEquals(10, sourceInfo.getLength());
sourceInfo = sourceInfos.get(1);
assertEquals(fileBytes2, sourceInfo.getFileBytes().get());
assertEquals(35, sourceInfo.getFileBytesOffset());
assertEquals(10, sourceInfo.getLength());
}
@Test
public void testSplitFileBytes() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(10), 25, 50);
mem.split(block1, addr(30));
MemoryBlock[] blocks = mem.getBlocks();
assertEquals(2, blocks.length);
assertEquals(20, blocks[0].getSize());
assertEquals(30, blocks[1].getSize());
assertEquals(addr(10), blocks[0].getStart());
assertEquals(addr(30), blocks[1].getStart());
List<SourceInfo> sourceInfos = blocks[0].getSourceInfos();
assertEquals(1, sourceInfos.size());
SourceInfo sourceInfo = sourceInfos.get(0);
assertEquals(fileBytes, sourceInfo.getFileBytes().get());
assertEquals(25, sourceInfo.getFileBytesOffset());
sourceInfos = blocks[1].getSourceInfos();
assertEquals(1, sourceInfos.size());
sourceInfo = sourceInfos.get(0);
assertEquals(fileBytes, sourceInfo.getFileBytes().get());
assertEquals(45, sourceInfo.getFileBytesOffset());
}
@Test
public void testDeleteFileBytesBlock() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(10), 25, 50);
mem.removeBlock(block1, TaskMonitor.DUMMY);
assertEquals(0, mem.getBlocks().length);
}
@Test
public void testPutByteToFileBytesBlockAndGetBothChangedAndOriginalValues() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block = createFileBytesBlock(fileBytes, addr(0), 0, 50);
byte[] bytes = new byte[20];
block.getBytes(addr(0), bytes);
checkBytes(bytes, 0);
block.getBytes(addr(20), bytes);
checkBytes(bytes, 20);
block.putBytes(addr(0), bytes);
block.getBytes(addr(0), bytes);
checkBytes(bytes, 20);
fileBytes.getOriginalBytes(0, bytes);
checkBytes(bytes, 0);
}
@Test
public void testSplitAndJoinUnitializedBlock() throws Exception {
MemoryBlock block = mem.createUninitializedBlock("test", addr(0), 40, false);
mem.split(block, addr(10));
MemoryBlock[] blocks = mem.getBlocks();
assertEquals(2, blocks.length);
assertEquals(addr(0), blocks[0].getStart());
assertEquals(addr(10), blocks[1].getStart());
assertEquals(10, blocks[0].getSize());
assertEquals(30, blocks[1].getSize());
assertTrue(!blocks[0].isInitialized());
assertTrue(!blocks[1].isInitialized());
mem.join(blocks[0], blocks[1]);
blocks = mem.getBlocks();
assertEquals(1, blocks.length);
assertEquals(addr(0), blocks[0].getStart());
assertEquals(40, blocks[0].getSize());
List<SourceInfo> sourceInfos = blocks[0].getSourceInfos();
assertEquals(1, sourceInfos.size()); // make sure the sub blocks were merged
}
private void checkBytes(byte[] bytes, int startingValue) {
for (int i = 0; i < bytes.length; i++) {
assertEquals(startingValue + i, bytes[i]);
}
}
@Test
public void testPutBytesToFileBytesBlockAndGetBothChangedAndOriginalValues() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block = createFileBytesBlock(fileBytes, addr(0), 0, 50);
assertEquals(0, block.getByte(addr(0)));
block.putByte(addr(0), (byte) 55);
assertEquals(55, block.getByte(addr(0)));
assertEquals(0, fileBytes.getOriginalByte(0));
}
@Test
public void testSplitOnSubBlockBoundary() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(0), 0, 10);
MemoryBlock block2 = createFileBytesBlock(fileBytes, addr(10), 30, 10);
mem.join(block1, block2);
MemoryBlock[] blocks = mem.getBlocks();
assertEquals(1, blocks.length);
mem.split(blocks[0], addr(10));
blocks = mem.getBlocks();
assertEquals(2, blocks.length);
assertEquals(1, blocks[0].getSourceInfos().size());
assertEquals(1, blocks[1].getSourceInfos().size());
}
@Test
public void testByteMappedGetPutByte() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(0), 0, 10);
MemoryBlock mappedBlock = mem.createByteMappedBlock("mapped", addr(100), addr(0), 20);
assertEquals(5, mappedBlock.getByte(addr(105)));
assertEquals(5, block1.getByte(addr(5)));
mappedBlock.putByte(addr(105), (byte) 87);
assertEquals(87, block1.getByte(addr(5)));
}
@Test
public void testByteMappedGetPutBytes() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block1 = createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlock mappedBlock = mem.createByteMappedBlock("mapped", addr(100), addr(0), 20);
byte[] bytes = new byte[10];
mappedBlock.getBytes(addr(100), bytes);
checkBytes(bytes, 0);
mappedBlock.putBytes(addr(105), bytes);
block1.getBytes(addr(5), bytes);
checkBytes(bytes, 0);
}
@Test
public void testByteMappedJoin() throws Exception {
FileBytes fileBytes = createFileBytes();
createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlock mappedBlock1 = mem.createByteMappedBlock("mapped1", addr(100), addr(0), 10);
MemoryBlock mappedBlock2 = mem.createByteMappedBlock("mapped2", addr(110), addr(10), 10);
try {
mem.join(mappedBlock1, mappedBlock2);
fail("Expected exception when joining byte mapped blocks");
}
catch (IllegalArgumentException e) {
// expected
}
}
@Test
public void testByteMappedSplit() throws Exception {
FileBytes fileBytes = createFileBytes();
createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlock mappedBlock1 = mem.createByteMappedBlock("mapped1", addr(100), addr(0), 20);
mem.split(mappedBlock1, addr(110));
MemoryBlock[] blocks = mem.getBlocks();
assertEquals(3, blocks.length);
assertEquals(addr(110), blocks[2].getStart());
}
@Test
public void testBitMappedGetPutByte() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block = createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlock mappedBlock = mem.createBitMappedBlock("mapped1", addr(100), addr(0), 20);
assertEquals(0, mappedBlock.getByte(addr(100)));
assertEquals(0, mappedBlock.getByte(addr(101)));
assertEquals(0, mappedBlock.getByte(addr(114)));
assertEquals(1, mappedBlock.getByte(addr(108)));
assertEquals(0, mappedBlock.getByte(addr(116)));
mappedBlock.putByte(addr(100), (byte) 4);
assertEquals(1, block.getByte(addr(0)));
}
@Test
public void testBitMappedGetPutBytes() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlock block = createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlock mappedBlock = mem.createBitMappedBlock("mapped1", addr(100), addr(0), 50);
byte[] bytes = new byte[8];
mappedBlock.getBytes(addr(108), bytes);
assertEquals(1, bytes[0]);
for (int i = 1; i < 8; i++) {
assertEquals(0, bytes[i]);
}
for (int i = 0; i < 8; i++) {
bytes[i] = 1;
}
mappedBlock.putBytes(addr(100), bytes);
assertEquals(-1, block.getByte(addr(0)));
}
@Test
public void testBitMappedJoin() throws Exception {
FileBytes fileBytes = createFileBytes();
createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlock mappedBlock1 = mem.createBitMappedBlock("mapped1", addr(100), addr(0), 16);
MemoryBlock mappedBlock2 = mem.createBitMappedBlock("mapped2", addr(116), addr(2), 16);
try {
mem.join(mappedBlock1, mappedBlock2);
fail("Expected exception when joining bit mapped blocks");
}
catch (IllegalArgumentException e) {
// expected
}
}
@Test
public void testBitMappedSplit() throws Exception {
FileBytes fileBytes = createFileBytes();
createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlock mappedBlock1 = mem.createBitMappedBlock("mapped1", addr(100), addr(0), 16);
try {
mem.split(mappedBlock1, addr(108));
fail("Expected exception when joining bit mapped blocks");
}
catch (IllegalArgumentException e) {
// expected
}
}
@Test
public void testGetByteSourceSetForFileBytesBlock() throws Exception {
FileBytes fileBytes = createFileBytes();
MemoryBlockDB block = (MemoryBlockDB) createFileBytesBlock(fileBytes, addr(0), 10, 50);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(5), 10);
// we expect to get a single range ByteSourceSet pointing into the filebytes at offset
// 15 (10 because block was created at filebytes:10 and 5 because we start at the 5th byte
// in the block)
assertEquals(1, ranges.getRangeCount());
assertEquals(10, ranges.get(0).getSize());
assertEquals(5, ranges.get(0).getStart().getOffset());
assertEquals(14, ranges.get(0).getEnd().getOffset());
assertEquals(fileBytes.getId(), ranges.get(0).getSourceId());
assertEquals(15, ranges.get(0).getOffset());
}
@Test
public void testGetByteSourceSetForBufferBlock() throws Exception {
MemoryBlockDB block = (MemoryBlockDB) mem.createInitializedBlock("test", addr(0), 30,
(byte) 1, TaskMonitor.DUMMY, false);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(10), 10);
// We expect to get to ranges because we made the buffer size small (16) so when we
// created a 30 size block, it had to make two separate sub blocks each with its own
// DBBuffer. The first range should contain the first 6 bytes of the requested range
// and the second buffer should contain the last 4 bytes of request range.
assertEquals(2, ranges.getRangeCount()); // we have two sublocks so two distinct ranges
assertEquals(10, ranges.get(0).getSize() + ranges.get(1).getSize());
ByteSourceRange range = ranges.get(0);
assertEquals(10, range.getStart().getOffset());
assertEquals(15, range.getEnd().getOffset());
assertEquals(6, range.getSize());
assertEquals(10, range.getOffset());
range = ranges.get(1);
assertEquals(16, range.getStart().getOffset());
assertEquals(19, range.getEnd().getOffset());
assertEquals(4, range.getSize());
assertEquals(0, range.getOffset());
}
@Test
public void testGetByteSourceForUndefinedBlock() throws Exception {
MemoryBlockDB block =
(MemoryBlockDB) mem.createUninitializedBlock("test", addr(0), 30, false);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(10), 10);
// undefined blocks have no source bytes
assertTrue(ranges.isEmpty());
}
@Test
public void testGetByteSourceForByteMappedBlock() throws Exception {
mem.createInitializedBlock("test1", addr(0), 15, (byte) 1, TaskMonitor.DUMMY, false);
mem.createUninitializedBlock("test2", addr(15), 20, false);
mem.createInitializedBlock("test3", addr(35), 15, (byte) 1, TaskMonitor.DUMMY, false);
MemoryBlockDB block =
(MemoryBlockDB) mem.createByteMappedBlock("mapped", addr(1000), addr(5), 40);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(1005), 30);
// Uninitialized blocks don't contribute, so we should have 10 address (5 from first and last blocks each).
assertEquals(2, ranges.getRangeCount());
assertEquals(10, ranges.get(0).getSize() + ranges.get(1).getSize());
ByteSourceRange range = ranges.get(0);
assertEquals(addr(1005), range.getStart());
assertEquals(addr(1009), range.getEnd());
assertEquals(5, range.getSize());
assertEquals(10, range.getOffset());
range = ranges.get(1);
assertEquals(addr(1030), range.getStart());
assertEquals(addr(1034), range.getEnd());
assertEquals(5, range.getSize());
assertEquals(0, range.getOffset());
}
@Test
public void testGetByteSourceForBitMappedBlock() throws Exception {
FileBytes fileBytes = createFileBytes();
createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlockDB block =
(MemoryBlockDB) mem.createBitMappedBlock("mapped", addr(0x1000), addr(5), 0x14);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(0x1000), 0x14);
assertEquals(1, ranges.getRangeCount());
assertEquals(3, ranges.get(0).getSize());
ByteSourceRange range = ranges.get(0);
assertEquals(addr(0x1000), range.getStart());
assertEquals(addr(0x1017), range.getEnd());
assertEquals(3, range.getSize());
assertEquals(5, range.getOffset());
}
@Test
public void testGetByteSourceForBitMappedBlockOffcutStart() throws Exception {
FileBytes fileBytes = createFileBytes();
createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlockDB block =
(MemoryBlockDB) mem.createBitMappedBlock("mapped", addr(0x1000), addr(5), 0x14);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(0x1005), 8);
assertEquals(1, ranges.getRangeCount());
assertEquals(2, ranges.get(0).getSize());
ByteSourceRange range = ranges.get(0);
assertEquals(addr(0x1000), range.getStart());
assertEquals(addr(0x100f), range.getEnd());
assertEquals(2, range.getSize());
assertEquals(5, range.getOffset());
}
@Test
public void testGetByteSourceForBitMappedBlockOffcutStartNotAtStart() throws Exception {
FileBytes fileBytes = createFileBytes();
createFileBytesBlock(fileBytes, addr(0), 0, 50);
MemoryBlockDB block =
(MemoryBlockDB) mem.createBitMappedBlock("mapped", addr(0x1000), addr(5), 0x44);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(0x1015), 8);
assertEquals(1, ranges.getRangeCount());
assertEquals(2, ranges.get(0).getSize());
ByteSourceRange range = ranges.get(0);
assertEquals(addr(0x1010), range.getStart());
assertEquals(addr(0x101f), range.getEnd());
assertEquals(2, range.getSize());
assertEquals(7, range.getOffset());
}
@Test
public void testGetByteSourceForBitMappedBlock2() throws Exception {
mem.createInitializedBlock("test1", addr(0), 4, (byte) 1, TaskMonitor.DUMMY, false);
mem.createUninitializedBlock("test2", addr(0x4), 4, false);
mem.createInitializedBlock("test3", addr(0x8), 4, (byte) 1, TaskMonitor.DUMMY, false);
MemoryBlockDB block =
(MemoryBlockDB) mem.createBitMappedBlock("mapped", addr(0x1000), addr(2), 0x40);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(0x1008), 0x30);
assertEquals(2, ranges.getRangeCount());
ByteSourceRange range = ranges.get(0);
assertEquals(addr(0x1008), range.getStart());
assertEquals(addr(0x100f), range.getEnd());
assertEquals(1, range.getSize());
assertEquals(3, range.getOffset());
range = ranges.get(1);
assertEquals(addr(0x1030), range.getStart());
assertEquals(addr(0x1037), range.getEnd());
assertEquals(1, range.getSize());
assertEquals(0, range.getOffset());
}
@Test
public void testGetByteSourceForBitMappedBlock2Offcut() throws Exception {
mem.createInitializedBlock("test1", addr(0), 4, (byte) 1, TaskMonitor.DUMMY, false);
mem.createUninitializedBlock("test2", addr(0x4), 4, false);
mem.createInitializedBlock("test3", addr(0x8), 4, (byte) 1, TaskMonitor.DUMMY, false);
MemoryBlockDB block =
(MemoryBlockDB) mem.createBitMappedBlock("mapped", addr(0x1000), addr(2), 0x40);
ByteSourceRangeList ranges = block.getByteSourceRangeList(addr(0x1006), 0x34);
assertEquals(2, ranges.getRangeCount());
ByteSourceRange range = ranges.get(0);
assertEquals(addr(0x1000), range.getStart());
assertEquals(addr(0x100f), range.getEnd());
assertEquals(2, range.getSize());
assertEquals(2, range.getOffset());
range = ranges.get(1);
assertEquals(addr(0x1030), range.getStart());
assertEquals(addr(0x103f), range.getEnd());
assertEquals(2, range.getSize());
assertEquals(0, range.getOffset());
}
private MemoryBlock createFileBytesBlock(FileBytes fileBytes, Address addr, int offset,
int length) throws Exception {
return mem.createInitializedBlock("test" + addr.toString(), addr, fileBytes, offset, length,
false);
}
private FileBytes createFileBytes() throws IOException {
byte[] bytes = new byte[256];
for (int i = 0; i < 256; i++) {
bytes[i] = (byte) i;
}
FileBytes fileBytes = mem.createFileBytes("test", 0, 100, new ByteArrayInputStream(bytes));
return fileBytes;
}
private Address addr(long offset) {
return addressFactory.getDefaultAddressSpace().getAddress(offset);
}
private Language getLanguage(String languageName) throws Exception {
ResourceFile ldefFile = Application.getModuleDataFile("Toy", "languages/toy.ldefs");
if (ldefFile != null) {
LanguageService languageService = DefaultLanguageService.getLanguageService(ldefFile);
Language language = languageService.getLanguage(new LanguageID(languageName));
return language;
}
throw new LanguageNotFoundException("Unsupported test language: " + languageName);
}
}