GP-2426: Refactor emulator to use trace access shims. Implement register mapping conventions.

This commit is contained in:
Dan
2022-09-13 16:02:02 -04:00
parent 975db1919c
commit e4f18ad824
202 changed files with 8221 additions and 4199 deletions
@@ -21,7 +21,6 @@ import java.util.function.BiFunction;
import org.apache.commons.lang3.StringUtils;
import ghidra.framework.options.*;
import ghidra.framework.options.AutoOptions.*;
import ghidra.framework.options.annotation.AutoOptionConsumed;
import ghidra.framework.options.annotation.AutoOptionDefined;
@@ -20,7 +20,6 @@ import java.util.*;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.framework.plugintool.util.ServiceListener;
import ghidra.util.Msg;
public class AutoServiceListener<R> implements ServiceListener {
@@ -22,6 +22,7 @@ import ghidra.pcode.exec.PcodeArithmetic.Purpose;
import ghidra.pcode.exec.PcodeExecutorState;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.model.mem.MemBuffer;
/**
@@ -44,12 +45,18 @@ public class ThreadPcodeExecutorState<T> implements PcodeExecutorState<T> {
*/
public ThreadPcodeExecutorState(PcodeExecutorState<T> sharedState,
PcodeExecutorState<T> localState) {
assert Objects.equals(sharedState.getLanguage(), localState.getLanguage());
assert Objects.equals(sharedState.getArithmetic(), localState.getArithmetic());
this.sharedState = sharedState;
this.localState = localState;
this.arithmetic = sharedState.getArithmetic();
}
@Override
public Language getLanguage() {
return sharedState.getLanguage();
}
@Override
public PcodeArithmetic<T> getArithmetic() {
return arithmetic;
@@ -42,8 +42,8 @@ import ghidra.program.model.lang.Language;
* guess (or keep up to date) the concrete state piece classes to instantiate.
*
* <p>
* The factory itself should be a singleton object. See the Taint Analyzer for a complete solution
* using this interface.
* The factory itself should be a singleton object. See the Taint Analyzer for a complete example
* solution using this interface.
*
* @param <U> the type of auxiliary values
*/
@@ -127,6 +127,11 @@ public abstract class AbstractLongOffsetPcodeExecutorStatePiece<A, T, S>
uniqueSpace = language.getAddressFactory().getUniqueSpace();
}
@Override
public Language getLanguage() {
return language;
}
@Override
public PcodeArithmetic<A> getAddressArithmetic() {
return addressArithmetic;
@@ -21,6 +21,7 @@ import java.util.Map;
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.model.mem.MemBuffer;
/**
@@ -35,6 +36,7 @@ import ghidra.program.model.mem.MemBuffer;
*/
public class AddressOfPcodeExecutorStatePiece
implements PcodeExecutorStatePiece<byte[], Address> {
private final Language language;
private final BytesPcodeArithmetic addressArithmetic;
private final Map<Long, Address> unique = new HashMap<>();
@@ -43,8 +45,14 @@ public class AddressOfPcodeExecutorStatePiece
*
* @param isBigEndian true if the control language is big endian
*/
public AddressOfPcodeExecutorStatePiece(boolean isBigEndian) {
this.addressArithmetic = BytesPcodeArithmetic.forEndian(isBigEndian);
public AddressOfPcodeExecutorStatePiece(Language language) {
this.language = language;
this.addressArithmetic = BytesPcodeArithmetic.forEndian(language.isBigEndian());
}
@Override
public Language getLanguage() {
return language;
}
@Override
@@ -554,7 +554,10 @@ public abstract class AnnotatedPcodeUseropLibrary<T> implements PcodeUseropLibra
Type opType = getOperandType();
@SuppressWarnings({ "unchecked", "rawtypes" })
Class<? extends AnnotatedPcodeUseropLibrary<T>> cls = (Class) this.getClass();
Set<Method> methods = CACHE_BY_CLASS.computeIfAbsent(cls, __ -> collectDefinitions(cls));
Set<Method> methods;
synchronized (CACHE_BY_CLASS) {
methods = CACHE_BY_CLASS.computeIfAbsent(cls, __ -> collectDefinitions(cls));
}
for (Method m : methods) {
ops.put(m.getName(), AnnotatedPcodeUseropDefinition
.create(m.getAnnotation(PcodeUserop.class), this, opType, lookup, m));
@@ -119,7 +119,7 @@ public class BytesPcodeExecutorStateSpace<B> {
return result;
}
protected Set<Register> getRegs(AddressSet set) {
protected Set<Register> getRegs(AddressSetView set) {
Set<Register> regs = new TreeSet<>();
for (AddressRange rng : set) {
Register r = language.getRegister(rng.getMinAddress(), (int) rng.getLength());
@@ -133,7 +133,7 @@ public class BytesPcodeExecutorStateSpace<B> {
return regs;
}
protected void warnAddressSet(String message, AddressSet set) {
protected void warnAddressSet(String message, AddressSetView set) {
Set<Register> regs = getRegs(set);
if (regs.isEmpty()) {
Msg.warn(this, message + ": " + set);
@@ -18,6 +18,7 @@ package ghidra.pcode.exec;
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.model.mem.MemBuffer;
/**
@@ -45,6 +46,11 @@ public class DefaultPcodeExecutorState<T> implements PcodeExecutorState<T> {
this(piece, piece.getArithmetic());
}
@Override
public Language getLanguage() {
return piece.getLanguage();
}
@Override
public T getVar(AddressSpace space, T offset, int size, boolean quantize) {
return piece.getVar(space, offset, size, quantize);
@@ -20,6 +20,7 @@ import org.apache.commons.lang3.tuple.Pair;
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.model.mem.MemBuffer;
/**
@@ -71,6 +72,11 @@ public class PairedPcodeExecutorState<L, R> implements PcodeExecutorState<Pair<L
this(left, right, new PairedPcodeArithmetic<>(left.getArithmetic(), right.getArithmetic()));
}
@Override
public Language getLanguage() {
return piece.getLanguage();
}
@Override
public PcodeArithmetic<Pair<L, R>> getArithmetic() {
return arithmetic;
@@ -20,6 +20,7 @@ import org.apache.commons.lang3.tuple.Pair;
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Language;
import ghidra.program.model.mem.MemBuffer;
/**
@@ -70,6 +71,11 @@ public class PairedPcodeExecutorStatePiece<A, L, R>
new PairedPcodeArithmetic<>(left.getArithmetic(), right.getArithmetic()));
}
@Override
public Language getLanguage() {
return left.getLanguage();
}
@Override
public PcodeArithmetic<A> getAddressArithmetic() {
return addressArithmetic;
@@ -17,6 +17,7 @@ package ghidra.pcode.exec;
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Register;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.pcode.Varnode;
@@ -55,6 +56,13 @@ public interface PcodeExecutorStatePiece<A, T> {
}
}
/**
* Get the language defining the address spaces of this state piece
*
* @return the language
*/
Language getLanguage();
/**
* Get the arithmetic used to manipulate addresses of the type used by this state
*
@@ -21,9 +21,6 @@ import java.nio.ByteOrder;
import org.apache.commons.lang3.ArrayUtils;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.MemoryAccessException;
public interface MemBufferAdapter extends MemBuffer {
int getBytes(ByteBuffer buffer, int addressOffset);