From 706960a1390d3e9a25869f7300a11f1699489076 Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Thu, 9 May 2019 11:32:26 -0400 Subject: [PATCH] removing implied casts in array index expressions --- .../Decompiler/src/decompile/cpp/printc.cc | 41 +++++++++++++++++-- .../Decompiler/src/decompile/cpp/printc.hh | 3 +- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc index 7c3fa0f073..218a794a8f 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc @@ -577,8 +577,12 @@ void PrintC::opReturn(const PcodeOp *op) void PrintC::opIntZext(const PcodeOp *op) { - if (castStrategy->isZextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) - opTypeCast(op); + if (castStrategy->isZextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) { + if (isExtensionCastImplied(op)) + pushVnImplied(op->getIn(0),op,mods); + else + opTypeCast(op); + } else opFunc(op); } @@ -586,8 +590,12 @@ void PrintC::opIntZext(const PcodeOp *op) void PrintC::opIntSext(const PcodeOp *op) { - if (castStrategy->isSextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) - opTypeCast(op); + if (castStrategy->isSextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) { + if (isExtensionCastImplied(op)) + pushVnImplied(op->getIn(0),op,mods); + else + opTypeCast(op); + } else opFunc(op); } @@ -1247,6 +1255,31 @@ bool PrintC::printCharacterConstant(ostream &s,const Address &addr,int4 charsize return res; } +/// \brief Is the given ZEXT/SEXT cast implied by the expression its in +/// +/// We know that the given ZEXT or SEXT op can be viewed as a natural \e cast operation. +/// Sometimes such a cast is implied by the expression its in, and the cast itself +/// doesn't need to be printed. +/// \param op is the given ZEXT or SEXT PcodeOp +/// \return \b true if the op as a cast does not need to be printed +bool PrintC::isExtensionCastImplied(const PcodeOp *op) const + +{ + const Varnode *outVn = op->getOut(); + if (outVn->isExplicit()) { + + } + else { + PcodeOp *expOp = outVn->loneDescend(); + if (expOp != (PcodeOp *)0) { + OpCode opc = expOp->code(); + if (opc == CPUI_PTRADD) + return true; + } + } + return false; +} + /// \brief Push a single character constant to the RPN stack /// /// For C, a character constant is usually emitted as the character in single quotes. diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/printc.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/printc.hh index d65e9be483..c27e9ff495 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/printc.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/printc.hh @@ -153,9 +153,10 @@ protected: void emitCommentGroup(const PcodeOp *inst); ///< Emit comments associated with a given statement void emitCommentFuncHeader(const Funcdata *fd); ///< Emit comments in the given function's header void opFunc(const PcodeOp *op); ///< Push a \e functional expression based on the given p-code op to the RPN stack - void opTypeCast(const PcodeOp *op); ///< Pus the given p-code op using type-cast syntax to the RPN stack + void opTypeCast(const PcodeOp *op); ///< Push the given p-code op using type-cast syntax to the RPN stack static bool hasCharTerminator(uint1 *buffer,int4 size,int4 charsize); bool printCharacterConstant(ostream &s,const Address &addr,int4 charsize) const; + bool isExtensionCastImplied(const PcodeOp *op) const; virtual void pushConstant(uintb val,const Datatype *ct, const Varnode *vn,const PcodeOp *op); virtual bool pushEquate(uintb val,int4 sz,const EquateSymbol *sym,