mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-1997 Don't over propagate global values
This commit is contained in:
parent
afb63d811c
commit
9d0829651a
7 changed files with 17 additions and 20 deletions
|
@ -3331,7 +3331,6 @@ int4 ActionDeterminedBranch::apply(Funcdata &data)
|
||||||
cbranch = bb->lastOp();
|
cbranch = bb->lastOp();
|
||||||
if ((cbranch == (PcodeOp *)0)||(cbranch->code() != CPUI_CBRANCH)) continue;
|
if ((cbranch == (PcodeOp *)0)||(cbranch->code() != CPUI_CBRANCH)) continue;
|
||||||
if (!cbranch->getIn(1)->isConstant()) continue;
|
if (!cbranch->getIn(1)->isConstant()) continue;
|
||||||
if (cbranch->isSplitting()) continue; // Already tried to remove before
|
|
||||||
uintb val = cbranch->getIn(1)->getOffset();
|
uintb val = cbranch->getIn(1)->getOffset();
|
||||||
int4 num = ((val!=0)!=cbranch->isBooleanFlip()) ? 0 : 1;
|
int4 num = ((val!=0)!=cbranch->isBooleanFlip()) ? 0 : 1;
|
||||||
data.removeBranch(bb,num);
|
data.removeBranch(bb,num);
|
||||||
|
@ -4052,7 +4051,7 @@ int4 ActionPrototypeTypes::apply(Funcdata &data)
|
||||||
{
|
{
|
||||||
list<PcodeOp *>::const_iterator iter,iterend;
|
list<PcodeOp *>::const_iterator iter,iterend;
|
||||||
|
|
||||||
// Set the evalutation prototype if we are not already locked
|
// Set the evaluation prototype if we are not already locked
|
||||||
ProtoModel *evalfp = data.getArch()->evalfp_current;
|
ProtoModel *evalfp = data.getArch()->evalfp_current;
|
||||||
if (evalfp == (ProtoModel *)0)
|
if (evalfp == (ProtoModel *)0)
|
||||||
evalfp = data.getArch()->defaultfp;
|
evalfp = data.getArch()->defaultfp;
|
||||||
|
|
|
@ -1377,6 +1377,7 @@ void Heritage::guardReturns(uint4 fl,const Address &addr,int4 size,vector<Varnod
|
||||||
vn->setAddrForce();
|
vn->setAddrForce();
|
||||||
vn->setActiveHeritage();
|
vn->setActiveHeritage();
|
||||||
fd->opSetOpcode(copyop,CPUI_COPY);
|
fd->opSetOpcode(copyop,CPUI_COPY);
|
||||||
|
copyop->setStopCopyPropagation();
|
||||||
Varnode *invn = fd->newVarnode(size,addr);
|
Varnode *invn = fd->newVarnode(size,addr);
|
||||||
invn->setActiveHeritage();
|
invn->setActiveHeritage();
|
||||||
fd->opSetInput(copyop,invn,0);
|
fd->opSetInput(copyop,invn,0);
|
||||||
|
|
|
@ -280,7 +280,8 @@ void PcodeOp::setOpcode(TypeOp *t_op)
|
||||||
{
|
{
|
||||||
flags &= ~(PcodeOp::branch | PcodeOp::call | PcodeOp::coderef | PcodeOp::commutative |
|
flags &= ~(PcodeOp::branch | PcodeOp::call | PcodeOp::coderef | PcodeOp::commutative |
|
||||||
PcodeOp::returns | PcodeOp::nocollapse | PcodeOp::marker | PcodeOp::booloutput |
|
PcodeOp::returns | PcodeOp::nocollapse | PcodeOp::marker | PcodeOp::booloutput |
|
||||||
PcodeOp::unary | PcodeOp::binary | PcodeOp::special);
|
PcodeOp::unary | PcodeOp::binary | PcodeOp::ternary | PcodeOp::special |
|
||||||
|
PcodeOp::has_callspec | PcodeOp::no_copy_propagation);
|
||||||
opcode = t_op;
|
opcode = t_op;
|
||||||
flags |= t_op->getFlags();
|
flags |= t_op->getFlags();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
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)
|
||||||
ternary = 0x40000, ///< Evaluate as ternary operator (or higher)
|
ternary = 0x40000, ///< Evaluate as ternary operator (or higher)
|
||||||
splittingbranch = 0x80000, ///< Dead edge cannot be removed as it splits
|
no_copy_propagation = 0x80000, ///< Op does not allow COPY propagation through its inputs
|
||||||
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
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
warning = 8, ///< Warning has been generated for this op
|
warning = 8, ///< Warning has been generated for this op
|
||||||
incidental_copy = 0x10, ///< Treat this as \e incidental for parameter recovery algorithms
|
incidental_copy = 0x10, ///< Treat this as \e incidental for parameter recovery algorithms
|
||||||
is_cpool_transformed = 0x20, ///< Have we checked for cpool transforms
|
is_cpool_transformed = 0x20, ///< Have we checked for cpool transforms
|
||||||
stop_propagation = 0x40 ///< Stop propagation into output from descendants
|
stop_type_propagation = 0x40 ///< Stop data-type propagation into output from descendants
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
TypeOp *opcode; ///< Pointer to class providing behavioral details of the operation
|
TypeOp *opcode; ///< Pointer to class providing behavioral details of the operation
|
||||||
|
@ -195,7 +195,6 @@ public:
|
||||||
void clearIndirectSource(void) { flags &= ~PcodeOp::indirect_source; } ///< Clear INDIRECT source flag
|
void clearIndirectSource(void) { flags &= ~PcodeOp::indirect_source; } ///< Clear INDIRECT source flag
|
||||||
bool isPtrFlow(void) const { return ((flags&PcodeOp::ptrflow)!=0); } ///< Return \b true if this produces/consumes ptrs
|
bool isPtrFlow(void) const { return ((flags&PcodeOp::ptrflow)!=0); } ///< Return \b true if this produces/consumes ptrs
|
||||||
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 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 ((addlflags&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 isIncidentalCopy(void) const { return ((addlflags&PcodeOp::incidental_copy)!=0); } ///< Return \b true if \b this COPY is \e incidental
|
bool isIncidentalCopy(void) const { return ((addlflags&PcodeOp::incidental_copy)!=0); } ///< Return \b true if \b this COPY is \e incidental
|
||||||
|
@ -204,9 +203,11 @@ 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 ((addlflags&PcodeOp::is_cpool_transformed)!=0); }
|
bool isCpoolTransformed(void) const { return ((addlflags&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
|
||||||
bool stopsPropagation(void) const { return ((addlflags&stop_propagation)!=0); } ///< Is propagation from below stopped
|
bool stopsTypePropagation(void) const { return ((addlflags&stop_type_propagation)!=0); } ///< Is data-type propagation from below stopped
|
||||||
void setStopPropagation(void) { addlflags |= stop_propagation; } ///< Stop propagation from below
|
void setStopTypePropagation(void) { addlflags |= stop_type_propagation; } ///< Stop data-type propagation from below
|
||||||
void clearStopPropagation(void) { addlflags &= ~stop_propagation; } ///< Allow propagation from below
|
void clearStopTypePropagation(void) { addlflags &= ~stop_type_propagation; } ///< Allow data-type propagation from below
|
||||||
|
bool stopsCopyPropagation(void) const { return ((flags&no_copy_propagation)!=0); } ///< Does \b this allow COPY propagation
|
||||||
|
void setStopCopyPropagation(void) { flags |= no_copy_propagation; } ///< Stop COPY propagation through inputs
|
||||||
/// \brief Return \b true if this LOADs or STOREs from a dynamic \e spacebase pointer
|
/// \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); }
|
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
|
||||||
|
|
|
@ -3552,13 +3552,8 @@ int4 RulePropagateCopy::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
int4 i;
|
int4 i;
|
||||||
PcodeOp *copyop;
|
PcodeOp *copyop;
|
||||||
Varnode *vn,*invn;
|
Varnode *vn,*invn;
|
||||||
OpCode opc;
|
|
||||||
|
|
||||||
opc = op->code();
|
if (op->stopsCopyPropagation()) return 0;
|
||||||
if (opc==CPUI_RETURN) return 0; // Preserve the address of return variable
|
|
||||||
// else if (opc == CPUI_INDIRECT) {
|
|
||||||
// if (op->Output()->isAddrForce()) return 0;
|
|
||||||
// }
|
|
||||||
for(i=0;i<op->numInput();++i) {
|
for(i=0;i<op->numInput();++i) {
|
||||||
vn = op->getIn(i);
|
vn = op->getIn(i);
|
||||||
if (!vn->isWritten()) continue; // Varnode must be written to
|
if (!vn->isWritten()) continue; // Varnode must be written to
|
||||||
|
@ -6163,7 +6158,7 @@ void AddTreeState::buildTree(void)
|
||||||
newop = data.newOpBefore(baseOp,CPUI_PTRSUB,multNode,data.newConstant(ptrsize,offset));
|
newop = data.newOpBefore(baseOp,CPUI_PTRSUB,multNode,data.newConstant(ptrsize,offset));
|
||||||
data.inheritReadResolution(newop, 0, baseOp, baseSlot);
|
data.inheritReadResolution(newop, 0, baseOp, baseSlot);
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
newop->setStopPropagation();
|
newop->setStopTypePropagation();
|
||||||
multNode = newop->getOut();
|
multNode = newop->getOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6376,7 +6371,7 @@ int4 RuleStructOffset0::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
|
|
||||||
PcodeOp *newop = data.newOpBefore(op,CPUI_PTRSUB,op->getIn(1),data.newConstant(op->getIn(1)->getSize(),0));
|
PcodeOp *newop = data.newOpBefore(op,CPUI_PTRSUB,op->getIn(1),data.newConstant(op->getIn(1)->getSize(),0));
|
||||||
data.inheritReadResolution(newop, 0, op, 1);
|
data.inheritReadResolution(newop, 0, op, 1);
|
||||||
newop->setStopPropagation();
|
newop->setStopTypePropagation();
|
||||||
data.opSetInput(op,newop->getOut(),1);
|
data.opSetInput(op,newop->getOut(),1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -6575,7 +6570,7 @@ int4 RulePtrsubUndo::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
data.opSetOpcode(op,CPUI_INT_ADD);
|
data.opSetOpcode(op,CPUI_INT_ADD);
|
||||||
op->clearStopPropagation();
|
op->clearStopTypePropagation();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -807,7 +807,7 @@ Datatype *TypeOpCallother::getOutputLocal(const PcodeOp *op) const
|
||||||
TypeOpReturn::TypeOpReturn(TypeFactory *t) : TypeOp(t,CPUI_RETURN,"return")
|
TypeOpReturn::TypeOpReturn(TypeFactory *t) : TypeOp(t,CPUI_RETURN,"return")
|
||||||
|
|
||||||
{
|
{
|
||||||
opflags = PcodeOp::special|PcodeOp::returns|PcodeOp::nocollapse;
|
opflags = PcodeOp::special|PcodeOp::returns|PcodeOp::nocollapse|PcodeOp::no_copy_propagation;
|
||||||
behave = new OpBehavior(CPUI_RETURN,false,true); // Dummy behavior
|
behave = new OpBehavior(CPUI_RETURN,false,true); // Dummy behavior
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -787,7 +787,7 @@ Datatype *Varnode::getLocalType(bool &blockup) const
|
||||||
ct = (Datatype *)0;
|
ct = (Datatype *)0;
|
||||||
if (def != (PcodeOp *)0) {
|
if (def != (PcodeOp *)0) {
|
||||||
ct = def->outputTypeLocal();
|
ct = def->outputTypeLocal();
|
||||||
if (def->stopsPropagation()) {
|
if (def->stopsTypePropagation()) {
|
||||||
blockup = true;
|
blockup = true;
|
||||||
return ct;
|
return ct;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue