mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-1288: more work on config options
This commit is contained in:
parent
9c3084ccee
commit
885bdd36b3
16 changed files with 349 additions and 29 deletions
|
@ -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,8 +380,10 @@ public class DebugControlImpl1 implements DebugControlInternal {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSpecificFilterArgument(int index, String arg) {
|
public void setSpecificFilterArgument(int index, String arg) {
|
||||||
ULONG ulIndex = new ULONG(index);
|
if (arg != null) {
|
||||||
COMUtils.checkRC(jnaControl.SetSpecificFilterArgument(ulIndex, arg));
|
ULONG ulIndex = new ULONG(index);
|
||||||
|
COMUtils.checkRC(jnaControl.SetSpecificFilterArgument(ulIndex, arg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,8 @@ public interface DbgEventFilter {
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
|
String getArg();
|
||||||
|
|
||||||
String getCmd();
|
String getCmd();
|
||||||
|
|
||||||
int getExecutionOption();
|
int getExecutionOption();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue