Merge remote-tracking branch 'origin/GP-3405_Dan_syncDynamicViews--SQUASHED'

This commit is contained in:
Ryan Kurtz 2025-04-11 12:55:14 -04:00
commit 0ef0447601
19 changed files with 549 additions and 322 deletions

View file

@ -0,0 +1,38 @@
/* ###
* 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.app.plugin.core.debug.event;
import java.util.Objects;
import ghidra.app.events.AbstractHighlightPluginEvent;
import ghidra.program.util.ProgramSelection;
import ghidra.trace.model.program.TraceProgramView;
public class TraceHighlightPluginEvent extends AbstractHighlightPluginEvent {
public static final String NAME = "TraceHighlight";
private final TraceProgramView view;
public TraceHighlightPluginEvent(String src, ProgramSelection highlight,
TraceProgramView view) {
super(src, NAME, highlight, view);
this.view = Objects.requireNonNull(view);
}
public TraceProgramView getTraceProgramView() {
return view;
}
}

View file

@ -15,34 +15,21 @@
*/ */
package ghidra.app.plugin.core.debug.event; package ghidra.app.plugin.core.debug.event;
import java.util.Objects; import ghidra.app.events.AbstractLocationPluginEvent;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.program.TraceProgramView; import ghidra.trace.model.program.TraceProgramView;
public class TraceLocationPluginEvent extends PluginEvent { public class TraceLocationPluginEvent extends AbstractLocationPluginEvent {
public static final String NAME = "TraceLocation"; public static final String NAME = "TraceLocation";
private final ProgramLocation loc;
private final TraceProgramView view; private final TraceProgramView view;
public TraceLocationPluginEvent(String src, ProgramLocation loc) { public TraceLocationPluginEvent(String src, ProgramLocation loc) {
super(src, NAME); super(src, NAME, loc, loc.getProgram());
this.loc = Objects.requireNonNull(loc);
this.view = (TraceProgramView) loc.getProgram(); this.view = (TraceProgramView) loc.getProgram();
} }
public ProgramLocation getLocation() {
return loc;
}
public TraceProgramView getTraceProgramView() { public TraceProgramView getTraceProgramView() {
return view; return view;
} }
@Override
protected String getDetails() {
return loc.getClass() + " addr==> " + loc.getAddress();
}
} }

View file

@ -17,33 +17,22 @@ package ghidra.app.plugin.core.debug.event;
import java.util.Objects; import java.util.Objects;
import ghidra.framework.plugintool.PluginEvent; import ghidra.app.events.AbstractSelectionPluginEvent;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.trace.model.program.TraceProgramView; import ghidra.trace.model.program.TraceProgramView;
public class TraceSelectionPluginEvent extends PluginEvent { public class TraceSelectionPluginEvent extends AbstractSelectionPluginEvent {
public static final String NAME = "TraceSelection"; public static final String NAME = "TraceSelection";
private ProgramSelection selection; private final TraceProgramView view;
private TraceProgramView view;
public TraceSelectionPluginEvent(String src, ProgramSelection sel, TraceProgramView view) { public TraceSelectionPluginEvent(String src, ProgramSelection selection,
super(src, NAME); TraceProgramView view) {
super(src, NAME, selection, view);
this.selection = Objects.requireNonNull(sel);
this.view = Objects.requireNonNull(view); this.view = Objects.requireNonNull(view);
} }
public ProgramSelection getSelection() {
return selection;
}
public TraceProgramView getTraceProgramView() { public TraceProgramView getTraceProgramView() {
return view; return view;
} }
@Override
protected String getDetails() {
return getClass() + " ==> " + selection;
}
} }

View file

@ -0,0 +1,34 @@
/* ###
* 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.app.plugin.core.debug.event;
import ghidra.debug.api.action.LocationTrackingSpec;
import ghidra.framework.plugintool.PluginEvent;
public class TrackingChangedPluginEvent extends PluginEvent {
public static final String NAME = "TrackingChanged";
private final LocationTrackingSpec spec;
public TrackingChangedPluginEvent(String sourceName, LocationTrackingSpec spec) {
super(sourceName, NAME);
this.spec = spec;
}
public LocationTrackingSpec getLocationTrackingSpec() {
return spec;
}
}

View file

@ -62,7 +62,6 @@ import utilities.util.SuppressableCallback.Suppression;
packageName = DebuggerPluginPackage.NAME, packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED, status = PluginStatus.RELEASED,
eventsConsumed = { eventsConsumed = {
// ProgramHighlightPluginEvent.class, // TODO: Later or remove
ProgramOpenedPluginEvent.class, // For auto-open log cleanup ProgramOpenedPluginEvent.class, // For auto-open log cleanup
ProgramClosedPluginEvent.class, // For marker set cleanup ProgramClosedPluginEvent.class, // For marker set cleanup
ProgramActivatedPluginEvent.class, // To track the static program for sync ProgramActivatedPluginEvent.class, // To track the static program for sync
@ -70,19 +69,25 @@ import utilities.util.SuppressableCallback.Suppression;
ProgramSelectionPluginEvent.class, // For static listing sync ProgramSelectionPluginEvent.class, // For static listing sync
TraceActivatedPluginEvent.class, // Trace/thread activation and register tracking TraceActivatedPluginEvent.class, // Trace/thread activation and register tracking
TraceClosedPluginEvent.class, TraceClosedPluginEvent.class,
TraceLocationPluginEvent.class,
TraceSelectionPluginEvent.class,
TraceHighlightPluginEvent.class,
TrackingChangedPluginEvent.class,
}, },
eventsProduced = { eventsProduced = {
ProgramLocationPluginEvent.class, ProgramLocationPluginEvent.class,
ProgramSelectionPluginEvent.class, ProgramSelectionPluginEvent.class,
TraceLocationPluginEvent.class, TraceLocationPluginEvent.class,
TraceSelectionPluginEvent.class TraceSelectionPluginEvent.class,
TraceHighlightPluginEvent.class,
TrackingChangedPluginEvent.class,
}, },
servicesRequired = { servicesRequired = {
DebuggerStaticMappingService.class, // For static listing sync. TODO: Optional? DebuggerStaticMappingService.class, // For static listing sync. TODO: Optional?
DebuggerEmulationService.class, // TODO: Optional? DebuggerEmulationService.class, // TODO: Optional?
ProgramManager.class, // For static listing sync ProgramManager.class, // For static listing sync
ClipboardService.class, ClipboardService.class,
MarkerService.class // TODO: Make optional? MarkerService.class, // TODO: Make optional?
}, },
servicesProvided = { servicesProvided = {
DebuggerListingService.class, DebuggerListingService.class,
@ -208,11 +213,16 @@ public class DebuggerListingPlugin extends AbstractCodeBrowserPlugin<DebuggerLis
public void locationChanged(CodeViewerProvider provider, ProgramLocation location) { public void locationChanged(CodeViewerProvider provider, ProgramLocation location) {
// TODO: Fix cursor? // TODO: Fix cursor?
// Do not fire ProgramLocationPluginEvent. // Do not fire ProgramLocationPluginEvent.
if (provider == connectedProvider) {
firePluginEvent(new TraceLocationPluginEvent(getName(), location)); firePluginEvent(new TraceLocationPluginEvent(getName(), location));
} }
}
@Override @Override
public void selectionChanged(CodeViewerProvider provider, ProgramSelection selection) { public void selectionChanged(CodeViewerProvider provider, ProgramSelection selection) {
if (provider != connectedProvider) {
return;
}
TraceProgramView view = current.getView(); TraceProgramView view = current.getView();
if (view == null) { if (view == null) {
return; return;
@ -222,9 +232,16 @@ public class DebuggerListingPlugin extends AbstractCodeBrowserPlugin<DebuggerLis
} }
@Override @Override
public void highlightChanged(CodeViewerProvider codeViewerProvider, public void highlightChanged(CodeViewerProvider provider, ProgramSelection highlight) {
ProgramSelection highlight) { if (provider != connectedProvider) {
// TODO Nothing, yet return;
}
TraceProgramView view = current.getView();
if (view == null) {
return;
}
// Do not fire ProgramHighlightPluginEvent
firePluginEvent(new TraceHighlightPluginEvent(getName(), highlight, view));
} }
protected boolean heedLocationEvent(PluginEvent ev) { protected boolean heedLocationEvent(PluginEvent ev) {
@ -259,40 +276,51 @@ public class DebuggerListingPlugin extends AbstractCodeBrowserPlugin<DebuggerLis
@Override @Override
public void processEvent(PluginEvent event) { public void processEvent(PluginEvent event) {
if (event instanceof ProgramLocationPluginEvent ev) { switch (event) {
cbProgramLocationEvents.invoke(() -> { case ProgramLocationPluginEvent ev -> cbProgramLocationEvents.invoke(() -> {
if (heedLocationEvent(ev)) { if (heedLocationEvent(ev)) {
connectedProvider.staticProgramLocationChanged(ev.getLocation()); connectedProvider.staticProgramLocationChanged(ev.getLocation());
} }
}); });
} case ProgramSelectionPluginEvent ev -> cbProgramSelectionEvents.invoke(() -> {
if (event instanceof ProgramSelectionPluginEvent ev) {
cbProgramSelectionEvents.invoke(() -> {
if (heedSelectionEvent(ev)) { if (heedSelectionEvent(ev)) {
connectedProvider.staticProgramSelectionChanged(ev.getProgram(), connectedProvider.staticProgramSelectionChanged(ev.getProgram(),
ev.getSelection()); ev.getSelection());
} }
}); });
} case ProgramOpenedPluginEvent ev -> allProviders(p -> p.programOpened(ev.getProgram()));
if (event instanceof ProgramOpenedPluginEvent ev) { case ProgramClosedPluginEvent ev -> allProviders(p -> p.programClosed(ev.getProgram()));
allProviders(p -> p.programOpened(ev.getProgram())); case ProgramActivatedPluginEvent ev -> allProviders(
} p -> p.staticProgramActivated(ev.getActiveProgram()));
if (event instanceof ProgramClosedPluginEvent ev) { case TraceActivatedPluginEvent ev -> {
allProviders(p -> p.programClosed(ev.getProgram()));
}
if (event instanceof ProgramActivatedPluginEvent ev) {
allProviders(p -> p.staticProgramActivated(ev.getActiveProgram()));
}
if (event instanceof TraceActivatedPluginEvent ev) {
current = ev.getActiveCoordinates(); current = ev.getActiveCoordinates();
allProviders(p -> p.coordinatesActivated(current)); allProviders(p -> p.coordinatesActivated(current));
} }
if (event instanceof TraceClosedPluginEvent ev) { case TraceClosedPluginEvent ev -> {
if (current.getTrace() == ev.getTrace()) { if (current.getTrace() == ev.getTrace()) {
current = DebuggerCoordinates.NOWHERE; current = DebuggerCoordinates.NOWHERE;
} }
allProviders(p -> p.traceClosed(ev.getTrace())); allProviders(p -> p.traceClosed(ev.getTrace()));
} }
case TraceLocationPluginEvent ev -> {
// For those comparing to CodeBrowserPlugin, there is no "viewManager" here.
connectedProvider.goTo(ev.getTraceProgramView(), ev.getLocation());
}
case TraceSelectionPluginEvent ev -> {
if (ev.getTraceProgramView() == current.getView()) {
connectedProvider.setSelection(ev.getSelection());
}
}
case TraceHighlightPluginEvent ev -> {
if (ev.getTraceProgramView() == current.getView()) {
connectedProvider.setHighlight(ev.getHighlight());
}
}
case TrackingChangedPluginEvent ev -> connectedProvider
.setTrackingSpec(ev.getLocationTrackingSpec());
default -> {
}
}
} }
void fireStaticLocationEvent(ProgramLocation staticLoc) { void fireStaticLocationEvent(ProgramLocation staticLoc) {

View file

@ -52,6 +52,7 @@ import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel;
import ghidra.app.plugin.core.debug.disassemble.CurrentPlatformTraceDisassembleCommand; import ghidra.app.plugin.core.debug.disassemble.CurrentPlatformTraceDisassembleCommand;
import ghidra.app.plugin.core.debug.disassemble.CurrentPlatformTraceDisassembleCommand.Reqs; import ghidra.app.plugin.core.debug.disassemble.CurrentPlatformTraceDisassembleCommand.Reqs;
import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPlugin; import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPlugin;
import ghidra.app.plugin.core.debug.event.TrackingChangedPluginEvent;
import ghidra.app.plugin.core.debug.gui.*; import ghidra.app.plugin.core.debug.gui.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction; import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.OpenProgramAction; import ghidra.app.plugin.core.debug.gui.DebuggerResources.OpenProgramAction;
@ -240,6 +241,9 @@ public class DebuggerListingProvider extends CodeViewerProvider {
@Override @Override
protected void specChanged(LocationTrackingSpec spec) { protected void specChanged(LocationTrackingSpec spec) {
if (isMainListing()) {
plugin.firePluginEvent(new TrackingChangedPluginEvent(getName(), spec));
}
updateTitle(); updateTitle();
trackingLabel.setText(""); trackingLabel.setText("");
trackingLabel.setToolTipText(""); trackingLabel.setToolTipText("");

View file

@ -22,10 +22,9 @@ import java.util.stream.Collectors;
import org.jdom.Element; import org.jdom.Element;
import docking.action.DockingAction; import docking.action.DockingAction;
import ghidra.app.events.ProgramLocationPluginEvent;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.byteviewer.*; import ghidra.app.plugin.core.byteviewer.AbstractByteViewerPlugin;
import ghidra.app.plugin.core.byteviewer.ByteViewerComponentProvider;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.event.*; import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.NewMemoryAction; import ghidra.app.plugin.core.debug.gui.DebuggerResources.NewMemoryAction;
@ -37,8 +36,8 @@ import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.trace.model.program.TraceProgramView;
@PluginInfo( @PluginInfo(
shortDescription = "View bytes of trace (possibly live) memory", shortDescription = "View bytes of trace (possibly live) memory",
@ -53,10 +52,16 @@ import ghidra.program.util.ProgramSelection;
// ProgramHighlightPluginEvent.class, // TODO: Later or remove // ProgramHighlightPluginEvent.class, // TODO: Later or remove
TraceActivatedPluginEvent.class, // Trace/thread activation and register tracking TraceActivatedPluginEvent.class, // Trace/thread activation and register tracking
TraceClosedPluginEvent.class, TraceClosedPluginEvent.class,
TraceLocationPluginEvent.class,
TraceSelectionPluginEvent.class,
TraceHighlightPluginEvent.class,
TrackingChangedPluginEvent.class,
}, },
eventsProduced = { eventsProduced = {
TraceLocationPluginEvent.class, TraceLocationPluginEvent.class,
TraceSelectionPluginEvent.class, TraceSelectionPluginEvent.class,
TraceHighlightPluginEvent.class,
TrackingChangedPluginEvent.class,
}, },
servicesRequired = { servicesRequired = {
ClipboardService.class, ClipboardService.class,
@ -116,29 +121,12 @@ public class DebuggerMemoryBytesPlugin
} }
} }
@Override
protected void updateLocation(
ProgramByteViewerComponentProvider programByteViewerComponentProvider,
ProgramLocationPluginEvent event, boolean export) {
// TODO
}
@Override
protected void fireProgramLocationPluginEvent(
ProgramByteViewerComponentProvider programByteViewerComponentProvider,
ProgramLocationPluginEvent pluginEvent) {
// TODO
}
@Override
public void updateSelection(ByteViewerComponentProvider provider,
ProgramSelectionPluginEvent event, Program program) {
// TODO
}
@Override @Override
public void highlightChanged(ByteViewerComponentProvider provider, ProgramSelection highlight) { public void highlightChanged(ByteViewerComponentProvider provider, ProgramSelection highlight) {
// TODO if (provider == connectedProvider) {
tool.firePluginEvent(new TraceHighlightPluginEvent(getName(), highlight,
(TraceProgramView) connectedProvider.getProgram()));
}
} }
protected void allProviders(Consumer<DebuggerMemoryBytesProvider> action) { protected void allProviders(Consumer<DebuggerMemoryBytesProvider> action) {
@ -150,17 +138,22 @@ public class DebuggerMemoryBytesPlugin
@Override @Override
public void processEvent(PluginEvent event) { public void processEvent(PluginEvent event) {
// do not delegate to super
if (event instanceof TraceActivatedPluginEvent ev) { if (event instanceof TraceActivatedPluginEvent ev) {
current = ev.getActiveCoordinates(); current = ev.getActiveCoordinates();
allProviders(p -> p.coordinatesActivated(current)); allProviders(p -> p.coordinatesActivated(current));
} }
if (event instanceof TraceClosedPluginEvent ev) { else if (event instanceof TraceClosedPluginEvent ev) {
if (current.getTrace() == ev.getTrace()) { if (current.getTrace() == ev.getTrace()) {
current = DebuggerCoordinates.NOWHERE; current = DebuggerCoordinates.NOWHERE;
} }
allProviders(p -> p.traceClosed(ev.getTrace())); allProviders(p -> p.traceClosed(ev.getTrace()));
} }
// TODO: Sync among dynamic providers? else if (event instanceof TraceLocationPluginEvent ev) {
currentLocation = ev.getLocation();
}
connectedProvider.doHandleTraceEvent(event);
} }
@AutoServiceConsumed @AutoServiceConsumed

View file

@ -36,13 +36,15 @@ import docking.action.ToggleDockingAction;
import docking.menu.MultiStateDockingAction; import docking.menu.MultiStateDockingAction;
import docking.widgets.fieldpanel.support.ViewerPosition; import docking.widgets.fieldpanel.support.ViewerPosition;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.events.AbstractLocationPluginEvent;
import ghidra.app.events.AbstractSelectionPluginEvent;
import ghidra.app.plugin.core.byteviewer.*; import ghidra.app.plugin.core.byteviewer.*;
import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.plugin.core.debug.gui.*; import ghidra.app.plugin.core.debug.gui.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction; import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction;
import ghidra.app.plugin.core.debug.gui.action.*; import ghidra.app.plugin.core.debug.gui.action.*;
import ghidra.app.plugin.core.debug.gui.action.AutoReadMemorySpec.AutoReadMemorySpecConfigFieldCodec; import ghidra.app.plugin.core.debug.gui.action.AutoReadMemorySpec.AutoReadMemorySpecConfigFieldCodec;
import ghidra.app.plugin.core.format.ByteBlock; import ghidra.app.plugin.core.format.*;
import ghidra.app.plugin.core.format.ByteBlockAccessException;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerControlService.ControlModeChangeListener; import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
import ghidra.debug.api.action.GoToInput; import ghidra.debug.api.action.GoToInput;
@ -133,18 +135,21 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
DebuggerMemoryBytesProvider.this); DebuggerMemoryBytesProvider.this);
} }
@Override
protected void locationTracked() {
doGoToTracked();
}
@Override @Override
protected void specChanged(LocationTrackingSpec spec) { protected void specChanged(LocationTrackingSpec spec) {
if (isMainViewer()) {
plugin.firePluginEvent(new TrackingChangedPluginEvent(getName(), spec));
}
updateTitle(); updateTitle();
trackingLabel.setText(""); trackingLabel.setText("");
trackingLabel.setToolTipText(""); trackingLabel.setToolTipText("");
trackingLabel.setForeground(Colors.FOREGROUND); trackingLabel.setForeground(Colors.FOREGROUND);
} }
@Override
protected void locationTracked() {
doGoToTracked();
}
} }
protected class ForMemoryBytesReadsMemoryTrait extends DebuggerReadsMemoryTrait { protected class ForMemoryBytesReadsMemoryTrait extends DebuggerReadsMemoryTrait {
@ -380,15 +385,32 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
} }
class TargetByteBlockSet extends ProgramByteBlockSet { class TargetByteBlockSet extends ProgramByteBlockSet {
private final DebuggerMemoryBytesProvider provider;
protected TargetByteBlockSet(ByteBlockChangeManager changeManager) { protected TargetByteBlockSet(ByteBlockChangeManager changeManager) {
super(DebuggerMemoryBytesProvider.this, DebuggerMemoryBytesProvider.this.program, super(DebuggerMemoryBytesProvider.this, DebuggerMemoryBytesProvider.this.program,
changeManager); changeManager);
this.provider = DebuggerMemoryBytesProvider.this;
} }
@Override @Override
protected MemoryByteBlock newMemoryByteBlock(Memory memory, MemoryBlock memBlock) { protected MemoryByteBlock newMemoryByteBlock(Memory memory, MemoryBlock memBlock) {
return new TargetByteBlock(program, memory, memBlock); return new TargetByteBlock(program, memory, memBlock);
} }
@Override
public AbstractLocationPluginEvent getPluginEvent(String source, ByteBlock block,
BigInteger offset, int column) {
ProgramLocation loc = provider.getLocation(block, offset, column);
return new TraceLocationPluginEvent(source, loc);
}
@Override
public AbstractSelectionPluginEvent getPluginEvent(String source,
ByteBlockSelection selection) {
ProgramSelection pSel = convertSelection(selection);
return new TraceSelectionPluginEvent(source, pSel, (TraceProgramView) program);
}
} }
@Override @Override
@ -604,6 +626,20 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
} }
} }
void doHandleTraceEvent(PluginEvent event) {
if (getByteBlocks() == null) {
return;
}
switch (event) {
case TraceLocationPluginEvent ev -> processLocationEvent(ev);
case TraceSelectionPluginEvent ev -> processSelectionEvent(ev);
case TraceHighlightPluginEvent ev -> processHighlightEvent(ev);
case TrackingChangedPluginEvent ev -> setTrackingSpec(ev.getLocationTrackingSpec());
default -> {
}
}
}
public void setFollowsCurrentThread(boolean follows) { public void setFollowsCurrentThread(boolean follows) {
if (isMainViewer()) { if (isMainViewer()) {
throw new IllegalStateException( throw new IllegalStateException(

View file

@ -0,0 +1,69 @@
/* ###
* 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.app.events;
import java.lang.ref.WeakReference;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramSelection;
/**
* Plugin event generated when the highlight in a program changes.
*/
public abstract class AbstractHighlightPluginEvent extends PluginEvent {
private final ProgramSelection highlight;
private final WeakReference<Program> programRef;
/**
* Construct a new event.
*
* @param sourceName the name of the plugin that generated this event
* @param eventName the name of the event type
* @param highlight the program highlight
* @param program the program associated with this event
*/
public AbstractHighlightPluginEvent(String sourceName, String eventName,
ProgramSelection highlight, Program program) {
super(sourceName, eventName);
this.highlight = highlight;
this.programRef = new WeakReference<Program>(program);
}
/**
* Get the program highlight contained in this event.
*
* @return the program highlight in this event.
*/
public ProgramSelection getHighlight() {
return highlight;
}
/**
* Get the program that the highlight refers to.
*
* @return the program
*/
public Program getProgram() {
return programRef.get();
}
@Override
protected String getDetails() {
return getClass() + " ==> " + highlight;
}
}

View file

@ -0,0 +1,79 @@
/* ###
* 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.app.events;
import java.lang.ref.WeakReference;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.util.Msg;
public abstract class AbstractLocationPluginEvent extends PluginEvent {
private final ProgramLocation location;
private final WeakReference<Program> programRef;
/**
* Construct a new event
*
* @param sourceName the name of the plugin that generated this event.
* @param eventName the name of the event type
* @param location the new location
* @param program the program for which the location object refers.
*/
protected AbstractLocationPluginEvent(String sourceName, String eventName,
ProgramLocation location, Program program) {
super(sourceName, eventName);
// don't allow a null for a program location
if (location == null) {
NullPointerException exc = new NullPointerException(
"Null ProgramLocation passed to create a Plugin event");
Msg.showError(this,
null, "Error",
"Null LocationEvent being created. Trace and remove this problem", exc);
}
this.location = location;
this.programRef = new WeakReference<Program>(program);
}
/**
* Get the location stored in this event.
*
* @return the location
*/
public ProgramLocation getLocation() {
return location;
}
/**
* Get the program that the location refers to.
*
* @return the program
*/
public Program getProgram() {
return programRef.get();
}
@Override
protected String getDetails() {
if (location != null) {
return location.getClass().getName() + " addr==> " + location.getAddress() + "\n";
}
return super.getDetails();
}
}

View file

@ -0,0 +1,80 @@
/* ###
* 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.app.events;
import java.lang.ref.WeakReference;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramSelection;
import ghidra.util.Msg;
/**
* Plugin event generated when the selection in a program changes.
*/
public abstract class AbstractSelectionPluginEvent extends PluginEvent {
private final ProgramSelection selection;
private final WeakReference<Program> programRef;
/**
* Construct a new plugin event
*
* @param sourceName the name of the plugin that generated this event
* @param eventName the name of the event type
* @param selection the program selection
* @param program the program associated with this event
*/
public AbstractSelectionPluginEvent(String sourceName, String eventName,
ProgramSelection selection, Program program) {
super(sourceName, eventName);
// don't allow null program selection
if (selection == null) {
NullPointerException exc = new NullPointerException(
"Null ProgramSelection in creating Selection Plugin Event");
Msg.showError(this,
null, "Internal Error",
"Null SelectionEvent being created. Trace and remove this problem", exc);
}
this.selection = selection;
this.programRef = new WeakReference<Program>(program);
}
/**
* Get the program selection contained in this event.
*
* @return the program selection in this event.
*/
public ProgramSelection getSelection() {
return selection;
}
/**
* Get the program that the selection refers to.
*
* @return the program
*/
public Program getProgram() {
return programRef.get();
}
@Override
protected String getDetails() {
return getClass() + " ==> " + selection;
}
}

View file

@ -15,46 +15,23 @@
*/ */
package ghidra.app.events; package ghidra.app.events;
import java.lang.ref.WeakReference;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
/** /**
* Plugin event generated when the highlight in a program changes. * Plugin event generated when the highlight in a program changes.
*/ */
public final class ProgramHighlightPluginEvent extends PluginEvent { public final class ProgramHighlightPluginEvent extends AbstractHighlightPluginEvent {
public static final String NAME = "ProgramHighlight"; public static final String NAME = "ProgramHighlight";
private ProgramSelection highlight;
private WeakReference<Program> programRef;
/** /**
* Construct a new event. * Construct a new event.
*
* @param src name of the plugin that generated the event * @param src name of the plugin that generated the event
* @param hl Program selection containing the selected address set. * @param hl Program selection containing the selected address set.
* @param program program being highlighted * @param program program being highlighted
*/ */
public ProgramHighlightPluginEvent(String src, ProgramSelection hl, Program program) { public ProgramHighlightPluginEvent(String src, ProgramSelection hl, Program program) {
super(src, NAME); super(src, NAME, hl, program);
this.highlight = hl;
this.programRef = new WeakReference<Program>(program);
}
/**
* Returns the program selection contained in this event.
* @return ProgramSelection contained in this event.
*/
public ProgramSelection getHighlight() {
return highlight;
}
/**
* Returns the Program object that the highlight refers to.
* @return the Program object that the highlight refers to.
*/
public Program getProgram() {
return programRef.get();
} }
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,67 +15,32 @@
*/ */
package ghidra.app.events; package ghidra.app.events;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.Msg;
import java.lang.ref.WeakReference;
/** /**
* This plugin event class provides program location information. * This plugin event class provides program location information.
* The event is fired when a plugin's program location has changed. *
* Typically, a plugin does not actually generate the event unless it is * <p>
* processing some user action, * The event is fired when a plugin's program location has changed. Typically, a plugin does not
* e.g., the user mouse clicks somewhere on a plugin component to cause * actually generate the event unless it is processing some user action, e.g., the user mouse clicks
* the program location to change. * somewhere on a plugin component to cause the program location to change.
*/ */
public final class ProgramLocationPluginEvent extends PluginEvent { public final class ProgramLocationPluginEvent extends AbstractLocationPluginEvent {
/** /**
* The name of this plugin event. * The name of this plugin event.
*/ */
public static final String NAME = "ProgramLocationChange"; public static final String NAME = "ProgramLocationChange";
private ProgramLocation loc;
private WeakReference<Program> programRef;
/** /**
* Construct a new ProgramLocationEvent. * Construct a new ProgramLocationEvent.
*
* @param src the name of the plugin that generated this event. * @param src the name of the plugin that generated this event.
* @param loc the ProgramLocation object that contains the new location. * @param loc the ProgramLocation object that contains the new location.
* @param program the Program for which the loc object refers. * @param program the Program for which the loc object refers.
*/ */
public ProgramLocationPluginEvent(String src, ProgramLocation loc, Program program) { public ProgramLocationPluginEvent(String src, ProgramLocation loc, Program program) {
super(src,NAME); super(src, NAME, loc, program);
// don't allow a null for a program location
if (loc == null) {
NullPointerException exc = new NullPointerException(
"Null ProgramLocation passed to create a Plugin event");
Msg.showError(this,
null, "Error", "Null ProgramLocationEvent being created. Trace and remove this problem", exc);
}
this.loc = loc;
this.programRef = new WeakReference<Program>(program);
}
/**
* Returns the ProgramLocation stored in this event.
*/
public ProgramLocation getLocation() {
return loc;
}
/**
* Returns the Program object that the location refers to.
*/
public Program getProgram() {
return programRef.get();
}
@Override
protected String getDetails() {
if (loc != null) {
return loc.getClass().getName() + " addr==> " + loc.getAddress() +"\n";
}
return super.getDetails();
} }
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,65 +15,28 @@
*/ */
package ghidra.app.events; package ghidra.app.events;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.Msg;
import java.lang.ref.WeakReference;
/** /**
* Plugin event generated when the selection in a program changes. * Plugin event generated when the selection in a program changes.
*/ */
public final class ProgramSelectionPluginEvent extends PluginEvent { public final class ProgramSelectionPluginEvent extends AbstractSelectionPluginEvent {
/** /**
* The name of this plugin event. * The name of this plugin event.
*/ */
public static final String NAME = "ProgramSelection"; public static final String NAME = "ProgramSelection";
private ProgramSelection selection;
private WeakReference<Program> programRef;
/** /**
* Construct a new plugin event * Construct a new plugin event
*
* @param src the name of the plugin that generated this event * @param src the name of the plugin that generated this event
* @param sel the program selection * @param sel the program selection
* @param program the program associated with this event * @param program the program associated with this event
*/ */
public ProgramSelectionPluginEvent(String src, ProgramSelection sel, public ProgramSelectionPluginEvent(String src, ProgramSelection sel,
Program program) { Program program) {
super(src,NAME); super(src, NAME, sel, program);
// don't allow null program selection
if (sel == null) {
NullPointerException exc = new NullPointerException(
"Null ProgramSelection in creating Selection Plugin Event");
Msg.showError(this,
null, "Internal Error", "Null ProgramSelectionEvent being created. Trace and remove this problem", exc);
}
this.selection = sel;
this.programRef = new WeakReference<Program>(program);
}
/**
* Returns the program selection contained in this event.
* @return ProgramSelection the program selection in this event.
*/
public ProgramSelection getSelection() {
return selection;
}
/**
* Returns the Program object that the selection refers to.
*/
public Program getProgram() {
return programRef.get();
}
@Override
protected String getDetails() {
return "Address Set ==> " + selection;
} }
} }

View file

@ -19,8 +19,8 @@ import java.util.*;
import org.jdom.Element; import org.jdom.Element;
import ghidra.app.events.ProgramLocationPluginEvent; import ghidra.app.events.AbstractLocationPluginEvent;
import ghidra.app.events.ProgramSelectionPluginEvent; import ghidra.app.events.AbstractSelectionPluginEvent;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.framework.model.DomainFile; import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
@ -30,6 +30,7 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.SystemUtilities;
import utility.function.Callback; import utility.function.Callback;
public abstract class AbstractByteViewerPlugin<P extends ProgramByteViewerComponentProvider> public abstract class AbstractByteViewerPlugin<P extends ProgramByteViewerComponentProvider>
@ -270,8 +271,12 @@ public abstract class AbstractByteViewerPlugin<P extends ProgramByteViewerCompon
return connectedProvider; return connectedProvider;
} }
public abstract void updateSelection(ByteViewerComponentProvider provider, public void updateSelection(ByteViewerComponentProvider provider,
ProgramSelectionPluginEvent event, Program program); AbstractSelectionPluginEvent event, Program program) {
if (provider == connectedProvider) {
firePluginEvent(event);
}
}
public abstract void highlightChanged(ByteViewerComponentProvider provider, public abstract void highlightChanged(ByteViewerComponentProvider provider,
ProgramSelection highlight); ProgramSelection highlight);
@ -298,11 +303,31 @@ public abstract class AbstractByteViewerPlugin<P extends ProgramByteViewerCompon
provider.dispose(); provider.dispose();
} }
protected abstract void updateLocation( public void updateLocation(ProgramByteViewerComponentProvider provider,
ProgramByteViewerComponentProvider programByteViewerComponentProvider, AbstractLocationPluginEvent event, boolean export) {
ProgramLocationPluginEvent event, boolean export);
protected abstract void fireProgramLocationPluginEvent( if (eventsDisabled()) {
ProgramByteViewerComponentProvider programByteViewerComponentProvider, return;
ProgramLocationPluginEvent pluginEvent); }
if (provider == connectedProvider) {
fireProgramLocationPluginEvent(provider, event);
}
else if (export) {
exportLocation(provider.getProgram(), event.getLocation());
}
}
public void fireProgramLocationPluginEvent(ProgramByteViewerComponentProvider provider,
AbstractLocationPluginEvent event) {
if (SystemUtilities.isEqual(event.getLocation(), currentLocation)) {
return;
}
currentLocation = event.getLocation();
if (provider == connectedProvider) {
firePluginEvent(event);
}
}
} }

View file

@ -24,7 +24,6 @@ import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.SystemUtilities;
//@formatter:off //@formatter:off
@PluginInfo( @PluginInfo(
@ -69,10 +68,8 @@ public class ByteViewerPlugin extends AbstractByteViewerPlugin<ProgramByteViewer
if (event instanceof ProgramClosedPluginEvent) { if (event instanceof ProgramClosedPluginEvent) {
Program program = ((ProgramClosedPluginEvent) event).getProgram(); Program program = ((ProgramClosedPluginEvent) event).getProgram();
programClosed(program); programClosed(program);
return;
} }
else if (event instanceof ProgramActivatedPluginEvent) {
if (event instanceof ProgramActivatedPluginEvent) {
currentProgram = ((ProgramActivatedPluginEvent) event).getActiveProgram(); currentProgram = ((ProgramActivatedPluginEvent) event).getActiveProgram();
currentLocation = null; currentLocation = null;
} }
@ -94,44 +91,6 @@ public class ByteViewerPlugin extends AbstractByteViewerPlugin<ProgramByteViewer
} }
} }
@Override
public void updateLocation(ProgramByteViewerComponentProvider provider,
ProgramLocationPluginEvent event, boolean export) {
if (eventsDisabled()) {
return;
}
if (provider == connectedProvider) {
fireProgramLocationPluginEvent(provider, event);
}
else if (export) {
exportLocation(provider.getProgram(), event.getLocation());
}
}
@Override
public void fireProgramLocationPluginEvent(ProgramByteViewerComponentProvider provider,
ProgramLocationPluginEvent event) {
if (SystemUtilities.isEqual(event.getLocation(), currentLocation)) {
return;
}
currentLocation = event.getLocation();
if (provider == connectedProvider) {
firePluginEvent(event);
}
}
@Override
public void updateSelection(ByteViewerComponentProvider provider,
ProgramSelectionPluginEvent event, Program program) {
if (provider == connectedProvider) {
firePluginEvent(event);
}
}
@Override @Override
public void highlightChanged(ByteViewerComponentProvider provider, ProgramSelection highlight) { public void highlightChanged(ByteViewerComponentProvider provider, ProgramSelection highlight) {
if (provider == connectedProvider) { if (provider == connectedProvider) {

View file

@ -19,8 +19,7 @@ import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import ghidra.app.events.ProgramLocationPluginEvent; import ghidra.app.events.*;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.plugin.core.format.*; import ghidra.app.plugin.core.format.*;
import ghidra.framework.options.SaveState; import ghidra.framework.options.SaveState;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
@ -59,17 +58,8 @@ public class ProgramByteBlockSet implements ByteBlockSet {
return blocks; return blocks;
} }
/** protected ProgramSelection convertSelection(ByteBlockSelection selection) {
* Get the appropriate plugin event for the given block selection.
*
* @param source source to use in the event
* @param selection selection to use to generate the event
*/
@Override
public ProgramSelectionPluginEvent getPluginEvent(String source, ByteBlockSelection selection) {
AddressSet addrSet = new AddressSet(); AddressSet addrSet = new AddressSet();
for (int i = 0; i < selection.getNumberOfRanges(); i++) { for (int i = 0; i < selection.getNumberOfRanges(); i++) {
ByteBlockRange br = selection.getRange(i); ByteBlockRange br = selection.getRange(i);
ByteBlock block = br.getByteBlock(); ByteBlock block = br.getByteBlock();
@ -77,7 +67,20 @@ public class ProgramByteBlockSet implements ByteBlockSet {
Address end = getAddress(block, br.getEndIndex()); Address end = getAddress(block, br.getEndIndex());
addrSet.add(new AddressRangeImpl(start, end)); addrSet.add(new AddressRangeImpl(start, end));
} }
return new ProgramSelectionPluginEvent(source, new ProgramSelection(addrSet), program); return new ProgramSelection(addrSet);
}
/**
* Get the appropriate plugin event for the given block selection.
*
* @param source source to use in the event
* @param selection selection to use to generate the event
*/
@Override
public AbstractSelectionPluginEvent getPluginEvent(String source,
ByteBlockSelection selection) {
ProgramSelection pSel = convertSelection(selection);
return new ProgramSelectionPluginEvent(source, pSel, program);
} }
/** /**
@ -89,7 +92,7 @@ public class ProgramByteBlockSet implements ByteBlockSet {
* @param column the column within the UI byte field * @param column the column within the UI byte field
*/ */
@Override @Override
public ProgramLocationPluginEvent getPluginEvent(String source, ByteBlock block, public AbstractLocationPluginEvent getPluginEvent(String source, ByteBlock block,
BigInteger offset, int column) { BigInteger offset, int column) {
ProgramLocation loc = provider.getLocation(block, offset, column); ProgramLocation loc = provider.getLocation(block, offset, column);

View file

@ -197,7 +197,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
panel.setViewerSelection(blockSelection); panel.setViewerSelection(blockSelection);
if (notify) { if (notify) {
ProgramSelectionPluginEvent selectionEvent = AbstractSelectionPluginEvent selectionEvent =
blockSet.getPluginEvent(getName(), blockSelection); blockSet.getPluginEvent(getName(), blockSelection);
plugin.updateSelection(this, selectionEvent, program); plugin.updateSelection(this, selectionEvent, program);
} }
@ -449,7 +449,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
} }
} }
ProgramLocation getLocation(ByteBlock block, BigInteger offset, int column) { protected ProgramLocation getLocation(ByteBlock block, BigInteger offset, int column) {
Address address = blockSet.getAddress(block, offset); Address address = blockSet.getAddress(block, offset);
int characterOffset = column; int characterOffset = column;
ProgramLocation loc = new ByteViewerProgramLocation(program, address, characterOffset); ProgramLocation loc = new ByteViewerProgramLocation(program, address, characterOffset);
@ -515,17 +515,17 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
} }
} }
private void processHighlightEvent(ProgramHighlightPluginEvent event) { protected void processHighlightEvent(AbstractHighlightPluginEvent event) {
ProgramSelection programSelection = event.getHighlight(); ProgramSelection programSelection = event.getHighlight();
setHighlight(programSelection); setHighlight(programSelection);
} }
private void processSelectionEvent(ProgramSelectionPluginEvent event) { protected void processSelectionEvent(AbstractSelectionPluginEvent event) {
ProgramSelection programSelection = event.getSelection(); ProgramSelection programSelection = event.getSelection();
setSelection(programSelection); setSelection(programSelection);
} }
private void processLocationEvent(ProgramLocationPluginEvent event) { protected void processLocationEvent(AbstractLocationPluginEvent event) {
ProgramLocation loc = event.getLocation(); ProgramLocation loc = event.getLocation();
setLocation(loc); setLocation(loc);
} }
@ -603,7 +603,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
@Override @Override
protected void updateSelection(ByteBlockSelection selection) { protected void updateSelection(ByteBlockSelection selection) {
ProgramSelectionPluginEvent event = blockSet.getPluginEvent(plugin.getName(), selection); AbstractSelectionPluginEvent event = blockSet.getPluginEvent(plugin.getName(), selection);
liveSelection = null; liveSelection = null;
currentSelection = event.getSelection(); currentSelection = event.getSelection();
plugin.updateSelection(this, event, program); plugin.updateSelection(this, event, program);
@ -614,7 +614,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
@Override @Override
protected void updateLiveSelection(ByteBlockSelection selection) { protected void updateLiveSelection(ByteBlockSelection selection) {
ProgramSelectionPluginEvent event = blockSet.getPluginEvent(plugin.getName(), selection); AbstractSelectionPluginEvent event = blockSet.getPluginEvent(plugin.getName(), selection);
liveSelection = event.getSelection(); liveSelection = event.getSelection();
updateTitle(); updateTitle();
} }
@ -622,7 +622,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
@Override @Override
protected void updateLocation(ByteBlock block, BigInteger blockOffset, int column, protected void updateLocation(ByteBlock block, BigInteger blockOffset, int column,
boolean export) { boolean export) {
ProgramLocationPluginEvent event = AbstractLocationPluginEvent event =
blockSet.getPluginEvent(plugin.getName(), block, blockOffset, column); blockSet.getPluginEvent(plugin.getName(), block, blockOffset, column);
currentLocation = event.getLocation(); currentLocation = event.getLocation();
plugin.updateLocation(this, event, export); plugin.updateLocation(this, event, export);

View file

@ -17,8 +17,8 @@ package ghidra.app.plugin.core.format;
import java.math.BigInteger; import java.math.BigInteger;
import ghidra.app.events.ProgramLocationPluginEvent; import ghidra.app.events.AbstractLocationPluginEvent;
import ghidra.app.events.ProgramSelectionPluginEvent; import ghidra.app.events.AbstractSelectionPluginEvent;
import ghidra.program.model.address.AddressSet; import ghidra.program.model.address.AddressSet;
/** /**
@ -42,7 +42,7 @@ public interface ByteBlockSet {
* @param column the column within the UI byte field * @param column the column within the UI byte field
* @return the event * @return the event
*/ */
public ProgramLocationPluginEvent getPluginEvent(String source, ByteBlock block, public AbstractLocationPluginEvent getPluginEvent(String source, ByteBlock block,
BigInteger offset, int column); BigInteger offset, int column);
/** /**
@ -52,7 +52,7 @@ public interface ByteBlockSet {
* @param selection selection to use to generate the event * @param selection selection to use to generate the event
* @return the event * @return the event
*/ */
public ProgramSelectionPluginEvent getPluginEvent(String source, ByteBlockSelection selection); public AbstractSelectionPluginEvent getPluginEvent(String source, ByteBlockSelection selection);
/** /**
* Return true if the block has been changed at the given index. * Return true if the block has been changed at the given index.