Merge remote-trackng branch 'origin/patch'

This commit is contained in:
Ryan Kurtz 2025-03-25 06:27:58 -04:00
commit 01652d9ba1
4 changed files with 119 additions and 10 deletions

View file

@ -474,7 +474,7 @@ public class PcodeExecutor<T> {
}
else {
branchToOffset(op, target.getOffset(), frame);
branchToAddress(op, target);
branchToAddress(op, checkInjectedTarget(target));
}
}
@ -530,6 +530,28 @@ public class PcodeExecutor<T> {
return op.getInput(0);
}
/**
* Check and correct the given target address, if it resides in "NO ADDRESS" space.
*
* <p>
* At some point, we made a change to set the "target address" of compiled p-code userops to
* {@link Address#NO_ADDRESS} instead of pretending its at {@code ram:00000000}. This is
* philosophically cleaner, but leads to a practical issue in that the p-code compiler sets the
* target address of any branch to be in the same space, which for injects, will wind up in "NO
* ADDRESS." I don't know the use case for having target addresses anywhere but default space,
* so I'll maintain that behavior, but if it ever lands in "NO ADDRESS," we're going to assume
* it was an inject, and that the intended target was the default space.
*
* @param target the proposed target address
* @return the same or corrected target address
*/
protected Address checkInjectedTarget(Address target) {
if (target.getAddressSpace() != Address.NO_ADDRESS.getAddressSpace()) {
return target;
}
return language.getDefaultSpace().getAddress(target.getOffset());
}
/**
* Perform the actual logic of an indirect branch p-code op
*
@ -548,7 +570,7 @@ public class PcodeExecutor<T> {
long concrete = arithmetic.toLong(offset, Purpose.BRANCH);
Address target = op.getSeqnum().getTarget().getNewAddress(concrete, true);
branchToAddress(op, target);
branchToAddress(op, checkInjectedTarget(target));
}
/**
@ -576,7 +598,7 @@ public class PcodeExecutor<T> {
public void executeCall(PcodeOp op, PcodeFrame frame, PcodeUseropLibrary<T> library) {
Address target = getBranchTarget(op);
branchToOffset(op, target.getOffset(), frame);
branchToAddress(op, target);
branchToAddress(op, checkInjectedTarget(target));
}
/**

View file

@ -21,6 +21,7 @@ import java.util.stream.Collectors;
import ghidra.app.plugin.processors.sleigh.*;
import ghidra.app.plugin.processors.sleigh.template.ConstructTpl;
import ghidra.app.plugin.processors.sleigh.template.OpTpl;
import ghidra.pcode.utils.MessageFormattingUtils;
import ghidra.pcodeCPort.pcoderaw.VarnodeData;
import ghidra.pcodeCPort.sleighbase.SleighBase;
@ -149,6 +150,9 @@ public enum SleighProgramCompiler {
*/
public static ConstructTpl compileTemplate(Language language, PcodeParser parser,
String sourceName, String source) {
if (source.isBlank()) {
return new ConstructTpl(new OpTpl[] {});
}
return parser.compilePcode(source, sourceName, 1);
}
@ -285,7 +289,8 @@ public enum SleighProgramCompiler {
* evaluator p-code program uses its own library as a means of capturing the result; however,
* userop libraries are easily composed. It should be easy to add that feature if needed.
*
* @param language the languge of the target p-code machine
* @param parser a parser for the given language
* @param language the language of the target p-code machine
* @param expression the Sleigh expression to be evaluated
* @return a p-code program whose {@link PcodeExpression#evaluate(PcodeExecutor)} method will
* evaluate the expression on the given executor and its state.