GP-3067: Changes in anticipation of GP-2038.

This commit is contained in:
Dan 2023-01-30 14:59:49 -05:00
parent 9014d10edf
commit b8e1808cb8
7 changed files with 44 additions and 36 deletions

View file

@ -310,7 +310,7 @@ public class VariableValueHoverService extends AbstractConfigurableHover
} }
if (variable != null) { if (variable != null) {
return fillFrameStorage(frame, variable.getName(), variable.getDataType(), return fillFrameStorage(frame, variable.getName(), variable.getDataType(),
variable.getVariableStorage()); variable.getProgram(), variable.getVariableStorage());
} }
Address dynAddr = frame.getBasePointer().add(stackAddress.getOffset()); Address dynAddr = frame.getBasePointer().add(stackAddress.getOffset());
TraceCodeUnit unit = current.getTrace() TraceCodeUnit unit = current.getTrace()
@ -377,7 +377,7 @@ public class VariableValueHoverService extends AbstractConfigurableHover
if (variable != null) { if (variable != null) {
return fillFrameStorage(frame, variable.getName(), variable.getDataType(), return fillFrameStorage(frame, variable.getName(), variable.getDataType(),
variable.getVariableStorage()); variable.getProgram(), variable.getVariableStorage());
} }
if (frame.getLevel() == 0) { if (frame.getLevel() == 0) {
@ -418,16 +418,17 @@ public class VariableValueHoverService extends AbstractConfigurableHover
} }
public CompletableFuture<VariableValueTable> fillStorage(Function function, String name, public CompletableFuture<VariableValueTable> fillStorage(Function function, String name,
DataType type, VariableStorage storage, AddressSetView symbolStorage) { DataType type, Program program, VariableStorage storage,
AddressSetView symbolStorage) {
return executeBackground(monitor -> { return executeBackground(monitor -> {
UnwoundFrame<WatchValue> frame = UnwoundFrame<WatchValue> frame =
VariableValueUtils.requiresFrame(storage, symbolStorage) VariableValueUtils.requiresFrame(program, storage, symbolStorage)
? eval.getStackFrame(function, warnings, monitor) ? eval.getStackFrame(function, warnings, monitor)
: eval.getGlobalsFakeFrame(); : eval.getGlobalsFakeFrame();
if (frame == null) { if (frame == null) {
throw new UnwindException("Cannot find frame for " + function); throw new UnwindException("Cannot find frame for " + function);
} }
return fillFrameStorage(frame, name, type, storage); return fillFrameStorage(frame, name, type, program, storage);
}); });
} }
@ -459,14 +460,14 @@ public class VariableValueHoverService extends AbstractConfigurableHover
} }
public VariableValueTable fillFrameStorage(UnwoundFrame<WatchValue> frame, String name, public VariableValueTable fillFrameStorage(UnwoundFrame<WatchValue> frame, String name,
DataType type, VariableStorage storage) { DataType type, Program program, VariableStorage storage) {
table.add(new NameRow(name)); table.add(new NameRow(name));
if (!frame.isFake()) { if (!frame.isFake()) {
table.add(new FrameRow(frame)); table.add(new FrameRow(frame));
} }
table.add(new StorageRow(storage)); table.add(new StorageRow(storage));
table.add(new TypeRow(type)); table.add(new TypeRow(type));
WatchValue value = frame.getValue(storage); WatchValue value = frame.getValue(program, storage);
return fillWatchValue(frame, storage.getMinAddress(), type, value); return fillWatchValue(frame, storage.getMinAddress(), type, value);
} }
@ -486,8 +487,7 @@ public class VariableValueHoverService extends AbstractConfigurableHover
} }
public CompletableFuture<VariableValueTable> fillHighVariable(HighVariable hVar, public CompletableFuture<VariableValueTable> fillHighVariable(HighVariable hVar,
String name, String name, AddressSetView symbolStorage) {
AddressSetView symbolStorage) {
Function function = hVar.getHighFunction().getFunction(); Function function = hVar.getHighFunction().getFunction();
VariableStorage storage = VariableValueUtils.fabricateStorage(hVar); VariableStorage storage = VariableValueUtils.fabricateStorage(hVar);
if (storage.isUniqueStorage()) { if (storage.isUniqueStorage()) {
@ -496,7 +496,8 @@ public class VariableValueHoverService extends AbstractConfigurableHover
table.add(new ValueRow("(Unique)", TraceMemoryState.KNOWN)); table.add(new ValueRow("(Unique)", TraceMemoryState.KNOWN));
return CompletableFuture.completedFuture(table); return CompletableFuture.completedFuture(table);
} }
return fillStorage(function, name, hVar.getDataType(), storage, symbolStorage); return fillStorage(function, name, hVar.getDataType(), function.getProgram(), storage,
symbolStorage);
} }
public CompletableFuture<VariableValueTable> fillHighVariable(HighVariable hVar, public CompletableFuture<VariableValueTable> fillHighVariable(HighVariable hVar,
@ -521,7 +522,7 @@ public class VariableValueHoverService extends AbstractConfigurableHover
public CompletableFuture<VariableValueTable> fillComposite(HighSymbol hSym, public CompletableFuture<VariableValueTable> fillComposite(HighSymbol hSym,
HighVariable hVar, AddressSetView symbolStorage) { HighVariable hVar, AddressSetView symbolStorage) {
return fillStorage(hVar.getHighFunction().getFunction(), hSym.getName(), return fillStorage(hVar.getHighFunction().getFunction(), hSym.getName(),
hSym.getDataType(), hSym.getStorage(), symbolStorage); hSym.getDataType(), hSym.getProgram(), hSym.getStorage(), symbolStorage);
} }
public CompletableFuture<VariableValueTable> fillToken(ClangToken token) { public CompletableFuture<VariableValueTable> fillToken(ClangToken token) {
@ -582,7 +583,7 @@ public class VariableValueHoverService extends AbstractConfigurableHover
throw new UnwindException("Cannot find frame for " + function); throw new UnwindException("Cannot find frame for " + function);
} }
return fillFrameStorage(frame, variable.getName(), variable.getDataType(), return fillFrameStorage(frame, variable.getName(), variable.getDataType(),
variable.getVariableStorage()); variable.getProgram(), variable.getVariableStorage());
}); });
} }
} }

View file

@ -159,8 +159,8 @@ public enum VariableValueUtils {
} }
@Override @Override
public Boolean evaluateStorage(VariableStorage storage) { public Boolean evaluateStorage(Program program, VariableStorage storage) {
return evaluateStorage(storage, false); return evaluateStorage(program, storage, false);
} }
} }
@ -347,13 +347,15 @@ public enum VariableValueUtils {
/** /**
* Check if evaluation of the given storage will require a frame * Check if evaluation of the given storage will require a frame
* *
* @param program the program containing the variable storage
* @param storage the storage to evaluate * @param storage the storage to evaluate
* @param symbolStorage the leaves of evaluation, usually storage used by symbols in scope. See * @param symbolStorage the leaves of evaluation, usually storage used by symbols in scope. See
* {@link #collectSymbolStorage(ClangLine)} * {@link #collectSymbolStorage(ClangLine)}
* @return true if a frame is required, false otherwise * @return true if a frame is required, false otherwise
*/ */
public static boolean requiresFrame(VariableStorage storage, AddressSetView symbolStorage) { public static boolean requiresFrame(Program program, VariableStorage storage,
return new RequiresFrameEvaluator(symbolStorage).evaluateStorage(storage); AddressSetView symbolStorage) {
return new RequiresFrameEvaluator(symbolStorage).evaluateStorage(program, storage);
} }
/** /**

View file

@ -271,14 +271,14 @@ public abstract class AbstractUnwoundFrame<T> implements UnwoundFrame<T> {
protected abstract Address applyBase(long offset); protected abstract Address applyBase(long offset);
@Override @Override
public T getValue(VariableStorage storage) { public T getValue(Program program, VariableStorage storage) {
SavedRegisterMap registerMap = computeRegisterMap(); SavedRegisterMap registerMap = computeRegisterMap();
return new FrameVarnodeValueGetter<T>(state.getArithmetic()) { return new FrameVarnodeValueGetter<T>(state.getArithmetic()) {
@Override @Override
protected T evaluateMemory(Address address, int size) { protected T evaluateMemory(Address address, int size) {
return registerMap.getVar(state, address, size, Reason.INSPECT); return registerMap.getVar(state, address, size, Reason.INSPECT);
} }
}.evaluateStorage(storage); }.evaluateStorage(program, storage);
} }
@Override @Override
@ -289,14 +289,14 @@ public abstract class AbstractUnwoundFrame<T> implements UnwoundFrame<T> {
} }
@Override @Override
public T evaluate(VariableStorage storage, AddressSetView symbolStorage) { public T evaluate(Program program, VariableStorage storage, AddressSetView symbolStorage) {
SavedRegisterMap registerMap = computeRegisterMap(); SavedRegisterMap registerMap = computeRegisterMap();
return new FrameVarnodeEvaluator<T>(state.getArithmetic(), symbolStorage) { return new FrameVarnodeEvaluator<T>(state.getArithmetic(), symbolStorage) {
@Override @Override
protected T evaluateMemory(Address address, int size) { protected T evaluateMemory(Address address, int size) {
return registerMap.getVar(state, address, size, Reason.INSPECT); return registerMap.getVar(state, address, size, Reason.INSPECT);
} }
}.evaluateStorage(storage); }.evaluateStorage(program, storage);
} }
@Override @Override
@ -311,8 +311,8 @@ public abstract class AbstractUnwoundFrame<T> implements UnwoundFrame<T> {
} }
@Override @Override
public CompletableFuture<Void> setValue(StateEditor editor, VariableStorage storage, public CompletableFuture<Void> setValue(StateEditor editor, Program program,
BigInteger value) { VariableStorage storage, BigInteger value) {
SavedRegisterMap registerMap = computeRegisterMap(); SavedRegisterMap registerMap = computeRegisterMap();
ByteBuffer buf = ByteBuffer.wrap(Utils.bigIntegerToBytes(value, storage.size(), true)); ByteBuffer buf = ByteBuffer.wrap(Utils.bigIntegerToBytes(value, storage.size(), true));
AsyncFence fence = new AsyncFence(); AsyncFence fence = new AsyncFence();
@ -334,10 +334,10 @@ public abstract class AbstractUnwoundFrame<T> implements UnwoundFrame<T> {
} }
@Override @Override
public ByteBuffer evaluateStorage(VariableStorage storage) { public ByteBuffer evaluateStorage(Program program, VariableStorage storage) {
return evaluateStorage(storage, buf); return evaluateStorage(program, storage, buf);
} }
}.evaluateStorage(storage); }.evaluateStorage(program, storage);
return fence.ready(); return fence.ready();
} }

View file

@ -149,10 +149,11 @@ public interface UnwoundFrame<T> {
* <b>WARNING:</b> Never invoke this method from the Swing thread. The state could be associated * <b>WARNING:</b> Never invoke this method from the Swing thread. The state could be associated
* with a live session, and this may block to retrieve live state. * with a live session, and this may block to retrieve live state.
* *
* @param program the program containing the variable storage
* @param storage the storage * @param storage the storage
* @return the value * @return the value
*/ */
T getValue(VariableStorage storage); T getValue(Program program, VariableStorage storage);
/** /**
* Get the value of the variable from the frame * Get the value of the variable from the frame
@ -166,7 +167,7 @@ public interface UnwoundFrame<T> {
* @return the value * @return the value
*/ */
default T getValue(Variable variable) { default T getValue(Variable variable) {
return getValue(variable.getVariableStorage()); return getValue(variable.getProgram(), variable.getVariableStorage());
} }
/** /**
@ -198,11 +199,12 @@ public interface UnwoundFrame<T> {
* with a live session, and this may block to retrieve live state. * with a live session, and this may block to retrieve live state.
* *
* @see VariableValueUtils#collectSymbolStorage(ClangLine) * @see VariableValueUtils#collectSymbolStorage(ClangLine)
* @param program the program containing the variable storage
* @param storage the storage to evaluate * @param storage the storage to evaluate
* @param symbolStorage the terminal storage, usually that of symbols * @param symbolStorage the terminal storage, usually that of symbols
* @return the value * @return the value
*/ */
T evaluate(VariableStorage storage, AddressSetView symbolStorage); T evaluate(Program program, VariableStorage storage, AddressSetView symbolStorage);
/** /**
* Evaluate the output for the given p-code op, ascending until symbol storage is reached * Evaluate the output for the given p-code op, ascending until symbol storage is reached
@ -227,11 +229,13 @@ public interface UnwoundFrame<T> {
* stack. * stack.
* *
* @param editor the editor for setting values * @param editor the editor for setting values
* @param program the program containing the variable storage
* @param storage the storage to modify * @param storage the storage to modify
* @param value the desired value * @param value the desired value
* @return a future which completes when the necessary commands have all completed * @return a future which completes when the necessary commands have all completed
*/ */
CompletableFuture<Void> setValue(StateEditor editor, VariableStorage storage, BigInteger value); CompletableFuture<Void> setValue(StateEditor editor, Program program, VariableStorage storage,
BigInteger value);
/** /**
* Set the value of the given variable * Set the value of the given variable
@ -244,7 +248,7 @@ public interface UnwoundFrame<T> {
*/ */
default CompletableFuture<Void> setValue(StateEditor editor, Variable variable, default CompletableFuture<Void> setValue(StateEditor editor, Variable variable,
BigInteger value) { BigInteger value) {
return setValue(editor, variable.getVariableStorage(), value); return setValue(editor, variable.getProgram(), variable.getVariableStorage(), value);
} }
/** /**

View file

@ -187,12 +187,12 @@ public abstract class AbstractVarnodeEvaluator<T> implements VarnodeEvaluator<T>
/** /**
* Evaluate variable storage, providing an "identity" value * Evaluate variable storage, providing an "identity" value
* *
* @param program the program containing the variable storage
* @param storage the storage to evaluate * @param storage the storage to evaluate
* @param identity the value if storage had no varnodes * @param identity the value if storage had no varnodes
* @return the value of the storage * @return the value of the storage
*/ */
protected T evaluateStorage(VariableStorage storage, T identity) { protected T evaluateStorage(Program program, VariableStorage storage, T identity) {
Program program = storage.getProgram();
int total = storage.size(); int total = storage.size();
T value = identity; T value = identity;
for (Varnode vn : storage.getVarnodes()) { for (Varnode vn : storage.getVarnodes()) {

View file

@ -17,7 +17,7 @@ package ghidra.pcode.eval;
import java.util.Map; import java.util.Map;
import ghidra.pcode.exec.*; import ghidra.pcode.exec.PcodeArithmetic;
import ghidra.pcode.exec.PcodeArithmetic.Purpose; import ghidra.pcode.exec.PcodeArithmetic.Purpose;
import ghidra.pcode.opbehavior.BinaryOpBehavior; import ghidra.pcode.opbehavior.BinaryOpBehavior;
import ghidra.pcode.opbehavior.UnaryOpBehavior; import ghidra.pcode.opbehavior.UnaryOpBehavior;
@ -75,8 +75,8 @@ public abstract class ArithmeticVarnodeEvaluator<T> extends AbstractVarnodeEvalu
} }
@Override @Override
public T evaluateStorage(VariableStorage storage) { public T evaluateStorage(Program program, VariableStorage storage) {
return evaluateStorage(storage, arithmetic.fromConst(0, storage.size())); return evaluateStorage(program, storage, arithmetic.fromConst(0, storage.size()));
} }
@Override @Override

View file

@ -50,10 +50,11 @@ public interface VarnodeEvaluator<T> {
* concatenated. The lower-indexed varnodes in storage are the more significant pieces, similar * concatenated. The lower-indexed varnodes in storage are the more significant pieces, similar
* to big endian. * to big endian.
* *
* @param program the program containing the variable storage
* @param storage the storage * @param storage the storage
* @return the value of the storage * @return the value of the storage
*/ */
T evaluateStorage(VariableStorage storage); T evaluateStorage(Program program, VariableStorage storage);
/** /**
* Evaluate a high p-code op * Evaluate a high p-code op