mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GP-2814_Dan_guestOpRefsInListing-REBASED-1--SQUASHED'
This commit is contained in:
commit
ebf0ef3a41
8 changed files with 201 additions and 25 deletions
|
@ -17,6 +17,9 @@ package ghidra.app.plugin.core.debug.gui.listing;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -29,10 +32,14 @@ import org.junit.experimental.categories.Category;
|
||||||
import docking.menu.ActionState;
|
import docking.menu.ActionState;
|
||||||
import docking.menu.MultiStateDockingAction;
|
import docking.menu.MultiStateDockingAction;
|
||||||
import docking.widgets.EventTrigger;
|
import docking.widgets.EventTrigger;
|
||||||
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
import generic.test.category.NightlyCategory;
|
import generic.test.category.NightlyCategory;
|
||||||
|
import generic.test.rule.Repeated;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
|
import ghidra.app.plugin.assembler.*;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||||
|
import ghidra.app.plugin.core.codebrowser.hover.ReferenceListingHoverPlugin;
|
||||||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
|
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
|
||||||
|
@ -44,6 +51,7 @@ import ghidra.app.plugin.core.debug.gui.console.DebuggerConsoleProvider.LogRow;
|
||||||
import ghidra.app.plugin.core.debug.gui.modules.DebuggerMissingModuleActionContext;
|
import ghidra.app.plugin.core.debug.gui.modules.DebuggerMissingModuleActionContext;
|
||||||
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils;
|
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
|
import ghidra.app.util.viewer.listingpanel.ListingPanel;
|
||||||
import ghidra.async.SwingExecutorService;
|
import ghidra.async.SwingExecutorService;
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
import ghidra.lifecycle.Unfinished;
|
import ghidra.lifecycle.Unfinished;
|
||||||
|
@ -51,12 +59,13 @@ import ghidra.plugin.importer.ImporterPlugin;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.lang.Register;
|
import ghidra.program.model.lang.Register;
|
||||||
import ghidra.program.model.lang.RegisterValue;
|
import ghidra.program.model.lang.RegisterValue;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.model.listing.Instruction;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.*;
|
||||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||||
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||||
import ghidra.trace.database.stack.DBTraceStackManager;
|
import ghidra.trace.database.stack.DBTraceStackManager;
|
||||||
import ghidra.trace.model.*;
|
import ghidra.trace.model.*;
|
||||||
|
import ghidra.trace.model.guest.TraceGuestPlatform;
|
||||||
import ghidra.trace.model.memory.*;
|
import ghidra.trace.model.memory.*;
|
||||||
import ghidra.trace.model.modules.TraceModule;
|
import ghidra.trace.model.modules.TraceModule;
|
||||||
import ghidra.trace.model.stack.TraceStack;
|
import ghidra.trace.model.stack.TraceStack;
|
||||||
|
@ -1615,4 +1624,117 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
||||||
// TODO: Test this independent of this particular action?
|
// TODO: Test this independent of this particular action?
|
||||||
assertNull(consolePlugin.getLogRow(ctx));
|
assertNull(consolePlugin.getLogRow(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Instruction placeGuestInstruction(int guestRangeLength) throws Throwable {
|
||||||
|
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||||
|
tb.trace.getMemoryManager()
|
||||||
|
.addRegion("Memory[.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||||
|
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
|
||||||
|
TraceGuestPlatform toy = tb.trace.getPlatformManager()
|
||||||
|
.addGuestPlatform(getToyBE64Language().getDefaultCompilerSpec());
|
||||||
|
Address hostEntry = tb.addr(0x00400000);
|
||||||
|
Address guestEntry = tb.addr(toy, 0x00000000);
|
||||||
|
toy.addMappedRange(hostEntry, guestEntry, guestRangeLength);
|
||||||
|
|
||||||
|
Assembler asm = Assemblers.getAssembler(toy.getLanguage());
|
||||||
|
AssemblyBuffer buf = new AssemblyBuffer(asm, guestEntry);
|
||||||
|
buf.assemble("call 0x123");
|
||||||
|
Instruction callInstr =
|
||||||
|
tb.addInstruction(0, hostEntry, toy, ByteBuffer.wrap(buf.getBytes()));
|
||||||
|
|
||||||
|
return callInstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGuestInstructionNavigation() throws Throwable {
|
||||||
|
createAndOpenTrace("DATA:BE:64:default");
|
||||||
|
|
||||||
|
Instruction callInstr = placeGuestInstruction(0x1000);
|
||||||
|
traceManager.activateTrace(tb.trace);
|
||||||
|
waitForSwing();
|
||||||
|
|
||||||
|
assertEquals("call 0x00400123", callInstr.toString());
|
||||||
|
|
||||||
|
listingPlugin.goTo(new OperandFieldLocation(tb.trace.getProgramView(), tb.addr(0x00400000),
|
||||||
|
null, null, null, 0, 0));
|
||||||
|
waitForPass(() -> assertEquals(tb.addr(0x00400000), listingPlugin.getCurrentAddress()));
|
||||||
|
|
||||||
|
click(listingPlugin, 2);
|
||||||
|
waitForPass(() -> assertEquals(tb.addr(0x00400123), listingPlugin.getCurrentAddress()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGuestInstructionNavigationUnmapped() throws Throwable {
|
||||||
|
createAndOpenTrace("DATA:BE:64:default");
|
||||||
|
|
||||||
|
Instruction callInstr = placeGuestInstruction(0x100);
|
||||||
|
traceManager.activateTrace(tb.trace);
|
||||||
|
waitForSwing();
|
||||||
|
|
||||||
|
assertEquals("call guest:ram:00000123", callInstr.toString());
|
||||||
|
|
||||||
|
listingPlugin.goTo(new OperandFieldLocation(tb.trace.getProgramView(), tb.addr(0x00400000),
|
||||||
|
null, null, null, 0, 0));
|
||||||
|
waitForPass(() -> assertEquals(tb.addr(0x00400000), listingPlugin.getCurrentAddress()));
|
||||||
|
|
||||||
|
click(listingPlugin, 2); // It should not move, nor crash
|
||||||
|
waitForPass(() -> assertEquals(tb.addr(0x00400000), listingPlugin.getCurrentAddress()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void triggerPopup(Point cursorPoint, Component eventSource) {
|
||||||
|
moveMouse(eventSource, cursorPoint.x, cursorPoint.y);
|
||||||
|
clickMouse(eventSource, MouseEvent.BUTTON1, cursorPoint.x, cursorPoint.y, 1, 0);
|
||||||
|
moveMouse(eventSource, cursorPoint.x + 5, cursorPoint.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGuestInstructionHover() throws Throwable {
|
||||||
|
ReferenceListingHoverPlugin hoverPlugin =
|
||||||
|
addPlugin(tool, ReferenceListingHoverPlugin.class);
|
||||||
|
ListingPanel listingPanel = listingProvider.getListingPanel();
|
||||||
|
FieldPanel fieldPanel = listingPanel.getFieldPanel();
|
||||||
|
|
||||||
|
createAndOpenTrace("DATA:BE:64:default");
|
||||||
|
|
||||||
|
Instruction callInstr = placeGuestInstruction(0x1000);
|
||||||
|
traceManager.activateTrace(tb.trace);
|
||||||
|
waitForSwing();
|
||||||
|
|
||||||
|
assertEquals("call 0x00400123", callInstr.toString());
|
||||||
|
|
||||||
|
listingPlugin.goTo(new OperandFieldLocation(tb.trace.getProgramView(), tb.addr(0x00400000),
|
||||||
|
null, null, null, 0, 0));
|
||||||
|
waitForPass(() -> assertEquals(tb.addr(0x00400000), listingPlugin.getCurrentAddress()));
|
||||||
|
Point p = fieldPanel.getCursorPoint();
|
||||||
|
triggerPopup(p, fieldPanel);
|
||||||
|
waitForPass(() -> assertTrue(listingPanel.isHoverShowing()));
|
||||||
|
|
||||||
|
ListingPanel popupPanel = hoverPlugin.getReferenceHoverService().getPanel();
|
||||||
|
assertEquals(tb.addr(0x00400123), popupPanel.getProgramLocation().getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGuestInstructionHoverUnmapped() throws Throwable {
|
||||||
|
addPlugin(tool, ReferenceListingHoverPlugin.class);
|
||||||
|
ListingPanel listingPanel = listingProvider.getListingPanel();
|
||||||
|
FieldPanel fieldPanel = listingPanel.getFieldPanel();
|
||||||
|
|
||||||
|
createAndOpenTrace("DATA:BE:64:default");
|
||||||
|
|
||||||
|
Instruction callInstr = placeGuestInstruction(0x100);
|
||||||
|
traceManager.activateTrace(tb.trace);
|
||||||
|
waitForSwing();
|
||||||
|
|
||||||
|
assertEquals("call guest:ram:00000123", callInstr.toString());
|
||||||
|
|
||||||
|
listingPlugin.goTo(new OperandFieldLocation(tb.trace.getProgramView(), tb.addr(0x00400000),
|
||||||
|
null, null, null, 0, 0));
|
||||||
|
waitForPass(() -> assertEquals(tb.addr(0x00400000), listingPlugin.getCurrentAddress()));
|
||||||
|
Point p = fieldPanel.getCursorPoint();
|
||||||
|
triggerPopup(p, fieldPanel);
|
||||||
|
listingPlugin.updateNow();
|
||||||
|
waitForSwing();
|
||||||
|
assertFalse(listingPanel.isHoverShowing());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.trace.database.listing;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import db.DBRecord;
|
import db.DBRecord;
|
||||||
|
@ -24,8 +25,7 @@ import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.listing.ContextChangeException;
|
import ghidra.program.model.listing.ContextChangeException;
|
||||||
import ghidra.program.model.listing.FlowOverride;
|
import ghidra.program.model.listing.FlowOverride;
|
||||||
import ghidra.program.model.mem.MemBuffer;
|
import ghidra.program.model.mem.*;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.trace.database.DBTrace;
|
import ghidra.trace.database.DBTrace;
|
||||||
import ghidra.trace.database.DBTraceUtils;
|
import ghidra.trace.database.DBTraceUtils;
|
||||||
|
@ -106,11 +106,32 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
||||||
@Override
|
@Override
|
||||||
public ParserContext getParserContext(Address instructionAddress)
|
public ParserContext getParserContext(Address instructionAddress)
|
||||||
throws UnknownContextException, MemoryAccessException {
|
throws UnknownContextException, MemoryAccessException {
|
||||||
// TODO: Does the given address need mapping?
|
|
||||||
return DBTraceInstruction.this.getParserContext(instructionAddress);
|
return DBTraceInstruction.this.getParserContext(instructionAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected class GuestMemBuffer implements MemBufferAdapter {
|
||||||
|
@Override
|
||||||
|
public Address getAddress() {
|
||||||
|
return platform.mapHostToGuest(getX1());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Memory getMemory() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBigEndian() {
|
||||||
|
return platform.getLanguage().isBigEndian();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytes(ByteBuffer buffer, int addressOffset) {
|
||||||
|
return DBTraceInstruction.this.getBytes(buffer, addressOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@DBAnnotatedField(column = PLATFORM_COLUMN_NAME)
|
@DBAnnotatedField(column = PLATFORM_COLUMN_NAME)
|
||||||
private int platformKey;
|
private int platformKey;
|
||||||
@DBAnnotatedField(column = PROTOTYPE_COLUMN_NAME)
|
@DBAnnotatedField(column = PROTOTYPE_COLUMN_NAME)
|
||||||
|
@ -126,6 +147,7 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
||||||
protected ParserContext parserContext;
|
protected ParserContext parserContext;
|
||||||
protected InternalTracePlatform platform;
|
protected InternalTracePlatform platform;
|
||||||
protected InstructionContext instructionContext;
|
protected InstructionContext instructionContext;
|
||||||
|
protected MemBuffer memBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an instruction unit
|
* Construct an instruction unit
|
||||||
|
@ -150,9 +172,11 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
if (platform.isHost()) {
|
if (platform.isHost()) {
|
||||||
instructionContext = this;
|
instructionContext = this;
|
||||||
|
memBuffer = this;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
instructionContext = new GuestInstructionContext();
|
instructionContext = new GuestInstructionContext();
|
||||||
|
memBuffer = new GuestMemBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,12 +732,13 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MemBuffer getMemBuffer() {
|
public MemBuffer getMemBuffer() {
|
||||||
return this;
|
return memBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ParserContext getParserContext() throws MemoryAccessException {
|
public ParserContext getParserContext() throws MemoryAccessException {
|
||||||
return parserContext == null ? parserContext = prototype.getParserContext(this, this)
|
return parserContext == null
|
||||||
|
? parserContext = prototype.getParserContext(getMemBuffer(), getProcessorContext())
|
||||||
: parserContext;
|
: parserContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,18 @@
|
||||||
package ghidra.trace.util;
|
package ghidra.trace.util;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.lang.*;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.listing.Instruction;
|
|
||||||
import ghidra.program.model.listing.InstructionPcodeOverride;
|
import ghidra.program.model.listing.InstructionPcodeOverride;
|
||||||
import ghidra.program.model.pcode.PcodeOp;
|
import ghidra.program.model.pcode.PcodeOp;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
import ghidra.program.model.symbol.RefType;
|
import ghidra.program.model.symbol.RefType;
|
||||||
|
import ghidra.trace.model.guest.TracePlatform;
|
||||||
|
import ghidra.trace.model.listing.TraceInstruction;
|
||||||
|
|
||||||
public interface InstructionAdapterFromPrototype extends Instruction {
|
public interface InstructionAdapterFromPrototype extends TraceInstruction {
|
||||||
default String getFullString() {
|
default String getFullString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(getMnemonicString());
|
sb.append(getMnemonicString());
|
||||||
|
@ -68,7 +70,7 @@ public interface InstructionAdapterFromPrototype extends Instruction {
|
||||||
InstructionContext context = getInstructionContext();
|
InstructionContext context = getInstructionContext();
|
||||||
int opType = prototype.getOpType(opIndex, context);
|
int opType = prototype.getOpType(opIndex, context);
|
||||||
if (OperandType.isAddress(opType)) {
|
if (OperandType.isAddress(opType)) {
|
||||||
return prototype.getAddress(opIndex, context);
|
return getPlatform().mapGuestToHost(prototype.getAddress(opIndex, context));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -106,11 +108,13 @@ public interface InstructionAdapterFromPrototype extends Instruction {
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (Object opElem : opList) {
|
for (Object opElem : opList) {
|
||||||
if (opElem instanceof Address) {
|
if (opElem instanceof Address opAddr) {
|
||||||
Address opAddr = (Address) opElem;
|
|
||||||
sb.append("0x");
|
sb.append("0x");
|
||||||
sb.append(opAddr.toString(false));
|
sb.append(opAddr.toString(false));
|
||||||
}
|
}
|
||||||
|
else if (opElem == null) {
|
||||||
|
sb.append("<null>");
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
sb.append(opElem.toString());
|
sb.append(opElem.toString());
|
||||||
}
|
}
|
||||||
|
@ -120,7 +124,23 @@ public interface InstructionAdapterFromPrototype extends Instruction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<Object> getDefaultOperandRepresentationList(int opIndex) {
|
default List<Object> getDefaultOperandRepresentationList(int opIndex) {
|
||||||
return getPrototype().getOpRepresentationList(opIndex, getInstructionContext());
|
// TODO: Cache this in the instruction?
|
||||||
|
List<Object> list =
|
||||||
|
getPrototype().getOpRepresentationList(opIndex, getInstructionContext());
|
||||||
|
TracePlatform platform = getPlatform();
|
||||||
|
if (platform.isHost()) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
return list.stream().map(obj -> {
|
||||||
|
if (obj instanceof Address addr) {
|
||||||
|
Address hostAddr = platform.mapGuestToHost(addr);
|
||||||
|
if (hostAddr == null) {
|
||||||
|
return "guest:" + addr.toString(true);
|
||||||
|
}
|
||||||
|
return hostAddr;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -41,7 +41,7 @@ import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
public class ReferenceListingHoverPlugin extends Plugin {
|
public class ReferenceListingHoverPlugin extends Plugin {
|
||||||
|
|
||||||
private ReferenceListingHover referenceHoverService;
|
private final ReferenceListingHover referenceHoverService;
|
||||||
|
|
||||||
public ReferenceListingHoverPlugin(PluginTool tool) {
|
public ReferenceListingHoverPlugin(PluginTool tool) {
|
||||||
super(tool);
|
super(tool);
|
||||||
|
@ -66,4 +66,9 @@ public class ReferenceListingHoverPlugin extends Plugin {
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
referenceHoverService.dispose();
|
referenceHoverService.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* testing */
|
||||||
|
public ReferenceListingHover getReferenceHoverService() {
|
||||||
|
return referenceHoverService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import ghidra.GhidraOptions;
|
||||||
import ghidra.app.plugin.core.hover.AbstractScalarOperandHover;
|
import ghidra.app.plugin.core.hover.AbstractScalarOperandHover;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.lang.InstructionPrototype;
|
|
||||||
import ghidra.program.model.listing.Instruction;
|
import ghidra.program.model.listing.Instruction;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
import ghidra.program.model.scalar.Scalar;
|
||||||
|
@ -96,9 +95,7 @@ public class ScalarOperandListingHover extends AbstractScalarOperandHover
|
||||||
return operands[0];
|
return operands[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
InstructionPrototype prototype = instruction.getPrototype();
|
List<Object> list = instruction.getDefaultOperandRepresentationList(opIndex);
|
||||||
List<Object> list =
|
|
||||||
prototype.getOpRepresentationList(opIndex, instruction.getInstructionContext());
|
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,16 @@ public abstract class AbstractReferenceHover extends AbstractConfigurableHover {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* testing */
|
||||||
|
public ListingPanel getPanel() {
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* testing */
|
||||||
|
public JToolTip getToolTip() {
|
||||||
|
return toolTip;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
|
@ -21,7 +21,6 @@ import ghidra.app.util.NamespaceUtils;
|
||||||
import ghidra.app.util.viewer.field.CommentUtils;
|
import ghidra.app.util.viewer.field.CommentUtils;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.lang.InstructionPrototype;
|
|
||||||
import ghidra.program.model.lang.Register;
|
import ghidra.program.model.lang.Register;
|
||||||
import ghidra.program.model.listing.CodeUnitFormatOptions.ShowBlockName;
|
import ghidra.program.model.listing.CodeUnitFormatOptions.ShowBlockName;
|
||||||
import ghidra.program.model.listing.CodeUnitFormatOptions.ShowNamespace;
|
import ghidra.program.model.listing.CodeUnitFormatOptions.ShowNamespace;
|
||||||
|
@ -212,7 +211,6 @@ public class CodeUnitFormat {
|
||||||
|
|
||||||
Program program = cu.getProgram();
|
Program program = cu.getProgram();
|
||||||
Instruction instr = (Instruction) cu;
|
Instruction instr = (Instruction) cu;
|
||||||
InstructionPrototype proto = instr.getPrototype();
|
|
||||||
|
|
||||||
if (!program.getLanguage().supportsPcode()) {
|
if (!program.getLanguage().supportsPcode()) {
|
||||||
// Formatted mark-up only supported for languages which support PCode
|
// Formatted mark-up only supported for languages which support PCode
|
||||||
|
@ -220,8 +218,7 @@ public class CodeUnitFormat {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get raw representation list and map of registers contained within it
|
// Get raw representation list and map of registers contained within it
|
||||||
ArrayList<Object> representationList =
|
List<Object> representationList = instr.getDefaultOperandRepresentationList(opIndex);
|
||||||
proto.getOpRepresentationList(opIndex, instr.getInstructionContext());
|
|
||||||
if (representationList == null) {
|
if (representationList == null) {
|
||||||
return new OperandRepresentationList("<BAD-Instruction>");
|
return new OperandRepresentationList("<BAD-Instruction>");
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import docking.DialogComponentProvider;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.fieldpanel.FieldPanel;
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
import ghidra.GhidraTestApplicationLayout;
|
import ghidra.GhidraTestApplicationLayout;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.AbstractCodeBrowserPlugin;
|
||||||
import ghidra.framework.ApplicationConfiguration;
|
import ghidra.framework.ApplicationConfiguration;
|
||||||
import ghidra.framework.GhidraApplicationConfiguration;
|
import ghidra.framework.GhidraApplicationConfiguration;
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
|
@ -192,11 +192,11 @@ public abstract class AbstractGhidraHeadedIntegrationTest
|
||||||
* @param codeBrowser the CodeBrowserPlugin
|
* @param codeBrowser the CodeBrowserPlugin
|
||||||
* @param clickCount the click count
|
* @param clickCount the click count
|
||||||
*/
|
*/
|
||||||
public void click(CodeBrowserPlugin codeBrowser, int clickCount) {
|
public void click(AbstractCodeBrowserPlugin<?> codeBrowser, int clickCount) {
|
||||||
click(codeBrowser, clickCount, true);
|
click(codeBrowser, clickCount, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void click(CodeBrowserPlugin codeBrowser, int clickCount, boolean wait) {
|
public void click(AbstractCodeBrowserPlugin<?> codeBrowser, int clickCount, boolean wait) {
|
||||||
|
|
||||||
// make sure that the code browser is ready to go--sometimes it is not, due to timing
|
// make sure that the code browser is ready to go--sometimes it is not, due to timing
|
||||||
// during the testing process, like when the tool is first loaded.
|
// during the testing process, like when the tool is first loaded.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue