From 0ed3459dbfc4b57c20c2cffeed7538fb2de8e20b Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Thu, 4 Jan 2024 22:57:33 +0000 Subject: [PATCH] GP-4201 Check for descendants prior to normalizeReadSize --- .../Decompiler/src/decompile/cpp/heritage.cc | 17 ++++++++++------- .../Decompiler/src/decompile/cpp/heritage.hh | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc index 30a8959dd3..d6ca0cb615 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc @@ -331,20 +331,17 @@ bool Heritage::callOpIndirectEffect(const Address &addr,int4 size,PcodeOp *op) c /// of the address range currently being linked, create a Varnode of /// the correct size and define the original Varnode as a SUBPIECE. /// \param vn is the given too small Varnode +/// \param op is the reading PcodeOp /// \param addr is the start of the (larger) range /// \param size is the number of bytes in the range /// \return the new larger Varnode -Varnode *Heritage::normalizeReadSize(Varnode *vn,const Address &addr,int4 size) +Varnode *Heritage::normalizeReadSize(Varnode *vn,PcodeOp *op,const Address &addr,int4 size) { int4 overlap; Varnode *vn1,*vn2; - PcodeOp *op,*newop; + PcodeOp *newop; - list::const_iterator oiter = vn->beginDescend(); - op = *oiter++; - if (oiter != vn->endDescend()) - throw LowlevelError("Free varnode with multiple reads"); newop = fd->newOp(2,op->getAddr()); fd->opSetOpcode(newop,CPUI_SUBPIECE); vn1 = fd->newVarnode(size,addr); @@ -1122,8 +1119,14 @@ void Heritage::guard(const Address &addr,int4 size,bool guardPerformed, for(iter=read.begin();iter!=read.end();++iter) { vn = *iter; + list::const_iterator oiter = vn->beginDescend(); + if (oiter == vn->endDescend()) // removeRevisitedMarkers may have eliminated descendant + continue; + PcodeOp *op = *oiter++; + if (oiter != vn->endDescend()) + throw LowlevelError("Free varnode with multiple reads"); if (vn->getSize() < size) - *iter = vn = normalizeReadSize(vn,addr,size); + *iter = vn = normalizeReadSize(vn,op,addr,size); vn->setActiveHeritage(); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh index b488a25235..a309fb27aa 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh @@ -235,7 +235,7 @@ class Heritage { void removeRevisitedMarkers(const vector &remove,const Address &addr,int4 size); int4 collect(Address addr,int4 size,vector &read,vector &write,vector &input,vector &remove) const; bool callOpIndirectEffect(const Address &addr,int4 size,PcodeOp *op) const; - Varnode *normalizeReadSize(Varnode *vn,const Address &addr,int4 size); + Varnode *normalizeReadSize(Varnode *vn,PcodeOp *op,const Address &addr,int4 size); Varnode *normalizeWriteSize(Varnode *vn,const Address &addr,int4 size); Varnode *concatPieces(const vector &vnlist,PcodeOp *insertop,Varnode *finalvn); void splitPieces(const vector &vnlist,PcodeOp *insertop,const Address &addr,int4 size,Varnode *startvn);