diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java index 71e3efcd05..3762dcb91b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java @@ -63,7 +63,7 @@ public class SymbolicPropogator { protected boolean readExecutableAddress; protected VarnodeContext context; - protected AddressSet body; // body of processed instructions + protected AddressSet visitedBody; // body of processed instructions protected boolean hitCodeFlow = false; // no branching so far protected boolean debug = false; @@ -409,7 +409,7 @@ public class SymbolicPropogator { public AddressSet flowConstants(Address fromAddr, Address startAddr, AddressSetView restrictSet, ContextEvaluator eval, VarnodeContext vContext, TaskMonitor monitor) throws CancelledException { - body = new AddressSet(); + visitedBody = new AddressSet(); AddressSet conflicts = new AddressSet(); // prime the context stack with the entry point address @@ -425,8 +425,8 @@ public class SymbolicPropogator { while (!contextStack.isEmpty()) { monitor.checkCancelled(); if (canceled) { - body.add(conflicts); // put the conflict/redone addresses back in - return body; + visitedBody.add(conflicts); // put the conflict/redone addresses back in + return visitedBody; } // if we run into a flow that has already been done, flow until @@ -440,7 +440,7 @@ public class SymbolicPropogator { nextFlow.restoreState(vContext); // already done it! - if (body.contains(nextAddr)) { + if (visitedBody.contains(nextAddr)) { // allow it to keep flowing until the next branch/call/ret flow! hitOtherFlow = true; if (!continueAfterHittingFlow) { @@ -461,7 +461,7 @@ public class SymbolicPropogator { monitor.checkCancelled(); // already done it! - if (body.contains(nextAddr)) { + if (visitedBody.contains(nextAddr)) { // allow it to keep flowing until the next branch/call/ret flow! hitOtherFlow = true; if (!continueAfterHittingFlow) { @@ -499,8 +499,8 @@ public class SymbolicPropogator { if (evaluator != null) { if (evaluator.evaluateContextBefore(vContext, instr)) { - body.add(conflicts); // put the conflict/redone addresses back in - return body; + visitedBody.add(conflicts); // put the conflict/redone addresses back in + return visitedBody; } } @@ -510,7 +510,7 @@ public class SymbolicPropogator { Address retAddr = applyPcode(vContext, instr, monitor); // add this instruction to processed body set - body.addRange(minInstrAddress, maxAddr); + visitedBody.addRange(minInstrAddress, maxAddr); /* Allow evaluateContext routine to change override the flowtype of an instruction. * Jumps Changed to calls will now continue processing. @@ -519,8 +519,8 @@ public class SymbolicPropogator { */ if (evaluator != null) { if (evaluator.evaluateContext(vContext, instr)) { - body.add(conflicts); // put the conflict/redone addresses back in - return body; + visitedBody.add(conflicts); // put the conflict/redone addresses back in + return visitedBody; } } @@ -533,7 +533,7 @@ public class SymbolicPropogator { } } - Address inlineCall = null; + Address callFlowAddr = null; boolean simpleFlow = isSimpleFallThrough(instrFlow); // once we encounter any flow, must set the hitCodeFlow flag @@ -568,7 +568,7 @@ public class SymbolicPropogator { } } else { - inlineCall = flows[0]; + callFlowAddr = flows[0]; } } else if (instrFlow.isComputed() && instrFlow.isCall()) { @@ -577,12 +577,17 @@ public class SymbolicPropogator { } } - if (inlineCall != null) { - Function func = program.getFunctionManager().getFunctionAt(inlineCall); + if (callFlowAddr != null) { + Function func = program.getFunctionManager().getFunctionAt(callFlowAddr); if (func != null && func.isInline()) { - vContext.mergeToFutureFlowState(maxAddr, inlineCall); + vContext.mergeToFutureFlowState(maxAddr, callFlowAddr); vContext.flowEnd(maxAddr); - flowConstants(maxAddr, inlineCall, func.getBody(), eval, vContext, monitor); + // Body will get re-initialized. + // The inlined function may be called multiple times, so body of inlined function + // should not be included in the already visited body. + AddressSet savedBody = visitedBody; + flowConstants(maxAddr, callFlowAddr, func.getBody(), eval, vContext, monitor); + visitedBody = savedBody; vContext.mergeToFutureFlowState(minInstrAddress, maxAddr); // @@ -641,8 +646,8 @@ public class SymbolicPropogator { vContext.flowEnd(maxAddr); } - body.add(conflicts); // put the conflict/redone addresses back in - return body; + visitedBody.add(conflicts); // put the conflict/redone addresses back in + return visitedBody; } private boolean isSimpleFallThrough(FlowType instrFlow) { @@ -2200,7 +2205,7 @@ public class SymbolicPropogator { for (Reference ref : refs) { Address refAddr = ref.getToAddress(); Address addr = refAddr.getAddressSpace().getTruncatedAddress(val, true); - if (ref.getReferenceType() == RefType.PARAM && !body.contains(ref.getFromAddress())) { + if (ref.getReferenceType() == RefType.PARAM && !visitedBody.contains(ref.getFromAddress())) { // if reference address is not in body yet, this is the first time at this location // get rid of the reference, reference could be changed to new AddressSpace or value instr.removeOperandReference(ref.getOperandIndex(), refAddr);