From 9d0829651a69989f516b0c0afa8e0a6d565e2e18 Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Wed, 4 May 2022 19:08:46 -0400 Subject: [PATCH] GP-1997 Don't over propagate global values --- .../Decompiler/src/decompile/cpp/coreaction.cc | 3 +-- .../Decompiler/src/decompile/cpp/heritage.cc | 1 + Ghidra/Features/Decompiler/src/decompile/cpp/op.cc | 3 ++- Ghidra/Features/Decompiler/src/decompile/cpp/op.hh | 13 +++++++------ .../Decompiler/src/decompile/cpp/ruleaction.cc | 13 ++++--------- .../Features/Decompiler/src/decompile/cpp/typeop.cc | 2 +- .../Decompiler/src/decompile/cpp/varnode.cc | 2 +- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 3c90de4263..325f943671 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -3331,7 +3331,6 @@ int4 ActionDeterminedBranch::apply(Funcdata &data) cbranch = bb->lastOp(); if ((cbranch == (PcodeOp *)0)||(cbranch->code() != CPUI_CBRANCH)) continue; if (!cbranch->getIn(1)->isConstant()) continue; - if (cbranch->isSplitting()) continue; // Already tried to remove before uintb val = cbranch->getIn(1)->getOffset(); int4 num = ((val!=0)!=cbranch->isBooleanFlip()) ? 0 : 1; data.removeBranch(bb,num); @@ -4052,7 +4051,7 @@ int4 ActionPrototypeTypes::apply(Funcdata &data) { list::const_iterator iter,iterend; - // Set the evalutation prototype if we are not already locked + // Set the evaluation prototype if we are not already locked ProtoModel *evalfp = data.getArch()->evalfp_current; if (evalfp == (ProtoModel *)0) evalfp = data.getArch()->defaultfp; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc index 49c515196b..7e19617da3 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc @@ -1377,6 +1377,7 @@ void Heritage::guardReturns(uint4 fl,const Address &addr,int4 size,vectorsetAddrForce(); vn->setActiveHeritage(); fd->opSetOpcode(copyop,CPUI_COPY); + copyop->setStopCopyPropagation(); Varnode *invn = fd->newVarnode(size,addr); invn->setActiveHeritage(); fd->opSetInput(copyop,invn,0); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc index ba74450c6e..03b86f27da 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc @@ -280,7 +280,8 @@ void PcodeOp::setOpcode(TypeOp *t_op) { flags &= ~(PcodeOp::branch | PcodeOp::call | PcodeOp::coderef | PcodeOp::commutative | PcodeOp::returns | PcodeOp::nocollapse | PcodeOp::marker | PcodeOp::booloutput | - PcodeOp::unary | PcodeOp::binary | PcodeOp::special); + PcodeOp::unary | PcodeOp::binary | PcodeOp::ternary | PcodeOp::special | + PcodeOp::has_callspec | PcodeOp::no_copy_propagation); opcode = t_op; flags |= t_op->getFlags(); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh index 6029b040a1..e2d234767f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh @@ -86,7 +86,7 @@ public: binary = 0x10000, ///< Evaluate as binary expression special = 0x20000, ///< Cannot be evaluated (without special processing) ternary = 0x40000, ///< Evaluate as ternary operator (or higher) - splittingbranch = 0x80000, ///< Dead edge cannot be removed as it splits + no_copy_propagation = 0x80000, ///< Op does not allow COPY propagation through its inputs nonprinting = 0x100000, ///< Op should not be directly printed as source halt = 0x200000, ///< instruction causes processor or process to halt badinstruction = 0x400000, ///< placeholder for bad instruction data @@ -107,7 +107,7 @@ public: warning = 8, ///< Warning has been generated for this op incidental_copy = 0x10, ///< Treat this as \e incidental for parameter recovery algorithms is_cpool_transformed = 0x20, ///< Have we checked for cpool transforms - stop_propagation = 0x40 ///< Stop propagation into output from descendants + stop_type_propagation = 0x40 ///< Stop data-type propagation into output from descendants }; private: TypeOp *opcode; ///< Pointer to class providing behavioral details of the operation @@ -195,7 +195,6 @@ public: void clearIndirectSource(void) { flags &= ~PcodeOp::indirect_source; } ///< Clear INDIRECT source flag bool isPtrFlow(void) const { return ((flags&PcodeOp::ptrflow)!=0); } ///< Return \b true if this produces/consumes ptrs void setPtrFlow(void) { flags |= PcodeOp::ptrflow; } ///< Mark this op as consuming/producing ptrs - bool isSplitting(void) const { return ((flags&PcodeOp::splittingbranch)!=0); } ///< Return \b true if this branch splits bool doesSpecialPropagation(void) const { return ((addlflags&PcodeOp::special_prop)!=0); } ///< Return \b true if this does datatype propagation bool doesSpecialPrinting(void) const { return ((addlflags&PcodeOp::special_print)!=0); } ///< Return \b true if this needs to special printing bool isIncidentalCopy(void) const { return ((addlflags&PcodeOp::incidental_copy)!=0); } ///< Return \b true if \b this COPY is \e incidental @@ -204,9 +203,11 @@ public: /// \brief Return \b true if we have already examined this cpool bool isCpoolTransformed(void) const { return ((addlflags&PcodeOp::is_cpool_transformed)!=0); } bool isCollapsible(void) const; ///< Return \b true if this can be collapsed to a COPY of a constant - bool stopsPropagation(void) const { return ((addlflags&stop_propagation)!=0); } ///< Is propagation from below stopped - void setStopPropagation(void) { addlflags |= stop_propagation; } ///< Stop propagation from below - void clearStopPropagation(void) { addlflags &= ~stop_propagation; } ///< Allow propagation from below + bool stopsTypePropagation(void) const { return ((addlflags&stop_type_propagation)!=0); } ///< Is data-type propagation from below stopped + void setStopTypePropagation(void) { addlflags |= stop_type_propagation; } ///< Stop data-type propagation from below + void clearStopTypePropagation(void) { addlflags &= ~stop_type_propagation; } ///< Allow data-type propagation from below + bool stopsCopyPropagation(void) const { return ((flags&no_copy_propagation)!=0); } ///< Does \b this allow COPY propagation + void setStopCopyPropagation(void) { flags |= no_copy_propagation; } ///< Stop COPY propagation through inputs /// \brief Return \b true if this LOADs or STOREs from a dynamic \e spacebase pointer bool usesSpacebasePtr(void) const { return ((flags&PcodeOp::spacebase_ptr)!=0); } uintm getCseHash(void) const; ///< Return hash indicating possibility of common subexpression elimination diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc index bb5f05e34a..1b64d156f9 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc @@ -3552,13 +3552,8 @@ int4 RulePropagateCopy::applyOp(PcodeOp *op,Funcdata &data) int4 i; PcodeOp *copyop; Varnode *vn,*invn; - OpCode opc; - opc = op->code(); - if (opc==CPUI_RETURN) return 0; // Preserve the address of return variable -// else if (opc == CPUI_INDIRECT) { -// if (op->Output()->isAddrForce()) return 0; -// } + if (op->stopsCopyPropagation()) return 0; for(i=0;inumInput();++i) { vn = op->getIn(i); if (!vn->isWritten()) continue; // Varnode must be written to @@ -6163,7 +6158,7 @@ void AddTreeState::buildTree(void) newop = data.newOpBefore(baseOp,CPUI_PTRSUB,multNode,data.newConstant(ptrsize,offset)); data.inheritReadResolution(newop, 0, baseOp, baseSlot); if (size != 0) - newop->setStopPropagation(); + newop->setStopTypePropagation(); multNode = newop->getOut(); } @@ -6376,7 +6371,7 @@ int4 RuleStructOffset0::applyOp(PcodeOp *op,Funcdata &data) PcodeOp *newop = data.newOpBefore(op,CPUI_PTRSUB,op->getIn(1),data.newConstant(op->getIn(1)->getSize(),0)); data.inheritReadResolution(newop, 0, op, 1); - newop->setStopPropagation(); + newop->setStopTypePropagation(); data.opSetInput(op,newop->getOut(),1); return 1; } @@ -6575,7 +6570,7 @@ int4 RulePtrsubUndo::applyOp(PcodeOp *op,Funcdata &data) return 0; data.opSetOpcode(op,CPUI_INT_ADD); - op->clearStopPropagation(); + op->clearStopTypePropagation(); return 1; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/typeop.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/typeop.cc index b904264b0f..96e462a01e 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/typeop.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/typeop.cc @@ -807,7 +807,7 @@ Datatype *TypeOpCallother::getOutputLocal(const PcodeOp *op) const TypeOpReturn::TypeOpReturn(TypeFactory *t) : TypeOp(t,CPUI_RETURN,"return") { - opflags = PcodeOp::special|PcodeOp::returns|PcodeOp::nocollapse; + opflags = PcodeOp::special|PcodeOp::returns|PcodeOp::nocollapse|PcodeOp::no_copy_propagation; behave = new OpBehavior(CPUI_RETURN,false,true); // Dummy behavior } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc index a88025dc15..481fd1721c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc @@ -787,7 +787,7 @@ Datatype *Varnode::getLocalType(bool &blockup) const ct = (Datatype *)0; if (def != (PcodeOp *)0) { ct = def->outputTypeLocal(); - if (def->stopsPropagation()) { + if (def->stopsTypePropagation()) { blockup = true; return ct; }