mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
New flag for dynamic STORE test
This commit is contained in:
parent
b6b9b27128
commit
cb39d39a23
11 changed files with 67 additions and 88 deletions
|
@ -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->getIn(1) != vn) return; // First parameter must result of new
|
||||
// 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.opSetFlag(op,PcodeOp::nonprinting); // Don't print the new operator as stand-alone operation
|
||||
data.opMarkSpecialPrint(firstuse); // Mark call to print the new operator as well
|
||||
data.opMarkNonPrinting(op); // Don't print the new operator as stand-alone operation
|
||||
}
|
||||
|
||||
int4 ActionMarkExplicit::apply(Funcdata &data)
|
||||
|
|
|
@ -212,7 +212,7 @@ void FlowInfo::newAddress(PcodeOp *from,const Address &to)
|
|||
|
||||
if (seenInstruction(to)) { // If we have seen this address before
|
||||
PcodeOp *op = target(to);
|
||||
data.opSetFlag(op,PcodeOp::startbasic);
|
||||
data.opMarkStartBasic(op);
|
||||
return;
|
||||
}
|
||||
addrlist.push_back(to);
|
||||
|
@ -255,7 +255,7 @@ PcodeOp *FlowInfo::xrefControlFlow(list<PcodeOp *>::const_iterator oiter,bool &s
|
|||
while(oiter != obank.endDead()) {
|
||||
op = *oiter++;
|
||||
if (startbasic) {
|
||||
data.opSetFlag(op,PcodeOp::startbasic);
|
||||
data.opMarkStartBasic(op);
|
||||
startbasic = false;
|
||||
}
|
||||
switch(op->code()) {
|
||||
|
@ -266,7 +266,7 @@ PcodeOp *FlowInfo::xrefControlFlow(list<PcodeOp *>::const_iterator oiter,bool &s
|
|||
Address fallThruAddr;
|
||||
PcodeOp *destop = findRelTarget(op,fallThruAddr);
|
||||
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();
|
||||
if (newtime > maxtime)
|
||||
maxtime = newtime;
|
||||
|
@ -286,7 +286,7 @@ PcodeOp *FlowInfo::xrefControlFlow(list<PcodeOp *>::const_iterator oiter,bool &s
|
|||
Address fallThruAddr;
|
||||
PcodeOp *destop = findRelTarget(op,fallThruAddr);
|
||||
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();
|
||||
if (newtime > maxtime)
|
||||
maxtime = newtime;
|
||||
|
@ -456,7 +456,7 @@ bool FlowInfo::processInstruction(const Address &curaddr,bool &startbasic)
|
|||
|
||||
if (oiter != obank.endDead()) {
|
||||
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)
|
||||
data.overrideFlow(curaddr,flowoverride);
|
||||
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
|
||||
addrlist.pop_back(); // Throw it away
|
||||
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;
|
||||
}
|
||||
if (addr < (*iter).first + (*iter).second.size)
|
||||
|
@ -555,7 +555,7 @@ void FlowInfo::fallthru(void)
|
|||
if (bound == addrlist.back()) { // Hit the bound exactly
|
||||
if (startbasic) {
|
||||
PcodeOp *op = target(addrlist.back());
|
||||
data.opSetFlag(op,PcodeOp::startbasic);
|
||||
data.opMarkStartBasic(op);
|
||||
}
|
||||
addrlist.pop_back();
|
||||
break;
|
||||
|
@ -828,7 +828,7 @@ void FlowInfo::findUnprocessed(void)
|
|||
for(iter=addrlist.begin();iter!=addrlist.end();++iter) {
|
||||
if (seenInstruction(*iter)) {
|
||||
PcodeOp *op = target(*iter);
|
||||
data.opSetFlag(op,PcodeOp::startbasic);
|
||||
data.opMarkStartBasic(op);
|
||||
}
|
||||
else
|
||||
unprocessed.push_back(*iter);
|
||||
|
@ -868,7 +868,8 @@ void FlowInfo::fillinBranchStubs(void)
|
|||
dedupUnprocessed();
|
||||
for(iter=unprocessed.begin();iter!=unprocessed.end();++iter) {
|
||||
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;
|
||||
}
|
||||
// If the inlining "jumps back" this starts a new basic block
|
||||
data.opSetFlag(nextop,PcodeOp::startbasic);
|
||||
data.opMarkStartBasic(nextop);
|
||||
}
|
||||
|
||||
inline_recursion->insert(inlinefd->getAddress());
|
||||
|
@ -1173,7 +1174,7 @@ void FlowInfo::doInjection(InjectPayload *payload,InjectContext &icontext,PcodeO
|
|||
iter = op->getInsertIter();
|
||||
++iter; // Mark next op after the call
|
||||
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
|
||||
|
@ -1356,12 +1357,12 @@ void FlowInfo::checkContainedCall(void)
|
|||
data.opSetOpcode(op,CPUI_BRANCH);
|
||||
// Make sure target of new goto starts a basic block
|
||||
PcodeOp *targ = target(addr);
|
||||
data.opSetFlag(targ,PcodeOp::startbasic);
|
||||
data.opMarkStartBasic(targ);
|
||||
// Make sure the following op starts a basic block
|
||||
list<PcodeOp *>::const_iterator oiter = op->getInsertIter();
|
||||
++oiter;
|
||||
if (oiter != obank.endDead())
|
||||
data.opSetFlag(*oiter,PcodeOp::startbasic);
|
||||
data.opMarkStartBasic(*oiter);
|
||||
// Restore original address
|
||||
data.opSetInput(op,data.newCodeRef(addr),0);
|
||||
iter = qlst.erase(iter); // Delete the call
|
||||
|
|
|
@ -413,9 +413,14 @@ public:
|
|||
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 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 opClearFlag(PcodeOp *op,uint4 fl) { op->clearFlag(fl); } ///< Clear a boolean property on the given PcodeOp
|
||||
void opFlipFlag(PcodeOp *op,uint4 fl) { op->flipFlag(fl); } ///< Flip a boolean property on the given PcodeOp
|
||||
void opMarkStartBasic(PcodeOp *op) { op->setFlag(PcodeOp::startbasic); } ///< Mark PcodeOp as starting a basic block
|
||||
void opMarkStartInstruction(PcodeOp *op) { op->setFlag(PcodeOp::startmark); } ///< Mark PcodeOp as starting its instruction
|
||||
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
|
||||
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);
|
||||
|
|
|
@ -762,7 +762,7 @@ PcodeOp *Funcdata::nodeSplitCloneOp(PcodeOp *op)
|
|||
opSetOpcode(dup,op->code());
|
||||
uint4 flags = op->flags & (PcodeOp::startbasic | PcodeOp::nocollapse |
|
||||
PcodeOp::startmark);
|
||||
opSetFlag(dup,flags);
|
||||
dup->setFlag(flags);
|
||||
return dup;
|
||||
}
|
||||
|
||||
|
|
|
@ -532,7 +532,7 @@ PcodeOp *Funcdata::cloneOp(const PcodeOp *op,const SeqNum &seq)
|
|||
PcodeOp *newop = newOp(op->numInput(),seq);
|
||||
opSetOpcode(newop,op->code());
|
||||
uint4 flags = op->flags & (PcodeOp::startmark | PcodeOp::startbasic);
|
||||
opSetFlag(newop,flags);
|
||||
newop->setFlag(flags);
|
||||
if (op->getOut() != (Varnode *)0)
|
||||
opSetOutput(newop,cloneVarnode(op->getOut()));
|
||||
for(int4 i=0;i<op->numInput();++i)
|
||||
|
|
|
@ -519,9 +519,9 @@ bool Funcdata::fillinReadOnly(Varnode *vn)
|
|||
if (vn->isWritten()) { // Can't replace output with constant
|
||||
PcodeOp *defop = vn->getDef();
|
||||
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
|
||||
defop->setFlag(PcodeOp::warning);
|
||||
defop->setAdditionalFlag(PcodeOp::warning);
|
||||
ostringstream s;
|
||||
if ((!vn->isAddrForce())||(!vn->hasNoDescend())) {
|
||||
s << "Read-only address (";
|
||||
|
|
|
@ -1072,7 +1072,7 @@ void Merge::markRedundantCopies(HighVariable *high,vector<PcodeOp *> ©,int4
|
|||
PcodeOp *domOp = copy[pos + j];
|
||||
if (domOp->isDead()) continue;
|
||||
if (checkCopyPair(high, domOp, subOp)) {
|
||||
data.opSetFlag(subOp, PcodeOp::nonprinting);
|
||||
data.opMarkNonPrinting(subOp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1233,7 +1233,7 @@ void Merge::markInternalCopies(void)
|
|||
v1 = op->getOut();
|
||||
h1 = v1->getHigh();
|
||||
if (h1 == op->getIn(0)->getHigh()) {
|
||||
data.opSetFlag(op, PcodeOp::nonprinting);
|
||||
data.opMarkNonPrinting(op);
|
||||
}
|
||||
else { // COPY between different HighVariables
|
||||
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
|
||||
if (v1->hasNoDescend()) { // Don't print shadow assignments
|
||||
if (shadowedVarnode(v1)) {
|
||||
data.opSetFlag(op, PcodeOp::nonprinting);
|
||||
data.opMarkNonPrinting(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1261,7 +1261,7 @@ void Merge::markInternalCopies(void)
|
|||
v3 = h3->getTiedVarnode();
|
||||
if (v3->overlap(*v1) != 0) break;
|
||||
if (v2->overlap(*v1) != v3->getSize()) break;
|
||||
data.opSetFlag(op,PcodeOp::nonprinting);
|
||||
data.opMarkNonPrinting(op);
|
||||
break;
|
||||
case CPUI_SUBPIECE:
|
||||
h1 = op->getOut()->getHigh();
|
||||
|
@ -1272,7 +1272,7 @@ void Merge::markInternalCopies(void)
|
|||
v2 = h2->getTiedVarnode();
|
||||
val = op->getIn(1)->getOffset();
|
||||
if (v1->overlap(*v2) != val) break;
|
||||
data.opSetFlag(op,PcodeOp::nonprinting);
|
||||
data.opMarkNonPrinting(op);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -62,7 +62,7 @@ class PcodeOp {
|
|||
friend class VarnodeBank; // Only uses setInput
|
||||
public:
|
||||
/// 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 {
|
||||
startbasic = 1, ///< This instruction starts a basic block
|
||||
branch = 2, ///< This instruction is a branch
|
||||
|
@ -73,38 +73,39 @@ public:
|
|||
marker = 0x40, ///< special placeholder op (multiequal or indirect)
|
||||
///< or CPUI_COPY between different copies
|
||||
///< of same variable
|
||||
booloutput = 0x80, ///< Boolean operation
|
||||
boolean_flip = 0x100, ///< Set if condition must be false to take branch
|
||||
fallthru_true = 0x200, ///< Set if fallthru happens on true condition
|
||||
indirect_source = 0x400, ///< Op is source of (one or more) CPUI_INDIRECTs
|
||||
coderef = 0x800, ///< The first parameter to this op is a coderef
|
||||
startmark = 0x1000, ///< This op is the first in its instruction
|
||||
mark = 0x2000, ///< Used by many algorithms that need to detect loops or avoid repeats
|
||||
commutative = 0x4000, ///< Order of input parameters does not matter
|
||||
unary = 0x8000, ///< Evaluate as unary expression
|
||||
binary = 0x10000, ///< Evaluate as binary expression
|
||||
special = 0x20000, ///< Cannot be evaluated (without special processing)
|
||||
floatingpoint = 0x40000, ///< A floating point operation
|
||||
splittingbranch = 0x80000, ///< Dead edge cannot be removed as it splits
|
||||
nonprinting = 0x100000, ///< Op should not be directly printed as source
|
||||
halt = 0x200000, ///< instruction causes processor or process to halt
|
||||
badinstruction = 0x400000, ///< placeholder for bad instruction data
|
||||
unimplemented = 0x800000, ///< placeholder for unimplemented instruction
|
||||
noreturn = 0x1000000, ///< placeholder for previous call that doesn't exit
|
||||
missing = 0x2000000, ///< ops at this address were not generated
|
||||
warning = 0x4000000, ///< Warning has been generated for this op
|
||||
booloutput = 0x80, ///< Boolean operation
|
||||
boolean_flip = 0x100, ///< Set if condition must be false to take branch
|
||||
fallthru_true = 0x200, ///< Set if fallthru happens on true condition
|
||||
indirect_source = 0x400, ///< Op is source of (one or more) CPUI_INDIRECTs
|
||||
coderef = 0x800, ///< The first parameter to this op is a coderef
|
||||
startmark = 0x1000, ///< This op is the first in its instruction
|
||||
mark = 0x2000, ///< Used by many algorithms that need to detect loops or avoid repeats
|
||||
commutative = 0x4000, ///< Order of input parameters does not matter
|
||||
unary = 0x8000, ///< Evaluate as unary expression
|
||||
binary = 0x10000, ///< Evaluate as binary expression
|
||||
special = 0x20000, ///< Cannot be evaluated (without special processing)
|
||||
floatingpoint = 0x40000, ///< A floating point operation
|
||||
splittingbranch = 0x80000, ///< Dead edge cannot be removed as it splits
|
||||
nonprinting = 0x100000, ///< Op should not be directly printed as source
|
||||
halt = 0x200000, ///< instruction causes processor or process to halt
|
||||
badinstruction = 0x400000, ///< placeholder for bad instruction data
|
||||
unimplemented = 0x800000, ///< placeholder for unimplemented instruction
|
||||
noreturn = 0x1000000, ///< placeholder for previous call that doesn't exit
|
||||
missing = 0x2000000, ///< ops at this address were not generated
|
||||
spacebase_ptr = 0x4000000, ///< Loads or stores from a dynamic pointer into a spacebase
|
||||
indirect_creation = 0x8000000, ///< Output varnode is created by indirect effect
|
||||
calculated_bool = 0x10000000, ///< Output has been determined to be a 1-bit boolean value
|
||||
is_cpool_transformed = 0x20000000, ///< Have we checked for cpool transforms
|
||||
ptrflow = 0x40000000, ///< Op consumes or produces a ptr
|
||||
special_print = 0x80000000 ///< Op is marked for special printing
|
||||
ptrflow = 0x40000000 ///< Op consumes or produces a ptr
|
||||
};
|
||||
enum {
|
||||
has_thisptr = 0x1, ///< First parameter ( getIn(1) ) is a this pointer
|
||||
is_constructor = 0x2, ///< Op is call to a constructor
|
||||
is_destructor = 0x4, ///< Op is call to a destructor
|
||||
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:
|
||||
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
|
||||
|
||||
// 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 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
|
||||
|
@ -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 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
|
||||
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
|
||||
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
|
||||
|
@ -189,7 +191,7 @@ public:
|
|||
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 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 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
|
||||
|
@ -198,9 +200,10 @@ public:
|
|||
/// \brief Return \b true if we have already examined this cpool
|
||||
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
|
||||
/// \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
|
||||
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
|
||||
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
|
||||
|
|
|
@ -3263,7 +3263,7 @@ int4 RuleCollapseConstants::applyOp(PcodeOp *op,Funcdata &data)
|
|||
newval = data.getArch()->getConstant(op->collapse(markedInput));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3294,14 +3294,14 @@ int4 RuleTransformCpool::applyOp(PcodeOp *op,Funcdata &data)
|
|||
|
||||
{
|
||||
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;
|
||||
for(int4 i=1;i<op->numInput();++i)
|
||||
refs.push_back(op->getIn(i)->getOffset());
|
||||
const CPoolRecord *rec = data.getArch()->cpool->getRecord(refs); // Recover the record
|
||||
if (rec != (const CPoolRecord *)0) {
|
||||
if (rec->getTag() == CPoolRecord::instance_of) {
|
||||
data.opSetFlag(op,PcodeOp::calculated_bool);
|
||||
data.opMarkCalculatedBool(op);
|
||||
}
|
||||
else if (rec->getTag() == CPoolRecord::primitive) {
|
||||
int4 sz = op->getOut()->getSize();
|
||||
|
@ -4883,7 +4883,7 @@ int4 RuleCondNegate::applyOp(PcodeOp *op,Funcdata &data)
|
|||
data.opSetInput(newop,vn,0);
|
||||
data.opSetInput(op,outvn,1);
|
||||
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
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -126,35 +126,6 @@ bool AddrSpace::contain(AddrSpace *id2) const
|
|||
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
|
||||
/// The caller provides only the \e offset, and this routine fills
|
||||
/// in other details pertaining to this particular space.
|
||||
|
|
|
@ -130,7 +130,6 @@ public:
|
|||
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 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
|
||||
|
||||
virtual int4 numSpacebase(void) const; ///< Number of base registers associated with this space
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue