mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-4528: Fix byte values in trace diff view
This commit is contained in:
parent
6389d9630c
commit
e914b126db
5 changed files with 70 additions and 55 deletions
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 |
Loading…
Add table
Add a link
Reference in a new issue