Merge remote-tracking branch 'origin/GP-1223_Dan_emuAccessors'

This commit is contained in:
Ryan Kurtz
2021-09-21 10:36:45 -04:00
10 changed files with 140 additions and 23 deletions

View File

@@ -186,7 +186,7 @@ public class WatchRow {
private ReadDepsTraceBytesPcodeExecutorState depsState;
public ReadDepsPcodeExecutor(ReadDepsTraceBytesPcodeExecutorState depsState,
Language language, PairedPcodeArithmetic<byte[], Address> arithmetic,
SleighLanguage language, PairedPcodeArithmetic<byte[], Address> arithmetic,
PcodeExecutorState<Pair<byte[], Address>> state) {
super(language, arithmetic, state);
this.depsState = depsState;
@@ -211,11 +211,14 @@ public class WatchRow {
new ReadDepsTraceBytesPcodeExecutorState(trace, coordinates.getViewSnap(),
coordinates.getThread(), coordinates.getFrame());
Language language = trace.getBaseLanguage();
if (!(language instanceof SleighLanguage)) {
throw new IllegalArgumentException("Watch expressions require a SLEIGH language");
}
PcodeExecutorState<Pair<byte[], Address>> paired =
state.paired(new AddressOfPcodeExecutorState(language.isBigEndian()));
PairedPcodeArithmetic<byte[], Address> arithmetic = new PairedPcodeArithmetic<>(
BytesPcodeArithmetic.forLanguage(language), AddressOfPcodeArithmetic.INSTANCE);
return new ReadDepsPcodeExecutor(state, language, arithmetic, paired);
return new ReadDepsPcodeExecutor(state, (SleighLanguage) language, arithmetic, paired);
}
public void setCoordinates(DebuggerCoordinates coordinates) {

View File

@@ -19,8 +19,8 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.async.AsyncUtils;
import ghidra.program.model.lang.Language;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
@@ -39,9 +39,10 @@ import ghidra.program.model.pcode.Varnode;
* @param <T> the type of values in the state
*/
public class AsyncPcodeExecutor<T> extends PcodeExecutor<CompletableFuture<T>> {
public AsyncPcodeExecutor(Language language, PcodeArithmetic<CompletableFuture<T>> behavior,
public AsyncPcodeExecutor(SleighLanguage language,
PcodeArithmetic<CompletableFuture<T>> arithmetic,
PcodeExecutorStatePiece<CompletableFuture<T>, CompletableFuture<T>> state) {
super(language, behavior, state);
super(language, arithmetic, state);
}
public CompletableFuture<Void> stepOpAsync(PcodeOp op, PcodeFrame frame,

View File

@@ -30,7 +30,6 @@ import ghidra.app.services.TraceRecorder;
import ghidra.dbg.model.TestTargetRegisterBankInThread;
import ghidra.dbg.testutil.DebuggerModelTestUtils;
import ghidra.pcode.utils.Utils;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Register;
import ghidra.trace.model.Trace;
import ghidra.trace.model.thread.TraceThread;
@@ -55,10 +54,10 @@ public class TraceRecorderAsyncPcodeExecTest extends AbstractGhidraHeadedDebugge
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
Trace trace = recorder.getTrace();
Language language = trace.getBaseLanguage();
SleighLanguage language = (SleighLanguage) trace.getBaseLanguage();
SleighExpression expr = SleighProgramCompiler
.compileExpression((SleighLanguage) language, "r0 + r1");
.compileExpression(language, "r0 + r1");
Register r0 = language.getRegister("r0");
Register r1 = language.getRegister("r1");
@@ -98,9 +97,9 @@ public class TraceRecorderAsyncPcodeExecTest extends AbstractGhidraHeadedDebugge
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
Trace trace = recorder.getTrace();
Language language = trace.getBaseLanguage();
SleighLanguage language = (SleighLanguage) trace.getBaseLanguage();
PcodeProgram prog = SleighProgramCompiler.compileProgram((SleighLanguage) language, "test",
PcodeProgram prog = SleighProgramCompiler.compileProgram(language, "test",
List.of("r2 = r0 + r1;"), SleighUseropLibrary.NIL);
Register r0 = language.getRegister("r0");

View File

@@ -51,7 +51,11 @@ public enum TraceSleighUtils {
TraceBytesPcodeExecutorState state =
new TraceBytesPcodeExecutorState(trace, snap, thread, frame);
Language language = trace.getBaseLanguage();
return new PcodeExecutor<>(language, BytesPcodeArithmetic.forLanguage(language), state);
if (!(language instanceof SleighLanguage)) {
throw new IllegalArgumentException("Trace must use a SLEIGH language");
}
return new PcodeExecutor<>((SleighLanguage) language,
BytesPcodeArithmetic.forLanguage(language), state);
}
public static PcodeExecutor<Pair<byte[], TraceMemoryState>> buildByteWithStateExecutor(
@@ -60,9 +64,12 @@ public enum TraceSleighUtils {
new TraceBytesPcodeExecutorState(trace, snap, thread, frame);
PcodeExecutorState<Pair<byte[], TraceMemoryState>> paired = state.withMemoryState();
Language language = trace.getBaseLanguage();
return new PcodeExecutor<>(language, new PairedPcodeArithmetic<>(
BytesPcodeArithmetic.forLanguage(language),
TraceMemoryStatePcodeArithmetic.INSTANCE), paired);
if (!(language instanceof SleighLanguage)) {
throw new IllegalArgumentException("Trace must use a SLEIGH language");
}
return new PcodeExecutor<>((SleighLanguage) language, new PairedPcodeArithmetic<>(
BytesPcodeArithmetic.forLanguage(language), TraceMemoryStatePcodeArithmetic.INSTANCE),
paired);
}
public static byte[] evaluateBytes(SleighExpression expr, Trace trace, long snap,

View File

@@ -86,7 +86,7 @@ public abstract class AbstractModifiedPcodeThread<T> extends DefaultPcodeThread<
}
protected class GluePcodeThreadExecutor extends PcodeThreadExecutor {
public GluePcodeThreadExecutor(Language language, PcodeArithmetic<T> arithmetic,
public GluePcodeThreadExecutor(SleighLanguage language, PcodeArithmetic<T> arithmetic,
PcodeExecutorStatePiece<T, T> state) {
super(language, arithmetic, state);
}

View File

@@ -57,6 +57,26 @@ public abstract class AbstractPcodeMachine<T> implements PcodeMachine<T> {
this.initializer = getPluggableInitializer(language);
}
@Override
public SleighLanguage getLanguage() {
return language;
}
@Override
public PcodeArithmetic<T> getArithmetic() {
return arithmetic;
}
@Override
public SleighUseropLibrary<T> getUseropLibrary() {
return library;
}
@Override
public SleighUseropLibrary<T> getStubUseropLibrary() {
return stubLibrary;
}
protected abstract PcodeExecutorState<T> createSharedState();
protected abstract PcodeExecutorState<T> createLocalState(PcodeThread<T> thread);

View File

@@ -21,7 +21,8 @@ import java.util.*;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.pcode.exec.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.*;
import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.util.ProgramContextImpl;
@@ -69,7 +70,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
protected class PcodeThreadExecutor extends PcodeExecutor<T> {
volatile boolean suspended = false;
public PcodeThreadExecutor(Language language, PcodeArithmetic<T> arithmetic,
public PcodeThreadExecutor(SleighLanguage language, PcodeArithmetic<T> arithmetic,
PcodeExecutorStatePiece<T, T> state) {
super(language, arithmetic, state);
}

View File

@@ -18,9 +18,9 @@ package ghidra.pcode.emu;
import java.util.Collection;
import java.util.List;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.pcode.emu.DefaultPcodeThread.SleighEmulationLibrary;
import ghidra.pcode.exec.PcodeExecutorState;
import ghidra.pcode.exec.PcodeProgram;
import ghidra.pcode.exec.*;
import ghidra.program.model.address.Address;
/**
@@ -30,6 +30,47 @@ import ghidra.program.model.address.Address;
*/
public interface PcodeMachine<T> {
/**
* Get the machine's SLEIGH language (processor model)
*
* @return the language
*/
SleighLanguage getLanguage();
/**
* Get the arithmetic applied by the machine
*
* @return the arithmetic
*/
PcodeArithmetic<T> getArithmetic();
/**
* Get the userop library common to all threads in the machine.
*
* <p>
* Note that threads may have larger libraries, but each should contain all the userops in this
* library.
*
* @return the userop library
*/
SleighUseropLibrary<T> getUseropLibrary();
/**
* Get a userop library which at least declares all userops available in thread userop
* libraries.
*
* <p>
* Thread userop libraries may have more userops than are defined in the machine's userop
* library. However, to compile SLEIGH programs linked to thread libraries, the thread's userops
* must be known to the compiler. The stub library will name all userops common among the
* threads, even if their definitions vary. <b>WARNING:</b> The stub library is not required to
* provide implementations of the userops. Often they will throw exceptions, so do not attempt
* to use the returned library in an executor.
*
* @return the stub library
*/
SleighUseropLibrary<T> getStubUseropLibrary();
/**
* Create a new thread with a default name in this machine
*

View File

@@ -17,6 +17,7 @@ package ghidra.pcode.emu;
import java.util.List;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.pcode.emu.DefaultPcodeThread.SleighEmulationLibrary;
import ghidra.pcode.exec.*;
import ghidra.program.model.address.Address;
@@ -222,6 +223,24 @@ public interface PcodeThread<T> {
*/
void setSuspended(boolean suspended);
/**
* Get the thread's SLEIGH language (processor model)
*
* @return the language
*/
default SleighLanguage getLanguage() {
return getExecutor().getLanguage();
}
/**
* Get the thread's p-code arithmetic
*
* @return the arithmetic
*/
default PcodeArithmetic<T> getArithmetic() {
return getExecutor().getArithmetic();
}
/**
* Get the thread's p-code executor
*

View File

@@ -24,19 +24,18 @@ import ghidra.pcode.exec.SleighUseropLibrary.SleighUseropDefinition;
import ghidra.pcode.opbehavior.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Register;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
public class PcodeExecutor<T> {
protected final Language language;
protected final SleighLanguage language;
protected final PcodeArithmetic<T> arithmetic;
protected final PcodeExecutorStatePiece<T, T> state;
protected final Register pc;
protected final int pointerSize;
public PcodeExecutor(Language language, PcodeArithmetic<T> arithmetic,
public PcodeExecutor(SleighLanguage language, PcodeArithmetic<T> arithmetic,
PcodeExecutorStatePiece<T, T> state) {
this.language = language;
this.arithmetic = arithmetic;
@@ -46,8 +45,35 @@ public class PcodeExecutor<T> {
this.pointerSize = language.getDefaultSpace().getPointerSize();
}
/**
* Get the executor's SLEIGH language (processor model)
*
* @return the language
*/
public SleighLanguage getLanguage() {
return language;
}
/**
* Get the arithmetic applied by the executor
*
* @return the arithmetic
*/
public PcodeArithmetic<T> getArithmetic() {
return arithmetic;
}
/**
* Get the state bound to this executor
*
* @return the state
*/
public PcodeExecutorStatePiece<T, T> getState() {
return state;
}
public void executeLine(String line) {
PcodeProgram program = SleighProgramCompiler.compileProgram((SleighLanguage) language,
PcodeProgram program = SleighProgramCompiler.compileProgram(language,
"line", List.of(line + ";"), SleighUseropLibrary.NIL);
execute(program, SleighUseropLibrary.nil());
}