Interface PcodeArithmetic<T>
- Type Parameters:
T
- the type of values operated on
- All Known Implementing Classes:
AddressesReadPcodeArithmetic
,BytesPcodeArithmetic
,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
Modifier and TypeInterfaceDescriptionstatic enum
Reasons for requiring a concrete value -
Field Summary
Modifier and TypeFieldDescriptionstatic final int
The 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 T
Apply a binary operator to the given inputfromConst
(byte[] value) Convert the given constant concrete value to typeT
having the same size.default T
fromConst
(long value, int size) Convert the given constant concrete value to typeT
having the given size.default T
fromConst
(BigInteger value, int size) Convert the given constant concrete value to typeT
having the given size.default T
fromConst
(BigInteger value, int size, boolean isContextreg) Convert the given constant concrete value to typeT
having the given size.Get the endianness of this arithmeticdefault boolean
isTrue
(T cond, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract condition to a concrete boolean valuemodAfterLoad
(int sizeout, int sizeinAddress, T inAddress, int sizeinValue, T inValue) Apply any modifications after a value is loadedmodBeforeStore
(int sizeout, int sizeinAddress, T inAddress, int sizeinValue, T inValue) Apply any modifications before a value is storeddefault T
Apply thePcodeOp.PTRADD
operator to the given inputsdefault T
Apply thePcodeOp.PTRSUB
operator to the given inputslong
Get the size in bytes, if possible, of the given abstract valuedefault T
sizeOfAbstract
(T value) Get the size in bytes, if possible, of the given abstract value, as an abstract valuedefault BigInteger
toBigInteger
(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete big integerbyte[]
toConcrete
(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete byte arraydefault long
toLong
(T value, PcodeArithmetic.Purpose purpose) Convert, if possible, the given abstract value to a concrete longApply a unary operator to the given inputdefault T
Apply 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
BigInteger
may 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
-
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
-
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
BigInteger
may 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
-
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
-
ptrAdd
Apply thePcodeOp.PTRADD
operator 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
size
operand must be constant. Supposearr
is an array whose elements aresize
bytes each, and the address of its first element isbase
. The decompiler would likely render thePcodeOp.PTRADD
op 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.PTRSUB
operator 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
. Supposest
is a structure pointer with a fieldf
locatedinOffset
bytes into the structure, andst
has the valuebase
. The decompiler would likely render thePcodeOp.PTRSUB
op 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 address/offset and the value before the value is actually stored into the state.- Parameters:
sizeout
- the size (in bytes) of the output variablesizeinAddress
- the size (in bytes) of the variable used for indirectioninAddress
- the value used as the address (or offset)sizeinValue
- the size (in bytes) of the variable to storeinValue
- 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.- Parameters:
sizeout
- the size (in bytes) of the output variablesizeinAddress
- the size (in bytes) of the variable used for indirectioninAddress
- the value used as the address (or offset)sizeinValue
- the size (in bytes) of the variable loadedinValue
- the value loaded- Returns:
- the modified value loaded
-
fromConst
Convert the given constant concrete value to typeT
having the same size.- Parameters:
value
- the constant value- Returns:
- the value as a
T
-
fromConst
Convert the given constant concrete value to typeT
having 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 the given constant concrete value to typeT
having 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. IfT
represents 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 value to typeT
having the given size.The value is assumed not to be for the disassembly context register.
- 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
-
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
-
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
-