diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc index ebd9219e83..0af0a3670c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc @@ -1142,7 +1142,7 @@ Address SegmentedResolver::resolve(uintb val,int4 sz,const Address &point,uintb { int4 innersz = segop->getInnerSize(); - if (sz <= innersz) { // If -sz- matches the inner size, consider the value a "near" pointer + if (sz >= 0 && sz <= innersz) { // If -sz- matches the inner size, consider the value a "near" pointer // In this case the address offset is not fully specified // we check if the rest is stored in a context variable // (as with near pointers) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc index 98582c96c2..9586df45d7 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc @@ -490,9 +490,12 @@ AddrSpace *AddrSpaceManager::getSpaceByShortcut(char sc) const /// If there is a special resolver for the AddrSpace, this is invoked, otherwise /// basic wordsize conversion and wrapping is performed. If the address encoding is /// partial (as in a \e near pointer) and the full encoding can be recovered, it is passed back. +/// The \e sz parameter indicates the number of bytes in constant and is used to determine if +/// the constant is a partial or full pointer encoding. A value of -1 indicates the value is +/// known to be a full encoding. /// \param spc is the space to generate the address from /// \param val is the constant encoding of the address -/// \param sz is the size of the constant encoding +/// \param sz is the size of the constant encoding (or -1) /// \param point is the context address (for recovering full encoding info if necessary) /// \param fullEncoding is used to pass back the recovered full encoding of the pointer /// \return the formal Address associated with the encoding diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh index b0f4c48105..26b048305b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh @@ -144,8 +144,12 @@ public: /// \brief The main resolver method. /// /// Given a native constant in a specific context, resolve what address is being referred to. + /// The constant can be a partially encoded pointer, in which case the full pointer encoding + /// is recovered as well as the address. Whether or not a pointer is partially encoded or not + /// is determined by the \e sz parameter, indicating the number of bytes in the pointer. A value + /// of -1 here indicates that the pointer is known to be a full encoding. /// \param val is constant to be resolved to an address - /// \param sz is the size of \e val in context. + /// \param sz is the size of \e val in context (or -1). /// \param point is the address at which this constant is being used /// \param fullEncoding is used to hold the full pointer encoding if \b val is a partial encoding /// \return the resolved Address diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc index 4e511230a4..084612f10d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc @@ -1125,15 +1125,15 @@ Datatype *TypeSpacebase::getSubType(uintb off,uintb *newoff) const { Scope *scope = getMap(); off = AddrSpace::byteToAddress(off, spaceid->getWordSize()); // Convert from byte offset to address unit - // It should always be the case that given offset represents a full encoding of the - // pointer, so the point of context is unused + // It should always be the case that the given offset represents a full encoding of the + // pointer, so the point of context is unused and the size is given as -1 Address nullPoint; uintb fullEncoding; - Address addr = glb->resolveConstant(spaceid, off, spaceid->getAddrSize(), nullPoint, fullEncoding); + Address addr = glb->resolveConstant(spaceid, off, -1, nullPoint, fullEncoding); SymbolEntry *smallest; - // Assume symbol being referenced is address tied, - // so we use empty usepoint + // Assume symbol being referenced is address tied so we use a null point of context + // FIXME: A valid point of context may be necessary in the future smallest = scope->queryContainer(addr,1,nullPoint); if (smallest == (SymbolEntry *)0) { @@ -1172,6 +1172,9 @@ Address TypeSpacebase::getAddress(uintb off,int4 sz,const Address &point) const { uintb fullEncoding; + // Currently a constant off of a global spacebase must be a full pointer encoding + if (localframe.isInvalid()) + sz = -1; // Set size to -1 to guarantee that full encoding recovery isn't launched return glb->resolveConstant(spaceid,off,sz,point,fullEncoding); }