GP-1288: more work on config options

This commit is contained in:
d-millar 2021-09-23 15:34:23 +00:00
parent 9c3084ccee
commit 885bdd36b3
16 changed files with 349 additions and 29 deletions

View file

@ -365,8 +365,12 @@ public class DebugControlImpl1 implements DebugControlInternal {
public String getSpecificFilterArgument(int index) { public String getSpecificFilterArgument(int index) {
ULONG ulIndex = new ULONG(index); ULONG ulIndex = new ULONG(index);
ULONGByReference ulArgumentSize = new ULONGByReference(); ULONGByReference ulArgumentSize = new ULONGByReference();
COMUtils.checkRC( HRESULT hr =
jnaControl.GetSpecificFilterArgument(ulIndex, null, new ULONG(0), ulArgumentSize)); jnaControl.GetSpecificFilterArgument(ulIndex, null, new ULONG(0), ulArgumentSize);
if (hr.equals(COMUtilsExtra.E_INVALID_PARAM)) {
return null;
}
COMUtils.checkRC(hr);
byte[] buffer = new byte[ulArgumentSize.getValue().intValue()]; byte[] buffer = new byte[ulArgumentSize.getValue().intValue()];
ULONG ulBufferSize = ulArgumentSize.getValue(); ULONG ulBufferSize = ulArgumentSize.getValue();
COMUtils.checkRC( COMUtils.checkRC(
@ -376,9 +380,11 @@ public class DebugControlImpl1 implements DebugControlInternal {
@Override @Override
public void setSpecificFilterArgument(int index, String arg) { public void setSpecificFilterArgument(int index, String arg) {
if (arg != null) {
ULONG ulIndex = new ULONG(index); ULONG ulIndex = new ULONG(index);
COMUtils.checkRC(jnaControl.SetSpecificFilterArgument(ulIndex, arg)); COMUtils.checkRC(jnaControl.SetSpecificFilterArgument(ulIndex, arg));
} }
}
@Override @Override
public DebugExceptionFilterInformation getExceptionFilterParameters(int start, int[] codes, public DebugExceptionFilterInformation getExceptionFilterParameters(int start, int[] codes,

View file

@ -21,6 +21,8 @@ public interface DbgEventFilter {
String getName(); String getName();
String getArg();
String getCmd(); String getCmd();
int getExecutionOption(); int getExecutionOption();

View file

@ -47,9 +47,10 @@ public class DbgListEventFiltersCommand
for (int i = 0; i < info.getNumberEvents(); i++) { for (int i = 0; i < info.getNumberEvents(); i++) {
String text = control.getEventFilterText(i); String text = control.getEventFilterText(i);
String cmd = control.getEventFilterCommand(i); String cmd = control.getEventFilterCommand(i);
String arg = control.getSpecificFilterArgument(i);
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(i); DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(i);
DbgEventFilterImpl f = DbgEventFilterImpl f =
new DbgEventFilterImpl(i, text, cmd, p.ExecutionOption.intValue(), new DbgEventFilterImpl(i, text, cmd, arg, p.ExecutionOption.intValue(),
p.ContinueOption.intValue()); p.ContinueOption.intValue());
result.add(f); result.add(f);
} }

View file

@ -0,0 +1,39 @@
/* ###
* 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 agent.dbgeng.manager.cmd;
import agent.dbgeng.dbgeng.DebugControl;
import agent.dbgeng.manager.impl.DbgManagerImpl;
public class DbgSetFilterArgumentCommand
extends AbstractDbgCommand<Void> {
private int index;
private String cmd;
public DbgSetFilterArgumentCommand(DbgManagerImpl manager, int index,
String cmd) {
super(manager);
this.index = index;
this.cmd = cmd;
}
@Override
public void invoke() {
DebugControl control = manager.getControl();
control.setEventFilterCommand(index, cmd);
}
}

View file

@ -0,0 +1,39 @@
/* ###
* 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 agent.dbgeng.manager.cmd;
import agent.dbgeng.dbgeng.DebugControl;
import agent.dbgeng.manager.impl.DbgManagerImpl;
public class DbgSetFilterCommandCommand
extends AbstractDbgCommand<Void> {
private int index;
private String cmd;
public DbgSetFilterCommandCommand(DbgManagerImpl manager, int index,
String cmd) {
super(manager);
this.index = index;
this.cmd = cmd;
}
@Override
public void invoke() {
DebugControl control = manager.getControl();
control.setEventFilterCommand(index, cmd);
}
}

View file

@ -0,0 +1,39 @@
/* ###
* 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 agent.dbgeng.manager.cmd;
import agent.dbgeng.dbgeng.DebugControl;
import agent.dbgeng.manager.impl.DbgManagerImpl;
public class DbgSetFilterSecondChanceCmdCommand
extends AbstractDbgCommand<Void> {
private int index;
private String cmd;
public DbgSetFilterSecondChanceCmdCommand(DbgManagerImpl manager, int index,
String cmd) {
super(manager);
this.index = index;
this.cmd = cmd;
}
@Override
public void invoke() {
DebugControl control = manager.getControl();
control.setExceptionFilterSecondCommand(index, cmd);
}
}

View file

@ -21,15 +21,17 @@ public class DbgEventFilterImpl implements DbgEventFilter {
protected int index; protected int index;
protected final String text; protected final String text;
protected final String arg;
protected final String cmd; protected final String cmd;
protected int executionOption; protected int executionOption;
protected int continueOption; protected int continueOption;
public DbgEventFilterImpl(int index, String text, String cmd, int executionOption, public DbgEventFilterImpl(int index, String text, String cmd, String arg, int executionOption,
int continueOption) { int continueOption) {
this.index = index; this.index = index;
this.text = text; this.text = text;
this.cmd = cmd; this.cmd = cmd;
this.arg = arg;
this.setExecutionOption(executionOption); this.setExecutionOption(executionOption);
this.setContinueOption(continueOption); this.setContinueOption(continueOption);
} }
@ -44,6 +46,11 @@ public class DbgEventFilterImpl implements DbgEventFilter {
return text; return text;
} }
@Override
public String getArg() {
return arg == null ? "N/A" : arg;
}
@Override @Override
public String getCmd() { public String getCmd() {
return cmd; return cmd;

View file

@ -25,7 +25,7 @@ public class DbgExceptionFilterImpl extends DbgEventFilterImpl implements DbgExc
public DbgExceptionFilterImpl(int index, String text, String cmd, String cmd2, public DbgExceptionFilterImpl(int index, String text, String cmd, String cmd2,
int executionOption, int executionOption,
int continueOption, long exceptionCode) { int continueOption, long exceptionCode) {
super(index, text, cmd, executionOption, continueOption); super(index, text, cmd, null, executionOption, continueOption);
this.cmd2 = cmd2; this.cmd2 = cmd2;
this.exceptionCode = exceptionCode; this.exceptionCode = exceptionCode;
} }

View file

@ -18,8 +18,12 @@ package agent.dbgeng.model.iface2;
import agent.dbgeng.manager.*; import agent.dbgeng.manager.*;
import agent.dbgeng.manager.evt.AbstractDbgEvent; import agent.dbgeng.manager.evt.AbstractDbgEvent;
import agent.dbgeng.model.iface1.DbgModelSelectableObject; import agent.dbgeng.model.iface1.DbgModelSelectableObject;
import agent.dbgeng.model.iface1.DbgModelTargetConfigurable;
public interface DbgModelTargetEvent extends DbgModelSelectableObject, DbgEventsListenerAdapter // public interface DbgModelTargetEvent extends
DbgModelSelectableObject, //
DbgModelTargetConfigurable, //
DbgEventsListenerAdapter //
{ {
public DbgEventFilter getFilter(); public DbgEventFilter getFilter();

View file

@ -15,8 +15,14 @@
*/ */
package agent.dbgeng.model.iface2; package agent.dbgeng.model.iface2;
import java.util.concurrent.CompletableFuture;
import ghidra.dbg.target.TargetTogglable; import ghidra.dbg.target.TargetTogglable;
public interface DbgModelTargetEventOption extends DbgModelTargetObject, TargetTogglable { public interface DbgModelTargetEventOption extends DbgModelTargetObject, TargetTogglable {
int getOption();
CompletableFuture<Void> setOption(int ordinal);
} }

View file

@ -57,17 +57,23 @@ public class DbgModelTargetContinuationOptionImpl extends DbgModelTargetObjectIm
@Override @Override
public CompletableFuture<Void> disable() { public CompletableFuture<Void> disable() {
DbgManagerImpl manager = getManager(); return setOption(DebugFilterContinuationOption.DEBUG_FILTER_GO_NOT_HANDLED.ordinal());
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_NOT_HANDLED;
setAttributes();
return manager.execute(
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));
} }
@Override @Override
public CompletableFuture<Void> enable() { public CompletableFuture<Void> enable() {
return setOption(DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED.ordinal());
}
@Override
public int getOption() {
return optionCont.ordinal();
}
@Override
public CompletableFuture<Void> setOption(int ordinal) {
DbgManagerImpl manager = getManager(); DbgManagerImpl manager = getManager();
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED; optionCont = DebugFilterContinuationOption.getByNumber(ordinal);
setAttributes(); setAttributes();
return manager.execute( return manager.execute(
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont)); new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));

View file

@ -15,14 +15,20 @@
*/ */
package agent.dbgeng.model.impl; package agent.dbgeng.model.impl;
import java.util.List; import java.util.*;
import java.util.Map; import java.util.concurrent.CompletableFuture;
import agent.dbgeng.dbgeng.DebugControl.*; import agent.dbgeng.dbgeng.DebugControl.*;
import agent.dbgeng.manager.DbgCause; import agent.dbgeng.manager.DbgCause;
import agent.dbgeng.manager.DbgEventFilter; import agent.dbgeng.manager.DbgEventFilter;
import agent.dbgeng.manager.cmd.DbgSetFilterArgumentCommand;
import agent.dbgeng.manager.cmd.DbgSetFilterCommandCommand;
import agent.dbgeng.manager.evt.*; import agent.dbgeng.manager.evt.*;
import agent.dbgeng.manager.impl.DbgManagerImpl;
import agent.dbgeng.model.iface2.*; import agent.dbgeng.model.iface2.*;
import ghidra.async.AsyncUtils;
import ghidra.dbg.error.DebuggerIllegalArgumentException;
import ghidra.dbg.target.TargetMethod.ParameterDescription;
import ghidra.dbg.target.schema.*; import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@ -34,6 +40,12 @@ import ghidra.dbg.util.PathUtils;
@TargetAttributeType(type = Object.class) }) @TargetAttributeType(type = Object.class) })
public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
implements DbgModelTargetEvent { implements DbgModelTargetEvent {
final String COMMAND_ATTRIBUTE_NAME = "Command";
final String ARGUMENT_ATTRIBUTE_NAME = "Argument";
final String CONTINUE_OPTION_ATTRIBUTE_NAME = "Continue";
final String EXECUTE_OPTION_ATTRIBUTE_NAME = "Execute";
protected static String indexFilter(DbgEventFilter filter) { protected static String indexFilter(DbgEventFilter filter) {
return filter.getName(); return filter.getName();
} }
@ -61,9 +73,10 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
changeAttributes(List.of(), List.of(), Map.of( // changeAttributes(List.of(), List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, getIndex(), // DISPLAY_ATTRIBUTE_NAME, getIndex(), //
"Command", filter.getCmd(), // COMMAND_ATTRIBUTE_NAME, filter.getCmd(), //
"Execute", execOption, // ARGUMENT_ATTRIBUTE_NAME, filter.getArg(), //
"Continue", contOption // EXECUTE_OPTION_ATTRIBUTE_NAME, execOption, //
CONTINUE_OPTION_ATTRIBUTE_NAME, contOption //
), "Initialized"); ), "Initialized");
getManager().addEventsListener(this); getManager().addEventsListener(this);
@ -114,4 +127,54 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed"); MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
} }
} }
@Override
public Map<String, ParameterDescription<?>> getConfigParameters() {
Map<String, ParameterDescription<?>> map = new HashMap<>();
ParameterDescription<String> cmdDesc = ParameterDescription.create(String.class,
COMMAND_ATTRIBUTE_NAME, false, "", COMMAND_ATTRIBUTE_NAME, "filter command");
map.put(COMMAND_ATTRIBUTE_NAME, cmdDesc);
ParameterDescription<String> argDesc =
ParameterDescription.create(String.class, ARGUMENT_ATTRIBUTE_NAME, false, "",
ARGUMENT_ATTRIBUTE_NAME, "filter argument");
map.put(ARGUMENT_ATTRIBUTE_NAME, argDesc);
return map;
}
@Override
public CompletableFuture<Void> writeConfigurationOption(String key, Object value) {
DbgManagerImpl manager = getManager();
switch (key) {
case COMMAND_ATTRIBUTE_NAME:
if (value instanceof String) {
this.changeAttributes(List.of(), Map.of(COMMAND_ATTRIBUTE_NAME, value),
"Modified");
String cmd = (String) getCachedAttribute(COMMAND_ATTRIBUTE_NAME);
return manager.execute(
new DbgSetFilterCommandCommand(manager, getEventIndex(), cmd));
}
throw new DebuggerIllegalArgumentException("Command should be a string");
case ARGUMENT_ATTRIBUTE_NAME:
if (value instanceof String) {
this.changeAttributes(List.of(), Map.of(ARGUMENT_ATTRIBUTE_NAME, value),
"Modified");
String cmd = (String) getCachedAttribute(ARGUMENT_ATTRIBUTE_NAME);
return manager.execute(
new DbgSetFilterArgumentCommand(manager, getEventIndex(), cmd));
}
throw new DebuggerIllegalArgumentException("Argument should be a string");
case EXECUTE_OPTION_ATTRIBUTE_NAME:
if (value instanceof Integer) {
execOption.setOption((Integer) value);
}
throw new DebuggerIllegalArgumentException("Option should be numeric");
case CONTINUE_OPTION_ATTRIBUTE_NAME:
if (value instanceof Integer) {
contOption.setOption((Integer) value);
}
throw new DebuggerIllegalArgumentException("Option should be numeric");
default:
}
return AsyncUtils.NIL;
}
} }

View file

@ -15,19 +15,25 @@
*/ */
package agent.dbgeng.model.impl; package agent.dbgeng.model.impl;
import java.util.List; import java.util.*;
import java.util.Map; import java.util.concurrent.CompletableFuture;
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption; import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption; import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
import agent.dbgeng.dbgeng.DebugExceptionRecord64; import agent.dbgeng.dbgeng.DebugExceptionRecord64;
import agent.dbgeng.manager.DbgCause; import agent.dbgeng.manager.DbgCause;
import agent.dbgeng.manager.DbgExceptionFilter; import agent.dbgeng.manager.DbgExceptionFilter;
import agent.dbgeng.manager.cmd.DbgSetFilterCommandCommand;
import agent.dbgeng.manager.cmd.DbgSetFilterSecondChanceCmdCommand;
import agent.dbgeng.manager.evt.AbstractDbgEvent; import agent.dbgeng.manager.evt.AbstractDbgEvent;
import agent.dbgeng.manager.evt.DbgExceptionEvent; import agent.dbgeng.manager.evt.DbgExceptionEvent;
import agent.dbgeng.manager.impl.DbgManagerImpl;
import agent.dbgeng.model.iface1.DbgModelTargetFocusScope; import agent.dbgeng.model.iface1.DbgModelTargetFocusScope;
import agent.dbgeng.model.iface2.*; import agent.dbgeng.model.iface2.*;
import ghidra.async.AsyncUtils;
import ghidra.dbg.error.DebuggerIllegalArgumentException;
import ghidra.dbg.target.TargetFocusScope; import ghidra.dbg.target.TargetFocusScope;
import ghidra.dbg.target.TargetMethod.ParameterDescription;
import ghidra.dbg.target.schema.*; import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@ -39,6 +45,13 @@ import ghidra.dbg.util.PathUtils;
@TargetAttributeType(type = Object.class) }) @TargetAttributeType(type = Object.class) })
public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
implements DbgModelTargetException { implements DbgModelTargetException {
final String COMMAND_ATTRIBUTE_NAME = "Command";
final String COMMAND2_ATTRIBUTE_NAME = "SecondCmd";
final String CONTINUE_OPTION_ATTRIBUTE_NAME = "Continue";
final String EXECUTE_OPTION_ATTRIBUTE_NAME = "Execute";
final String EXCEPTION_CODE_ATTRIBUTE_NAME = "Exception";
protected static String indexFilter(DbgExceptionFilter filter) { protected static String indexFilter(DbgExceptionFilter filter) {
return filter.getName(); return filter.getName();
} }
@ -67,11 +80,11 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
changeAttributes(List.of(), List.of(), Map.of( // changeAttributes(List.of(), List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, getIndex(), // DISPLAY_ATTRIBUTE_NAME, getIndex(), //
"Command", filter.getCmd(), // COMMAND_ATTRIBUTE_NAME, filter.getCmd(), //
"SecondCmd", filter.getCmd(), // COMMAND2_ATTRIBUTE_NAME, filter.getCmd(), //
"Execute", execOption, // EXECUTE_OPTION_ATTRIBUTE_NAME, execOption, //
"Continue", contOption, // CONTINUE_OPTION_ATTRIBUTE_NAME, contOption, //
"Exception", filter.getExceptionCode() // EXCEPTION_CODE_ATTRIBUTE_NAME, filter.getExceptionCode() //
), "Initialized"); ), "Initialized");
getManager().addEventsListener(this); getManager().addEventsListener(this);
@ -101,4 +114,54 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
} }
} }
} }
@Override
public Map<String, ParameterDescription<?>> getConfigParameters() {
Map<String, ParameterDescription<?>> map = new HashMap<>();
ParameterDescription<String> cmdDesc = ParameterDescription.create(String.class,
COMMAND_ATTRIBUTE_NAME, false, "", COMMAND_ATTRIBUTE_NAME, "filter command");
map.put(COMMAND_ATTRIBUTE_NAME, cmdDesc);
ParameterDescription<String> cmdDesc2 =
ParameterDescription.create(String.class, COMMAND2_ATTRIBUTE_NAME, false, "",
COMMAND2_ATTRIBUTE_NAME, "filter 2nd-chance command");
map.put(COMMAND2_ATTRIBUTE_NAME, cmdDesc2);
return map;
}
@Override
public CompletableFuture<Void> writeConfigurationOption(String key, Object value) {
DbgManagerImpl manager = getManager();
switch (key) {
case COMMAND_ATTRIBUTE_NAME:
if (value instanceof String) {
this.changeAttributes(List.of(), Map.of(COMMAND_ATTRIBUTE_NAME, value),
"Modified");
String cmd = (String) getCachedAttribute(COMMAND_ATTRIBUTE_NAME);
return manager.execute(
new DbgSetFilterCommandCommand(manager, getEventIndex(), cmd));
}
throw new DebuggerIllegalArgumentException("Command should be a string");
case COMMAND2_ATTRIBUTE_NAME:
if (value instanceof String) {
this.changeAttributes(List.of(), Map.of(COMMAND2_ATTRIBUTE_NAME, value),
"Modified");
String cmd = (String) getCachedAttribute(COMMAND2_ATTRIBUTE_NAME);
return manager.execute(
new DbgSetFilterSecondChanceCmdCommand(manager, getEventIndex(), cmd));
}
throw new DebuggerIllegalArgumentException("Command should be a string");
case EXECUTE_OPTION_ATTRIBUTE_NAME:
if (value instanceof Integer) {
execOption.setOption((Integer) value);
}
throw new DebuggerIllegalArgumentException("Option should be numeric");
case CONTINUE_OPTION_ATTRIBUTE_NAME:
if (value instanceof Integer) {
contOption.setOption((Integer) value);
}
throw new DebuggerIllegalArgumentException("Option should be numeric");
default:
}
return AsyncUtils.NIL;
}
} }

View file

@ -62,8 +62,18 @@ public class DbgModelTargetExecutionOptionImpl extends DbgModelTargetObjectImpl
@Override @Override
public CompletableFuture<Void> enable() { public CompletableFuture<Void> enable() {
DbgManagerImpl manager = getManager();
int ordinal = (optionExc.ordinal() + 1) % (DebugFilterExecutionOption.values().length - 1); int ordinal = (optionExc.ordinal() + 1) % (DebugFilterExecutionOption.values().length - 1);
return setOption(ordinal);
}
@Override
public int getOption() {
return optionExc.ordinal();
}
@Override
public CompletableFuture<Void> setOption(int ordinal) {
DbgManagerImpl manager = getManager();
optionExc = DebugFilterExecutionOption.getByNumber(ordinal); optionExc = DebugFilterExecutionOption.getByNumber(ordinal);
setAttributes(); setAttributes();
return manager.execute( return manager.execute(

View file

@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.util.*; import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -212,6 +213,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
private boolean asTree = true; private boolean asTree = true;
private MyObjectListener listener = new MyObjectListener(); private MyObjectListener listener = new MyObjectListener();
public DebuggerMethodInvocationDialog configDialog;
public DebuggerMethodInvocationDialog launchDialog; public DebuggerMethodInvocationDialog launchDialog;
public DebuggerAttachDialog attachDialog; public DebuggerAttachDialog attachDialog;
public DebuggerBreakpointDialog breakpointDialog; public DebuggerBreakpointDialog breakpointDialog;
@ -336,6 +338,8 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
//attachDialogOld = new DebuggerAttachDialog(this); //attachDialogOld = new DebuggerAttachDialog(this);
attachDialog = new DebuggerAttachDialog(this); attachDialog = new DebuggerAttachDialog(this);
breakpointDialog = new DebuggerBreakpointDialog(this); breakpointDialog = new DebuggerBreakpointDialog(this);
configDialog = new DebuggerMethodInvocationDialog(tool, "Config", "Config",
DebuggerResources.ICON_LAUNCH);
} }
private void addToPanel(ObjectPane p) throws Exception { private void addToPanel(ObjectPane p) throws Exception {
@ -1228,13 +1232,27 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex) .popupMenuGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
.helpLocation(AbstractToggleAction.help(plugin)) .helpLocation(AbstractToggleAction.help(plugin))
.enabledWhen(ctx -> isInstance(ctx, TargetTogglable.class)) .enabledWhen(ctx -> isInstance(ctx, TargetTogglable.class))
.popupWhen(ctx -> isInstance(ctx, TargetResumable.class)) .popupWhen(ctx -> isInstance(ctx, TargetTogglable.class))
.onAction(ctx -> performToggle(ctx)) .onAction(ctx -> performToggle(ctx))
.enabled(false) .enabled(false)
.buildAndInstallLocal(this); .buildAndInstallLocal(this);
groupTargetIndex++; groupTargetIndex++;
new ActionBuilder("Configure", plugin.getName())
.keyBinding("C")
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
.popupMenuPath("&Configure")
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
.helpLocation(AbstractToggleAction.help(plugin))
.enabledWhen(ctx -> isInstance(ctx, TargetConfigurable.class))
.popupWhen(ctx -> isInstance(ctx, TargetConfigurable.class))
.onAction(ctx -> performConfigure(ctx))
.enabled(false)
.buildAndInstallLocal(this);
groupTargetIndex++;
displayAsTreeAction = new DisplayAsTreeAction(tool, plugin.getName(), this); displayAsTreeAction = new DisplayAsTreeAction(tool, plugin.getName(), this);
displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this); displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this);
displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this); displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this);
@ -1506,6 +1524,16 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
}, "Couldn't toggle"); }, "Couldn't toggle");
} }
public void performConfigure(ActionContext context) {
performAction(context, false, TargetConfigurable.class, configurable -> {
Map<String, ?> args = configDialog.promptArguments(configurable.getConfigParameters());
for (Entry<String, ?> entry : args.entrySet()) {
configurable.writeConfigurationOption(entry.getKey(), entry.getValue());
}
return AsyncUtils.NIL;
}, "Couldn't configure");
}
public void initiateConsole(ActionContext context) { public void initiateConsole(ActionContext context) {
performAction(context, false, TargetInterpreter.class, interpreter -> { performAction(context, false, TargetInterpreter.class, interpreter -> {
getPlugin().showConsole(interpreter); getPlugin().showConsole(interpreter);

View file

@ -15,9 +15,12 @@
*/ */
package ghidra.dbg.target; package ghidra.dbg.target;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import ghidra.dbg.DebuggerTargetObjectIface; import ghidra.dbg.DebuggerTargetObjectIface;
import ghidra.dbg.target.TargetMethod.ParameterDescription;
/** /**
* A target with writable configuration options * A target with writable configuration options
@ -55,4 +58,8 @@ public interface TargetConfigurable extends TargetObject {
* is not valid. * is not valid.
*/ */
public CompletableFuture<Void> writeConfigurationOption(String key, Object value); public CompletableFuture<Void> writeConfigurationOption(String key, Object value);
public default Map<String, ParameterDescription<?>> getConfigParameters() {
return new HashMap<>();
}
} }