GP-4528: Fix byte values in trace diff view

This commit is contained in:
Dan 2024-04-22 15:46:41 -04:00
parent 6389d9630c
commit e914b126db
5 changed files with 70 additions and 55 deletions

View file

@ -15,7 +15,7 @@
*/ */
package ghidra.trace.database.program; package ghidra.trace.database.program;
import static ghidra.lifecycle.Unfinished.*; import static ghidra.lifecycle.Unfinished.TODO;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.IOException; import java.io.IOException;
@ -42,8 +42,8 @@ public class DBTraceProgramViewListingTest extends AbstractGhidraHeadlessIntegra
ToyDBTraceBuilder b; ToyDBTraceBuilder b;
DBTraceProgramView view; DBTraceVariableSnapProgramView view;
DBTraceProgramViewListing listing; // TODO: Do I want to expose the internal types? DBTraceProgramViewListing listing;
DBTraceMemoryManager memory; DBTraceMemoryManager memory;
DBTraceCodeManager code; DBTraceCodeManager code;
@ -878,4 +878,22 @@ public class DBTraceProgramViewListingTest extends AbstractGhidraHeadlessIntegra
assertEquals(i4005, listing.getDefinedCodeUnitBefore(b.addr(0x4006))); assertEquals(i4005, listing.getDefinedCodeUnitBefore(b.addr(0x4006)));
assertEquals(d4000, listing.getDefinedCodeUnitBefore(b.addr(0x4005))); assertEquals(d4000, listing.getDefinedCodeUnitBefore(b.addr(0x4005)));
} }
@Test
public void testGetCodeUnitsInTwoViews() throws Throwable {
try (Transaction tx = b.startTransaction()) {
memory.putBytes(0, b.addr(0x00400000), b.buf(1, 2, 3, 4, 5, 6, 7, 8));
memory.putBytes(1, b.addr(0x00400000), b.buf(8, 7, 6, 5, 4, 3, 2, 1));
}
view.setSnap(1);
DBTraceProgramView view0 = b.trace.getFixedProgramView(0);
DBTraceProgramViewListing listing0 = view0.getListing();
CodeUnit cu0 = listing0.getCodeUnitAt(b.addr(0x00400000));
CodeUnit cu1 = listing.getCodeUnitAt(b.addr(0x00400000));
assertArrayEquals(b.arr(1), cu0.getBytes());
assertArrayEquals(b.arr(8), cu1.getBytes());
}
} }

View file

@ -23,7 +23,8 @@ import org.junit.*;
import db.Transaction; import db.Transaction;
import ghidra.program.database.ProgramBuilder; import ghidra.program.database.ProgramBuilder;
import ghidra.program.model.address.*; import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.LanguageNotFoundException; import ghidra.program.model.lang.LanguageNotFoundException;
import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.mem.MemoryBlock;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest; import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
@ -31,50 +32,47 @@ import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.database.memory.DBTraceMemoryManager; import ghidra.trace.database.memory.DBTraceMemoryManager;
import ghidra.trace.database.memory.DBTraceMemoryRegion; import ghidra.trace.database.memory.DBTraceMemoryRegion;
import ghidra.trace.model.memory.TraceMemoryFlag; import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.memory.TraceOverlappedRegionException;
import ghidra.util.exception.DuplicateNameException;
public class DBTraceProgramViewMemoryTest extends AbstractGhidraHeadlessIntegrationTest { public class DBTraceProgramViewMemoryTest extends AbstractGhidraHeadlessIntegrationTest {
ToyDBTraceBuilder b; ToyDBTraceBuilder tb;
DBTraceProgramView view; DBTraceVariableSnapProgramView view;
DBTraceProgramViewMemory vmem; DBTraceProgramViewMemory vmem;
DBTraceMemoryManager memory; DBTraceMemoryManager memory;
@Before @Before
public void setUpTraceProgramViewMemoryTest() throws LanguageNotFoundException, IOException { public void setUpTraceProgramViewMemoryTest() throws LanguageNotFoundException, IOException {
b = new ToyDBTraceBuilder("Testing", ProgramBuilder._TOY64_BE); tb = new ToyDBTraceBuilder("Testing", ProgramBuilder._TOY64_BE);
try (Transaction tx = b.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
b.trace.getTimeManager().createSnapshot("Created"); tb.trace.getTimeManager().createSnapshot("Created");
} }
memory = b.trace.getMemoryManager(); memory = tb.trace.getMemoryManager();
// NOTE: First snap has to exist first // NOTE: First snap has to exist first
view = b.trace.getProgramView(); view = tb.trace.getProgramView();
vmem = view.getMemory(); vmem = view.getMemory();
} }
@After @After
public void tearDownTraceProgramViewListingTest() { public void tearDownTraceProgramViewListingTest() {
if (b != null) { if (tb != null) {
b.close(); tb.close();
} }
} }
@Test @Test
public void testBlockInOverlay() throws DuplicateNameException, TraceOverlappedRegionException, public void testBlockInOverlay() throws Throwable {
AddressOutOfBoundsException {
AddressSpace os; AddressSpace os;
DBTraceMemoryRegion io; DBTraceMemoryRegion io;
try (Transaction tx = b.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
os = memory.createOverlayAddressSpace("test", os = memory.createOverlayAddressSpace("test",
b.trace.getBaseAddressFactory().getDefaultAddressSpace()); tb.trace.getBaseAddressFactory().getDefaultAddressSpace());
io = (DBTraceMemoryRegion) memory.createRegion(".io", 0, b.range(os, 0x1000, 0x1fff), io = (DBTraceMemoryRegion) memory.createRegion(".io", 0, tb.range(os, 0x1000, 0x1fff),
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE, TraceMemoryFlag.VOLATILE); TraceMemoryFlag.READ, TraceMemoryFlag.WRITE, TraceMemoryFlag.VOLATILE);
} }
AddressSet asSet = new AddressSet(vmem); AddressSet asSet = new AddressSet(vmem);
assertEquals(b.set(b.range(os, 0x1000, 0x1fff)), asSet); assertEquals(tb.set(tb.range(os, 0x1000, 0x1fff)), asSet);
MemoryBlock[] blocks = vmem.getBlocks(); MemoryBlock[] blocks = vmem.getBlocks();
assertEquals(1, blocks.length); assertEquals(1, blocks.length);
@ -82,7 +80,26 @@ public class DBTraceProgramViewMemoryTest extends AbstractGhidraHeadlessIntegrat
MemoryBlock blk = blocks[0]; MemoryBlock blk = blocks[0];
assertSame(blk, vmem.getRegionBlock(io)); assertSame(blk, vmem.getRegionBlock(io));
assertEquals(".io", blk.getName()); assertEquals(".io", blk.getName());
assertEquals(b.addr(os, 0x1000), blk.getStart()); assertEquals(tb.addr(os, 0x1000), blk.getStart());
assertEquals(b.addr(os, 0x1fff), blk.getEnd()); assertEquals(tb.addr(os, 0x1fff), blk.getEnd());
}
@Test
public void testBytesInTwoViews() throws Throwable {
try (Transaction tx = tb.startTransaction()) {
memory.putBytes(0, tb.addr(0x00400000), tb.buf(1, 2, 3, 4, 5, 6, 7, 8));
memory.putBytes(1, tb.addr(0x00400000), tb.buf(8, 7, 6, 5, 4, 3, 2, 1));
}
view.setSnap(1);
DBTraceProgramView view0 = tb.trace.getFixedProgramView(0);
byte[] actual = new byte[8];
view0.getMemory().getBytes(tb.addr(0x00400000), actual);
assertArrayEquals(tb.arr(1, 2, 3, 4, 5, 6, 7, 8), actual);
view.getMemory().getBytes(tb.addr(0x00400000), actual);
assertArrayEquals(tb.arr(8, 7, 6, 5, 4, 3, 2, 1), actual);
} }
} }

View file

@ -24,6 +24,8 @@ package ghidra.app.util.viewer.field;
import java.awt.Color; import java.awt.Color;
import java.math.BigInteger; import java.math.BigInteger;
import org.apache.commons.lang3.ArrayUtils;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
@ -35,8 +37,6 @@ import ghidra.framework.options.ToolOptions;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Structure; import ghidra.program.model.data.Structure;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.util.BytesFieldLocation; import ghidra.program.util.BytesFieldLocation;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
@ -168,45 +168,25 @@ public class BytesFieldFactory extends FieldFactory {
@Override @Override
public ListingField getField(ProxyObj<?> proxy, int varWidth) { public ListingField getField(ProxyObj<?> proxy, int varWidth) {
Object obj = proxy.getObject(); if (!enabled || !(proxy.getObject() instanceof CodeUnit cu)) {
if (!enabled || !(obj instanceof CodeUnit)) {
return null; return null;
} }
CodeUnit cu = (CodeUnit) obj;
int length;
// Instructions: use prototype length so we display all bytes for length-override case // Instructions: use prototype length so we display all bytes for length-override case
if (cu instanceof Instruction) { // Consider all parsed bytes even if the overlap the next instruction due to the
// Consider all parsed bytes even if the overlap the next instruction due to the // use of an instruction length-override.
// use of an instruction length-override. final int arrLength =
length = ((Instruction) cu).getParsedLength(); cu instanceof Instruction ins ? ins.getParsedLength() : Math.min(cu.getLength(), 100);
}
else {
length = Math.min(cu.getLength(), 100);
}
byte[] bytes = new byte[length]; byte[] bytes = new byte[arrLength];
Memory memory = cu.getProgram().getMemory(); final int length = cu.getBytes(bytes, 0);
try {
length = memory.getBytes(cu.getAddress(), bytes);
}
catch (MemoryAccessException e) {
return null;
}
if (length == 0) { if (length == 0) {
return null; return null;
} }
if ((cu instanceof Instruction) && reverseInstByteOrdering && !memory.isBigEndian()) { if ((cu instanceof Instruction) && reverseInstByteOrdering && !cu.isBigEndian()) {
int i = 0; ArrayUtils.reverse(bytes);
int j = length - 1;
while (j > i) {
byte b = bytes[i];
bytes[i++] = bytes[j];
bytes[j--] = b;
}
} }
int groupLength = length / byteGroupSize; int groupLength = length / byteGroupSize;

View file

@ -691,7 +691,7 @@ public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
}); });
waitForCondition(() -> actionNextDiff.isEnabled()); waitForCondition(() -> actionNextDiff.isEnabled());
flatDbg.goToDynamic(secTermminesData.getStart()); flatDbg.goToDynamic(secTermminesData.getStart());
// Because auto-strack is a little broken right now // Because auto-track is a little broken right now
Thread.sleep(500); Thread.sleep(500);
flatDbg.goToDynamic(secTermminesData.getStart()); flatDbg.goToDynamic(secTermminesData.getStart());

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After