mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Overlapping input fixes
This commit is contained in:
parent
a8f9d4f7ac
commit
2df81f803b
4 changed files with 33 additions and 9 deletions
|
@ -1649,6 +1649,12 @@ int4 AncestorRealistic::enterNode(State &state)
|
||||||
multiDepth += 1;
|
multiDepth += 1;
|
||||||
stateStack.push_back(State(op,0));
|
stateStack.push_back(State(op,0));
|
||||||
return enter_node; // Nothing to check, start traversing inputs of MULTIEQUAL
|
return enter_node; // Nothing to check, start traversing inputs of MULTIEQUAL
|
||||||
|
case CPUI_PIECE:
|
||||||
|
// If the trial is getting pieced together and then truncated in a register,
|
||||||
|
// this is evidence of artificial data-flow.
|
||||||
|
if (state.vn->getSize() > trial->getSize() && state.vn->getSpace()->getType() != IPTR_SPACEBASE)
|
||||||
|
return pop_fail;
|
||||||
|
return pop_solid;
|
||||||
default:
|
default:
|
||||||
return pop_solid; // Any other LOAD or arithmetic/logical operation is viewed as solid movement
|
return pop_solid; // Any other LOAD or arithmetic/logical operation is viewed as solid movement
|
||||||
}
|
}
|
||||||
|
|
|
@ -7279,7 +7279,7 @@ int4 RuleSubvarAnd::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
// if ((vn->getConsume() & 0xff)==0xff) return 0;
|
// if ((vn->getConsume() & 0xff)==0xff) return 0;
|
||||||
// if (op->getIn(1)->getOffset() != (uintb)1) return 0;
|
// if (op->getIn(1)->getOffset() != (uintb)1) return 0;
|
||||||
if (op->getOut()->hasNoDescend()) return 0;
|
if (op->getOut()->hasNoDescend()) return 0;
|
||||||
SubvariableFlow subflow(&data,vn,cmask,false,false);
|
SubvariableFlow subflow(&data,vn,cmask,false,false,false);
|
||||||
if (!subflow.doTrace()) return 0;
|
if (!subflow.doTrace()) return 0;
|
||||||
subflow.doReplacement();
|
subflow.doReplacement();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -7298,14 +7298,24 @@ int4 RuleSubvarSubpiece::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
{
|
{
|
||||||
Varnode *vn = op->getIn(0);
|
Varnode *vn = op->getIn(0);
|
||||||
Varnode *outvn = op->getOut();
|
Varnode *outvn = op->getOut();
|
||||||
uintb mask = calc_mask( outvn->getSize() );
|
int4 flowsize = outvn->getSize();
|
||||||
|
uintb mask = calc_mask( flowsize );
|
||||||
mask <<= 8*((int4)op->getIn(1)->getOffset());
|
mask <<= 8*((int4)op->getIn(1)->getOffset());
|
||||||
bool aggressive = outvn->isPtrFlow();
|
bool aggressive = outvn->isPtrFlow();
|
||||||
if (!aggressive) {
|
if (!aggressive) {
|
||||||
if ((vn->getConsume() & mask) != vn->getConsume()) return 0;
|
if ((vn->getConsume() & mask) != vn->getConsume()) return 0;
|
||||||
if (op->getOut()->hasNoDescend()) return 0;
|
if (op->getOut()->hasNoDescend()) return 0;
|
||||||
}
|
}
|
||||||
SubvariableFlow subflow(&data,vn,mask,aggressive,false);
|
bool big = false;
|
||||||
|
if (flowsize >= 8 && vn->isInput()) {
|
||||||
|
// Vector register inputs getting truncated to what actually gets used
|
||||||
|
// happens occasionally. We let SubvariableFlow deal with this special case
|
||||||
|
// to avoid overlapping inputs
|
||||||
|
// TODO: ActionLaneDivide should be handling this
|
||||||
|
if (vn->loneDescend() == op)
|
||||||
|
big = true;
|
||||||
|
}
|
||||||
|
SubvariableFlow subflow(&data,vn,mask,aggressive,false,big);
|
||||||
if (!subflow.doTrace()) return 0;
|
if (!subflow.doTrace()) return 0;
|
||||||
subflow.doReplacement();
|
subflow.doReplacement();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -7624,7 +7634,7 @@ int4 RuleSubvarCompZero::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SubvariableFlow subflow(&data,vn,mask,false,false);
|
SubvariableFlow subflow(&data,vn,mask,false,false,false);
|
||||||
if (!subflow.doTrace()) {
|
if (!subflow.doTrace()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -7656,7 +7666,7 @@ int4 RuleSubvarShift::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
mask = (mask >> sa) << sa;
|
mask = (mask >> sa) << sa;
|
||||||
if (op->getOut()->hasNoDescend()) return 0;
|
if (op->getOut()->hasNoDescend()) return 0;
|
||||||
|
|
||||||
SubvariableFlow subflow(&data,vn,mask,false,false);
|
SubvariableFlow subflow(&data,vn,mask,false,false,false);
|
||||||
if (!subflow.doTrace()) return 0;
|
if (!subflow.doTrace()) return 0;
|
||||||
subflow.doReplacement();
|
subflow.doReplacement();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -7677,7 +7687,7 @@ int4 RuleSubvarZext::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
Varnode *invn = op->getIn(0);
|
Varnode *invn = op->getIn(0);
|
||||||
uintb mask = calc_mask(invn->getSize());
|
uintb mask = calc_mask(invn->getSize());
|
||||||
|
|
||||||
SubvariableFlow subflow(&data,vn,mask,invn->isPtrFlow(),false);
|
SubvariableFlow subflow(&data,vn,mask,invn->isPtrFlow(),false,false);
|
||||||
if (!subflow.doTrace()) return 0;
|
if (!subflow.doTrace()) return 0;
|
||||||
subflow.doReplacement();
|
subflow.doReplacement();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -7698,7 +7708,7 @@ int4 RuleSubvarSext::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
Varnode *invn = op->getIn(0);
|
Varnode *invn = op->getIn(0);
|
||||||
uintb mask = calc_mask(invn->getSize());
|
uintb mask = calc_mask(invn->getSize());
|
||||||
|
|
||||||
SubvariableFlow subflow(&data,vn,mask,isaggressive,true);
|
SubvariableFlow subflow(&data,vn,mask,isaggressive,true,false);
|
||||||
if (!subflow.doTrace()) return 0;
|
if (!subflow.doTrace()) return 0;
|
||||||
subflow.doReplacement();
|
subflow.doReplacement();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -1260,7 +1260,8 @@ bool SubvariableFlow::processNextWork(void)
|
||||||
/// \param mask is a mask where 1 bits indicate the position of the logical value within the \e root Varnode
|
/// \param mask is a mask where 1 bits indicate the position of the logical value within the \e root Varnode
|
||||||
/// \param aggr is \b true if we should use aggressive (less restrictive) tests during the trace
|
/// \param aggr is \b true if we should use aggressive (less restrictive) tests during the trace
|
||||||
/// \param sext is \b true if we should assume sign extensions from the logical value into its container
|
/// \param sext is \b true if we should assume sign extensions from the logical value into its container
|
||||||
SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext)
|
/// \param big is \b true if we look for subvariable flow for \e big (8-byte) logical values
|
||||||
|
SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext,bool big)
|
||||||
|
|
||||||
{
|
{
|
||||||
fd = f;
|
fd = f;
|
||||||
|
@ -1280,6 +1281,13 @@ SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,
|
||||||
flowsize = 3;
|
flowsize = 3;
|
||||||
else if (bitsize <= 32)
|
else if (bitsize <= 32)
|
||||||
flowsize = 4;
|
flowsize = 4;
|
||||||
|
else if (bitsize <= 64) {
|
||||||
|
if (!big) {
|
||||||
|
fd = (Funcdata *)0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flowsize = 8;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
fd = (Funcdata *)0;
|
fd = (Funcdata *)0;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -118,7 +118,7 @@ class SubvariableFlow {
|
||||||
Varnode *getReplaceVarnode(ReplaceVarnode *rvn);
|
Varnode *getReplaceVarnode(ReplaceVarnode *rvn);
|
||||||
bool processNextWork(void); ///< Extend the subgraph from the next node in the worklist
|
bool processNextWork(void); ///< Extend the subgraph from the next node in the worklist
|
||||||
public:
|
public:
|
||||||
SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext); ///< Constructor
|
SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext,bool big); ///< Constructor
|
||||||
bool doTrace(void); ///< Trace logical value through data-flow, constructing transform
|
bool doTrace(void); ///< Trace logical value through data-flow, constructing transform
|
||||||
void doReplacement(void); ///< Perform the discovered transform, making logical values explicit
|
void doReplacement(void); ///< Perform the discovered transform, making logical values explicit
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue