54 static const char arrange[];
56 void complement(
void);
57 bool convertToBoolean(
void);
58 static bool newStride(uintb mask,int4 step,int4 oldStep,uint4 rem,uintb &myleft,uintb &myright);
59 static bool newDomain(uintb newMask,int4 newStep,uintb &myleft,uintb &myright);
60 static char encodeRangeOverlaps(uintb op1left,uintb op1right,uintb op2left,uintb op2right);
63 CircleRange(uintb lft,uintb rgt,int4 size,int4 stp);
66 void setRange(uintb lft,uintb rgt,int4 size,int4 step);
69 bool isEmpty(
void)
const {
return isempty; }
70 bool isFull(
void)
const {
return ((!isempty) && (step == 1) && (left == right)); }
71 bool isSingle(
void)
const {
return (!isempty) && (right == ((left + step)& mask)); }
72 uintb
getMin(
void)
const {
return left; }
73 uintb
getMax(
void)
const {
return (right-step)&mask; }
74 uintb
getEnd(
void)
const {
return right; }
75 uintb
getMask(
void)
const {
return mask; }
80 bool getNext(uintb &val)
const { val = (val+step)&mask;
return (val!=right); }
95 int4 inSize,int4 outSize,int4 maxStep);
137 vector<Equation> equations;
140 bool doesEquationApply(int4 num,int4 slot)
const;
142 void setVarnode(
Varnode *v,int4 tCode);
143 void addEquation(int4 slot,int4 type,
const CircleRange &constraint);
144 void addLandmark(int4 type,
const CircleRange &constraint) { addEquation(numParams,type,constraint); }
145 bool computeTypeCode(
void);
146 bool iterate(
Widener &widener);
183 int4 equationTypeCode;
186 void setPcodeOp(
PcodeOp *o,int4 slt);
187 void addEquation(int4 slt,int4 type,
const CircleRange &constraint);
210 virtual int4 determineIterationReset(
const ValueSet &valueSet)=0;
216 virtual bool checkFreeze(
const ValueSet &valueSet)=0;
239 WidenerFull(int4 wide,int4 full) { widenIteration = wide; fullIteration = full; }
240 virtual int4 determineIterationReset(
const ValueSet &valueSet);
241 virtual bool checkFreeze(
const ValueSet &valueSet);
253 int4 freezeIteration;
256 virtual int4 determineIterationReset(
const ValueSet &valueSet);
257 virtual bool checkFreeze(
const ValueSet &valueSet);
280 const vector<ValueSet *> *rootEdges;
283 list<PcodeOp *>::const_iterator iter;
285 ValueSetEdge(
ValueSet *node,
const vector<ValueSet *> &roots);
289 list<ValueSet> valueNodes;
290 map<SeqNum,ValueSetRead> readNodes;
292 list<Partition> recordStorage;
293 vector<ValueSet *> rootNodes;
294 vector<ValueSet *> nodeStack;
295 int4 depthFirstIndex;
298 void newValueSet(
Varnode *vn,int4 tCode);
304 void establishTopologicalOrder(
void);
309 void constraintsFromCBranch(
PcodeOp *cbranch);
310 void generateConstraints(
const vector<Varnode *> &worklist,
const vector<PcodeOp *> &reads);
311 bool checkRelativeConstant(
Varnode *vn,int4 &typeCode,uintb &value)
const;
312 void generateRelativeConstraint(
PcodeOp *compOp,
PcodeOp *cbranch);
314 void establishValueSets(
const vector<Varnode *> &sinks,
const vector<PcodeOp *> &reads,
Varnode *stackReg,
bool indirectAsCopy);
316 void solve(int4 max,
Widener &widener);
317 list<ValueSet>::const_iterator
beginValueSets(
void)
const {
return valueNodes.begin(); }
318 list<ValueSet>::const_iterator
endValueSets(
void)
const {
return valueNodes.end(); }
319 map<SeqNum,ValueSetRead>::const_iterator
beginValueSetReads(
void)
const {
return readNodes.begin(); }
320 map<SeqNum,ValueSetRead>::const_iterator
endValueSetReads(
void)
const {
return readNodes.end(); }
323 void dumpValueSets(ostream &s)
const;
332 if (isempty != op2.isempty)
return false;
333 if (isempty)
return true;
334 return (left == op2.left) && (right == op2.right) && (mask == op2.mask) && (step == op2.step);
356 inline char CircleRange::encodeRangeOverlaps(uintb op1left, uintb op1right, uintb op2left, uintb op2right)
359 int4 val = (op1left <= op1right) ? 0x20 : 0;
360 val |= (op1left <= op2left) ? 0x10 : 0;
361 val |= (op1left <= op2right) ? 0x8 : 0;
362 val |= (op1right <= op2left) ? 4 : 0;
363 val |= (op1right <= op2right) ? 2 : 0;
364 val |= (op2left <= op2right) ? 1 : 0;
373 inline bool ValueSet::doesEquationApply(int4 num,int4 slot)
const 376 if (num < equations.size()) {
377 if (equations[num].slot == slot) {
378 if (equations[num].typeCode == typeCode)
390 vertex->next = part.startNode;
391 part.startNode = vertex;
393 part.stopNode = vertex;
401 head.stopNode->next = part.startNode;
402 part.startNode = head.startNode;
404 part.stopNode = head.stopNode;
int4 getMaxInfo(void) const
Get maximum information content of range.
Definition: rangeutil.cc:278
CircleRange(void)
Construct an empty range.
Definition: rangeutil.hh:62
bool pullBackBinary(OpCode opc, uintb val, int4 slot, int4 inSize, int4 outSize)
Pull-back this thru binary operator.
Definition: rangeutil.cc:797
A range of nodes (within the weak topological ordering) that are iterated together.
Definition: rangeutil.hh:159
void printRaw(ostream &s) const
Write a text representation of this to stream.
Definition: rangeutil.cc:1456
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
bool pullBackUnary(OpCode opc, int4 inSize, int4 outSize)
Pull-back this through the given unary operator.
Definition: rangeutil.cc:726
bool isEmpty(void) const
Return true if this range is empty.
Definition: rangeutil.hh:69
Class for freezing value sets at a specific iteration (to accelerate convergence) ...
Definition: rangeutil.hh:252
WidenerFull(void)
Constructor with default iterations.
Definition: rangeutil.hh:238
const CircleRange & getRange(void) const
Get the actual range of values.
Definition: rangeutil.hh:190
const CircleRange & getRange(void) const
Get the actual range of values.
Definition: rangeutil.hh:152
list< ValueSet >::const_iterator endValueSets(void) const
End of all ValueSets in the system.
Definition: rangeutil.hh:318
Partition(void)
Construct empty partition.
Definition: rangeutil.hh:165
map< SeqNum, ValueSetRead >::const_iterator beginValueSetReads(void) const
Start of ValueSetReads.
Definition: rangeutil.hh:319
list< ValueSet >::const_iterator beginValueSets(void) const
Start of all ValueSets in the system.
Definition: rangeutil.hh:317
Equation(int4 s, int4 tc, const CircleRange &rng)
Constructor.
Definition: rangeutil.hh:125
int4 translate2Op(OpCode &opc, uintb &c, int4 &cslot) const
Translate range to a comparison op.
Definition: rangeutil.cc:1410
bool isLeftStable(void) const
Return true if the left boundary hasn't been changing.
Definition: rangeutil.hh:191
uintb getSize(void) const
Get the size of this range.
Definition: rangeutil.cc:254
int4 getTypeCode(void) const
Return '0' for normal constant, '1' for spacebase relative.
Definition: rangeutil.hh:189
void setFull(int4 size)
Set a completely full range.
Definition: rangeutil.cc:243
void widen(const CircleRange &op2, bool leftIsStable)
Widen the unstable bound to match containing range.
Definition: rangeutil.cc:1381
int4 invert(void)
Convert to complementary range.
Definition: rangeutil.cc:531
const ValueSetRead & getValueSetRead(const SeqNum &seq)
Get ValueSetRead by SeqNum.
Definition: rangeutil.hh:321
bool isFull(void) const
Return true if this contains all possible values.
Definition: rangeutil.hh:70
Class that determines a ValueSet for each Varnode in a data-flow system.
Definition: rangeutil.hh:272
bool contains(const CircleRange &op2) const
Check containment of another range in this.
Definition: rangeutil.cc:299
A class for manipulating integer value ranges.
Definition: rangeutil.hh:48
Varnode * pullBack(PcodeOp *op, Varnode **constMarkup, bool usenzmask)
Pull-back this range through given PcodeOp.
Definition: rangeutil.cc:1012
Lowest level operation of the p-code language.
Definition: op.hh:58
virtual ~Widener(void)
Destructor.
Definition: rangeutil.hh:204
bool minimalContainer(const CircleRange &op2, int4 maxStep)
Construct minimal range that contains both this and another range.
Definition: rangeutil.cc:452
bool isRightStable(void) const
Return true if the right boundary hasn't been changing.
Definition: rangeutil.hh:192
bool operator==(const CircleRange &op2) const
Equals operator.
Definition: rangeutil.hh:329
uintb getEnd(void) const
Get the right boundary of the range.
Definition: rangeutil.hh:74
static const int4 MAX_STEP
Definition: rangeutil.hh:113
bool isRightStable(void) const
Return true if the right boundary hasn't been changing.
Definition: rangeutil.hh:154
bool pushForwardUnary(OpCode opc, const CircleRange &in1, int4 inSize, int4 outSize)
Push-forward thru given unary operator.
Definition: rangeutil.cc:1083
int4 intersect(const CircleRange &op2)
Intersect this with another range.
Definition: rangeutil.cc:547
map< SeqNum, ValueSetRead >::const_iterator endValueSetReads(void) const
End of ValueSetReads.
Definition: rangeutil.hh:320
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
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.
Definition: rangeutil.cc:1367
void setStride(int4 newStep, uintb rem)
Set a new step on this range.
Definition: rangeutil.cc:705
int4 getNumIterations(void) const
Get the current number of iterations.
Definition: rangeutil.hh:315
bool pushForwardBinary(OpCode opc, const CircleRange &in1, const CircleRange &in2, int4 inSize, int4 outSize, int4 maxStep)
Push this range forward through a binary operation.
Definition: rangeutil.cc:1165
Class holding a particular widening strategy for the ValueSetSolver iteration algorithm.
Definition: rangeutil.hh:202
int4 getSize(void) const
Get the number of bytes this Varnode stores.
Definition: varnode.hh:170
uintb getMin(void) const
Get the left boundary of the range.
Definition: rangeutil.hh:72
Varnode * getVarnode(void) const
Get the Varnode attached to this ValueSet.
Definition: rangeutil.hh:151
WidenerFull(int4 wide, int4 full)
Constructor specifying iterations.
Definition: rangeutil.hh:239
bool isLeftStable(void) const
Return true if the left boundary hasn't been changing.
Definition: rangeutil.hh:153
An external that can be applied to a ValueSet.
Definition: rangeutil.hh:119
void setRange(uintb lft, uintb rgt, int4 size, int4 step)
Set directly to a specific range.
Definition: rangeutil.cc:217
Class for doing normal widening.
Definition: rangeutil.hh:234
bool isSingle(void) const
Return true if this contains single value.
Definition: rangeutil.hh:71
bool setNZMask(uintb nzmask, int4 size)
Set the range based on a putative mask.
Definition: rangeutil.cc:670
int4 getCount(void) const
Get the current iteration count.
Definition: rangeutil.hh:148
bool getNext(uintb &val) const
Advance an integer within the range.
Definition: rangeutil.hh:80
The PcodeOp and PcodeOpBank classes.
int4 circleUnion(const CircleRange &op2)
Union two ranges.
Definition: rangeutil.cc:358
uintb getMax(void) const
Get the right-most integer contained in the range.
Definition: rangeutil.hh:73
A special form of ValueSet associated with the read point of a Varnode.
Definition: rangeutil.hh:176
A range of values attached to a Varnode within a data-flow subsystem.
Definition: rangeutil.hh:111
int4 getStep(void) const
Get the step for this range.
Definition: rangeutil.hh:77
int4 getTypeCode(void) const
Return '0' for normal constant, '1' for spacebase relative.
Definition: rangeutil.hh:150
uintb getMask(void) const
Get the mask.
Definition: rangeutil.hh:75
A class for uniquely labelling and comparing PcodeOps.
Definition: address.hh:111