mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
PTRADD adjustments post ActionRestructureHigh
This commit is contained in:
parent
cfc1177ac1
commit
9a3ab38631
4 changed files with 50 additions and 21 deletions
|
@ -2059,17 +2059,24 @@ int4 ActionSetCasts::apply(Funcdata &data)
|
||||||
for(iter=bb->beginOp();iter!=bb->endOp();++iter) {
|
for(iter=bb->beginOp();iter!=bb->endOp();++iter) {
|
||||||
op = *iter;
|
op = *iter;
|
||||||
if (op->notPrinted()) continue;
|
if (op->notPrinted()) continue;
|
||||||
if (op->code() == CPUI_CAST) continue;
|
OpCode opc = op->code();
|
||||||
|
if (opc == CPUI_CAST) continue;
|
||||||
|
if (opc == CPUI_PTRADD) { // Check for PTRADD that no longer fits its pointer
|
||||||
|
int4 sz = (int4)op->getIn(2)->getOffset();
|
||||||
|
TypePointer *ct = (TypePointer *)op->getIn(0)->getHigh()->getType();
|
||||||
|
if ((ct->getMetatype() != TYPE_PTR)||(ct->getPtrTo()->getSize() != AddrSpace::addressToByteInt(sz, ct->getWordSize())))
|
||||||
|
data.opUndoPtradd(op,true);
|
||||||
|
}
|
||||||
for(int4 i=0;i<op->numInput();++i) // Do input casts first, as output may depend on input
|
for(int4 i=0;i<op->numInput();++i) // Do input casts first, as output may depend on input
|
||||||
count += castInput(op,i,data,castStrategy);
|
count += castInput(op,i,data,castStrategy);
|
||||||
if (op->code() == CPUI_LOAD) {
|
if (opc == CPUI_LOAD) {
|
||||||
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHigh()->getType();
|
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHigh()->getType();
|
||||||
int4 valsize = op->getOut()->getSize();
|
int4 valsize = op->getOut()->getSize();
|
||||||
if ((ptrtype->getMetatype()!=TYPE_PTR)||
|
if ((ptrtype->getMetatype()!=TYPE_PTR)||
|
||||||
(ptrtype->getPtrTo()->getSize() != valsize))
|
(ptrtype->getPtrTo()->getSize() != valsize))
|
||||||
data.warning("Load size is inaccurate",op->getAddr());
|
data.warning("Load size is inaccurate",op->getAddr());
|
||||||
}
|
}
|
||||||
else if (op->code() == CPUI_STORE) {
|
else if (opc == CPUI_STORE) {
|
||||||
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHigh()->getType();
|
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHigh()->getType();
|
||||||
int4 valsize = op->getIn(2)->getSize();
|
int4 valsize = op->getIn(2)->getSize();
|
||||||
if ((ptrtype->getMetatype()!=TYPE_PTR)||
|
if ((ptrtype->getMetatype()!=TYPE_PTR)||
|
||||||
|
|
|
@ -428,6 +428,7 @@ public:
|
||||||
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);
|
||||||
PcodeOp *opStackStore(AddrSpace *spc,uintb off,PcodeOp *op,bool insertafter);
|
PcodeOp *opStackStore(AddrSpace *spc,uintb off,PcodeOp *op,bool insertafter);
|
||||||
|
void opUndoPtradd(PcodeOp *op,bool finalize); ///< Convert a CPUI_PTRADD back into a CPUI_INT_ADD
|
||||||
|
|
||||||
/// \brief Start of PcodeOp objects with the given op-code
|
/// \brief Start of PcodeOp objects with the given op-code
|
||||||
list<PcodeOp *>::const_iterator beginOp(OpCode opc) const { return obank.begin(opc); }
|
list<PcodeOp *>::const_iterator beginOp(OpCode opc) const { return obank.begin(opc); }
|
||||||
|
|
|
@ -521,6 +521,42 @@ Varnode *Funcdata::opStackLoad(AddrSpace *spc,uintb off,uint4 sz,PcodeOp *op,Var
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert the given CPUI_PTRADD into the equivalent CPUI_INT_ADD. This may involve inserting a
|
||||||
|
/// CPUI_INT_MULT PcodeOp. If finalization is requested and a new PcodeOp is needed, the output
|
||||||
|
/// Varnode is marked as \e implicit and has its data-type set
|
||||||
|
/// \param op is the given PTRADD
|
||||||
|
void Funcdata::opUndoPtradd(PcodeOp *op,bool finalize)
|
||||||
|
|
||||||
|
{
|
||||||
|
Varnode *multVn = op->getIn(2);
|
||||||
|
int4 multSize = multVn->getOffset(); // Size the PTRADD thinks we are pointing
|
||||||
|
|
||||||
|
opRemoveInput(op,2);
|
||||||
|
opSetOpcode(op,CPUI_INT_ADD);
|
||||||
|
if (multSize == 1) return; // If no multiplier, we are done
|
||||||
|
Varnode *offVn = op->getIn(1);
|
||||||
|
if (offVn->isConstant()) {
|
||||||
|
uintb newVal = multSize * offVn->getOffset();
|
||||||
|
newVal &= calc_mask(offVn->getSize());
|
||||||
|
Varnode *newOffVn = newConstant(offVn->getSize(), newVal);
|
||||||
|
if (finalize)
|
||||||
|
newOffVn->updateType(offVn->getType(), false, false);
|
||||||
|
opSetInput(op,newOffVn,1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PcodeOp *multOp = newOp(2,op->getAddr());
|
||||||
|
opSetOpcode(multOp,CPUI_INT_MULT);
|
||||||
|
Varnode *addVn = newUniqueOut(offVn->getSize(),multOp);
|
||||||
|
if (finalize) {
|
||||||
|
addVn->updateType(multVn->getType(), false, false);
|
||||||
|
addVn->setImplied();
|
||||||
|
}
|
||||||
|
opSetInput(multOp,offVn,0);
|
||||||
|
opSetInput(multOp,multVn,1);
|
||||||
|
opSetInput(op,addVn,1);
|
||||||
|
opInsertBefore(multOp,op);
|
||||||
|
}
|
||||||
|
|
||||||
/// Make a clone of the given PcodeOp, copying control-flow properties as well. The data-type
|
/// Make a clone of the given PcodeOp, copying control-flow properties as well. The data-type
|
||||||
/// is \e not cloned.
|
/// is \e not cloned.
|
||||||
/// \param op is the PcodeOp to clone
|
/// \param op is the PcodeOp to clone
|
||||||
|
|
|
@ -6105,14 +6105,11 @@ void RulePtraddUndo::getOpList(vector<uint4> &oplist) const
|
||||||
int4 RulePtraddUndo::applyOp(PcodeOp *op,Funcdata &data)
|
int4 RulePtraddUndo::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
|
|
||||||
{
|
{
|
||||||
int4 size;
|
Varnode *basevn;
|
||||||
Varnode *basevn,*offvn,*multvn,*addvn;
|
|
||||||
PcodeOp *multop;
|
|
||||||
TypePointer *tp;
|
TypePointer *tp;
|
||||||
|
|
||||||
if (!data.isTypeRecoveryOn()) return 0;
|
if (!data.isTypeRecoveryOn()) return 0;
|
||||||
multvn = op->getIn(2);
|
int4 size = (int4)op->getIn(2)->getOffset(); // Size the PTRADD thinks we are pointing
|
||||||
size = multvn->getOffset(); // Size the PTRADD thinks we are pointing
|
|
||||||
basevn = op->getIn(0);
|
basevn = op->getIn(0);
|
||||||
tp = (TypePointer *)basevn->getType();
|
tp = (TypePointer *)basevn->getType();
|
||||||
if (tp->getMetatype() == TYPE_PTR) // Make sure we are still a pointer
|
if (tp->getMetatype() == TYPE_PTR) // Make sure we are still a pointer
|
||||||
|
@ -6122,19 +6119,7 @@ int4 RulePtraddUndo::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point we have a type mismatch to fix
|
data.opUndoPtradd(op,false);
|
||||||
data.opRemoveInput(op,2);
|
|
||||||
data.opSetOpcode(op,CPUI_INT_ADD);
|
|
||||||
if (size == 1) return 1; // If no multiplier, we are done
|
|
||||||
multop = data.newOp(2,op->getAddr());
|
|
||||||
data.opSetOpcode(multop,CPUI_INT_MULT);
|
|
||||||
offvn = op->getIn(1);
|
|
||||||
addvn = data.newUniqueOut(offvn->getSize(),multop);
|
|
||||||
data.opSetInput(multop,offvn,0);
|
|
||||||
data.opSetInput(multop,multvn,1);
|
|
||||||
data.opSetInput(op,addvn,1);
|
|
||||||
data.opInsertBefore(multop,op);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue