GT-3196 correct pcode emit for fall-through override

This commit is contained in:
ghidra1 2019-09-30 10:38:28 -04:00
parent 66299066e2
commit 7335ccd191
2 changed files with 37 additions and 0 deletions

View file

@ -185,6 +185,34 @@ public abstract class PcodeEmit {
*/
public abstract void resolveRelatives();
/**
* Now that all pcode has been generated, including special
* overrides and injections, ensure that a fallthrough override
* adds a final branch to prevent dropping out the bottom. This
* addresses both fall-through cases:
* <ul>
* <li>last pcode op has fall-through</li>
* <li>internal label used to branch beyond last pcode op</li>
* </ul>
*/
void resolveFinalFallthrough() {
try {
if (fallOverride == null || fallOverride.equals(getStartAddress().add(fallOffset))) {
return;
}
}
catch (AddressOutOfBoundsException e) {
// ignore
}
VarnodeData dest = new VarnodeData();
dest.space = fallOverride.getAddressSpace().getPhysicalSpace();
dest.offset = fallOverride.getOffset();
dest.size = dest.space.getPointerSize();
dump(startAddress, PcodeOp.BRANCH, new VarnodeData[] { dest }, 1, null);
}
abstract void dump(Address instrAddr, int opcode, VarnodeData[] in, int isize, VarnodeData out);
private boolean dumpBranchOverride(OpTpl opt) {

View file

@ -968,6 +968,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
new PcodeEmitObjects(walker, context, fallOffset, override, uniqueFactory);
emit.build(walker.getConstructor().getTempl(), -1);
emit.resolveRelatives();
if (!isindelayslot) {
emit.resolveFinalFallthrough();
}
protoContext.setDelaySlotLength(0);
return emit.getPcodeOp();
}
@ -1016,6 +1019,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
emit.build(walker.getConstructor().getTempl(), -1);
emit.resolveRelatives();
if (!isindelayslot) {
emit.resolveFinalFallthrough();
}
protoContext.setDelaySlotLength(0);
emit.write(PcodeEmitPacked.end_tag); // Terminate the inst_tag
return emit.getPackedBytes();
@ -1048,6 +1054,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
PcodeEmitObjects emit = new PcodeEmitObjects(walker);
emit.build(walker.getConstructor().getTempl(), -1);
emit.resolveRelatives();
if (!isindelayslot) {
emit.resolveFinalFallthrough();
}
return emit.getPcodeOp();
}
}