New flag for dynamic STORE test

This commit is contained in:
caheckman 2019-06-25 14:23:05 -04:00
parent b6b9b27128
commit cb39d39a23
11 changed files with 67 additions and 88 deletions

View file

@ -2494,8 +2494,8 @@ void ActionMarkExplicit::checkNewToConstructor(Funcdata &data,Varnode *vn)
if (firstuse->numInput() < 2) return; // Must have at least 1 parameter (plus destination varnode) if (firstuse->numInput() < 2) return; // Must have at least 1 parameter (plus destination varnode)
if (firstuse->getIn(1) != vn) return; // First parameter must result of new if (firstuse->getIn(1) != vn) return; // First parameter must result of new
// if (!fc->isConstructor()) return; // Function must be a constructor // if (!fc->isConstructor()) return; // Function must be a constructor
data.opSetFlag(firstuse,PcodeOp::special_print); // Mark call to print the new operator as well data.opMarkSpecialPrint(firstuse); // Mark call to print the new operator as well
data.opSetFlag(op,PcodeOp::nonprinting); // Don't print the new operator as stand-alone operation data.opMarkNonPrinting(op); // Don't print the new operator as stand-alone operation
} }
int4 ActionMarkExplicit::apply(Funcdata &data) int4 ActionMarkExplicit::apply(Funcdata &data)

View file

@ -212,7 +212,7 @@ void FlowInfo::newAddress(PcodeOp *from,const Address &to)
if (seenInstruction(to)) { // If we have seen this address before if (seenInstruction(to)) { // If we have seen this address before
PcodeOp *op = target(to); PcodeOp *op = target(to);
data.opSetFlag(op,PcodeOp::startbasic); data.opMarkStartBasic(op);
return; return;
} }
addrlist.push_back(to); addrlist.push_back(to);
@ -255,7 +255,7 @@ PcodeOp *FlowInfo::xrefControlFlow(list<PcodeOp *>::const_iterator oiter,bool &s
while(oiter != obank.endDead()) { while(oiter != obank.endDead()) {
op = *oiter++; op = *oiter++;
if (startbasic) { if (startbasic) {
data.opSetFlag(op,PcodeOp::startbasic); data.opMarkStartBasic(op);
startbasic = false; startbasic = false;
} }
switch(op->code()) { switch(op->code()) {
@ -266,7 +266,7 @@ PcodeOp *FlowInfo::xrefControlFlow(list<PcodeOp *>::const_iterator oiter,bool &s
Address fallThruAddr; Address fallThruAddr;
PcodeOp *destop = findRelTarget(op,fallThruAddr); PcodeOp *destop = findRelTarget(op,fallThruAddr);
if (destop != (PcodeOp *)0) { if (destop != (PcodeOp *)0) {
data.opSetFlag(destop,PcodeOp::startbasic); // Make sure the target op is a basic block start data.opMarkStartBasic(destop); // Make sure the target op is a basic block start
uintm newtime = destop->getTime(); uintm newtime = destop->getTime();
if (newtime > maxtime) if (newtime > maxtime)
maxtime = newtime; maxtime = newtime;
@ -286,7 +286,7 @@ PcodeOp *FlowInfo::xrefControlFlow(list<PcodeOp *>::const_iterator oiter,bool &s
Address fallThruAddr; Address fallThruAddr;
PcodeOp *destop = findRelTarget(op,fallThruAddr); PcodeOp *destop = findRelTarget(op,fallThruAddr);
if (destop != (PcodeOp *)0) { if (destop != (PcodeOp *)0) {
data.opSetFlag(destop,PcodeOp::startbasic); // Make sure the target op is a basic block start data.opMarkStartBasic(destop); // Make sure the target op is a basic block start
uintm newtime = destop->getTime(); uintm newtime = destop->getTime();
if (newtime > maxtime) if (newtime > maxtime)
maxtime = newtime; maxtime = newtime;
@ -456,7 +456,7 @@ bool FlowInfo::processInstruction(const Address &curaddr,bool &startbasic)
if (oiter != obank.endDead()) { if (oiter != obank.endDead()) {
stat.seqnum = (*oiter)->getSeqNum(); stat.seqnum = (*oiter)->getSeqNum();
data.opSetFlag(*oiter,PcodeOp::startmark); // Mark the first op in the instruction data.opMarkStartInstruction(*oiter); // Mark the first op in the instruction
if (flowoverride != Override::NONE) if (flowoverride != Override::NONE)
data.overrideFlow(curaddr,flowoverride); data.overrideFlow(curaddr,flowoverride);
xrefControlFlow(oiter,startbasic,isfallthru,(FuncCallSpecs *)0); xrefControlFlow(oiter,startbasic,isfallthru,(FuncCallSpecs *)0);
@ -484,7 +484,7 @@ bool FlowInfo::setFallthruBound(Address &bound)
if (addr == (*iter).first) { // If we have already visited this address if (addr == (*iter).first) { // If we have already visited this address
addrlist.pop_back(); // Throw it away addrlist.pop_back(); // Throw it away
PcodeOp *op = target(addr); // But make sure the address PcodeOp *op = target(addr); // But make sure the address
data.opSetFlag(op,PcodeOp::startbasic); // starts a basic block data.opMarkStartBasic(op); // starts a basic block
return false; return false;
} }
if (addr < (*iter).first + (*iter).second.size) if (addr < (*iter).first + (*iter).second.size)
@ -555,7 +555,7 @@ void FlowInfo::fallthru(void)
if (bound == addrlist.back()) { // Hit the bound exactly if (bound == addrlist.back()) { // Hit the bound exactly
if (startbasic) { if (startbasic) {
PcodeOp *op = target(addrlist.back()); PcodeOp *op = target(addrlist.back());
data.opSetFlag(op,PcodeOp::startbasic); data.opMarkStartBasic(op);
} }
addrlist.pop_back(); addrlist.pop_back();
break; break;
@ -828,7 +828,7 @@ void FlowInfo::findUnprocessed(void)
for(iter=addrlist.begin();iter!=addrlist.end();++iter) { for(iter=addrlist.begin();iter!=addrlist.end();++iter) {
if (seenInstruction(*iter)) { if (seenInstruction(*iter)) {
PcodeOp *op = target(*iter); PcodeOp *op = target(*iter);
data.opSetFlag(op,PcodeOp::startbasic); data.opMarkStartBasic(op);
} }
else else
unprocessed.push_back(*iter); unprocessed.push_back(*iter);
@ -868,7 +868,8 @@ void FlowInfo::fillinBranchStubs(void)
dedupUnprocessed(); dedupUnprocessed();
for(iter=unprocessed.begin();iter!=unprocessed.end();++iter) { for(iter=unprocessed.begin();iter!=unprocessed.end();++iter) {
PcodeOp *op = artificialHalt(*iter,PcodeOp::missing); PcodeOp *op = artificialHalt(*iter,PcodeOp::missing);
data.opSetFlag(op,PcodeOp::startmark|PcodeOp::startbasic); data.opMarkStartBasic(op);
data.opMarkStartInstruction(op);
} }
} }
@ -1125,7 +1126,7 @@ bool FlowInfo::testHardInlineRestrictions(Funcdata *inlinefd,PcodeOp *op,Address
return false; return false;
} }
// If the inlining "jumps back" this starts a new basic block // If the inlining "jumps back" this starts a new basic block
data.opSetFlag(nextop,PcodeOp::startbasic); data.opMarkStartBasic(nextop);
} }
inline_recursion->insert(inlinefd->getAddress()); inline_recursion->insert(inlinefd->getAddress());
@ -1173,7 +1174,7 @@ void FlowInfo::doInjection(InjectPayload *payload,InjectContext &icontext,PcodeO
iter = op->getInsertIter(); iter = op->getInsertIter();
++iter; // Mark next op after the call ++iter; // Mark next op after the call
if (iter != obank.endDead()) if (iter != obank.endDead())
data.opSetFlag(*iter,PcodeOp::startbasic); // as start of basic block data.opMarkStartBasic(*iter); // as start of basic block
} }
obank.moveSequenceDead(firstop,lastop,op); // Move the injection to right after the call obank.moveSequenceDead(firstop,lastop,op); // Move the injection to right after the call
@ -1356,12 +1357,12 @@ void FlowInfo::checkContainedCall(void)
data.opSetOpcode(op,CPUI_BRANCH); data.opSetOpcode(op,CPUI_BRANCH);
// Make sure target of new goto starts a basic block // Make sure target of new goto starts a basic block
PcodeOp *targ = target(addr); PcodeOp *targ = target(addr);
data.opSetFlag(targ,PcodeOp::startbasic); data.opMarkStartBasic(targ);
// Make sure the following op starts a basic block // Make sure the following op starts a basic block
list<PcodeOp *>::const_iterator oiter = op->getInsertIter(); list<PcodeOp *>::const_iterator oiter = op->getInsertIter();
++oiter; ++oiter;
if (oiter != obank.endDead()) if (oiter != obank.endDead())
data.opSetFlag(*oiter,PcodeOp::startbasic); data.opMarkStartBasic(*oiter);
// Restore original address // Restore original address
data.opSetInput(op,data.newCodeRef(addr),0); data.opSetInput(op,data.newCodeRef(addr),0);
iter = qlst.erase(iter); // Delete the call iter = qlst.erase(iter); // Delete the call

View file

@ -413,9 +413,14 @@ public:
void opSetAllInput(PcodeOp *op,const vector<Varnode *> &vvec); ///< Set all input Varnodes for the given PcodeOp simultaneously void opSetAllInput(PcodeOp *op,const vector<Varnode *> &vvec); ///< Set all input Varnodes for the given PcodeOp simultaneously
void opRemoveInput(PcodeOp *op,int4 slot); ///< Remove a specific input slot for the given PcodeOp void opRemoveInput(PcodeOp *op,int4 slot); ///< Remove a specific input slot for the given PcodeOp
void opInsertInput(PcodeOp *op,Varnode *vn,int4 slot); ///< Insert a new Varnode into the operand list for the given PcodeOp void opInsertInput(PcodeOp *op,Varnode *vn,int4 slot); ///< Insert a new Varnode into the operand list for the given PcodeOp
void opSetFlag(PcodeOp *op,uint4 fl) { op->setFlag(fl); } ///< Set a boolean property on the given PcodeOp void opMarkStartBasic(PcodeOp *op) { op->setFlag(PcodeOp::startbasic); } ///< Mark PcodeOp as starting a basic block
void opClearFlag(PcodeOp *op,uint4 fl) { op->clearFlag(fl); } ///< Clear a boolean property on the given PcodeOp void opMarkStartInstruction(PcodeOp *op) { op->setFlag(PcodeOp::startmark); } ///< Mark PcodeOp as starting its instruction
void opFlipFlag(PcodeOp *op,uint4 fl) { op->flipFlag(fl); } ///< Flip a boolean property on the given PcodeOp void opMarkNonPrinting(PcodeOp *op) { op->setFlag(PcodeOp::nonprinting); } ///< Mark PcodeOp as not being printed
void opMarkSpecialPrint(PcodeOp *op) { op->setAdditionalFlag(PcodeOp::special_print); } ///< Mark PcodeOp as needing special printing
void opMarkNoCollapse(PcodeOp *op) { op->setFlag(PcodeOp::nocollapse); } ///< Mark PcodeOp as not collapsible
void opMarkCpoolTransformed(PcodeOp *op) { op->setFlag(PcodeOp::is_cpool_transformed); } ///< Mark cpool record was visited
void opMarkCalculatedBool(PcodeOp *op) { op->setFlag(PcodeOp::calculated_bool); } ///< Mark PcodeOp as having boolean output
void opFlipCondition(PcodeOp *op) { op->flipFlag(PcodeOp::boolean_flip); } ///< Flip output condition of given CBRANCH
PcodeOp *target(const Address &addr) const { return obank.target(addr); } ///< Look up a PcodeOp by an instruction Address PcodeOp *target(const Address &addr) const { return obank.target(addr); } ///< Look up a PcodeOp by an instruction Address
Varnode *createStackRef(AddrSpace *spc,uintb off,PcodeOp *op,Varnode *stackptr,bool insertafter); Varnode *createStackRef(AddrSpace *spc,uintb off,PcodeOp *op,Varnode *stackptr,bool insertafter);
Varnode *opStackLoad(AddrSpace *spc,uintb off,uint4 sz,PcodeOp *op,Varnode *stackptr,bool insertafter); Varnode *opStackLoad(AddrSpace *spc,uintb off,uint4 sz,PcodeOp *op,Varnode *stackptr,bool insertafter);

View file

@ -762,7 +762,7 @@ PcodeOp *Funcdata::nodeSplitCloneOp(PcodeOp *op)
opSetOpcode(dup,op->code()); opSetOpcode(dup,op->code());
uint4 flags = op->flags & (PcodeOp::startbasic | PcodeOp::nocollapse | uint4 flags = op->flags & (PcodeOp::startbasic | PcodeOp::nocollapse |
PcodeOp::startmark); PcodeOp::startmark);
opSetFlag(dup,flags); dup->setFlag(flags);
return dup; return dup;
} }

View file

@ -532,7 +532,7 @@ PcodeOp *Funcdata::cloneOp(const PcodeOp *op,const SeqNum &seq)
PcodeOp *newop = newOp(op->numInput(),seq); PcodeOp *newop = newOp(op->numInput(),seq);
opSetOpcode(newop,op->code()); opSetOpcode(newop,op->code());
uint4 flags = op->flags & (PcodeOp::startmark | PcodeOp::startbasic); uint4 flags = op->flags & (PcodeOp::startmark | PcodeOp::startbasic);
opSetFlag(newop,flags); newop->setFlag(flags);
if (op->getOut() != (Varnode *)0) if (op->getOut() != (Varnode *)0)
opSetOutput(newop,cloneVarnode(op->getOut())); opSetOutput(newop,cloneVarnode(op->getOut()));
for(int4 i=0;i<op->numInput();++i) for(int4 i=0;i<op->numInput();++i)

View file

@ -519,9 +519,9 @@ bool Funcdata::fillinReadOnly(Varnode *vn)
if (vn->isWritten()) { // Can't replace output with constant if (vn->isWritten()) { // Can't replace output with constant
PcodeOp *defop = vn->getDef(); PcodeOp *defop = vn->getDef();
if (defop->isMarker()) if (defop->isMarker())
defop->setFlag(PcodeOp::warning); // Not a true write, ignore it defop->setAdditionalFlag(PcodeOp::warning); // Not a true write, ignore it
else if (!defop->isWarning()) { // No warning generated before else if (!defop->isWarning()) { // No warning generated before
defop->setFlag(PcodeOp::warning); defop->setAdditionalFlag(PcodeOp::warning);
ostringstream s; ostringstream s;
if ((!vn->isAddrForce())||(!vn->hasNoDescend())) { if ((!vn->isAddrForce())||(!vn->hasNoDescend())) {
s << "Read-only address ("; s << "Read-only address (";

View file

@ -1072,7 +1072,7 @@ void Merge::markRedundantCopies(HighVariable *high,vector<PcodeOp *> &copy,int4
PcodeOp *domOp = copy[pos + j]; PcodeOp *domOp = copy[pos + j];
if (domOp->isDead()) continue; if (domOp->isDead()) continue;
if (checkCopyPair(high, domOp, subOp)) { if (checkCopyPair(high, domOp, subOp)) {
data.opSetFlag(subOp, PcodeOp::nonprinting); data.opMarkNonPrinting(subOp);
break; break;
} }
} }
@ -1233,7 +1233,7 @@ void Merge::markInternalCopies(void)
v1 = op->getOut(); v1 = op->getOut();
h1 = v1->getHigh(); h1 = v1->getHigh();
if (h1 == op->getIn(0)->getHigh()) { if (h1 == op->getIn(0)->getHigh()) {
data.opSetFlag(op, PcodeOp::nonprinting); data.opMarkNonPrinting(op);
} }
else { // COPY between different HighVariables else { // COPY between different HighVariables
if (!h1->hasCopyIn1()) { // If this is the first COPY we've seen for this high if (!h1->hasCopyIn1()) { // If this is the first COPY we've seen for this high
@ -1244,7 +1244,7 @@ void Merge::markInternalCopies(void)
h1->setCopyIn2(); // This is at least the second COPY we've seen h1->setCopyIn2(); // This is at least the second COPY we've seen
if (v1->hasNoDescend()) { // Don't print shadow assignments if (v1->hasNoDescend()) { // Don't print shadow assignments
if (shadowedVarnode(v1)) { if (shadowedVarnode(v1)) {
data.opSetFlag(op, PcodeOp::nonprinting); data.opMarkNonPrinting(op);
} }
} }
} }
@ -1261,7 +1261,7 @@ void Merge::markInternalCopies(void)
v3 = h3->getTiedVarnode(); v3 = h3->getTiedVarnode();
if (v3->overlap(*v1) != 0) break; if (v3->overlap(*v1) != 0) break;
if (v2->overlap(*v1) != v3->getSize()) break; if (v2->overlap(*v1) != v3->getSize()) break;
data.opSetFlag(op,PcodeOp::nonprinting); data.opMarkNonPrinting(op);
break; break;
case CPUI_SUBPIECE: case CPUI_SUBPIECE:
h1 = op->getOut()->getHigh(); h1 = op->getOut()->getHigh();
@ -1272,7 +1272,7 @@ void Merge::markInternalCopies(void)
v2 = h2->getTiedVarnode(); v2 = h2->getTiedVarnode();
val = op->getIn(1)->getOffset(); val = op->getIn(1)->getOffset();
if (v1->overlap(*v2) != val) break; if (v1->overlap(*v2) != val) break;
data.opSetFlag(op,PcodeOp::nonprinting); data.opMarkNonPrinting(op);
break; break;
default: default:
break; break;

View file

@ -62,7 +62,7 @@ class PcodeOp {
friend class VarnodeBank; // Only uses setInput friend class VarnodeBank; // Only uses setInput
public: public:
/// Boolean attributes (flags) that can be placed on a PcodeOp. Even though this enum is public, these are /// Boolean attributes (flags) that can be placed on a PcodeOp. Even though this enum is public, these are
/// all set and read internally, although many are read publically via \e get or \e is methods. /// all set and read internally, although many are read publicly via \e get or \e is methods.
enum { enum {
startbasic = 1, ///< This instruction starts a basic block startbasic = 1, ///< This instruction starts a basic block
branch = 2, ///< This instruction is a branch branch = 2, ///< This instruction is a branch
@ -73,38 +73,39 @@ public:
marker = 0x40, ///< special placeholder op (multiequal or indirect) marker = 0x40, ///< special placeholder op (multiequal or indirect)
///< or CPUI_COPY between different copies ///< or CPUI_COPY between different copies
///< of same variable ///< of same variable
booloutput = 0x80, ///< Boolean operation booloutput = 0x80, ///< Boolean operation
boolean_flip = 0x100, ///< Set if condition must be false to take branch boolean_flip = 0x100, ///< Set if condition must be false to take branch
fallthru_true = 0x200, ///< Set if fallthru happens on true condition fallthru_true = 0x200, ///< Set if fallthru happens on true condition
indirect_source = 0x400, ///< Op is source of (one or more) CPUI_INDIRECTs indirect_source = 0x400, ///< Op is source of (one or more) CPUI_INDIRECTs
coderef = 0x800, ///< The first parameter to this op is a coderef coderef = 0x800, ///< The first parameter to this op is a coderef
startmark = 0x1000, ///< This op is the first in its instruction startmark = 0x1000, ///< This op is the first in its instruction
mark = 0x2000, ///< Used by many algorithms that need to detect loops or avoid repeats mark = 0x2000, ///< Used by many algorithms that need to detect loops or avoid repeats
commutative = 0x4000, ///< Order of input parameters does not matter commutative = 0x4000, ///< Order of input parameters does not matter
unary = 0x8000, ///< Evaluate as unary expression unary = 0x8000, ///< Evaluate as unary expression
binary = 0x10000, ///< Evaluate as binary expression binary = 0x10000, ///< Evaluate as binary expression
special = 0x20000, ///< Cannot be evaluated (without special processing) special = 0x20000, ///< Cannot be evaluated (without special processing)
floatingpoint = 0x40000, ///< A floating point operation floatingpoint = 0x40000, ///< A floating point operation
splittingbranch = 0x80000, ///< Dead edge cannot be removed as it splits splittingbranch = 0x80000, ///< Dead edge cannot be removed as it splits
nonprinting = 0x100000, ///< Op should not be directly printed as source nonprinting = 0x100000, ///< Op should not be directly printed as source
halt = 0x200000, ///< instruction causes processor or process to halt halt = 0x200000, ///< instruction causes processor or process to halt
badinstruction = 0x400000, ///< placeholder for bad instruction data badinstruction = 0x400000, ///< placeholder for bad instruction data
unimplemented = 0x800000, ///< placeholder for unimplemented instruction unimplemented = 0x800000, ///< placeholder for unimplemented instruction
noreturn = 0x1000000, ///< placeholder for previous call that doesn't exit noreturn = 0x1000000, ///< placeholder for previous call that doesn't exit
missing = 0x2000000, ///< ops at this address were not generated missing = 0x2000000, ///< ops at this address were not generated
warning = 0x4000000, ///< Warning has been generated for this op spacebase_ptr = 0x4000000, ///< Loads or stores from a dynamic pointer into a spacebase
indirect_creation = 0x8000000, ///< Output varnode is created by indirect effect indirect_creation = 0x8000000, ///< Output varnode is created by indirect effect
calculated_bool = 0x10000000, ///< Output has been determined to be a 1-bit boolean value calculated_bool = 0x10000000, ///< Output has been determined to be a 1-bit boolean value
is_cpool_transformed = 0x20000000, ///< Have we checked for cpool transforms is_cpool_transformed = 0x20000000, ///< Have we checked for cpool transforms
ptrflow = 0x40000000, ///< Op consumes or produces a ptr ptrflow = 0x40000000 ///< Op consumes or produces a ptr
special_print = 0x80000000 ///< Op is marked for special printing
}; };
enum { enum {
has_thisptr = 0x1, ///< First parameter ( getIn(1) ) is a this pointer has_thisptr = 0x1, ///< First parameter ( getIn(1) ) is a this pointer
is_constructor = 0x2, ///< Op is call to a constructor is_constructor = 0x2, ///< Op is call to a constructor
is_destructor = 0x4, ///< Op is call to a destructor is_destructor = 0x4, ///< Op is call to a destructor
special_prop = 0x8, ///< Does some special form of datatype propagation special_prop = 0x8, ///< Does some special form of datatype propagation
modified = 0x10 ///< This op has been modified by the current action special_print = 0x10, ///< Op is marked for special printing
modified = 0x20, ///< This op has been modified by the current action
warning = 0x40 ///< Warning has been generated for this op
}; };
private: private:
TypeOp *opcode; ///< Pointer to class providing behavioral details of the operation TypeOp *opcode; ///< Pointer to class providing behavioral details of the operation
@ -119,6 +120,7 @@ private:
vector<Varnode *> inrefs; ///< The ordered list of input Varnodes for this op vector<Varnode *> inrefs; ///< The ordered list of input Varnodes for this op
// Only used by Funcdata // Only used by Funcdata
void setOpcode(TypeOp *t_op); ///< Set the opcode for this PcodeOp
void setOutput(Varnode *vn) { output = vn; } ///< Set the output Varnode of this op void setOutput(Varnode *vn) { output = vn; } ///< Set the output Varnode of this op
void clearInput(int4 slot) { inrefs[slot] = (Varnode *)0; } ///< Clear a specific input Varnode to \e null void clearInput(int4 slot) { inrefs[slot] = (Varnode *)0; } ///< Clear a specific input Varnode to \e null
void setInput(Varnode *vn,int4 slot) { inrefs[slot] = vn; } ///< Set a specific input Varnode void setInput(Varnode *vn,int4 slot) { inrefs[slot] = vn; } ///< Set a specific input Varnode
@ -180,7 +182,7 @@ public:
bool isModified(void) const { return ((addlflags&PcodeOp::modified)!=0); } ///< Return \b true if this is modified by the current action bool isModified(void) const { return ((addlflags&PcodeOp::modified)!=0); } ///< Return \b true if this is modified by the current action
bool isMark(void) const { return ((flags&PcodeOp::mark)!=0); } ///< Return \b true if this op has been marked bool isMark(void) const { return ((flags&PcodeOp::mark)!=0); } ///< Return \b true if this op has been marked
void setMark(void) const { flags |= PcodeOp::mark; } ///< Set the mark on this op void setMark(void) const { flags |= PcodeOp::mark; } ///< Set the mark on this op
bool isWarning(void) const { return ((flags&PcodeOp::warning)!=0); } ///< Return \b true if a warning has been generated for this op bool isWarning(void) const { return ((addlflags&PcodeOp::warning)!=0); } ///< Return \b true if a warning has been generated for this op
void clearMark(void) const { flags &= ~PcodeOp::mark; } ///< Clear any mark on this op void clearMark(void) const { flags &= ~PcodeOp::mark; } ///< Clear any mark on this op
bool isIndirectSource(void) const { return ((flags&PcodeOp::indirect_source)!=0); } ///< Return \b true if this causes an INDIRECT bool isIndirectSource(void) const { return ((flags&PcodeOp::indirect_source)!=0); } ///< Return \b true if this causes an INDIRECT
void setIndirectSource(void) { flags |= PcodeOp::indirect_source; } ///< Mark this op as source of INDIRECT void setIndirectSource(void) { flags |= PcodeOp::indirect_source; } ///< Mark this op as source of INDIRECT
@ -189,7 +191,7 @@ public:
void setPtrFlow(void) { flags |= PcodeOp::ptrflow; } ///< Mark this op as consuming/producing ptrs void setPtrFlow(void) { flags |= PcodeOp::ptrflow; } ///< Mark this op as consuming/producing ptrs
bool isSplitting(void) const { return ((flags&PcodeOp::splittingbranch)!=0); } ///< Return \b true if this branch splits bool isSplitting(void) const { return ((flags&PcodeOp::splittingbranch)!=0); } ///< Return \b true if this branch splits
bool doesSpecialPropagation(void) const { return ((addlflags&PcodeOp::special_prop)!=0); } ///< Return \b true if this does datatype propagation bool doesSpecialPropagation(void) const { return ((addlflags&PcodeOp::special_prop)!=0); } ///< Return \b true if this does datatype propagation
bool doesSpecialPrinting(void) const { return ((flags&PcodeOp::special_print)!=0); } ///< Return \b true if this needs to special printing bool doesSpecialPrinting(void) const { return ((addlflags&PcodeOp::special_print)!=0); } ///< Return \b true if this needs to special printing
bool hasThisPointer(void) const { return ((addlflags&PcodeOp::has_thisptr)!=0); } ///< Return \b true if this is a call taking 'this' parameter bool hasThisPointer(void) const { return ((addlflags&PcodeOp::has_thisptr)!=0); } ///< Return \b true if this is a call taking 'this' parameter
bool isConstructor(void) const { return ((addlflags&PcodeOp::is_constructor)!=0); } ///< Return \b true if this is call to a constructor bool isConstructor(void) const { return ((addlflags&PcodeOp::is_constructor)!=0); } ///< Return \b true if this is call to a constructor
bool isDestructor(void) const { return ((addlflags&PcodeOp::is_destructor)!=0); } ///< Return \b true if this is call to a destructor bool isDestructor(void) const { return ((addlflags&PcodeOp::is_destructor)!=0); } ///< Return \b true if this is call to a destructor
@ -198,9 +200,10 @@ public:
/// \brief Return \b true if we have already examined this cpool /// \brief Return \b true if we have already examined this cpool
bool isCpoolTransformed(void) const { return ((flags&PcodeOp::is_cpool_transformed)!=0); } bool isCpoolTransformed(void) const { return ((flags&PcodeOp::is_cpool_transformed)!=0); }
bool isCollapsible(void) const; ///< Return \b true if this can be collapsed to a COPY of a constant bool isCollapsible(void) const; ///< Return \b true if this can be collapsed to a COPY of a constant
/// \brief Return \b true if this LOADs or STOREs from a dynamic \e spacebase pointer
bool usesSpacebasePtr(void) const { return ((flags&PcodeOp::spacebase_ptr)!=0); }
uintm getCseHash(void) const; ///< Return hash indicating possibility of common subexpression elimination uintm getCseHash(void) const; ///< Return hash indicating possibility of common subexpression elimination
bool isCseMatch(const PcodeOp *op) const; ///< Return \b true if this and \e op represent common subexpressions bool isCseMatch(const PcodeOp *op) const; ///< Return \b true if this and \e op represent common subexpressions
void setOpcode(TypeOp *t_op); ///< Set the opcode for this PcodeOp
TypeOp *getOpcode(void) const { return opcode; } ///< Get the opcode for this op TypeOp *getOpcode(void) const { return opcode; } ///< Get the opcode for this op
OpCode code(void) const { return opcode->getOpcode(); } ///< Get the opcode id (enum) for this op OpCode code(void) const { return opcode->getOpcode(); } ///< Get the opcode id (enum) for this op
bool isCommutative(void) const { return ((flags & PcodeOp::commutative)!=0); } ///< Return \b true if inputs commute bool isCommutative(void) const { return ((flags & PcodeOp::commutative)!=0); } ///< Return \b true if inputs commute

View file

@ -3263,7 +3263,7 @@ int4 RuleCollapseConstants::applyOp(PcodeOp *op,Funcdata &data)
newval = data.getArch()->getConstant(op->collapse(markedInput)); newval = data.getArch()->getConstant(op->collapse(markedInput));
} }
catch(LowlevelError &err) { catch(LowlevelError &err) {
data.opSetFlag(op,PcodeOp::nocollapse); // Dont know how or dont want to collapse further data.opMarkNoCollapse(op); // Dont know how or dont want to collapse further
return 0; return 0;
} }
@ -3294,14 +3294,14 @@ int4 RuleTransformCpool::applyOp(PcodeOp *op,Funcdata &data)
{ {
if (op->isCpoolTransformed()) return 0; // Already visited if (op->isCpoolTransformed()) return 0; // Already visited
data.opSetFlag(op,PcodeOp::is_cpool_transformed); // Mark our visit data.opMarkCpoolTransformed(op); // Mark our visit
vector<uintb> refs; vector<uintb> refs;
for(int4 i=1;i<op->numInput();++i) for(int4 i=1;i<op->numInput();++i)
refs.push_back(op->getIn(i)->getOffset()); refs.push_back(op->getIn(i)->getOffset());
const CPoolRecord *rec = data.getArch()->cpool->getRecord(refs); // Recover the record const CPoolRecord *rec = data.getArch()->cpool->getRecord(refs); // Recover the record
if (rec != (const CPoolRecord *)0) { if (rec != (const CPoolRecord *)0) {
if (rec->getTag() == CPoolRecord::instance_of) { if (rec->getTag() == CPoolRecord::instance_of) {
data.opSetFlag(op,PcodeOp::calculated_bool); data.opMarkCalculatedBool(op);
} }
else if (rec->getTag() == CPoolRecord::primitive) { else if (rec->getTag() == CPoolRecord::primitive) {
int4 sz = op->getOut()->getSize(); int4 sz = op->getOut()->getSize();
@ -4883,7 +4883,7 @@ int4 RuleCondNegate::applyOp(PcodeOp *op,Funcdata &data)
data.opSetInput(newop,vn,0); data.opSetInput(newop,vn,0);
data.opSetInput(op,outvn,1); data.opSetInput(op,outvn,1);
data.opInsertBefore(newop,op); data.opInsertBefore(newop,op);
data.opFlipFlag(op,PcodeOp::boolean_flip); // Flip meaning of condition data.opFlipCondition(op); // Flip meaning of condition
// NOTE fallthru block is still same status // NOTE fallthru block is still same status
return 1; return 1;
} }

View file

@ -126,35 +126,6 @@ bool AddrSpace::contain(AddrSpace *id2) const
return true; return true;
} }
/// Convert an array of bytes, which we assume are contained in
/// the space, into an integer value. The conversion depends
/// on the endian property of the space
/// \param ptr is the array of bytes
/// \param size is the size of the array to convert
/// \return the converted integer value
uintm AddrSpace::data2Uintm(const uint1 *ptr,int4 size) const
{
uintm res;
int4 i;
if ((flags&big_endian)!=0) {
res = 0;
for(i=0;i<size;++i) {
res <<= 8;
res |= ptr[i];
}
}
else {
res = 0;
for(i=size-1;i>=0;--i) {
res <<= 8;
res |= ptr[i];
}
}
return res;
}
/// Write the main XML attributes for an address within this space /// Write the main XML attributes for an address within this space
/// The caller provides only the \e offset, and this routine fills /// The caller provides only the \e offset, and this routine fills
/// in other details pertaining to this particular space. /// in other details pertaining to this particular space.

View file

@ -130,7 +130,6 @@ public:
bool isOverlay(void) const; ///< Return \b true if this is an overlay space bool isOverlay(void) const; ///< Return \b true if this is an overlay space
bool isOverlayBase(void) const; ///< Return \b true if other spaces overlay this space bool isOverlayBase(void) const; ///< Return \b true if other spaces overlay this space
bool isTruncated(void) const; ///< Return \b true if this space is truncated from its original size bool isTruncated(void) const; ///< Return \b true if this space is truncated from its original size
uintm data2Uintm(const uint1 *ptr,int4 size) const; ///< Convert a sequence of bytes into an integer value
void printOffset(ostream &s,uintb offset) const; ///< Write an address offset to a stream void printOffset(ostream &s,uintb offset) const; ///< Write an address offset to a stream
virtual int4 numSpacebase(void) const; ///< Number of base registers associated with this space virtual int4 numSpacebase(void) const; ///< Number of base registers associated with this space