decompiler
1.0.0
|
A strategy for applying type casts. More...
#include <cast.hh>
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 Datatype * | castStandard (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 Datatype * | arithmeticOutputStandard (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 | |
TypeFactory * | tlst |
Type factory associated with the Architecture. | |
int4 | promoteSize |
Size of int data-type, (size that integers get promoted to) | |
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:
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
What is the output data-type produced by the given integer arithmetic operation.
op | is the given operation |
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::TypeOpIntAdd::getOutputToken(), ghidra::TypeOpIntSub::getOutputToken(), ghidra::TypeOpInt2Comp::getOutputToken(), ghidra::TypeOpIntNegate::getOutputToken(), ghidra::TypeOpIntXor::getOutputToken(), ghidra::TypeOpIntAnd::getOutputToken(), ghidra::TypeOpIntOr::getOutputToken(), ghidra::TypeOpIntMult::getOutputToken(), and ~CastStrategy().
|
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.
vn | is the constant with character data-type |
op | is the given PcodeOp which reads the constant (may be null) |
Referenced by ghidra::PrintC::pushCharConstant().
|
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.
reqtype | is the expected data-type |
curtype | is the current data-type |
care_uint_int | is true if we care about a change in signedness |
care_ptr_uint | is true if we care about conversions between pointers and unsigned values |
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().
|
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.
op | is the given comparison operator |
slot | is the input slot being tested |
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().
|
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.
op | is the given extension operator INT_ZEXT or INT_SEXT |
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::TypeOpIntZext::getInputCast(), ghidra::TypeOpIntSext::getInputCast(), and ~CastStrategy().
|
pure virtual |
Calculate the integer promotion code of a given Varnode.
Recursively examine the expression defining the Varnode as necessary
vn | is the given Varnode |
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::CastStrategyC::checkIntPromotionForCompare(), ghidra::CastStrategyC::checkIntPromotionForExtension(), ghidra::TypeOpIntRight::getInputCast(), ghidra::TypeOpIntSright::getInputCast(), ghidra::TypeOpIntDiv::getInputCast(), ghidra::TypeOpIntSdiv::getInputCast(), ghidra::TypeOpIntRem::getInputCast(), ghidra::TypeOpIntSrem::getInputCast(), and ~CastStrategy().
|
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.
op | is the given ZEXT or SEXT PcodeOp |
readOp | is the PcodeOp consuming the output of the extensions (or null) |
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::PrintC::opIntSext(), ghidra::PrintC::opIntZext(), and ~CastStrategy().
|
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.
outtype | is the output data-type |
intype | is the input data-type |
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::PrintC::opIntSext(), and ~CastStrategy().
|
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.
outtype | is the output data-type |
intype | is the input data-type |
offset | is number of bytes truncated by the SUBPIECE |
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::CastStrategyC::isSubpieceCastEndian(), ghidra::PrintC::opSubpiece(), and ~CastStrategy().
|
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.
outtype | is the output data-type |
intype | is the input data-type |
offset | is the given byte offset (into the input memory) |
isbigend | is true if the address space holding the memory is big endian. |
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::PrintC::pushPartialSymbol(), and ~CastStrategy().
|
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.
outtype | is the output data-type |
intype | is the input data-type |
Implemented in ghidra::CastStrategyJava, and ghidra::CastStrategyC.
Referenced by ghidra::PrintC::opIntZext(), and ~CastStrategy().
|
pure virtual |
Decide on integer promotion by examining just local properties of the given Varnode.
Implemented in ghidra::CastStrategyC.
Referenced by ghidra::CastStrategyC::intPromotionType(), and ~CastStrategy().
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).
op | is the PcodeOp taking the value as input |
slot | is the input slot of the value |
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().
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.
op | is the PcodeOp taking the value as input |
slot | is the input slot of the value |
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().
void ghidra::CastStrategy::setTypeFactory | ( | TypeFactory * | t | ) |
Establish the data-type factory.
Sets the TypeFactory used to produce data-types for the arithmeticOutputStandard() method
t | is the TypeFactory |
References ghidra::TypeFactory::getSizeOfInt(), promoteSize, and tlst.
Referenced by CastStrategy(), and ghidra::PrintC::initializeFromArchitecture().