GP-2274 Apply SUB_PTRREL_UNK only if relative pointer is ephemeral

This commit is contained in:
caheckman 2022-07-01 14:31:29 -04:00
parent 290078d929
commit 6154f16072
2 changed files with 16 additions and 12 deletions

View file

@ -1881,9 +1881,9 @@ void TypePointerRel::decode(Decoder &decoder,TypeFactory &typegrp)
decoder.closeElement(subId); decoder.closeElement(subId);
if (offset == 0) if (offset == 0)
throw new LowlevelError("For metatype=\"ptrstruct\", <off> tag must not be zero"); throw new LowlevelError("For metatype=\"ptrstruct\", <off> tag must not be zero");
submeta = (ptrto->getMetatype()==TYPE_UNKNOWN) ? SUB_PTRREL_UNK: SUB_PTRREL; submeta = SUB_PTRREL;
if (name.size() == 0) // If the data-type is not named if (name.size() == 0) // If the data-type is not named
cacheStrippedType(typegrp); // it is considered ephemeral markEphemeral(typegrp); // it is considered ephemeral
// decoder.closeElement(elemId); // decoder.closeElement(elemId);
} }
@ -3251,7 +3251,7 @@ TypePointerRel *TypeFactory::getTypePointerRel(TypePointer *parentPtr,Datatype *
{ {
TypePointerRel tp(parentPtr->size,ptrTo,parentPtr->wordsize,parentPtr->ptrto,off); TypePointerRel tp(parentPtr->size,ptrTo,parentPtr->wordsize,parentPtr->ptrto,off);
tp.cacheStrippedType(*this); // Mark as ephemeral tp.markEphemeral(*this); // Mark as ephemeral
TypePointerRel *res = (TypePointerRel *) findAdd(tp); TypePointerRel *res = (TypePointerRel *) findAdd(tp);
return res; return res;
} }

View file

@ -469,7 +469,7 @@ protected:
TypePointer *stripped; ///< Same data-type with container info stripped TypePointer *stripped; ///< Same data-type with container info stripped
Datatype *parent; ///< Parent structure or array which \b this is pointing into Datatype *parent; ///< Parent structure or array which \b this is pointing into
int4 offset; ///< Byte offset within the parent where \b this points to int4 offset; ///< Byte offset within the parent where \b this points to
void cacheStrippedType(TypeFactory &typegrp); void markEphemeral(TypeFactory &typegrp);
void decode(Decoder &decoder,TypeFactory &typegrp); ///< Restore \b this relative pointer data-type from a stream void decode(Decoder &decoder,TypeFactory &typegrp); ///< Restore \b this relative pointer data-type from a stream
/// Internal constructor for decode /// Internal constructor for decode
TypePointerRel(void) : TypePointer() { offset = 0; parent = (Datatype *)0; stripped = (TypePointer *)0; submeta = SUB_PTRREL; } TypePointerRel(void) : TypePointer() { offset = 0; parent = (Datatype *)0; stripped = (TypePointer *)0; submeta = SUB_PTRREL; }
@ -479,8 +479,7 @@ public:
offset = op.offset; parent = op.parent; stripped = op.stripped; } offset = op.offset; parent = op.parent; stripped = op.stripped; }
/// Construct given a size, pointed-to type, parent, and offset /// Construct given a size, pointed-to type, parent, and offset
TypePointerRel(int4 sz,Datatype *pt,uint4 ws,Datatype *par,int4 off) : TypePointer(sz,pt,ws) { TypePointerRel(int4 sz,Datatype *pt,uint4 ws,Datatype *par,int4 off) : TypePointer(sz,pt,ws) {
parent = par; offset = off; stripped = (TypePointer *)0; flags |= is_ptrrel; parent = par; offset = off; stripped = (TypePointer *)0; flags |= is_ptrrel; submeta = SUB_PTRREL; }
submeta = pt->getMetatype()==TYPE_UNKNOWN ? SUB_PTRREL_UNK : SUB_PTRREL; }
Datatype *getParent(void) const { return parent; } ///< Get the parent data-type to which \b this pointer is offset Datatype *getParent(void) const { return parent; } ///< Get the parent data-type to which \b this pointer is offset
bool evaluateThruParent(uintb addrOff) const; ///< Do we display given address offset as coming from the parent data-type bool evaluateThruParent(uintb addrOff) const; ///< Do we display given address offset as coming from the parent data-type
@ -700,18 +699,23 @@ inline TypeArray::TypeArray(int4 n,Datatype *ao) : Datatype(n*ao->getSize(),TYPE
flags |= needs_resolution; flags |= needs_resolution;
} }
/// \brief Set up the base pointer data-type \b this is modeling /// \brief Mark \b this as an ephemeral data-type, to be replaced in the final output
/// ///
/// This base data-type is used for formal variable declarations in source code output. /// A \e base data-type is cached, which is a stripped version of the relative pointer, leaving
/// Calling this method marks the TypePointerRel as an ephemeral data-type. The TypePointerRel /// just a plain TypePointer object with the same underlying \b ptrto. The base data-type
/// is not considered a formal data-type and is replaced with the base pointer data-type, after propagation, /// replaces \b this relative pointer for formal variable declarations in source code output.
/// in the final decompiler output. /// This TypePointerRel is not considered a formal data-type but is only used to provide extra
/// context for the pointer during propagation.
/// \param typegrp is the factory from which to fetch the base pointer /// \param typegrp is the factory from which to fetch the base pointer
inline void TypePointerRel::cacheStrippedType(TypeFactory &typegrp) inline void TypePointerRel::markEphemeral(TypeFactory &typegrp)
{ {
stripped = typegrp.getTypePointer(size,ptrto,wordsize); stripped = typegrp.getTypePointer(size,ptrto,wordsize);
flags |= has_stripped; flags |= has_stripped;
// An ephemeral relative pointer that points to something unknown, propagates slightly
// differently than a formal relative pointer
if (ptrto->getMetatype() == TYPE_UNKNOWN)
submeta = SUB_PTRREL_UNK;
} }
#endif #endif