mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-1932 Decompiler support for address space attribute on pointers
This commit is contained in:
parent
31b30adf2d
commit
7078885aea
12 changed files with 710 additions and 366 deletions
|
@ -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)
|
||||
int4 num = numSpaces();
|
||||
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->getBaseSpace() != range.getSpace()) continue;
|
||||
if (ospc->getContain() != range.getSpace()) continue;
|
||||
symboltab->addRange(scope,ospc,range.getFirst(),range.getLast());
|
||||
}
|
||||
}
|
||||
|
@ -852,7 +852,7 @@ void Architecture::addOtherSpace(void)
|
|||
for(int4 i=0;i<num;++i){
|
||||
AddrSpace *ospc = getSpace(i);
|
||||
if (!ospc->isOverlay()) continue;
|
||||
if (((OverlaySpace *)ospc)->getBaseSpace() != otherSpace) continue;
|
||||
if (ospc->getContain() != otherSpace) continue;
|
||||
symboltab->addRange(scope,ospc,0,otherSpace->getHighest());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,8 +226,17 @@ Datatype *CastStrategyC::castStandard(Datatype *reqtype,Datatype *curtype,
|
|||
Datatype *curbase = curtype;
|
||||
bool isptr = false;
|
||||
while((reqbase->getMetatype()==TYPE_PTR)&&(curbase->getMetatype()==TYPE_PTR)) {
|
||||
reqbase = ((const TypePointer *)reqbase)->getPtrTo();
|
||||
curbase = ((const TypePointer *)curbase)->getPtrTo();
|
||||
const TypePointer *reqptr = (const TypePointer *)reqbase;
|
||||
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;
|
||||
isptr = true;
|
||||
}
|
||||
|
|
|
@ -935,17 +935,25 @@ int4 ActionShadowVar::apply(Funcdata &data)
|
|||
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
|
||||
/// until we hit a LOAD or STORE.
|
||||
/// From a constant, search forward in its data-flow either for a LOAD or STORE operation where we can
|
||||
/// 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 op is the PcodeOp reading the constant
|
||||
/// \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) {
|
||||
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()) {
|
||||
case CPUI_INT_ADD:
|
||||
case CPUI_COPY:
|
||||
|
@ -988,6 +996,11 @@ AddrSpace *ActionConstantPtr::selectInferSpace(Varnode *vn,PcodeOp *op,const vec
|
|||
|
||||
{
|
||||
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) {
|
||||
AddrSpace *spc = spaceList[i];
|
||||
int4 minSize = spc->getMinimumPtrSize();
|
||||
|
@ -998,7 +1011,7 @@ AddrSpace *ActionConstantPtr::selectInferSpace(Varnode *vn,PcodeOp *op,const vec
|
|||
else if (vn->getSize() < minSize)
|
||||
continue;
|
||||
if (resSpace != (AddrSpace *)0) {
|
||||
AddrSpace *searchSpc = searchForLoadStore(vn,op);
|
||||
AddrSpace *searchSpc = searchForSpaceAttribute(vn,op);
|
||||
if (searchSpc != (AddrSpace *)0)
|
||||
resSpace = searchSpc;
|
||||
break;
|
||||
|
@ -2167,6 +2180,42 @@ int4 ActionDefaultParams::apply(Funcdata &data)
|
|||
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
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
if (opc == CPUI_LOAD) {
|
||||
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHighTypeReadFacing(op);
|
||||
int4 valsize = op->getOut()->getSize();
|
||||
if ((ptrtype->getMetatype()!=TYPE_PTR)||
|
||||
(ptrtype->getPtrTo()->getSize() != valsize))
|
||||
data.warning("Load size is inaccurate",op->getAddr());
|
||||
checkPointerIssues(op, op->getOut(), data);
|
||||
}
|
||||
else if (opc == CPUI_STORE) {
|
||||
TypePointer *ptrtype = (TypePointer *)op->getIn(1)->getHighTypeReadFacing(op);
|
||||
int4 valsize = op->getIn(2)->getSize();
|
||||
if ((ptrtype->getMetatype()!=TYPE_PTR)||
|
||||
(ptrtype->getPtrTo()->getSize() != valsize))
|
||||
data.warning("Store size is inaccurate",op->getAddr());
|
||||
checkPointerIssues(op, op->getIn(2), data);
|
||||
}
|
||||
Varnode *vn = op->getOut();
|
||||
if (vn == (Varnode *)0) continue;
|
||||
|
|
|
@ -180,7 +180,7 @@ public:
|
|||
/// \brief Check for constants, with pointer type, that correspond to global symbols
|
||||
class ActionConstantPtr : public Action {
|
||||
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 SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,int4 slot,
|
||||
Address &rampoint,uintb &fullEncoding,Funcdata &data);
|
||||
|
@ -310,6 +310,7 @@ public:
|
|||
/// input. In this case, it casts to the necessary pointer type
|
||||
/// immediately.
|
||||
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 tryResolutionAdjustment(PcodeOp *op,int4 slot,Funcdata &data);
|
||||
static bool isOpIdentical(Datatype *ct1,Datatype *ct2);
|
||||
|
|
|
@ -2893,8 +2893,10 @@ void IfcReadonly::execute(istream &s)
|
|||
/// \class IfcPointerSetting
|
||||
/// \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
|
||||
/// - \b offset which creates a shifted pointer
|
||||
/// Alternately: `pointer setting <name> <basetype> space <spacename>`
|
||||
/// 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)
|
||||
|
||||
{
|
||||
|
@ -2927,6 +2929,19 @@ void IfcPointerSetting::execute(istream &s)
|
|||
AddrSpace *spc = dcp->conf->getDefaultDataSpace();
|
||||
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
|
||||
throw IfaceParseError("Unknown pointer setting: "+setting);
|
||||
*status->optr << "Successfully created pointer: " << typeName << endl;
|
||||
|
|
|
@ -659,13 +659,6 @@ OverlaySpace::OverlaySpace(AddrSpaceManager *m,const Translate *t)
|
|||
setFlags(overlay);
|
||||
}
|
||||
|
||||
/// \return the base address space
|
||||
AddrSpace *OverlaySpace::getBaseSpace(void) const
|
||||
|
||||
{
|
||||
return baseSpace;
|
||||
}
|
||||
|
||||
void OverlaySpace::saveXml(ostream &s) const
|
||||
|
||||
{
|
||||
|
|
|
@ -244,7 +244,7 @@ class OverlaySpace : public AddrSpace {
|
|||
AddrSpace *baseSpace; ///< Space being overlayed
|
||||
public:
|
||||
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 restoreXml(const Element *el);
|
||||
};
|
||||
|
|
|
@ -345,8 +345,7 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc)
|
|||
// fallthru
|
||||
case IPTR_PROCESSOR:
|
||||
if (spc->isOverlay()) { // If this is a new overlay space
|
||||
OverlaySpace *ospc = (OverlaySpace *)spc;
|
||||
ospc->getBaseSpace()->setFlags(AddrSpace::overlaybase); // Mark the base as being overlayed
|
||||
spc->getContain()->setFlags(AddrSpace::overlaybase); // Mark the base as being overlayed
|
||||
}
|
||||
else if (spc->isOtherSpace()) {
|
||||
if (spc->index != OtherSpace::INDEX)
|
||||
|
|
|
@ -619,6 +619,9 @@ void TypePointer::printRaw(ostream &s) const
|
|||
{
|
||||
ptrto->printRaw(s);
|
||||
s << " *";
|
||||
if (spaceid != (AddrSpace *)0) {
|
||||
s << '(' << spaceid->getName() << ')';
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
TypePointer *tp = (TypePointer *) &op;
|
||||
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;
|
||||
if (level < 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
|
||||
if (ptrto != tp->ptrto) return (ptrto < tp->ptrto) ? -1 : 1; // Compare absolute pointers
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -658,6 +671,8 @@ void TypePointer::saveXml(ostream &s) const
|
|||
saveXmlBasic(metatype,s);
|
||||
if (wordsize != 1)
|
||||
a_v_i(s,"wordsize",wordsize);
|
||||
if (spaceid != (AddrSpace *)0)
|
||||
a_v(s,"space",spaceid->getName());
|
||||
s << '>';
|
||||
ptrto->saveXmlRef(s);
|
||||
s << "</type>";
|
||||
|
@ -670,12 +685,17 @@ void TypePointer::restoreXml(const Element *el,TypeFactory &typegrp)
|
|||
|
||||
{
|
||||
restoreXmlBasic(el);
|
||||
for(int4 i=0;i<el->getNumAttributes();++i)
|
||||
if (el->getAttributeName(i) == "wordsize") {
|
||||
for(int4 i=0;i<el->getNumAttributes();++i) {
|
||||
const string &attrName(el->getAttributeName(i));
|
||||
if (attrName == "wordsize") {
|
||||
istringstream s(el->getAttributeValue(i));
|
||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s >> wordsize;
|
||||
}
|
||||
else if (attrName == "space") {
|
||||
spaceid = typegrp.getArch()->getSpaceByName(el->getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
ptrto = typegrp.restoreXmlType( *el->getChildren().begin() );
|
||||
calcSubmeta();
|
||||
if (name.size() == 0) // Inherit only if no name
|
||||
|
@ -1740,12 +1760,17 @@ void TypePointerRel::restoreXml(const Element *el,TypeFactory &typegrp)
|
|||
flags |= is_ptrrel;
|
||||
restoreXmlBasic(el);
|
||||
metatype = TYPE_PTR; // Don't use TYPE_PTRREL internally
|
||||
for(int4 i=0;i<el->getNumAttributes();++i)
|
||||
if (el->getAttributeName(i) == "wordsize") {
|
||||
for(int4 i=0;i<el->getNumAttributes();++i) {
|
||||
const string &attribName(el->getAttributeName(i));
|
||||
if (attribName == "wordsize") {
|
||||
istringstream s(el->getAttributeValue(i));
|
||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
||||
s >> wordsize;
|
||||
}
|
||||
else if (attribName == "space") {
|
||||
spaceid = typegrp.getArch()->getSpaceByName(el->getAttributeValue("space"));
|
||||
}
|
||||
}
|
||||
const List &list(el->getChildren());
|
||||
List::const_iterator iter;
|
||||
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
|
||||
/// 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)
|
||||
|
||||
{
|
||||
|
@ -3114,6 +3146,24 @@ TypePointerRel *TypeFactory::getTypePointerRel(int4 sz,Datatype *parent,Datatype
|
|||
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.
|
||||
/// Indirect references (via TypeArray TypeStruct etc.) are not affected
|
||||
/// \param ct is the data-type to destroy
|
||||
|
|
|
@ -281,25 +281,30 @@ class TypePointer : public Datatype {
|
|||
protected:
|
||||
friend class TypeFactory;
|
||||
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
|
||||
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
|
||||
/// 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:
|
||||
/// 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
|
||||
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
|
||||
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 int4 numDepend(void) const { return 1; }
|
||||
virtual Datatype *getDepend(int4 index) const { return ptrto; }
|
||||
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 compareDependency(const Datatype &op) const; // For tree structure
|
||||
virtual int4 compare(const Datatype &op,int4 level) const;
|
||||
virtual int4 compareDependency(const Datatype &op) const;
|
||||
virtual Datatype *clone(void) const { return new TypePointer(*this); }
|
||||
virtual void saveXml(ostream &s) const;
|
||||
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
|
||||
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);
|
||||
TypePointer *getTypePointerWithSpace(Datatype *ptrTo,AddrSpace *spc,const string &nm);
|
||||
void destroyType(Datatype *ct); ///< Remove a data-type from \b this
|
||||
Datatype *concretize(Datatype *ct); ///< Convert given data-type to concrete form
|
||||
void dependentOrder(vector<Datatype *> &deporder) const; ///< Place all data-types in dependency order
|
||||
|
|
|
@ -21,8 +21,7 @@ import java.util.List;
|
|||
import org.xml.sax.*;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.VoidDataType;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
||||
|
@ -265,7 +264,7 @@ public class HighParamID extends PcodeSyntaxTree {
|
|||
dataType = pm.getDataType();
|
||||
}
|
||||
else {
|
||||
dataType = dtManage.findUndefined(vn.getSize());
|
||||
dataType = Undefined.getUndefinedDataType(vn.getSize());
|
||||
}
|
||||
//Msg.debug(this, "func: " + func.getName() + " -- type: " + dataType.getName());
|
||||
if (!(dataType == null || dataType instanceof VoidDataType)) {
|
||||
|
@ -298,7 +297,7 @@ public class HighParamID extends PcodeSyntaxTree {
|
|||
dataType = pm.getDataType();
|
||||
}
|
||||
else {
|
||||
dataType = dtManage.findUndefined(vn.getSize());
|
||||
dataType = Undefined.getUndefinedDataType(vn.getSize());
|
||||
}
|
||||
Variable v = new ParameterImpl(null, dataType, buildStorage(vn), func.getProgram());
|
||||
//Msg.debug(this, "function(" + func.getName() + ")--param: " + v.toString() +
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue