decompiler  1.0.0
Public Types | Public Member Functions | Protected Attributes | List of all members
ghidra::CastStrategy Class Referenceabstract

A strategy for applying type casts. More...

#include <cast.hh>

Inheritance diagram for ghidra::CastStrategy:
ghidra::CastStrategyC ghidra::CastStrategyJava

Public Types

enum  IntPromotionCode {
  NO_PROMOTION = -1, UNKNOWN_PROMOTION = 0, UNSIGNED_EXTENSION = 1, SIGNED_EXTENSION = 2,
  EITHER_EXTENSION = 3
}
 Types of integer promotion. More...
 

Public Member Functions

 CastStrategy (void)
 Constructor.
 
void setTypeFactory (TypeFactory *t)
 Establish the data-type factory. More...
 
virtual ~CastStrategy (void)
 Destructor.
 
virtual int4 localExtensionType (const Varnode *vn, const PcodeOp *op) const =0
 Decide on integer promotion by examining just local properties of the given Varnode. More...
 
virtual int4 intPromotionType (const Varnode *vn) const =0
 Calculate the integer promotion code of a given Varnode. More...
 
virtual bool checkIntPromotionForCompare (const PcodeOp *op, int4 slot) const =0
 Check if integer promotion forces a cast for the given comparison op and slot. More...
 
virtual bool checkIntPromotionForExtension (const PcodeOp *op) const =0
 Check if integer promotion forces a cast for the input to the given extension. More...
 
virtual bool isExtensionCastImplied (const PcodeOp *op, const PcodeOp *readOp) const =0
 Is the given ZEXT/SEXT cast implied by the expression its in? More...
 
virtual DatatypecastStandard (Datatype *reqtype, Datatype *curtype, bool care_uint_int, bool care_ptr_uint) const =0
 Does there need to be a visible cast between the given data-types. More...
 
virtual DatatypearithmeticOutputStandard (const PcodeOp *op)=0
 What is the output data-type produced by the given integer arithmetic operation. More...
 
virtual bool isSubpieceCast (Datatype *outtype, Datatype *intype, uint4 offset) const =0
 Is truncating an input data-type, producing an output data-type, considered a cast. More...
 
virtual bool isSubpieceCastEndian (Datatype *outtype, Datatype *intype, uint4 offset, bool isbigend) const =0
 Is the given data-type truncation considered a cast, given endianess concerns. More...
 
virtual bool isSextCast (Datatype *outtype, Datatype *intype) const =0
 Is sign-extending an input data-type, producing an output data-type, considered a cast. More...
 
virtual bool isZextCast (Datatype *outtype, Datatype *intype) const =0
 Is zero-extending an input data-type, producing an output data-type, considered a cast. More...
 
bool markExplicitUnsigned (PcodeOp *op, int4 slot) const
 Check if a constant input should be explicitly labeled as an unsigned token. More...
 
bool markExplicitLongSize (PcodeOp *op, int4 slot) const
 Check is a constant input should be explicitly labeled as a long integer token. More...
 
bool caresAboutCharRepresentation (const Varnode *vn, const PcodeOp *op) const
 For the given PcodeOp, does it matter if a constant operand is presented as a character or integer. More...
 

Protected Attributes

TypeFactorytlst
 Type factory associated with the Architecture.
 
int4 promoteSize
 Size of int data-type, (size that integers get promoted to)
 

Detailed Description

A strategy for applying type casts.

A cast operation in C or other languages masks a variety of possible low-level conversions, such as extensions, truncations, integer to floating-point, etc. On top of this, languages allow many of these types of operations to be implied in the source code, with no explicit token representing the conversion. Conversions happen automatically for things like integer promotion, between different sizes (of integers), and between signed and unsigned data-type variants.

This class is the API for making four kinds of decisions:

Member Enumeration Documentation

◆ IntPromotionCode

Types of integer promotion.

For many languages, small integers are automatically promoted to a standard size. The decompiler describes how an expression is or will be affected by integer promotion, using these codes

Enumerator
NO_PROMOTION 

There is no integer promotion.

UNKNOWN_PROMOTION 

The type of integer promotion cannot be determined.

UNSIGNED_EXTENSION 

The value is promoted using unsigned extension.

SIGNED_EXTENSION 

The value is promoted using signed extension.

EITHER_EXTENSION 

The value is promoted using either signed or unsigned extension.

Member Function Documentation

◆ arithmeticOutputStandard()

virtual Datatype* ghidra::CastStrategy::arithmeticOutputStandard ( const PcodeOp op)
pure virtual

◆ caresAboutCharRepresentation()

bool ghidra::CastStrategy::caresAboutCharRepresentation ( const Varnode vn,
const PcodeOp op 
) const
inline

For the given PcodeOp, does it matter if a constant operand is presented as a character or integer.

In most languages, character constants are promoted to integers as a matter of course, so it doesn't matter if the constant is represented as an integer (a string of digits) or a character (surrounded by quotes). But its possible that a particular operator does care. If the operator needs an explicit character representation for an operand with a character data-type, return true.

Parameters
vnis the constant with character data-type
opis the given PcodeOp which reads the constant (may be null)
Returns
true if the constant must be represented as an explicit character

Referenced by ghidra::PrintC::pushCharConstant().

◆ castStandard()

virtual Datatype* ghidra::CastStrategy::castStandard ( Datatype reqtype,
Datatype curtype,
bool  care_uint_int,
bool  care_ptr_uint 
) const
pure virtual

Does there need to be a visible cast between the given data-types.

The cast is from a current data-type to an expected data-type. NULL is returned if no cast is required, otherwise the data-type to cast to (usually the expected data-type) is returned.

Parameters
reqtypeis the expected data-type
curtypeis the current data-type
care_uint_intis true if we care about a change in signedness
care_ptr_uintis true if we care about conversions between pointers and unsigned values
Returns
NULL to indicate no cast, or the data-type to cast to

Implemented in ghidra::CastStrategyJava, and ghidra::CastStrategyC.

Referenced by ghidra::ActionSetCasts::castOutput(), ghidra::TypeOp::getInputCast(), ghidra::TypeOpCopy::getInputCast(), ghidra::TypeOpLoad::getInputCast(), ghidra::TypeOpStore::getInputCast(), ghidra::TypeOpEqual::getInputCast(), ghidra::TypeOpNotEqual::getInputCast(), ghidra::TypeOpIntSless::getInputCast(), ghidra::TypeOpIntSlessEqual::getInputCast(), ghidra::TypeOpIntLess::getInputCast(), ghidra::TypeOpIntLessEqual::getInputCast(), ghidra::TypeOpIntZext::getInputCast(), ghidra::TypeOpIntSext::getInputCast(), ghidra::TypeOpIntRight::getInputCast(), ghidra::TypeOpIntSright::getInputCast(), ghidra::TypeOpIntDiv::getInputCast(), ghidra::TypeOpIntSdiv::getInputCast(), ghidra::TypeOpIntRem::getInputCast(), ghidra::TypeOpIntSrem::getInputCast(), ghidra::TypeOpPtradd::getInputCast(), ghidra::TypeOpPtrsub::getInputCast(), ghidra::ActionSetCasts::testStructOffset0(), and ~CastStrategy().

◆ checkIntPromotionForCompare()

virtual bool ghidra::CastStrategy::checkIntPromotionForCompare ( const PcodeOp op,
int4  slot 
) const
pure virtual

Check if integer promotion forces a cast for the given comparison op and slot.

Compute to what level the given slot has seen integer promotion and if a cast is required before the comparison operator makes sense.

Parameters
opis the given comparison operator
slotis the input slot being tested
Returns
true if a cast is required before comparing

Implemented in ghidra::CastStrategyC.

Referenced by ghidra::TypeOpEqual::getInputCast(), ghidra::TypeOpNotEqual::getInputCast(), ghidra::TypeOpIntSless::getInputCast(), ghidra::TypeOpIntSlessEqual::getInputCast(), ghidra::TypeOpIntLess::getInputCast(), ghidra::TypeOpIntLessEqual::getInputCast(), and ~CastStrategy().

◆ checkIntPromotionForExtension()

virtual bool ghidra::CastStrategy::checkIntPromotionForExtension ( const PcodeOp op) const
pure virtual

Check if integer promotion forces a cast for the input to the given extension.

Compute to what level the given slot has seen integer promotion and if a cast is required before the extension operator makes sense.

Parameters
opis the given extension operator INT_ZEXT or INT_SEXT
Returns
true if a cast is required before extending

Implemented in ghidra::CastStrategyC.

Referenced by ghidra::TypeOpIntZext::getInputCast(), ghidra::TypeOpIntSext::getInputCast(), and ~CastStrategy().

◆ intPromotionType()

virtual int4 ghidra::CastStrategy::intPromotionType ( const Varnode vn) const
pure virtual

◆ isExtensionCastImplied()

virtual bool ghidra::CastStrategy::isExtensionCastImplied ( const PcodeOp op,
const PcodeOp readOp 
) const
pure virtual

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 cast operation. Determine if the cast is implied by the expression its and doesn't need to be printed.

Parameters
opis the given ZEXT or SEXT PcodeOp
readOpis the PcodeOp consuming the output of the extensions (or null)
Returns
true if the op as a cast does not need to be printed

Implemented in ghidra::CastStrategyC.

Referenced by ghidra::PrintC::opIntSext(), ghidra::PrintC::opIntZext(), and ~CastStrategy().

◆ isSextCast()

virtual bool ghidra::CastStrategy::isSextCast ( Datatype outtype,
Datatype intype 
) const
pure virtual

Is sign-extending an input data-type, producing an output data-type, considered a cast.

Data-types must be provided from the input and output of an INT_SEXT operation.

Parameters
outtypeis the output data-type
intypeis the input data-type
Returns
true if the INT_SEXT should be represented as a cast

Implemented in ghidra::CastStrategyC.

Referenced by ghidra::PrintC::opIntSext(), and ~CastStrategy().

◆ isSubpieceCast()

virtual bool ghidra::CastStrategy::isSubpieceCast ( Datatype outtype,
Datatype intype,
uint4  offset 
) const
pure virtual

Is truncating an input data-type, producing an output data-type, considered a cast.

Data-types must be provided from the input and output of a SUBPIECE operation.

Parameters
outtypeis the output data-type
intypeis the input data-type
offsetis number of bytes truncated by the SUBPIECE
Returns
true if the SUBPIECE should be represented as a cast

Implemented in ghidra::CastStrategyC.

Referenced by ghidra::CastStrategyC::isSubpieceCastEndian(), ghidra::PrintC::opSubpiece(), and ~CastStrategy().

◆ isSubpieceCastEndian()

virtual bool ghidra::CastStrategy::isSubpieceCastEndian ( Datatype outtype,
Datatype intype,
uint4  offset,
bool  isbigend 
) const
pure virtual

Is the given data-type truncation considered a cast, given endianess concerns.

This is equivalent to isSubpieceCast() but where the truncation is accomplished by pulling bytes directly out of memory. We assume the input data-type is layed down in memory, and we pull the output value starting at a given byte offset.

Parameters
outtypeis the output data-type
intypeis the input data-type
offsetis the given byte offset (into the input memory)
isbigendis true if the address space holding the memory is big endian.
Returns
true if the truncation should be represented as a cast

Implemented in ghidra::CastStrategyC.

Referenced by ghidra::PrintC::pushPartialSymbol(), and ~CastStrategy().

◆ isZextCast()

virtual bool ghidra::CastStrategy::isZextCast ( Datatype outtype,
Datatype intype 
) const
pure virtual

Is zero-extending an input data-type, producing an output data-type, considered a cast.

Data-types must be provided from the input and output of an INT_ZEXT operation.

Parameters
outtypeis the output data-type
intypeis the input data-type
Returns
true if the INT_ZEXT should be represented as a cast

Implemented in ghidra::CastStrategyJava, and ghidra::CastStrategyC.

Referenced by ghidra::PrintC::opIntZext(), and ~CastStrategy().

◆ localExtensionType()

virtual int4 ghidra::CastStrategy::localExtensionType ( const Varnode vn,
const PcodeOp op 
) const
pure virtual

Decide on integer promotion by examining just local properties of the given Varnode.

Parameters
vnis the given Varnode
opis the PcodeOp reading the Varnode
Returns
an IntPromotionCode (excluding NO_PROMOTION)

Implemented in ghidra::CastStrategyC.

Referenced by ghidra::CastStrategyC::intPromotionType(), and ~CastStrategy().

◆ markExplicitLongSize()

bool ghidra::CastStrategy::markExplicitLongSize ( PcodeOp op,
int4  slot 
) const

Check is a constant input should be explicitly labeled as a long integer token.

This method checks if the indicated input is an integer constant that needs to be coerced (as a source token) into a data-type that is larger than the base integer. If this is true, the input Varnode is marked for printing as explicitly a larger integer (typically long).

Parameters
opis the PcodeOp taking the value as input
slotis the input slot of the value
Returns
true if the Varnode gets marked for printing

References ghidra::Varnode::getHigh(), ghidra::PcodeOp::getIn(), ghidra::Datatype::getMetatype(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getOpcode(), ghidra::Varnode::getSize(), ghidra::HighVariable::getType(), ghidra::Varnode::isConstant(), ghidra::TypeOp::isShiftOp(), promoteSize, ghidra::Varnode::setLongPrint(), ghidra::TYPE_INT, ghidra::TYPE_UINT, and ghidra::TYPE_UNKNOWN.

Referenced by ghidra::ActionSetCasts::castInput(), and ~CastStrategy().

◆ markExplicitUnsigned()

bool ghidra::CastStrategy::markExplicitUnsigned ( PcodeOp op,
int4  slot 
) const

Check if a constant input should be explicitly labeled as an unsigned token.

Many languages can mark an integer constant as explicitly unsigned. When the decompiler is deciding on cast operations, this is one of the checks it performs. This method checks if the indicated input is an integer constant that needs to be coerced (as a source token) into being unsigned. If this is true, the input Varnode is marked for printing as explicitly unsigned.

Parameters
opis the PcodeOp taking the value as input
slotis the input slot of the value
Returns
true if the Varnode gets marked for printing

References ghidra::Varnode::getHighTypeReadFacing(), ghidra::PcodeOp::getIn(), ghidra::Datatype::getMetatype(), ghidra::PcodeOp::getOpcode(), ghidra::PcodeOp::getOut(), ghidra::TypeOp::inheritsSign(), ghidra::TypeOp::inheritsSignFirstParamOnly(), ghidra::Datatype::isCharPrint(), ghidra::Varnode::isConstant(), ghidra::Datatype::isEnumType(), ghidra::Varnode::isExplicit(), ghidra::Varnode::loneDescend(), ghidra::PcodeOp::numInput(), ghidra::Varnode::setUnsignedPrint(), ghidra::TYPE_UINT, and ghidra::TYPE_UNKNOWN.

Referenced by ghidra::ActionSetCasts::castInput(), and ~CastStrategy().

◆ setTypeFactory()

void ghidra::CastStrategy::setTypeFactory ( TypeFactory t)

Establish the data-type factory.

Sets the TypeFactory used to produce data-types for the arithmeticOutputStandard() method

Parameters
tis the TypeFactory

References ghidra::TypeFactory::getSizeOfInt(), promoteSize, and tlst.

Referenced by CastStrategy(), and ghidra::PrintC::initializeFromArchitecture().


The documentation for this class was generated from the following files: