mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-1808: Added 'Run to Address'-type actions to right-click menu for some connectors.
This commit is contained in:
parent
44d7c4f031
commit
bde529b4d5
39 changed files with 1663 additions and 136 deletions
|
@ -123,6 +123,30 @@ public interface GdbThread
|
|||
*/
|
||||
CompletableFuture<Void> step(StepCmd suffix);
|
||||
|
||||
/**
|
||||
* Advance the thread to the given location
|
||||
*
|
||||
* <p>
|
||||
* This is equivalent to the CLI command {@code advance}.
|
||||
*
|
||||
* <p>
|
||||
* Note that the command can complete before the thread has finished advancing. The command
|
||||
* completes as soon as the thread is running. A separate stop event is emitted when the thread
|
||||
* has stopped.
|
||||
*
|
||||
* @param loc the location to stop at, same syntax as breakpoint locations
|
||||
* @return a future that completes once the thread is running
|
||||
*/
|
||||
CompletableFuture<Void> advance(String loc);
|
||||
|
||||
/**
|
||||
* Advance the thread to the given address
|
||||
*
|
||||
* @param addr the address
|
||||
* @see #advance(String)
|
||||
*/
|
||||
CompletableFuture<Void> advance(long addr);
|
||||
|
||||
/**
|
||||
* Detach from the entire process
|
||||
*
|
||||
|
|
|
@ -45,6 +45,7 @@ public interface GdbBreakpointInsertions {
|
|||
/**
|
||||
* Insert a breakpoint (usually a watchpoint) at the given address range
|
||||
*
|
||||
* <p>
|
||||
* Note, this implements the length by casting the address pointer to a
|
||||
* fixed-length-char-array-pointer where the array has the given length. Support for specific
|
||||
* lengths may vary by platform.
|
||||
|
|
|
@ -286,6 +286,17 @@ public class GdbThreadImpl implements GdbThread {
|
|||
return execute(new GdbStepCommand(manager, id, suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> advance(String loc) {
|
||||
// There's no exec-advance or similar in MI2....
|
||||
return console("advance " + loc, CompletesWithRunning.MUST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> advance(long addr) {
|
||||
return advance(String.format("*0x%x", addr));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> kill() {
|
||||
return execute(new GdbKillCommand(manager, id));
|
||||
|
|
|
@ -192,9 +192,6 @@ public class GdbModelTargetInferior
|
|||
case SKIP:
|
||||
case EXTENDED:
|
||||
throw new UnsupportedOperationException(kind.name());
|
||||
case ADVANCE: // Why no exec-advance in GDB/MI?
|
||||
// TODO: This doesn't work, since advance requires a parameter
|
||||
return model.gateFuture(inferior.console("advance", CompletesWithRunning.MUST));
|
||||
default:
|
||||
return model.gateFuture(inferior.step(GdbModelTargetThread.convertToGdb(kind)));
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package agent.gdb.model.impl;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
@ -24,14 +25,15 @@ import agent.gdb.manager.GdbManager.StepCmd;
|
|||
import agent.gdb.manager.impl.GdbFrameInfo;
|
||||
import agent.gdb.manager.impl.GdbThreadInfo;
|
||||
import agent.gdb.manager.impl.cmd.GdbStateChangeRecord;
|
||||
import agent.gdb.manager.impl.cmd.GdbConsoleExecCommand.CompletesWithRunning;
|
||||
import agent.gdb.manager.reason.GdbBreakpointHitReason;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.agent.DefaultTargetObject;
|
||||
import ghidra.dbg.target.*;
|
||||
import ghidra.dbg.target.TargetMethod.AnnotatedTargetMethod;
|
||||
import ghidra.dbg.target.schema.*;
|
||||
import ghidra.dbg.util.PathUtils;
|
||||
import ghidra.lifecycle.Internal;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
@TargetObjectSchemaInfo(
|
||||
|
@ -44,15 +46,13 @@ public class GdbModelTargetThread
|
|||
extends DefaultTargetObject<TargetObject, GdbModelTargetThreadContainer> implements
|
||||
TargetThread, TargetExecutionStateful, TargetSteppable, TargetAggregate,
|
||||
GdbModelSelectableObject {
|
||||
protected static final TargetStepKindSet SUPPORTED_KINDS = TargetStepKindSet.of( //
|
||||
TargetStepKind.ADVANCE, //
|
||||
TargetStepKind.FINISH, //
|
||||
TargetStepKind.LINE, //
|
||||
TargetStepKind.OVER, //
|
||||
TargetStepKind.OVER_LINE, //
|
||||
TargetStepKind.RETURN, //
|
||||
TargetStepKind.UNTIL, //
|
||||
TargetStepKind.EXTENDED);
|
||||
protected static final TargetStepKindSet SUPPORTED_KINDS = TargetStepKindSet.of(
|
||||
TargetStepKind.FINISH,
|
||||
TargetStepKind.LINE,
|
||||
TargetStepKind.OVER,
|
||||
TargetStepKind.OVER_LINE,
|
||||
TargetStepKind.RETURN,
|
||||
TargetStepKind.UNTIL);
|
||||
|
||||
protected static String indexThread(int threadId) {
|
||||
return PathUtils.makeIndex(threadId);
|
||||
|
@ -87,12 +87,15 @@ public class GdbModelTargetThread
|
|||
|
||||
this.stack = new GdbModelTargetStack(this, inferior);
|
||||
|
||||
changeAttributes(List.of(), List.of(stack), Map.of( //
|
||||
STATE_ATTRIBUTE_NAME, state = convertState(thread.getState()), //
|
||||
SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME, SUPPORTED_KINDS, //
|
||||
SHORT_DISPLAY_ATTRIBUTE_NAME, shortDisplay = computeShortDisplay(), //
|
||||
DISPLAY_ATTRIBUTE_NAME, display = computeDisplay() //
|
||||
), "Initialized");
|
||||
changeAttributes(List.of(), List.of(),
|
||||
AnnotatedTargetMethod.collectExports(MethodHandles.lookup(), impl, this),
|
||||
"Methods");
|
||||
changeAttributes(List.of(), List.of(stack), Map.of(
|
||||
STATE_ATTRIBUTE_NAME, state = convertState(thread.getState()),
|
||||
SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME, SUPPORTED_KINDS,
|
||||
SHORT_DISPLAY_ATTRIBUTE_NAME, shortDisplay = computeShortDisplay(),
|
||||
DISPLAY_ATTRIBUTE_NAME, display = computeDisplay()),
|
||||
"Initialized");
|
||||
|
||||
updateInfo().exceptionally(ex -> {
|
||||
Msg.error(this, "Could not initialize thread info");
|
||||
|
@ -214,14 +217,20 @@ public class GdbModelTargetThread
|
|||
case SKIP:
|
||||
case EXTENDED:
|
||||
throw new UnsupportedOperationException(kind.name());
|
||||
case ADVANCE: // Why no exec-advance in GDB/MI?
|
||||
// TODO: This doesn't work, since advance requires a parameter
|
||||
return model.gateFuture(thread.console("advance", CompletesWithRunning.CANNOT));
|
||||
default:
|
||||
return model.gateFuture(thread.step(convertToGdb(kind)));
|
||||
}
|
||||
}
|
||||
|
||||
@TargetMethod.Export("Advance")
|
||||
public CompletableFuture<Void> advance(
|
||||
@TargetMethod.Param(
|
||||
name = "target",
|
||||
display = "Target",
|
||||
description = "The address to advance to") Address target) {
|
||||
return impl.gateFuture(thread.advance(target.getOffset()));
|
||||
}
|
||||
|
||||
protected void invalidateRegisterCaches() {
|
||||
stack.invalidateRegisterCaches();
|
||||
}
|
||||
|
@ -257,5 +266,4 @@ public class GdbModelTargetThread
|
|||
this.base = (Integer) value;
|
||||
updateInfo();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue