New data-type ordering implementation

This commit is contained in:
caheckman 2021-10-05 16:33:49 -04:00
parent f9463e600d
commit 60dbaa0559
4 changed files with 81 additions and 49 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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);
}