mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-10-23 13:41:04 +00:00
GP-3962 Fix for test failures from delayslot with branches flow
following, also fixed backward flow following through delayslots with branches
This commit is contained in:
parent
041be82286
commit
00bbee3163
|
@ -175,7 +175,7 @@ public class FollowDelaySlotFlowTest extends AbstractFollowFlowTest {
|
|||
AddressSet flowAddresses = followFlow.getFlowAddressSet(TaskMonitor.DUMMY);
|
||||
|
||||
AddressSet expectedAddresses = new AddressSet();
|
||||
expectedAddresses.add(address(10), address(15));
|
||||
expectedAddresses.add(address(10), address(17));
|
||||
expectedAddresses.add(address(20), address(25));
|
||||
|
||||
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||
|
@ -580,7 +580,7 @@ public class FollowDelaySlotFlowTest extends AbstractFollowFlowTest {
|
|||
AddressSet flowAddresses = followFlow.getFlowToAddressSet(TaskMonitor.DUMMY);
|
||||
|
||||
AddressSet expectedAddresses = new AddressSet();
|
||||
expectedAddresses.add(address(16), address(17));
|
||||
expectedAddresses.add(address(14), address(17));
|
||||
|
||||
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ public class InstructionDB extends CodeUnitDB implements Instruction, Instructio
|
|||
}
|
||||
|
||||
do {
|
||||
// skip past delay slot instructions
|
||||
// skip past delay slot instructions which satisfy specific conditions
|
||||
try {
|
||||
instr = program.getListing()
|
||||
.getInstructionContaining(
|
||||
|
@ -229,28 +229,31 @@ public class InstructionDB extends CodeUnitDB implements Instruction, Instructio
|
|||
catch (AddressOverflowException e) {
|
||||
return null;
|
||||
}
|
||||
// if an instruction is in a delay slot and has references to it,
|
||||
// consider this the fallfrom instruction
|
||||
if (instr != null && instr.isInDelaySlot() && instr.hasFallthrough()) {
|
||||
if (program.getSymbolTable().hasSymbol(instr.getMinAddress())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (instr != null && instr.isInDelaySlot());
|
||||
// Continue walking instructions backwards if a delay-slot instruction is found and
|
||||
// either the delay slot instruction does not fallthrough or it does not have a
|
||||
// ref or label on it.
|
||||
while (instr != null && instr.isInDelaySlot() &&
|
||||
(!instr.hasFallthrough() ||
|
||||
!program.getSymbolTable().hasSymbol(instr.getMinAddress())));
|
||||
|
||||
if (instr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If this instruction is in a delay slot,
|
||||
// it is assumed to always fall from the delay-slotted
|
||||
// instruction regardless of its fall-through
|
||||
if (this.isInDelaySlot()) {
|
||||
// If this instruction is within delay-slot, return a null fall-from address if
|
||||
// previous instruction (i.e., instruction with delay slot, found above)
|
||||
// does not have a fallthrough and this instruction has a ref or label on it.
|
||||
if (!instr.hasFallthrough() &&
|
||||
program.getSymbolTable().hasSymbol(this.getMinAddress())) {
|
||||
return null;
|
||||
}
|
||||
// Return previous instruction's address (i.e., instruction with delay slot, found above)
|
||||
return instr.getMinAddress();
|
||||
}
|
||||
|
||||
// No delay slot, but check if the instruction falls into this one.
|
||||
// No delay-slot, but check if the instruction falls into this one.
|
||||
Address fallAddr = instr.getFallThrough();
|
||||
if (fallAddr != null && fallAddr.equals(address)) {
|
||||
return instr.getMinAddress();
|
||||
|
|
|
@ -143,6 +143,29 @@ public interface Instruction extends CodeUnit, ProcessorContext {
|
|||
* this instruction.
|
||||
* This is useful for handling instructions that are found
|
||||
* in a delay slot.
|
||||
*
|
||||
* Note: if an instruction is in a delayslot, then it may have
|
||||
* a branch into the delayslot, which is handled as follows
|
||||
*
|
||||
* <pre>
|
||||
* JMPIF Y, X
|
||||
* lab:
|
||||
* _ADD getFallFrom() = JMPIF
|
||||
* MOV getFallFrom() = _ADD
|
||||
*
|
||||
* JMP Y, X
|
||||
* lab:
|
||||
* _ADD getFallFrom() = null
|
||||
* MOV getFallFrom() = _ADD
|
||||
*
|
||||
* JMPIF Y, X
|
||||
* _ADD getFallFrom() = JMPIF
|
||||
* MOV getFallFrom() = JMPIF
|
||||
*
|
||||
* JMP Y, X
|
||||
* _ADD getFallFrom() = JMP
|
||||
* MOV getFallFrom() = null
|
||||
*</pre>
|
||||
*/
|
||||
public Address getFallFrom();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user