mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GT-3196 correct pcode emit for fall-through override
This commit is contained in:
parent
66299066e2
commit
7335ccd191
2 changed files with 37 additions and 0 deletions
|
@ -185,6 +185,34 @@ public abstract class PcodeEmit {
|
||||||
*/
|
*/
|
||||||
public abstract void resolveRelatives();
|
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);
|
abstract void dump(Address instrAddr, int opcode, VarnodeData[] in, int isize, VarnodeData out);
|
||||||
|
|
||||||
private boolean dumpBranchOverride(OpTpl opt) {
|
private boolean dumpBranchOverride(OpTpl opt) {
|
||||||
|
|
|
@ -968,6 +968,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
|
||||||
new PcodeEmitObjects(walker, context, fallOffset, override, uniqueFactory);
|
new PcodeEmitObjects(walker, context, fallOffset, override, uniqueFactory);
|
||||||
emit.build(walker.getConstructor().getTempl(), -1);
|
emit.build(walker.getConstructor().getTempl(), -1);
|
||||||
emit.resolveRelatives();
|
emit.resolveRelatives();
|
||||||
|
if (!isindelayslot) {
|
||||||
|
emit.resolveFinalFallthrough();
|
||||||
|
}
|
||||||
protoContext.setDelaySlotLength(0);
|
protoContext.setDelaySlotLength(0);
|
||||||
return emit.getPcodeOp();
|
return emit.getPcodeOp();
|
||||||
}
|
}
|
||||||
|
@ -1016,6 +1019,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
|
||||||
|
|
||||||
emit.build(walker.getConstructor().getTempl(), -1);
|
emit.build(walker.getConstructor().getTempl(), -1);
|
||||||
emit.resolveRelatives();
|
emit.resolveRelatives();
|
||||||
|
if (!isindelayslot) {
|
||||||
|
emit.resolveFinalFallthrough();
|
||||||
|
}
|
||||||
protoContext.setDelaySlotLength(0);
|
protoContext.setDelaySlotLength(0);
|
||||||
emit.write(PcodeEmitPacked.end_tag); // Terminate the inst_tag
|
emit.write(PcodeEmitPacked.end_tag); // Terminate the inst_tag
|
||||||
return emit.getPackedBytes();
|
return emit.getPackedBytes();
|
||||||
|
@ -1048,6 +1054,9 @@ public class SleighInstructionPrototype implements InstructionPrototype {
|
||||||
PcodeEmitObjects emit = new PcodeEmitObjects(walker);
|
PcodeEmitObjects emit = new PcodeEmitObjects(walker);
|
||||||
emit.build(walker.getConstructor().getTempl(), -1);
|
emit.build(walker.getConstructor().getTempl(), -1);
|
||||||
emit.resolveRelatives();
|
emit.resolveRelatives();
|
||||||
|
if (!isindelayslot) {
|
||||||
|
emit.resolveFinalFallthrough();
|
||||||
|
}
|
||||||
return emit.getPcodeOp();
|
return emit.getPcodeOp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue