mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Add constants to analysis of hiding extension casts
This commit is contained in:
parent
36aebc2d9b
commit
f28c377e9b
4 changed files with 64 additions and 58 deletions
|
@ -166,6 +166,57 @@ int4 CastStrategyC::intPromotionType(const Varnode *vn) const
|
||||||
return UNKNOWN_PROMOTION;
|
return UNKNOWN_PROMOTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CastStrategyC::isExtensionCastImplied(const PcodeOp *op,const PcodeOp *readOp) const
|
||||||
|
|
||||||
|
{
|
||||||
|
const Varnode *outVn = op->getOut();
|
||||||
|
if (outVn->isExplicit()) {
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (readOp == (PcodeOp *) 0)
|
||||||
|
return false;
|
||||||
|
type_metatype metatype = outVn->getHigh()->getType()->getMetatype();
|
||||||
|
const Varnode *otherVn;
|
||||||
|
int4 slot;
|
||||||
|
switch (readOp->code()) {
|
||||||
|
case CPUI_PTRADD:
|
||||||
|
break;
|
||||||
|
case CPUI_INT_ADD:
|
||||||
|
case CPUI_INT_SUB:
|
||||||
|
case CPUI_INT_MULT:
|
||||||
|
case CPUI_INT_DIV:
|
||||||
|
case CPUI_INT_AND:
|
||||||
|
case CPUI_INT_OR:
|
||||||
|
case CPUI_INT_XOR:
|
||||||
|
case CPUI_INT_EQUAL:
|
||||||
|
case CPUI_INT_NOTEQUAL:
|
||||||
|
case CPUI_INT_LESS:
|
||||||
|
case CPUI_INT_LESSEQUAL:
|
||||||
|
case CPUI_INT_SLESS:
|
||||||
|
case CPUI_INT_SLESSEQUAL:
|
||||||
|
slot = readOp->getSlot(outVn);
|
||||||
|
otherVn = readOp->getIn(1 - slot);
|
||||||
|
// Check if the expression involves an explicit variable of the right integer type
|
||||||
|
if (otherVn->isConstant()) {
|
||||||
|
// Integer tokens do not naturally indicate their size, and
|
||||||
|
// integers that are bigger than the promotion size are NOT naturally extended.
|
||||||
|
if (otherVn->getSize() > promoteSize) // So if the integer is bigger than the promotion size
|
||||||
|
return false; // The extension cast on the other side must be explicit
|
||||||
|
}
|
||||||
|
else if (!otherVn->isExplicit())
|
||||||
|
return false;
|
||||||
|
if (otherVn->getHigh()->getType()->getMetatype() != metatype)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true; // Everything is integer promotion
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Datatype *CastStrategyC::castStandard(Datatype *reqtype,Datatype *curtype,
|
Datatype *CastStrategyC::castStandard(Datatype *reqtype,Datatype *curtype,
|
||||||
bool care_uint_int,bool care_ptr_uint) const
|
bool care_uint_int,bool care_ptr_uint) const
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,16 @@ public:
|
||||||
/// \return \b true if a cast is required before extending
|
/// \return \b true if a cast is required before extending
|
||||||
virtual bool checkIntPromotionForExtension(const PcodeOp *op) const=0;
|
virtual bool checkIntPromotionForExtension(const PcodeOp *op) const=0;
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Is the given ZEXT/SEXT cast implied by the expression its in?
|
||||||
|
///
|
||||||
|
/// We've already determined that the given ZEXT or SEXT op can be viewed as a natural \e cast operation.
|
||||||
|
/// Determine if the cast is implied by the expression its and doesn't need to be printed.
|
||||||
|
/// \param op is the given ZEXT or SEXT PcodeOp
|
||||||
|
/// \param readOp is the PcodeOp consuming the output of the extensions (or null)
|
||||||
|
/// \return \b true if the op as a cast does not need to be printed
|
||||||
|
virtual bool isExtensionCastImplied(const PcodeOp *op,const PcodeOp *readOp) const=0;
|
||||||
|
|
||||||
/// \brief Does there need to be a visible cast between the given data-types
|
/// \brief Does there need to be a visible cast between the given data-types
|
||||||
///
|
///
|
||||||
/// The cast is from a \e current data-type to an \e expected data-type. NULL is returned
|
/// The cast is from a \e current data-type to an \e expected data-type. NULL is returned
|
||||||
|
@ -151,6 +161,7 @@ public:
|
||||||
virtual int4 intPromotionType(const Varnode *vn) const;
|
virtual int4 intPromotionType(const Varnode *vn) const;
|
||||||
virtual bool checkIntPromotionForCompare(const PcodeOp *op,int4 slot) const;
|
virtual bool checkIntPromotionForCompare(const PcodeOp *op,int4 slot) const;
|
||||||
virtual bool checkIntPromotionForExtension(const PcodeOp *op) const;
|
virtual bool checkIntPromotionForExtension(const PcodeOp *op) const;
|
||||||
|
virtual bool isExtensionCastImplied(const PcodeOp *op,const PcodeOp *readOp) const;
|
||||||
virtual Datatype *castStandard(Datatype *reqtype,Datatype *curtype,bool care_uint_int,bool care_ptr_uint) const;
|
virtual Datatype *castStandard(Datatype *reqtype,Datatype *curtype,bool care_uint_int,bool care_ptr_uint) const;
|
||||||
virtual Datatype *arithmeticOutputStandard(const PcodeOp *op);
|
virtual Datatype *arithmeticOutputStandard(const PcodeOp *op);
|
||||||
virtual bool isSubpieceCast(Datatype *outtype,Datatype *intype,uint4 offset) const;
|
virtual bool isSubpieceCast(Datatype *outtype,Datatype *intype,uint4 offset) const;
|
||||||
|
|
|
@ -595,7 +595,7 @@ void PrintC::opIntZext(const PcodeOp *op,const PcodeOp *readOp)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (castStrategy->isZextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) {
|
if (castStrategy->isZextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) {
|
||||||
if (isExtensionCastImplied(op,readOp))
|
if (option_hide_exts && castStrategy->isExtensionCastImplied(op,readOp))
|
||||||
opHiddenFunc(op);
|
opHiddenFunc(op);
|
||||||
else
|
else
|
||||||
opTypeCast(op);
|
opTypeCast(op);
|
||||||
|
@ -608,7 +608,7 @@ void PrintC::opIntSext(const PcodeOp *op,const PcodeOp *readOp)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (castStrategy->isSextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) {
|
if (castStrategy->isSextCast(op->getOut()->getHigh()->getType(),op->getIn(0)->getHigh()->getType())) {
|
||||||
if (isExtensionCastImplied(op,readOp))
|
if (option_hide_exts && castStrategy->isExtensionCastImplied(op,readOp))
|
||||||
opHiddenFunc(op);
|
opHiddenFunc(op);
|
||||||
else
|
else
|
||||||
opTypeCast(op);
|
opTypeCast(op);
|
||||||
|
@ -1282,61 +1282,6 @@ bool PrintC::printCharacterConstant(ostream &s,const Address &addr,int4 charsize
|
||||||
return res;
|
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
|
|
||||||
/// \param readOp is the PcodeOp consuming the output of the extensions (or null)
|
|
||||||
/// \return \b true if the op as a cast does not need to be printed
|
|
||||||
bool PrintC::isExtensionCastImplied(const PcodeOp *op,const PcodeOp *readOp) const
|
|
||||||
|
|
||||||
{
|
|
||||||
if (!option_hide_exts)
|
|
||||||
return false; // If hiding extensions is not on, we must always print extension
|
|
||||||
const Varnode *outVn = op->getOut();
|
|
||||||
if (outVn->isExplicit()) {
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (readOp == (PcodeOp *) 0)
|
|
||||||
return false;
|
|
||||||
type_metatype metatype = outVn->getHigh()->getType()->getMetatype();
|
|
||||||
const Varnode *otherVn;
|
|
||||||
int4 slot;
|
|
||||||
switch (readOp->code()) {
|
|
||||||
case CPUI_PTRADD:
|
|
||||||
break;
|
|
||||||
case CPUI_INT_ADD:
|
|
||||||
case CPUI_INT_SUB:
|
|
||||||
case CPUI_INT_MULT:
|
|
||||||
case CPUI_INT_DIV:
|
|
||||||
case CPUI_INT_AND:
|
|
||||||
case CPUI_INT_OR:
|
|
||||||
case CPUI_INT_XOR:
|
|
||||||
case CPUI_INT_EQUAL:
|
|
||||||
case CPUI_INT_NOTEQUAL:
|
|
||||||
case CPUI_INT_LESS:
|
|
||||||
case CPUI_INT_LESSEQUAL:
|
|
||||||
case CPUI_INT_SLESS:
|
|
||||||
case CPUI_INT_SLESSEQUAL:
|
|
||||||
slot = readOp->getSlot(outVn);
|
|
||||||
otherVn = readOp->getIn(1 - slot);
|
|
||||||
// Check if the expression involves an explicit variable of the right integer type
|
|
||||||
if (!otherVn->isExplicit() && !otherVn->isConstant())
|
|
||||||
return false;
|
|
||||||
if (otherVn->getHigh()->getType()->getMetatype() != metatype)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true; // Everything is integer promotion
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Push a single character constant to the RPN stack
|
/// \brief Push a single character constant to the RPN stack
|
||||||
///
|
///
|
||||||
/// For C, a character constant is usually emitted as the character in single quotes.
|
/// For C, a character constant is usually emitted as the character in single quotes.
|
||||||
|
|
|
@ -159,7 +159,6 @@ protected:
|
||||||
void opHiddenFunc(const PcodeOp *op); ///< Push the given p-code op as a hidden token
|
void opHiddenFunc(const PcodeOp *op); ///< Push the given p-code op as a hidden token
|
||||||
static bool hasCharTerminator(uint1 *buffer,int4 size,int4 charsize);
|
static bool hasCharTerminator(uint1 *buffer,int4 size,int4 charsize);
|
||||||
bool printCharacterConstant(ostream &s,const Address &addr,int4 charsize) const;
|
bool printCharacterConstant(ostream &s,const Address &addr,int4 charsize) const;
|
||||||
bool isExtensionCastImplied(const PcodeOp *op,const PcodeOp *readOp) const;
|
|
||||||
virtual void pushConstant(uintb val,const Datatype *ct,
|
virtual void pushConstant(uintb val,const Datatype *ct,
|
||||||
const Varnode *vn,const PcodeOp *op);
|
const Varnode *vn,const PcodeOp *op);
|
||||||
virtual bool pushEquate(uintb val,int4 sz,const EquateSymbol *sym,
|
virtual bool pushEquate(uintb val,int4 sz,const EquateSymbol *sym,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue