mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Merge remote-tracking branch 'origin/GP-3405_Dan_syncDynamicViews--SQUASHED'
This commit is contained in:
commit
0ef0447601
19 changed files with 549 additions and 322 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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("");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue