mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Fix for "PTRSUB off of" errors
This commit is contained in:
parent
2ea73a65a0
commit
4382d043f1
4 changed files with 42 additions and 24 deletions
|
@ -2289,6 +2289,16 @@ int4 ActionSetCasts::apply(Funcdata &data)
|
||||||
if ((ct->getMetatype() != TYPE_PTR)||(ct->getPtrTo()->getSize() != AddrSpace::addressToByteInt(sz, ct->getWordSize())))
|
if ((ct->getMetatype() != TYPE_PTR)||(ct->getPtrTo()->getSize() != AddrSpace::addressToByteInt(sz, ct->getWordSize())))
|
||||||
data.opUndoPtradd(op,true);
|
data.opUndoPtradd(op,true);
|
||||||
}
|
}
|
||||||
|
else if (opc == CPUI_PTRSUB) { // Check for PTRSUB that no longer fits pointer
|
||||||
|
if (!op->getIn(0)->getHigh()->getType()->isPtrsubMatching(op->getIn(1)->getOffset())) {
|
||||||
|
if (op->getIn(1)->getOffset() == 0) {
|
||||||
|
data.opRemoveInput(op, 1);
|
||||||
|
data.opSetOpcode(op, CPUI_COPY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.opSetOpcode(op, CPUI_INT_ADD);
|
||||||
|
}
|
||||||
|
}
|
||||||
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 (opc == CPUI_LOAD) {
|
if (opc == CPUI_LOAD) {
|
||||||
|
|
|
@ -6363,30 +6363,8 @@ int4 RulePtrsubUndo::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
if (!data.isTypeRecoveryOn()) return 0;
|
if (!data.isTypeRecoveryOn()) return 0;
|
||||||
|
|
||||||
Varnode *basevn = op->getIn(0);
|
Varnode *basevn = op->getIn(0);
|
||||||
TypePointer *ct = (TypePointer *)basevn->getType();
|
if (basevn->getType()->isPtrsubMatching(op->getIn(1)->getOffset()))
|
||||||
bool undo = false;
|
return 0;
|
||||||
|
|
||||||
if (ct->getMetatype()!=TYPE_PTR)
|
|
||||||
undo = true;
|
|
||||||
else {
|
|
||||||
Datatype *basetype = ct->getPtrTo();
|
|
||||||
if (basetype->getMetatype()==TYPE_SPACEBASE) {
|
|
||||||
uintb newoff = AddrSpace::addressToByte(op->getIn(1)->getOffset(),ct->getWordSize());
|
|
||||||
basetype->getSubType(newoff,&newoff);
|
|
||||||
if (newoff != 0)
|
|
||||||
undo = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int4 size = op->getIn(1)->getOffset();
|
|
||||||
int4 typesize = basetype->getSize();
|
|
||||||
if ((basetype->getMetatype()!=TYPE_ARRAY)&&(basetype->getMetatype()!=TYPE_STRUCT))
|
|
||||||
undo = true; // Not a pointer to a structured type
|
|
||||||
else if ((typesize <= AddrSpace::addressToByteInt(size,ct->getWordSize()))&&(typesize!=0))
|
|
||||||
undo = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!undo) return 0;
|
|
||||||
|
|
||||||
data.opSetOpcode(op,CPUI_INT_ADD);
|
data.opSetOpcode(op,CPUI_INT_ADD);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -316,6 +316,35 @@ void Datatype::saveXmlRef(ostream &s) const
|
||||||
saveXml(s);
|
saveXml(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A CPUI_PTRSUB must act on a pointer data-type where the given offset addresses a component.
|
||||||
|
/// Perform this check.
|
||||||
|
/// \param is the given offset
|
||||||
|
/// \return \b true if \b this is a suitable PTRSUB data-type
|
||||||
|
bool Datatype::isPtrsubMatching(uintb offset) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (metatype != TYPE_PTR)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Datatype *basetype = ((TypePointer *)this)->getPtrTo();
|
||||||
|
uint4 wordsize = ((TypePointer *)this)->getWordSize();
|
||||||
|
if (basetype->metatype==TYPE_SPACEBASE) {
|
||||||
|
uintb newoff = AddrSpace::addressToByte(offset,wordsize);
|
||||||
|
basetype->getSubType(newoff,&newoff);
|
||||||
|
if (newoff != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int4 size = offset;
|
||||||
|
int4 typesize = basetype->getSize();
|
||||||
|
if ((basetype->metatype != TYPE_ARRAY)&&(basetype->metatype != TYPE_STRUCT))
|
||||||
|
return false; // Not a pointer to a structured type
|
||||||
|
else if ((typesize <= AddrSpace::addressToByteInt(size,wordsize))&&(typesize!=0))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Restore the basic properties (name,size,id) of a data-type from an XML element
|
/// Restore the basic properties (name,size,id) of a data-type from an XML element
|
||||||
/// Properties are read from the attributes of the element
|
/// Properties are read from the attributes of the element
|
||||||
/// \param el is the XML element
|
/// \param el is the XML element
|
||||||
|
|
|
@ -126,6 +126,7 @@ public:
|
||||||
int4 typeOrderBool(const Datatype &op) const; ///< Order \b this with -op-, treating \e bool data-type as special
|
int4 typeOrderBool(const Datatype &op) const; ///< Order \b this with -op-, treating \e bool data-type as special
|
||||||
void saveXmlBasic(ostream &s) const; ///< Save basic data-type properties
|
void saveXmlBasic(ostream &s) const; ///< Save basic data-type properties
|
||||||
void saveXmlRef(ostream &s) const; ///< Write an XML reference of \b this to stream
|
void saveXmlRef(ostream &s) const; ///< Write an XML reference of \b this to stream
|
||||||
|
bool isPtrsubMatching(uintb offset) const; ///< Is this data-type suitable as input to a CPUI_PTRSUB op
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Specifies subfields of a structure or what a pointer points to
|
/// \brief Specifies subfields of a structure or what a pointer points to
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue