Interface PcodeArithmetic<T>
- Type Parameters:
T- the type of values operated on
- All Known Implementing Classes:
AddressesReadPcodeArithmetic,BytesPcodeArithmetic,JitDataFlowArithmetic,LocationPcodeArithmetic,PairedPcodeArithmetic
T.
See BytesPcodeArithmetic for the typical pattern when implementing an arithmetic. There
are generally two cases: 1) Where endianness matters, 2) Where endianness does not matter. The
first is typical. The implementation should be an Enum with two constants, one for the
big endian implementation, and one for the little endian implementation. The class should also
provide static methods: forEndian(boolean isBigEndian) for getting the correct one based
on endianness, and forLanguage(Language language) for getting the correct one given a
language. If endianness does not matter, then the implementation should follow a singleton
pattern. See notes on getEndian() for the endian-agnostic case.
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic enumReasons for requiring a concrete value -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe number of bytes needed to encode the size (in bytes) of any value -
Method Summary
Modifier and TypeMethodDescriptionApply a binary operator to the given inputsdefault TApply a binary operator to the given inputdefault TfromConst(boolean value, int size) Convert abooleantoTfromConst(byte[] value) Convert the given constant concrete value to typeThaving the same size.default TfromConst(byte value, int size) Convert abytetoT, with unsigned extensiondefault TfromConst(double value, int size) Convert adoubletoTdefault TfromConst(float value, int size) Convert afloattoTdefault TfromConst(int value, int size) Convert aninttoT, with unsigned extensiondefault TfromConst(long value, int size) Convert the given constant concrete value to typeThaving the given size.default TfromConst(short value, int size) Convert ashorttoT, with unsigned extensiondefault TfromConst(RegisterValue value) Convert the given constant concrete register value to typeTdefault TfromConst(BigInteger value, int size) Convert the given constant concrete value to typeThaving the given size.default TfromConst(BigInteger value, int size, boolean isContextreg) Convert the given constant concrete value to typeThaving the given size.Get the endianness of this arithmeticdefault booleanisTrue(T cond, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract condition to a concrete boolean valuemodAfterLoad(int sizeinOffset, AddressSpace space, T inOffset, int sizeinValue, T inValue) Apply any modifications after a value is loadeddefault TmodAfterLoad(PcodeOp op, AddressSpace space, T inOffset, T inValue) Apply any modifications after a value is loadedmodBeforeStore(int sizeinOffset, AddressSpace space, T inOffset, int sizeinValue, T inValue) Apply any modifications before a value is storeddefault TmodBeforeStore(PcodeOp op, AddressSpace space, T inOffset, T inValue) Apply any modifications before a value is storeddefault TApply thePcodeOp.PTRADDoperator to the given inputsdefault TApply thePcodeOp.PTRSUBoperator to the given inputslongGet the size in bytes, if possible, of the given abstract valuedefault TsizeOfAbstract(T value) Get the size in bytes, if possible, of the given abstract value, as an abstract valuedefault BigIntegertoBigInteger(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete big integerdefault booleantoBoolean(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete booleanbyte[]toConcrete(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete byte arraydefault doubletoDouble(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete doubledefault floattoFloat(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete floatdefault longtoLong(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete longdefault RegisterValuetoRegisterValue(Register register, T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete register valueApply a unary operator to the given inputdefault TApply a unary operator to the given input
-
Field Details
-
SIZEOF_SIZEOF
static final int SIZEOF_SIZEOFThe number of bytes needed to encode the size (in bytes) of any value- See Also:
-
-
Method Details
-
getEndian
Endian getEndian()Get the endianness of this arithmeticOften T is a byte array, or at least represents one abstractly. Ideally, it is an array where each element is an abstraction of a byte. If that is the case, then the arithmetic likely has to interpret those bytes as integral values according to an endianness. This should return that endianness.
If the abstraction has no notion of endianness, return null. In that case, the both
fromConst(BigInteger, int, boolean)andfromConst(long, int)must be overridden. Furthermore, unlesstoConcrete(Object, Purpose)is guaranteed to throw an exception, thentoBigInteger(Object, Purpose)andtoLong(Object, Purpose)must also be overridden.- Returns:
- the endianness or null
-
unaryOp
Apply a unary operator to the given inputNote the sizes of variables are given, because values don't necessarily have an intrinsic size. For example, a
BigIntegermay have a minimum encoding size, but that does not necessarily reflect the size of the variable from which is was read.- Parameters:
opcode- the p-code opcodesizeout- the size (in bytes) of the output variablesizein1- the size (in bytes) of the input variablein1- the input value- Returns:
- the output value
- Implementation Notes:
OpBehaviorFactory.getOpBehavior(int)for the given opcode is guaranteed to return a derivative ofUnaryOpBehavior.
-
unaryOp
Apply a unary operator to the given inputThis provides the full p-code op, allowing deeper inspection of the code. For example, an arithmetic may wish to distinguish immediate (constant) values from variables. By default, this unpacks the details and defers to
unaryOp(int, int, int, Object).- Parameters:
op- the operationin1- the input value- Returns:
- the output value
- Implementation Notes:
OpBehaviorFactory.getOpBehavior(int)for the given opcode is guaranteed to return a derivative ofUnaryOpBehavior.
-
binaryOp
Apply a binary operator to the given inputsNote the sizes of variables are given, because values don't necessarily have an intrinsic size. For example, a
BigIntegermay have a minimum encoding size, but that does not necessarily reflect the size of the variable from which is was read.- Parameters:
opcode- the operation's opcode. SeePcodeOp.sizeout- the size (in bytes) of the output variablesizein1- the size (in bytes) of the first (left) input variablein1- the first (left) input valuesizein2- the size (in bytes) of the second (right) input variablein2- the second (right) input value- Returns:
- the output value
- Implementation Notes:
OpBehaviorFactory.getOpBehavior(int)for the given opcode is guaranteed to return a derivative ofBinaryOpBehavior.
-
binaryOp
Apply a binary operator to the given inputThis provides the full p-code op, allowing deeper inspection of the code. For example, an arithmetic may wish to distinguish immediate (constant) values from variables. By default, this unpacks the details and defers to
binaryOp(int, int, int, Object, int, Object).- Parameters:
op- the operationin1- the first (left) input valuein2- the second (right) input value- Returns:
- the output value
- Implementation Notes:
OpBehaviorFactory.getOpBehavior(int)for the given opcode is guaranteed to return a derivative ofBinaryOpBehavior.
-
ptrAdd
Apply thePcodeOp.PTRADDoperator to the given inputsThe "pointer add" op takes three operands: base, index, size; and is used as a more compact representation of array index address computation. The
sizeoperand must be constant. Supposearris an array whose elements aresizebytes each, and the address of its first element isbase. The decompiler would likely render thePcodeOp.PTRADDop as&arr[index]. An equivalent SLEIGH expression isbase + index*size.NOTE: This op is always a result of decompiler simplification, not low p-code generation, and so are not ordinarily used by a
PcodeExecutor.- Parameters:
sizeout- the size (in bytes) of the output variablesizeinBase- the size (in bytes) of the variable used for the array's base addressinBase- the value used as the array's base addresssizeinIndex- the size (in bytes) of the variable used for the indexinIndex- the value used as the indexinSize- the size of each array element in bytes- Returns:
- the output value
-
ptrSub
Apply thePcodeOp.PTRSUBoperator to the given inputsThe "pointer subfield" op takes two operands: base, offset; and is used as a more specific representation of structure field address computation. Its behavior is exactly equivalent to
PcodeOp.INT_ADD. Supposestis a structure pointer with a fieldflocatedinOffsetbytes into the structure, andsthas the valuebase. The decompiler would likely render thePcodeOp.PTRSUBop as&st->f. An equivalent SLEIGH expression isbase + offset.NOTE: This op is always a result of decompiler simplification, not low p-code generation, and so are not ordinarily used by a
PcodeExecutor.- Parameters:
sizeout- the size (in bytes) of the output variablesizeinBase- the size (in bytes) of the variable used for the structure's base addressinBase- the value used as the structure's base addresssizeinOffset- the size (in bytes) of the variable used for the offsetinOffset- the value used as the offset- Returns:
- the output value
-
modBeforeStore
Apply any modifications before a value is storedThis implements any abstractions associated with
PcodeOp.STORE. This is called on the offset and the value before the value is actually stored into the state. NOTE: STORE ops always quantize the offset.- Parameters:
sizeinOffset- the size (in bytes) of the variable used for indirectionspace- the address spaceinOffset- the value used as the address (or offset)sizeinValue- the size (in bytes) of the variable to store and of the output variableinValue- the value to store- Returns:
- the modified value to store
-
modBeforeStore
Apply any modifications before a value is storedThis provides the full p-code op, allowing deeper inspection of the code. NOTE: STORE ops always quantize the offset.
- Parameters:
op- the operationspace- the address spaceinOffset- the value used as the offsetinValue- the value to store- Returns:
- the modified value to store
-
modAfterLoad
Apply any modifications after a value is loadedThis implements any abstractions associated with
PcodeOp.LOAD. This is called on the address/offset and the value after the value is actually loaded from the state. NOTE: LOAD ops always quantize the offset.- Parameters:
sizeinOffset- the size (in bytes) of the variable used for indirectionspace- the address spaceinOffset- the value used as the offsetsizeinValue- the size (in bytes) of the variable loaded and of the output variableinValue- the value loaded- Returns:
- the modified value loaded
-
modAfterLoad
Apply any modifications after a value is loadedThis provides the full p-code op, allowing deeper inspection of the code. NOTE: LOAD ops always quantize the offset.
- Parameters:
op- the operationspace- the address spaceinOffset- the value used as the offsetinValue- the value loaded- Returns:
- the modified value loaded
-
fromConst
Convert the given constant concrete value to typeThaving the same size.- Parameters:
value- the constant value- Returns:
- the value as a
T
-
fromConst
Convert abytetoT, with unsigned extension- Parameters:
value- the constant valuesize- the size in bytes- Returns:
- the value
-
fromConst
Convert ashorttoT, with unsigned extension- Parameters:
value- the constant valuesize- the size in bytes- Returns:
- the value
-
fromConst
Convert aninttoT, with unsigned extension- Parameters:
value- the constant valuesize- the size in bytes- Returns:
- the value
-
fromConst
Convert the given constant concrete value to typeThaving the given size.Note that the size may not be applicable to
T. It is given to ensure the value can be held in a variable of that size when passed to downstream operators or stored in the executor state.- Parameters:
value- the constant valuesize- the size (in bytes) of the variable into which the value is to be stored- Returns:
- the value as a
T
-
fromConst
Convert afloattoTIf size is not 4, bytes are truncated or passed with 0s, according to machine endianness.
- Parameters:
value- the constant valuesize- the size in bytes- Returns:
- the value
-
fromConst
Convert adoubletoTIf size is not 8, bytes are truncated or passed with 0s, according to machine endianness.
- Parameters:
value- the constant valuesize- the size in bytes- Returns:
- the value
-
fromConst
Convert abooleantoTtrueis represented as 1, andfalseas 0, padded to the given size.- Parameters:
value- the constant valuesize- the size in bytes- Returns:
- the value
-
fromConst
Convert the given constant concrete value to typeThaving the given size.Note that the size may not be applicable to
T. It is given to ensure the value can be held in a variable of that size when passed to downstream operators or stored in the executor state.- Parameters:
value- the constant valuesize- the size (in bytes) of the variable into which the value is to be storedisContextreg- true to indicate the value is from the disassembly context register. IfTrepresents bytes, and the value is the contextreg, then the bytes are in big endian, no matter the machine language's endianness.- Returns:
- the value as a
T
-
fromConst
Convert the given constant concrete register value to typeT- Parameters:
value- the register value- Returns:
- the value as a
T
-
fromConst
Convert the given constant concrete value to typeThaving the given size.The value is assumed not to be for the disassembly context register.
- Parameters:
value- the constant valuesize- the size (in bytes) of the variable into which the value is to be stored- Returns:
- the value as a
T - See Also:
-
toConcrete
Convert, if possible, the given abstract value to a concrete byte array- Parameters:
value- the abstract valuepurpose- the purpose for which the emulator needs a concrete value- Returns:
- the array
- Throws:
ConcretionError- if the value cannot be made concrete
-
isTrue
Convert, if possible, the given abstract condition to a concrete boolean value- Parameters:
cond- the abstract conditionpurpose- probablyPcodeArithmetic.Purpose.CONDITION- Returns:
- the boolean value
-
toRegisterValue
Convert, if possible, the given abstract value to a concrete register value- Parameters:
register- the registervalue- the abstract valuepurpose- the reason why the emulator needs a concrete value- Returns:
- the concrete value
- Throws:
ConcretionError- if the value cannot be made concrete
-
toBigInteger
Convert, if possible, the given abstract value to a concrete big integerIf the conversion is not possible, throw an exception.
- Parameters:
value- the abstract valuepurpose- the reason why the emulator needs a concrete value- Returns:
- the concrete value
- Throws:
ConcretionError- if the value cannot be made concrete
-
toLong
Convert, if possible, the given abstract value to a concrete longIf the conversion is not possible, throw an exception.
- Parameters:
value- the abstract valuepurpose- the reason why the emulator needs a concrete value- Returns:
- the concrete value
- Throws:
ConcretionError- if the value cannot be made concrete
-
toFloat
Convert, if possible, the given abstract value to a concrete floatIf value does not have size 4, it is truncated or padded, according to machine endianness, before the raw bits are converted to a float.
- Parameters:
value- the abstract valuepurpose- the reason why the emulator needs a concrete value- Returns:
- the concrete value
- Throws:
ConcretionError- if the value cannot be made concrete
-
toDouble
Convert, if possible, the given abstract value to a concrete doubleIf value does not have size 8, it is truncated or padded, according to machine endianness, before the raw bits are converted to a double.
- Parameters:
value- the abstract valuepurpose- the reason why the emulator needs a concrete value- Returns:
- the concrete value
- Throws:
ConcretionError- if the value cannot be made concrete
-
toBoolean
Convert, if possible, the given abstract value to a concrete booleanAny non-zero value is considered true
- Parameters:
value- the abstract valuepurpose- the reason why the emulator needs a concrete value- Returns:
- the concrete value
- Throws:
ConcretionError- if the value cannot be made concrete
-
sizeOf
Get the size in bytes, if possible, of the given abstract valueIf the abstract value does not conceptually have a size, throw an exception.
- Parameters:
value- the abstract value- Returns:
- the size in bytes
-
sizeOfAbstract
Get the size in bytes, if possible, of the given abstract value, as an abstract valueThe returned size should itself has a size of
SIZEOF_SIZEOF.- Parameters:
value- the abstract value- Returns:
- the size in bytes, as an abstract value
-