mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GP-1407_TypePropagation'
This commit is contained in:
commit
618f52c0ed
4 changed files with 81 additions and 49 deletions
|
@ -3163,6 +3163,9 @@ void IfcLoadTestFile::execute(istream &s)
|
|||
s >> filename;
|
||||
dcp->testCollection = new FunctionTestCollection(status);
|
||||
dcp->testCollection->loadTest(filename);
|
||||
#ifdef OPACTION_DEBUG
|
||||
dcp->conf->setDebugStream(status->fileoptr);
|
||||
#endif
|
||||
*status->optr << filename << " test successfully loaded: " << dcp->conf->getDescription() << endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
#include "type.hh"
|
||||
#include "funcdata.hh"
|
||||
|
||||
sub_metatype Datatype::base2sub[11] = {
|
||||
SUB_STRUCT, SUB_ARRAY, SUB_PTR, SUB_FLOAT, SUB_CODE, SUB_BOOL,
|
||||
SUB_UINT_PLAIN, SUB_INT_PLAIN, SUB_UNKNOWN, SUB_SPACEBASE, SUB_VOID
|
||||
};
|
||||
|
||||
// Some default routines for displaying data
|
||||
|
||||
/// Display an array of bytes as a hex dump at a given address.
|
||||
|
@ -138,7 +143,9 @@ Datatype *Datatype::nearestArrayedComponentBackward(uintb off,uintb *newoff,int4
|
|||
int4 Datatype::compare(const Datatype &op,int4 level) const
|
||||
|
||||
{
|
||||
return compareDependency(op);
|
||||
if (size != op.size) return (op.size - size);
|
||||
if (submeta != op.submeta) return (submeta < op.submeta) ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Sort data-types for the main TypeFactory container. The sort needs to be based on
|
||||
|
@ -152,15 +159,7 @@ int4 Datatype::compareDependency(const Datatype &op) const
|
|||
|
||||
{
|
||||
if (size != op.size) return (op.size-size);
|
||||
if (metatype != op.metatype) return (metatype < op.metatype) ? -1 : 1;
|
||||
uint4 fl = flags & (~coretype);
|
||||
uint4 opfl = op.flags & (~coretype);
|
||||
// We need to be careful here, we compare flags so that enum types are more specific than base int or uint,
|
||||
// we also want UTF16 and UTF32 to be more specific than int, BUT
|
||||
// we don't want char to be more specific than int1 because char is the default size 1 integer type.
|
||||
fl ^= chartype;
|
||||
opfl ^= chartype;
|
||||
if (fl != opfl) return (opfl < fl) ? -1 : 1;
|
||||
if (submeta != op.submeta) return (submeta < op.submeta) ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -381,6 +380,7 @@ void Datatype::restoreXmlBasic(const Element *el)
|
|||
if (size < 0)
|
||||
throw LowlevelError("Bad size for type "+name);
|
||||
metatype = string2metatype( el->getAttributeValue("metatype") );
|
||||
submeta = base2sub[metatype];
|
||||
id = 0;
|
||||
for(int4 i=0;i<el->getNumAttributes();++i) {
|
||||
const string &attribName( el->getAttributeName(i) );
|
||||
|
@ -454,6 +454,13 @@ uint8 Datatype::hashSize(uint8 id,int4 size)
|
|||
return id;
|
||||
}
|
||||
|
||||
void TypeChar::restoreXml(const Element *el,TypeFactory &typegrp)
|
||||
|
||||
{
|
||||
restoreXmlBasic(el);
|
||||
submeta = (metatype == TYPE_INT) ? SUB_INT_CHAR : SUB_UINT_CHAR;
|
||||
}
|
||||
|
||||
void TypeChar::saveXml(ostream &s) const
|
||||
|
||||
{
|
||||
|
@ -486,12 +493,14 @@ void TypeUnicode::restoreXml(const Element *el,TypeFactory &typegrp)
|
|||
restoreXmlBasic(el);
|
||||
// Get endianness flag from architecture, rather than specific type encoding
|
||||
setflags();
|
||||
submeta = (metatype == TYPE_INT) ? SUB_INT_UNICODE : SUB_UINT_UNICODE;
|
||||
}
|
||||
|
||||
TypeUnicode::TypeUnicode(const string &nm,int4 sz,type_metatype m)
|
||||
: TypeBase(sz,m,nm)
|
||||
{
|
||||
setflags(); // Set special unicode UTF flags
|
||||
submeta = (m == TYPE_INT) ? SUB_INT_UNICODE : SUB_UINT_UNICODE;
|
||||
}
|
||||
|
||||
void TypeUnicode::saveXml(ostream &s) const
|
||||
|
@ -527,12 +536,10 @@ void TypePointer::printRaw(ostream &s) const
|
|||
int4 TypePointer::compare(const Datatype &op,int4 level) const
|
||||
|
||||
{
|
||||
TypePointer *tp;
|
||||
|
||||
if (size != op.getSize()) return (op.getSize()-size);
|
||||
if (metatype != op.getMetatype()) return (metatype < op.getMetatype()) ? -1 : 1;
|
||||
int4 res = Datatype::compare(op,level);
|
||||
if (res != 0) return res;
|
||||
// Both must be pointers
|
||||
tp = (TypePointer *) &op;
|
||||
TypePointer *tp = (TypePointer *) &op;
|
||||
if (wordsize != tp->wordsize) return (wordsize < tp->wordsize) ? -1 : 1;
|
||||
level -= 1;
|
||||
if (level < 0) {
|
||||
|
@ -545,12 +552,10 @@ int4 TypePointer::compare(const Datatype &op,int4 level) const
|
|||
int4 TypePointer::compareDependency(const Datatype &op) const
|
||||
|
||||
{
|
||||
TypePointer *tp;
|
||||
|
||||
if (size != op.getSize()) return (op.getSize()-size);
|
||||
if (metatype != op.getMetatype()) return (metatype < op.getMetatype()) ? -1 : 1;
|
||||
int4 res = Datatype::compareDependency(op);
|
||||
if (res != 0) return res;
|
||||
// Both must be pointers
|
||||
tp = (TypePointer *) &op;
|
||||
TypePointer *tp = (TypePointer *) &op;
|
||||
if (wordsize != tp->wordsize) return (wordsize < tp->wordsize) ? -1 : 1;
|
||||
if (ptrto == tp->ptrto) return 0;
|
||||
return (ptrto < tp->ptrto) ? -1 : 1; // Compare the absolute pointers
|
||||
|
@ -636,27 +641,23 @@ void TypeArray::printRaw(ostream &s) const
|
|||
int4 TypeArray::compare(const Datatype &op,int4 level) const
|
||||
|
||||
{
|
||||
TypeArray *ta;
|
||||
|
||||
if (size != op.getSize()) return (op.getSize()-size);
|
||||
if (metatype != op.getMetatype()) return (metatype < op.getMetatype()) ? -1 : 1;
|
||||
int4 res = Datatype::compare(op,level);
|
||||
if (res != 0) return res;
|
||||
level -= 1;
|
||||
if (level < 0) {
|
||||
if (id == op.getId()) return 0;
|
||||
return (id < op.getId()) ? -1 : 1;
|
||||
}
|
||||
ta = (TypeArray *) &op; // Both must be arrays
|
||||
TypeArray *ta = (TypeArray *) &op; // Both must be arrays
|
||||
return arrayof->compare(*ta->arrayof,level); // Compare array elements
|
||||
}
|
||||
|
||||
int4 TypeArray::compareDependency(const Datatype &op) const
|
||||
|
||||
{
|
||||
TypeArray *ta;
|
||||
|
||||
if (size != op.getSize()) return (op.getSize()-size);
|
||||
if (metatype != op.getMetatype()) return (metatype < op.getMetatype()) ? -1 : 1;
|
||||
ta = (TypeArray *) &op; // Both must be arrays
|
||||
int4 res = Datatype::compareDependency(op);
|
||||
if (res != 0) return res;
|
||||
TypeArray *ta = (TypeArray *) &op; // Both must be arrays
|
||||
if (arrayof == ta->arrayof) return 0;
|
||||
return (arrayof < ta->arrayof) ? -1 : 1;
|
||||
}
|
||||
|
@ -886,6 +887,7 @@ void TypeEnum::restoreXml(const Element *el,TypeFactory &typegrp)
|
|||
|
||||
{
|
||||
restoreXmlBasic(el);
|
||||
submeta = (metatype == TYPE_INT) ? SUB_INT_ENUM : SUB_UINT_ENUM;
|
||||
const List &list(el->getChildren());
|
||||
List::const_iterator iter;
|
||||
map<uintb,string> nmap;
|
||||
|
@ -1067,9 +1069,8 @@ Datatype *TypeStruct::nearestArrayedComponentForward(uintb off,uintb *newoff,int
|
|||
|
||||
int4 TypeStruct::compare(const Datatype &op,int4 level) const
|
||||
{
|
||||
if (size != op.getSize()) return (op.getSize()-size);
|
||||
if (metatype != op.getMetatype()) return (metatype < op.getMetatype()) ? -1 : 1;
|
||||
|
||||
int4 res = Datatype::compare(op,level);
|
||||
if (res != 0) return res;
|
||||
const TypeStruct *ts = (const TypeStruct *)&op;
|
||||
vector<TypeField>::const_iterator iter1,iter2;
|
||||
|
||||
|
@ -1109,9 +1110,8 @@ int4 TypeStruct::compare(const Datatype &op,int4 level) const
|
|||
int4 TypeStruct::compareDependency(const Datatype &op) const
|
||||
|
||||
{
|
||||
if (size != op.getSize()) return (op.getSize()-size);
|
||||
if (metatype != op.getMetatype()) return (metatype < op.getMetatype()) ? -1 : 1;
|
||||
|
||||
int4 res = Datatype::compareDependency(op);
|
||||
if (res != 0) return res;
|
||||
const TypeStruct *ts = (const TypeStruct *)&op;
|
||||
vector<TypeField>::const_iterator iter1,iter2;
|
||||
|
||||
|
@ -1269,9 +1269,6 @@ void TypeCode::setProperties(bool isConstructor,bool isDestructor)
|
|||
int4 TypeCode::compareBasic(const TypeCode *op) const
|
||||
|
||||
{
|
||||
if (size != op->getSize()) return (op->getSize() < size) ? -1 : 1;
|
||||
if (metatype != op->getMetatype()) return (metatype < op->getMetatype()) ? -1 : 1;
|
||||
|
||||
if (proto == (FuncProto *)0) {
|
||||
if (op->proto == (FuncProto *)0) return 0;
|
||||
return 1;
|
||||
|
@ -1312,8 +1309,10 @@ Datatype *TypeCode::getSubType(uintb off,uintb *newoff) const
|
|||
int4 TypeCode::compare(const Datatype &op,int4 level) const
|
||||
|
||||
{
|
||||
int4 res = Datatype::compare(op,level);
|
||||
if (res != 0) return res;
|
||||
const TypeCode *tc = (const TypeCode *)&op;
|
||||
int4 res = compareBasic(tc);
|
||||
res = compareBasic(tc);
|
||||
if (res != 2) return res;
|
||||
|
||||
level -= 1;
|
||||
|
@ -1342,8 +1341,10 @@ int4 TypeCode::compare(const Datatype &op,int4 level) const
|
|||
int4 TypeCode::compareDependency(const Datatype &op) const
|
||||
|
||||
{
|
||||
int4 res = Datatype::compareDependency(op);
|
||||
if (res != 0) return res;
|
||||
const TypeCode *tc = (const TypeCode *)&op;
|
||||
int4 res = compareBasic(tc);
|
||||
res = compareBasic(tc);
|
||||
if (res != 2) return res;
|
||||
|
||||
int4 nump = proto->numParams();
|
||||
|
@ -1518,8 +1519,8 @@ int4 TypeSpacebase::compare(const Datatype &op,int4 level) const
|
|||
int4 TypeSpacebase::compareDependency(const Datatype &op) const
|
||||
|
||||
{
|
||||
if (size != op.getSize()) return (op.getSize()-size);
|
||||
if (metatype != op.getMetatype()) return (metatype < op.getMetatype()) ? -1 : 1;
|
||||
int4 res = Datatype::compareDependency(op);
|
||||
if (res != 0) return res;
|
||||
TypeSpacebase *tsb = (TypeSpacebase *) &op;
|
||||
if (spaceid != tsb->spaceid) return (spaceid < tsb->spaceid) ? -1:1;
|
||||
if (localframe.isInvalid()) return 0; // Global space base
|
||||
|
|
|
@ -45,6 +45,26 @@ enum type_metatype {
|
|||
TYPE_STRUCT = 0 ///< Structure data-type, made up of component datatypes
|
||||
};
|
||||
|
||||
enum sub_metatype {
|
||||
SUB_VOID = 16, ///< Compare as a TYPE_VOID
|
||||
SUB_SPACEBASE = 15, ///< Compare as a TYPE_SPACEBASE
|
||||
SUB_UNKNOWN = 14, ///< Compare as a TYPE_UNKNOWN
|
||||
SUB_INT_CHAR = 13, ///< Signed 1-byte character, sub-type of TYPE_INT
|
||||
SUB_UINT_CHAR = 12, ///< Unsigned 1-byte character, sub-type of TYPE_UINT
|
||||
SUB_INT_PLAIN = 11, ///< Compare as a plain TYPE_INT
|
||||
SUB_UINT_PLAIN = 10, ///< Compare as a plain TYPE_UINT
|
||||
SUB_INT_ENUM = 9, ///< Signed enum, sub-type of TYPE_INT
|
||||
SUB_UINT_ENUM = 8, ///< Unsigned enum, sub-type of TYPE_UINT
|
||||
SUB_INT_UNICODE = 7, ///< Signed wide character, sub-type of TYPE_INT
|
||||
SUB_UINT_UNICODE = 6, ///< Unsigned wide character, sub-type of TYPE_UINT
|
||||
SUB_BOOL = 5, ///< Compare as TYPE_BOOL
|
||||
SUB_CODE = 4, ///< Compare as TYPE_CODE
|
||||
SUB_FLOAT = 3, ///< Compare as TYPE_FLOAT
|
||||
|
||||
SUB_PTR = 2, ///< Compare as TYPE_PTR
|
||||
SUB_ARRAY = 1, ///< Compare as TYPE_ARRAY
|
||||
SUB_STRUCT = 0 ///< Compare as TYPE_STRUCT
|
||||
};
|
||||
/// Convert type \b meta-type to name
|
||||
extern void metatype2string(type_metatype metatype,string &res);
|
||||
|
||||
|
@ -61,6 +81,7 @@ struct DatatypeCompare;
|
|||
/// Used for symbols, function prototypes, type propagation etc.
|
||||
class Datatype {
|
||||
protected:
|
||||
static sub_metatype base2sub[11];
|
||||
/// Boolean properties of datatypes
|
||||
enum {
|
||||
coretype = 1, ///< This is a basic type which will never be redefined
|
||||
|
@ -82,6 +103,7 @@ protected:
|
|||
int4 size; ///< Size (of variable holding a value of this type)
|
||||
string name; ///< Name of type
|
||||
type_metatype metatype; ///< Meta-type - type disregarding size
|
||||
sub_metatype submeta; ///< Sub-type of of the meta-type, for comparisons
|
||||
uint4 flags; ///< Boolean properties of the type
|
||||
uint8 id; ///< A unique id for the type (or 0 if an id is not assigned)
|
||||
Datatype *typedefImm; ///< The immediate data-type being typedefed by \e this
|
||||
|
@ -94,11 +116,12 @@ protected:
|
|||
static uint8 hashSize(uint8 id,int4 size); ///< Reversibly hash size into id
|
||||
public:
|
||||
/// Construct the base data-type copying low-level properties of another
|
||||
Datatype(const Datatype &op) { size = op.size; name=op.name; metatype=op.metatype; flags=op.flags; id=op.id; typedefImm=op.typedefImm; }
|
||||
Datatype(const Datatype &op) { size = op.size; name=op.name; metatype=op.metatype; submeta=op.submeta; flags=op.flags;
|
||||
id=op.id; typedefImm=op.typedefImm; }
|
||||
/// Construct the base data-type providing size and meta-type
|
||||
Datatype(int4 s,type_metatype m) { size=s; metatype=m; flags=0; id=0; typedefImm=(Datatype *)0; }
|
||||
Datatype(int4 s,type_metatype m) { size=s; metatype=m; submeta=base2sub[m]; flags=0; id=0; typedefImm=(Datatype *)0; }
|
||||
/// Construct the base data-type providing size, meta-type, and name
|
||||
Datatype(int4 s,type_metatype m,const string &n) { name=n; size=s; metatype=m; flags=0; id=0; typedefImm=(Datatype *)0; }
|
||||
Datatype(int4 s,type_metatype m,const string &n) { name=n; size=s; metatype=m; submeta=base2sub[m]; flags=0; id=0; typedefImm=(Datatype *)0; }
|
||||
virtual ~Datatype(void) {} ///< Destructor
|
||||
bool isCoreType(void) const { return ((flags&coretype)!=0); } ///< Is this a core data-type
|
||||
bool isCharPrint(void) const { return ((flags&(chartype|utf16|utf32|opaque_string))!=0); } ///< Does this print as a 'char'
|
||||
|
@ -186,11 +209,12 @@ public:
|
|||
class TypeChar : public TypeBase {
|
||||
protected:
|
||||
friend class TypeFactory;
|
||||
virtual void restoreXml(const Element *el,TypeFactory &typegrp);
|
||||
public:
|
||||
/// Construct TypeChar copying properties from another data-type
|
||||
TypeChar(const TypeChar &op) : TypeBase(op) { flags |= Datatype::chartype; }
|
||||
/// Construct a char (always 1-byte) given a name
|
||||
TypeChar(const string &n) : TypeBase(1,TYPE_INT,n) { flags |= Datatype::chartype; }
|
||||
TypeChar(const string &n) : TypeBase(1,TYPE_INT,n) { flags |= Datatype::chartype; submeta = SUB_INT_CHAR; }
|
||||
virtual Datatype *clone(void) const { return new TypeChar(*this); }
|
||||
virtual void saveXml(ostream &s) const;
|
||||
};
|
||||
|
@ -298,9 +322,11 @@ public:
|
|||
/// Construct from another TypeEnum
|
||||
TypeEnum(const TypeEnum &op);
|
||||
/// Construct from a size and meta-type (TYPE_INT or TYPE_UINT)
|
||||
TypeEnum(int4 s,type_metatype m) : TypeBase(s,m) { flags |= enumtype; }
|
||||
TypeEnum(int4 s,type_metatype m) : TypeBase(s,m) {
|
||||
flags |= enumtype; submeta = (m==TYPE_INT) ? SUB_INT_ENUM : SUB_UINT_ENUM; }
|
||||
/// Construct from a size, meta-type, and name
|
||||
TypeEnum(int4 s,type_metatype m,const string &nm) : TypeBase(s,m,nm) { flags |= enumtype; }
|
||||
TypeEnum(int4 s,type_metatype m,const string &nm) : TypeBase(s,m,nm) {
|
||||
flags |= enumtype; submeta = (m==TYPE_INT) ? SUB_INT_ENUM : SUB_UINT_ENUM; }
|
||||
map<uintb,string>::const_iterator beginEnum(void) const { return namemap.begin(); } ///< Beginning of name map
|
||||
map<uintb,string>::const_iterator endEnum(void) const { return namemap.end(); } ///< End of name map
|
||||
bool getMatches(uintb val,vector<string> &matchname) const; ///< Recover the named representation
|
||||
|
|
|
@ -1714,6 +1714,8 @@ Datatype *TypeOpPtrsub::getOutputToken(const PcodeOp *op,CastStrategy *castStrat
|
|||
Datatype *rettype = ptype->downChain(offset,false,*tlst);
|
||||
if ((offset==0)&&(rettype != (Datatype *)0))
|
||||
return rettype;
|
||||
rettype = tlst->getBase(1, TYPE_UNKNOWN);
|
||||
return tlst->getTypePointer(op->getOut()->getSize(), rettype, ptype->getWordSize());
|
||||
}
|
||||
return TypeOp::getOutputToken(op,castStrategy);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue