Ghidra Decompiler Analysis Engine
Public Member Functions | List of all members
CircleRange Class Reference

A class for manipulating integer value ranges. More...

#include <rangeutil.hh>

Public Member Functions

 CircleRange (uintb lft, uintb rgt, int4 size, int4 stp)
 Construct given specific boundaries. More...
 
 CircleRange (bool val)
 Construct a boolean range. More...
 
 CircleRange (uintb val, int4 size)
 Construct range with single value. More...
 
void setRange (uintb lft, uintb rgt, int4 size, int4 step)
 Set directly to a specific range. More...
 
void setRange (uintb val, int4 size)
 Set range with a single value. More...
 
void setFull (int4 size)
 Set a completely full range. More...
 
uintb getSize (void) const
 Get the size of this range. More...
 
int4 getMaxInfo (void) const
 Get maximum information content of range. More...
 
bool operator== (const CircleRange &op2) const
 Equals operator. More...
 
bool contains (const CircleRange &op2) const
 Check containment of another range in this. More...
 
bool contains (uintb val) const
 Check containment of a specific integer. More...
 
int4 intersect (const CircleRange &op2)
 Intersect this with another range. More...
 
bool setNZMask (uintb nzmask, int4 size)
 Set the range based on a putative mask. More...
 
int4 circleUnion (const CircleRange &op2)
 Union two ranges. More...
 
bool minimalContainer (const CircleRange &op2, int4 maxStep)
 Construct minimal range that contains both this and another range. More...
 
int4 invert (void)
 Convert to complementary range. More...
 
void setStride (int4 newStep, uintb rem)
 Set a new step on this range. More...
 
bool pullBackUnary (OpCode opc, int4 inSize, int4 outSize)
 Pull-back this through the given unary operator. More...
 
bool pullBackBinary (OpCode opc, uintb val, int4 slot, int4 inSize, int4 outSize)
 Pull-back this thru binary operator. More...
 
VarnodepullBack (PcodeOp *op, Varnode **constMarkup, bool usenzmask)
 Pull-back this range through given PcodeOp. More...
 
bool pushForwardUnary (OpCode opc, const CircleRange &in1, int4 inSize, int4 outSize)
 Push-forward thru given unary operator. More...
 
bool pushForwardBinary (OpCode opc, const CircleRange &in1, const CircleRange &in2, int4 inSize, int4 outSize, int4 maxStep)
 Push this range forward through a binary operation. More...
 
bool pushForwardTrinary (OpCode opc, const CircleRange &in1, const CircleRange &in2, const CircleRange &in3, int4 inSize, int4 outSize, int4 maxStep)
 Push this range forward through a trinary operation. More...
 
void widen (const CircleRange &op2, bool leftIsStable)
 Widen the unstable bound to match containing range. More...
 
int4 translate2Op (OpCode &opc, uintb &c, int4 &cslot) const
 Translate range to a comparison op. More...
 
void printRaw (ostream &s) const
 Write a text representation of this to stream. More...
 

Detailed Description

A class for manipulating integer value ranges.

The idea is to have a representation of common sets of values that a varnode might take on in analysis so that the representation can be manipulated symbolically to some extent. The representation is a circular range (determined by a half-open interval [left,right)), over the integers mod 2^n, where mask = 2^n-1. The range can support a step, if some of the least significant bits of the mask are set to zero.

The class then can

val = range.getMin();
do {
} while(range.getNext(val));

Constructor & Destructor Documentation

◆ CircleRange() [1/3]

CircleRange::CircleRange ( uintb  lft,
uintb  rgt,
int4  size,
int4  stp 
)

Construct given specific boundaries.

Give specific left/right boundaries and step information. The first element in the set is given left boundary. The sequence then proceeds by the given step up to (but not including) the given right boundary. Care should be taken to make sure the remainders of the left and right boundaries modulo the step are equal.

Parameters
lftis the left boundary of the range
rgtis the right boundary of the range
sizeis the domain size in bytes (1,2,4,8,..)
stpis the desired step (1,2,4,8,..)

◆ CircleRange() [2/3]

CircleRange::CircleRange ( bool  val)

Construct a boolean range.

The range contains only a single integer, 0 or 1, depending on the boolean parameter.

Parameters
valis the boolean parameter

◆ CircleRange() [3/3]

CircleRange::CircleRange ( uintb  val,
int4  size 
)

Construct range with single value.

A size specifies the number of bytes (*8 to get number of bits) in the mask. The stride is assumed to be 1.

Parameters
valis is the single value
sizeis the size of the mask in bytes

Member Function Documentation

◆ circleUnion()

int4 CircleRange::circleUnion ( const CircleRange op2)

Union two ranges.

Set this to the union of this and op2 as a single interval. Return 0 if the result is valid. Return 2 if the union is two pieces. If result is not zero, this is not modified.

Parameters
op2is the range to union with
Returns
the result code

◆ contains() [1/2]

bool CircleRange::contains ( const CircleRange op2) const

Check containment of another range in this.

Parameters
op2is the specific range to test for containment.
Returns
true if this contains the interval op2

◆ contains() [2/2]

bool CircleRange::contains ( uintb  val) const

Check containment of a specific integer.

Check if a specific integer is a member of this range.

Parameters
valis the specific integer
Returns
true if it is contained in this

◆ getMaxInfo()

int4 CircleRange::getMaxInfo ( void  ) const

Get maximum information content of range.

In this context, the information content of a value is the index (+1) of the most significant non-zero bit (of the absolute value). This routine returns the maximum information across all values in the range.

Returns
the maximum information

◆ getSize()

uintb CircleRange::getSize ( void  ) const

Get the size of this range.

Returns
the number of integers contained in this range

◆ intersect()

int4 CircleRange::intersect ( const CircleRange op2)

Intersect this with another range.

Set this to the intersection of this and op2 as a single interval if possible. Return 0 if the result is valid Return 2 if the intersection is two pieces If result is not zero, this is not modified

Parameters
op2is the second range
Returns
the intersection code

◆ invert()

int4 CircleRange::invert ( void  )

Convert to complementary range.

Convert range to its complement. The step is automatically converted to 1 first.

Returns
the original step size

◆ minimalContainer()

bool CircleRange::minimalContainer ( const CircleRange op2,
int4  maxStep 
)

Construct minimal range that contains both this and another range.

Turn this into a range that contains both the original range and the other given range. The resulting range may contain values that were in neither of the original ranges (not a strict union). But the number of added values will be minimal. This method will create a range with step if the input ranges hold single values and the distance between them is a power of 2 and less or equal than a given bound.

Parameters
op2is the other given range to combine with this
maxStepis the step bound that can be induced for a container with two singles
Returns
true if the container is everything (full)

◆ operator==()

bool CircleRange::operator== ( const CircleRange op2) const
inline

Equals operator.

Parameters
op2is the range to compare this to
Returns
true if the two ranges are equal

◆ printRaw()

void CircleRange::printRaw ( ostream &  s) const

Write a text representation of this to stream.

Parameters
sis the stream to write to

◆ pullBack()

Varnode * CircleRange::pullBack ( PcodeOp op,
Varnode **  constMarkup,
bool  usenzmask 
)

Pull-back this range through given PcodeOp.

The pull-back is performed through a given p-code op and set this to the resulting range (if possible). If there is a single unknown input, and the set of values for this input that cause the output of op to fall into this form a range, then set this to the range (the "pullBack") and return the unknown varnode. Return null otherwise.

We may know something about the input varnode in the form of its NZMASK, which can further restrict the range we return. If usenzmask is true, and NZMASK forms a range, intersect this with the result.

If there is Symbol markup on any constant passed into the op, pass that information back.

Parameters
opis the given PcodeOp
constMarkupis the reference for passing back the constant relevant to the pull-back
usenzmaskspecifies whether to use the NZMASK
Returns
the input Varnode or NULL

◆ pullBackBinary()

bool CircleRange::pullBackBinary ( OpCode  opc,
uintb  val,
int4  slot,
int4  inSize,
int4  outSize 
)

Pull-back this thru binary operator.

Parameters
opcis the OpCode to pull the range back through
valis the constant value of the other input parameter (if present)
slotis the slot of the input variable whose range gets produced
inSizeis the storage size in bytes of the resulting input
outSizeis the storage size in bytes of the range to pull-back
Returns
true if a valid range is formed in the pull-back

◆ pullBackUnary()

bool CircleRange::pullBackUnary ( OpCode  opc,
int4  inSize,
int4  outSize 
)

Pull-back this through the given unary operator.

Parameters
opcis the OpCode to pull the range back through
inSizeis the storage size in bytes of the resulting input
outSizeis the storage size in bytes of the range to pull-back
Returns
true if a valid range is formed in the pull-back

◆ pushForwardBinary()

bool CircleRange::pushForwardBinary ( OpCode  opc,
const CircleRange in1,
const CircleRange in2,
int4  inSize,
int4  outSize,
int4  maxStep 
)

Push this range forward through a binary operation.

Push all values in the given ranges through a binary p-code operator. If the output set of values forms a range, then set this to the range and return true.

Parameters
opcis the given p-code operator
in1is the first given input range
in2is the second given input range
inSizeis the storage space in bytes for the input
outSizeis the storage space in bytes for the output
maxStepis the maximum to allow step to grow via multiplication
Returns
true if the result is known and forms a range

◆ pushForwardTrinary()

bool CircleRange::pushForwardTrinary ( OpCode  opc,
const CircleRange in1,
const CircleRange in2,
const CircleRange in3,
int4  inSize,
int4  outSize,
int4  maxStep 
)

Push this range forward through a trinary operation.

Push all values in the given ranges through a trinary p-code operator (currenly only CPUI_PTRADD). If the output set of values forms a range, then set this to the range and return true.

Parameters
opcis the given p-code operator
in1is the first given input range
in2is the second given input range
in3is the third given input range
inSizeis the storage space in bytes for the input
outSizeis the storage space in bytes for the output
maxStepis the maximum to allow step to grow via multiplication
Returns
true if the result is known and forms a range

◆ pushForwardUnary()

bool CircleRange::pushForwardUnary ( OpCode  opc,
const CircleRange in1,
int4  inSize,
int4  outSize 
)

Push-forward thru given unary operator.

Push all values in the given range through a p-code operator. If the output set of values forms a range, then set this to the range and return true.

Parameters
opcis the given p-code operator
in1is the given input range
inSizeis the storage space in bytes for the input
outSizeis the storage space in bytes for the output
Returns
true if the result is known and forms a range

◆ setFull()

void CircleRange::setFull ( int4  size)

Set a completely full range.

Make a range of values that holds everything.

Parameters
sizeis the size (in bytes) of the range

◆ setNZMask()

bool CircleRange::setNZMask ( uintb  nzmask,
int4  size 
)

Set the range based on a putative mask.

Try to create a range given a value that is not necessarily a valid mask. If the mask is valid, range is set to all possible values that whose non-zero bits are contained in the mask. If the mask is invalid, this range is not modified.

Parameters
nzmaskis the putative mask
sizeis a maximum size (in bytes) for the mask
Returns
true if the mask is valid

◆ setRange() [1/2]

void CircleRange::setRange ( uintb  lft,
uintb  rgt,
int4  size,
int4  stp 
)

Set directly to a specific range.

Parameters
lftis the left boundary of the range
rgtis the right boundary of the range
sizeis the size of the range domain in bytes
stpis the step/stride of the range

◆ setRange() [2/2]

void CircleRange::setRange ( uintb  val,
int4  size 
)

Set range with a single value.

A size specifies the number of bytes (*8 to get number of bits) in the mask. The stride is assumed to be 1.

Parameters
valis is the single value
sizeis the size of the mask in bytes

◆ setStride()

void CircleRange::setStride ( int4  newStep,
uintb  rem 
)

Set a new step on this range.

This method changes the step for this range, i.e. elements are removed. The boundaries of the range do not change except for the remainder modulo the new step.

Parameters
newStepis the new step amount
remis the desired phase (remainder of the values modulo the step)

◆ translate2Op()

int4 CircleRange::translate2Op ( OpCode opc,
uintb &  c,
int4 &  cslot 
) const

Translate range to a comparison op.

Recover parameters for a comparison PcodeOp, that returns true for input values exactly in this range. Return:

  • 0 on success
  • 1 if all inputs must return true
  • 2 if this is not possible
  • 3 if no inputs must return true
    Parameters
    opcwill contain the OpCode for the comparison PcodeOp
    cwill contain the constant input to the op
    cslotwill indicate the slot holding the constant
    Returns
    the success code

◆ widen()

void CircleRange::widen ( const CircleRange op2,
bool  leftIsStable 
)

Widen the unstable bound to match containing range.

Widen this range so at least one of the boundaries matches with the given range, which must contain this.

Parameters
op2is the given containing range
leftIsStableis true if we want to match right boundaries

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