From 2ef4843e7076bdd9d1d830ab4be962acefb65235 Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Fri, 28 Feb 2020 12:13:34 -0500 Subject: [PATCH] more subvariable extension pushes --- .../Decompiler/src/decompile/cpp/subflow.cc | 32 ++++++++++++++----- .../Decompiler/src/decompile/cpp/subflow.hh | 1 + 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc index 9d9f76679c..42d1b44312 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.cc @@ -301,10 +301,7 @@ bool SubvariableFlow::tryCallReturnPush(PcodeOp *op,ReplaceVarnode *rvn) if (fc->isOutputLocked()) return false; if (fc->isOutputActive()) return false; // Don't trim while in the middle of figuring out return value - patchlist.push_front(PatchRecord()); // Push to the front of the patch list - patchlist.front().type = PatchRecord::push_patch; - patchlist.front().patchOp = op; - patchlist.front().in1 = rvn; + addPush(op,rvn); // pullcount += 1; // This is a push NOT a pull return true; } @@ -655,10 +652,7 @@ bool SubvariableFlow::traceBackward(ReplaceVarnode *rvn) case CPUI_INT_SEXT: if ((rvn->mask & calc_mask(op->getIn(0)->getSize())) != rvn->mask) { if ((rvn->mask & 1)!=0 && flowsize > op->getIn(0)->getSize()) { - patchlist.push_front(PatchRecord()); // Push to the front of the patch list - patchlist.front().type = PatchRecord::push_patch; - patchlist.front().patchOp = op; - patchlist.front().in1 = rvn; + addPush(op,rvn); return true; } break; // Check if subvariable comes through extension @@ -903,6 +897,13 @@ bool SubvariableFlow::traceBackwardSext(ReplaceVarnode *rvn) if (!createLink(rop,rvn->mask,i,op->getIn(i))) // Same inputs and mask return false; return true; + case CPUI_INT_ZEXT: + if (op->getIn(0)->getSize() < flowsize) { + // zero extension from a smaller size still acts as a signed extension + addPush(op,rvn); + return true; + } + break; case CPUI_INT_SEXT: if (flowsize != op->getIn(0)->getSize()) return false; rop = createOp(CPUI_COPY,1,rvn); @@ -1037,6 +1038,21 @@ void SubvariableFlow::createNewOut(ReplaceOp *rop,uintb mask) res->def = rop; } +/// \brief Mark an operation where original data-flow is being pushed into a subgraph variable +/// +/// The operation is not manipulating the logical value, but it produces a variable containing +/// the logical value. The original op will not change but will just produce a smaller value. +/// \param pushOp is the operation to mark +/// \param rvn is the output variable holding the logical value +void SubvariableFlow::addPush(PcodeOp *pushOp,ReplaceVarnode *rvn) + +{ + patchlist.push_front(PatchRecord()); // Push to the front of the patch list + patchlist.front().type = PatchRecord::push_patch; + patchlist.front().patchOp = pushOp; + patchlist.front().in1 = rvn; +} + /// \brief Mark an operation where a subgraph variable is naturally copied into the original data-flow /// /// If the operations naturally takes the given logical value as input but the output diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh index d659eb0f59..cdf80a6572 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/subflow.hh @@ -105,6 +105,7 @@ class SubvariableFlow { bool traceBackwardSext(ReplaceVarnode *rvn); ///< Trace logical data-flow backward assuming sign-extensions bool createLink(ReplaceOp *rop,uintb mask,int4 slot,Varnode *vn); bool createCompareBridge(PcodeOp *op,ReplaceVarnode *inrvn,int4 slot,Varnode *othervn); + void addPush(PcodeOp *pushOp,ReplaceVarnode *rvn); void addTerminalPatch(PcodeOp *pullop,ReplaceVarnode *rvn); void addTerminalPatchSameOp(PcodeOp *pullop,ReplaceVarnode *rvn,int4 slot); void addBooleanPatch(PcodeOp *pullop,ReplaceVarnode *rvn,int4 slot);