Variable length types

This commit is contained in:
caheckman 2020-09-28 17:26:20 -04:00
parent 02e6c66f11
commit 97b04cac7e
7 changed files with 29 additions and 23 deletions

View file

@ -4244,7 +4244,7 @@ Datatype *ActionInferTypes::propagateAddIn2Out(TypeFactory *typegrp,PcodeOp *op,
int4 offset = propagateAddPointer(op,inslot);
if (offset==-1) return op->getOut()->getTempType(); // Doesn't look like a good pointer add
uintb uoffset = AddrSpace::addressToByte(offset,((TypePointer *)rettype)->getWordSize());
if (tstruct->getSize() > 0)
if (tstruct->getSize() > 0 && !tstruct->isVariableLength())
uoffset = uoffset % tstruct->getSize();
if (uoffset==0) {
if (op->code() == CPUI_PTRSUB) // Go down at least one level
@ -4419,7 +4419,7 @@ bool ActionInferTypes::propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 i
}
else if (alttype->getMetatype()==TYPE_PTR) {
newtype = ((TypePointer *)alttype)->getPtrTo();
if (newtype->getSize() != outvn->getTempType()->getSize()) // Size must be appropriate
if (newtype->getSize() != outvn->getTempType()->getSize() || newtype->isVariableLength()) // Size must be appropriate
newtype = outvn->getTempType();
}
else
@ -4432,7 +4432,7 @@ bool ActionInferTypes::propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 i
}
else if (alttype->getMetatype()==TYPE_PTR) {
newtype = ((TypePointer *)alttype)->getPtrTo();
if (newtype->getSize() != outvn->getTempType()->getSize())
if (newtype->getSize() != outvn->getTempType()->getSize() || newtype->isVariableLength())
newtype = outvn->getTempType();
}
else

View file

@ -38,7 +38,7 @@ ScopeGhidra::~ScopeGhidra(void)
}
/// The Ghidra client reports a \e namespace id associated with
/// Symbol. Determine if a matching \e namespac Scope already exists in the cache and build
/// Symbol. Determine if a matching \e namespace Scope already exists in the cache and build
/// it if it isn't. This may mean creating a new \e namespace Scope.
/// \param id is the ID associated with the Ghidra namespace
/// \return the Scope matching the id.

View file

@ -1670,21 +1670,7 @@ void PrintC::pushAnnotation(const Varnode *vn,const PcodeOp *op)
void PrintC::pushSymbol(const Symbol *sym,const Varnode *vn,const PcodeOp *op)
{
Datatype *ct = sym->getType();
EmitXml::syntax_highlight tokenColor;
if (((sym->getFlags()&Varnode::readonly)!=0)&&(ct->getMetatype()==TYPE_ARRAY)) {
Datatype *subct = ((TypeArray *)ct)->getBase();
if (subct->isCharPrint()) {
SymbolEntry *entry = sym->getFirstWholeMap();
if (entry != (SymbolEntry *)0) {
ostringstream s;
if (printCharacterConstant(s,entry->getAddr(),subct)) {
pushAtom(Atom(s.str(),vartoken,EmitXml::const_color,op,vn));
return;
}
}
}
}
if (sym->getScope()->isGlobal())
tokenColor = EmitXml::global_color;
else if (sym->getCategory() == 0)

View file

@ -5627,6 +5627,9 @@ AddTreeState::AddTreeState(Funcdata &d,PcodeOp *op,int4 slot)
ptrsize = ptr->getSize();
ptrmask = calc_mask(ptrsize);
baseType = ct->getPtrTo();
if (baseType->isVariableLength())
size = 0; // Open-ended size being pointed to, there will be no "multiples" component
else
size = AddrSpace::byteToAddressInt(baseType->getSize(),ct->getWordSize());
multsum = 0; // Sums start out as zero
nonmultsum = 0;

View file

@ -46,7 +46,7 @@ class AddTreeState {
const TypePointer *ct; ///< The pointer data-type
const Datatype *baseType; ///< The base data-type being pointed at
int4 ptrsize; ///< Size of the pointer
int4 size; ///< Size of data-type being pointed to (in address units)
int4 size; ///< Size of data-type being pointed to (in address units) or 0 for open ended pointer
uintb ptrmask; ///< Mask for modulo calculations in ptr space
uintb offset; ///< Number of bytes we dig into the base data-type
uintb correct; ///< Number of bytes being double counted

View file

@ -1092,15 +1092,18 @@ void TypeStruct::restoreXml(const Element *el,TypeFactory &typegrp)
}
/// Turn on the data-type's function prototype
/// \param tfact is the factory that owns \b this
/// \param model is the prototype model
/// \param outtype is the return type of the prototype
/// \param intypes is the list of input parameters
/// \param dotdotdot is true if the prototype takes variable arguments
/// \param voidtype is the reference "void" data-type
void TypeCode::set(ProtoModel *model,
void TypeCode::set(TypeFactory *tfact,ProtoModel *model,
Datatype *outtype,const vector<Datatype *> &intypes,
bool dotdotdot,Datatype *voidtype)
{
factory = tfact;
flags |= variable_length;
if (proto != (FuncProto *)0)
delete proto;
proto = new FuncProto();
@ -1123,6 +1126,7 @@ TypeCode::TypeCode(const TypeCode &op) : Datatype(op)
{
proto = (FuncProto *)0;
factory = op.factory;
if (op.proto != (FuncProto *)0) {
proto = new FuncProto();
proto->copy(*op.proto);
@ -1133,6 +1137,7 @@ TypeCode::TypeCode(const string &nm) : Datatype(1,TYPE_CODE,nm)
{
proto = (FuncProto *)0;
factory = (TypeFactory *)0;
}
TypeCode::~TypeCode(void)
@ -1204,6 +1209,14 @@ int4 TypeCode::compareBasic(const TypeCode *op) const
return 2; // Carry on with comparison of parameters
}
Datatype *TypeCode::getSubType(uintb off,uintb *newoff) const
{
if (factory == (TypeFactory *)0) return (Datatype *)0;
*newoff = 0;
return factory->getBase(1, TYPE_CODE); // Return code byte unattached to function prototype
}
int4 TypeCode::compare(const Datatype &op,int4 level) const
{
@ -1284,6 +1297,8 @@ void TypeCode::restoreXml(const Element *el,TypeFactory &typegrp)
iter = list.begin();
if (iter == list.end()) return; // No underlying prototype
Architecture *glb = typegrp.getArch();
factory = &typegrp;
flags |= variable_length;
proto = new FuncProto();
proto->setInternal( glb->defaultfp, typegrp.getTypeVoid() );
proto->restoreXml(*iter,glb);
@ -2107,7 +2122,7 @@ TypeCode *TypeFactory::getTypeCode(ProtoModel *model,Datatype *outtype,
bool dotdotdot)
{
TypeCode tc(""); // getFuncdata type with no name
tc.set(model,outtype,intypes,dotdotdot,getTypeVoid());
tc.set(this,model,outtype,intypes,dotdotdot,getTypeVoid());
return (TypeCode *) findAdd(tc);
}

View file

@ -342,7 +342,8 @@ class TypeCode : public Datatype {
protected:
friend class TypeFactory;
FuncProto *proto; ///< If non-null, this describes the prototype of the underlying function
void set(ProtoModel *model,
TypeFactory *factory; ///< Factory owning \b this
void set(TypeFactory *tfact,ProtoModel *model,
Datatype *outtype,const vector<Datatype *> &intypes,
bool dotdotdot,Datatype *voidtype); ///< Establish a function pointer
virtual void restoreXml(const Element *el,TypeFactory &typegrp);
@ -354,6 +355,7 @@ public:
void setProperties(bool isConstructor,bool isDestructor); ///< Set additional function properties
virtual ~TypeCode(void);
virtual void printRaw(ostream &s) const;
virtual Datatype *getSubType(uintb off,uintb *newoff) const;
virtual int4 compare(const Datatype &op,int4 level) const;
virtual int4 compareDependency(const Datatype &op) const;
virtual Datatype *clone(void) const { return new TypeCode(*this); }