mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Adjust typeref tags for variable length data-types
This commit is contained in:
parent
6397e835dc
commit
bb7bf84ac9
5 changed files with 35 additions and 11 deletions
|
@ -309,7 +309,14 @@ void Datatype::saveXmlRef(ostream &s) const
|
|||
if ((id!=0)&&(metatype != TYPE_VOID)) {
|
||||
s << "<typeref";
|
||||
a_v(s,"name",name);
|
||||
s << " id=\"0x" << hex << id << '\"';
|
||||
if (isVariableLength()) { // For a type with a "variable length" base
|
||||
uintb origId = hashSize(id, size); // Emit the size independent version of the id
|
||||
s << " id=\"0x" << hex << origId << '\"';
|
||||
s << " size=\"" << dec << size << '\"'; // but also emit size of this instance
|
||||
}
|
||||
else {
|
||||
s << " id=\"0x" << hex << id << '\"';
|
||||
}
|
||||
s << "/>";
|
||||
}
|
||||
else
|
||||
|
@ -1656,13 +1663,20 @@ Datatype *TypeFactory::findByIdLocal(const string &n,uint8 id) const
|
|||
return *iter;
|
||||
}
|
||||
|
||||
/// Search for a Datatype by \b name and/or \b id. Derived classes may search outside this container.
|
||||
/// The id is expected to resolve uniquely. Internally, different length instances
|
||||
/// of a variable length data-type are stored as separate Datatype objects. A non-zero
|
||||
/// size can be given to distinguish these cases.
|
||||
/// Derived classes may search outside this container.
|
||||
/// \param n is the name of the data-type
|
||||
/// \param id is the type id of the data-type
|
||||
/// \param sz is the given distinguishign size if non-zero
|
||||
/// \return the matching Datatype object
|
||||
Datatype *TypeFactory::findById(const string &n,uint8 id)
|
||||
Datatype *TypeFactory::findById(const string &n,uint8 id,int4 sz)
|
||||
|
||||
{
|
||||
if (sz > 0) { // If the id is for a "variable length" base data-type
|
||||
id = Datatype::hashSize(id, sz); // Construct the id for the "sized" variant
|
||||
}
|
||||
return findByIdLocal(n,id);
|
||||
}
|
||||
|
||||
|
@ -1672,7 +1686,7 @@ Datatype *TypeFactory::findById(const string &n,uint8 id)
|
|||
Datatype *TypeFactory::findByName(const string &n)
|
||||
|
||||
{
|
||||
return findById(n,0);
|
||||
return findById(n,0,0);
|
||||
}
|
||||
|
||||
/// Find data-type without reference to name, using the functional comparators
|
||||
|
@ -2197,18 +2211,25 @@ Datatype *TypeFactory::restoreXmlType(const Element *el)
|
|||
Datatype *ct;
|
||||
if (el->getName() == "typeref") {
|
||||
uint8 newid = 0;
|
||||
int4 size = -1;
|
||||
int4 num = el->getNumAttributes();
|
||||
for(int4 i=0;i<num;++i) {
|
||||
if (el->getAttributeName(i) == "id") {
|
||||
const string &nm(el->getAttributeName(i));
|
||||
if (nm == "id") {
|
||||
istringstream s(el->getAttributeValue(i));
|
||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s >> newid;
|
||||
}
|
||||
else if (nm == "size") { // A "size" attribute indicates a "variable length" base
|
||||
istringstream s(el->getAttributeValue(i));
|
||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s >> size;
|
||||
}
|
||||
}
|
||||
const string &newname( el->getAttributeValue("name"));
|
||||
if (newid == 0) // If there was no id, use the name hash
|
||||
newid = Datatype::hashName(newname);
|
||||
ct = findById(newname,newid);
|
||||
ct = findById(newname,newid,size);
|
||||
if (ct == (Datatype *)0)
|
||||
throw LowlevelError("Unable to resolve type: "+newname);
|
||||
return ct;
|
||||
|
|
|
@ -415,7 +415,7 @@ class TypeFactory {
|
|||
protected:
|
||||
Architecture *glb; ///< The Architecture object that owns this TypeFactory
|
||||
Datatype *findByIdLocal(const string &nm,uint8 id) const; ///< Search locally by name and id
|
||||
virtual Datatype *findById(const string &n,uint8 id); ///< Search by name and id
|
||||
virtual Datatype *findById(const string &n,uint8 id,int4 sz); ///< Search by \e name and/or \e id
|
||||
public:
|
||||
TypeFactory(Architecture *g); ///< Construct a factory
|
||||
void setupSizes(void); ///< Derive some size information from Architecture
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,10 +15,10 @@
|
|||
*/
|
||||
#include "typegrp_ghidra.hh"
|
||||
|
||||
Datatype *TypeFactoryGhidra::findById(const string &n,uint8 id)
|
||||
Datatype *TypeFactoryGhidra::findById(const string &n,uint8 id,int4 sz)
|
||||
|
||||
{
|
||||
Datatype *ct = TypeFactory::findById(n,id); // Try internal find
|
||||
Datatype *ct = TypeFactory::findById(n,id,sz); // Try internal find
|
||||
if (ct != (Datatype *)0) return ct;
|
||||
|
||||
Document *doc;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
/// converted into a Datatype object and cached in this object.
|
||||
class TypeFactoryGhidra : public TypeFactory {
|
||||
protected:
|
||||
virtual Datatype *findById(const string &n,uint8 id);
|
||||
virtual Datatype *findById(const string &n,uint8 id,int4 sz);
|
||||
public:
|
||||
TypeFactoryGhidra(ArchitectureGhidra *g) : TypeFactory(g) {} ///< Constructor
|
||||
virtual ~TypeFactoryGhidra(void) {}
|
||||
|
|
|
@ -277,6 +277,7 @@ public class PcodeDataTypeManager {
|
|||
// construct a <typeref> tag but must build a full <type> tag.
|
||||
return buildType(type, size);
|
||||
}
|
||||
size = 1;
|
||||
}
|
||||
else if (type.getLength() <= 0) {
|
||||
return buildType(type, size);
|
||||
|
@ -294,6 +295,9 @@ public class PcodeDataTypeManager {
|
|||
if (id > 0) {
|
||||
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "id", id);
|
||||
}
|
||||
if (type.getLength() <= 0 && size > 0) {
|
||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
||||
}
|
||||
}
|
||||
resBuf.append("/>");
|
||||
return resBuf;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue