diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc index e7df72241f..d0fd7f6242 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc @@ -553,7 +553,7 @@ void ParamListStandard::assignMap(const vector &proto,bool isinput,T spc = typefactory.getArch()->getDefaultDataSpace(); int4 pointersize = spc->getAddrSize(); int4 wordsize = spc->getWordSize(); - Datatype *pointertp = typefactory.getTypePointerAbsolute(pointersize,proto[i],wordsize); + Datatype *pointertp = typefactory.getTypePointer(pointersize,proto[i],wordsize); res.back().addr = assignAddress(pointertp,status); res.back().type = pointertp; res.back().flags = Varnode::indirectstorage; @@ -1102,7 +1102,7 @@ void ParamListStandardOut::assignMap(const vector &proto,bool isinpu spc = typefactory.getArch()->getDefaultDataSpace(); int4 pointersize = spc->getAddrSize(); int4 wordsize = spc->getWordSize(); - Datatype *pointertp = typefactory.getTypePointerAbsolute(pointersize, proto[0], wordsize); + Datatype *pointertp = typefactory.getTypePointer(pointersize, proto[0], wordsize); res.back().addr = assignAddress(pointertp,status); if (res.back().addr.isInvalid()) throw ParamUnassignedError("Cannot assign return value as a pointer"); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index 0e340dd1bb..87c9f82499 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -345,7 +345,7 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Symbol *sym = entry->getSymbol(); Datatype *entrytype = sym->getType(); - Datatype *ptrentrytype = glb->types->getTypePointer(sz,entrytype,spaceid->getWordSize()); + Datatype *ptrentrytype = glb->types->getTypePointerStripArray(sz,entrytype,spaceid->getWordSize()); bool typelock = sym->isTypeLocked(); if (typelock && (entrytype->getMetatype() == TYPE_UNKNOWN)) typelock = false; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y b/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y index 70fc90a27a..3836408878 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y @@ -654,7 +654,7 @@ Datatype *PointerModifier::modType(Datatype *base,const TypeDeclarator *decl,Arc { int4 addrsize = glb->getDefaultDataSpace()->getAddrSize(); Datatype *restype; - restype = glb->types->getTypePointerAbsolute(addrsize,base,glb->getDefaultDataSpace()->getWordSize()); + restype = glb->types->getTypePointer(addrsize,base,glb->getDefaultDataSpace()->getWordSize()); return restype; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc index 8ef64e26d5..dabcb040fc 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/printc.cc @@ -645,6 +645,13 @@ void PrintC::opPtradd(const PcodeOp *op) { bool printval = isSet(print_load_value|print_store_value); uint4 m = mods & ~(print_load_value|print_store_value); + if (!printval) { + TypePointer *tp = (TypePointer *)op->getIn(0)->getHigh()->getType(); + if (tp->getMetatype() == TYPE_PTR) { + if (tp->getPtrTo()->getMetatype() == TYPE_ARRAY) + printval = true; + } + } if (printval) // Use array notation if we need value pushOp(&subscript,op); else // just a '+' diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc index 91bab2c586..42924b2894 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc @@ -5652,7 +5652,7 @@ bool AddTreeState::checkMultTerm(Varnode *vn,PcodeOp *op,uintb treeCoeff) { Varnode *vnconst = op->getIn(1); Varnode *vnterm = op->getIn(0); - uintb val,rem; + uintb val; if (vnterm->isFree()) { valid = false; @@ -5660,13 +5660,9 @@ bool AddTreeState::checkMultTerm(Varnode *vn,PcodeOp *op,uintb treeCoeff) } if (vnconst->isConstant()) { val = (vnconst->getOffset() * treeCoeff) & ptrmask; - if (size == 0) - rem = val; - else { - intb sval = (intb) val; - sign_extend(sval, vn->getSize() * 8 - 1); - rem = sval % size; - } + intb sval = (intb) val; + sign_extend(sval, vn->getSize() * 8 - 1); + intb rem = (size == 0) ? sval : sval % size; if (rem != 0) { if ((val > size) && (size != 0)) { valid = false; // Size is too big: pointer type must be wrong @@ -5685,7 +5681,7 @@ bool AddTreeState::checkMultTerm(Varnode *vn,PcodeOp *op,uintb treeCoeff) if (treeCoeff != 1) isDistributeUsed = true; multiple.push_back(vnterm); - coeff.push_back(val); + coeff.push_back(sval); return false; } } @@ -5701,7 +5697,6 @@ bool AddTreeState::checkTerm(Varnode *vn,uintb treeCoeff) { uintb val; - intb rem; PcodeOp *def; if (vn == ptr) return false; @@ -5709,13 +5704,9 @@ bool AddTreeState::checkTerm(Varnode *vn,uintb treeCoeff) if (treeCoeff != 1) isDistributeUsed = true; val = vn->getOffset() * treeCoeff; - if (size == 0) - rem = val; - else { - intb sval = (intb)val; - sign_extend(sval,vn->getSize()*8-1); - rem = sval % size; - } + intb sval = (intb)val; + sign_extend(sval,vn->getSize()*8-1); + intb rem = (size == 0) ? sval : (sval % size); if (rem!=0) { // constant is not multiple of size nonmultsum += val; return true; @@ -5851,7 +5842,7 @@ Varnode *AddTreeState::buildMultiples(void) else resNode= data.newConstant(ptrsize,constCoeff); for(int4 i=0;i multiple; ///< Varnodes which are multiples of size - vector coeff; ///< Associated constant multiple + vector coeff; ///< Associated constant multiple vector nonmult; ///< Varnodes which are not multiples PcodeOp *distributeOp; ///< A CPUI_INT_MULT op that needs to be distributed uintb multsum; ///< Sum of multiple constants diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc index 7bd13949bf..612b6b7709 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc @@ -1799,22 +1799,18 @@ TypeCode *TypeFactory::getTypeCode(const string &nm) return (TypeCode *) findAdd(tmp); } -/// This creates a pointer to a given data-type. It doesn't allow -/// a "pointer to array" to be created however and will drill-down to -/// the first non-array data-type +/// This creates a pointer to a given data-type. If the given data-type is +/// an array, the TYPE_ARRAY property is stripped off, and a pointer to +/// the array element data-type is returned. /// \param s is the size of the pointer /// \param pt is the pointed-to data-type /// \param ws is the wordsize associated with the pointer /// \return the TypePointer object -TypePointer *TypeFactory::getTypePointer(int4 s,Datatype *pt,uint4 ws) +TypePointer *TypeFactory::getTypePointerStripArray(int4 s,Datatype *pt,uint4 ws) -{ // Create pointer to type -pt- - if (pt->getMetatype() == TYPE_ARRAY) { - // Do no allow pointers to array - do { - pt = ((TypeArray *)pt)->getBase(); - } while(pt->getMetatype() == TYPE_ARRAY); - } +{ + if (pt->getMetatype() == TYPE_ARRAY) + pt = ((TypeArray *)pt)->getBase(); // Strip the first ARRAY type TypePointer tmp(s,pt,ws); return (TypePointer *) findAdd(tmp); } @@ -1824,7 +1820,7 @@ TypePointer *TypeFactory::getTypePointer(int4 s,Datatype *pt,uint4 ws) /// \param pt is the pointed-to data-type /// \param ws is the wordsize associated with the pointer /// \return the TypePointer object -TypePointer *TypeFactory::getTypePointerAbsolute(int4 s,Datatype *pt,uint4 ws) +TypePointer *TypeFactory::getTypePointer(int4 s,Datatype *pt,uint4 ws) { TypePointer tmp(s,pt,ws); @@ -1946,7 +1942,7 @@ Datatype *TypeFactory::downChain(Datatype *ptrtype,uintb &off) pt = pt->getSubType(off,&off); if (pt == (Datatype *)0) return (Datatype *)0; - return getTypePointer(ptype->size,pt,ptype->getWordSize()); + return getTypePointerStripArray(ptype->size,pt,ptype->getWordSize()); } /// The data-type propagation system can push around data-types that are \e partial or are diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh index f5ddd7dba7..3e44af0af1 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh @@ -430,8 +430,8 @@ public: Datatype *getBase(int4 s,type_metatype m); ///< Get atomic type Datatype *getBase(int4 s,type_metatype m,const string &n); ///< Get named atomic type TypeCode *getTypeCode(void); ///< Get an "anonymous" function data-type - TypePointer *getTypePointer(int4 s,Datatype *pt,uint4 ws); ///< Construct a pointer data-type - TypePointer *getTypePointerAbsolute(int4 s,Datatype *pt,uint4 ws); ///< Construct an absolute pointer data-type + TypePointer *getTypePointerStripArray(int4 s,Datatype *pt,uint4 ws); ///< Construct a pointer data-type, stripping an ARRAY level + TypePointer *getTypePointer(int4 s,Datatype *pt,uint4 ws); ///< Construct an absolute pointer data-type TypePointer *getTypePointerNoDepth(int4 s,Datatype *pt,uint4 ws); ///< Construct a depth limited pointer data-type TypeArray *getTypeArray(int4 as,Datatype *ao); ///< Construct an array data-type TypeStruct *getTypeStruct(const string &n); ///< Create an (empty) structure