GP-1932 Decompiler support for address space attribute on pointers

This commit is contained in:
caheckman 2022-03-04 20:07:34 -05:00
parent 31b30adf2d
commit 7078885aea
12 changed files with 710 additions and 366 deletions

View file

@ -831,9 +831,9 @@ void Architecture::parseGlobal(const Element *el)
// We need to duplicate the range being marked as global into the overlay space(s) // We need to duplicate the range being marked as global into the overlay space(s)
int4 num = numSpaces(); int4 num = numSpaces();
for(int4 i=0;i<num;++i) { for(int4 i=0;i<num;++i) {
OverlaySpace *ospc = (OverlaySpace *)getSpace(i); AddrSpace *ospc = getSpace(i);
if (ospc == (AddrSpace *)0 || !ospc->isOverlay()) continue; if (ospc == (AddrSpace *)0 || !ospc->isOverlay()) continue;
if (ospc->getBaseSpace() != range.getSpace()) continue; if (ospc->getContain() != range.getSpace()) continue;
symboltab->addRange(scope,ospc,range.getFirst(),range.getLast()); symboltab->addRange(scope,ospc,range.getFirst(),range.getLast());
} }
} }
@ -852,7 +852,7 @@ void Architecture::addOtherSpace(void)
for(int4 i=0;i<num;++i){ for(int4 i=0;i<num;++i){
AddrSpace *ospc = getSpace(i); AddrSpace *ospc = getSpace(i);
if (!ospc->isOverlay()) continue; if (!ospc->isOverlay()) continue;
if (((OverlaySpace *)ospc)->getBaseSpace() != otherSpace) continue; if (ospc->getContain() != otherSpace) continue;
symboltab->addRange(scope,ospc,0,otherSpace->getHighest()); symboltab->addRange(scope,ospc,0,otherSpace->getHighest());
} }
} }

View file

@ -226,8 +226,17 @@ Datatype *CastStrategyC::castStandard(Datatype *reqtype,Datatype *curtype,
Datatype *curbase = curtype; Datatype *curbase = curtype;
bool isptr = false; bool isptr = false;
while((reqbase->getMetatype()==TYPE_PTR)&&(curbase->getMetatype()==TYPE_PTR)) { while((reqbase->getMetatype()==TYPE_PTR)&&(curbase->getMetatype()==TYPE_PTR)) {
reqbase = ((const TypePointer *)reqbase)->getPtrTo(); const TypePointer *reqptr = (const TypePointer *)reqbase;
curbase = ((const TypePointer *)curbase)->getPtrTo(); const TypePointer *curptr = (const TypePointer *)curbase;
if (reqptr->getWordSize() != curptr->getWordSize())
return reqtype;
if (reqptr->getSpace() != curptr->getSpace()) {
if (reqptr->getSpace() != (AddrSpace *)0 && curptr->getSpace() != (AddrSpace *)0)
return reqtype; // Pointers to different address spaces. We must cast
// If one pointer doesn't have an address, assume a conversion to/from sub-type and don't need a cast
}
reqbase = reqptr->getPtrTo();
curbase = curptr->getPtrTo();
care_uint_int = true; care_uint_int = true;
isptr = true; isptr = true;
} }

View file

@ -935,17 +935,25 @@ int4 ActionShadowVar::apply(Funcdata &data)
return 0; return 0;
} }
/// \brief Make a limited search from a constant for a LOAD or STORE so we can see the AddrSpace being accessed /// \brief Search for address space annotations in the path of a pointer constant.
/// ///
/// We traverse forward through the op reading the constant, through INT_ADD, INDIRECT, COPY, and MULTIEQUAL /// From a constant, search forward in its data-flow either for a LOAD or STORE operation where we can
/// until we hit a LOAD or STORE. /// see the address space being accessed, or search for a pointer data-type with an address space attribute.
/// We make a limited traversal through the op reading the constant, through INT_ADD, INDIRECT, COPY,
/// and MULTIEQUAL until we hit a LOAD or STORE.
/// \param vn is the constant we are searching from /// \param vn is the constant we are searching from
/// \param op is the PcodeOp reading the constant /// \param op is the PcodeOp reading the constant
/// \return the discovered AddrSpace or null /// \return the discovered AddrSpace or null
AddrSpace *ActionConstantPtr::searchForLoadStore(Varnode *vn,PcodeOp *op) AddrSpace *ActionConstantPtr::searchForSpaceAttribute(Varnode *vn,PcodeOp *op)
{ {
for(int4 i=0;i<3;++i) { for(int4 i=0;i<3;++i) {
Datatype *dt = vn->getType();
if (dt->getMetatype() == TYPE_PTR) {
AddrSpace *spc = ((TypePointer*)dt)->getSpace();
if (spc != (AddrSpace*)0 && spc->getAddrSize() == vn->getSize()) // If provided a pointer with space attribute
return spc; // use that
}
switch(op->code()) { switch(op->code()) {
case CPUI_INT_ADD: case CPUI_INT_ADD:
case CPUI_COPY: case CPUI_COPY:
@ -988,6 +996,11 @@ AddrSpace *ActionConstantPtr::selectInferSpace(Varnode *vn,PcodeOp *op,const vec
{ {
AddrSpace *resSpace = (AddrSpace *)0; AddrSpace *resSpace = (AddrSpace *)0;
if (vn->getType()->getMetatype() == TYPE_PTR) {
AddrSpace *spc = ((TypePointer *)vn->getType())->getSpace();
if (spc != (AddrSpace *)0 && spc->getAddrSize() == vn->getSize())
return spc;
}
for(int4 i=0;i<spaceList.size();++i) { for(int4 i=0;i<spaceList.size();++i) {
AddrSpace *spc = spaceList[i]; AddrSpace *spc = spaceList[i];
int4 minSize = spc->getMinimumPtrSize(); int4 minSize = spc->getMinimumPtrSize();
@ -998,7 +1011,7 @@ AddrSpace *ActionConstantPtr::selectInferSpace(Varnode *vn,PcodeOp *op,const vec
else if (vn->getSize() < minSize) else if (vn->getSize() < minSize)
continue; continue;
if (resSpace != (AddrSpace *)0) { if (resSpace != (AddrSpace *)0) {
AddrSpace *searchSpc = searchForLoadStore(vn,op); AddrSpace *searchSpc = searchForSpaceAttribute(vn,op);
if (searchSpc != (AddrSpace *)0) if (searchSpc != (AddrSpace *)0)
resSpace = searchSpc; resSpace = searchSpc;
break; break;
@ -2167,6 +2180,42 @@ int4 ActionDefaultParams::apply(Funcdata &data)
return 0; // Indicate success return 0; // Indicate success
} }
/// \brief Check if the data-type of the given value being used as a pointer makes sense
///
/// If the data-type is a pointer make sure:
/// - The pointed-to size matches the size of the value being loaded are stored
/// - Any address space attached to the pointer matches the address space of the LOAD/STORE
///
/// If any of the conditions are violated, a warning is added to the output.
/// \param op is the LOAD/STORE acting on a pointer
/// \param vn is the given value being used as a pointer
/// \param data is the function containing the PcodeOp
void ActionSetCasts::checkPointerIssues(PcodeOp *op,Varnode *vn,Funcdata &data)
{
Datatype *ptrtype = op->getIn(1)->getHighTypeReadFacing(op);
int4 valsize = vn->getSize();
if ((ptrtype->getMetatype()!=TYPE_PTR)|| (((TypePointer *)ptrtype)->getPtrTo()->getSize() != valsize)) {
string name = op->getOpcode()->getName();
name[0] = toupper( name[0] );
data.warning(name + " size is inaccurate",op->getAddr());
}
if (ptrtype->getMetatype()==TYPE_PTR) {
AddrSpace *spc = ((TypePointer *)ptrtype)->getSpace();
if (spc != (AddrSpace *)0) {
AddrSpace *opSpc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
if (opSpc != spc && spc->getContain() != opSpc) {
string name = op->getOpcode()->getName();
name[0] = toupper( name[0] );
ostringstream s;
s << name << " refers to '" << opSpc->getName() << "' but pointer attribute is '";
s << spc->getName() << '\'';
data.warning(s.str(),op->getAddr());
}
}
}
}
/// \brief Test if the given cast conflict can be resolved by passing to the first structure field /// \brief Test if the given cast conflict can be resolved by passing to the first structure field
/// ///
/// Test if the given Varnode data-type is a pointer to a structure and if interpreting /// Test if the given Varnode data-type is a pointer to a structure and if interpreting
@ -2512,18 +2561,10 @@ int4 ActionSetCasts::apply(Funcdata &data)
count += castInput(op,i,data,castStrategy); count += castInput(op,i,data,castStrategy);
} }
if (opc == CPUI_LOAD) { if (opc == CPUI_LOAD) {
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHighTypeReadFacing(op); checkPointerIssues(op, op->getOut(), data);
int4 valsize = op->getOut()->getSize();
if ((ptrtype->getMetatype()!=TYPE_PTR)||
(ptrtype->getPtrTo()->getSize() != valsize))
data.warning("Load size is inaccurate",op->getAddr());
} }
else if (opc == CPUI_STORE) { else if (opc == CPUI_STORE) {
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHighTypeReadFacing(op); checkPointerIssues(op, op->getIn(2), data);
int4 valsize = op->getIn(2)->getSize();
if ((ptrtype->getMetatype()!=TYPE_PTR)||
(ptrtype->getPtrTo()->getSize() != valsize))
data.warning("Store size is inaccurate",op->getAddr());
} }
Varnode *vn = op->getOut(); Varnode *vn = op->getOut();
if (vn == (Varnode *)0) continue; if (vn == (Varnode *)0) continue;

View file

@ -180,7 +180,7 @@ public:
/// \brief Check for constants, with pointer type, that correspond to global symbols /// \brief Check for constants, with pointer type, that correspond to global symbols
class ActionConstantPtr : public Action { class ActionConstantPtr : public Action {
int4 localcount; ///< Number of passes made for this function int4 localcount; ///< Number of passes made for this function
static AddrSpace *searchForLoadStore(Varnode *vn,PcodeOp *op); static AddrSpace *searchForSpaceAttribute(Varnode *vn,PcodeOp *op);
static AddrSpace *selectInferSpace(Varnode *vn,PcodeOp *op,const vector<AddrSpace *> &spaceList); static AddrSpace *selectInferSpace(Varnode *vn,PcodeOp *op,const vector<AddrSpace *> &spaceList);
static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot, static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot,
Address &rampoint,uintb &fullEncoding,Funcdata &data); Address &rampoint,uintb &fullEncoding,Funcdata &data);
@ -310,6 +310,7 @@ public:
/// input. In this case, it casts to the necessary pointer type /// input. In this case, it casts to the necessary pointer type
/// immediately. /// immediately.
class ActionSetCasts : public Action { class ActionSetCasts : public Action {
static void checkPointerIssues(PcodeOp *op,Varnode *vn,Funcdata &data);
static bool testStructOffset0(Varnode *vn,PcodeOp *op,Datatype *ct,CastStrategy *castStrategy); static bool testStructOffset0(Varnode *vn,PcodeOp *op,Datatype *ct,CastStrategy *castStrategy);
static bool tryResolutionAdjustment(PcodeOp *op,int4 slot,Funcdata &data); static bool tryResolutionAdjustment(PcodeOp *op,int4 slot,Funcdata &data);
static bool isOpIdentical(Datatype *ct1,Datatype *ct2); static bool isOpIdentical(Datatype *ct1,Datatype *ct2);

View file

@ -2893,8 +2893,10 @@ void IfcReadonly::execute(istream &s)
/// \class IfcPointerSetting /// \class IfcPointerSetting
/// \brief Create a pointer with additional settings: `pointer setting <name> <basetype> offset <val>` /// \brief Create a pointer with additional settings: `pointer setting <name> <basetype> offset <val>`
/// ///
/// The new data-type is named and must be pointer. It must have a setting /// Alternately: `pointer setting <name> <basetype> space <spacename>`
/// - \b offset which creates a shifted pointer /// The new data-type is named and must be pointer.
/// An \e offset setting creates a relative pointer and attaches the provided offset value.
/// A \e space setting create a pointer with the provided address space as an attribute.
void IfcPointerSetting::execute(istream &s) void IfcPointerSetting::execute(istream &s)
{ {
@ -2927,6 +2929,19 @@ void IfcPointerSetting::execute(istream &s)
AddrSpace *spc = dcp->conf->getDefaultDataSpace(); AddrSpace *spc = dcp->conf->getDefaultDataSpace();
dcp->conf->types->getTypePointerRel(spc->getAddrSize(), bt, ptrto, spc->getWordSize(), off,typeName); dcp->conf->types->getTypePointerRel(spc->getAddrSize(), bt, ptrto, spc->getWordSize(), off,typeName);
} }
else if (setting == "space") {
string spaceName;
s >> spaceName;
if (spaceName.length() == 0)
throw IfaceParseError("Missing name of address space");
Datatype *ptrTo = dcp->conf->types->findByName(baseType);
if (ptrTo == (Datatype *)0)
throw IfaceParseError("Unknown base data-type: "+baseType);
AddrSpace *spc = dcp->conf->getSpaceByName(spaceName);
if (spc == (AddrSpace *)0)
throw IfaceParseError("Unknown space: "+spaceName);
dcp->conf->types->getTypePointerWithSpace(ptrTo,spc,typeName);
}
else else
throw IfaceParseError("Unknown pointer setting: "+setting); throw IfaceParseError("Unknown pointer setting: "+setting);
*status->optr << "Successfully created pointer: " << typeName << endl; *status->optr << "Successfully created pointer: " << typeName << endl;

View file

@ -659,13 +659,6 @@ OverlaySpace::OverlaySpace(AddrSpaceManager *m,const Translate *t)
setFlags(overlay); setFlags(overlay);
} }
/// \return the base address space
AddrSpace *OverlaySpace::getBaseSpace(void) const
{
return baseSpace;
}
void OverlaySpace::saveXml(ostream &s) const void OverlaySpace::saveXml(ostream &s) const
{ {

View file

@ -244,7 +244,7 @@ class OverlaySpace : public AddrSpace {
AddrSpace *baseSpace; ///< Space being overlayed AddrSpace *baseSpace; ///< Space being overlayed
public: public:
OverlaySpace(AddrSpaceManager *m,const Translate *t); ///< Constructor OverlaySpace(AddrSpaceManager *m,const Translate *t); ///< Constructor
AddrSpace *getBaseSpace(void) const; ///< Get the address space being overlayed virtual AddrSpace *getContain(void) const { return baseSpace; }
virtual void saveXml(ostream &s) const; virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el); virtual void restoreXml(const Element *el);
}; };

View file

@ -345,8 +345,7 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc)
// fallthru // fallthru
case IPTR_PROCESSOR: case IPTR_PROCESSOR:
if (spc->isOverlay()) { // If this is a new overlay space if (spc->isOverlay()) { // If this is a new overlay space
OverlaySpace *ospc = (OverlaySpace *)spc; spc->getContain()->setFlags(AddrSpace::overlaybase); // Mark the base as being overlayed
ospc->getBaseSpace()->setFlags(AddrSpace::overlaybase); // Mark the base as being overlayed
} }
else if (spc->isOtherSpace()) { else if (spc->isOtherSpace()) {
if (spc->index != OtherSpace::INDEX) if (spc->index != OtherSpace::INDEX)

View file

@ -619,6 +619,9 @@ void TypePointer::printRaw(ostream &s) const
{ {
ptrto->printRaw(s); ptrto->printRaw(s);
s << " *"; s << " *";
if (spaceid != (AddrSpace *)0) {
s << '(' << spaceid->getName() << ')';
}
} }
int4 TypePointer::compare(const Datatype &op,int4 level) const int4 TypePointer::compare(const Datatype &op,int4 level) const
@ -629,6 +632,11 @@ int4 TypePointer::compare(const Datatype &op,int4 level) const
// Both must be pointers // Both must be pointers
TypePointer *tp = (TypePointer *) &op; TypePointer *tp = (TypePointer *) &op;
if (wordsize != tp->wordsize) return (wordsize < tp->wordsize) ? -1 : 1; if (wordsize != tp->wordsize) return (wordsize < tp->wordsize) ? -1 : 1;
if (spaceid != tp->spaceid) {
if (spaceid == (AddrSpace *)0) return 1; // Pointers with address space come earlier
if (tp->spaceid == (AddrSpace *)0) return -1;
return (spaceid->getIndex() < tp->spaceid->getIndex()) ? -1 : 1;
}
level -= 1; level -= 1;
if (level < 0) { if (level < 0) {
if (id == op.getId()) return 0; if (id == op.getId()) return 0;
@ -644,6 +652,11 @@ int4 TypePointer::compareDependency(const Datatype &op) const
TypePointer *tp = (TypePointer *) &op; // Both must be pointers TypePointer *tp = (TypePointer *) &op; // Both must be pointers
if (ptrto != tp->ptrto) return (ptrto < tp->ptrto) ? -1 : 1; // Compare absolute pointers if (ptrto != tp->ptrto) return (ptrto < tp->ptrto) ? -1 : 1; // Compare absolute pointers
if (wordsize != tp->wordsize) return (wordsize < tp->wordsize) ? -1 : 1; if (wordsize != tp->wordsize) return (wordsize < tp->wordsize) ? -1 : 1;
if (spaceid != tp->spaceid) {
if (spaceid == (AddrSpace *)0) return 1; // Pointers with address space come earlier
if (tp->spaceid == (AddrSpace *)0) return -1;
return (spaceid->getIndex() < tp->spaceid->getIndex()) ? -1 : 1;
}
return (op.getSize()-size); return (op.getSize()-size);
} }
@ -658,6 +671,8 @@ void TypePointer::saveXml(ostream &s) const
saveXmlBasic(metatype,s); saveXmlBasic(metatype,s);
if (wordsize != 1) if (wordsize != 1)
a_v_i(s,"wordsize",wordsize); a_v_i(s,"wordsize",wordsize);
if (spaceid != (AddrSpace *)0)
a_v(s,"space",spaceid->getName());
s << '>'; s << '>';
ptrto->saveXmlRef(s); ptrto->saveXmlRef(s);
s << "</type>"; s << "</type>";
@ -670,12 +685,17 @@ void TypePointer::restoreXml(const Element *el,TypeFactory &typegrp)
{ {
restoreXmlBasic(el); restoreXmlBasic(el);
for(int4 i=0;i<el->getNumAttributes();++i) for(int4 i=0;i<el->getNumAttributes();++i) {
if (el->getAttributeName(i) == "wordsize") { const string &attrName(el->getAttributeName(i));
if (attrName == "wordsize") {
istringstream s(el->getAttributeValue(i)); istringstream s(el->getAttributeValue(i));
s.unsetf(ios::dec | ios::hex | ios::oct); s.unsetf(ios::dec | ios::hex | ios::oct);
s >> wordsize; s >> wordsize;
} }
else if (attrName == "space") {
spaceid = typegrp.getArch()->getSpaceByName(el->getAttributeValue(i));
}
}
ptrto = typegrp.restoreXmlType( *el->getChildren().begin() ); ptrto = typegrp.restoreXmlType( *el->getChildren().begin() );
calcSubmeta(); calcSubmeta();
if (name.size() == 0) // Inherit only if no name if (name.size() == 0) // Inherit only if no name
@ -1740,12 +1760,17 @@ void TypePointerRel::restoreXml(const Element *el,TypeFactory &typegrp)
flags |= is_ptrrel; flags |= is_ptrrel;
restoreXmlBasic(el); restoreXmlBasic(el);
metatype = TYPE_PTR; // Don't use TYPE_PTRREL internally metatype = TYPE_PTR; // Don't use TYPE_PTRREL internally
for(int4 i=0;i<el->getNumAttributes();++i) for(int4 i=0;i<el->getNumAttributes();++i) {
if (el->getAttributeName(i) == "wordsize") { const string &attribName(el->getAttributeName(i));
if (attribName == "wordsize") {
istringstream s(el->getAttributeValue(i)); istringstream s(el->getAttributeValue(i));
s.unsetf(ios::dec | ios::hex | ios::oct); s.unsetf(ios::dec | ios::hex | ios::oct);
s >> wordsize; s >> wordsize;
} }
else if (attribName == "space") {
spaceid = typegrp.getArch()->getSpaceByName(el->getAttributeValue("space"));
}
}
const List &list(el->getChildren()); const List &list(el->getChildren());
List::const_iterator iter; List::const_iterator iter;
iter = list.begin(); iter = list.begin();
@ -3104,6 +3129,13 @@ TypePointerRel *TypeFactory::getTypePointerRel(TypePointer *parentPtr,Datatype *
/// ///
/// The resulting data-type is named and not ephemeral and will display as a formal data-type /// The resulting data-type is named and not ephemeral and will display as a formal data-type
/// in decompiler output. /// in decompiler output.
/// \param sz is the size in bytes of the pointer
/// \param parent is data-type of the parent container being indirectly pointed to
/// \param ptrTo is the data-type being pointed directly to
/// \param ws is the addressable unit size of pointed to data
/// \param off is the offset of the pointed-to data-type relative to the \e container
/// \param nm is the name to associate with the pointer
/// \return the new/matching pointer
TypePointerRel *TypeFactory::getTypePointerRel(int4 sz,Datatype *parent,Datatype *ptrTo,int4 ws,int4 off,const string &nm) TypePointerRel *TypeFactory::getTypePointerRel(int4 sz,Datatype *parent,Datatype *ptrTo,int4 ws,int4 off,const string &nm)
{ {
@ -3114,6 +3146,24 @@ TypePointerRel *TypeFactory::getTypePointerRel(int4 sz,Datatype *parent,Datatype
return res; return res;
} }
/// \brief Build a named pointer with an address space attribute
///
/// The new data-type acts like a typedef of a normal pointer but can affect the resolution of
/// constants by the type propagation system.
/// \param ptrTo is the data-type being pointed directly to
/// \param spc is the address space to associate with the pointer
/// \param nm is the name to associate with the pointer
/// \return the new/matching pointer
TypePointer *TypeFactory::getTypePointerWithSpace(Datatype *ptrTo,AddrSpace *spc,const string &nm)
{
TypePointer tp(ptrTo,spc);
tp.name = nm;
tp.id = Datatype::hashName(nm);
TypePointer *res = (TypePointer *)findAdd(tp);
return res;
}
/// The indicated Datatype object is removed from this container. /// The indicated Datatype object is removed from this container.
/// Indirect references (via TypeArray TypeStruct etc.) are not affected /// Indirect references (via TypeArray TypeStruct etc.) are not affected
/// \param ct is the data-type to destroy /// \param ct is the data-type to destroy

View file

@ -281,25 +281,30 @@ class TypePointer : public Datatype {
protected: protected:
friend class TypeFactory; friend class TypeFactory;
Datatype *ptrto; ///< Type being pointed to Datatype *ptrto; ///< Type being pointed to
AddrSpace *spaceid; ///< If non-null, the address space \b this is intented to point into
uint4 wordsize; ///< What size unit does the pointer address uint4 wordsize; ///< What size unit does the pointer address
void restoreXml(const Element *el,TypeFactory &typegrp); ///< Restore \b this pointer data-type from an XML element void restoreXml(const Element *el,TypeFactory &typegrp); ///< Restore \b this pointer data-type from an XML element
void calcSubmeta(void); ///< Calculate specific submeta for \b this pointer void calcSubmeta(void); ///< Calculate specific submeta for \b this pointer
/// Internal constructor for use with restoreXml /// Internal constructor for use with restoreXml
TypePointer(void) : Datatype(0,TYPE_PTR) { ptrto = (Datatype *)0; wordsize=1; } TypePointer(void) : Datatype(0,TYPE_PTR) { ptrto = (Datatype *)0; wordsize=1; spaceid=(AddrSpace *)0; }
public: public:
/// Construct from another TypePointer /// Construct from another TypePointer
TypePointer(const TypePointer &op) : Datatype(op) { ptrto = op.ptrto; wordsize=op.wordsize; } TypePointer(const TypePointer &op) : Datatype(op) { ptrto = op.ptrto; wordsize=op.wordsize; spaceid=op.spaceid; }
/// Construct from a size, pointed-to type, and wordsize /// Construct from a size, pointed-to type, and wordsize
TypePointer(int4 s,Datatype *pt,uint4 ws) : Datatype(s,TYPE_PTR) { TypePointer(int4 s,Datatype *pt,uint4 ws) : Datatype(s,TYPE_PTR) {
ptrto = pt; flags = ptrto->getInheritable(); wordsize=ws; calcSubmeta(); } ptrto = pt; flags = ptrto->getInheritable(); wordsize=ws; spaceid=(AddrSpace *)0; calcSubmeta(); }
/// Construct from a pointed-to type and an address space attribute
TypePointer(Datatype *pt,AddrSpace *spc) : Datatype(spc->getAddrSize(), TYPE_PTR) {
ptrto = pt; flags = ptrto->getInheritable(); spaceid=spc; wordsize=spc->getWordSize(); calcSubmeta(); }
Datatype *getPtrTo(void) const { return ptrto; } ///< Get the pointed-to Datatype Datatype *getPtrTo(void) const { return ptrto; } ///< Get the pointed-to Datatype
uint4 getWordSize(void) const { return wordsize; } ///< Get the wordsize of the pointer uint4 getWordSize(void) const { return wordsize; } ///< Get the size of the addressable unit being pointed to
AddrSpace *getSpace(void) const { return spaceid; } ///< Get any address space associated with \b this pointer
virtual void printRaw(ostream &s) const; virtual void printRaw(ostream &s) const;
virtual int4 numDepend(void) const { return 1; } virtual int4 numDepend(void) const { return 1; }
virtual Datatype *getDepend(int4 index) const { return ptrto; } virtual Datatype *getDepend(int4 index) const { return ptrto; }
virtual void printNameBase(ostream &s) const { s << 'p'; ptrto->printNameBase(s); } virtual void printNameBase(ostream &s) const { s << 'p'; ptrto->printNameBase(s); }
virtual int4 compare(const Datatype &op,int4 level) const; // For tree structure virtual int4 compare(const Datatype &op,int4 level) const;
virtual int4 compareDependency(const Datatype &op) const; // For tree structure virtual int4 compareDependency(const Datatype &op) const;
virtual Datatype *clone(void) const { return new TypePointer(*this); } virtual Datatype *clone(void) const { return new TypePointer(*this); }
virtual void saveXml(ostream &s) const; virtual void saveXml(ostream &s) const;
virtual TypePointer *downChain(uintb &off,TypePointer *&par,uintb &parOff,bool allowArrayWrap,TypeFactory &typegrp); virtual TypePointer *downChain(uintb &off,TypePointer *&par,uintb &parOff,bool allowArrayWrap,TypeFactory &typegrp);
@ -597,6 +602,7 @@ public:
Datatype *getTypedef(Datatype *ct,const string &name,uint8 id); ///< Create a new \e typedef data-type Datatype *getTypedef(Datatype *ct,const string &name,uint8 id); ///< Create a new \e typedef data-type
TypePointerRel *getTypePointerRel(TypePointer *parentPtr,Datatype *ptrTo,int4 off); ///< Get pointer offset relative to a container TypePointerRel *getTypePointerRel(TypePointer *parentPtr,Datatype *ptrTo,int4 off); ///< Get pointer offset relative to a container
TypePointerRel *getTypePointerRel(int4 sz,Datatype *parent,Datatype *ptrTo,int4 ws,int4 off,const string &nm); TypePointerRel *getTypePointerRel(int4 sz,Datatype *parent,Datatype *ptrTo,int4 ws,int4 off,const string &nm);
TypePointer *getTypePointerWithSpace(Datatype *ptrTo,AddrSpace *spc,const string &nm);
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

View file

@ -21,8 +21,7 @@ import java.util.List;
import org.xml.sax.*; import org.xml.sax.*;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.*;
import ghidra.program.model.data.VoidDataType;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.listing.Function.FunctionUpdateType; import ghidra.program.model.listing.Function.FunctionUpdateType;
@ -265,7 +264,7 @@ public class HighParamID extends PcodeSyntaxTree {
dataType = pm.getDataType(); dataType = pm.getDataType();
} }
else { else {
dataType = dtManage.findUndefined(vn.getSize()); dataType = Undefined.getUndefinedDataType(vn.getSize());
} }
//Msg.debug(this, "func: " + func.getName() + " -- type: " + dataType.getName()); //Msg.debug(this, "func: " + func.getName() + " -- type: " + dataType.getName());
if (!(dataType == null || dataType instanceof VoidDataType)) { if (!(dataType == null || dataType instanceof VoidDataType)) {
@ -298,7 +297,7 @@ public class HighParamID extends PcodeSyntaxTree {
dataType = pm.getDataType(); dataType = pm.getDataType();
} }
else { else {
dataType = dtManage.findUndefined(vn.getSize()); dataType = Undefined.getUndefinedDataType(vn.getSize());
} }
Variable v = new ParameterImpl(null, dataType, buildStorage(vn), func.getProgram()); Variable v = new ParameterImpl(null, dataType, buildStorage(vn), func.getProgram());
//Msg.debug(this, "function(" + func.getName() + ")--param: " + v.toString() + //Msg.debug(this, "function(" + func.getName() + ")--param: " + v.toString() +