GP-5184_PtrsubUndoFix

This commit is contained in:
caheckman 2024-12-16 20:29:08 +00:00
parent 420dd7ce0c
commit 21a6a276b2
10 changed files with 66 additions and 47 deletions

View file

@ -289,7 +289,7 @@ Varnode *StringSequence::constructTypedPointer(PcodeOp *insertPoint)
spacePtr = data.newUniqueOut(spacePtr->getSize(), ptrsub);
data.opInsertBefore(ptrsub, insertPoint);
TypePointer *curType = types->getTypePointerStripArray(spacePtr->getSize(), baseType, spc->getWordSize());
spacePtr->updateType(curType, false, false);
spacePtr->updateType(curType);
int8 curOff = rootAddr.getOffset() - entry->getFirst();
while(baseType != charType) {
int4 elSize = -1;
@ -321,7 +321,7 @@ Varnode *StringSequence::constructTypedPointer(PcodeOp *insertPoint)
spacePtr = data.newUniqueOut(spacePtr->getSize(), ptrsub);
data.opInsertBefore(ptrsub, insertPoint);
curType = types->getTypePointerStripArray(spacePtr->getSize(), baseType, spc->getWordSize());
spacePtr->updateType(curType, false, false);
spacePtr->updateType(curType);
curOff = newOff;
}
if (curOff != 0) {
@ -333,7 +333,7 @@ Varnode *StringSequence::constructTypedPointer(PcodeOp *insertPoint)
spacePtr = data.newUniqueOut(spacePtr->getSize(), addOp);
data.opInsertBefore(addOp, insertPoint);
curType = types->getTypePointer(spacePtr->getSize(), charType, spc->getWordSize());
spacePtr->updateType(curType, false, false);
spacePtr->updateType(curType);
}
return spacePtr;
}
@ -365,7 +365,7 @@ PcodeOp *StringSequence::buildStringCopy(void)
data.opSetInput(copyOp, destPtr, 1);
data.opSetInput(copyOp, srcPtr, 2);
Varnode *lenVn = data.newConstant(4,index);
lenVn->updateType(copyOp->inputTypeLocal(3), false, false);
lenVn->updateType(copyOp->inputTypeLocal(3));
data.opSetInput(copyOp, lenVn, 3);
data.opInsertBefore(copyOp, insertPoint);
return copyOp;
@ -717,14 +717,14 @@ PcodeOp *HeapSequence::buildStringCopy(void)
data.opSetInput(addOp, indexVn, 0);
data.opSetInput(addOp, nonConstAdds[i],1);
indexVn = data.newUniqueOut(indexVn->getSize(), addOp);
indexVn->updateType(intType, false, false);
indexVn->updateType(intType);
data.opInsertBefore(addOp, insertPoint);
}
}
if (baseOffset != 0) { // Add in any non-zero constant
uint8 numEl = baseOffset / charType->getAlignSize();
Varnode *cvn = data.newConstant(basePointer->getSize(), numEl);
cvn->updateType(intType, false, false);
cvn->updateType(intType);
if (indexVn == (Varnode *)0)
indexVn = cvn;
else {
@ -733,7 +733,7 @@ PcodeOp *HeapSequence::buildStringCopy(void)
data.opSetInput(addOp, indexVn, 0);
data.opSetInput(addOp, cvn,1);
indexVn = data.newUniqueOut(indexVn->getSize(), addOp);
indexVn->updateType(intType, false, false);
indexVn->updateType(intType);
data.opInsertBefore(addOp, insertPoint);
}
}
@ -743,7 +743,7 @@ PcodeOp *HeapSequence::buildStringCopy(void)
data.opSetInput(ptrAdd,basePointer,0);
data.opSetInput(ptrAdd,indexVn,1);
data.opSetInput(ptrAdd,data.newConstant(basePointer->getSize(), charType->getAlignSize()),2);
destPtr->updateType(charPtrType, false, false);
destPtr->updateType(charPtrType);
data.opInsertBefore(ptrAdd, insertPoint);
}
int4 index;
@ -755,7 +755,7 @@ PcodeOp *HeapSequence::buildStringCopy(void)
data.opSetInput(copyOp, destPtr, 1);
data.opSetInput(copyOp, srcPtr, 2);
Varnode *lenVn = data.newConstant(4,index);
lenVn->updateType(copyOp->inputTypeLocal(3), false, false);
lenVn->updateType(copyOp->inputTypeLocal(3));
data.opSetInput(copyOp, lenVn, 3);
data.opInsertBefore(copyOp, insertPoint);
return copyOp;

View file

@ -2552,7 +2552,7 @@ int4 ActionSetCasts::castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStr
}
}
else if (outHighResolve->getMetatype() != TYPE_PTR) { // If implied varnode has an atomic (non-pointer) type
outvn->updateType(tokenct,false,false); // Ignore it in favor of the token type
outvn->updateType(tokenct); // Ignore it in favor of the token type
outHighResolve = outvn->getHighTypeDefFacing();
}
else if (tokenct->getMetatype() == TYPE_PTR) { // If the token is a pointer AND implied varnode is pointer
@ -2560,7 +2560,7 @@ int4 ActionSetCasts::castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStr
type_metatype meta = outct->getMetatype();
// Preserve implied pointer if it points to a composite
if ((meta!=TYPE_ARRAY)&&(meta!=TYPE_STRUCT)&&(meta!=TYPE_UNION)) {
outvn->updateType(tokenct,false,false); // Otherwise ignore it in favor of the token type
outvn->updateType(tokenct); // Otherwise ignore it in favor of the token type
outHighResolve = outvn->getHighTypeDefFacing();
}
}
@ -2578,7 +2578,7 @@ int4 ActionSetCasts::castOutput(PcodeOp *op,Funcdata &data,CastStrategy *castStr
}
// Generate the cast op
vn = data.newUnique(outvn->getSize());
vn->updateType(tokenct,false,false);
vn->updateType(tokenct);
vn->setImplied();
newop = data.newOp((opc != CPUI_CAST) ? 2 : 1,op->getAddr());
#ifdef CPUI_STATISTICS
@ -2618,7 +2618,7 @@ PcodeOp *ActionSetCasts::insertPtrsubZero(PcodeOp *op,int4 slot,Datatype *ct,Fun
Varnode *vn = op->getIn(slot);
PcodeOp *newop = data.newOp(2,op->getAddr());
Varnode *vnout = data.newUniqueOut(vn->getSize(), newop);
vnout->updateType(ct,false,false);
vnout->updateType(ct);
vnout->setImplied();
data.opSetOpcode(newop, CPUI_PTRSUB);
data.opSetInput(newop,vn,0);
@ -2658,7 +2658,7 @@ int4 ActionSetCasts::castInput(PcodeOp *op,int4 slot,Funcdata &data,CastStrategy
if (vn->isWritten() && (vn->getDef()->code() == CPUI_CAST)) {
if (vn->isImplied()) {
if (vn->loneDescend() == op) {
vn->updateType(ct,false,false);
vn->updateType(ct);
if (vn->getType()==ct)
return 1;
}
@ -2670,7 +2670,7 @@ int4 ActionSetCasts::castInput(PcodeOp *op,int4 slot,Funcdata &data,CastStrategy
}
}
else if (vn->isConstant()) {
vn->updateType(ct,false,false);
vn->updateType(ct);
if (vn->getType() == ct)
return 1;
}
@ -2686,7 +2686,7 @@ int4 ActionSetCasts::castInput(PcodeOp *op,int4 slot,Funcdata &data,CastStrategy
}
newop = data.newOp(1,op->getAddr());
vnout = data.newUniqueOut(vnin->getSize(),newop);
vnout->updateType(ct,false,false);
vnout->updateType(ct);
vnout->setImplied();
#ifdef CPUI_STATISTICS
data.getArch()->stats->countCast();
@ -4898,7 +4898,7 @@ bool ActionInferTypes::writeBack(Funcdata &data)
if (vn->isAnnotation()) continue;
if ((!vn->isWritten())&&(vn->hasNoDescend())) continue;
ct = vn->getTempType();
if (vn->updateType(ct,false,false))
if (vn->updateType(ct))
change = true;
}
return change;

View file

@ -565,7 +565,7 @@ void Funcdata::opUndoPtradd(PcodeOp *op,bool finalize)
newVal &= calc_mask(offVn->getSize());
Varnode *newOffVn = newConstant(offVn->getSize(), newVal);
if (finalize)
newOffVn->updateType(offVn->getTypeReadFacing(op), false, false);
newOffVn->updateType(offVn->getTypeReadFacing(op));
opSetInput(op,newOffVn,1);
return;
}
@ -573,7 +573,7 @@ void Funcdata::opUndoPtradd(PcodeOp *op,bool finalize)
opSetOpcode(multOp,CPUI_INT_MULT);
Varnode *addVn = newUniqueOut(offVn->getSize(),multOp);
if (finalize) {
addVn->updateType(multVn->getType(), false, false);
addVn->updateType(multVn->getType());
addVn->setImplied();
}
opSetInput(multOp,offVn,0);

View file

@ -1081,7 +1081,7 @@ bool Funcdata::syncVarnodesWithSymbol(VarnodeLocSet::const_iterator &iter,uint4
vn->clearFlags((~fl)&mask);
}
if (ct != (Datatype *)0) {
if (vn->updateType(ct,false,false))
if (vn->updateType(ct))
updateoccurred = true;
}
} while(iter != enditer);

View file

@ -6298,7 +6298,7 @@ void AddTreeState::assignPropagatedType(PcodeOp *op)
Datatype *inType = vn->getTypeReadFacing(op);
Datatype *newType = op->getOpcode()->propagateType(inType, op, vn, op->getOut(), 0, -1);
if (newType != (Datatype *)0)
op->getOut()->updateType(newType, false, false);
op->getOut()->updateType(newType);
}
/// Construct part of the tree that sums to a multiple of the base data-type size.
@ -6749,7 +6749,7 @@ void RulePushPtr::duplicateNeed(PcodeOp *op,Funcdata &data)
int4 slot = decOp->getSlot(outVn);
PcodeOp *newOp = data.newOp(num, op->getAddr()); // Duplicate op associated with original address
Varnode *newOut = buildVarnodeOut(outVn, newOp, data); // Result contained in original storage
newOut->updateType(outVn->getType(),false,false);
newOut->updateType(outVn->getType());
data.opSetOpcode(newOp, opc);
data.opSetInput(newOp, inVn, 0);
if (num > 1)
@ -6959,7 +6959,6 @@ int8 RulePtrsubUndo::getExtraOffset(PcodeOp *op,int8 &multiplier)
op = outvn->loneDescend();
}
extra = sign_extend(extra, 8*outvn->getSize()-1);
extra &= calc_mask(outvn->getSize());
return extra;
}
@ -7033,6 +7032,8 @@ int8 RulePtrsubUndo::removeLocalAdds(Varnode *vn,Funcdata &data)
}
else if (opc == CPUI_PTRADD) {
if (op->getIn(0) != vn) break;
// The PTRADD should be converted to an INT_ADD or COPY
// as it is associated with the invalid PTRSUB
int8 ptraddmult = op->getIn(2)->getOffset();
Varnode *invn = op->getIn(1);
if (invn->isConstant()) {
@ -7041,6 +7042,10 @@ int8 RulePtrsubUndo::removeLocalAdds(Varnode *vn,Funcdata &data)
data.opRemoveInput(op,1);
data.opSetOpcode(op, CPUI_COPY);
}
else {
data.opUndoPtradd(op, false);
extra += removeLocalAddRecurse(op,1,DEPTH_LIMIT, data);
}
}
else {
break;
@ -7257,7 +7262,7 @@ bool RulePtrsubCharConstant::pushConstFurther(Funcdata &data,TypePointer *outtyp
addval *= op->getIn(2)->getOffset();
val += addval;
Varnode *newconst = data.newConstant(vn->getSize(),val);
newconst->updateType(outtype,false,false); // Put the pointer datatype on new constant
newconst->updateType(outtype); // Put the pointer datatype on new constant
data.opRemoveInput(op,2);
data.opRemoveInput(op,1);
data.opSetOpcode(op,CPUI_COPY);
@ -7319,7 +7324,7 @@ int4 RulePtrsubCharConstant::applyOp(PcodeOp *op,Funcdata &data)
}
else { // Convert the original PTRSUB to a COPY of the constant
Varnode *newvn = data.newConstant(outvn->getSize(),vn1->getOffset());
newvn->updateType(outtype,false,false);
newvn->updateType(outtype);
data.opRemoveInput(op,1);
data.opSetInput(op,newvn,0);
data.opSetOpcode(op,CPUI_COPY);
@ -7462,7 +7467,7 @@ bool RulePieceStructure::convertZextToPiece(PcodeOp *zext,Datatype *ct,int4 offs
}
Varnode *zerovn = data.newConstant(sz, 0);
if (ct != (Datatype *)0 && ct->getSize() == sz)
zerovn->updateType(ct, false, false);
zerovn->updateType(ct);
data.opSetOpcode(zext, CPUI_PIECE);
data.opInsertInput(zext, zerovn, 0);
if (invn->getType()->needsResolution())
@ -7590,7 +7595,7 @@ int4 RulePieceStructure::applyOp(PcodeOp *op,Funcdata &data)
Datatype *newType = data.getArch()->types->getExactPiece(ct, node.getTypeOffset(), vn->getSize());
if (newType == (Datatype *)0)
newType = vn->getType();
newVn->updateType(newType, false, false);
newVn->updateType(newType);
data.opSetOpcode(copyOp, CPUI_COPY);
data.opSetInput(copyOp, vn, 0);
data.opSetInput(node.getOp(),newVn,node.getSlot());
@ -10808,13 +10813,13 @@ void RuleExpandLoad::modifyAndComparison(Funcdata &data,Varnode *oldVn,Varnode *
uintb newOff = andOp->getIn(1)->getOffset();
newOff <<= offset;
Varnode *vn = data.newConstant(dt->getSize(), newOff);
vn->updateType(dt, false, false);
vn->updateType(dt);
data.opSetInput(andOp, newVn, 0);
data.opSetInput(andOp, vn, 1);
newOff = compOp->getIn(1)->getOffset();
newOff <<= offset;
vn = data.newConstant(dt->getSize(), newOff);
vn->updateType(dt, false, false);
vn->updateType(dt);
data.opSetInput(compOp,vn,1);
}
}

View file

@ -2164,7 +2164,7 @@ void SplitDatatype::RootPointer::duplicateToTemp(Funcdata &data,PcodeOp *followO
{
Varnode *newRoot = data.buildCopyTemp(pointer, followOp);
newRoot->updateType(ptrType, false, false);
newRoot->updateType(ptrType);
pointer = newRoot;
}
@ -2438,7 +2438,7 @@ bool SplitDatatype::generateConstants(Varnode *vn,vector<Varnode *> &inVarnodes)
val &= calc_mask(dt->getSize());
Varnode *outVn = data.newConstant(dt->getSize(), val);
inVarnodes.push_back(outVn);
outVn->updateType(dt, false, false);
outVn->updateType(dt);
}
data.opDestroy(op);
return true;
@ -2463,7 +2463,7 @@ void SplitDatatype::buildInConstants(Varnode *rootVn,vector<Varnode *> &inVarnod
uintb val = (baseVal >> (8*off)) & calc_mask(dt->getSize());
Varnode *outVn = data.newConstant(dt->getSize(), val);
inVarnodes.push_back(outVn);
outVn->updateType(dt, false, false);
outVn->updateType(dt);
}
}
@ -2493,7 +2493,7 @@ void SplitDatatype::buildInSubpieces(Varnode *rootVn,PcodeOp *followOp,vector<Va
data.opSetInput(subpiece,data.newConstant(4, off), 1);
Varnode *outVn = data.newVarnodeOut(dt->getSize(), addr, subpiece);
inVarnodes.push_back(outVn);
outVn->updateType(dt, false, false);
outVn->updateType(dt);
data.opInsertBefore(subpiece, followOp);
}
}
@ -2631,7 +2631,7 @@ void SplitDatatype::buildPointers(Varnode *rootVn,TypePointer *ptrType,int4 base
data.opSetInput(newOp, indexVn, 1);
data.opSetInput(newOp, data.newConstant(inPtr->getSize(), sz), 2);
Datatype *indexType = types->getBase(indexVn->getSize(),TYPE_INT);
indexVn->updateType(indexType, false, false);
indexVn->updateType(indexType);
}
else {
int8 finalOffset = AddrSpace::byteToAddressInt(curOff - newOff,ptrType->getWordSize());
@ -2642,7 +2642,7 @@ void SplitDatatype::buildPointers(Varnode *rootVn,TypePointer *ptrType,int4 base
}
inPtr = data.newUniqueOut(inPtr->getSize(), newOp);
Datatype *tmpPtr = types->getTypePointerStripArray(ptrType->getSize(), newType, ptrType->getWordSize());
inPtr->updateType(tmpPtr, false, false);
inPtr->updateType(tmpPtr);
data.opInsertBefore(newOp, followOp);
tmpType = newType;
curOff = newOff;
@ -2842,7 +2842,7 @@ bool SplitDatatype::splitStore(PcodeOp *storeOp,Datatype *outType)
data.opSetInput(newLoadOp,loadPtrs[i],1);
Datatype *dt = dataTypePieces[i].inType;
Varnode *vn = data.newUniqueOut(dt->getSize(), newLoadOp);
vn->updateType(dt, false, false);
vn->updateType(dt);
inVarnodes.push_back(vn);
data.opInsertBefore(newLoadOp, loadOp);
}

View file

@ -21,7 +21,7 @@ namespace ghidra {
/// The base propagation ordering associated with each meta-type.
/// The array elements correspond to the ordering of #type_metatype.
sub_metatype Datatype::base2sub[18] = {
SUB_PARTIALUNION, SUB_PARTIALSTRUCT, SUB_UINT_ENUM, SUB_UNION, SUB_STRUCT, SUB_INT_ENUM, SUB_UINT_ENUM,
SUB_PARTIALUNION, SUB_PARTIALSTRUCT, SUB_UINT_PARTIALENUM, SUB_UNION, SUB_STRUCT, SUB_INT_ENUM, SUB_UINT_ENUM,
SUB_ARRAY, SUB_PTRREL, SUB_PTR, SUB_FLOAT, SUB_CODE, SUB_BOOL, SUB_UINT_PLAIN, SUB_INT_PLAIN, SUB_UNKNOWN,
SUB_SPACEBASE, SUB_VOID
};

View file

@ -101,15 +101,16 @@ enum type_metatype {
/// Specializations of the core meta-types. Each enumeration is associated with a specific #type_metatype.
/// Ordering is important: The lower the number, the more \b specific the data-type, affecting propagation.
enum sub_metatype {
SUB_VOID = 22, ///< Compare as a TYPE_VOID
SUB_SPACEBASE = 21, ///< Compare as a TYPE_SPACEBASE
SUB_UNKNOWN = 20, ///< Compare as a TYPE_UNKNOWN
SUB_PARTIALSTRUCT = 19, ///< Compare as TYPE_PARTIALSTRUCT
SUB_INT_CHAR = 18, ///< Signed 1-byte character, sub-type of TYPE_INT
SUB_UINT_CHAR = 17, ///< Unsigned 1-byte character, sub-type of TYPE_UINT
SUB_INT_PLAIN = 16, ///< Compare as a plain TYPE_INT
SUB_UINT_PLAIN = 15, ///< Compare as a plain TYPE_UINT
SUB_INT_ENUM = 14, ///< Signed enum, sub-type of TYPE_INT
SUB_VOID = 23, ///< Compare as a TYPE_VOID
SUB_SPACEBASE = 22, ///< Compare as a TYPE_SPACEBASE
SUB_UNKNOWN = 21, ///< Compare as a TYPE_UNKNOWN
SUB_PARTIALSTRUCT = 20, ///< Compare as TYPE_PARTIALSTRUCT
SUB_INT_CHAR = 19, ///< Signed 1-byte character, sub-type of TYPE_INT
SUB_UINT_CHAR = 18, ///< Unsigned 1-byte character, sub-type of TYPE_UINT
SUB_INT_PLAIN = 17, ///< Compare as a plain TYPE_INT
SUB_UINT_PLAIN = 16, ///< Compare as a plain TYPE_UINT
SUB_INT_ENUM = 15, ///< Signed enum, sub-type of TYPE_INT
SUB_UINT_PARTIALENUM = 14, ///< Unsigned partial enum, sub-type of TYPE_UINT
SUB_UINT_ENUM = 13, ///< Unsigned enum, sub-type of TYPE_UINT
SUB_INT_UNICODE = 12, ///< Signed wide character, sub-type of TYPE_INT
SUB_UINT_UNICODE = 11, ///< Unsigned wide character, sub-type of TYPE_UINT

View file

@ -451,6 +451,18 @@ void Varnode::setSymbolReference(SymbolEntry *entry,int4 off)
}
}
/// \param ct is the Datatype to change to
/// \return \b true if the Datatype changed
bool Varnode::updateType(Datatype *ct)
{
if (type == ct || isTypeLock()) return false;
type = ct;
if (high != (HighVariable *)0)
high->typeDirty();
return true;
}
/// Change the Datatype and lock state associated with this Varnode if various conditions are met
/// - Don't change a previously locked Datatype (unless \b override flag is \b true)
/// - Don't consider an \b undefined type to be locked

View file

@ -333,7 +333,8 @@ public:
void setStopUpPropagation(void) { addlflags |= Varnode::stop_uppropagation; } ///< Stop up-propagation thru \b this
void clearStopUpPropagation(void) { addlflags &= ~Varnode::stop_uppropagation; } ///< Stop up-propagation thru \b this
void setImpliedField(void) { addlflags |= Varnode::has_implied_field; } ///< Mark \b this as having an implied field
bool updateType(Datatype *ct,bool lock,bool override); ///< (Possibly) set the Datatype given various restrictions
bool updateType(Datatype *ct); ///< Set the Datatype if not locked
bool updateType(Datatype *ct,bool lock,bool over); ///< (Possibly) set the Datatype given various restrictions
void setStackStore(void) { addlflags |= Varnode::stack_store; } ///< Mark as produced by explicit CPUI_STORE
void setLockedInput(void) { addlflags |= Varnode::locked_input; } ///< Mark as existing input, even if unused
void copySymbol(const Varnode *vn); ///< Copy symbol info from \b vn