mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-3067: Changes in anticipation of GP-2038.
This commit is contained in:
parent
9014d10edf
commit
b8e1808cb8
7 changed files with 44 additions and 36 deletions
|
@ -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());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue