mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
This commit is contained in:
parent
8b2ea61e27
commit
8aed810d4a
10 changed files with 259 additions and 124 deletions
|
@ -231,6 +231,10 @@ Datatype *CastStrategyC::castStandard(Datatype *reqtype,Datatype *curtype,
|
||||||
care_uint_int = true;
|
care_uint_int = true;
|
||||||
isptr = true;
|
isptr = true;
|
||||||
}
|
}
|
||||||
|
while(reqbase->getTypedef() != (Datatype *)0)
|
||||||
|
reqbase = reqbase->getTypedef();
|
||||||
|
while(curbase->getTypedef() != (Datatype *)0)
|
||||||
|
curbase = curbase->getTypedef();
|
||||||
if (curbase == reqbase) return (Datatype *)0; // Different typedefs could point to the same type
|
if (curbase == reqbase) return (Datatype *)0; // Different typedefs could point to the same type
|
||||||
if ((reqbase->getMetatype()==TYPE_VOID)||(curtype->getMetatype()==TYPE_VOID))
|
if ((reqbase->getMetatype()==TYPE_VOID)||(curtype->getMetatype()==TYPE_VOID))
|
||||||
return (Datatype *)0; // Don't cast from or to VOID
|
return (Datatype *)0; // Don't cast from or to VOID
|
||||||
|
|
|
@ -311,12 +311,11 @@ void Datatype::saveXmlRef(ostream &s) const
|
||||||
s << "<typeref";
|
s << "<typeref";
|
||||||
a_v(s,"name",name);
|
a_v(s,"name",name);
|
||||||
if (isVariableLength()) { // For a type with a "variable length" base
|
if (isVariableLength()) { // For a type with a "variable length" base
|
||||||
uintb origId = hashSize(id, size); // Emit the size independent version of the id
|
a_v_u(s,"id",hashSize(id,size)); // Emit the size independent version of the id
|
||||||
s << " id=\"0x" << hex << origId << '\"';
|
a_v_i(s,"size",size); // but also emit size of this instance
|
||||||
s << " size=\"" << dec << size << '\"'; // but also emit size of this instance
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
s << " id=\"0x" << hex << id << '\"';
|
a_v_u(s,"id",id);
|
||||||
}
|
}
|
||||||
s << "/>";
|
s << "/>";
|
||||||
}
|
}
|
||||||
|
@ -324,6 +323,21 @@ void Datatype::saveXmlRef(ostream &s) const
|
||||||
saveXml(s);
|
saveXml(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called only if the \b typedefImm field is non-null. Write the data-type to the
|
||||||
|
/// stream as a simple \<typedef> tag including only the names and ids of \b this and
|
||||||
|
/// the data-type it typedefs.
|
||||||
|
/// \param s is the output stream
|
||||||
|
void Datatype::saveXmlTypedef(ostream &s) const
|
||||||
|
|
||||||
|
{
|
||||||
|
s << "<def";
|
||||||
|
a_v(s,"name",name);
|
||||||
|
a_v_u(s,"id",id);
|
||||||
|
s << ">";
|
||||||
|
typedefImm->saveXmlRef(s);
|
||||||
|
s << "</def>";
|
||||||
|
}
|
||||||
|
|
||||||
/// A CPUI_PTRSUB must act on a pointer data-type where the given offset addresses a component.
|
/// A CPUI_PTRSUB must act on a pointer data-type where the given offset addresses a component.
|
||||||
/// Perform this check.
|
/// Perform this check.
|
||||||
/// \param offset is the given offset
|
/// \param offset is the given offset
|
||||||
|
@ -443,6 +457,10 @@ uint8 Datatype::hashSize(uint8 id,int4 size)
|
||||||
void TypeChar::saveXml(ostream &s) const
|
void TypeChar::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
a_v_b(s,"char",true);
|
a_v_b(s,"char",true);
|
||||||
|
@ -479,6 +497,10 @@ TypeUnicode::TypeUnicode(const string &nm,int4 sz,type_metatype m)
|
||||||
void TypeUnicode::saveXml(ostream &s) const
|
void TypeUnicode::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
a_v_b(s,"utf",true);
|
a_v_b(s,"utf",true);
|
||||||
|
@ -488,6 +510,10 @@ void TypeUnicode::saveXml(ostream &s) const
|
||||||
void TypeVoid::saveXml(ostream &s) const
|
void TypeVoid::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<void/>";
|
s << "<void/>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,6 +559,10 @@ int4 TypePointer::compareDependency(const Datatype &op) const
|
||||||
void TypePointer::saveXml(ostream &s) const
|
void TypePointer::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
if (wordsize != 1)
|
if (wordsize != 1)
|
||||||
|
@ -660,6 +690,10 @@ Datatype *TypeArray::getSubEntry(int4 off,int4 sz,int4 *newoff,int4 *el) const
|
||||||
void TypeArray::saveXml(ostream &s) const
|
void TypeArray::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
a_v_i(s,"arraysize",arraysize);
|
a_v_i(s,"arraysize",arraysize);
|
||||||
|
@ -830,6 +864,10 @@ int4 TypeEnum::compareDependency(const Datatype &op) const
|
||||||
void TypeEnum::saveXml(ostream &s) const
|
void TypeEnum::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
a_v(s,"enum","true");
|
a_v(s,"enum","true");
|
||||||
|
@ -1099,6 +1137,10 @@ int4 TypeStruct::compareDependency(const Datatype &op) const
|
||||||
void TypeStruct::saveXml(ostream &s) const
|
void TypeStruct::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
s << ">\n";
|
s << ">\n";
|
||||||
|
@ -1326,6 +1368,10 @@ int4 TypeCode::compareDependency(const Datatype &op) const
|
||||||
void TypeCode::saveXml(ostream &s) const
|
void TypeCode::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
s << ">\n";
|
s << ">\n";
|
||||||
|
@ -1500,6 +1546,10 @@ Address TypeSpacebase::getAddress(uintb off,int4 sz,const Address &point) const
|
||||||
void TypeSpacebase::saveXml(ostream &s) const
|
void TypeSpacebase::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (typedefImm != (Datatype *)0) {
|
||||||
|
saveXmlTypedef(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
s << "<type";
|
s << "<type";
|
||||||
saveXmlBasic(s);
|
saveXmlBasic(s);
|
||||||
a_v(s,"space",spaceid->getName());
|
a_v(s,"space",spaceid->getName());
|
||||||
|
@ -1709,7 +1759,7 @@ Datatype *TypeFactory::findByIdLocal(const string &n,uint8 id) const
|
||||||
/// Derived classes may search outside this container.
|
/// Derived classes may search outside this container.
|
||||||
/// \param n is the name of the data-type
|
/// \param n is the name of the data-type
|
||||||
/// \param id is the type id of the data-type
|
/// \param id is the type id of the data-type
|
||||||
/// \param sz is the given distinguishign size if non-zero
|
/// \param sz is the given distinguishing size if non-zero
|
||||||
/// \return the matching Datatype object
|
/// \return the matching Datatype object
|
||||||
Datatype *TypeFactory::findById(const string &n,uint8 id,int4 sz)
|
Datatype *TypeFactory::findById(const string &n,uint8 id,int4 sz)
|
||||||
|
|
||||||
|
@ -1745,6 +1795,26 @@ Datatype *TypeFactory::findNoName(Datatype &ct)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Internal method for finally inserting a new Datatype pointer
|
||||||
|
/// \param newtype is the new pointer
|
||||||
|
void TypeFactory::insert(Datatype *newtype)
|
||||||
|
|
||||||
|
{
|
||||||
|
pair<DatatypeSet::iterator,bool> insres = tree.insert(newtype);
|
||||||
|
if (!insres.second) {
|
||||||
|
ostringstream s;
|
||||||
|
s << "Shared type id: " << hex << newtype->getId() << endl;
|
||||||
|
s << " ";
|
||||||
|
newtype->printRaw(s);
|
||||||
|
s << " : ";
|
||||||
|
(*insres.first)->printRaw(s);
|
||||||
|
delete newtype;
|
||||||
|
throw LowlevelError(s.str());
|
||||||
|
}
|
||||||
|
if (newtype->id!=0)
|
||||||
|
nametree.insert(newtype);
|
||||||
|
}
|
||||||
|
|
||||||
/// Use quickest method (name or id is possible) to locate the matching data-type.
|
/// Use quickest method (name or id is possible) to locate the matching data-type.
|
||||||
/// If its not currently in \b this container, clone the data-type and add it to the container.
|
/// If its not currently in \b this container, clone the data-type and add it to the container.
|
||||||
/// \param ct is the data-type to match
|
/// \param ct is the data-type to match
|
||||||
|
@ -1770,18 +1840,7 @@ Datatype *TypeFactory::findAdd(Datatype &ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype = ct.clone(); // Add the new type to trees
|
newtype = ct.clone(); // Add the new type to trees
|
||||||
pair<DatatypeSet::iterator,bool> insres = tree.insert(newtype);
|
insert(newtype);
|
||||||
if (!insres.second) {
|
|
||||||
ostringstream s;
|
|
||||||
s << "Shared type id: " << hex << newtype->getId() << endl;
|
|
||||||
s << " ";
|
|
||||||
newtype->printRaw(s);
|
|
||||||
s << " : ";
|
|
||||||
(*insres.first)->printRaw(s);
|
|
||||||
throw LowlevelError(s.str());
|
|
||||||
}
|
|
||||||
if (newtype->id!=0)
|
|
||||||
nametree.insert(newtype);
|
|
||||||
return newtype;
|
return newtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1926,6 +1985,8 @@ void TypeFactory::orderRecurse(vector<Datatype *> &deporder,DatatypeSet &mark,
|
||||||
{ // Make sure dependants of ct are in order, then add ct
|
{ // Make sure dependants of ct are in order, then add ct
|
||||||
pair<DatatypeSet::iterator,bool> res = mark.insert(ct);
|
pair<DatatypeSet::iterator,bool> res = mark.insert(ct);
|
||||||
if (!res.second) return; // Already inserted before
|
if (!res.second) return; // Already inserted before
|
||||||
|
if (ct->typedefImm != (Datatype *)0)
|
||||||
|
orderRecurse(deporder,mark,ct->typedefImm);
|
||||||
int4 size = ct->numDepend();
|
int4 size = ct->numDepend();
|
||||||
for(int4 i=0;i<size;++i)
|
for(int4 i=0;i<size;++i)
|
||||||
orderRecurse(deporder,mark,ct->getDepend(i));
|
orderRecurse(deporder,mark,ct->getDepend(i));
|
||||||
|
@ -2074,6 +2135,32 @@ TypeCode *TypeFactory::getTypeCode(const string &nm)
|
||||||
return (TypeCode *) findAdd(tmp);
|
return (TypeCode *) findAdd(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find or create a data-type identical to the given data-type except for its name and id.
|
||||||
|
/// If the name and id already describe an incompatible data-type, an exception is thrown.
|
||||||
|
/// \param ct is the given data-type to clone
|
||||||
|
/// \param name is the new name for the clone
|
||||||
|
/// \param id is the new id for the clone (or 0)
|
||||||
|
/// \return the (found or created) \e typedef data-type
|
||||||
|
Datatype *TypeFactory::getTypedef(Datatype *ct,const string &name,uint8 id)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (id == 0)
|
||||||
|
id = Datatype::hashName(name);
|
||||||
|
Datatype *res = findByIdLocal(name, id);
|
||||||
|
if (res != (Datatype *)0) {
|
||||||
|
if (ct != res->getTypedef())
|
||||||
|
throw LowlevelError("Trying to create typedef of existing type: " + name);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
res = ct->clone(); // Clone everything
|
||||||
|
res->name = name; // But a new name
|
||||||
|
res->id = id; // and new id
|
||||||
|
res->flags &= ~((uint4)Datatype::coretype); // Not a core type
|
||||||
|
res->typedefImm = ct;
|
||||||
|
insert(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/// This creates a pointer to a given data-type. If the given data-type is
|
/// This creates a pointer to a given data-type. If the given data-type is
|
||||||
/// an array, the TYPE_ARRAY property is stripped off, and a pointer to
|
/// an array, the TYPE_ARRAY property is stripped off, and a pointer to
|
||||||
/// the array element data-type is returned.
|
/// the array element data-type is returned.
|
||||||
|
@ -2355,6 +2442,37 @@ void TypeFactory::saveXmlCoreTypes(ostream &s) const
|
||||||
s << "</coretypes>\n";
|
s << "</coretypes>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Scan the new id and name. A subtag references the data-type being typedefed.
|
||||||
|
/// Construct the new data-type based on the referenced data-type but with new name and id.
|
||||||
|
/// \param el is the \<def> element
|
||||||
|
/// \return the constructed typedef data-type
|
||||||
|
Datatype *TypeFactory::restoreTypedef(const Element *el)
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8 id;
|
||||||
|
istringstream s1(el->getAttributeValue("id"));
|
||||||
|
s1.unsetf(ios::dec | ios::hex | ios::oct);
|
||||||
|
s1 >> id;
|
||||||
|
string nm = el->getAttributeValue("name");
|
||||||
|
Datatype *defedType = restoreXmlType( *el->getChildren().begin() );
|
||||||
|
if (defedType->isVariableLength())
|
||||||
|
id = Datatype::hashSize(id, defedType->size);
|
||||||
|
if (defedType->getMetatype() == TYPE_STRUCT) {
|
||||||
|
// Its possible that a typedef of a struct is recursively defined, in which case
|
||||||
|
// an incomplete version may already be in the container
|
||||||
|
TypeStruct *prev = (TypeStruct *)findByIdLocal(nm, id);
|
||||||
|
if (prev != (Datatype *)0) {
|
||||||
|
if (defedType != prev->getTypedef())
|
||||||
|
throw LowlevelError("Trying to create typedef of existing type: " + prev->name);
|
||||||
|
TypeStruct *defedStruct = (TypeStruct *)defedType;
|
||||||
|
if (prev->field.size() != defedStruct->field.size())
|
||||||
|
prev->field = defedStruct->field;
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getTypedef(defedType, nm, id);
|
||||||
|
}
|
||||||
|
|
||||||
/// Restore a Datatype object from an XML \<type> tag. (Don't use for \<typeref> tags)
|
/// Restore a Datatype object from an XML \<type> tag. (Don't use for \<typeref> tags)
|
||||||
/// The new Datatype is added to \b this container
|
/// The new Datatype is added to \b this container
|
||||||
/// \param el is the XML element
|
/// \param el is the XML element
|
||||||
|
@ -2366,9 +2484,12 @@ Datatype *TypeFactory::restoreXmlTypeNoRef(const Element *el,bool forcecore)
|
||||||
string metastring;
|
string metastring;
|
||||||
Datatype *ct;
|
Datatype *ct;
|
||||||
|
|
||||||
if (el->getNumAttributes() == 0) {
|
char c = el->getName()[0];
|
||||||
|
if (c != 't') {
|
||||||
if (el->getName() == "void")
|
if (el->getName() == "void")
|
||||||
return getTypeVoid(); // Automatically a coretype
|
return getTypeVoid(); // Automatically a coretype
|
||||||
|
if (el->getName() == "def")
|
||||||
|
return restoreTypedef(el);
|
||||||
}
|
}
|
||||||
metastring = el->getAttributeValue("metatype");
|
metastring = el->getAttributeValue("metatype");
|
||||||
type_metatype meta = string2metatype(metastring);
|
type_metatype meta = string2metatype(metastring);
|
||||||
|
|
|
@ -84,17 +84,21 @@ protected:
|
||||||
type_metatype metatype; ///< Meta-type - type disregarding size
|
type_metatype metatype; ///< Meta-type - type disregarding size
|
||||||
uint4 flags; ///< Boolean properties of the type
|
uint4 flags; ///< Boolean properties of the type
|
||||||
uint8 id; ///< A unique id for the type (or 0 if an id is not assigned)
|
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
|
||||||
void restoreXmlBasic(const Element *el); ///< Recover basic data-type properties
|
void restoreXmlBasic(const Element *el); ///< Recover basic data-type properties
|
||||||
|
void saveXmlBasic(ostream &s) const; ///< Save basic data-type properties
|
||||||
|
void saveXmlTypedef(ostream &s) const; ///< Write \b this as a \e typedef tag to stream
|
||||||
virtual void restoreXml(const Element *el,TypeFactory &typegrp); ///< Restore data-type from XML
|
virtual void restoreXml(const Element *el,TypeFactory &typegrp); ///< Restore data-type from XML
|
||||||
|
virtual Datatype *clone(void) const=0; ///< Clone the data-type
|
||||||
static uint8 hashName(const string &nm); ///< Produce a data-type id by hashing the type name
|
static uint8 hashName(const string &nm); ///< Produce a data-type id by hashing the type name
|
||||||
static uint8 hashSize(uint8 id,int4 size); ///< Reversibly hash size into id
|
static uint8 hashSize(uint8 id,int4 size); ///< Reversibly hash size into id
|
||||||
public:
|
public:
|
||||||
/// Construct the base data-type copying low-level properties of another
|
/// 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; }
|
Datatype(const Datatype &op) { size = op.size; name=op.name; metatype=op.metatype; flags=op.flags; id=op.id; typedefImm=op.typedefImm; }
|
||||||
/// Construct the base data-type providing size and meta-type
|
/// Construct the base data-type providing size and meta-type
|
||||||
Datatype(int4 s,type_metatype m) { size=s; metatype=m; flags=0; id=0; }
|
Datatype(int4 s,type_metatype m) { size=s; metatype=m; flags=0; id=0; typedefImm=(Datatype *)0; }
|
||||||
/// Construct the base data-type providing size, meta-type, and name
|
/// 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; }
|
Datatype(int4 s,type_metatype m,const string &n) { name=n; size=s; metatype=m; flags=0; id=0; typedefImm=(Datatype *)0; }
|
||||||
virtual ~Datatype(void) {} ///< Destructor
|
virtual ~Datatype(void) {} ///< Destructor
|
||||||
bool isCoreType(void) const { return ((flags&coretype)!=0); } ///< Is this a core data-type
|
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'
|
bool isCharPrint(void) const { return ((flags&(chartype|utf16|utf32|opaque_string))!=0); } ///< Does this print as a 'char'
|
||||||
|
@ -111,6 +115,7 @@ public:
|
||||||
uint8 getId(void) const { return id; } ///< Get the type id
|
uint8 getId(void) const { return id; } ///< Get the type id
|
||||||
int4 getSize(void) const { return size; } ///< Get the type size
|
int4 getSize(void) const { return size; } ///< Get the type size
|
||||||
const string &getName(void) const { return name; } ///< Get the type name
|
const string &getName(void) const { return name; } ///< Get the type name
|
||||||
|
Datatype *getTypedef(void) const { return typedefImm; } ///< Get the data-type immediately typedefed by \e this (or null)
|
||||||
virtual void printRaw(ostream &s) const; ///< Print a description of the type to stream
|
virtual void printRaw(ostream &s) const; ///< Print a description of the type to stream
|
||||||
virtual Datatype *getSubType(uintb off,uintb *newoff) const; ///< Recover component data-type one-level down
|
virtual Datatype *getSubType(uintb off,uintb *newoff) const; ///< Recover component data-type one-level down
|
||||||
virtual Datatype *nearestArrayedComponentForward(uintb off,uintb *newoff,int4 *elSize) const;
|
virtual Datatype *nearestArrayedComponentForward(uintb off,uintb *newoff,int4 *elSize) const;
|
||||||
|
@ -120,11 +125,9 @@ public:
|
||||||
virtual void printNameBase(ostream &s) const { if (!name.empty()) s<<name[0]; } ///< Print name as short prefix
|
virtual void printNameBase(ostream &s) const { if (!name.empty()) s<<name[0]; } ///< Print name as short prefix
|
||||||
virtual int4 compare(const Datatype &op,int4 level) const; ///< Order types for propagation
|
virtual int4 compare(const Datatype &op,int4 level) const; ///< Order types for propagation
|
||||||
virtual int4 compareDependency(const Datatype &op) const; ///< Compare for storage in tree structure
|
virtual int4 compareDependency(const Datatype &op) const; ///< Compare for storage in tree structure
|
||||||
virtual Datatype *clone(void) const=0; ///< Clone the data-type
|
|
||||||
virtual void saveXml(ostream &s) const; ///< Serialize the data-type to XML
|
virtual void saveXml(ostream &s) const; ///< Serialize the data-type to XML
|
||||||
int4 typeOrder(const Datatype &op) const { if (this==&op) return 0; return compare(op,10); } ///< Order this with -op- datatype
|
int4 typeOrder(const Datatype &op) const { if (this==&op) return 0; return compare(op,10); } ///< Order this with -op- datatype
|
||||||
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 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
|
bool isPtrsubMatching(uintb offset) const; ///< Is this data-type suitable as input to a CPUI_PTRSUB op
|
||||||
};
|
};
|
||||||
|
@ -406,8 +409,10 @@ class TypeFactory {
|
||||||
Datatype *typecache16; ///< Specially cached 16-byte float type
|
Datatype *typecache16; ///< Specially cached 16-byte float type
|
||||||
Datatype *type_nochar; ///< Same dimensions as char but acts and displays as an INT
|
Datatype *type_nochar; ///< Same dimensions as char but acts and displays as an INT
|
||||||
Datatype *findNoName(Datatype &ct); ///< Find data-type (in this container) by function
|
Datatype *findNoName(Datatype &ct); ///< Find data-type (in this container) by function
|
||||||
|
void insert(Datatype *newtype); ///< Insert pointer into the cross-reference sets
|
||||||
Datatype *findAdd(Datatype &ct); ///< Find data-type in this container or add it
|
Datatype *findAdd(Datatype &ct); ///< Find data-type in this container or add it
|
||||||
void orderRecurse(vector<Datatype *> &deporder,DatatypeSet &mark,Datatype *ct) const; ///< Write out dependency list
|
void orderRecurse(vector<Datatype *> &deporder,DatatypeSet &mark,Datatype *ct) const; ///< Write out dependency list
|
||||||
|
Datatype *restoreTypedef(const Element *el); ///< Restore a \<def> XML tag describing a typedef
|
||||||
Datatype *restoreXmlTypeNoRef(const Element *el,bool forcecore); ///< Restore from an XML tag
|
Datatype *restoreXmlTypeNoRef(const Element *el,bool forcecore); ///< Restore from an XML tag
|
||||||
void clearCache(void); ///< Clear the common type cache
|
void clearCache(void); ///< Clear the common type cache
|
||||||
TypeChar *getTypeChar(const string &n); ///< Create a default "char" type
|
TypeChar *getTypeChar(const string &n); ///< Create a default "char" type
|
||||||
|
@ -452,6 +457,7 @@ public:
|
||||||
TypeCode *getTypeCode(ProtoModel *model,Datatype *outtype,
|
TypeCode *getTypeCode(ProtoModel *model,Datatype *outtype,
|
||||||
const vector<Datatype *> &intypes,
|
const vector<Datatype *> &intypes,
|
||||||
bool dotdotdot); ///< Create a "function" datatype
|
bool dotdotdot); ///< Create a "function" datatype
|
||||||
|
Datatype *getTypedef(Datatype *ct,const string &name,uint8 id); ///< Create a new \e typedef data-type
|
||||||
void destroyType(Datatype *ct); ///< Remove a data-type from \b this
|
void destroyType(Datatype *ct); ///< Remove a data-type from \b this
|
||||||
Datatype *concretize(Datatype *ct); ///< Convert given data-type to concrete form
|
Datatype *concretize(Datatype *ct); ///< Convert given data-type to concrete form
|
||||||
void dependentOrder(vector<Datatype *> &deporder) const; ///< Place all data-types in dependency order
|
void dependentOrder(vector<Datatype *> &deporder) const; ///< Place all data-types in dependency order
|
||||||
|
|
|
@ -817,7 +817,8 @@ public class DecompileCallback {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StringBuilder resBuf = dtmanage.buildType(type, 0);
|
StringBuilder resBuf = new StringBuilder();
|
||||||
|
dtmanage.buildType(resBuf, type, 0);
|
||||||
resBuf.append("\n"); // Make into official XML document
|
resBuf.append("\n"); // Make into official XML document
|
||||||
String res = resBuf.toString();
|
String res = resBuf.toString();
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
|
|
|
@ -347,9 +347,11 @@ public class DecompileDebug {
|
||||||
//Next, use the dependency stack to output types.
|
//Next, use the dependency stack to output types.
|
||||||
for (DataType dataType : TypeOrderer.getDependencyList()) {
|
for (DataType dataType : TypeOrderer.getDependencyList()) {
|
||||||
if (!(dataType instanceof BuiltIn)) {
|
if (!(dataType instanceof BuiltIn)) {
|
||||||
debugStream.write(
|
StringBuilder typeBuf = new StringBuilder();
|
||||||
(dtmanage.buildType(dataType, dataType.getLength()) + "\n").toString()
|
|
||||||
.getBytes());
|
dtmanage.buildType(typeBuf, dataType, dataType.getLength());
|
||||||
|
typeBuf.append('\n');
|
||||||
|
debugStream.write(typeBuf.toString().getBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugStream.write("</typegrp>\n".getBytes());
|
debugStream.write("</typegrp>\n".getBytes());
|
||||||
|
|
|
@ -142,7 +142,7 @@ public class DataTypeDependencyOrderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns two lists:
|
* This method returns two lists:
|
||||||
* 1) is the set of structs and typedefs to structs. Intended for outputting zero-sized definitions.
|
* 1) is the set of structs. Intended for outputting zero-sized definitions.
|
||||||
* 2) is the acyclic dependency list (broken at structs and pointers to structs)
|
* 2) is the acyclic dependency list (broken at structs and pointers to structs)
|
||||||
* This works (and the dependency graph is able to be broken of cycles) because
|
* This works (and the dependency graph is able to be broken of cycles) because
|
||||||
* structures can be given zero size to start with and then later updated with full size.
|
* structures can be given zero size to start with and then later updated with full size.
|
||||||
|
@ -156,10 +156,10 @@ public class DataTypeDependencyOrderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the ArrayList of structs and typedefs
|
* This method returns the ArrayList of structs
|
||||||
* to structs found in the input list, intended
|
* to structs found in the input list, intended
|
||||||
* to be used initially as zero-sized structures.
|
* to be used initially as zero-sized structures.
|
||||||
* @return An arrayList of structs and typedefs of structs
|
* @return An arrayList of structs
|
||||||
*/
|
*/
|
||||||
public ArrayList<DataType> getStructList() {
|
public ArrayList<DataType> getStructList() {
|
||||||
if (processed == false) {
|
if (processed == false) {
|
||||||
|
@ -316,9 +316,8 @@ public class DataTypeDependencyOrderer {
|
||||||
//Msg.debug(this, "ORDERED_LIST_SIZE: " + orderedDependentsList.size() + " -- TYPE: " +
|
//Msg.debug(this, "ORDERED_LIST_SIZE: " + orderedDependentsList.size() + " -- TYPE: " +
|
||||||
// dataType.getName());
|
// dataType.getName());
|
||||||
orderedDependentsList.add(entry.dataType);
|
orderedDependentsList.add(entry.dataType);
|
||||||
//dependency stack of struct or typedef to struct types for which zero-sized structs should first be used. See _____TODO:method
|
//dependency stack of struct for which zero-sized structs should first be used.
|
||||||
if ((entry.dataType instanceof Structure) || ((entry.dataType instanceof TypeDef) &&
|
if (entry.dataType instanceof Structure) {
|
||||||
(((TypeDef) entry.dataType).getBaseDataType() instanceof Structure))) {
|
|
||||||
structList.add(entry.dataType);
|
structList.add(entry.dataType);
|
||||||
}
|
}
|
||||||
removeMyDependentsEdgesToMe(entry);
|
removeMyDependentsEdgesToMe(entry);
|
||||||
|
@ -343,8 +342,7 @@ public class DataTypeDependencyOrderer {
|
||||||
procSet.add(subEntry);
|
procSet.add(subEntry);
|
||||||
}
|
}
|
||||||
if (entry.dataType instanceof Pointer) { //avoid cycles with structures/composites
|
if (entry.dataType instanceof Pointer) { //avoid cycles with structures/composites
|
||||||
if ((subType instanceof Structure) || (subType instanceof TypeDef) &&
|
if (subType instanceof Structure) {
|
||||||
(((TypeDef) subType).getBaseDataType() instanceof Structure)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ public abstract class ConstantPool {
|
||||||
SpecXmlUtils.xmlEscape(buf, token);
|
SpecXmlUtils.xmlEscape(buf, token);
|
||||||
buf.append("</token>\n");
|
buf.append("</token>\n");
|
||||||
}
|
}
|
||||||
buf.append(dtmanage.buildTypeRef(type, type.getLength()));
|
dtmanage.buildTypeRef(buf, type, type.getLength());
|
||||||
buf.append("</cpoolrec>\n");
|
buf.append("</cpoolrec>\n");
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,7 +378,7 @@ public class FunctionPrototype {
|
||||||
res.append("<addr/>\n "); // Don't specify where return type is stored
|
res.append("<addr/>\n "); // Don't specify where return type is stored
|
||||||
}
|
}
|
||||||
|
|
||||||
res.append(dtmanage.buildTypeRef(returntype, sz));
|
dtmanage.buildTypeRef(res, returntype, sz);
|
||||||
res.append(" </returnsym>\n");
|
res.append(" </returnsym>\n");
|
||||||
if (injectname != null) {
|
if (injectname != null) {
|
||||||
res.append("<inject>");
|
res.append("<inject>");
|
||||||
|
@ -404,7 +404,7 @@ public class FunctionPrototype {
|
||||||
if (sz < 0) {
|
if (sz < 0) {
|
||||||
sz = 1;
|
sz = 1;
|
||||||
}
|
}
|
||||||
res.append(dtmanage.buildTypeRef(dt, sz));
|
dtmanage.buildTypeRef(res, dt, sz);
|
||||||
res.append("</param>\n");
|
res.append("</param>\n");
|
||||||
}
|
}
|
||||||
res.append("</internallist>\n");
|
res.append("</internallist>\n");
|
||||||
|
|
|
@ -401,7 +401,7 @@ public class HighSymbol {
|
||||||
buf.append("<symbol");
|
buf.append("<symbol");
|
||||||
saveXMLHeader(buf);
|
saveXMLHeader(buf);
|
||||||
buf.append(">\n");
|
buf.append(">\n");
|
||||||
buf.append(dtmanage.buildTypeRef(type, getSize()));
|
dtmanage.buildTypeRef(buf, type, getSize());
|
||||||
buf.append("</symbol>\n");
|
buf.append("</symbol>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ public class PcodeDataTypeManager {
|
||||||
* element
|
* element
|
||||||
*/
|
*/
|
||||||
public DataType readXMLDataType(XmlPullParser parser) throws PcodeXMLException {
|
public DataType readXMLDataType(XmlPullParser parser) throws PcodeXMLException {
|
||||||
XmlElement el = parser.start("type", "void", "typeref");
|
XmlElement el = parser.start("type", "void", "typeref", "def");
|
||||||
try {
|
try {
|
||||||
if (el == null) {
|
if (el == null) {
|
||||||
throw new PcodeXMLException("Bad <type> tag");
|
throw new PcodeXMLException("Bad <type> tag");
|
||||||
|
@ -176,6 +176,12 @@ public class PcodeDataTypeManager {
|
||||||
if (el.getName().equals("typeref")) {
|
if (el.getName().equals("typeref")) {
|
||||||
return findBaseType(el.getAttribute("name"), el.getAttribute("id"));
|
return findBaseType(el.getAttribute("name"), el.getAttribute("id"));
|
||||||
}
|
}
|
||||||
|
if (el.getName().equals("def")) {
|
||||||
|
String nameStr = el.getAttribute("name");
|
||||||
|
String idStr = el.getAttribute("id");
|
||||||
|
parser.discardSubTree(); // Get rid of unused <typeref>
|
||||||
|
return findBaseType(nameStr, idStr);
|
||||||
|
}
|
||||||
String name = el.getAttribute("name");
|
String name = el.getAttribute("name");
|
||||||
if (name.length() != 0) {
|
if (name.length() != 0) {
|
||||||
return findBaseType(name, el.getAttribute("id"));
|
return findBaseType(name, el.getAttribute("id"));
|
||||||
|
@ -249,25 +255,29 @@ public class PcodeDataTypeManager {
|
||||||
* fully describing the data-type. Where possible a {@code <typeref>} tag is produced, which just gives
|
* fully describing the data-type. Where possible a {@code <typeref>} tag is produced, which just gives
|
||||||
* the name of the data-type, deferring a full description of the data-type. For certain simple or
|
* the name of the data-type, deferring a full description of the data-type. For certain simple or
|
||||||
* nameless data-types, a {@code <type>} tag is emitted giving a full description.
|
* nameless data-types, a {@code <type>} tag is emitted giving a full description.
|
||||||
|
* @param resBuf is the stream to append the tag to
|
||||||
* @param type is the data-type to be converted
|
* @param type is the data-type to be converted
|
||||||
* @param size is the size in bytes of the specific instance of the data-type
|
* @param size is the size in bytes of the specific instance of the data-type
|
||||||
* @return a StringBuilder containing the XML tag
|
|
||||||
*/
|
*/
|
||||||
public StringBuilder buildTypeRef(DataType type, int size) {
|
public void buildTypeRef(StringBuilder resBuf, DataType type, int size) {
|
||||||
if (type != null && type.getDataTypeManager() != progDataTypes) {
|
if (type != null && type.getDataTypeManager() != progDataTypes) {
|
||||||
type = type.clone(progDataTypes);
|
type = type.clone(progDataTypes);
|
||||||
}
|
}
|
||||||
if ((type instanceof VoidDataType) || (type == null)) {
|
if ((type instanceof VoidDataType) || (type == null)) {
|
||||||
return buildType(type, size);
|
buildType(resBuf, type, size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (type instanceof AbstractIntegerDataType) {
|
if (type instanceof AbstractIntegerDataType) {
|
||||||
return buildType(type, size);
|
buildType(resBuf, type, size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (type instanceof Pointer) {
|
if (type instanceof Pointer) {
|
||||||
return buildType(type, size);
|
buildType(resBuf, type, size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (type instanceof Array) {
|
if (type instanceof Array) {
|
||||||
return buildType(type, size);
|
buildType(resBuf, type, size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (type instanceof FunctionDefinition) {
|
if (type instanceof FunctionDefinition) {
|
||||||
long id = progDataTypes.getID(type);
|
long id = progDataTypes.getID(type);
|
||||||
|
@ -275,14 +285,15 @@ public class PcodeDataTypeManager {
|
||||||
// Its possible the FunctionDefinition was built on the fly and is not
|
// Its possible the FunctionDefinition was built on the fly and is not
|
||||||
// a permanent data-type of the program with an ID. In this case, we can't
|
// a permanent data-type of the program with an ID. In this case, we can't
|
||||||
// construct a <typeref> tag but must build a full <type> tag.
|
// construct a <typeref> tag but must build a full <type> tag.
|
||||||
return buildType(type, size);
|
buildType(resBuf, type, size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
size = 1;
|
size = 1;
|
||||||
}
|
}
|
||||||
else if (type.getLength() <= 0) {
|
else if (type.getLength() <= 0) {
|
||||||
return buildType(type, size);
|
buildType(resBuf, type, size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
StringBuilder resBuf = new StringBuilder();
|
|
||||||
resBuf.append("<typeref");
|
resBuf.append("<typeref");
|
||||||
if (type instanceof BuiltIn) {
|
if (type instanceof BuiltIn) {
|
||||||
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name",
|
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name",
|
||||||
|
@ -300,24 +311,28 @@ public class PcodeDataTypeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resBuf.append("/>");
|
resBuf.append("/>");
|
||||||
return resBuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuilder getCharTypeRef(int size) {
|
private void appendCharTypeRef(StringBuilder resBuf, int size) {
|
||||||
if (size == dataOrganization.getCharSize()) {
|
if (size == dataOrganization.getCharSize()) {
|
||||||
return new StringBuilder("<typeref name=\"char\"/>"); // could have size 1 or 2
|
resBuf.append("<typeref name=\"char\"/>"); // could have size 1 or 2
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (size == dataOrganization.getWideCharSize()) {
|
if (size == dataOrganization.getWideCharSize()) {
|
||||||
return new StringBuilder("<typeref name=\"wchar_t\"/>");
|
resBuf.append("<typeref name=\"wchar_t\"/>");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (size == 2) {
|
if (size == 2) {
|
||||||
return new StringBuilder("<typeref name=\"wchar16\"/>");
|
resBuf.append("<typeref name=\"wchar16\"/>");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (size == 4) {
|
if (size == 4) {
|
||||||
return new StringBuilder("<typeref name=\"wchar32\"/>");
|
resBuf.append("<typeref name=\"wchar32\"/>");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
return new StringBuilder("<typeref name=\"byte\"/>");
|
resBuf.append("<typeref name=\"byte\"/>");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Unsupported character size");
|
throw new IllegalArgumentException("Unsupported character size");
|
||||||
}
|
}
|
||||||
|
@ -343,22 +358,10 @@ public class PcodeDataTypeManager {
|
||||||
resBuf.append("</field>\n");
|
resBuf.append("</field>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildTypeInternal(DataType origType, int size) { // Build all of type except name attribute
|
private String buildTypeInternal(StringBuilder resBuf, DataType type, int size) {
|
||||||
DataType type;
|
resBuf.append("<type");
|
||||||
if (origType instanceof TypeDef) {
|
|
||||||
type = ((TypeDef) origType).getBaseDataType();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type = origType;
|
|
||||||
}
|
|
||||||
StringBuilder resBuf = new StringBuilder();
|
|
||||||
if (type instanceof Pointer) {
|
if (type instanceof Pointer) {
|
||||||
if (origType == type) {
|
SpecXmlUtils.encodeStringAttribute(resBuf, "name", "");
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "name", "");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
appendNameIdAttributes(resBuf, origType);
|
|
||||||
}
|
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "ptr");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "ptr");
|
||||||
int ptrLen = type.getLength();
|
int ptrLen = type.getLength();
|
||||||
if (ptrLen <= 0) {
|
if (ptrLen <= 0) {
|
||||||
|
@ -375,54 +378,46 @@ public class PcodeDataTypeManager {
|
||||||
ptrto = ptrto.clone(progDataTypes);
|
ptrto = ptrto.clone(progDataTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder ptrtoTypeRef;
|
|
||||||
if (ptrto == null) {
|
if (ptrto == null) {
|
||||||
ptrtoTypeRef = buildTypeRef(DefaultDataType.dataType, 1);
|
buildTypeRef(resBuf, DefaultDataType.dataType, 1);
|
||||||
}
|
}
|
||||||
else if (ptrto instanceof AbstractStringDataType) {
|
else if (ptrto instanceof AbstractStringDataType) {
|
||||||
if ((ptrto instanceof StringDataType) ||
|
if ((ptrto instanceof StringDataType) ||
|
||||||
(type instanceof TerminatedStringDataType)) { // Convert pointer to string
|
(type instanceof TerminatedStringDataType)) { // Convert pointer to string
|
||||||
ptrtoTypeRef = getCharTypeRef(dataOrganization.getCharSize()); // to pointer to char
|
appendCharTypeRef(resBuf, dataOrganization.getCharSize()); // to pointer to char
|
||||||
}
|
}
|
||||||
else if (ptrto instanceof StringUTF8DataType) { // Convert pointer to string
|
else if (ptrto instanceof StringUTF8DataType) { // Convert pointer to string
|
||||||
// TODO: Need to ensure that UTF8 decoding applies
|
// TODO: Need to ensure that UTF8 decoding applies
|
||||||
ptrtoTypeRef = getCharTypeRef(1); // to pointer to char
|
appendCharTypeRef(resBuf, 1); // to pointer to char
|
||||||
}
|
}
|
||||||
else if ((ptrto instanceof UnicodeDataType) ||
|
else if ((ptrto instanceof UnicodeDataType) ||
|
||||||
(ptrto instanceof TerminatedUnicodeDataType)) {
|
(ptrto instanceof TerminatedUnicodeDataType)) {
|
||||||
ptrtoTypeRef = getCharTypeRef(2);
|
appendCharTypeRef(resBuf, 2);
|
||||||
}
|
}
|
||||||
else if ((ptrto instanceof Unicode32DataType) ||
|
else if ((ptrto instanceof Unicode32DataType) ||
|
||||||
(ptrto instanceof TerminatedUnicode32DataType)) {
|
(ptrto instanceof TerminatedUnicode32DataType)) {
|
||||||
ptrtoTypeRef = getCharTypeRef(4);
|
appendCharTypeRef(resBuf, 4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ptrtoTypeRef = new StringBuilder();
|
resBuf.append("<type");
|
||||||
ptrtoTypeRef.append("<type");
|
appendNameIdAttributes(resBuf, ptrto);
|
||||||
appendNameIdAttributes(ptrtoTypeRef, ptrto);
|
appendOpaqueString(resBuf, ptrto, 16384);
|
||||||
appendOpaqueString(ptrtoTypeRef, ptrto, 16384);
|
resBuf.append("</type>\n");
|
||||||
ptrtoTypeRef.append("</type>\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ptrto instanceof FunctionDefinition) {
|
else if (ptrto instanceof FunctionDefinition) {
|
||||||
// FunctionDefinition may have size of -1, do not translate to undefined
|
// FunctionDefinition may have size of -1, do not translate to undefined
|
||||||
ptrtoTypeRef = buildTypeRef(ptrto, ptrto.getLength());
|
buildTypeRef(resBuf, ptrto, ptrto.getLength());
|
||||||
}
|
}
|
||||||
else if (ptrto.getLength() < 0 && !(ptrto instanceof FunctionDefinition)) {
|
else if (ptrto.getLength() < 0 && !(ptrto instanceof FunctionDefinition)) {
|
||||||
ptrtoTypeRef = buildTypeRef(Undefined1DataType.dataType, 1);
|
buildTypeRef(resBuf, Undefined1DataType.dataType, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ptrtoTypeRef = buildTypeRef(ptrto, ptrto.getLength());
|
buildTypeRef(resBuf, ptrto, ptrto.getLength());
|
||||||
}
|
}
|
||||||
resBuf.append(ptrtoTypeRef);
|
|
||||||
}
|
}
|
||||||
else if (type instanceof Array) {
|
else if (type instanceof Array) {
|
||||||
if (origType == type) {
|
SpecXmlUtils.encodeStringAttribute(resBuf, "name", "");
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "name", "");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
appendNameIdAttributes(resBuf, origType);
|
|
||||||
}
|
|
||||||
int sz = type.getLength();
|
int sz = type.getLength();
|
||||||
if (sz == 0) {
|
if (sz == 0) {
|
||||||
sz = size;
|
sz = size;
|
||||||
|
@ -432,11 +427,10 @@ public class PcodeDataTypeManager {
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize",
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize",
|
||||||
((Array) type).getNumElements());
|
((Array) type).getNumElements());
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
resBuf.append(
|
buildTypeRef(resBuf, ((Array) type).getDataType(), ((Array) type).getElementLength());
|
||||||
buildTypeRef(((Array) type).getDataType(), ((Array) type).getElementLength()));
|
|
||||||
}
|
}
|
||||||
else if (type instanceof Structure) {
|
else if (type instanceof Structure) {
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
// if size is 0, insert an Undefined4 component
|
// if size is 0, insert an Undefined4 component
|
||||||
//
|
//
|
||||||
int sz = type.getLength();
|
int sz = type.getLength();
|
||||||
|
@ -462,13 +456,13 @@ public class PcodeDataTypeManager {
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "offset", comp.getOffset());
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "offset", comp.getOffset());
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
DataType fieldtype = comp.getDataType();
|
DataType fieldtype = comp.getDataType();
|
||||||
resBuf.append(buildTypeRef(fieldtype, comp.getLength()));
|
buildTypeRef(resBuf, fieldtype, comp.getLength());
|
||||||
resBuf.append("</field>\n");
|
resBuf.append("</field>\n");
|
||||||
}
|
}
|
||||||
// TODO: trailing flexible array component not yet supported
|
// TODO: trailing flexible array component not yet supported
|
||||||
}
|
}
|
||||||
else if (type instanceof Enum) {
|
else if (type instanceof Enum) {
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
Enum enumDt = (Enum) type;
|
Enum enumDt = (Enum) type;
|
||||||
long[] keys = enumDt.getValues();
|
long[] keys = enumDt.getValues();
|
||||||
String metatype = "uint";
|
String metatype = "uint";
|
||||||
|
@ -490,7 +484,7 @@ public class PcodeDataTypeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type instanceof CharDataType) {
|
else if (type instanceof CharDataType) {
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
boolean signed = ((CharDataType) type).isSigned();
|
boolean signed = ((CharDataType) type).isSigned();
|
||||||
int sz = type.getLength();
|
int sz = type.getLength();
|
||||||
if (sz <= 0) {
|
if (sz <= 0) {
|
||||||
|
@ -508,7 +502,7 @@ public class PcodeDataTypeManager {
|
||||||
}
|
}
|
||||||
else if (type instanceof WideCharDataType || type instanceof WideChar16DataType ||
|
else if (type instanceof WideCharDataType || type instanceof WideChar16DataType ||
|
||||||
type instanceof WideChar32DataType) {
|
type instanceof WideChar32DataType) {
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "int");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "int");
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", type.getLength());
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", type.getLength());
|
||||||
SpecXmlUtils.encodeBooleanAttribute(resBuf, "utf", true);
|
SpecXmlUtils.encodeBooleanAttribute(resBuf, "utf", true);
|
||||||
|
@ -521,7 +515,7 @@ public class PcodeDataTypeManager {
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size);
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
resBuf.append(getCharTypeRef(dataOrganization.getCharSize()));
|
appendCharTypeRef(resBuf, dataOrganization.getCharSize());
|
||||||
}
|
}
|
||||||
else if (type instanceof StringUTF8DataType) {
|
else if (type instanceof StringUTF8DataType) {
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "name", "");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "name", "");
|
||||||
|
@ -529,7 +523,7 @@ public class PcodeDataTypeManager {
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size);
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
resBuf.append(getCharTypeRef(1)); // TODO: Need to ensure that UTF8 decoding applies
|
appendCharTypeRef(resBuf, 1); // TODO: Need to ensure that UTF8 decoding applies
|
||||||
}
|
}
|
||||||
else if ((type instanceof UnicodeDataType) ||
|
else if ((type instanceof UnicodeDataType) ||
|
||||||
(type instanceof TerminatedUnicodeDataType)) {
|
(type instanceof TerminatedUnicodeDataType)) {
|
||||||
|
@ -538,7 +532,7 @@ public class PcodeDataTypeManager {
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size / 2);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size / 2);
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
resBuf.append(getCharTypeRef(2));
|
appendCharTypeRef(resBuf, 2);
|
||||||
}
|
}
|
||||||
else if ((type instanceof Unicode32DataType) ||
|
else if ((type instanceof Unicode32DataType) ||
|
||||||
(type instanceof TerminatedUnicode32DataType)) {
|
(type instanceof TerminatedUnicode32DataType)) {
|
||||||
|
@ -547,7 +541,7 @@ public class PcodeDataTypeManager {
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size / 4);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "arraysize", size / 4);
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
resBuf.append(getCharTypeRef(4));
|
appendCharTypeRef(resBuf, 4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
appendNameIdAttributes(resBuf, type);
|
appendNameIdAttributes(resBuf, type);
|
||||||
|
@ -558,7 +552,7 @@ public class PcodeDataTypeManager {
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
size = 1;
|
size = 1;
|
||||||
}
|
}
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "code");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "code");
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", 1); // Force size of 1
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", 1); // Force size of 1
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
|
@ -568,7 +562,7 @@ public class PcodeDataTypeManager {
|
||||||
fproto.buildPrototypeXML(resBuf, this);
|
fproto.buildPrototypeXML(resBuf, this);
|
||||||
}
|
}
|
||||||
else if (type instanceof BooleanDataType) {
|
else if (type instanceof BooleanDataType) {
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "bool");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "bool");
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", type.getLength());
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", type.getLength());
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
|
@ -579,13 +573,13 @@ public class PcodeDataTypeManager {
|
||||||
if (sz <= 0) {
|
if (sz <= 0) {
|
||||||
sz = size;
|
sz = size;
|
||||||
}
|
}
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", signed ? "int" : "uint");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", signed ? "int" : "uint");
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", sz);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", sz);
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
}
|
}
|
||||||
else if (type instanceof AbstractFloatDataType) {
|
else if (type instanceof AbstractFloatDataType) {
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "float");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "float");
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", type.getLength());
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", type.getLength());
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
|
@ -597,7 +591,7 @@ public class PcodeDataTypeManager {
|
||||||
sz = size;
|
sz = size;
|
||||||
isVarLength = true;
|
isVarLength = true;
|
||||||
}
|
}
|
||||||
appendNameIdAttributes(resBuf, origType);
|
appendNameIdAttributes(resBuf, type);
|
||||||
if (sz < 16) {
|
if (sz < 16) {
|
||||||
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "unknown");
|
SpecXmlUtils.encodeStringAttribute(resBuf, "metatype", "unknown");
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", sz);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", sz);
|
||||||
|
@ -613,6 +607,7 @@ public class PcodeDataTypeManager {
|
||||||
resBuf.append('>');
|
resBuf.append('>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
resBuf.append("</type>");
|
||||||
return resBuf.toString();
|
return resBuf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,27 +628,36 @@ public class PcodeDataTypeManager {
|
||||||
/**
|
/**
|
||||||
* Build an XML document string representing the type information for a data type
|
* Build an XML document string representing the type information for a data type
|
||||||
*
|
*
|
||||||
|
* @param resBuf is the stream to append the document to
|
||||||
* @param type data type to build XML for
|
* @param type data type to build XML for
|
||||||
* @param size size of the data type
|
* @param size size of the data type
|
||||||
*
|
|
||||||
* @return XML string document
|
|
||||||
*/
|
*/
|
||||||
public StringBuilder buildType(DataType type, int size) {
|
public void buildType(StringBuilder resBuf, DataType type, int size) {
|
||||||
if (type != null && type.getDataTypeManager() != progDataTypes) {
|
if (type != null && type.getDataTypeManager() != progDataTypes) {
|
||||||
type = type.clone(progDataTypes);
|
type = type.clone(progDataTypes);
|
||||||
}
|
}
|
||||||
StringBuilder resBuf = new StringBuilder();
|
|
||||||
if ((type instanceof VoidDataType) || (type == null)) {
|
if ((type instanceof VoidDataType) || (type == null)) {
|
||||||
return resBuf.append("<void/>");
|
resBuf.append("<void/>");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
resBuf.append("<type");
|
else if (type instanceof TypeDef) {
|
||||||
resBuf.append(buildTypeInternal(type, size));
|
resBuf.append("<def");
|
||||||
resBuf.append("</type>");
|
appendNameIdAttributes(resBuf, type);
|
||||||
return resBuf;
|
resBuf.append('>');
|
||||||
|
DataType refType = ((TypeDef) type).getDataType();
|
||||||
|
int sz = refType.getLength();
|
||||||
|
if (sz <= 0) {
|
||||||
|
sz = size;
|
||||||
|
}
|
||||||
|
buildTypeRef(resBuf, refType, sz);
|
||||||
|
resBuf.append("</def>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buildTypeInternal(resBuf, type, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an XML document string representing the Structure or Typedef to Structure that has
|
* Build an XML document string representing the Structure that has
|
||||||
* its size reported as zero.
|
* its size reported as zero.
|
||||||
*
|
*
|
||||||
* @param type data type to build XML for
|
* @param type data type to build XML for
|
||||||
|
@ -662,8 +666,7 @@ public class PcodeDataTypeManager {
|
||||||
*/
|
*/
|
||||||
public StringBuilder buildStructTypeZeroSizeOveride(DataType type) {
|
public StringBuilder buildStructTypeZeroSizeOveride(DataType type) {
|
||||||
StringBuilder resBuf = new StringBuilder();
|
StringBuilder resBuf = new StringBuilder();
|
||||||
if (!((type instanceof Structure) || ((type instanceof TypeDef) &&
|
if (!(type instanceof Structure)) {
|
||||||
(((TypeDef) type).getBaseDataType() instanceof Structure)))) {
|
|
||||||
return resBuf; //empty. Could throw AssertException.
|
return resBuf; //empty. Could throw AssertException.
|
||||||
}
|
}
|
||||||
resBuf.append("<type");
|
resBuf.append("<type");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue